* lib: add mu_str_parse_arglist + unit tests

This commit is contained in:
djcb
2013-05-20 05:14:35 +03:00
parent 2f5d6e246b
commit 59f855b39b
3 changed files with 161 additions and 3 deletions

View File

@ -840,3 +840,122 @@ mu_str_quoted_from_strv (const gchar **params)
return g_string_free (str, FALSE);
}
static char*
read_key (const char *str, const char **val, GError **err)
{
const char *cur;
GString *gstr;
cur = str;
gstr = g_string_sized_new (strlen(cur));
while (*cur && *cur != ':') {
g_string_append_c (gstr, *cur);
++cur;
}
if (*cur != ':' || gstr->len == 0) {
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR,
"expected: '<alphanum>+:' (%s)",
str);
g_string_free (gstr, TRUE);
*val = NULL;
return NULL;
} else {
*val = cur + 1;
return g_string_free (gstr, FALSE);
}
}
static char*
read_val (const char *str, const char **endval, GError **err)
{
const char *cur;
gboolean quoted;
GString *gstr;
gstr = g_string_sized_new (strlen(str));
for (quoted = FALSE, cur = str; *cur; ++cur) {
if (*cur == '\\') {
if (cur[1] != '"' && cur[1] != '\\') {
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR,
"invalid escaping");
goto errexit;
} else {
++cur;
g_string_append_c (gstr, *cur);
continue;
}
} else if (*cur == '"') {
quoted = !quoted;
continue;
} else if (isblank(*cur) && !quoted)
break;
else
g_string_append_c (gstr, *cur);
}
if (quoted) {
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR,
"error in quoting");
goto errexit;
}
*endval = cur;
return g_string_free (gstr, FALSE);
errexit:
g_string_free (gstr, TRUE);
return NULL;
}
GHashTable*
mu_str_parse_arglist (const char *args, GError **err)
{
GHashTable *hash;
const char *cur;
g_return_val_if_fail (args, NULL);
hash = g_hash_table_new_full (
g_str_hash,
g_str_equal,
(GDestroyNotify)g_free,
(GDestroyNotify)g_free);
cur = args;
while ((isblank(*cur)))
++cur;
do {
char *key, *val;
const char *valstart, *valend;
key = read_key (cur, &valstart, err);
if (!key)
goto errexit;
val = read_val (valstart, &valend, err);
if (!val)
goto errexit;
g_print ("%s->%s\n", key, val);
g_hash_table_insert (hash, key, val);
cur = valend;
while ((isblank(*cur)))
++cur;
} while (*cur);
return hash;
errexit:
g_hash_table_destroy (hash);
return NULL;
}