#define INIT 0x000800 /* initialize component */
#define SPLIT 0x001000 /* split headers (don't concatenate) */
#define NONEWLINE 0x002000 /* don't write trailing newline */
-#define LBITS "\020\01NOCOMPONENT\02UPPERCASE\03CENTER\04CLEARTEXT\05EXTRA\06HDROUTPUT\07LEFTADJUST\010COMPRESS\011ADDRFMT\012DATEFMT\013FORMAT\014INIT\015SPLIT\016NONEWLINE"
+#define RTRIM 0x004000 /* trim trailing whitespace */
+#define RAW 0x008000 /* print the raw input */
+#define LBITS "\020\01NOCOMPONENT\02UPPERCASE\03CENTER\04CLEARTEXT\05EXTRA\06HDROUTPUT\07LEFTADJUST\010COMPRESS\011ADDRFMT\012DATEFMT\013FORMAT\014INIT\015SPLIT\016NONEWLINE\017RTRIM\020RAW"
#define GFLAGS (NOCOMPONENT | UPPERCASE | CENTER | LEFTADJUST | COMPRESS | SPLIT)
struct mcomp {
static struct triple triples[] = {
{ "nocomponent", NOCOMPONENT, 0 },
- { "uppercase", UPPERCASE, 0 },
+ { "uppercase", UPPERCASE, RAW },
{ "nouppercase", 0, UPPERCASE },
- { "center", CENTER, 0 },
+ { "center", CENTER, RAW },
{ "nocenter", 0, CENTER },
- { "leftadjust", LEFTADJUST, 0 },
+ { "leftadjust", LEFTADJUST, RAW },
{ "noleftadjust", 0, LEFTADJUST },
- { "compress", COMPRESS, 0 },
+ { "compress", COMPRESS, RAW },
{ "nocompress", 0, COMPRESS },
{ "split", SPLIT, 0 },
{ "nosplit", 0, SPLIT },
- { "addrfield", ADDRFMT, DATEFMT },
- { "datefield", DATEFMT, ADDRFMT },
- { "newline", 0, NONEWLINE },
+ { "rtrim", RTRIM, RAW },
+ { "nortrim", 0, RTRIM },
+ { "raw", RAW|SPLIT|NOCOMPONENT|NONEWLINE, UPPERCASE|CENTER|LEFTADJUST|COMPRESS|DATEFMT|ADDRFMT },
+ { "addrfield", ADDRFMT, DATEFMT|RAW },
+ { "datefield", DATEFMT, ADDRFMT|RAW },
+ { "newline", 0, NONEWLINE|RAW },
{ "nonewline", NONEWLINE, 0 },
{ NULL, 0, 0 }
};
c1->c_flags &= ~HDROUTPUT;
}
+static boolean
+simplematch(char *pattern, char *b)
+{
+ char *match = strrchr(pattern, '*');
+ char repl;
+ boolean ret;
+
+ /* check if pattern ends with a * and is not escaped witch a \ */
+ if (!match || match[1] || (match > pattern && match[-1] == '\\')) {
+ if (!match || match[1]) {
+ return mh_strcasecmp(pattern, b) == 0;
+ }
+ match[0] = '\0';
+ match[-1] = '*';
+ ret = mh_strcasecmp(pattern, b)==0;
+ match[-1] = '\\';
+ match[0] = '*';
+ return ret;
+ }
+
+ repl = b[match-pattern];
+ b[match-pattern] = '\0';
+ *match = '\0';
+ ret = (mh_strcasecmp(pattern, b) == 0);
+ b[match-pattern] = repl;
+ *match = '*';
+ return ret;
+}
static void
mhlfile(FILE *fp, char *mname, int ofilen, int ofilec)
switch (state = m_getfld2(state, &f, fp)) {
case FLD2:
for (ip = ignores; *ip; ip++)
- if (mh_strcasecmp(f.name, *ip)==0) {
+ if (simplematch(*ip, f.name)) {
break;
}
if (*ip) {
*head = *tail = NULL;
}
-
static void
putcomp(struct mcomp *c1, struct mcomp *c2, int flag)
{
int count, cchdr;
unsigned char *cp;
+ char trimmed_prefix[BUFSIZ];
+ strncpy(trimmed_prefix, c1->c_text ? c1->c_text : c1->c_name, sizeof(trimmed_prefix) - 1);
+ rtrim(trimmed_prefix);
cchdr = 0;
lm = 0;
wid = c1->c_width ? c1->c_width : global.c_width;
onelp = NULL;
if (c1->c_flags & CLEARTEXT) {
- putstr(c1->c_text);
+ putstr((c1->c_flags & RTRIM) ? rtrim(c1->c_text) : c1->c_text);
putstr("\n");
return;
}
+ if (c1->c_flags & RAW) {
+ switch (flag) {
+ case ONECOMP:
+ printf("%s:%s", c1->c_name, c1->c_text);
+ break;
+ case TWOCOMP:
+ printf("%s:%s", c2->c_name, c2->c_text);
+ break;
+ case BODYCOMP:
+ fputs(c2->c_text, stdout);
+ break;
+ default:
+ adios(EX_SOFTWARE, NULL, "BUG: putcomp() is called with a unknown flag");
+ }
+ return;
+ }
+
if (c1->c_fstr && (c1->c_flags & (ADDRFMT | DATEFMT | FORMAT)))
mcomp_format(c1, c2);
for (cp = (c1->c_text ? c1->c_text : c1->c_name); *cp; cp++)
if (islower(*cp))
*cp = toupper(*cp);
- putstr(c1->c_text ? c1->c_text : c1->c_name);
+ if (*c2->c_text && *c2->c_text != '\n' && *c2->c_text != '\r') {
+ putstr(c1->c_text ? c1->c_text : c1->c_name);
+ } else {
+ putstr(trimmed_prefix);
+ }
if (flag != BODYCOMP) {
putstr(": ");
if (!(c1->c_flags & SPLIT))
}
count += c1->c_offset;
- if ((cp = oneline(c2->c_text, c1->c_flags)))
- putstr(cp);
+ if ((cp = oneline(c2->c_text, c1->c_flags))) {
+ putstr((c1->c_flags & RTRIM) ? rtrim(cp) : cp);
+ }
if (term == '\n')
putstr("\n");
while ((cp = oneline(c2->c_text, c1->c_flags))) {
lm = count;
- if (flag == BODYCOMP && !(c1->c_flags & NOCOMPONENT))
- putstr(c1->c_text ? c1->c_text : c1->c_name);
+ if (flag == BODYCOMP && !(c1->c_flags & NOCOMPONENT)) {
+ if (*cp) {
+ putstr(c1->c_text ? c1->c_text : c1->c_name);
+ } else {
+ putstr(trimmed_prefix);
+ }
+ }
if (*cp)
- putstr(cp);
+ putstr((c1->c_flags & RTRIM) ? rtrim(cp) : cp);
+
if (term == '\n')
putstr("\n");
}
c1->c_flags &= ~HDROUTPUT; /* Buffer ended on a newline */
}
-
static char *
oneline(char *stuff, long flags)
{
return ret;
}
-
static void
putstr(char *string)
{