]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/conf-parser.c
remap: Change remapping function argument type from void to int16_t / float as approp...
[pulseaudio] / src / pulsecore / conf-parser.c
index 41849c21f7a7ff1bac072931c5bce103f2dd70b4..200252bb7ad567dd2d180395b5f893d36d385cdc 100644 (file)
 #define WHITESPACE " \t\n"
 #define COMMENTS "#;\n"
 
-struct parser_state {
-    const char *filename;
-    unsigned lineno;
-    char *section;
-    const pa_config_item *item_table;
-    char buf[4096];
-    void *userdata;
-
-    char *lvalue;
-    char *rvalue;
-};
-
 /* Run the user supplied parser for an assignment */
-static int next_assignment(struct parser_state *state) {
+static int normal_assignment(pa_config_parser_state *state) {
     const pa_config_item *item;
 
     pa_assert(state);
@@ -68,7 +56,9 @@ static int next_assignment(struct parser_state *state) {
         if (item->section && !pa_streq(state->section, item->section))
             continue;
 
-        return item->parse(state->filename, state->lineno, state->section, state->lvalue, state->rvalue, item->data, state->userdata);
+        state->data = item->data;
+
+        return item->parse(state);
     }
 
     pa_log("[%s:%u] Unknown lvalue '%s' in section '%s'.", state->filename, state->lineno, state->lvalue, pa_strna(state->section));
@@ -76,8 +66,21 @@ static int next_assignment(struct parser_state *state) {
     return -1;
 }
 
+/* Parse a proplist entry. */
+static int proplist_assignment(pa_config_parser_state *state) {
+    pa_assert(state);
+    pa_assert(state->proplist);
+
+    if (pa_proplist_sets(state->proplist, state->lvalue, state->rvalue) < 0) {
+        pa_log("[%s:%u] Failed to parse a proplist entry: %s = %s", state->filename, state->lineno, state->lvalue, state->rvalue);
+        return -1;
+    }
+
+    return 0;
+}
+
 /* Parse a variable assignment line */
-static int parse_line(struct parser_state *state) {
+static int parse_line(pa_config_parser_state *state) {
     char *c;
 
     state->lvalue = state->buf + strspn(state->buf, WHITESPACE);
@@ -102,7 +105,7 @@ static int parse_line(struct parser_state *state) {
             }
         }
 
-        r = pa_config_parse(fn, NULL, state->item_table, state->userdata);
+        r = pa_config_parse(fn, NULL, state->item_table, state->proplist, state->userdata);
         pa_xfree(path);
         return r;
     }
@@ -120,6 +123,17 @@ static int parse_line(struct parser_state *state) {
 
         pa_xfree(state->section);
         state->section = pa_xstrndup(state->lvalue + 1, k-2);
+
+        if (pa_streq(state->section, "Properties")) {
+            if (!state->proplist) {
+                pa_log("[%s:%u] \"Properties\" section is not allowed in this file.", state->filename, state->lineno);
+                return -1;
+            }
+
+            state->in_proplist = true;
+        } else
+            state->in_proplist = false;
+
         return 0;
     }
 
@@ -134,18 +148,23 @@ static int parse_line(struct parser_state *state) {
     state->lvalue = pa_strip(state->lvalue);
     state->rvalue = pa_strip(state->rvalue);
 
-    return next_assignment(state);
+    if (state->in_proplist)
+        return proplist_assignment(state);
+    else
+        return normal_assignment(state);
 }
 
 /* Go through the file and parse each line */
-int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata) {
+int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, pa_proplist *proplist, void *userdata) {
     int r = -1;
-    pa_bool_t do_close = !f;
-    struct parser_state state;
+    bool do_close = !f;
+    pa_config_parser_state state;
 
     pa_assert(filename);
     pa_assert(t);
 
+    pa_zero(state);
+
     if (!f && !(f = pa_fopen_cloexec(filename, "r"))) {
         if (errno == ENOENT) {
             pa_log_debug("Failed to open configuration file '%s': %s", filename, pa_cstrerror(errno));
@@ -157,11 +176,13 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void
         goto finish;
     }
 
-    pa_zero(state);
     state.filename = filename;
     state.item_table = t;
     state.userdata = userdata;
 
+    if (proplist)
+        state.proplist = pa_proplist_new();
+
     while (!feof(f)) {
         if (!fgets(state.buf, sizeof(state.buf), f)) {
             if (feof(f))
@@ -177,9 +198,15 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void
             goto finish;
     }
 
+    if (proplist)
+        pa_proplist_update(proplist, PA_UPDATE_REPLACE, state.proplist);
+
     r = 0;
 
 finish:
+    if (state.proplist)
+        pa_proplist_free(state.proplist);
+
     pa_xfree(state.section);
 
     if (do_close && f)
@@ -188,17 +215,16 @@ finish:
     return r;
 }
 
-int pa_config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    int *i = data;
+int pa_config_parse_int(pa_config_parser_state *state) {
+    int *i;
     int32_t k;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
+
+    i = state->data;
 
-    if (pa_atoi(rvalue, &k) < 0) {
-        pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
+    if (pa_atoi(state->rvalue, &k) < 0) {
+        pa_log("[%s:%u] Failed to parse numeric value: %s", state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -206,17 +232,16 @@ int pa_config_parse_int(const char *filename, unsigned line, const char *section
     return 0;
 }
 
-int pa_config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    unsigned *u = data;
+int pa_config_parse_unsigned(pa_config_parser_state *state) {
+    unsigned *u;
     uint32_t k;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
 
-    if (pa_atou(rvalue, &k) < 0) {
-        pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
+    u = state->data;
+
+    if (pa_atou(state->rvalue, &k) < 0) {
+        pa_log("[%s:%u] Failed to parse numeric value: %s", state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -224,17 +249,16 @@ int pa_config_parse_unsigned(const char *filename, unsigned line, const char *se
     return 0;
 }
 
-int pa_config_parse_size(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    size_t *i = data;
+int pa_config_parse_size(pa_config_parser_state *state) {
+    size_t *i;
     uint32_t k;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
 
-    if (pa_atou(rvalue, &k) < 0) {
-        pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
+    i = state->data;
+
+    if (pa_atou(state->rvalue, &k) < 0) {
+        pa_log("[%s:%u] Failed to parse numeric value: %s", state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -242,17 +266,16 @@ int pa_config_parse_size(const char *filename, unsigned line, const char *sectio
     return 0;
 }
 
-int pa_config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+int pa_config_parse_bool(pa_config_parser_state *state) {
     int k;
-    pa_bool_t *b = data;
+    bool *b;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
+
+    b = state->data;
 
-    if ((k = pa_parse_boolean(rvalue)) < 0) {
-        pa_log("[%s:%u] Failed to parse boolean value: %s", filename, line, rvalue);
+    if ((k = pa_parse_boolean(state->rvalue)) < 0) {
+        pa_log("[%s:%u] Failed to parse boolean value: %s", state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -261,22 +284,16 @@ int pa_config_parse_bool(const char *filename, unsigned line, const char *sectio
     return 0;
 }
 
-int pa_config_parse_not_bool(
-        const char *filename, unsigned line,
-        const char *section,
-        const char *lvalue, const char *rvalue,
-        void *data, void *userdata) {
-
+int pa_config_parse_not_bool(pa_config_parser_state *state) {
     int k;
-    pa_bool_t *b = data;
+    bool *b;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
 
-    if ((k = pa_parse_boolean(rvalue)) < 0) {
-        pa_log("[%s:%u] Failed to parse boolean value: %s", filename, line, rvalue);
+    b = state->data;
+
+    if ((k = pa_parse_boolean(state->rvalue)) < 0) {
+        pa_log("[%s:%u] Failed to parse boolean value: %s", state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -285,15 +302,14 @@ int pa_config_parse_not_bool(
     return 0;
 }
 
-int pa_config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    char **s = data;
+int pa_config_parse_string(pa_config_parser_state *state) {
+    char **s;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
+
+    s = state->data;
 
     pa_xfree(*s);
-    *s = *rvalue ? pa_xstrdup(rvalue) : NULL;
+    *s = *state->rvalue ? pa_xstrdup(state->rvalue) : NULL;
     return 0;
 }