improve printutf8pad - stagit-gopher - A git gopher frontend. (mirror)
git clone git://bitreich.org/stagit-gopher/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/stagit-gopher/
Log
Files
Refs
Tags
README
LICENSE
---
commit 22d8f0453a32ca7e9cc13382170fc38234597a88
parent 33f9c2a548fa4d2b31c66530ea1d14f852573187
Author: Hiltjo Posthuma 
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(-)
---
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);
 }
 
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);
 }