X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/ba8b265a8211b2052b424dc9bd7ea391a8ded87a..4a56a28ac439137ba2b71fcb5952b4e4abd1e2fc:/sbr/fmt_scan.c?ds=inline diff --git a/sbr/fmt_scan.c b/sbr/fmt_scan.c index b0beeb23..c75db3ec 100644 --- a/sbr/fmt_scan.c +++ b/sbr/fmt_scan.c @@ -1,6 +1,4 @@ - -/* - * fmt_scan.c -- format string interpretation +/* fmt_scan.c -- format string interpretation * * This code is Copyright (c) 2002, by the authors of nmh. See the * COPYRIGHT file in the root directory of the nmh distribution for @@ -16,6 +14,7 @@ #include #include #include +#include "unquote.h" #ifdef HAVE_SYS_TIME_H # include @@ -49,24 +48,14 @@ match (char *str, char *sub) char *s1, *s2; while ((c1 = *sub)) { - c1 = (isascii((unsigned char) c1) && isalpha((unsigned char) c1) && - isupper((unsigned char) c1)) ? tolower((unsigned char) c1) : c1; - while ((c2 = *str++) && c1 != ((isascii((unsigned char) c2) && - isalpha((unsigned char) c2) && - isupper((unsigned char) c2)) ? - tolower((unsigned char) c2) : c2)) + c1 = tolower((unsigned char)c1); + while ((c2 = *str++) && c1 != tolower((unsigned char)c2)) ; if (! c2) return 0; s1 = sub + 1; s2 = str; - while ((c1 = *s1++) && ((isascii((unsigned char) c1) && - isalpha((unsigned char) c1) && - isupper((unsigned char) c1)) ? - tolower(c1) : c1) == - ((isascii((unsigned char) (c2 =*s2++)) && - isalpha((unsigned char) c2) && - isupper((unsigned char) c2)) ? - tolower((unsigned char) c2) : c2)) + while ((c1 = *s1++) && + tolower((unsigned char)c1) == tolower((unsigned char)(c2 = *s2++))) ; if (! c1) return 1; @@ -129,6 +118,7 @@ void cptrimmed(charstring_t dest, char *str, int wid, char fill, size_t max) { int remaining; /* remaining output width available */ int rjust; + struct charstring *trimmed; size_t end; /* number of input bytes remaining in str */ #ifdef MULTIBYTE_SUPPORT int char_len; /* bytes in current character */ @@ -147,6 +137,8 @@ cptrimmed(charstring_t dest, char *str, int wid, char fill, size_t max) { } if (remaining > (int) max) { remaining = max; } + trimmed = rjust ? charstring_create(remaining) : dest; + if ((sp = str)) { #ifdef MULTIBYTE_SUPPORT if (mbtowc(NULL, NULL, 0)) {} /* reset shift state */ @@ -192,7 +184,7 @@ cptrimmed(charstring_t dest, char *str, int wid, char fill, size_t max) { sp++; #endif if (!prevCtrl) { - charstring_push_back (dest, ' '); + charstring_push_back (trimmed, ' '); remaining--; } @@ -203,39 +195,26 @@ cptrimmed(charstring_t dest, char *str, int wid, char fill, size_t max) { #ifdef MULTIBYTE_SUPPORT if (w >= 0 && remaining >= w) { - charstring_push_back_chars (dest, altstr ? altstr : sp, + charstring_push_back_chars (trimmed, altstr ? altstr : sp, char_len, w); remaining -= w; altstr = NULL; } sp += char_len; #else - charstring_push_back (dest, *sp++); + charstring_push_back (trimmed, *sp++); remaining--; #endif } } - if (rjust) { - if (remaining > 0) { - /* copy string to the right */ - charstring_t copy = charstring_copy (dest); - - /* add padding at the beginning */ - charstring_clear (dest); - for (; remaining > 0; --remaining) { - charstring_push_back (dest, fill); - } - - charstring_append (dest, copy); + while (remaining-- > 0) { + charstring_push_back(dest, fill); + } - charstring_free (copy); - } - } else { - /* pad remaining space */ - while (remaining-- > 0) { - charstring_push_back (dest, fill); - } + if (rjust) { + charstring_append(dest, trimmed); + charstring_free(trimmed); } } @@ -268,16 +247,15 @@ cpstripped (charstring_t dest, size_t max, char *str) while (*str != '\0' && len > 0 && max > 0) { #ifdef MULTIBYTE_SUPPORT char_len = mbtowc(&wide_char, str, len); - w = wcwidth(wide_char); /* * If mbrtowc() failed, then we have a character that isn't valid - * in the current encoding. Replace it with a '?'. We do that by + * in the current encoding, or len wasn't enough for the whole + * multi-byte rune to be read. Replace it with a '?'. We do that by * setting the alstr variable to the value of the replacement string; * altstr is used below when the bytes are copied into the output * buffer. */ - if (char_len < 0) { altstr = "?"; char_len = mbtowc(&wide_char, altstr, 1); @@ -309,10 +287,21 @@ cpstripped (charstring_t dest, size_t max, char *str) prevCtrl = 0; #ifdef MULTIBYTE_SUPPORT - charstring_push_back_chars (dest, altstr ? altstr : str, char_len, w); - max -= w; - str += char_len; - altstr = NULL; + w = wcwidth(wide_char); + assert(w >= 0); + if (max >= (size_t) w) { + charstring_push_back_chars (dest, altstr ? altstr : str, char_len, w); + max -= w; + str += char_len; + altstr = NULL; + } else { + /* Not enough width available for the last character. Output + space(s) to fill. */ + while (max-- > 0) { + charstring_push_back (dest, ' '); + } + break; + } #else /* MULTIBYE_SUPPORT */ charstring_push_back (dest, *str++); --max; @@ -374,7 +363,7 @@ fmt_scan (struct format *format, charstring_t scanlp, int width, int *dat, { char *sp; char *savestr, *str; - char buffer[BUFSIZ], buffer2[BUFSIZ]; + char buffer[NMH_BUFSIZ], buffer2[NMH_BUFSIZ]; int i, c, rjust; int value; time_t t; @@ -482,7 +471,7 @@ fmt_scan (struct format *format, charstring_t scanlp, int width, int *dat, int num = value; unsigned int wid; - for (wid = num <= 0 ? 1 : 0; num; ++wid, num /= 10) {} + for (wid = num <= 0; num; ++wid, num /= 10) {} cpnumber (scanlp, value, wid, ' ', max - charstring_chars (scanlp)); break; @@ -751,13 +740,13 @@ fmt_scan (struct format *format, charstring_t scanlp, int width, int *dat, break; case FT_LV_DIVIDE_L: if (fmt->f_value) - value = value / fmt->f_value; + value /= fmt->f_value; else value = 0; break; case FT_LV_MODULO_L: if (fmt->f_value) - value = value % fmt->f_value; + value %= fmt->f_value; else value = 0; break; @@ -835,7 +824,7 @@ fmt_scan (struct format *format, charstring_t scanlp, int width, int *dat, } break; case FT_LV_ZONEF: - if ((fmt->f_comp->c_tws->tw_flags & TW_SZONE) == TW_SZEXP) + if (fmt->f_comp->c_tws->tw_flags & TW_SZEXP) value = 1; else value = -1; @@ -1185,5 +1174,5 @@ fmt_scan (struct format *format, charstring_t scanlp, int width, int *dat, } } - return ((struct format *)0); + return (NULL); }