mirror of
https://github.com/tmux/tmux.git
synced 2025-09-02 05:21:10 +00:00
Merge branch 'obsd-master'
This commit is contained in:
78
utf8.c
78
utf8.c
@ -393,6 +393,8 @@ utf8_open(struct utf8_data *utf8data, u_char ch)
|
||||
int
|
||||
utf8_append(struct utf8_data *utf8data, u_char ch)
|
||||
{
|
||||
/* XXX this should do validity checks too! */
|
||||
|
||||
if (utf8data->have >= utf8data->size)
|
||||
fatalx("UTF-8 character overflow");
|
||||
if (utf8data->size > sizeof utf8data->data)
|
||||
@ -466,18 +468,46 @@ utf8_combine(const struct utf8_data *utf8data)
|
||||
case 3:
|
||||
value = utf8data->data[2] & 0x3f;
|
||||
value |= (utf8data->data[1] & 0x3f) << 6;
|
||||
value |= (utf8data->data[0] & 0x0f) << 12;
|
||||
value |= (utf8data->data[0] & 0xf) << 12;
|
||||
break;
|
||||
case 4:
|
||||
value = utf8data->data[3] & 0x3f;
|
||||
value |= (utf8data->data[2] & 0x3f) << 6;
|
||||
value |= (utf8data->data[1] & 0x3f) << 12;
|
||||
value |= (utf8data->data[0] & 0x07) << 18;
|
||||
value |= (utf8data->data[0] & 0x7) << 18;
|
||||
break;
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
||||
/* Split a UTF-8 character. */
|
||||
int
|
||||
utf8_split(u_int uc, struct utf8_data *utf8data)
|
||||
{
|
||||
if (uc < 0x7f) {
|
||||
utf8data->size = 1;
|
||||
utf8data->data[0] = uc;
|
||||
} else if (uc < 0x7ff) {
|
||||
utf8data->size = 2;
|
||||
utf8data->data[0] = 0xc0 | ((uc >> 6) & 0x1f);
|
||||
utf8data->data[1] = 0x80 | (uc & 0x3f);
|
||||
} else if (uc < 0xffff) {
|
||||
utf8data->size = 3;
|
||||
utf8data->data[0] = 0xe0 | ((uc >> 12) & 0xf);
|
||||
utf8data->data[1] = 0x80 | ((uc >> 6) & 0x3f);
|
||||
utf8data->data[2] = 0x80 | (uc & 0x3f);
|
||||
} else if (uc < 0x1fffff) {
|
||||
utf8data->size = 4;
|
||||
utf8data->data[0] = 0xf0 | ((uc >> 18) & 0x7);
|
||||
utf8data->data[1] = 0x80 | ((uc >> 12) & 0x3f);
|
||||
utf8data->data[2] = 0x80 | ((uc >> 6) & 0x3f);
|
||||
utf8data->data[3] = 0x80 | (uc & 0x3f);
|
||||
} else
|
||||
return (-1);
|
||||
utf8data->width = utf8_width(utf8data);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Split a two-byte UTF-8 character. */
|
||||
u_int
|
||||
utf8_split2(u_int uc, u_char *ptr)
|
||||
@ -554,6 +584,50 @@ utf8_strvis(char *dst, const char *src, size_t len, int flag)
|
||||
return (dst - start);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanitize a string, changing any UTF-8 characters to '_'. Caller should free
|
||||
* the returned string. Anything not valid printable ASCII or UTF-8 is
|
||||
* stripped.
|
||||
*/
|
||||
char *
|
||||
utf8_sanitize(const char *src)
|
||||
{
|
||||
char *dst;
|
||||
size_t n;
|
||||
int more;
|
||||
struct utf8_data utf8data;
|
||||
u_int i;
|
||||
|
||||
dst = NULL;
|
||||
|
||||
n = 0;
|
||||
while (*src != '\0') {
|
||||
dst = xreallocarray(dst, n + 1, sizeof *dst);
|
||||
if (utf8_open(&utf8data, *src)) {
|
||||
more = 1;
|
||||
while (*++src != '\0' && more)
|
||||
more = utf8_append(&utf8data, *src);
|
||||
if (!more) {
|
||||
dst = xreallocarray(dst, n + utf8data.width,
|
||||
sizeof *dst);
|
||||
for (i = 0; i < utf8data.width; i++)
|
||||
dst[n++] = '_';
|
||||
continue;
|
||||
}
|
||||
src -= utf8data.have;
|
||||
}
|
||||
if (*src > 0x1f && *src < 0x7f)
|
||||
dst[n] = *src;
|
||||
src++;
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
dst = xreallocarray(dst, n + 1, sizeof *dst);
|
||||
dst[n] = '\0';
|
||||
return (dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a string into a buffer of UTF-8 characters. Terminated by size == 0.
|
||||
* Caller frees.
|
||||
|
Reference in New Issue
Block a user