diff options
author | Pekka Paalanen <ppaalanen@gmail.com> | 2011-12-05 15:58:11 +0200 |
---|---|---|
committer | Pekka Paalanen <ppaalanen@gmail.com> | 2011-12-08 10:25:12 +0200 |
commit | c1765c67b394ec82c5d576140e0e297088deaabb (patch) | |
tree | c1dbd63e13f96c3061b79054f246a601d1bb0d73 /shared | |
parent | 02dfb7514547e48045e20ed57f361cfc7826ada3 (diff) |
move config parser to a convenience library
Create a new directory for convenience librariers that can be shared
between compositor components and clients.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
Diffstat (limited to 'shared')
-rw-r--r-- | shared/Makefile.am | 3 | ||||
-rw-r--r-- | shared/configparser.c | 172 | ||||
-rw-r--r-- | shared/configparser.h | 54 |
3 files changed, 229 insertions, 0 deletions
diff --git a/shared/Makefile.am b/shared/Makefile.am new file mode 100644 index 0000000..a964a04 --- /dev/null +++ b/shared/Makefile.am @@ -0,0 +1,3 @@ +noinst_LTLIBRARIES = libconfigparser.la +libconfigparser_la_SOURCES = configparser.c \ + configparser.h diff --git a/shared/configparser.c b/shared/configparser.c new file mode 100644 index 0000000..c48fe4c --- /dev/null +++ b/shared/configparser.c @@ -0,0 +1,172 @@ +/* + * Copyright © 2011 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +#include "configparser.h" + +static int +handle_key(const struct config_key *key, const char *value) +{ + char *end, *s; + int i, len; + + switch (key->type) { + case CONFIG_KEY_INTEGER: + i = strtol(value, &end, 0); + if (*end != '\n') { + fprintf(stderr, "invalid integer: %s\n", value); + return -1; + } + *(int *)key->data = i; + return 0; + + case CONFIG_KEY_STRING: + len = strlen(value); + s = malloc(len); + if (s == NULL) + return -1; + memcpy(s, value, len - 1); + s[len - 1] = '\0'; + *(char **)key->data = s; + return 0; + + case CONFIG_KEY_BOOL: + if (strcmp(value, "false\n") == 0) + *(int *)key->data = 0; + else if (strcmp(value, "true\n") == 0) + *(int *)key->data = 1; + else { + fprintf(stderr, "invalid bool: %s\n", value); + return -1; + } + return 0; + + default: + assert(0); + break; + } +} + +int +parse_config_file(const char *path, + const struct config_section *sections, int num_sections, + void *data) +{ + FILE *fp; + char line[512], *p; + const struct config_section *current = NULL; + int i; + + fp = fopen(path, "r"); + if (fp == NULL) { + fprintf(stderr, "couldn't open %s\n", path); + return -1; + } + + 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); + return -1; + } + if (current && current->done) + current->done(data); + p[0] = '\0'; + for (i = 0; i < num_sections; i++) { + if (strcmp(sections[i].name, &line[1]) == 0) { + current = §ions[i]; + break; + } + } + if (i == num_sections) + current = NULL; + } else if (p = strchr(line, '='), p != NULL) { + if (current == NULL) + continue; + p[0] = '\0'; + for (i = 0; i < current->num_keys; i++) { + if (strcmp(current->keys[i].name, line) == 0) { + if (handle_key(¤t->keys[i], &p[1]) < 0) { + fclose(fp); + return -1; + } + break; + } + } + } else { + fprintf(stderr, "malformed config line: %s\n", line); + fclose(fp); + return -1; + } + } + + if (current && current->done) + current->done(data); + + fclose(fp); + + return 0; +} + +char * +config_file_path(const char *name) +{ + const char dotconf[] = "/.config/"; + const char *config_dir; + const char *home_dir; + char *path; + size_t size; + + config_dir = getenv("XDG_CONFIG_HOME"); + if (!config_dir) { + home_dir = getenv("HOME"); + if (!home_dir) { + fprintf(stderr, "HOME is not set, using cwd.\n"); + return strdup(name); + } + + size = strlen(home_dir) + sizeof dotconf + strlen(name); + path = malloc(size); + if (!path) + return NULL; + + snprintf(path, size, "%s%s%s", home_dir, dotconf, name); + return path; + } + + size = strlen(config_dir) + 1 + strlen(name) + 1; + path = malloc(size); + if (!path) + return NULL; + + snprintf(path, size, "%s/%s", config_dir, name); + return path; +} diff --git a/shared/configparser.h b/shared/configparser.h new file mode 100644 index 0000000..93b335c --- /dev/null +++ b/shared/configparser.h @@ -0,0 +1,54 @@ +/* + * Copyright © 2008 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef CONFIGPARSER_H +#define CONFIGPARSER_H + +enum { + CONFIG_KEY_INTEGER, + CONFIG_KEY_STRING, + CONFIG_KEY_BOOL +}; + +struct config_key { + const char *name; + int type; + void *data; +}; + +struct config_section { + const char *name; + const struct config_key *keys; + int num_keys; + void (*done)(void *data); +}; + +int +parse_config_file(const char *path, + const struct config_section *sections, int num_sections, + void *data); + +char * +config_file_path(const char *name); + +#endif /* CONFIGPARSER_H */ + |