Trailing withspace handling in mhl
authorPhilipp Takacs <philipp@bureaucracy.de>
Mon, 19 Nov 2018 02:04:12 +0000 (03:04 +0100)
committerPhilipp Takacs <philipp@bureaucracy.de>
Sun, 25 Nov 2018 14:08:54 +0000 (15:08 +0100)
If a component has trailing whitespace, e.g., body:component="> ", mhl
now trims that whitespace off when filtering blank text lines. Also add
a rtrim flag to mhl. This flag removes trailing whitespace in filtert text.

The implementation was done by David Levine <levinedl@acm.org> for nmh
commit ea0a6d8112a918809bd03d8126411040d22f2bb8
commit 1aa8f3e11e6d83ee4806abaa132ab9466f02ca5f

h/prototypes.h
man/mhl.man1
sbr/trim.c
test/tests/mhl/test-mhl-flags
uip/mhl.c

index 69556f9..6526582 100644 (file)
@@ -107,6 +107,7 @@ char *snprintb(char *, size_t, unsigned, char *);
 int stringdex(char *, char *);
 char *toabsdir(char *);
 char *trim(unsigned char *);
 int stringdex(char *, char *);
 char *toabsdir(char *);
 char *trim(unsigned char *);
+char *rtrim(char *);
 char *trimcpy(unsigned char *);
 int unputenv(char *);
 void unquote_string(const char *input, char *output);
 char *trimcpy(unsigned char *);
 int unputenv(char *);
 void unquote_string(const char *input, char *output);
index a80d6bf..9785fe2 100644 (file)
@@ -136,6 +136,8 @@ leftadjust  flag    strip off leading whitespace on each
 noleftadjust   flag    don't leftadjust
 compress       flag    change newlines in text to spaces
 nocompress     flag    don't compress
 noleftadjust   flag    don't leftadjust
 compress       flag    change newlines in text to spaces
 nocompress     flag    don't compress
+rtrim  flag    trim whitespace at end of text lines
+nortrim        flag    retain whitespace at end of text lines (default)
 split  flag    don't combine multiple fields into
                a single field
 nosplit        flag    combine multiple fields into
 split  flag    don't combine multiple fields into
                a single field
 nosplit        flag    combine multiple fields into
index 249faf9..cbf9098 100644 (file)
@@ -31,3 +31,15 @@ trim(unsigned char *cp)
 
        return cp;
 }
 
        return cp;
 }
+
+char *
+rtrim(char *cp)
+{
+       char *sp = cp + strlen(cp) - 1;
+
+       while (sp >= cp && isspace(*sp)) {
+               sp--;
+       }
+       *++sp = '\0';
+       return cp;
+}
index 7220e6c..578fd37 100755 (executable)
@@ -4,7 +4,6 @@
 
 . "$MH_TEST_COMMON"
 
 
 . "$MH_TEST_COMMON"
 
-test_skip "not implemented yet"
 
 
 cat >`mhpath b` <<EOF
 
 
 cat >`mhpath b` <<EOF
index a84703b..2987c0d 100644 (file)
--- a/uip/mhl.c
+++ b/uip/mhl.c
@@ -77,7 +77,8 @@ char *version=VERSION;
 #define INIT        0x000800  /* initialize component        */
 #define SPLIT       0x001000  /* split headers (don't concatenate) */
 #define NONEWLINE   0x002000  /* don't write trailing newline */
 #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 LBITS       "\020\01NOCOMPONENT\02UPPERCASE\03CENTER\04CLEARTEXT\05EXTRA\06HDROUTPUT\07LEFTADJUST\010COMPRESS\011ADDRFMT\012DATEFMT\013FORMAT\014INIT\015SPLIT\016NONEWLINE\017RTRIM"
 #define GFLAGS      (NOCOMPONENT | UPPERCASE | CENTER | LEFTADJUST | COMPRESS | SPLIT)
 
 struct mcomp {
 #define GFLAGS      (NOCOMPONENT | UPPERCASE | CENTER | LEFTADJUST | COMPRESS | SPLIT)
 
 struct mcomp {
@@ -148,6 +149,8 @@ static struct triple triples[] = {
        { "nocompress", 0, COMPRESS },
        { "split", SPLIT, 0 },
        { "nosplit", 0, SPLIT },
        { "nocompress", 0, COMPRESS },
        { "split", SPLIT, 0 },
        { "nosplit", 0, SPLIT },
+       { "rtrim", RTRIM, 0 },
+       { "nortrim", 0, RTRIM },
        { "addrfield", ADDRFMT, DATEFMT },
        { "datefield", DATEFMT, ADDRFMT },
        { "newline", 0, NONEWLINE },
        { "addrfield", ADDRFMT, DATEFMT },
        { "datefield", DATEFMT, ADDRFMT },
        { "newline", 0, NONEWLINE },
@@ -884,7 +887,10 @@ putcomp(struct mcomp *c1, struct mcomp *c2, int flag)
 {
        int count, cchdr;
        unsigned char *cp;
 {
        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;
        cchdr = 0;
        lm = 0;
        wid = c1->c_width ? c1->c_width : global.c_width;
@@ -897,7 +903,7 @@ putcomp(struct mcomp *c1, struct mcomp *c2, int flag)
        onelp = NULL;
 
        if (c1->c_flags & CLEARTEXT) {
        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;
        }
                putstr("\n");
                return;
        }
@@ -922,7 +928,11 @@ putcomp(struct mcomp *c1, struct mcomp *c2, int flag)
                        for (cp = (c1->c_text ? c1->c_text : c1->c_name); *cp; cp++)
                                if (islower(*cp))
                                        *cp = toupper(*cp);
                        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))
                if (flag != BODYCOMP) {
                        putstr(": ");
                        if (!(c1->c_flags & SPLIT))
@@ -970,16 +980,23 @@ putcomp(struct mcomp *c1, struct mcomp *c2, int flag)
        }
        count += c1->c_offset;
 
        }
        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 (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)
                if (*cp)
-                       putstr(cp);
+                       putstr((c1->c_flags & RTRIM) ? rtrim(cp) : cp);
+
                if (term == '\n')
                        putstr("\n");
        }
                if (term == '\n')
                        putstr("\n");
        }