diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/pulsecore/modargs.c | 73 | ||||
| -rw-r--r-- | src/pulsecore/modargs.h | 2 | ||||
| -rw-r--r-- | 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 73c67a8b..c7d734d9 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 809fb27e..b3125b10 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 3e723561..27a0d3fe 100644 --- a/src/tests/proplist-test.c +++ b/src/tests/proplist-test.c @@ -27,11 +27,14 @@  #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;  }  | 
