X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/831d609eb70021081f4ff6361e11e01b29acfbb1..792d7e1e:/uip/mhlsbr.c?ds=inline diff --git a/uip/mhlsbr.c b/uip/mhlsbr.c index 02ba0bcc..c56acff9 100644 --- a/uip/mhlsbr.c +++ b/uip/mhlsbr.c @@ -93,7 +93,9 @@ DEFINE_SWITCH_ARRAY(MHL, mhlswitches); #define NONEWLINE 0x020000 /* don't write trailing newline */ #define NOWRAP 0x040000 /* Don't wrap lines ever */ #define FMTFILTER 0x080000 /* Filter through format filter */ -#define LBITS "\020\01NOCOMPONENT\02UPPERCASE\03CENTER\04CLEARTEXT\05EXTRA\06HDROUTPUT\07CLEARSCR\010LEFTADJUST\011COMPRESS\012ADDRFMT\013BELL\014DATEFMT\015FORMAT\016INIT\017RTRIM\021SPLIT\022NONEWLINE\023NOWRAP\024FMTFILTER" +#define INVISIBLE 0x100000 /* count byte in display columns? */ +#define FORCE7BIT 0x200000 /* don't display 8-bit bytes */ +#define LBITS "\020\01NOCOMPONENT\02UPPERCASE\03CENTER\04CLEARTEXT\05EXTRA\06HDROUTPUT\07CLEARSCR\010LEFTADJUST\011COMPRESS\012ADDRFMT\013BELL\014DATEFMT\015FORMAT\016INIT\017RTRIM\021SPLIT\022NONEWLINE\023NOWRAP\024FMTFILTER\025INVISIBLE\026FORCE7BIT" #define GFLAGS (NOCOMPONENT | UPPERCASE | CENTER | LEFTADJUST | COMPRESS | SPLIT | NOWRAP) /* @@ -161,7 +163,7 @@ struct mcomp { int c_width; /* width of field */ int c_cwidth; /* width of component */ int c_length; /* length in lines */ - long c_flags; + unsigned long c_flags; struct mcomp *c_next; }; @@ -180,7 +182,7 @@ static struct mcomp holder = { struct pair { char *p_name; - long p_flags; + unsigned long p_flags; }; static struct pair pairs[] = { @@ -203,8 +205,8 @@ static struct pair pairs[] = { struct triple { char *t_name; - long t_on; - long t_off; + unsigned long t_on; + unsigned long t_off; }; static struct triple triples[] = { @@ -322,14 +324,14 @@ static char *parse (void); static void process (char *, char *, int, int); static void mhlfile (FILE *, char *, int, int); static int mcomp_flags (char *); -static char *mcomp_add (long, char *, char *); +static char *mcomp_add (unsigned long, char *, char *); static void mcomp_format (struct mcomp *, struct mcomp *); static struct mcomp *add_queue (struct mcomp **, struct mcomp **, char *, char *, int); static void free_queue (struct mcomp **, struct mcomp **); static void putcomp (struct mcomp *, struct mcomp *, int); -static char *oneline (char *, long); -static void putstr (char *, long); -static void putch (char, long); +static char *oneline (char *, unsigned long); +static void putstr (char *, unsigned long); +static void putch (char, unsigned long); static void intrser (int); static void pipeser (int); static void quitser (int); @@ -507,7 +509,7 @@ mhl (int argc, char **argv) if (forwall) { if (digest) { - printf ("%s", delim4); + fputs(delim4, stdout); if (volume == 0) { snprintf (buf, sizeof(buf), "End of %s Digest\n", digest); } else { @@ -519,7 +521,7 @@ mhl (int argc, char **argv) *cp++ = '*'; *cp++ = '\n'; *cp = 0; - printf ("%s", buf); + fputs(buf, stdout); } else printf ("\n------- End of Forwarded Message%s\n", @@ -944,7 +946,7 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec) if (forwall) { if (digest) - printf ("%s", ofilen == 1 ? delim3 : delim4); + fputs(ofilen == 1 ? delim3 : delim4, stdout); else { printf ("\n-------"); if (ofilen == 1) @@ -1125,7 +1127,7 @@ mcomp_flags (char *name) static char * -mcomp_add (long flags, char *s1, char *s2) +mcomp_add (unsigned long flags, char *s1, char *s2) { char *dp; @@ -1286,6 +1288,13 @@ putcomp (struct mcomp *c1, struct mcomp *c2, int flag) char *trimmed_prefix; int count, cchdr; char *cp; + const int utf8 = strcasecmp(get_charset(), "UTF-8") == 0; + + if (! utf8 && flag != BODYCOMP) { + /* Don't print 8-bit bytes in header field values if not in a + UTF-8 locale, as required by RFC 6532. */ + c1->c_flags |= FORCE7BIT; + } text = c1->c_text ? c1->c_text : c1->c_name; /* Create a copy with trailing whitespace trimmed, for use with @@ -1405,7 +1414,7 @@ putcomp (struct mcomp *c1, struct mcomp *c2, int flag) static char * -oneline (char *stuff, long flags) +oneline (char *stuff, unsigned long flags) { int spc; char *cp, *ret; @@ -1457,8 +1466,12 @@ oneline (char *stuff, long flags) static void -putstr (char *string, long flags) +putstr (char *string, unsigned long flags) { + /* To not count, for the purpose of counting columns, all of + the bytes of a multibyte character. */ + int char_len; + if (!column && lm > 0) { while (lm > 0) if (lm >= 8) { @@ -1471,13 +1484,38 @@ putstr (char *string, long flags) } } lm = 0; - while (*string) - putch (*string++, flags); + +#ifdef MULTIBYTE_SUPPORT + if (mbtowc (NULL, NULL, 0)) {} /* reset shift state */ + char_len = 0; +#else + NMH_UNUSED (char_len); +#endif + + while (*string) { + flags &= ~INVISIBLE; +#ifdef MULTIBYTE_SUPPORT + /* mbtowc should never return 0, because *string is non-NULL. */ + if (char_len <= 0) { + /* Find number of bytes in next character. */ + if ((char_len = + mbtowc (NULL, string, (size_t) MB_CUR_MAX)) == -1) { + char_len = 1; + } + } else { + /* Multibyte character, after the first byte. */ + flags |= INVISIBLE; + } + + --char_len; +#endif + putch (*string++, flags); + } } static void -putch (char ch, long flags) +putch (char ch, unsigned long flags) { char buf[BUFSIZ]; @@ -1531,8 +1569,25 @@ putch (char ch, long flags) putchar ('-'); putchar (' '); } - if (ch >= ' ') - column++; + /* + * Increment the character count, unless + * 1) In UTF-8 locale, this is other than the last byte of + a multibyte character, or + * 2) In C locale, will print a non-printable character. + */ + if ((flags & FORCE7BIT) == 0) { + /* UTF-8 locale */ + if ((flags & INVISIBLE) == 0) { + /* If multibyte character, its first byte only. */ + ++column; + } + } else { + /* If not an ASCII character, the replace character will be + displayed. Count it. */ + if (! isascii((unsigned char) ch) || isprint((unsigned char) ch)) { + ++column; + } + } break; } @@ -1545,7 +1600,11 @@ putch (char ch, long flags) return; } - putchar (ch); + if (flags & FORCE7BIT && ! isascii((unsigned char) ch)) { + putchar ('?'); + } else { + putchar (ch); + } }