Process glyph width for line length when truncating output - sacc - sacc(omys),… | |
git clone git://bitreich.org/sacc/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65… | |
Log | |
Files | |
Refs | |
Tags | |
LICENSE | |
--- | |
commit 13dd0464fab6950cbeee18b8ae6549d0f48723c7 | |
parent f5d039f7156956e52161605fa71715a2d1d7c3c8 | |
Author: Hiltjo Posthuma <[email protected]> | |
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 <errno.h> | |
#include <fcntl.h> | |
+#include <locale.h> | |
#include <netdb.h> | |
#include <netinet/in.h> | |
#include <signal.h> | |
@@ -9,6 +10,7 @@ | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
+#include <wchar.h> | |
#include <sys/socket.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
@@ -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)) <= … | |
+ 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 |