Would the patch in this form also allow the parse_properties in module-augment-properties to be replaced by this generic function from conf-parser.h? That would be a nice extra. Maarten 2011/12/3 Tanu Kaskinen <tanuk at iki.fi>: > --- > ?src/daemon/daemon-conf.c ? ? ? ? ? ? ? ?| ? ?2 +- > ?src/modules/alsa/alsa-mixer.c ? ? ? ? ? | ? ?4 +- > ?src/modules/module-augment-properties.c | ? ?2 +- > ?src/pulse/client-conf.c ? ? ? ? ? ? ? ? | ? ?2 +- > ?src/pulsecore/conf-parser.c ? ? ? ? ? ? | ? 46 ++++++++++++++++++++++++++++--- > ?src/pulsecore/conf-parser.h ? ? ? ? ? ? | ? 17 ++++++++++- > ?6 files changed, 62 insertions(+), 11 deletions(-) > > diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c > index 3ef7f81..4532e9e 100644 > --- a/src/daemon/daemon-conf.c > +++ b/src/daemon/daemon-conf.c > @@ -645,7 +645,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) { > ? ? ci.default_channel_map_set = ci.default_sample_spec_set = FALSE; > ? ? ci.conf = c; > > - ? ?r = f ? pa_config_parse(c->config_file, f, table, NULL) : 0; > + ? ?r = f ? pa_config_parse(c->config_file, f, table, NULL, NULL) : 0; > > ? ? if (r >= 0) { > > diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c > index 36f3351..c646f31 100644 > --- a/src/modules/alsa/alsa-mixer.c > +++ b/src/modules/alsa/alsa-mixer.c > @@ -2390,7 +2390,7 @@ pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa > > ? ? fn = pa_maybe_prefix_path(fname, paths_dir); > > - ? ?r = pa_config_parse(fn, NULL, items, p); > + ? ?r = pa_config_parse(fn, NULL, items, NULL, p); > ? ? pa_xfree(fn); > > ? ? if (r < 0) > @@ -4123,7 +4123,7 @@ pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pa_run_from_build_tree() ? PA_BUILDDIR "/modules/alsa/mixer/profile-sets/" : > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PA_ALSA_PROFILE_SETS_DIR); > > - ? ?r = pa_config_parse(fn, NULL, items, ps); > + ? ?r = pa_config_parse(fn, NULL, items, NULL, ps); > ? ? pa_xfree(fn); > > ? ? if (r < 0) > diff --git a/src/modules/module-augment-properties.c b/src/modules/module-augment-properties.c > index 05f6f0a..d45bcdc 100644 > --- a/src/modules/module-augment-properties.c > +++ b/src/modules/module-augment-properties.c > @@ -228,7 +228,7 @@ static void update_rule(struct rule *r) { > ? ? table[0].data = &r->application_name; > ? ? table[1].data = &r->icon_name; > > - ? ?if (pa_config_parse(fn, NULL, table, r) < 0) > + ? ?if (pa_config_parse(fn, NULL, table, NULL, r) < 0) > ? ? ? ? pa_log_warn("Failed to parse .desktop file %s.", fn); > > ? ? pa_xfree(fn); > diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c > index e2c2aae..3641e3e 100644 > --- a/src/pulse/client-conf.c > +++ b/src/pulse/client-conf.c > @@ -127,7 +127,7 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) { > ? ? ? ? ? ? ? ? goto finish; > ? ? } > > - ? ?r = f ? pa_config_parse(fn, f, table, NULL) : 0; > + ? ?r = f ? pa_config_parse(fn, f, table, NULL, NULL) : 0; > > ? ? if (!r) > ? ? ? ? r = pa_client_conf_load_cookie(c); > diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c > index 41849c2..6602766 100644 > --- a/src/pulsecore/conf-parser.c > +++ b/src/pulsecore/conf-parser.c > @@ -44,15 +44,17 @@ struct parser_state { > ? ? unsigned lineno; > ? ? char *section; > ? ? const pa_config_item *item_table; > + ? ?pa_proplist *proplist; > ? ? char buf[4096]; > ? ? void *userdata; > > ? ? char *lvalue; > ? ? char *rvalue; > + ? ?pa_bool_t in_proplist; > ?}; > > ?/* Run the user supplied parser for an assignment */ > -static int next_assignment(struct parser_state *state) { > +static int normal_assignment(struct parser_state *state) { > ? ? const pa_config_item *item; > > ? ? pa_assert(state); > @@ -76,6 +78,19 @@ static int next_assignment(struct parser_state *state) { > ? ? return -1; > ?} > > +/* Parse a proplist entry. */ > +static int proplist_assignment(struct 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) { > ? ? char *c; > @@ -102,7 +117,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 +135,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, "Property List")) { > + ? ? ? ? ? ?if (!state->proplist) { > + ? ? ? ? ? ? ? ?pa_log("[%s:%u] \"Property List\" 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,11 +160,14 @@ 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; > @@ -162,6 +191,9 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void > ? ? 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 +209,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) > diff --git a/src/pulsecore/conf-parser.h b/src/pulsecore/conf-parser.h > index c6c8a14..9fb0110 100644 > --- a/src/pulsecore/conf-parser.h > +++ b/src/pulsecore/conf-parser.h > @@ -24,6 +24,8 @@ > > ?#include <stdio.h> > > +#include <pulse/proplist.h> > + > ?/* An abstract parser for simple, line based, shallow configuration > ?* files consisting of variable assignments only. */ > > @@ -39,8 +41,19 @@ typedef struct pa_config_item { > > ?/* 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); > + * NULL. > + * > + * Some configuration files may contain a Property List section, which > + * is a bit special. Normally all accepted lvalues must be predefined > + * in the pa_config_item table, but in the Property List section the > + * pa_config_item table is ignored, and all lvalues are accepted (as > + * long as they are valid proplist keys). If the proplist pointer is > + * non-NULL, the parser will parse any section named "Property List" as > + * properties, and those properties will be merged into the given > + * proplist. If proplist is NULL, then sections named "Property List" > + * are not allowed at all in the configuration file. > + */ > +int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, pa_proplist *proplist, 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); > -- > 1.7.7.3 > > _______________________________________________ > pulseaudio-discuss mailing list > pulseaudio-discuss at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss