improve printutf8pad - stagit-gopher - A git gopher frontend. (mirror)
 (HTM) git clone git://bitreich.org/stagit-gopher/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/stagit-gopher/
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Tags
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 22d8f0453a32ca7e9cc13382170fc38234597a88
 (DIR) parent 33f9c2a548fa4d2b31c66530ea1d14f852573187
 (HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
       Date:   Fri, 23 Jun 2017 12:26:28 +0200
       
       improve printutf8pad
       
       correct truncation and count of utf-8 runes using mbtowc
       
       Diffstat:
         M stagit-gopher-index.c               |      34 ++++++++++++++++----------------
         M stagit-gopher.c                     |      35 +++++++++++++++----------------
       
       2 files changed, 34 insertions(+), 35 deletions(-)
       ---
 (DIR) diff --git a/stagit-gopher-index.c b/stagit-gopher-index.c
       @@ -25,32 +25,32 @@ static char *name = "";
        #define pledge(p1,p2) 0
        #endif
        
       -#define ISUTF8(c) (((c) & 0xc0) != 0x80)
       -
        /* print `len' columns of characters. If string is shorter pad the rest
         * with characters `pad`. */
        void
        printutf8pad(FILE *fp, const char *s, size_t len, int pad)
        {
                wchar_t w;
       -        size_t n = 0, i;
       -        int r;
       +        size_t col = 0, i, slen;
       +        int rl, wc;
       +
       +        if (!len)
       +                return;
        
       -        for (i = 0; *s && n < len; i++, s++) {
       -                if (ISUTF8(*s)) {
       -                        if ((r = mbtowc(&w, s, 4)) == -1)
       -                                break;
       -                        if ((r = wcwidth(w)) == -1)
       -                                r = 1;
       -                        n += (size_t)r;
       -                        if (n >= len) {
       -                                fputs("\xe2\x80\xa6", fp);
       -                                break;
       -                        }
       +        slen = strlen(s);
       +        for (i = 0; i < slen && col < len + 1; i += rl) {
       +                if ((rl = mbtowc(&w, &s[i], slen - i < 4 ? slen - i : 4)) <= 0)
       +                        break;
       +                if ((wc = wcwidth(w)) == -1)
       +                        wc = 1;
       +                col += (size_t)wc;
       +                if (col >= len && s[i + rl]) {
       +                        fputs("\xe2\x80\xa6", fp);
       +                        break;
                        }
       -                putc(*s, fp);
       +                fwrite(&s[i], 1, rl, fp);
                }
       -        for (; n < len; n++)
       +        for (; col < len; col++)
                        putc(pad, fp);
        }
        
 (DIR) diff --git a/stagit-gopher.c b/stagit-gopher.c
       @@ -68,33 +68,32 @@ static const char *cachefile;
        #define pledge(p1,p2) 0
        #endif
        
       -#define ISUTF8(c) (((c) & 0xc0) != 0x80)
       -
        /* print `len' columns of characters. If string is shorter pad the rest
         * with characters `pad`. */
        void
        printutf8pad(FILE *fp, const char *s, size_t len, int pad)
        {
                wchar_t w;
       -        size_t n = 0, i;
       -        int r;
       +        size_t col = 0, i, slen;
       +        int rl, wc;
        
       -        for (i = 0; *s && n < len; i++, s++) {
       -                if (ISUTF8(*s)) {
       -                        if (mbtowc(&w, s, 4) == -1)
       -                                break;
       -                        if ((r = wcwidth(w)) == -1)
       -                                r = 1;
       -                        n += (size_t)r;
       -                        if (n >= len) {
       -                                fputs("\xe2\x80\xa6", fp);
       -                                break;
       -                        }
       +        if (!len)
       +                return;
       +
       +        slen = strlen(s);
       +        for (i = 0; i < slen && col < len + 1; i += rl) {
       +                if ((rl = mbtowc(&w, &s[i], slen - i < 4 ? slen - i : 4)) <= 0)
       +                        break;
       +                if ((wc = wcwidth(w)) == -1)
       +                        wc = 1;
       +                col += (size_t)wc;
       +                if (col >= len && s[i + rl]) {
       +                        fputs("\xe2\x80\xa6", fp);
       +                        break;
                        }
       -                putc(*s, fp);
       +                fwrite(&s[i], 1, rl, fp);
                }
       -
       -        for (; n < len; n++)
       +        for (; col < len; col++)
                        putc(pad, fp);
        }