diff --git a/input-keys.c b/input-keys.c index f8d72124..1e2af6d1 100644 --- a/input-keys.c +++ b/input-keys.c @@ -168,7 +168,7 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m) return; } if (key != KEYC_NONE && justkey > 0x7f && justkey < KEYC_BASE) { - if (utf8_split(justkey, &ud) != 0) + if (utf8_split(justkey, &ud) != UTF8_DONE) return; if (key & KEYC_ESCAPE) bufferevent_write(wp->event, "\033", 1); diff --git a/input.c b/input.c index cb92e52f..f7b4e460 100644 --- a/input.c +++ b/input.c @@ -1923,7 +1923,7 @@ input_utf8_open(struct input_ctx *ictx) { struct utf8_data *ud = &ictx->utf8data; - if (!utf8_open(ud, ictx->ch)) + if (utf8_open(ud, ictx->ch) != UTF8_MORE) log_fatalx("UTF-8 open invalid %#hhx", ictx->ch); log_debug("%s %hhu", __func__, ud->size); @@ -1937,7 +1937,7 @@ input_utf8_add(struct input_ctx *ictx) { struct utf8_data *ud = &ictx->utf8data; - if (utf8_append(ud, ictx->ch) != 1) + if (utf8_append(ud, ictx->ch) != UTF8_MORE) log_fatalx("UTF-8 add invalid %#hhx", ictx->ch); log_debug("%s", __func__); @@ -1951,7 +1951,7 @@ input_utf8_close(struct input_ctx *ictx) { struct utf8_data *ud = &ictx->utf8data; - if (utf8_append(ud, ictx->ch) != 0) + if (utf8_append(ud, ictx->ch) != UTF8_DONE) log_fatalx("UTF-8 close invalid %#hhx", ictx->ch); log_debug("%s %hhu '%*s' (width %hhu)", __func__, ud->size, diff --git a/key-string.c b/key-string.c index ad7cbf50..9a44892d 100644 --- a/key-string.c +++ b/key-string.c @@ -144,10 +144,11 @@ key_string_lookup_string(const char *string) static const char *other = "!#()+,-.0123456789:;<=>?'\r\t"; key_code key; u_short u; - int size, more; + int size; key_code modifiers; struct utf8_data ud; u_int i; + enum utf8_state more; /* Is this a hexadecimal value? */ if (string[0] == '0' && string[1] == 'x') { @@ -173,13 +174,12 @@ key_string_lookup_string(const char *string) return (KEYC_NONE); } else { /* Try as a UTF-8 key. */ - if (utf8_open(&ud, (u_char)*string)) { + if ((more = utf8_open(&ud, (u_char)*string)) == UTF8_MORE) { if (strlen(string) != ud.size) return (KEYC_NONE); - more = 1; for (i = 1; i < ud.size; i++) more = utf8_append(&ud, (u_char)string[i]); - if (more != 0) + if (more != UTF8_DONE) return (KEYC_NONE); key = utf8_combine(&ud); return (key | modifiers); @@ -256,7 +256,7 @@ key_string_lookup_key(key_code key) /* Is this a UTF-8 key? */ if (key > 127 && key < KEYC_BASE) { - if (utf8_split(key, &ud) == 0) { + if (utf8_split(key, &ud) == UTF8_DONE) { memcpy(out, ud.data, ud.size); out[ud.size] = '\0'; return (out); diff --git a/screen-write.c b/screen-write.c index 9e1ef822..a887b0f1 100644 --- a/screen-write.c +++ b/screen-write.c @@ -115,7 +115,7 @@ screen_write_strlen(const char *fmt, ...) struct utf8_data ud; u_char *ptr; size_t left, size = 0; - int more; + enum utf8_state more; va_start(ap, fmt); xvasprintf(&msg, fmt, ap); @@ -123,17 +123,17 @@ screen_write_strlen(const char *fmt, ...) ptr = msg; while (*ptr != '\0') { - if (*ptr > 0x7f && utf8_open(&ud, *ptr)) { + if (*ptr > 0x7f && utf8_open(&ud, *ptr) == UTF8_MORE) { ptr++; left = strlen(ptr); if (left < (size_t)ud.size - 1) break; - while ((more = utf8_append(&ud, *ptr)) == 1) + while ((more = utf8_append(&ud, *ptr)) == UTF8_MORE) ptr++; ptr++; - if (more == 0) + if (more == UTF8_DONE) size += ud.width; } else { if (*ptr > 0x1f && *ptr < 0x7f) @@ -178,23 +178,23 @@ screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen, struct utf8_data ud; u_char *ptr; size_t left, size = 0; - int more; + enum utf8_state more; xvasprintf(&msg, fmt, ap); ptr = msg; while (*ptr != '\0') { - if (*ptr > 0x7f && utf8_open(&ud, *ptr)) { + if (*ptr > 0x7f && utf8_open(&ud, *ptr) == UTF8_MORE) { ptr++; left = strlen(ptr); if (left < (size_t)ud.size - 1) break; - while ((more = utf8_append(&ud, *ptr)) == 1) + while ((more = utf8_append(&ud, *ptr)) == UTF8_MORE) ptr++; ptr++; - if (more == 0) { + if (more == UTF8_DONE) { if (maxlen > 0 && size + ud.width > (size_t) maxlen) { while (size < (size_t) maxlen) { @@ -236,7 +236,7 @@ screen_write_cnputs(struct screen_write_ctx *ctx, ssize_t maxlen, char *msg; u_char *ptr, *last; size_t left, size = 0; - int more; + enum utf8_state more; va_start(ap, fmt); xvasprintf(&msg, fmt, ap); @@ -260,17 +260,17 @@ screen_write_cnputs(struct screen_write_ctx *ctx, ssize_t maxlen, continue; } - if (*ptr > 0x7f && utf8_open(&ud, *ptr)) { + if (*ptr > 0x7f && utf8_open(&ud, *ptr) == UTF8_MORE) { ptr++; left = strlen(ptr); if (left < (size_t)ud.size - 1) break; - while ((more = utf8_append(&ud, *ptr)) == 1) + while ((more = utf8_append(&ud, *ptr)) == UTF8_MORE) ptr++; ptr++; - if (more == 0) { + if (more == UTF8_DONE) { if (maxlen > 0 && size + ud.width > (size_t) maxlen) { while (size < (size_t) maxlen) { diff --git a/tmux.h b/tmux.h index 703dd440..f259e6f6 100644 --- a/tmux.h +++ b/tmux.h @@ -629,6 +629,11 @@ struct utf8_data { u_char width; /* 0xff if invalid */ } __packed; +enum utf8_state { + UTF8_MORE, + UTF8_DONE, + UTF8_ERROR +}; /* Grid attributes. */ #define GRID_ATTR_BRIGHT 0x1 @@ -2194,10 +2199,10 @@ void session_renumber_windows(struct session *); u_int utf8_width(u_int); void utf8_set(struct utf8_data *, u_char); void utf8_copy(struct utf8_data *, const struct utf8_data *); -int utf8_open(struct utf8_data *, u_char); -int utf8_append(struct utf8_data *, u_char); +enum utf8_state utf8_open(struct utf8_data *, u_char); +enum utf8_state utf8_append(struct utf8_data *, u_char); u_int utf8_combine(const struct utf8_data *); -int utf8_split(u_int, struct utf8_data *); +enum utf8_state utf8_split(u_int, struct utf8_data *); u_int utf8_split2(u_int, u_char *); int utf8_strvis(char *, const char *, size_t, int); char *utf8_sanitize(const char *); diff --git a/tty-keys.c b/tty-keys.c index cc6b934a..52dae4f7 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -472,9 +472,10 @@ tty_keys_next(struct tty *tty) const char *buf; size_t len, size; cc_t bspace; - int delay, expired = 0, more; + int delay, expired = 0; key_code key; struct utf8_data ud; + enum utf8_state more; u_int i; /* Get key buffer. */ @@ -539,17 +540,16 @@ first_key: } /* Is this valid UTF-8? */ - if (utf8_open(&ud, (u_char)*buf)) { + if ((more = utf8_open(&ud, (u_char)*buf) == UTF8_MORE)) { size = ud.size; if (len < size) { if (expired) goto discard_key; goto partial_key; } - more = 1; for (i = 1; i < size; i++) more = utf8_append(&ud, (u_char)buf[i]); - if (more != 0) + if (more != UTF8_DONE) goto discard_key; key = utf8_combine(&ud); log_debug("UTF-8 key %.*s %#llx", (int)size, buf, key); @@ -656,7 +656,7 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size) struct utf8_data ud; u_int i, value, x, y, b, sgr_b; u_char sgr_type, c; - int more; + enum utf8_state more; /* * Standard mouse sequences are \033[M followed by three characters @@ -697,14 +697,14 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size) return (1); if (tty->mode & MODE_MOUSE_UTF8) { - if (utf8_open(&ud, buf[*size])) { + if (utf8_open(&ud, buf[*size]) == UTF8_MORE) { if (ud.size != 2) return (-1); (*size)++; if (len <= *size) return (1); more = utf8_append(&ud, buf[*size]); - if (more != 0) + if (more != UTF8_DONE) return (-1); value = utf8_combine(&ud); } else diff --git a/utf8.c b/utf8.c index b5999dad..84322a9b 100644 --- a/utf8.c +++ b/utf8.c @@ -380,10 +380,8 @@ utf8_copy(struct utf8_data *to, const struct utf8_data *from) * 11000010-11011111 C2-DF start of 2-byte sequence * 11100000-11101111 E0-EF start of 3-byte sequence * 11110000-11110100 F0-F4 start of 4-byte sequence - * - * Returns 1 if more UTF-8 to come, 0 if not UTF-8. */ -int +enum utf8_state utf8_open(struct utf8_data *ud, u_char ch) { memset(ud, 0, sizeof *ud); @@ -394,18 +392,13 @@ utf8_open(struct utf8_data *ud, u_char ch) else if (ch >= 0xf0 && ch <= 0xf4) ud->size = 4; else - return (0); + return (UTF8_ERROR); utf8_append(ud, ch); - return (1); + return (UTF8_MORE); } -/* - * Append character to UTF-8, closing if finished. - * - * Returns 1 if more UTF-8 data to come, 0 if finished and valid, -1 if - * finished and invalid. - */ -int +/* Append character to UTF-8, closing if finished. */ +enum utf8_state utf8_append(struct utf8_data *ud, u_char ch) { if (ud->have >= ud->size) @@ -418,12 +411,12 @@ utf8_append(struct utf8_data *ud, u_char ch) ud->data[ud->have++] = ch; if (ud->have != ud->size) - return (1); + return (UTF8_MORE); if (ud->width == 0xff) - return (-1); + return (UTF8_ERROR); ud->width = utf8_width(utf8_combine(ud)); - return (0); + return (UTF8_DONE); } /* Build UTF-8 width tree. */ @@ -473,34 +466,34 @@ utf8_width(u_int uc) u_int utf8_combine(const struct utf8_data *ud) { - u_int value; + u_int uc; - value = 0xff; + uc = 0xfffd; switch (ud->size) { case 1: - value = ud->data[0]; + uc = ud->data[0]; break; case 2: - value = ud->data[1] & 0x3f; - value |= (ud->data[0] & 0x1f) << 6; + uc = ud->data[1] & 0x3f; + uc |= (ud->data[0] & 0x1f) << 6; break; case 3: - value = ud->data[2] & 0x3f; - value |= (ud->data[1] & 0x3f) << 6; - value |= (ud->data[0] & 0xf) << 12; + uc = ud->data[2] & 0x3f; + uc |= (ud->data[1] & 0x3f) << 6; + uc |= (ud->data[0] & 0xf) << 12; break; case 4: - value = ud->data[3] & 0x3f; - value |= (ud->data[2] & 0x3f) << 6; - value |= (ud->data[1] & 0x3f) << 12; - value |= (ud->data[0] & 0x7) << 18; + uc = ud->data[3] & 0x3f; + uc |= (ud->data[2] & 0x3f) << 6; + uc |= (ud->data[1] & 0x3f) << 12; + uc |= (ud->data[0] & 0x7) << 18; break; } - return (value); + return (uc); } /* Split 32-bit Unicode into UTF-8. */ -int +enum utf8_state utf8_split(u_int uc, struct utf8_data *ud) { if (uc < 0x7f) { @@ -522,9 +515,9 @@ utf8_split(u_int uc, struct utf8_data *ud) ud->data[2] = 0x80 | ((uc >> 6) & 0x3f); ud->data[3] = 0x80 | (uc & 0x3f); } else - return (-1); + return (UTF8_ERROR); ud->width = utf8_width(uc); - return (0); + return (UTF8_DONE); } /* Split a two-byte UTF-8 character. */ @@ -550,26 +543,24 @@ utf8_strvis(char *dst, const char *src, size_t len, int flag) { struct utf8_data ud; const char *start, *end; - int more; + enum utf8_state more; size_t i; start = dst; end = src + len; while (src < end) { - if (utf8_open(&ud, *src)) { - more = 1; - while (++src < end && more == 1) + if ((more = utf8_open(&ud, *src)) == UTF8_MORE) { + while (++src < end && more == UTF8_MORE) more = utf8_append(&ud, *src); - if (more == 0) { + if (more == UTF8_DONE) { /* UTF-8 character finished. */ for (i = 0; i < ud.size; i++) *dst++ = ud.data[i]; continue; - } else if (ud.have > 0) { - /* Not a complete, valid UTF-8 character. */ - src -= ud.have; } + /* Not a complete, valid UTF-8 character. */ + src -= ud.have; } if (src < end - 1) dst = vis(dst, src[0], flag, src[1]); @@ -592,7 +583,7 @@ utf8_sanitize(const char *src) { char *dst; size_t n; - int more; + enum utf8_state more; struct utf8_data ud; u_int i; @@ -601,11 +592,10 @@ utf8_sanitize(const char *src) n = 0; while (*src != '\0') { dst = xreallocarray(dst, n + 1, sizeof *dst); - if (utf8_open(&ud, *src)) { - more = 1; - while (*++src != '\0' && more == 1) + if ((more = utf8_open(&ud, *src)) == UTF8_MORE) { + while (*++src != '\0' && more == UTF8_MORE) more = utf8_append(&ud, *src); - if (more != 1) { + if (more == UTF8_DONE) { dst = xreallocarray(dst, n + ud.width, sizeof *dst); for (i = 0; i < ud.width; i++) @@ -616,6 +606,8 @@ utf8_sanitize(const char *src) } if (*src > 0x1f && *src < 0x7f) dst[n++] = *src; + else + dst[n++] = '_'; src++; } @@ -633,27 +625,24 @@ utf8_fromcstr(const char *src) { struct utf8_data *dst; size_t n; - int more; + enum utf8_state more; dst = NULL; n = 0; while (*src != '\0') { dst = xreallocarray(dst, n + 1, sizeof *dst); - if (utf8_open(&dst[n], *src)) { - more = 1; - while (*++src != '\0' && more == 1) + if ((more = utf8_open(&dst[n], *src)) == UTF8_MORE) { + while (*++src != '\0' && more == UTF8_MORE) more = utf8_append(&dst[n], *src); - if (more != 1) { + if (more == UTF8_DONE) { n++; continue; } src -= dst[n].have; } - if (*src > 0x1f && *src < 0x7f) { - utf8_set(&dst[n], *src); - n++; - } + utf8_set(&dst[n], *src); + n++; src++; } @@ -689,21 +678,20 @@ utf8_cstrwidth(const char *s) { struct utf8_data tmp; u_int width; - int more; + enum utf8_state more; width = 0; while (*s != '\0') { - if (utf8_open(&tmp, *s)) { - more = 1; - while (*++s != '\0' && more == 1) + if ((more = utf8_open(&tmp, *s)) == UTF8_MORE) { + while (*++s != '\0' && more == UTF8_MORE) more = utf8_append(&tmp, *s); - if (more != 1) { + if (more == UTF8_DONE) { width += tmp.width; continue; } s -= tmp.have; } - if (*s > 0x1f && *s < 0x7f) + if (*s > 0x1f && *s != 0x7f) width++; s++; }