| @@ -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 */ |
| @@ -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)); |
| @@ -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 |