diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2011-11-14 22:43:37 -0500 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2011-11-14 22:51:02 -0500 |
commit | ac3a59a0d16a90e1b7fb076ae1cb5b0a51f16f4e (patch) | |
tree | 9cf1bb4b2069e81570b9a2536bd02d5b6937c424 /clients/config.c | |
parent | 64f1c3fd520e38605fa408ffc8004300a0241a31 (diff) |
window: Add a cheesy parser for ini-files, use it in desktop-shell
Diffstat (limited to 'clients/config.c')
-rw-r--r-- | clients/config.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/clients/config.c b/clients/config.c new file mode 100644 index 0000000..f389b69 --- /dev/null +++ b/clients/config.c @@ -0,0 +1,137 @@ +/* + * 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 <window.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") == 0) + *(int *)key->data = 0; + else if (strcmp(value, "true") == 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; +} |