Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam 2015-11-12 14:01:14 +00:00
commit 4f88344df3
5 changed files with 73 additions and 68 deletions

View File

@ -18,6 +18,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "tmux.h" #include "tmux.h"
@ -54,10 +55,9 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq)
struct key_table *table; struct key_table *table;
struct key_binding *bd; struct key_binding *bd;
const char *key, *tablename, *r; const char *key, *tablename, *r;
char tmp[BUFSIZ]; char *cp, tmp[BUFSIZ];
size_t used; size_t used;
int repeat, width, tablewidth, keywidth; int repeat, width, tablewidth, keywidth;
u_int i;
if (self->entry == &cmd_list_commands_entry) if (self->entry == &cmd_list_commands_entry)
return (cmd_list_keys_commands(self, cmdq)); return (cmd_list_keys_commands(self, cmdq));
@ -82,7 +82,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq)
if (bd->can_repeat) if (bd->can_repeat)
repeat = 1; repeat = 1;
width = strlen(table->name); width = utf8_cstrwidth(table->name);
if (width > tablewidth) if (width > tablewidth)
tablewidth = width; tablewidth = width;
width = utf8_cstrwidth(key); width = utf8_cstrwidth(key);
@ -103,13 +103,20 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq)
r = "-r "; r = "-r ";
else else
r = " "; r = " ";
used = xsnprintf(tmp, sizeof tmp, "%s-T %-*s %s", r, xsnprintf(tmp, sizeof tmp, "%s-T ", r);
(int)tablewidth, table->name, key);
for (i = 0; i < keywidth - utf8_cstrwidth(key); i++) { cp = utf8_padcstr(table->name, tablewidth);
if (strlcat(tmp, " ", sizeof tmp) < sizeof tmp) strlcat(tmp, cp, sizeof tmp);
used++; strlcat(tmp, " ", sizeof tmp);
} free(cp);
if (used < sizeof tmp) {
cp = utf8_padcstr(key, keywidth);
strlcat(tmp, cp, sizeof tmp);
strlcat(tmp, " ", sizeof tmp);
free(cp);
used = strlen(tmp);
if (used < (sizeof tmp) - 1) {
cmd_list_print(bd->cmdlist, tmp + used, cmd_list_print(bd->cmdlist, tmp + used,
(sizeof tmp) - used); (sizeof tmp) - used);
} }

View File

@ -188,7 +188,6 @@ server_start(struct event_base *base, int lockfd, char *lockfile)
TAILQ_INIT(&session_groups); TAILQ_INIT(&session_groups);
mode_key_init_trees(); mode_key_init_trees();
key_bindings_init(); key_bindings_init();
utf8_build();
start_time = time(NULL); start_time = time(NULL);

8
tmux.1
View File

@ -192,8 +192,8 @@ that UTF-8 is supported.
.Pp .Pp
Note that Note that
.Nm .Nm
itself always accepts UTF-8, this controls whether it will send UTF-8 itself always accepts UTF-8; this controls whether it will send UTF-8
characters to the terminal it is running it (if not, they are replaced by characters to the terminal it is running (if not, they are replaced by
.Ql _ ) . .Ql _ ) .
.It Fl v .It Fl v
Request verbose logging. Request verbose logging.
@ -2800,8 +2800,8 @@ As with
.Ic status-left , .Ic status-left ,
.Ar string .Ar string
will be passed to will be passed to
.Xr strftime 3 , .Xr strftime 3
character pairs are replaced. and character pairs are replaced.
.It Ic status-right-length Ar length .It Ic status-right-length Ar length
Set the maximum Set the maximum
.Ar length .Ar length

3
tmux.h
View File

@ -2184,7 +2184,7 @@ void session_group_synchronize1(struct session *, struct session *);
void session_renumber_windows(struct session *); void session_renumber_windows(struct session *);
/* utf8.c */ /* utf8.c */
void utf8_build(void); u_int utf8_width(u_int);
void utf8_set(struct utf8_data *, u_char); void utf8_set(struct utf8_data *, u_char);
int utf8_open(struct utf8_data *, u_char); int utf8_open(struct utf8_data *, u_char);
int utf8_append(struct utf8_data *, u_char); int utf8_append(struct utf8_data *, u_char);
@ -2197,6 +2197,7 @@ struct utf8_data *utf8_fromcstr(const char *);
char *utf8_tocstr(struct utf8_data *); char *utf8_tocstr(struct utf8_data *);
u_int utf8_cstrwidth(const char *); u_int utf8_cstrwidth(const char *);
char *utf8_trimcstr(const char *, u_int); char *utf8_trimcstr(const char *, u_int);
char *utf8_padcstr(const char *, u_int);
/* osdep-*.c */ /* osdep-*.c */
char *osdep_get_name(int, char *); char *osdep_get_name(int, char *);

102
utf8.c
View File

@ -34,7 +34,7 @@ struct utf8_width_entry {
}; };
/* Sorted, then repeatedly split in the middle to balance the tree. */ /* Sorted, then repeatedly split in the middle to balance the tree. */
struct utf8_width_entry utf8_width_table[] = { static struct utf8_width_entry utf8_width_table[] = {
{ 0x00b41, 0x00b44, 0, NULL, NULL }, { 0x00b41, 0x00b44, 0, NULL, NULL },
{ 0x008e4, 0x00902, 0, NULL, NULL }, { 0x008e4, 0x00902, 0, NULL, NULL },
{ 0x006d6, 0x006dd, 0, NULL, NULL }, { 0x006d6, 0x006dd, 0, NULL, NULL },
@ -343,12 +343,9 @@ struct utf8_width_entry utf8_width_table[] = {
{ 0xe0100, 0xe01ef, 0, NULL, NULL }, { 0xe0100, 0xe01ef, 0, NULL, NULL },
{ 0x100000, 0x10fffd, 0, NULL, NULL }, { 0x100000, 0x10fffd, 0, NULL, NULL },
}; };
static struct utf8_width_entry *utf8_width_root = NULL;
struct utf8_width_entry *utf8_width_root = NULL; static void utf8_build(void);
int utf8_overlap(struct utf8_width_entry *, struct utf8_width_entry *);
u_int utf8_combine(const struct utf8_data *);
u_int utf8_width(const struct utf8_data *);
/* Set a single character. */ /* Set a single character. */
void void
@ -404,40 +401,20 @@ utf8_append(struct utf8_data *utf8data, u_char ch)
if (utf8data->have != utf8data->size) if (utf8data->have != utf8data->size)
return (1); return (1);
utf8data->width = utf8_width(utf8data); utf8data->width = utf8_width(utf8_combine(utf8data));
return (0);
}
/* Check if two width tree entries overlap. */
int
utf8_overlap(struct utf8_width_entry *item1, struct utf8_width_entry *item2)
{
if (item1->first >= item2->first && item1->first <= item2->last)
return (1);
if (item1->last >= item2->first && item1->last <= item2->last)
return (1);
if (item2->first >= item1->first && item2->first <= item1->last)
return (1);
if (item2->last >= item1->first && item2->last <= item1->last)
return (1);
return (0); return (0);
} }
/* Build UTF-8 width tree. */ /* Build UTF-8 width tree. */
void static void
utf8_build(void) utf8_build(void)
{ {
struct utf8_width_entry **ptr, *item, *node; struct utf8_width_entry **ptr, *item, *node;
u_int i, j; u_int i;
for (i = 0; i < nitems(utf8_width_table); i++) { for (i = 0; i < nitems(utf8_width_table); i++) {
item = &utf8_width_table[i]; item = &utf8_width_table[i];
for (j = 0; j < nitems(utf8_width_table); j++) {
if (i != j && utf8_overlap(item, &utf8_width_table[j]))
log_fatalx("utf8 overlap: %u %u", i, j);
}
ptr = &utf8_width_root; ptr = &utf8_width_root;
while (*ptr != NULL) { while (*ptr != NULL) {
node = *ptr; node = *ptr;
@ -450,6 +427,27 @@ utf8_build(void)
} }
} }
/* Lookup width of UTF-8 data in tree. */
u_int
utf8_width(u_int uc)
{
struct utf8_width_entry *item;
if (utf8_width_root == NULL)
utf8_build();
item = utf8_width_root;
while (item != NULL) {
if (uc < item->first)
item = item->left;
else if (uc > item->last)
item = item->right;
else
return (item->width);
}
return (1);
}
/* Combine UTF-8 into 32-bit Unicode. */ /* Combine UTF-8 into 32-bit Unicode. */
u_int u_int
utf8_combine(const struct utf8_data *utf8data) utf8_combine(const struct utf8_data *utf8data)
@ -480,7 +478,7 @@ utf8_combine(const struct utf8_data *utf8data)
return (value); return (value);
} }
/* Split a UTF-8 character. */ /* Split 32-bit Unicode into UTF-8. */
int int
utf8_split(u_int uc, struct utf8_data *utf8data) utf8_split(u_int uc, struct utf8_data *utf8data)
{ {
@ -504,7 +502,7 @@ utf8_split(u_int uc, struct utf8_data *utf8data)
utf8data->data[3] = 0x80 | (uc & 0x3f); utf8data->data[3] = 0x80 | (uc & 0x3f);
} else } else
return (-1); return (-1);
utf8data->width = utf8_width(utf8data); utf8data->width = utf8_width(uc);
return (0); return (0);
} }
@ -521,27 +519,6 @@ utf8_split2(u_int uc, u_char *ptr)
return (1); return (1);
} }
/* Lookup width of UTF-8 data in tree. */
u_int
utf8_width(const struct utf8_data *utf8data)
{
struct utf8_width_entry *item;
u_int value;
value = utf8_combine(utf8data);
item = utf8_width_root;
while (item != NULL) {
if (value < item->first)
item = item->left;
else if (value > item->last)
item = item->right;
else
return (item->width);
}
return (1);
}
/* /*
* Encode len characters from src into dst, which is guaranteed to have four * Encode len characters from src into dst, which is guaranteed to have four
* bytes available for each character from src (for \abc or UTF-8) plus space * bytes available for each character from src (for \abc or UTF-8) plus space
@ -735,3 +712,24 @@ utf8_trimcstr(const char *s, u_int width)
free(tmp); free(tmp);
return (out); return (out);
} }
/* Pad UTF-8 string to width. Caller frees. */
char *
utf8_padcstr(const char *s, u_int width)
{
size_t slen;
char *out;
u_int n, i;
n = utf8_cstrwidth(s);
if (n >= width)
return (xstrdup(s));
slen = strlen(s);
out = xmalloc(slen + 1 + (width - n));
memcpy(out, s, slen);
for (i = n; i < width; i++)
out[slen++] = ' ';
out[slen] = '\0';
return (out);
}