All these return values from utf8_* are confusing, use an enum.

This commit is contained in:
nicm 2015-11-14 11:45:43 +00:00
parent f401791a56
commit 205d15e82d
7 changed files with 70 additions and 77 deletions

View File

@ -169,7 +169,7 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
return; return;
} }
if (key != KEYC_NONE && justkey > 0x7f && justkey < KEYC_BASE) { if (key != KEYC_NONE && justkey > 0x7f && justkey < KEYC_BASE) {
if (utf8_split(justkey, &ud) != 0) if (utf8_split(justkey, &ud) != UTF8_DONE)
return; return;
if (key & KEYC_ESCAPE) if (key & KEYC_ESCAPE)
bufferevent_write(wp->event, "\033", 1); bufferevent_write(wp->event, "\033", 1);

View File

@ -1923,7 +1923,7 @@ input_utf8_open(struct input_ctx *ictx)
{ {
struct utf8_data *ud = &ictx->utf8data; 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_fatalx("UTF-8 open invalid %#hhx", ictx->ch);
log_debug("%s %hhu", __func__, ud->size); log_debug("%s %hhu", __func__, ud->size);
@ -1937,7 +1937,7 @@ input_utf8_add(struct input_ctx *ictx)
{ {
struct utf8_data *ud = &ictx->utf8data; 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_fatalx("UTF-8 add invalid %#hhx", ictx->ch);
log_debug("%s", __func__); log_debug("%s", __func__);
@ -1951,7 +1951,7 @@ input_utf8_close(struct input_ctx *ictx)
{ {
struct utf8_data *ud = &ictx->utf8data; 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_fatalx("UTF-8 close invalid %#hhx", ictx->ch);
log_debug("%s %hhu '%*s' (width %hhu)", __func__, ud->size, log_debug("%s %hhu '%*s' (width %hhu)", __func__, ud->size,

View File

@ -144,10 +144,11 @@ key_string_lookup_string(const char *string)
static const char *other = "!#()+,-.0123456789:;<=>?'\r\t"; static const char *other = "!#()+,-.0123456789:;<=>?'\r\t";
key_code key; key_code key;
u_short u; u_short u;
int size, more; int size;
key_code modifiers; key_code modifiers;
struct utf8_data ud; struct utf8_data ud;
u_int i; u_int i;
enum utf8_state more;
/* Is this a hexadecimal value? */ /* Is this a hexadecimal value? */
if (string[0] == '0' && string[1] == 'x') { if (string[0] == '0' && string[1] == 'x') {
@ -173,13 +174,12 @@ key_string_lookup_string(const char *string)
return (KEYC_NONE); return (KEYC_NONE);
} else { } else {
/* Try as a UTF-8 key. */ /* 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) if (strlen(string) != ud.size)
return (KEYC_NONE); return (KEYC_NONE);
more = 1;
for (i = 1; i < ud.size; i++) for (i = 1; i < ud.size; i++)
more = utf8_append(&ud, (u_char)string[i]); more = utf8_append(&ud, (u_char)string[i]);
if (more != 0) if (more != UTF8_DONE)
return (KEYC_NONE); return (KEYC_NONE);
key = utf8_combine(&ud); key = utf8_combine(&ud);
return (key | modifiers); return (key | modifiers);
@ -256,7 +256,7 @@ key_string_lookup_key(key_code key)
/* Is this a UTF-8 key? */ /* Is this a UTF-8 key? */
if (key > 127 && key < KEYC_BASE) { 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); memcpy(out, ud.data, ud.size);
out[ud.size] = '\0'; out[ud.size] = '\0';
return (out); return (out);

View File

@ -115,7 +115,7 @@ screen_write_strlen(const char *fmt, ...)
struct utf8_data ud; struct utf8_data ud;
u_char *ptr; u_char *ptr;
size_t left, size = 0; size_t left, size = 0;
int more; enum utf8_state more;
va_start(ap, fmt); va_start(ap, fmt);
xvasprintf(&msg, fmt, ap); xvasprintf(&msg, fmt, ap);
@ -123,17 +123,17 @@ screen_write_strlen(const char *fmt, ...)
ptr = msg; ptr = msg;
while (*ptr != '\0') { while (*ptr != '\0') {
if (*ptr > 0x7f && utf8_open(&ud, *ptr)) { if (*ptr > 0x7f && utf8_open(&ud, *ptr) == UTF8_MORE) {
ptr++; ptr++;
left = strlen(ptr); left = strlen(ptr);
if (left < (size_t)ud.size - 1) if (left < (size_t)ud.size - 1)
break; break;
while ((more = utf8_append(&ud, *ptr)) == 1) while ((more = utf8_append(&ud, *ptr)) == UTF8_MORE)
ptr++; ptr++;
ptr++; ptr++;
if (more == 0) if (more == UTF8_DONE)
size += ud.width; size += ud.width;
} else { } else {
if (*ptr > 0x1f && *ptr < 0x7f) if (*ptr > 0x1f && *ptr < 0x7f)
@ -178,23 +178,23 @@ screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
struct utf8_data ud; struct utf8_data ud;
u_char *ptr; u_char *ptr;
size_t left, size = 0; size_t left, size = 0;
int more; enum utf8_state more;
xvasprintf(&msg, fmt, ap); xvasprintf(&msg, fmt, ap);
ptr = msg; ptr = msg;
while (*ptr != '\0') { while (*ptr != '\0') {
if (*ptr > 0x7f && utf8_open(&ud, *ptr)) { if (*ptr > 0x7f && utf8_open(&ud, *ptr) == UTF8_MORE) {
ptr++; ptr++;
left = strlen(ptr); left = strlen(ptr);
if (left < (size_t)ud.size - 1) if (left < (size_t)ud.size - 1)
break; break;
while ((more = utf8_append(&ud, *ptr)) == 1) while ((more = utf8_append(&ud, *ptr)) == UTF8_MORE)
ptr++; ptr++;
ptr++; ptr++;
if (more == 0) { if (more == UTF8_DONE) {
if (maxlen > 0 && if (maxlen > 0 &&
size + ud.width > (size_t) maxlen) { size + ud.width > (size_t) maxlen) {
while (size < (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; char *msg;
u_char *ptr, *last; u_char *ptr, *last;
size_t left, size = 0; size_t left, size = 0;
int more; enum utf8_state more;
va_start(ap, fmt); va_start(ap, fmt);
xvasprintf(&msg, fmt, ap); xvasprintf(&msg, fmt, ap);
@ -260,17 +260,17 @@ screen_write_cnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
continue; continue;
} }
if (*ptr > 0x7f && utf8_open(&ud, *ptr)) { if (*ptr > 0x7f && utf8_open(&ud, *ptr) == UTF8_MORE) {
ptr++; ptr++;
left = strlen(ptr); left = strlen(ptr);
if (left < (size_t)ud.size - 1) if (left < (size_t)ud.size - 1)
break; break;
while ((more = utf8_append(&ud, *ptr)) == 1) while ((more = utf8_append(&ud, *ptr)) == UTF8_MORE)
ptr++; ptr++;
ptr++; ptr++;
if (more == 0) { if (more == UTF8_DONE) {
if (maxlen > 0 && if (maxlen > 0 &&
size + ud.width > (size_t) maxlen) { size + ud.width > (size_t) maxlen) {
while (size < (size_t) maxlen) { while (size < (size_t) maxlen) {

11
tmux.h
View File

@ -626,6 +626,11 @@ struct utf8_data {
u_char width; /* 0xff if invalid */ u_char width; /* 0xff if invalid */
} __packed; } __packed;
enum utf8_state {
UTF8_MORE,
UTF8_DONE,
UTF8_ERROR
};
/* Grid attributes. */ /* Grid attributes. */
#define GRID_ATTR_BRIGHT 0x1 #define GRID_ATTR_BRIGHT 0x1
@ -2191,10 +2196,10 @@ void session_renumber_windows(struct session *);
u_int utf8_width(u_int); u_int utf8_width(u_int);
void utf8_set(struct utf8_data *, u_char); void utf8_set(struct utf8_data *, u_char);
void utf8_copy(struct utf8_data *, const struct utf8_data *); void utf8_copy(struct utf8_data *, const struct utf8_data *);
int utf8_open(struct utf8_data *, u_char); enum utf8_state utf8_open(struct utf8_data *, u_char);
int utf8_append(struct utf8_data *, u_char); enum utf8_state utf8_append(struct utf8_data *, u_char);
u_int utf8_combine(const struct utf8_data *); 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 *); u_int utf8_split2(u_int, u_char *);
int utf8_strvis(char *, const char *, size_t, int); int utf8_strvis(char *, const char *, size_t, int);
char *utf8_sanitize(const char *); char *utf8_sanitize(const char *);

View File

@ -472,9 +472,10 @@ tty_keys_next(struct tty *tty)
const char *buf; const char *buf;
size_t len, size; size_t len, size;
cc_t bspace; cc_t bspace;
int delay, expired = 0, more; int delay, expired = 0;
key_code key; key_code key;
struct utf8_data ud; struct utf8_data ud;
enum utf8_state more;
u_int i; u_int i;
/* Get key buffer. */ /* Get key buffer. */
@ -539,17 +540,16 @@ first_key:
} }
/* Is this valid UTF-8? */ /* 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; size = ud.size;
if (len < size) { if (len < size) {
if (expired) if (expired)
goto discard_key; goto discard_key;
goto partial_key; goto partial_key;
} }
more = 1;
for (i = 1; i < size; i++) for (i = 1; i < size; i++)
more = utf8_append(&ud, (u_char)buf[i]); more = utf8_append(&ud, (u_char)buf[i]);
if (more != 0) if (more != UTF8_DONE)
goto discard_key; goto discard_key;
key = utf8_combine(&ud); key = utf8_combine(&ud);
log_debug("UTF-8 key %.*s %#llx", (int)size, buf, key); 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; struct utf8_data ud;
u_int i, value, x, y, b, sgr_b; u_int i, value, x, y, b, sgr_b;
u_char sgr_type, c; u_char sgr_type, c;
int more; enum utf8_state more;
/* /*
* Standard mouse sequences are \033[M followed by three characters * 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); return (1);
if (tty->mode & MODE_MOUSE_UTF8) { if (tty->mode & MODE_MOUSE_UTF8) {
if (utf8_open(&ud, buf[*size])) { if (utf8_open(&ud, buf[*size]) == UTF8_MORE) {
if (ud.size != 2) if (ud.size != 2)
return (-1); return (-1);
(*size)++; (*size)++;
if (len <= *size) if (len <= *size)
return (1); return (1);
more = utf8_append(&ud, buf[*size]); more = utf8_append(&ud, buf[*size]);
if (more != 0) if (more != UTF8_DONE)
return (-1); return (-1);
value = utf8_combine(&ud); value = utf8_combine(&ud);
} else } else

80
utf8.c
View File

@ -381,10 +381,8 @@ utf8_copy(struct utf8_data *to, const struct utf8_data *from)
* 11000010-11011111 C2-DF start of 2-byte sequence * 11000010-11011111 C2-DF start of 2-byte sequence
* 11100000-11101111 E0-EF start of 3-byte sequence * 11100000-11101111 E0-EF start of 3-byte sequence
* 11110000-11110100 F0-F4 start of 4-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) utf8_open(struct utf8_data *ud, u_char ch)
{ {
memset(ud, 0, sizeof *ud); memset(ud, 0, sizeof *ud);
@ -395,18 +393,13 @@ utf8_open(struct utf8_data *ud, u_char ch)
else if (ch >= 0xf0 && ch <= 0xf4) else if (ch >= 0xf0 && ch <= 0xf4)
ud->size = 4; ud->size = 4;
else else
return (0); return (UTF8_ERROR);
utf8_append(ud, ch); utf8_append(ud, ch);
return (1); return (UTF8_MORE);
} }
/* /* Append character to UTF-8, closing if finished. */
* Append character to UTF-8, closing if finished. enum utf8_state
*
* Returns 1 if more UTF-8 data to come, 0 if finished and valid, -1 if
* finished and invalid.
*/
int
utf8_append(struct utf8_data *ud, u_char ch) utf8_append(struct utf8_data *ud, u_char ch)
{ {
if (ud->have >= ud->size) if (ud->have >= ud->size)
@ -419,12 +412,12 @@ utf8_append(struct utf8_data *ud, u_char ch)
ud->data[ud->have++] = ch; ud->data[ud->have++] = ch;
if (ud->have != ud->size) if (ud->have != ud->size)
return (1); return (UTF8_MORE);
if (ud->width == 0xff) if (ud->width == 0xff)
return (-1); return (UTF8_ERROR);
ud->width = utf8_width(utf8_combine(ud)); ud->width = utf8_width(utf8_combine(ud));
return (0); return (UTF8_DONE);
} }
/* Build UTF-8 width tree. */ /* Build UTF-8 width tree. */
@ -501,7 +494,7 @@ utf8_combine(const struct utf8_data *ud)
} }
/* Split 32-bit Unicode into UTF-8. */ /* Split 32-bit Unicode into UTF-8. */
int enum utf8_state
utf8_split(u_int uc, struct utf8_data *ud) utf8_split(u_int uc, struct utf8_data *ud)
{ {
if (uc < 0x7f) { if (uc < 0x7f) {
@ -523,9 +516,9 @@ utf8_split(u_int uc, struct utf8_data *ud)
ud->data[2] = 0x80 | ((uc >> 6) & 0x3f); ud->data[2] = 0x80 | ((uc >> 6) & 0x3f);
ud->data[3] = 0x80 | (uc & 0x3f); ud->data[3] = 0x80 | (uc & 0x3f);
} else } else
return (-1); return (UTF8_ERROR);
ud->width = utf8_width(uc); ud->width = utf8_width(uc);
return (0); return (UTF8_DONE);
} }
/* Split a two-byte UTF-8 character. */ /* Split a two-byte UTF-8 character. */
@ -551,26 +544,24 @@ utf8_strvis(char *dst, const char *src, size_t len, int flag)
{ {
struct utf8_data ud; struct utf8_data ud;
const char *start, *end; const char *start, *end;
int more; enum utf8_state more;
size_t i; size_t i;
start = dst; start = dst;
end = src + len; end = src + len;
while (src < end) { while (src < end) {
if (utf8_open(&ud, *src)) { if ((more = utf8_open(&ud, *src)) == UTF8_MORE) {
more = 1; while (++src < end && more == UTF8_MORE)
while (++src < end && more == 1)
more = utf8_append(&ud, *src); more = utf8_append(&ud, *src);
if (more == 0) { if (more == UTF8_DONE) {
/* UTF-8 character finished. */ /* UTF-8 character finished. */
for (i = 0; i < ud.size; i++) for (i = 0; i < ud.size; i++)
*dst++ = ud.data[i]; *dst++ = ud.data[i];
continue; 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) if (src < end - 1)
dst = vis(dst, src[0], flag, src[1]); dst = vis(dst, src[0], flag, src[1]);
@ -593,7 +584,7 @@ utf8_sanitize(const char *src)
{ {
char *dst; char *dst;
size_t n; size_t n;
int more; enum utf8_state more;
struct utf8_data ud; struct utf8_data ud;
u_int i; u_int i;
@ -602,11 +593,10 @@ utf8_sanitize(const char *src)
n = 0; n = 0;
while (*src != '\0') { while (*src != '\0') {
dst = xreallocarray(dst, n + 1, sizeof *dst); dst = xreallocarray(dst, n + 1, sizeof *dst);
if (utf8_open(&ud, *src)) { if ((more = utf8_open(&ud, *src)) == UTF8_MORE) {
more = 1; while (*++src != '\0' && more == UTF8_MORE)
while (*++src != '\0' && more == 1)
more = utf8_append(&ud, *src); more = utf8_append(&ud, *src);
if (more != 1) { if (more == UTF8_DONE) {
dst = xreallocarray(dst, n + ud.width, dst = xreallocarray(dst, n + ud.width,
sizeof *dst); sizeof *dst);
for (i = 0; i < ud.width; i++) for (i = 0; i < ud.width; i++)
@ -617,6 +607,8 @@ utf8_sanitize(const char *src)
} }
if (*src > 0x1f && *src < 0x7f) if (*src > 0x1f && *src < 0x7f)
dst[n++] = *src; dst[n++] = *src;
else
dst[n++] = '_';
src++; src++;
} }
@ -634,27 +626,24 @@ utf8_fromcstr(const char *src)
{ {
struct utf8_data *dst; struct utf8_data *dst;
size_t n; size_t n;
int more; enum utf8_state more;
dst = NULL; dst = NULL;
n = 0; n = 0;
while (*src != '\0') { while (*src != '\0') {
dst = xreallocarray(dst, n + 1, sizeof *dst); dst = xreallocarray(dst, n + 1, sizeof *dst);
if (utf8_open(&dst[n], *src)) { if ((more = utf8_open(&dst[n], *src)) == UTF8_MORE) {
more = 1; while (*++src != '\0' && more == UTF8_MORE)
while (*++src != '\0' && more == 1)
more = utf8_append(&dst[n], *src); more = utf8_append(&dst[n], *src);
if (more != 1) { if (more == UTF8_DONE) {
n++; n++;
continue; continue;
} }
src -= dst[n].have; src -= dst[n].have;
} }
if (*src > 0x1f && *src < 0x7f) { utf8_set(&dst[n], *src);
utf8_set(&dst[n], *src); n++;
n++;
}
src++; src++;
} }
@ -690,21 +679,20 @@ utf8_cstrwidth(const char *s)
{ {
struct utf8_data tmp; struct utf8_data tmp;
u_int width; u_int width;
int more; enum utf8_state more;
width = 0; width = 0;
while (*s != '\0') { while (*s != '\0') {
if (utf8_open(&tmp, *s)) { if ((more = utf8_open(&tmp, *s)) == UTF8_MORE) {
more = 1; while (*++s != '\0' && more == UTF8_MORE)
while (*++s != '\0' && more == 1)
more = utf8_append(&tmp, *s); more = utf8_append(&tmp, *s);
if (more != 1) { if (more == UTF8_DONE) {
width += tmp.width; width += tmp.width;
continue; continue;
} }
s -= tmp.have; s -= tmp.have;
} }
if (*s > 0x1f && *s < 0x7f) if (*s > 0x1f && *s != 0x7f)
width++; width++;
s++; s++;
} }