diff --git a/config.c b/config.c index a8135b53..6b9663e7 100644 --- a/config.c +++ b/config.c @@ -133,11 +133,60 @@ parse_section_main(const char *key, const char *value, struct config *conf, return true; } +static bool +parse_section_colors(const char *key, const char *value, struct config *conf, + const char *path, unsigned lineno) +{ + uint32_t *color = NULL; + + if (strcmp(key, "foreground") == 0) color = &conf->colors.fg; + else if (strcmp(key, "background") == 0) color = &conf->colors.bg; + else if (strcmp(key, "regular0") == 0) color = &conf->colors.regular[0]; + else if (strcmp(key, "regular1") == 0) color = &conf->colors.regular[1]; + else if (strcmp(key, "regular2") == 0) color = &conf->colors.regular[2]; + else if (strcmp(key, "regular3") == 0) color = &conf->colors.regular[3]; + else if (strcmp(key, "regular4") == 0) color = &conf->colors.regular[4]; + else if (strcmp(key, "regular5") == 0) color = &conf->colors.regular[5]; + else if (strcmp(key, "regular6") == 0) color = &conf->colors.regular[6]; + else if (strcmp(key, "regular7") == 0) color = &conf->colors.regular[7]; + else if (strcmp(key, "bright0") == 0) color = &conf->colors.bright[0]; + else if (strcmp(key, "bright1") == 0) color = &conf->colors.bright[1]; + else if (strcmp(key, "bright2") == 0) color = &conf->colors.bright[2]; + else if (strcmp(key, "bright3") == 0) color = &conf->colors.bright[3]; + else if (strcmp(key, "bright4") == 0) color = &conf->colors.bright[4]; + else if (strcmp(key, "bright5") == 0) color = &conf->colors.bright[5]; + else if (strcmp(key, "bright6") == 0) color = &conf->colors.bright[6]; + else if (strcmp(key, "bright7") == 0) color = &conf->colors.bright[7]; + + else { + LOG_ERR("%s:%d: invalid key: %s", path, lineno, key); + return false; + } + + errno = 0; + char *end = NULL; + unsigned long res = strtoul(value, &end, 16); + + if (errno != 0) { + LOG_ERRNO("%s:%d: invalid color: %s", path, lineno, value); + return false; + } + + if (*end != '\0') { + LOG_ERR("%s:%d: invalid color: %s", path, lineno, value); + return false; + } + + *color = res & 0xffffff; + return true; +} + static bool parse_config_file(FILE *f, struct config *conf, const char *path) { enum section { SECTION_MAIN, + SECTION_COLORS, } section = SECTION_MAIN; /* Function pointer, called for each key/value line */ @@ -148,11 +197,13 @@ parse_config_file(FILE *f, struct config *conf, const char *path) /* Maps sections to line parser functions */ static const parser_fun_t section_parser_map[] = { [SECTION_MAIN] = &parse_section_main, + [SECTION_COLORS] = &parse_section_colors, }; #if defined(_DEBUG) && defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG static const char *const section_names[] = { [SECTION_MAIN] = "main", + [SECTION_COLORS] = "colors", }; #endif @@ -175,10 +226,25 @@ parse_config_file(FILE *f, struct config *conf, const char *path) break; } - /* No sections yet */ - if (line[0] == '[' && line[strlen(line) - 1] == ']') { - assert(false); - return false; + if (line[0] == '[') { + char *end = strchr(line, ']'); + if (end == NULL) { + LOG_ERR("%s:%d: syntax error: %s", path, lineno, line); + free(line); + return false; + } + + *end = '\0'; + + if (strcmp(&line[1], "colors") == 0) + section = SECTION_COLORS; + else { + LOG_ERR("%s:%d: invalid section name: %s", path, lineno, &line[1]); + free(line); + return false; + } + + continue; } char *key = strtok(line, "=");