From: c_14 Date: Tue, 16 May 2017 16:13:27 +0000 (+0200) Subject: fmt_scan: support multibyte characters in putstr decoding X-Git-Tag: mmh-0.4~37 X-Git-Url: http://git.marmaro.de/?a=commitdiff_plain;h=95f7880a49b3eb5d1d4f5a966c291d91aeca3c41;p=mmh fmt_scan: support multibyte characters in putstr decoding Fixes an issue where the string output by scan with a putstr format is truncated within a multibyte character causing terminal corruption --- diff --git a/sbr/fmt_scan.c b/sbr/fmt_scan.c index 2485e6c..d0b112b 100644 --- a/sbr/fmt_scan.c +++ b/sbr/fmt_scan.c @@ -188,17 +188,48 @@ cptrimmed(char **dest, char *str, unsigned int wid, char fill, size_t n) { static void cpstripped(char **start, char *end, char *str) { +#ifdef MULTIBYTE_SUPPORT + int char_len; /* bytes in current character */ + int nbytes; + wchar_t wide_char; +#else int c; +#endif char *s = str; if (!s) return; /* skip any initial control characters or spaces */ +#ifdef MULTIBYTE_SUPPORT + nbytes = end - *start + 1; + mbtowc(NULL, NULL, 0); /* reset shift state */ + while ((char_len = mbtowc(&wide_char, s, nbytes)) > 0 && (iswcntrl(wide_char) || iswspace(wide_char))) { + s += char_len; + nbytes -= char_len; + } +#else while ((c = (unsigned char) *s) && (iscntrl(c) || isspace(c))) s++; +#endif /* compact repeated control characters and spaces into a single space */ +#ifdef MULTIBYTE_SUPPORT + while ((char_len = mbtowc(&wide_char, s, nbytes)) > 0 && *start < end) { + if (!iswcntrl(wide_char) && !iswspace(wide_char)) { + strncpy(*start, s, char_len); + s += char_len; + *start += char_len; + nbytes -= char_len; + } else { + while ((char_len = mbtowc(&wide_char, s, nbytes)) > 0 && (iswcntrl(wide_char) || iswspace(wide_char))) { + s += char_len; + nbytes -= char_len; + } + *(*start)++ = ' '; + } + } +#else while((c = (unsigned char) *s++) && *start < end) if (!iscntrl(c) && !isspace(c)) *(*start)++ = c; @@ -208,6 +239,7 @@ cpstripped(char **start, char *end, char *str) s++; *(*start)++ = ' '; } +#endif } static char *lmonth[] = {