]> code.delx.au - pulseaudio/commitdiff
modargs: introduce pa_modargs_get_proplist()
authorLennart Poettering <lennart@poettering.net>
Wed, 27 May 2009 21:18:17 +0000 (23:18 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 27 May 2009 21:18:17 +0000 (23:18 +0200)
src/pulsecore/modargs.c
src/pulsecore/modargs.h
src/tests/proplist-test.c

index 73c67a8b085996cfe1730e312e8733e7e15fff28..c7d734d946c5e00223d9f1a8b98d0cc1723dc765 100644 (file)
@@ -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;
+}
index 809fb27ed1e5f34ee1285022a12bd400c79b1ec5..b3125b10b4cc153b3fd378526925e014d46cc3ad 100644 (file)
@@ -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
index 3e723561a5fa9b07558ad5e2f6a9679bed8d8f3b..27a0d3fef11ea0700849e8512681f96ce5eeab3b 100644 (file)
 #include <pulse/xmalloc.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/modargs.h>
 
 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;
 }