mirror of
https://github.com/djcb/mu.git
synced 2024-06-26 07:29:17 +02:00
* lib: add mu_str_parse_arglist + unit tests
This commit is contained in:
parent
2f5d6e246b
commit
59f855b39b
119
lib/mu-str.c
119
lib/mu-str.c
|
@ -840,3 +840,122 @@ mu_str_quoted_from_strv (const gchar **params)
|
||||||
|
|
||||||
return g_string_free (str, FALSE);
|
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;
|
||||||
|
}
|
||||||
|
|
15
lib/mu-str.h
15
lib/mu-str.h
|
@ -281,6 +281,21 @@ GSList* mu_str_to_list (const char *str, char sepa, gboolean strip);
|
||||||
GSList* mu_str_esc_to_list (const char *str);
|
GSList* mu_str_esc_to_list (const char *str);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a list of <key>:<value> arguments, where <value> supports
|
||||||
|
* quoting and escaping.
|
||||||
|
*
|
||||||
|
* @param args a list of arguments
|
||||||
|
* @param err receives error information
|
||||||
|
*
|
||||||
|
* @return a hash table with key->value, or NULL in case of
|
||||||
|
* error. Free with g_hash_table_destroy.
|
||||||
|
*/
|
||||||
|
GHashTable* mu_str_parse_arglist (const char *args, GError **err)
|
||||||
|
G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* free a GSList consisting of allocated strings
|
* free a GSList consisting of allocated strings
|
||||||
*
|
*
|
||||||
|
|
|
@ -129,6 +129,30 @@ test_mu_str_flatten (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_parse_arglist (void)
|
||||||
|
{
|
||||||
|
const char *args;
|
||||||
|
GHashTable *hash;
|
||||||
|
GError *err;
|
||||||
|
|
||||||
|
args = "cmd:find query:\"maildir:\\\"/sent items\\\"\" maxnum:500";
|
||||||
|
|
||||||
|
err = NULL;
|
||||||
|
hash = mu_str_parse_arglist (args, &err);
|
||||||
|
g_assert_no_error (err);
|
||||||
|
g_assert (hash);
|
||||||
|
|
||||||
|
g_assert_cmpstr (g_hash_table_lookup (hash, "cmd"), ==,
|
||||||
|
"find");
|
||||||
|
g_assert_cmpstr (g_hash_table_lookup (hash, "query"), ==,
|
||||||
|
"maildir:\"/sent items\"");
|
||||||
|
g_assert_cmpstr (g_hash_table_lookup (hash, "maxnum"), ==,
|
||||||
|
"500");
|
||||||
|
|
||||||
|
g_hash_table_destroy (hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -403,9 +427,6 @@ test_mu_term_fixups (void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -443,6 +464,9 @@ main (int argc, char *argv[])
|
||||||
g_test_add_func ("/mu-str/mu-str-to-list-strip",
|
g_test_add_func ("/mu-str/mu-str-to-list-strip",
|
||||||
test_mu_str_to_list_strip);
|
test_mu_str_to_list_strip);
|
||||||
|
|
||||||
|
g_test_add_func ("/mu-str/mu-str-esc-to-list",
|
||||||
|
test_parse_arglist);
|
||||||
|
|
||||||
g_test_add_func ("/mu-str/mu-str-esc-to-list",
|
g_test_add_func ("/mu-str/mu-str-esc-to-list",
|
||||||
test_mu_str_esc_to_list);
|
test_mu_str_esc_to_list);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user