fix truncation and padding for lines containing multiwidth glyphs - 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 e32410fe7894b741e141248a5e256f1e93e59fab
parent c1b5e802f0d0c349faf8d4e6b6988dcfdc574488
Author: Hiltjo Posthuma 
Date:   Sun,  1 Apr 2018 15:09:43 +0200

fix truncation and padding for lines containing multiwidth glyphs

Diffstat:
  M stagit-gopher.c                     |      22 +++++++++++++---------

1 file changed, 13 insertions(+), 9 deletions(-)
---
diff --git a/stagit-gopher.c b/stagit-gopher.c
@@ -76,29 +76,33 @@ static const char *cachefile;
 int
 utf8pad(char *buf, size_t bufsiz, const char *s, size_t len, int pad)
 {
-        wchar_t w;
+        wchar_t wc;
         size_t col = 0, i, slen, siz = 0;
-        int rl, wc;
+        int rl, w;
 
         if (!len)
                 return -1;
 
         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)
+        for (i = 0; i < slen; i += rl) {
+                if ((rl = mbtowc(&wc, &s[i], slen - i < 4 ? slen - i : 4)) <= 0)
                         break;
-                if ((wc = wcwidth(w)) == -1)
-                        wc = 1;
-                col += wc;
-                if (col >= len && s[i + rl]) {
+                if ((w = wcwidth(wc)) == -1)
+                        continue;
+                if (col + w > len || (col + w == len && s[i + rl])) {
                         if (siz + 4 >= bufsiz)
                                 return -1;
-                        memcpy(&buf[siz], "\xe2\x80\xa6", 4);
+                        memcpy(&buf[siz], "\xe2\x80\xa6", 3);
+                        siz += 3;
+                        if (col + w == len && w > 1)
+                                buf[siz++] = pad;
+                        buf[siz] = '\0';
                         return 0;
                 }
                 if (siz + rl + 1 >= bufsiz)
                         return -1;
                 memcpy(&buf[siz], &s[i], rl);
+                col += w;
                 siz += rl;
                 buf[siz] = '\0';
         }