[PATCH] Add new config parser

Emilio Pozuelo Monfort pochu27 at gmail.com
Mon Apr 1 10:36:06 PDT 2013


Hi,

On 04/01/2013 06:42 PM, Kristian Høgsberg wrote:
> 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

s/comfig/config/

> keys from the data structure.  The old parser is still available, but
> we'll transition to the new approach over the next few commits.

I really like this change. I have glanced through the patch and I have one
question. Is there a need for weston_config_get_section() ? It is currently With
the weston_config_section struct being private, I wonder if there's any reason
to have it. I would personally change the getters to have a char *section
argument instead of the current struct *weston_config_section. That would add a
little overhead as you need to look up the section struct for every get(), but
it would also make things a little simpler for the caller. What do you think?

Regards,
Emilio

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



More information about the wayland-devel mailing list