Seems good to me! But shouldn't weston_config_get_section() and all the weston_config_section_get_*() be WL_EXPORT?
2013/4/1 Kristian Høgsberg <[email protected]> > The current config parser, parses the ini file and pulls out the values > specified by the struct config_section passed to parse_config_file() and > then throw the rest away. This means that every place we want to get > info out of the ini file, we have to parse the whole thing again. It's not > a big overhead, but it's also not a convenient API. > > This patch adds a parser that parses the ini file to a data structure and > puts that in weston_compositor->config along with API to query comfig > keys from the data structure. The old parser is still available, but > we'll transition to the new approach over the next few commits. > --- > shared/config-parser.c | 225 > +++++++++++++++++++++++++++++++++++++++++++++++++ > shared/config-parser.h | 26 ++++++ > src/compositor.c | 2 + > src/compositor.h | 1 + > 4 files changed, 254 insertions(+) > > diff --git a/shared/config-parser.c b/shared/config-parser.c > index 10ff86a..5582cc4 100644 > --- a/shared/config-parser.c > +++ b/shared/config-parser.c > @@ -25,7 +25,9 @@ > #include <stdlib.h> > #include <assert.h> > #include <ctype.h> > +#include <errno.h> > > +#include <wayland-util.h> > #include "config-parser.h" > > static int > @@ -185,3 +187,226 @@ config_file_path(const char *name) > snprintf(path, size, "%s/%s", config_dir, name); > return path; > } > + > +struct weston_config_entry { > + char *key; > + char *value; > + struct wl_list link; > +}; > + > +struct weston_config_section { > + char *name; > + struct wl_list entry_list; > + struct wl_list link; > +}; > + > +struct weston_config { > + struct wl_list section_list; > +}; > + > +struct weston_config_section * > +weston_config_get_section(struct weston_config *config, const char > *section) > +{ > + struct weston_config_section *s; > + > + wl_list_for_each(s, &config->section_list, link) > + if (strcmp(s->name, section) == 0) > + return s; > + > + return NULL; > +} + +static struct weston_config_entry * > +config_section_get_entry(struct weston_config_section *section, > + const char *key) > +{ > + struct weston_config_entry *e; > + > + if (section == NULL) > + return NULL; > + wl_list_for_each(e, §ion->entry_list, link) > + if (strcmp(e->key, key) == 0) > + return e; > + > + return NULL; > +} > + > +int > +weston_config_section_get_int(struct weston_config_section *section, > + const char *key, > + int32_t *value, int32_t default_value) > +{ > + struct weston_config_entry *entry; > + char *end; > + > + entry = config_section_get_entry(section, key); > + if (entry == NULL) { > + *value = default_value; > + errno = ENOENT; > + return -1; > + } > + > + *value = strtol(entry->value, &end, 0); > + if (*end != '\0') { > + *value = default_value; > + errno = EINVAL; > + return -1; > + } > + > + return 0; > +} > + > +int > +weston_config_section_get_uint(struct weston_config_section *section, > + const char *key, > + uint32_t *value, uint32_t default_value) > +{ > + struct weston_config_entry *entry; > + char *end; > + > + entry = config_section_get_entry(section, key); > + if (entry == NULL) { > + *value = default_value; > + errno = ENOENT; > + return -1; > + } > + > + *value = strtoul(entry->value, &end, 0); > + if (*end != '\0') { > + *value = default_value; > + errno = EINVAL; > + return -1; > + } > + > + return 0; > +} > + > +int > +weston_config_section_get_string(struct weston_config_section *section, > + const char *key, > + const char **value, const char > *default_value) > +{ > + struct weston_config_entry *entry; > + > + entry = config_section_get_entry(section, key); > + if (entry == NULL) { > + if (default_value) > + *value = strdup(default_value); > + errno = ENOENT; > + return -1; > + } > + > + *value = strdup(entry->value); > + > + return 0; > +} > + > +int > +weston_config_section_get_bool(struct weston_config_section *section, > + const char *key, > + int *value, int default_value) > +{ > + struct weston_config_entry *entry; > + > + entry = config_section_get_entry(section, key); > + if (entry == NULL) { > + *value = default_value; > + errno = ENOENT; > + return -1; > + } > + > + if (strcmp(entry->value, "false\n") == 0) > + *value = 0; > + else if (strcmp(entry->value, "true\n") == 0) > + *value = 1; > + else { > + *value = default_value; > + errno = EINVAL; > + return -1; > + } > + > + return 0; > +} > + > +static struct weston_config_section * > +config_add_section(struct weston_config *config, const char *name) > +{ > + struct weston_config_section *section; > + > + section = malloc(sizeof *section); > + section->name = strdup(name); > + wl_list_init(§ion->entry_list); > + wl_list_insert(config->section_list.prev, §ion->link); > + > + return section; > +} > + > +static struct weston_config_entry * > +section_add_entry(struct weston_config_section *section, > + const char *key, const char *value) > +{ > + struct weston_config_entry *entry; > + > + entry = malloc(sizeof *entry); > + entry->key = strdup(key); > + entry->value = strdup(value); > + wl_list_insert(section->entry_list.prev, &entry->link); > + > + return entry; > +} > + > +struct weston_config * > +weston_config_parse(const char *path) > +{ > + FILE *fp; > + char line[512], *p; > + struct weston_config *config; > + struct weston_config_section *section = NULL; > + int i; > + > + config = malloc(sizeof *config); > + if (config == NULL) { > + free(path); > + return NULL; > + } > + > + wl_list_init(&config->section_list); > + > + fp = fopen(path, "r"); > + if (fp == NULL) { > + fprintf(stderr, "couldn't open %s\n", path); > + free(config); > + return NULL; > + } > + > + while (fgets(line, sizeof line, fp)) { > + if (line[0] == '#' || line[0] == '\n') { > + continue; > + } if (line[0] == '[') { > + p = strchr(&line[1], ']'); > + if (!p || p[1] != '\n') { > + fprintf(stderr, "malformed " > + "section header: %s\n", line); > + fclose(fp); > + free(config); > + return NULL; > + } > + p[0] = '\0'; > + section = config_add_section(config, &line[1]); > + } else if (p = strchr(line, '='), p && section) { > + p[0] = '\0'; > + i = strlen(&p[1]); > + p[i + 1] = '\0'; > + section_add_entry(section, line, &p[1]); > + } else { > + fprintf(stderr, "malformed config line: %s\n", > line); > + fclose(fp); > + free(config); > + return NULL; > + } > + } > + > + fclose(fp); > + > + return config; > +} > diff --git a/shared/config-parser.h b/shared/config-parser.h > index 1d0ee3f..0efbac3 100644 > --- a/shared/config-parser.h > +++ b/shared/config-parser.h > @@ -73,6 +73,32 @@ int > parse_options(const struct weston_option *options, > int count, int *argc, char *argv[]); > > +struct weston_config_section; > +struct weston_config; > + > +struct weston_config_section * > +weston_config_get_section(struct weston_config *config, const char > *section); > +int > +weston_config_section_get_int(struct weston_config_section *section, > + const char *key, > + int32_t *value, int32_t default_value); > +int > +weston_config_section_get_uint(struct weston_config_section *section, > + const char *key, > + uint32_t *value, uint32_t default_value); > +int > +weston_config_section_get_string(struct weston_config_section *section, > + const char *key, > + const char **value, > + const char *default_value); > +int > +weston_config_section_get_bool(struct weston_config_section *section, > + const char *key, > + int *value, int default_value); > +struct weston_config * > +weston_config_parse(const char *basename); > + > + > #ifdef __cplusplus > } > #endif > diff --git a/src/compositor.c b/src/compositor.c > index 1617d96..cb374f7 100644 > --- a/src/compositor.c > +++ b/src/compositor.c > @@ -3139,6 +3139,8 @@ weston_compositor_init(struct weston_compositor *ec, > keyboard_config_keys, > ARRAY_LENGTH(keyboard_config_keys) }, > }; > > + ec->config = weston_config_parse(config_file); > + > memset(&xkb_names, 0, sizeof(xkb_names)); > parse_config_file(config_file, cs, ARRAY_LENGTH(cs), ec); > > diff --git a/src/compositor.h b/src/compositor.h > index 7d1d68e..e4c7ab2 100644 > --- a/src/compositor.h > +++ b/src/compositor.h > @@ -301,6 +301,7 @@ struct weston_compositor { > > struct wl_display *wl_display; > struct weston_shell_interface shell_interface; > + struct weston_config *config; > > struct wl_signal activate_signal; > struct wl_signal kill_signal; > -- > 1.8.1.2 > >
_______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
