From 19d7ced40d4631d5d3a44a5f29ede8b00cc425bc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 27 May 2009 23:18:17 +0200 Subject: [PATCH] modargs: introduce pa_modargs_get_proplist() --- src/pulsecore/modargs.c | 73 +++++++++++++++++++++++++++++++++++++++++++---- src/pulsecore/modargs.h | 2 ++ src/tests/proplist-test.c | 14 +++++++++ 3 files changed, 84 insertions(+), 5 deletions(-) diff --git a/src/pulsecore/modargs.c b/src/pulsecore/modargs.c index 73c67a8..c7d734d 100644 --- a/src/pulsecore/modargs.c +++ b/src/pulsecore/modargs.c @@ -84,8 +84,11 @@ pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) { KEY, VALUE_START, VALUE_SIMPLE, + VALUE_SIMPLE_ESCAPED, VALUE_DOUBLE_QUOTES, - VALUE_TICKS + VALUE_DOUBLE_QUOTES_ESCAPED, + VALUE_TICKS, + VALUE_TICKS_ESCAPED } state; const char *p, *key = NULL, *value = NULL; @@ -131,9 +134,16 @@ pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) { value = p+1; value_len = 0; } else if (isspace(*p)) { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0) + if (add_key_value(map, + pa_xstrndup(key, key_len), + pa_xstrdup(""), + valid_keys) < 0) goto fail; state = WHITESPACE; + } else if (*p == '\\') { + state = VALUE_SIMPLE_ESCAPED; + value = p; + value_len = 1; } else { state = VALUE_SIMPLE; value = p; @@ -143,30 +153,63 @@ pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) { case VALUE_SIMPLE: if (isspace(*p)) { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0) + if (add_key_value(map, + pa_xstrndup(key, key_len), + pa_unescape(pa_xstrndup(value, value_len)), + valid_keys) < 0) goto fail; state = WHITESPACE; + } else if (*p == '\\') { + state = VALUE_SIMPLE_ESCAPED; + value_len++; } else value_len++; break; + case VALUE_SIMPLE_ESCAPED: + state = VALUE_SIMPLE; + value_len++; + break; + case VALUE_DOUBLE_QUOTES: if (*p == '"') { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0) + if (add_key_value(map, + pa_xstrndup(key, key_len), + pa_unescape(pa_xstrndup(value, value_len)), + valid_keys) < 0) goto fail; state = WHITESPACE; + } else if (*p == '\\') { + state = VALUE_DOUBLE_QUOTES_ESCAPED; + value_len++; } else value_len++; break; + case VALUE_DOUBLE_QUOTES_ESCAPED: + state = VALUE_DOUBLE_QUOTES; + value_len++; + break; + case VALUE_TICKS: if (*p == '\'') { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0) + if (add_key_value(map, + pa_xstrndup(key, key_len), + pa_unescape(pa_xstrndup(value, value_len)), + valid_keys) < 0) goto fail; state = WHITESPACE; + } else if (*p == '\\') { + state = VALUE_TICKS_ESCAPED; + value_len++; } else value_len++; break; + + case VALUE_TICKS_ESCAPED: + state = VALUE_TICKS; + value_len++; + break; } } @@ -352,3 +395,23 @@ int pa_modargs_get_sample_spec_and_channel_map( return 0; } + +int pa_modargs_get_proplist(pa_modargs *ma, const char *name, pa_proplist *p, pa_update_mode_t m) { + const char *v; + pa_proplist *n; + + pa_assert(ma); + pa_assert(name); + pa_assert(p); + + if (!(v = pa_modargs_get_value(ma, name, NULL))) + return 0; + + if (!(n = pa_proplist_from_string(v))) + return -1; + + pa_proplist_update(p, m, n); + pa_proplist_free(n); + + return 0; +} diff --git a/src/pulsecore/modargs.h b/src/pulsecore/modargs.h index 809fb27..b3125b1 100644 --- a/src/pulsecore/modargs.h +++ b/src/pulsecore/modargs.h @@ -58,4 +58,6 @@ structure if no channel_map is found, using pa_channel_map_init_auto() */ int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *ss, pa_channel_map *map, pa_channel_map_def_t def); +int pa_modargs_get_proplist(pa_modargs *ma, const char *name, pa_proplist *p, pa_update_mode_t m); + #endif diff --git a/src/tests/proplist-test.c b/src/tests/proplist-test.c index 3e72356..27a0d3f 100644 --- a/src/tests/proplist-test.c +++ b/src/tests/proplist-test.c @@ -27,11 +27,14 @@ #include #include #include +#include int main(int argc, char*argv[]) { + pa_modargs *ma; pa_proplist *a, *b, *c, *d; char *s, *t, *u, *v; const char *text; + const char *x[] = { "foo", NULL }; a = pa_proplist_new(); pa_assert_se(pa_proplist_sets(a, PA_PROP_MEDIA_TITLE, "Brandenburgische Konzerte") == 0); @@ -78,5 +81,16 @@ int main(int argc, char*argv[]) { printf("%s\n", v); pa_xfree(v); + pa_assert_se(ma = pa_modargs_new("foo='foobar=waldo foo2=\"lj\\\\\"dhflh\" foo3=\\'kjlskj\\\\\\'\\''", x)); + pa_assert_se(a = pa_proplist_new()); + + pa_assert_se(pa_modargs_get_proplist(ma, "foo", a, PA_UPDATE_REPLACE) >= 0); + + printf("%s\n", v = pa_proplist_to_string(a)); + pa_xfree(v); + + pa_proplist_free(a); + pa_modargs_free(ma); + return 0; } -- 2.7.4