<div dir="ltr">Seems good to me!<div>But shouldn't weston_config_get_section() and all the weston_config_section_get_*() be WL_EXPORT? <div class="gmail_extra"><br><br><div class="gmail_quote">2013/4/1 Kristian Høgsberg <span dir="ltr"><<a href="mailto:krh@bitplanet.net" target="_blank">krh@bitplanet.net</a>></span><br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">The current config parser, parses the ini file and pulls out the values<br>

specified by the struct config_section passed to parse_config_file() and<br>
then throw the rest away.  This means that every place we want to get<br>
info out of the ini file, we have to parse the whole thing again.  It's not<br>
a big overhead, but it's also not a convenient API.<br>
<br>
This patch adds a parser that parses the ini file to a data structure and<br>
puts that in weston_compositor->config along with API to query comfig<br>
keys from the data structure.  The old parser is still available, but<br>
we'll transition to the new approach over the next few commits.<br>
---<br>
 shared/config-parser.c | 225 +++++++++++++++++++++++++++++++++++++++++++++++++<br>
 shared/config-parser.h |  26 ++++++<br>
 src/compositor.c       |   2 +<br>
 src/compositor.h       |   1 +<br>
 4 files changed, 254 insertions(+)<br>
<br>
diff --git a/shared/config-parser.c b/shared/config-parser.c<br>
index 10ff86a..5582cc4 100644<br>
--- a/shared/config-parser.c<br>
+++ b/shared/config-parser.c<br>
@@ -25,7 +25,9 @@<br>
 #include <stdlib.h><br>
 #include <assert.h><br>
 #include <ctype.h><br>
+#include <errno.h><br>
<br>
+#include <wayland-util.h><br>
 #include "config-parser.h"<br>
<br>
 static int<br>
@@ -185,3 +187,226 @@ config_file_path(const char *name)<br>
        snprintf(path, size, "%s/%s", config_dir, name);<br>
        return path;<br>
 }<br>
+<br>
+struct weston_config_entry {<br>
+       char *key;<br>
+       char *value;<br>
+       struct wl_list link;<br>
+};<br>
+<br>
+struct weston_config_section {<br>
+       char *name;<br>
+       struct wl_list entry_list;<br>
+       struct wl_list link;<br>
+};<br>
+<br>
+struct weston_config {<br>
+       struct wl_list section_list;<br>
+};<br>
+<br>
+struct weston_config_section *<br>
+weston_config_get_section(struct weston_config *config, const char *section)<br>
+{<br>
+       struct weston_config_section *s;<br>
+<br>
+       wl_list_for_each(s, &config->section_list, link)<br>
+               if (strcmp(s->name, section) == 0)<br>
+                       return s;<br>
+<br>
+       return NULL;<br>
+}</blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+</blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

+static struct weston_config_entry *<br>
+config_section_get_entry(struct weston_config_section *section,<br>
+                        const char *key)<br>
+{<br>
+       struct weston_config_entry *e;<br>
+<br>
+       if (section == NULL)<br>
+               return NULL;<br>
+       wl_list_for_each(e, &section->entry_list, link)<br>
+               if (strcmp(e->key, key) == 0)<br>
+                       return e;<br>
+<br>
+       return NULL;<br>
+}<br>
+<br>
+int<br>
+weston_config_section_get_int(struct weston_config_section *section,<br>
+                             const char *key,<br>
+                             int32_t *value, int32_t default_value)<br>
+{<br>
+       struct weston_config_entry *entry;<br>
+       char *end;<br>
+<br>
+       entry = config_section_get_entry(section, key);<br>
+       if (entry == NULL) {<br>
+               *value = default_value;<br>
+               errno = ENOENT;<br>
+               return -1;<br>
+       }<br>
+<br>
+       *value = strtol(entry->value, &end, 0);<br>
+       if (*end != '\0') {<br>
+               *value = default_value;<br>
+               errno = EINVAL;<br>
+               return -1;<br>
+       }<br>
+<br>
+       return 0;<br>
+}<br>
+<br>
+int<br>
+weston_config_section_get_uint(struct weston_config_section *section,<br>
+                              const char *key,<br>
+                              uint32_t *value, uint32_t default_value)<br>
+{<br>
+       struct weston_config_entry *entry;<br>
+       char *end;<br>
+<br>
+       entry = config_section_get_entry(section, key);<br>
+       if (entry == NULL) {<br>
+               *value = default_value;<br>
+               errno = ENOENT;<br>
+               return -1;<br>
+       }<br>
+<br>
+       *value = strtoul(entry->value, &end, 0);<br>
+       if (*end != '\0') {<br>
+               *value = default_value;<br>
+               errno = EINVAL;<br>
+               return -1;<br>
+       }<br>
+<br>
+       return 0;<br>
+}<br>
+<br>
+int<br>
+weston_config_section_get_string(struct weston_config_section *section,<br>
+                                const char *key,<br>
+                                const char **value, const char *default_value)<br>
+{<br>
+       struct weston_config_entry *entry;<br>
+<br>
+       entry = config_section_get_entry(section, key);<br>
+       if (entry == NULL) {<br>
+               if (default_value)<br>
+                       *value = strdup(default_value);<br>
+               errno = ENOENT;<br>
+               return -1;<br>
+       }<br>
+<br>
+       *value = strdup(entry->value);<br>
+<br>
+       return 0;<br>
+}<br>
+<br>
+int<br>
+weston_config_section_get_bool(struct weston_config_section *section,<br>
+                              const char *key,<br>
+                              int *value, int default_value)<br>
+{<br>
+       struct weston_config_entry *entry;<br>
+<br>
+       entry = config_section_get_entry(section, key);<br>
+       if (entry == NULL) {<br>
+               *value = default_value;<br>
+               errno = ENOENT;<br>
+               return -1;<br>
+       }<br>
+<br>
+       if (strcmp(entry->value, "false\n") == 0)<br>
+               *value = 0;<br>
+       else if (strcmp(entry->value, "true\n") == 0)<br>
+               *value = 1;<br>
+       else {<br>
+               *value = default_value;<br>
+               errno = EINVAL;<br>
+               return -1;<br>
+       }<br>
+<br>
+       return 0;<br>
+}<br>
+<br>
+static struct weston_config_section *<br>
+config_add_section(struct weston_config *config, const char *name)<br>
+{<br>
+       struct weston_config_section *section;<br>
+<br>
+       section = malloc(sizeof *section);<br>
+       section->name = strdup(name);<br>
+       wl_list_init(&section->entry_list);<br>
+       wl_list_insert(config->section_list.prev, &section->link);<br>
+<br>
+       return section;<br>
+}<br>
+<br>
+static struct weston_config_entry *<br>
+section_add_entry(struct weston_config_section *section,<br>
+                 const char *key, const char *value)<br>
+{<br>
+       struct weston_config_entry *entry;<br>
+<br>
+       entry = malloc(sizeof *entry);<br>
+       entry->key = strdup(key);<br>
+       entry->value = strdup(value);<br>
+       wl_list_insert(section->entry_list.prev, &entry->link);<br>
+<br>
+       return entry;<br>
+}<br>
+<br>
+struct weston_config *<br>
+weston_config_parse(const char *path)<br>
+{<br>
+       FILE *fp;<br>
+       char line[512], *p;<br>
+       struct weston_config *config;<br>
+       struct weston_config_section *section = NULL;<br>
+       int i;<br>
+<br>
+       config = malloc(sizeof *config);<br>
+       if (config == NULL) {<br>
+               free(path);<br>
+               return NULL;<br>
+       }<br>
+<br>
+       wl_list_init(&config->section_list);<br>
+<br>
+       fp = fopen(path, "r");<br>
+       if (fp == NULL) {<br>
+               fprintf(stderr, "couldn't open %s\n", path);<br>
+               free(config);<br>
+               return NULL;<br>
+       }<br>
+<br>
+       while (fgets(line, sizeof line, fp)) {<br>
+               if (line[0] == '#' || line[0] == '\n') {<br>
+                       continue;<br>
+               } if (line[0] == '[') {<br>
+                       p = strchr(&line[1], ']');<br>
+                       if (!p || p[1] != '\n') {<br>
+                               fprintf(stderr, "malformed "<br>
+                                       "section header: %s\n", line);<br>
+                               fclose(fp);<br>
+                               free(config);<br>
+                               return NULL;<br>
+                       }<br>
+                       p[0] = '\0';<br>
+                       section = config_add_section(config, &line[1]);<br>
+               } else if (p = strchr(line, '='), p && section) {<br>
+                       p[0] = '\0';<br>
+                       i = strlen(&p[1]);<br>
+                       p[i + 1] = '\0';<br>
+                       section_add_entry(section, line, &p[1]);<br>
+               } else {<br>
+                       fprintf(stderr, "malformed config line: %s\n", line);<br>
+                       fclose(fp);<br>
+                       free(config);<br>
+                       return NULL;<br>
+               }<br>
+       }<br>
+<br>
+       fclose(fp);<br>
+<br>
+       return config;<br>
+}<br>
diff --git a/shared/config-parser.h b/shared/config-parser.h<br>
index 1d0ee3f..0efbac3 100644<br>
--- a/shared/config-parser.h<br>
+++ b/shared/config-parser.h<br>
@@ -73,6 +73,32 @@ int<br>
 parse_options(const struct weston_option *options,<br>
              int count, int *argc, char *argv[]);<br>
<br>
+struct weston_config_section;<br>
+struct weston_config;<br>
+<br>
+struct weston_config_section *<br>
+weston_config_get_section(struct weston_config *config, const char *section);<br>
+int<br>
+weston_config_section_get_int(struct weston_config_section *section,<br>
+                             const char *key,<br>
+                             int32_t *value, int32_t default_value);<br>
+int<br>
+weston_config_section_get_uint(struct weston_config_section *section,<br>
+                              const char *key,<br>
+                              uint32_t *value, uint32_t default_value);<br>
+int<br>
+weston_config_section_get_string(struct weston_config_section *section,<br>
+                                const char *key,<br>
+                                const char **value,<br>
+                                const char *default_value);<br>
+int<br>
+weston_config_section_get_bool(struct weston_config_section *section,<br>
+                              const char *key,<br>
+                              int *value, int default_value);<br>
+struct weston_config *<br>
+weston_config_parse(const char *basename);<br>
+<br>
+<br>
 #ifdef  __cplusplus<br>
 }<br>
 #endif<br>
diff --git a/src/compositor.c b/src/compositor.c<br>
index 1617d96..cb374f7 100644<br>
--- a/src/compositor.c<br>
+++ b/src/compositor.c<br>
@@ -3139,6 +3139,8 @@ weston_compositor_init(struct weston_compositor *ec,<br>
                   keyboard_config_keys, ARRAY_LENGTH(keyboard_config_keys) },<br>
        };<br>
<br>
+       ec->config = weston_config_parse(config_file);<br>
+<br>
        memset(&xkb_names, 0, sizeof(xkb_names));<br>
        parse_config_file(config_file, cs, ARRAY_LENGTH(cs), ec);<br>
<br>
diff --git a/src/compositor.h b/src/compositor.h<br>
index 7d1d68e..e4c7ab2 100644<br>
--- a/src/compositor.h<br>
+++ b/src/compositor.h<br>
@@ -301,6 +301,7 @@ struct weston_compositor {<br>
<br>
        struct wl_display *wl_display;<br>
        struct weston_shell_interface shell_interface;<br>
+       struct weston_config *config;<br>
<br>
        struct wl_signal activate_signal;<br>
        struct wl_signal kill_signal;<br>
<span class=""><font color="#888888">--<br>
1.8.1.2<br>
<br>
</font></span></blockquote></div><br></div></div></div>