[pulseaudio-discuss] [PATCH v4 2/9] conf-parser: Pass parser state in a struct also for parse callbacks.

Tanu Kaskinen tanu.kaskinen at digia.com
Thu Apr 12 04:59:06 PDT 2012


As suggested by Maarten Bosmans:
http://article.gmane.org/gmane.comp.audio.pulseaudio.general/12079
---
 src/daemon/daemon-conf.c                |  220 ++++++------
 src/modules/alsa/alsa-mixer.c           |  580 ++++++++++++-------------------
 src/modules/module-augment-properties.c |   60 +---
 src/pulsecore/conf-parser.c             |  115 +++---
 src/pulsecore/conf-parser.h             |   30 +-
 5 files changed, 422 insertions(+), 583 deletions(-)

diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
index 3ef7f81..abc1e61 100644
--- a/src/daemon/daemon-conf.c
+++ b/src/daemon/daemon-conf.c
@@ -263,48 +263,45 @@ int pa_daemon_conf_set_local_server_type(pa_daemon_conf *c, const char *string)
     return 0;
 }
 
-static int parse_log_target(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_log_target(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
+
+    pa_assert(state);
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    c = state->data;
 
-    if (pa_daemon_conf_set_log_target(c, rvalue) < 0) {
-        pa_log(_("[%s:%u] Invalid log target '%s'."), filename, line, rvalue);
+    if (pa_daemon_conf_set_log_target(c, state->rvalue) < 0) {
+        pa_log(_("[%s:%u] Invalid log target '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
     return 0;
 }
 
-static int parse_log_level(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_log_level(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
+
+    pa_assert(state);
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    c = state->data;
 
-    if (pa_daemon_conf_set_log_level(c, rvalue) < 0) {
-        pa_log(_("[%s:%u] Invalid log level '%s'."), filename, line, rvalue);
+    if (pa_daemon_conf_set_log_level(c, state->rvalue) < 0) {
+        pa_log(_("[%s:%u] Invalid log level '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
     return 0;
 }
 
-static int parse_resample_method(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_resample_method(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
+
+    pa_assert(state);
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    c = state->data;
 
-    if (pa_daemon_conf_set_resample_method(c, rvalue) < 0) {
-        pa_log(_("[%s:%u] Invalid resample method '%s'."), filename, line, rvalue);
+    if (pa_daemon_conf_set_resample_method(c, state->rvalue) < 0) {
+        pa_log(_("[%s:%u] Invalid resample method '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -312,22 +309,21 @@ static int parse_resample_method(const char *filename, unsigned line, const char
 }
 
 #ifdef HAVE_SYS_RESOURCE_H
-static int parse_rlimit(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    struct pa_rlimit *r = data;
+static int parse_rlimit(pa_config_parser_state *state) {
+    struct pa_rlimit *r;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(r);
+    pa_assert(state);
 
-    if (rvalue[strspn(rvalue, "\t ")] == 0) {
+    r = state->data;
+
+    if (state->rvalue[strspn(state->rvalue, "\t ")] == 0) {
         /* Empty string */
         r->is_set = 0;
         r->value = 0;
     } else {
         int32_t k;
-        if (pa_atoi(rvalue, &k) < 0) {
-            pa_log(_("[%s:%u] Invalid rlimit '%s'."), filename, line, rvalue);
+        if (pa_atoi(state->rvalue, &k) < 0) {
+            pa_log(_("[%s:%u] Invalid rlimit '%s'."), state->filename, state->lineno, state->rvalue);
             return -1;
         }
         r->is_set = k >= 0;
@@ -338,17 +334,16 @@ static int parse_rlimit(const char *filename, unsigned line, const char *section
 }
 #endif
 
-static int parse_sample_format(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_sample_format(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
     pa_sample_format_t f;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
 
-    if ((f = pa_parse_sample_format(rvalue)) < 0) {
-        pa_log(_("[%s:%u] Invalid sample format '%s'."), filename, line, rvalue);
+    c = state->data;
+
+    if ((f = pa_parse_sample_format(state->rvalue)) < 0) {
+        pa_log(_("[%s:%u] Invalid sample format '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -356,18 +351,17 @@ static int parse_sample_format(const char *filename, unsigned line, const char *
     return 0;
 }
 
-static int parse_sample_rate(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_sample_rate(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
     uint32_t r;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
 
-    if (pa_atou(rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0 ||
+    c = state->data;
+
+    if (pa_atou(state->rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0 ||
         !((r % 4000 == 0) || (r % 11025 == 0))) {
-        pa_log(_("[%s:%u] Invalid sample rate '%s'."), filename, line, rvalue);
+        pa_log(_("[%s:%u] Invalid sample rate '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -375,18 +369,17 @@ static int parse_sample_rate(const char *filename, unsigned line, const char *se
     return 0;
 }
 
-static int parse_alternate_sample_rate(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_alternate_sample_rate(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
     uint32_t r;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
 
-    if (pa_atou(rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0 ||
+    c = state->data;
+
+    if (pa_atou(state->rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0 ||
         !((r % 4000==0) || (r % 11025 == 0))) {
-        pa_log(_("[%s:%u] Invalid sample rate '%s'."), filename, line, rvalue);
+        pa_log(_("[%s:%u] Invalid sample rate '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -400,17 +393,16 @@ struct channel_conf_info {
     pa_bool_t default_channel_map_set;
 };
 
-static int parse_sample_channels(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    struct channel_conf_info *i = data;
+static int parse_sample_channels(pa_config_parser_state *state) {
+    struct channel_conf_info *i;
     int32_t n;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
+
+    i = state->data;
 
-    if (pa_atoi(rvalue, &n) < 0 || n > (int32_t) PA_CHANNELS_MAX || n <= 0) {
-        pa_log(_("[%s:%u] Invalid sample channels '%s'."), filename, line, rvalue);
+    if (pa_atoi(state->rvalue, &n) < 0 || n > (int32_t) PA_CHANNELS_MAX || n <= 0) {
+        pa_log(_("[%s:%u] Invalid sample channels '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -419,16 +411,15 @@ static int parse_sample_channels(const char *filename, unsigned line, const char
     return 0;
 }
 
-static int parse_channel_map(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    struct channel_conf_info *i = data;
+static int parse_channel_map(pa_config_parser_state *state) {
+    struct channel_conf_info *i;
+
+    pa_assert(state);
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    i = state->data;
 
-    if (!pa_channel_map_parse(&i->conf->default_channel_map, rvalue)) {
-        pa_log(_("[%s:%u] Invalid channel map '%s'."), filename, line, rvalue);
+    if (!pa_channel_map_parse(&i->conf->default_channel_map, state->rvalue)) {
+        pa_log(_("[%s:%u] Invalid channel map '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -436,17 +427,16 @@ static int parse_channel_map(const char *filename, unsigned line, const char *se
     return 0;
 }
 
-static int parse_fragments(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_fragments(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
     int32_t n;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
+
+    c = state->data;
 
-    if (pa_atoi(rvalue, &n) < 0 || n < 2) {
-        pa_log(_("[%s:%u] Invalid number of fragments '%s'."), filename, line, rvalue);
+    if (pa_atoi(state->rvalue, &n) < 0 || n < 2) {
+        pa_log(_("[%s:%u] Invalid number of fragments '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -454,17 +444,16 @@ static int parse_fragments(const char *filename, unsigned line, const char *sect
     return 0;
 }
 
-static int parse_fragment_size_msec(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_fragment_size_msec(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
     int32_t n;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
+
+    c = state->data;
 
-    if (pa_atoi(rvalue, &n) < 0 || n < 1) {
-        pa_log(_("[%s:%u] Invalid fragment size '%s'."), filename, line, rvalue);
+    if (pa_atoi(state->rvalue, &n) < 0 || n < 1) {
+        pa_log(_("[%s:%u] Invalid fragment size '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -472,17 +461,16 @@ static int parse_fragment_size_msec(const char *filename, unsigned line, const c
     return 0;
 }
 
-static int parse_nice_level(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_nice_level(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
     int32_t level;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
+
+    c = state->data;
 
-    if (pa_atoi(rvalue, &level) < 0 || level < -20 || level > 19) {
-        pa_log(_("[%s:%u] Invalid nice level '%s'."), filename, line, rvalue);
+    if (pa_atoi(state->rvalue, &level) < 0 || level < -20 || level > 19) {
+        pa_log(_("[%s:%u] Invalid nice level '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -490,21 +478,22 @@ static int parse_nice_level(const char *filename, unsigned line, const char *sec
     return 0;
 }
 
-static int parse_rtprio(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+static int parse_rtprio(pa_config_parser_state *state) {
+#if !defined(OS_IS_WIN32) && defined(HAVE_SCHED_H)
+    pa_daemon_conf *c;
+    int32_t rtprio;
+#endif
+
+    pa_assert(state);
+
 #ifdef OS_IS_WIN32
-    pa_log("[%s:%u] Realtime priority not available on win32.", filename, line);
+    pa_log("[%s:%u] Realtime priority not available on win32.", state->filename, state->lineno);
 #else
 # ifdef HAVE_SCHED_H
-    pa_daemon_conf *c = data;
-    int32_t rtprio;
+    c = state->data;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
-
-    if (pa_atoi(rvalue, &rtprio) < 0 || rtprio < sched_get_priority_min(SCHED_FIFO) || rtprio > sched_get_priority_max(SCHED_FIFO)) {
-        pa_log("[%s:%u] Invalid realtime priority '%s'.", filename, line, rvalue);
+    if (pa_atoi(state->rvalue, &rtprio) < 0 || rtprio < sched_get_priority_min(SCHED_FIFO) || rtprio > sched_get_priority_max(SCHED_FIFO)) {
+        pa_log("[%s:%u] Invalid realtime priority '%s'.", state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -516,16 +505,15 @@ static int parse_rtprio(const char *filename, unsigned line, const char *section
 }
 
 #ifdef HAVE_DBUS
-static int parse_server_type(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_server_type(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
+
+    pa_assert(state);
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    c = state->data;
 
-    if (pa_daemon_conf_set_local_server_type(c, rvalue) < 0) {
-        pa_log(_("[%s:%u] Invalid server type '%s'."), filename, line, rvalue);
+    if (pa_daemon_conf_set_local_server_type(c, state->rvalue) < 0) {
+        pa_log(_("[%s:%u] Invalid server type '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index abb12ee..fac5cd9 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -1784,78 +1784,66 @@ finish:
     return o;
 }
 
-static int element_parse_switch(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_switch(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
 
-    pa_assert(p);
+    pa_assert(state);
+
+    p = state->userdata;
 
-    if (!(e = element_get(p, section, TRUE))) {
-        pa_log("[%s:%u] Switch makes no sense in '%s'", filename, line, section);
+    if (!(e = element_get(p, state->section, TRUE))) {
+        pa_log("[%s:%u] Switch makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_streq(rvalue, "ignore"))
+    if (pa_streq(state->rvalue, "ignore"))
         e->switch_use = PA_ALSA_SWITCH_IGNORE;
-    else if (pa_streq(rvalue, "mute"))
+    else if (pa_streq(state->rvalue, "mute"))
         e->switch_use = PA_ALSA_SWITCH_MUTE;
-    else if (pa_streq(rvalue, "off"))
+    else if (pa_streq(state->rvalue, "off"))
         e->switch_use = PA_ALSA_SWITCH_OFF;
-    else if (pa_streq(rvalue, "on"))
+    else if (pa_streq(state->rvalue, "on"))
         e->switch_use = PA_ALSA_SWITCH_ON;
-    else if (pa_streq(rvalue, "select"))
+    else if (pa_streq(state->rvalue, "select"))
         e->switch_use = PA_ALSA_SWITCH_SELECT;
     else {
-        pa_log("[%s:%u] Switch invalid of '%s'", filename, line, section);
+        pa_log("[%s:%u] Switch invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
     return 0;
 }
 
-static int element_parse_volume(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_volume(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
 
-    pa_assert(p);
+    pa_assert(state);
 
-    if (!(e = element_get(p, section, TRUE))) {
-        pa_log("[%s:%u] Volume makes no sense in '%s'", filename, line, section);
+    p = state->userdata;
+
+    if (!(e = element_get(p, state->section, TRUE))) {
+        pa_log("[%s:%u] Volume makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_streq(rvalue, "ignore"))
+    if (pa_streq(state->rvalue, "ignore"))
         e->volume_use = PA_ALSA_VOLUME_IGNORE;
-    else if (pa_streq(rvalue, "merge"))
+    else if (pa_streq(state->rvalue, "merge"))
         e->volume_use = PA_ALSA_VOLUME_MERGE;
-    else if (pa_streq(rvalue, "off"))
+    else if (pa_streq(state->rvalue, "off"))
         e->volume_use = PA_ALSA_VOLUME_OFF;
-    else if (pa_streq(rvalue, "zero"))
+    else if (pa_streq(state->rvalue, "zero"))
         e->volume_use = PA_ALSA_VOLUME_ZERO;
     else {
         uint32_t constant;
 
-        if (pa_atou(rvalue, &constant) >= 0) {
+        if (pa_atou(state->rvalue, &constant) >= 0) {
             e->volume_use = PA_ALSA_VOLUME_CONSTANT;
             e->constant_volume = constant;
         } else {
-            pa_log("[%s:%u] Volume invalid of '%s'", filename, line, section);
+            pa_log("[%s:%u] Volume invalid of '%s'", state->filename, state->lineno, state->section);
             return -1;
         }
     }
@@ -1863,59 +1851,47 @@ static int element_parse_volume(
     return 0;
 }
 
-static int element_parse_enumeration(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_enumeration(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
 
-    pa_assert(p);
+    pa_assert(state);
+
+    p = state->userdata;
 
-    if (!(e = element_get(p, section, TRUE))) {
-        pa_log("[%s:%u] Enumeration makes no sense in '%s'", filename, line, section);
+    if (!(e = element_get(p, state->section, TRUE))) {
+        pa_log("[%s:%u] Enumeration makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_streq(rvalue, "ignore"))
+    if (pa_streq(state->rvalue, "ignore"))
         e->enumeration_use = PA_ALSA_ENUMERATION_IGNORE;
-    else if (pa_streq(rvalue, "select"))
+    else if (pa_streq(state->rvalue, "select"))
         e->enumeration_use = PA_ALSA_ENUMERATION_SELECT;
     else {
-        pa_log("[%s:%u] Enumeration invalid of '%s'", filename, line, section);
+        pa_log("[%s:%u] Enumeration invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
     return 0;
 }
 
-static int option_parse_priority(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int option_parse_priority(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_option *o;
     uint32_t prio;
 
-    pa_assert(p);
+    pa_assert(state);
 
-    if (!(o = option_get(p, section))) {
-        pa_log("[%s:%u] Priority makes no sense in '%s'", filename, line, section);
+    p = state->userdata;
+
+    if (!(o = option_get(p, state->section))) {
+        pa_log("[%s:%u] Priority makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_atou(rvalue, &prio) < 0) {
-        pa_log("[%s:%u] Priority invalid of '%s'", filename, line, section);
+    if (pa_atou(state->rvalue, &prio) < 0) {
+        pa_log("[%s:%u] Priority invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
@@ -1923,72 +1899,60 @@ static int option_parse_priority(
     return 0;
 }
 
-static int option_parse_name(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int option_parse_name(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_option *o;
 
-    pa_assert(p);
+    pa_assert(state);
+
+    p = state->userdata;
 
-    if (!(o = option_get(p, section))) {
-        pa_log("[%s:%u] Name makes no sense in '%s'", filename, line, section);
+    if (!(o = option_get(p, state->section))) {
+        pa_log("[%s:%u] Name makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
     pa_xfree(o->name);
-    o->name = pa_xstrdup(rvalue);
+    o->name = pa_xstrdup(state->rvalue);
 
     return 0;
 }
 
-static int element_parse_required(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_required(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
     pa_alsa_option *o;
     pa_alsa_jack *j;
     pa_alsa_required_t req;
 
-    pa_assert(p);
+    pa_assert(state);
+
+    p = state->userdata;
 
-    e = element_get(p, section, TRUE);
-    o = option_get(p, section);
-    j = jack_get(p, section);
+    e = element_get(p, state->section, TRUE);
+    o = option_get(p, state->section);
+    j = jack_get(p, state->section);
     if (!e && !o && !j) {
-        pa_log("[%s:%u] Required makes no sense in '%s'", filename, line, section);
+        pa_log("[%s:%u] Required makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_streq(rvalue, "ignore"))
+    if (pa_streq(state->rvalue, "ignore"))
         req = PA_ALSA_REQUIRED_IGNORE;
-    else if (pa_streq(rvalue, "switch") && e)
+    else if (pa_streq(state->rvalue, "switch") && e)
         req = PA_ALSA_REQUIRED_SWITCH;
-    else if (pa_streq(rvalue, "volume") && e)
+    else if (pa_streq(state->rvalue, "volume") && e)
         req = PA_ALSA_REQUIRED_VOLUME;
-    else if (pa_streq(rvalue, "enumeration"))
+    else if (pa_streq(state->rvalue, "enumeration"))
         req = PA_ALSA_REQUIRED_ENUMERATION;
-    else if (pa_streq(rvalue, "any"))
+    else if (pa_streq(state->rvalue, "any"))
         req = PA_ALSA_REQUIRED_ANY;
     else {
-        pa_log("[%s:%u] Required invalid of '%s'", filename, line, section);
+        pa_log("[%s:%u] Required invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_streq(lvalue, "required-absent")) {
+    if (pa_streq(state->lvalue, "required-absent")) {
         if (e)
             e->required_absent = req;
         if (o)
@@ -1996,7 +1960,7 @@ static int element_parse_required(
         if (j)
             j->required_absent = req;
     }
-    else if (pa_streq(lvalue, "required-any")) {
+    else if (pa_streq(state->lvalue, "required-any")) {
         if (e) {
             e->required_any = req;
             e->path->has_req_any |= (req != PA_ALSA_REQUIRED_IGNORE);
@@ -2023,57 +1987,47 @@ static int element_parse_required(
     return 0;
 }
 
-static int element_parse_direction(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_direction(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
 
-    pa_assert(p);
+    pa_assert(state);
+
+    p = state->userdata;
 
-    if (!(e = element_get(p, section, TRUE))) {
-        pa_log("[%s:%u] Direction makes no sense in '%s'", filename, line, section);
+    if (!(e = element_get(p, state->section, TRUE))) {
+        pa_log("[%s:%u] Direction makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_streq(rvalue, "playback"))
+    if (pa_streq(state->rvalue, "playback"))
         e->direction = PA_ALSA_DIRECTION_OUTPUT;
-    else if (pa_streq(rvalue, "capture"))
+    else if (pa_streq(state->rvalue, "capture"))
         e->direction = PA_ALSA_DIRECTION_INPUT;
     else {
-        pa_log("[%s:%u] Direction invalid of '%s'", filename, line, section);
+        pa_log("[%s:%u] Direction invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
     return 0;
 }
 
-static int element_parse_direction_try_other(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_direction_try_other(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
     int yes;
 
-    if (!(e = element_get(p, section, TRUE))) {
-        pa_log("[%s:%u] Direction makes no sense in '%s'", filename, line, section);
+    pa_assert(state);
+
+    p = state->userdata;
+
+    if (!(e = element_get(p, state->section, TRUE))) {
+        pa_log("[%s:%u] Direction makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if ((yes = pa_parse_boolean(rvalue)) < 0) {
-        pa_log("[%s:%u] Direction invalid of '%s'", filename, line, section);
+    if ((yes = pa_parse_boolean(state->rvalue)) < 0) {
+        pa_log("[%s:%u] Direction invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
@@ -2081,26 +2035,22 @@ static int element_parse_direction_try_other(
     return 0;
 }
 
-static int element_parse_volume_limit(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_volume_limit(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
     long volume_limit;
 
-    if (!(e = element_get(p, section, TRUE))) {
-        pa_log("[%s:%u] volume-limit makes no sense in '%s'", filename, line, section);
+    pa_assert(state);
+
+    p = state->userdata;
+
+    if (!(e = element_get(p, state->section, TRUE))) {
+        pa_log("[%s:%u] volume-limit makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_atol(rvalue, &volume_limit) < 0 || volume_limit < 0) {
-        pa_log("[%s:%u] Invalid value for volume-limit", filename, line);
+    if (pa_atol(state->rvalue, &volume_limit) < 0 || volume_limit < 0) {
+        pa_log("[%s:%u] Invalid value for volume-limit", state->filename, state->lineno);
         return -1;
     }
 
@@ -2141,40 +2091,36 @@ static pa_channel_position_mask_t parse_mask(const char *m) {
     return v;
 }
 
-static int element_parse_override_map(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_override_map(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
-    const char *state = NULL;
+    const char *split_state = NULL;
     unsigned i = 0;
     char *n;
 
-    if (!(e = element_get(p, section, TRUE))) {
-        pa_log("[%s:%u] Override map makes no sense in '%s'", filename, line, section);
+    pa_assert(state);
+
+    p = state->userdata;
+
+    if (!(e = element_get(p, state->section, TRUE))) {
+        pa_log("[%s:%u] Override map makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    while ((n = pa_split(rvalue, ",", &state))) {
+    while ((n = pa_split(state->rvalue, ",", &split_state))) {
         pa_channel_position_mask_t m;
 
         if (!*n)
             m = 0;
         else {
             if ((m = parse_mask(n)) == 0) {
-                pa_log("[%s:%u] Override map '%s' invalid in '%s'", filename, line, n, section);
+                pa_log("[%s:%u] Override map '%s' invalid in '%s'", state->filename, state->lineno, n, state->section);
                 pa_xfree(n);
                 return -1;
             }
         }
 
-        if (pa_streq(lvalue, "override-map.1"))
+        if (pa_streq(state->lvalue, "override-map.1"))
             e->masks[i++][0] = m;
         else
             e->masks[i++][1] = m;
@@ -2189,40 +2135,36 @@ static int element_parse_override_map(
     return 0;
 }
 
-static int jack_parse_state(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int jack_parse_state(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_jack *j;
     pa_port_available_t pa;
 
-    if (!(j = jack_get(p, section))) {
-        pa_log("[%s:%u] state makes no sense in '%s'", filename, line, section);
+    pa_assert(state);
+
+    p = state->userdata;
+
+    if (!(j = jack_get(p, state->section))) {
+        pa_log("[%s:%u] state makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (!strcmp(rvalue,"yes"))
+    if (pa_streq(state->rvalue, "yes"))
 	pa = PA_PORT_AVAILABLE_YES;
-    else if (!strcmp(rvalue,"no"))
+    else if (pa_streq(state->rvalue, "no"))
 	pa = PA_PORT_AVAILABLE_NO;
-    else if (!strcmp(rvalue,"unknown"))
+    else if (pa_streq(state->rvalue, "unknown"))
 	pa = PA_PORT_AVAILABLE_UNKNOWN;
     else {
-        pa_log("[%s:%u] state must be 'yes','no' or 'unknown' in '%s'", filename, line, section);
+        pa_log("[%s:%u] state must be 'yes', 'no' or 'unknown' in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (!strcmp(lvalue, "state.unplugged"))
+    if (pa_streq(state->lvalue, "state.unplugged"))
         j->state_unplugged = pa;
     else {
         j->state_plugged = pa;
-        pa_assert(!strcmp(lvalue, "state.plugged"));
+        pa_assert(pa_streq(state->lvalue, "state.plugged"));
     }
 
     return 0;
@@ -3427,268 +3369,214 @@ static pa_alsa_decibel_fix *decibel_fix_get(pa_alsa_profile_set *ps, const char
     return db_fix;
 }
 
-static int mapping_parse_device_strings(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int mapping_parse_device_strings(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_mapping *m;
 
-    pa_assert(ps);
+    pa_assert(state);
+
+    ps = state->userdata;
 
-    if (!(m = mapping_get(ps, section))) {
-        pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
+    if (!(m = mapping_get(ps, state->section))) {
+        pa_log("[%s:%u] %s invalid in section %s", state->filename, state->lineno, state->lvalue, state->section);
         return -1;
     }
 
     pa_xstrfreev(m->device_strings);
-    if (!(m->device_strings = pa_split_spaces_strv(rvalue))) {
-        pa_log("[%s:%u] Device string list empty of '%s'", filename, line, section);
+    if (!(m->device_strings = pa_split_spaces_strv(state->rvalue))) {
+        pa_log("[%s:%u] Device string list empty of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
     return 0;
 }
 
-static int mapping_parse_channel_map(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int mapping_parse_channel_map(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_mapping *m;
 
-    pa_assert(ps);
+    pa_assert(state);
+
+    ps = state->userdata;
 
-    if (!(m = mapping_get(ps, section))) {
-        pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
+    if (!(m = mapping_get(ps, state->section))) {
+        pa_log("[%s:%u] %s invalid in section %s", state->filename, state->lineno, state->lvalue, state->section);
         return -1;
     }
 
-    if (!(pa_channel_map_parse(&m->channel_map, rvalue))) {
-        pa_log("[%s:%u] Channel map invalid of '%s'", filename, line, section);
+    if (!(pa_channel_map_parse(&m->channel_map, state->rvalue))) {
+        pa_log("[%s:%u] Channel map invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
     return 0;
 }
 
-static int mapping_parse_paths(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int mapping_parse_paths(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_mapping *m;
 
-    pa_assert(ps);
+    pa_assert(state);
+
+    ps = state->userdata;
 
-    if (!(m = mapping_get(ps, section))) {
-        pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
+    if (!(m = mapping_get(ps, state->section))) {
+        pa_log("[%s:%u] %s invalid in section %s", state->filename, state->lineno, state->lvalue, state->section);
         return -1;
     }
 
-    if (pa_streq(lvalue, "paths-input")) {
+    if (pa_streq(state->lvalue, "paths-input")) {
         pa_xstrfreev(m->input_path_names);
-        m->input_path_names = pa_split_spaces_strv(rvalue);
+        m->input_path_names = pa_split_spaces_strv(state->rvalue);
     } else {
         pa_xstrfreev(m->output_path_names);
-        m->output_path_names = pa_split_spaces_strv(rvalue);
+        m->output_path_names = pa_split_spaces_strv(state->rvalue);
     }
 
     return 0;
 }
 
-static int mapping_parse_element(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int mapping_parse_element(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_mapping *m;
 
-    pa_assert(ps);
+    pa_assert(state);
 
-    if (!(m = mapping_get(ps, section))) {
-        pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
+    ps = state->userdata;
+
+    if (!(m = mapping_get(ps, state->section))) {
+        pa_log("[%s:%u] %s invalid in section %s", state->filename, state->lineno, state->lvalue, state->section);
         return -1;
     }
 
-    if (pa_streq(lvalue, "element-input")) {
+    if (pa_streq(state->lvalue, "element-input")) {
         pa_xstrfreev(m->input_element);
-        m->input_element = pa_split_spaces_strv(rvalue);
+        m->input_element = pa_split_spaces_strv(state->rvalue);
     } else {
         pa_xstrfreev(m->output_element);
-        m->output_element = pa_split_spaces_strv(rvalue);
+        m->output_element = pa_split_spaces_strv(state->rvalue);
     }
 
     return 0;
 }
 
-static int mapping_parse_direction(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int mapping_parse_direction(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_mapping *m;
 
-    pa_assert(ps);
+    pa_assert(state);
+
+    ps = state->userdata;
 
-    if (!(m = mapping_get(ps, section))) {
-        pa_log("[%s:%u] Section name %s invalid.", filename, line, section);
+    if (!(m = mapping_get(ps, state->section))) {
+        pa_log("[%s:%u] Section name %s invalid.", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_streq(rvalue, "input"))
+    if (pa_streq(state->rvalue, "input"))
         m->direction = PA_ALSA_DIRECTION_INPUT;
-    else if (pa_streq(rvalue, "output"))
+    else if (pa_streq(state->rvalue, "output"))
         m->direction = PA_ALSA_DIRECTION_OUTPUT;
-    else if (pa_streq(rvalue, "any"))
+    else if (pa_streq(state->rvalue, "any"))
         m->direction = PA_ALSA_DIRECTION_ANY;
     else {
-        pa_log("[%s:%u] Direction %s invalid.", filename, line, rvalue);
+        pa_log("[%s:%u] Direction %s invalid.", state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
     return 0;
 }
 
-static int mapping_parse_description(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int mapping_parse_description(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_profile *p;
     pa_alsa_mapping *m;
 
-    pa_assert(ps);
+    pa_assert(state);
 
-    if ((m = mapping_get(ps, section))) {
+    ps = state->userdata;
+
+    if ((m = mapping_get(ps, state->section))) {
         pa_xfree(m->description);
-        m->description = pa_xstrdup(rvalue);
-    } else if ((p = profile_get(ps, section))) {
+        m->description = pa_xstrdup(state->rvalue);
+    } else if ((p = profile_get(ps, state->section))) {
         pa_xfree(p->description);
-        p->description = pa_xstrdup(rvalue);
+        p->description = pa_xstrdup(state->rvalue);
     } else {
-        pa_log("[%s:%u] Section name %s invalid.", filename, line, section);
+        pa_log("[%s:%u] Section name %s invalid.", state->filename, state->lineno, state->section);
         return -1;
     }
 
     return 0;
 }
 
-static int mapping_parse_priority(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int mapping_parse_priority(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_profile *p;
     pa_alsa_mapping *m;
     uint32_t prio;
 
-    pa_assert(ps);
+    pa_assert(state);
+
+    ps = state->userdata;
 
-    if (pa_atou(rvalue, &prio) < 0) {
-        pa_log("[%s:%u] Priority invalid of '%s'", filename, line, section);
+    if (pa_atou(state->rvalue, &prio) < 0) {
+        pa_log("[%s:%u] Priority invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if ((m = mapping_get(ps, section)))
+    if ((m = mapping_get(ps, state->section)))
         m->priority = prio;
-    else if ((p = profile_get(ps, section)))
+    else if ((p = profile_get(ps, state->section)))
         p->priority = prio;
     else {
-        pa_log("[%s:%u] Section name %s invalid.", filename, line, section);
+        pa_log("[%s:%u] Section name %s invalid.", state->filename, state->lineno, state->section);
         return -1;
     }
 
     return 0;
 }
 
-static int profile_parse_mappings(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int profile_parse_mappings(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_profile *p;
 
-    pa_assert(ps);
+    pa_assert(state);
 
-    if (!(p = profile_get(ps, section))) {
-        pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
+    ps = state->userdata;
+
+    if (!(p = profile_get(ps, state->section))) {
+        pa_log("[%s:%u] %s invalid in section %s", state->filename, state->lineno, state->lvalue, state->section);
         return -1;
     }
 
-    if (pa_streq(lvalue, "input-mappings")) {
+    if (pa_streq(state->lvalue, "input-mappings")) {
         pa_xstrfreev(p->input_mapping_names);
-        p->input_mapping_names = pa_split_spaces_strv(rvalue);
+        p->input_mapping_names = pa_split_spaces_strv(state->rvalue);
     } else {
         pa_xstrfreev(p->output_mapping_names);
-        p->output_mapping_names = pa_split_spaces_strv(rvalue);
+        p->output_mapping_names = pa_split_spaces_strv(state->rvalue);
     }
 
     return 0;
 }
 
-static int profile_parse_skip_probe(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int profile_parse_skip_probe(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_profile *p;
     int b;
 
-    pa_assert(ps);
+    pa_assert(state);
+
+    ps = state->userdata;
 
-    if (!(p = profile_get(ps, section))) {
-        pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
+    if (!(p = profile_get(ps, state->section))) {
+        pa_log("[%s:%u] %s invalid in section %s", state->filename, state->lineno, state->lvalue, state->section);
         return -1;
     }
 
-    if ((b = pa_parse_boolean(rvalue)) < 0) {
-        pa_log("[%s:%u] Skip probe invalid of '%s'", filename, line, section);
+    if ((b = pa_parse_boolean(state->rvalue)) < 0) {
+        pa_log("[%s:%u] Skip probe invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
@@ -3697,16 +3585,8 @@ static int profile_parse_skip_probe(
     return 0;
 }
 
-static int decibel_fix_parse_db_values(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int decibel_fix_parse_db_values(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_decibel_fix *db_fix;
     char **items;
     char *item;
@@ -3718,19 +3598,17 @@ static int decibel_fix_parse_db_values(
     unsigned prev_step = 0;
     double prev_db = 0;
 
-    pa_assert(filename);
-    pa_assert(section);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(ps);
+    pa_assert(state);
+
+    ps = state->userdata;
 
-    if (!(db_fix = decibel_fix_get(ps, section))) {
-        pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
+    if (!(db_fix = decibel_fix_get(ps, state->section))) {
+        pa_log("[%s:%u] %s invalid in section %s", state->filename, state->lineno, state->lvalue, state->section);
         return -1;
     }
 
-    if (!(items = pa_split_spaces_strv(rvalue))) {
-        pa_log("[%s:%u] Value missing", pa_strnull(filename), line);
+    if (!(items = pa_split_spaces_strv(state->rvalue))) {
+        pa_log("[%s:%u] Value missing", state->filename, state->lineno);
         return -1;
     }
 
@@ -3747,13 +3625,13 @@ static int decibel_fix_parse_db_values(
 
         if (d == s) {
             /* item started with colon. */
-            pa_log("[%s:%u] No step value found in %s", filename, line, item);
+            pa_log("[%s:%u] No step value found in %s", state->filename, state->lineno, item);
             goto fail;
         }
 
         if (!*d || !*(d + 1)) {
             /* No colon found, or it was the last character in item. */
-            pa_log("[%s:%u] No dB value found in %s", filename, line, item);
+            pa_log("[%s:%u] No dB value found in %s", state->filename, state->lineno, item);
             goto fail;
         }
 
@@ -3762,22 +3640,22 @@ static int decibel_fix_parse_db_values(
         *d++ = '\0';
 
         if (pa_atou(s, &step) < 0) {
-            pa_log("[%s:%u] Invalid step value: %s", filename, line, s);
+            pa_log("[%s:%u] Invalid step value: %s", state->filename, state->lineno, s);
             goto fail;
         }
 
         if (pa_atod(d, &db) < 0) {
-            pa_log("[%s:%u] Invalid dB value: %s", filename, line, d);
+            pa_log("[%s:%u] Invalid dB value: %s", state->filename, state->lineno, d);
             goto fail;
         }
 
         if (step <= prev_step && i != 1) {
-            pa_log("[%s:%u] Step value %u not greater than the previous value %u", filename, line, step, prev_step);
+            pa_log("[%s:%u] Step value %u not greater than the previous value %u", state->filename, state->lineno, step, prev_step);
             goto fail;
         }
 
         if (db < prev_db && i != 1) {
-            pa_log("[%s:%u] Decibel value %0.2f less than the previous value %0.2f", filename, line, db, prev_db);
+            pa_log("[%s:%u] Decibel value %0.2f less than the previous value %0.2f", state->filename, state->lineno, db, prev_db);
             goto fail;
         }
 
diff --git a/src/modules/module-augment-properties.c b/src/modules/module-augment-properties.c
index 05f6f0a..2999ece 100644
--- a/src/modules/module-augment-properties.c
+++ b/src/modules/module-augment-properties.c
@@ -78,19 +78,15 @@ static void rule_free(struct rule *r) {
     pa_xfree(r);
 }
 
-static int parse_properties(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    struct rule *r = userdata;
+static int parse_properties(pa_config_parser_state *state) {
+    struct rule *r;
     pa_proplist *n;
 
-    if (!(n = pa_proplist_from_string(rvalue)))
+    pa_assert(state);
+
+    r = state->userdata;
+
+    if (!(n = pa_proplist_from_string(state->rvalue)))
         return -1;
 
     if (r->proplist) {
@@ -102,20 +98,16 @@ static int parse_properties(
     return 0;
 }
 
-static int parse_categories(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    struct rule *r = userdata;
-    const char *state = NULL;
+static int parse_categories(pa_config_parser_state *state) {
+    struct rule *r;
+    const char *split_state = NULL;
     char *c;
 
-    while ((c = pa_split(rvalue, ";", &state))) {
+    pa_assert(state);
+
+    r = state->userdata;
+
+    while ((c = pa_split(state->rvalue, ";", &split_state))) {
 
         if (pa_streq(c, "Game")) {
             pa_xfree(r->role);
@@ -131,27 +123,13 @@ static int parse_categories(
     return 0;
 }
 
-static int check_type(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
+static int check_type(pa_config_parser_state *state) {
+    pa_assert(state);
 
-    return pa_streq(rvalue, "Application") ? 0 : -1;
+    return pa_streq(state->rvalue, "Application") ? 0 : -1;
 }
 
-static int catch_all(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
+static int catch_all(pa_config_parser_state *state) {
     return 0;
 }
 
diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c
index 41849c2..95c21f0 100644
--- a/src/pulsecore/conf-parser.c
+++ b/src/pulsecore/conf-parser.c
@@ -39,20 +39,8 @@
 #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 next_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));
@@ -77,7 +67,7 @@ static int next_assignment(struct parser_state *state) {
 }
 
 /* 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);
@@ -141,7 +131,7 @@ static int parse_line(struct parser_state *state) {
 int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata) {
     int r = -1;
     pa_bool_t do_close = !f;
-    struct parser_state state;
+    pa_config_parser_state state;
 
     pa_assert(filename);
     pa_assert(t);
@@ -188,17 +178,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 +195,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);
+
+    u = state->data;
 
-    if (pa_atou(rvalue, &k) < 0) {
-        pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
+    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 +212,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);
+
+    i = state->data;
 
-    if (pa_atou(rvalue, &k) < 0) {
-        pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
+    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 +229,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;
+    pa_bool_t *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 +247,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;
+    pa_bool_t *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;
     }
 
@@ -285,15 +265,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;
 }
diff --git a/src/pulsecore/conf-parser.h b/src/pulsecore/conf-parser.h
index c6c8a14..1344121 100644
--- a/src/pulsecore/conf-parser.h
+++ b/src/pulsecore/conf-parser.h
@@ -27,7 +27,9 @@
 /* An abstract parser for simple, line based, shallow configuration
  * files consisting of variable assignments only. */
 
-typedef int (*pa_config_parser_cb_t)(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
+typedef struct pa_config_parser_state pa_config_parser_state;
+
+typedef int (*pa_config_parser_cb_t)(pa_config_parser_state *state);
 
 /* Wraps info for parsing a specific configuration variable */
 typedef struct pa_config_item {
@@ -37,17 +39,31 @@ typedef struct pa_config_item {
     const char *section;
 } pa_config_item;
 
+struct pa_config_parser_state {
+    const char *filename;
+    unsigned lineno;
+    char *section;
+    char *lvalue;
+    char *rvalue;
+    void *data; /* The data pointer of the current pa_config_item. */
+    void *userdata; /* The pointer that was given to pa_config_parse(). */
+
+    /* Private data to be used only by conf-parser.c. */
+    const pa_config_item *item_table;
+    char buf[4096];
+};
+
 /* The configuration file parsing routine. Expects a table of
  * pa_config_items in *t that is terminated by an item where lvalue is
  * NULL */
 int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata);
 
 /* Generic parsers for integers, size_t, booleans and strings */
-int pa_config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
-int pa_config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
-int pa_config_parse_size(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
-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_not_bool(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
-int pa_config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
+int pa_config_parse_int(pa_config_parser_state *state);
+int pa_config_parse_unsigned(pa_config_parser_state *state);
+int pa_config_parse_size(pa_config_parser_state *state);
+int pa_config_parse_bool(pa_config_parser_state *state);
+int pa_config_parse_not_bool(pa_config_parser_state *state);
+int pa_config_parse_string(pa_config_parser_state *state);
 
 #endif
-- 
1.7.10



More information about the pulseaudio-discuss mailing list