composetable: Parse multi-char values

Rewrite the value parsing function to accept strings
that hold more than a single Unicode character.
This commit is contained in:
Matthias Clasen 2021-02-02 00:21:11 -05:00
parent 564793d5b5
commit 773ae0cd0f

View File

@ -37,7 +37,6 @@
typedef struct { typedef struct {
gunichar *sequence; gunichar *sequence;
char *value; char *value;
char *comment;
} GtkComposeData; } GtkComposeData;
@ -46,7 +45,6 @@ gtk_compose_data_free (GtkComposeData *compose_data)
{ {
g_free (compose_data->sequence); g_free (compose_data->sequence);
g_free (compose_data->value); g_free (compose_data->value);
g_free (compose_data->comment);
g_slice_free (GtkComposeData, compose_data); g_slice_free (GtkComposeData, compose_data);
} }
@ -79,72 +77,66 @@ parse_compose_value (GtkComposeData *compose_data,
const char *val, const char *val,
const char *line) const char *line)
{ {
char **words = g_strsplit (val, "\"", 3); char *word;
gunichar uch; const char *p;
gsize len;
GString *value;
gunichar ch;
char *endp; char *endp;
char buf[8] = { 0, };
if (g_strv_length (words) < 3) len = strlen (val);
if (val[0] != '"' || val[len - 1] != '"')
{ {
g_warning ("Need to double-quote the value: %s: %s", val, line); g_warning ("Need to double-quote the value: %s: %s", val, line);
goto fail; goto fail;
} }
uch = g_utf8_get_char (words[1]); word = g_strndup (val + 1, len - 2);
if (uch == 0) value = g_string_new ("");
{
g_warning ("Invalid value: %s: %s", val, line);
goto fail;
}
else if (uch == '\\')
{
uch = words[1][1];
/* The escaped string "\"" is separated with '\\' and '"'. */ p = word;
if (uch == '\0' && words[2][0] == '"') while (*p)
{
if (*p == '\\')
{ {
uch = '"'; if (p[1] == '"')
}
/* The escaped octal */
else if (uch >= '0' && uch < '8')
{
uch = g_ascii_strtoll (words[1] + 1, &endp, 8);
if (*endp != '\0')
{ {
g_warning ("GTK supports to output one char only: %s: %s", val, line); g_string_append_c (value, '"');
p += 2;
}
else if (p[1] == '\\')
{
g_string_append_c (value, '\\');
p += 2;
}
else if (p[1] >= '0' && p[1] < '8')
{
ch = g_ascii_strtoll (p + 1, &endp, 8);
g_string_append_unichar (value, ch);
p = endp;
}
else
{
g_warning ("Invalid escape sequence: %s: %s", val, line);
goto fail; goto fail;
} }
} }
/* If we need to handle other escape sequences. */ else
else if (uch != '\\')
{ {
g_warning ("Invalid escape sequence: %s: %s", val, line); ch = g_utf8_get_char (p);
} g_string_append_unichar (value, ch);
} p = g_utf8_next_char (p);
else
{
if (g_utf8_get_char (g_utf8_next_char (words[1])) > 0)
{
g_warning ("GTK supports to output one char only: %s: %s", val, line);
goto fail;
} }
} }
g_unichar_to_utf8 (uch, buf); compose_data->value = g_string_free (value, FALSE);
compose_data->value = g_strdup (buf);
if (uch == '"') g_free (word);
compose_data->comment = g_strdup (g_strstrip (words[2] + 1));
else
compose_data->comment = g_strdup (g_strstrip (words[2]));
g_strfreev (words);
return TRUE; return TRUE;
fail: fail:
g_strfreev (words);
return FALSE; return FALSE;
} }