diff options
Diffstat (limited to 'src/config-parser.c')
-rw-r--r-- | src/config-parser.c | 340 |
1 files changed, 170 insertions, 170 deletions
diff --git a/src/config-parser.c b/src/config-parser.c index 0397a38..261c425 100644 --- a/src/config-parser.c +++ b/src/config-parser.c @@ -37,187 +37,187 @@ static int handle_key(const struct config_key *key, const char *value) { - char *end, *s; - int i, len; - unsigned int ui; - - 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_UNSIGNED_INTEGER: - ui = strtoul(value, &end, 0); - if (*end != '\n') { - fprintf(stderr, "invalid integer: %s\n", value); - return -1; - } - *(unsigned int *)key->data = ui; - return 0; - - case CONFIG_KEY_STRING: - len = strlen(value); - while (len > 0 && isspace(value[len - 1])) - len--; - s = malloc(len + 1); - if (s == NULL) - return -1; - memcpy(s, value, len); - s[len] = '\0'; - *(char **)key->data = s; - return 0; - - case CONFIG_KEY_BOOLEAN: - 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; - } - - return -1; + char *end, *s; + int i, len; + unsigned int ui; + + 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_UNSIGNED_INTEGER: + ui = strtoul(value, &end, 0); + if (*end != '\n') { + fprintf(stderr, "invalid integer: %s\n", value); + return -1; + } + *(unsigned int *)key->data = ui; + return 0; + + case CONFIG_KEY_STRING: + len = strlen(value); + while (len > 0 && isspace(value[len - 1])) + len--; + s = malloc(len + 1); + if (s == NULL) + return -1; + memcpy(s, value, len); + s[len] = '\0'; + *(char **)key->data = s; + return 0; + + case CONFIG_KEY_BOOLEAN: + 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; + } + + return -1; } int parse_config_file(int fd, - const struct config_section *sections, int num_sections, - void *data) + const struct config_section *sections, int num_sections, + void *data) { - FILE *fp; - char line[512], *p; - const struct config_section *current = NULL; - int i; + FILE *fp; + char line[512], *p; + const struct config_section *current = NULL; + int i; - if (fd == -1) - return -1; + if (fd == -1) + return -1; - fp = fdopen(dup(fd), "r"); - if (fp == NULL) { + fp = fdopen(dup(fd), "r"); + if (fp == NULL) { perror("couldn't open config file"); - return -1; - } - - rewind(fp); - - 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; + return -1; + } + + rewind(fp); + + 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; } int open_config_file(const char *name) { - const char *config_dir = getenv("XDG_CONFIG_HOME"); - const char *home_dir = getenv("HOME"); - const char *config_dirs = getenv("XDG_CONFIG_DIRS"); - char path[PATH_MAX]; - const char *p, *next; - int fd; - - /* Precedence is given to config files in the home directory, - * and then to directories listed in XDG_CONFIG_DIRS and - * finally to the current working directory. */ - - /* $XDG_CONFIG_HOME */ - if (config_dir) { - snprintf(path, sizeof path, "%s/%s", config_dir, name); - fd = open(path, O_RDONLY | O_CLOEXEC); - if (fd >= 0) - return fd; - } - - /* $HOME/.config */ - if (home_dir) { - snprintf(path, sizeof path, "%s/.config/%s", home_dir, name); - fd = open(path, O_RDONLY | O_CLOEXEC); - if (fd >= 0) - return fd; - } - - /* For each $XDG_CONFIG_DIRS: weston/<config_file> */ - if (!config_dirs) - config_dirs = "/etc/xdg"; /* See XDG base dir spec. */ - - for (p = config_dirs; *p != '\0'; p = next) { - next = strchrnul(p, ':'); - snprintf(path, sizeof path, - "%.*s/weston/%s", (int)(next - p), p, name); - fd = open(path, O_RDONLY | O_CLOEXEC); - if (fd >= 0) - return fd; - - if (*next == ':') - next++; - } - - /* Current working directory. */ - snprintf(path, sizeof path, "./%s", name); - fd = open(path, O_RDONLY | O_CLOEXEC); - - if (fd >= 0) - fprintf(stderr, - "using config in current working directory: %s\n", - path); - else - fprintf(stderr, "config file \"%s\" not found.\n", name); - - return fd; + const char *config_dir = getenv("XDG_CONFIG_HOME"); + const char *home_dir = getenv("HOME"); + const char *config_dirs = getenv("XDG_CONFIG_DIRS"); + char path[PATH_MAX]; + const char *p, *next; + int fd; + + /* Precedence is given to config files in the home directory, + * and then to directories listed in XDG_CONFIG_DIRS and + * finally to the current working directory. */ + + /* $XDG_CONFIG_HOME */ + if (config_dir) { + snprintf(path, sizeof path, "%s/%s", config_dir, name); + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd >= 0) + return fd; + } + + /* $HOME/.config */ + if (home_dir) { + snprintf(path, sizeof path, "%s/.config/%s", home_dir, name); + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd >= 0) + return fd; + } + + /* For each $XDG_CONFIG_DIRS: weston/<config_file> */ + if (!config_dirs) + config_dirs = "/etc/xdg"; /* See XDG base dir spec. */ + + for (p = config_dirs; *p != '\0'; p = next) { + next = strchrnul(p, ':'); + snprintf(path, sizeof path, + "%.*s/weston/%s", (int)(next - p), p, name); + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd >= 0) + return fd; + + if (*next == ':') + next++; + } + + /* Current working directory. */ + snprintf(path, sizeof path, "./%s", name); + fd = open(path, O_RDONLY | O_CLOEXEC); + + if (fd >= 0) + fprintf(stderr, + "using config in current working directory: %s\n", + path); + else + fprintf(stderr, "config file \"%s\" not found.\n", name); + + return fd; } |