aboutsummaryrefslogtreecommitdiff
path: root/cmd-string.c
diff options
context:
space:
mode:
authorThomas Adam <thomas@xteddy.org>2018-08-19 21:02:37 +0100
committerThomas Adam <thomas@xteddy.org>2018-08-19 21:02:37 +0100
commit3310972d75675abccf6b2ccbd46afaa7ad1014b5 (patch)
tree775cc7b10c1bf64a2f8ec238bbb1fa6c39af7bef /cmd-string.c
parent9ecf657703b85972c41291ab111f07b4ea16b47a (diff)
parentd95fad3d5f945c8047cd35de65cf59c60499f306 (diff)
downloadrtmux-3310972d75675abccf6b2ccbd46afaa7ad1014b5.tar.gz
rtmux-3310972d75675abccf6b2ccbd46afaa7ad1014b5.tar.bz2
rtmux-3310972d75675abccf6b2ccbd46afaa7ad1014b5.zip
Merge branch 'obsd-master'
Diffstat (limited to 'cmd-string.c')
-rw-r--r--cmd-string.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/cmd-string.c b/cmd-string.c
index 9c8f10c1..440a0231 100644
--- a/cmd-string.c
+++ b/cmd-string.c
@@ -54,6 +54,22 @@ cmd_string_ungetc(size_t *p)
(*p)--;
}
+static int
+cmd_string_unicode(wchar_t *wc, const char *s, size_t *p, char ch)
+{
+ int size = (ch == 'u') ? 4 : 8;
+ u_int tmp;
+
+ if (size == 4 && sscanf(s + *p, "%4x", &tmp) != 1)
+ return (-1);
+ if (size == 8 && sscanf(s + *p, "%8x", &tmp) != 1)
+ return (-1);
+ *p += size;
+
+ *wc = (wchar_t)tmp;
+ return (0);
+}
+
int
cmd_string_split(const char *s, int *rargc, char ***rargv)
{
@@ -191,12 +207,11 @@ cmd_string_copy(char **dst, char *src, size_t *len)
static char *
cmd_string_string(const char *s, size_t *p, char endch, int esc)
{
- int ch;
- char *buf, *t;
- size_t len;
-
- buf = NULL;
- len = 0;
+ int ch;
+ wchar_t wc;
+ struct utf8_data ud;
+ char *buf = NULL, *t;
+ size_t len = 0;
while ((ch = cmd_string_getc(s, p)) != endch) {
switch (ch) {
@@ -220,6 +235,18 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
case 't':
ch = '\t';
break;
+ case 'u':
+ case 'U':
+ if (cmd_string_unicode(&wc, s, p, ch) != 0)
+ goto error;
+ if (utf8_split(wc, &ud) != UTF8_DONE)
+ goto error;
+ if (len >= SIZE_MAX - ud.size - 1)
+ goto error;
+ buf = xrealloc(buf, len + ud.size);
+ memcpy(buf + len, ud.data, ud.size);
+ len += ud.size;
+ continue;
}
break;
case '$':