Process glyph width for line length when truncating output - sacc - sacc(omys), simple console gopher client
git clone git://bitreich.org/sacc/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/sacc/
Log
Files
Refs
Tags
LICENSE
---
commit 13dd0464fab6950cbeee18b8ae6549d0f48723c7
parent f5d039f7156956e52161605fa71715a2d1d7c3c8
Author: Hiltjo Posthuma 
Date:   Fri,  9 Feb 2018 17:43:53 +0100

Process glyph width for line length when truncating output

Diffstat:
  M common.h                            |       1 +
  M sacc.c                              |      31 +++++++++++++++++++++++++++++++
  M ui_ti.c                             |      20 ++++++++++----------
  M ui_txt.c                            |      13 +++++++------

4 files changed, 49 insertions(+), 16 deletions(-)
---
diff --git a/common.h b/common.h
@@ -23,6 +23,7 @@ struct dir {
 };
 
 void die(const char *fmt, ...);
+size_t mbsprint(const char *s, size_t len);
 const char *typedisplay(char t);
 void uidisplay(Item *item);
 Item *uiselectitem(Item *entry);
diff --git a/sacc.c b/sacc.c
@@ -1,6 +1,7 @@
 /* See LICENSE file for copyright and license details. */
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -9,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -37,6 +39,34 @@ die(const char *fmt, ...)
         exit(1);
 }
 
+/* print `len' columns of characters. */
+size_t
+mbsprint(const char *s, size_t len)
+{
+        wchar_t wc;
+        size_t col = 0, i, slen;
+        int rl, w;
+
+        if (!len)
+                return col;
+
+        slen = strlen(s);
+        for (i = 0; i < slen; i += rl) {
+                if ((rl = mbtowc(&wc, s + i, slen - i < 4 ? slen - i : 4)) <= 0)
+                        break;
+                if ((w = wcwidth(wc)) == -1)
+                        continue;
+                if (col + w > len || (col + w == len && s[i + rl])) {
+                        fputs("\xe2\x80\xa6", stdout);
+                        col++;
+                        break;
+                }
+                fwrite(s + i, 1, rl, stdout);
+                col += w;
+        }
+        return col;
+}
+
 static void *
 xreallocarray(void *m, const size_t n, const size_t s)
 {
@@ -779,6 +809,7 @@ setup(void)
         struct sigaction sa;
         int fd;
 
+        setlocale(LC_CTYPE, "");
         setenv("PAGER", "more", 0);
         atexit(cleanup);
         /* reopen stdin in case we're reading from a pipe */
diff --git a/ui_ti.c b/ui_ti.c
@@ -65,11 +65,10 @@ uiprompt(char *fmt, ...)
         if (vsnprintf(bufout, sizeof(bufout), fmt, ap) >= sizeof(bufout))
                 bufout[sizeof(bufout)-1] = '\0';
         va_end(ap);
-        printf("%.*s", columns, bufout);
+        n = mbsprint(bufout, columns);
 
         putp(tparm(exit_standout_mode));
-
-        if ((n = strlen(bufout)) < columns)
+        if (n < columns)
                 printf("%*s", columns - n, " ");
 
         putp(tparm(cursor_address, lines-1, n));
@@ -102,7 +101,8 @@ printitem(Item *item)
         if (snprintf(bufout, sizeof(bufout), "%s %s", typedisplay(item->type),
             item->username) >= sizeof(bufout))
                 bufout[sizeof(bufout)-1] = '\0';
-        printf("%.*s\r", columns, bufout);
+        mbsprint(bufout, columns);
+        putchar('\r');
 }
 
 static Item *
@@ -154,9 +154,9 @@ uistatus(char *fmt, ...)
         if (n >= sizeof(bufout))
                 bufout[sizeof(bufout)-1] = '\0';
 
-        printf("%.*s", columns, bufout);
+        n = mbsprint(bufout, columns);
         putp(tparm(exit_standout_mode));
-        if ((n = strlen(bufout)) < columns)
+        if (n < columns)
                 printf("%*s", columns - n, " ");
 
         putp(tparm(restore_cursor));
@@ -185,9 +185,9 @@ displaystatus(Item *item)
                      item->host, item->type, item->selector, item->port)
             >= sizeof(bufout))
                 bufout[sizeof(bufout)-1] = '\0';
-        printf("%.*s", columns, bufout);
+        n = mbsprint(bufout, columns);
         putp(tparm(exit_standout_mode));
-        if ((n = strlen(bufout)) < columns)
+        if (n < columns)
                 printf("%*s", columns - n, " ");
 
         putp(tparm(restore_cursor));
@@ -225,9 +225,9 @@ displayuri(Item *item)
         if (n >= sizeof(bufout))
                 bufout[sizeof(bufout)-1] = '\0';
 
-        printf("%.*s", columns, bufout);
+        n = mbsprint(bufout, columns);
         putp(tparm(exit_standout_mode));
-        if ((n = strlen(bufout)) < columns)
+        if (n < columns)
                 printf("%*s", columns - n, " ");
 
         putp(tparm(restore_cursor));
diff --git a/ui_txt.c b/ui_txt.c
@@ -83,7 +83,7 @@ uistatus(char *fmt, ...)
         if (n >= sizeof(bufout))
                 bufout[sizeof(bufout)-1] = '\0';
 
-        printf("%.*s", columns, bufout);
+        mbsprint(bufout, columns);
         fflush(stdout);
 
         getchar();
@@ -106,7 +106,7 @@ printstatus(Item *item, char c)
                      item->host, item->type, item->selector, c, item->port)
             >= sizeof(bufout))
                 bufout[sizeof(bufout)-1] = '\0';
-        printf("%.*s", columns, bufout);
+        mbsprint(bufout, columns);
 }
 
 char *
@@ -122,8 +122,7 @@ uiprompt(char *fmt, ...)
                 bufout[sizeof(bufout)-1] = '\0';
         va_end(ap);
 
-        printf("%.*s", columns, bufout);
-
+        mbsprint(bufout, columns);
         fflush(stdout);
 
         if ((r = getline(&input, &n, stdin)) < 0) {
@@ -163,7 +162,8 @@ uidisplay(Item *entry)
                              items[i].username)
                     >= sizeof(bufout))
                         bufout[sizeof(bufout)-1] = '\0';
-                printf("%.*s\n", columns, bufout);
+                mbsprint(bufout, columns);
+                putchar('\n');
         }
 
         fflush(stdout);
@@ -201,7 +201,8 @@ printuri(Item *item, size_t i)
         if (n >= sizeof(bufout))
                 bufout[sizeof(bufout)-1] = '\0';
 
-        printf("%.*s\n", columns, bufout);
+        mbsprint(bufout, columns);
+        putchar('\n');
 }
 
 void