[PATCH] Add new config parser

Giulio Camuffo giuliocamuffo at gmail.com
Mon Apr 1 10:29:08 PDT 2013


Sorry, i was a bit too rushing. I made a couple of comments below.


2013/4/1 Kristian Høgsberg <krh at bitplanet.net>

> 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, &section->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(&section->entry_list);
> +       wl_list_insert(config->section_list.prev, &section->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);
>

This shouldn't free the path. It is a const char* and could well be a
literal. The user should free it itself if it is the case.

+               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]);
>

This is also putting the newline in the value of the entry.

+               } 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20130401/7f9fb327/attachment.html>


More information about the wayland-devel mailing list