diff options
| author | Federico Angelilli <code@fedang.net> | 2024-11-29 14:20:57 +0100 |
|---|---|---|
| committer | Federico Angelilli <code@fedang.net> | 2024-11-29 14:20:57 +0100 |
| commit | 5a133f95105a494b9c6131132dcde27305b32a05 (patch) | |
| tree | 8d9da7cbd445b09e191df27255f6b114c122265a /src/config.c | |
| parent | 728e1e204d39bf11013ee999bcbff779aebc3399 (diff) | |
Improve parser errors
Diffstat (limited to 'src/config.c')
| -rw-r--r-- | src/config.c | 158 |
1 files changed, 124 insertions, 34 deletions
diff --git a/src/config.c b/src/config.c index 71b64de..6f66cd4 100644 --- a/src/config.c +++ b/src/config.c @@ -95,6 +95,79 @@ const char *config_type_to_string(config_type_t type) return types[type]; } +void config_format_string(FILE *stream, const char **string) +{ + if (*string == NULL) { + fputs("null", stream); + return; + } + + fputc('"', stream); + fputs(*string, stream); + fputc('"', stream); +} + +void config_format_int(FILE *stream, int *n) +{ + fprintf(stream, "%d", *n); +} + +void config_format_uint(FILE *stream, unsigned int *n) +{ + fprintf(stream, "%u", *n); +} + +void config_format_double(FILE *stream, double *n) +{ + fprintf(stream, "%g", *n); +} + +void config_format_bool(FILE *stream, bool *b) +{ + fputs(*b ? "true" : "false", stream); +} + +void config_format_color(FILE *stream, color_t *c) +{ + color_print(stream, c); +} + +void config_format_gradient(FILE *stream, gradient_t *g) +{ + gradient_print(stream, g); +} + +void config_format_time(FILE *stream, struct timespec *ts) +{ + timespec_print(stream, ts); +} + +void config_format_list(FILE *stream, const char ***list) +{ + const char **l = *list; + + fputc('[', stream); + for (size_t i = 0; l[i] != NULL; i++) { + config_format_string(stream, &l[i]); + if (l[i + 1] != NULL) + fputs(", ", stream); + } + fputc(']', stream); +} + +const any_log_formatter_t config_formatters[] = { + ANY_LOG_FORMATTER(config_format_string), + ANY_LOG_FORMATTER(config_format_int), + ANY_LOG_FORMATTER(config_format_uint), + ANY_LOG_FORMATTER(config_format_double), + ANY_LOG_FORMATTER(config_format_bool), + ANY_LOG_FORMATTER(config_format_color), + ANY_LOG_FORMATTER(config_format_gradient), + ANY_LOG_FORMATTER(config_format_int), + ANY_LOG_FORMATTER(config_format_time), + ANY_LOG_FORMATTER(config_format_list), +}; + static bool config_read_string(const char *value, char **result) { if (value == NULL) @@ -340,28 +413,24 @@ static block_t *config_alloc_block(config_t *config, const block_scheme_t *schem return block; } -static config_status_t config_read_block(block_t *block, config_type_t *type, const char *key, const char *value) +static config_status_t config_read_block(block_t *block, const config_entry_t **found, + const char *key, const char *value) { - size_t index = 0; - config_status_t status = config_read_entry(block_entries, block, &index, key, value); - *type = block_entries[index].type; + config_status_t status = config_read_entry(block_entries, block, found, key, value); if (status != CONFIG_UNKNOWN) return status; - if (block->type == BLOCK_GROUP) { - status = config_read_entry(block_group_entries, block, &index, key, value); - *type = block_group_entries[index].type; - } else if (block->type == BLOCK_TEXT) { - status = config_read_entry(block_text_entries, block, &index, key, value); - *type = block_text_entries[index].type; - } + if (block->type == BLOCK_GROUP) + status = config_read_entry(block_group_entries, block, found, key, value); + + if (block->type == BLOCK_TEXT) + status = config_read_entry(block_text_entries, block, found, key, value); if (status != CONFIG_UNKNOWN || block->scheme->entries == NULL) return status; - status = config_read_entry(block->scheme->entries, block, &index, key, value); - *type = block->scheme->entries[index].type; + status = config_read_entry(block->scheme->entries, block, found, key, value); return status; } @@ -409,11 +478,13 @@ void config_init(config_t *config) bar->spacing = 10; } -config_status_t config_read_entry(const config_entry_t *entries, void *result, size_t *index, const char *key, const char *value) +config_status_t config_read_entry(const config_entry_t *entries, void *result, const config_entry_t **found, + const char *key, const char *value) { for (size_t i = 0; entries[i].key != NULL; i++) { if (!strcmp(key, entries[i].key)) { - if (index != NULL) *index = i; + if (found != NULL) + *found = &entries[i]; result += entries[i].offset; bool nullable = entries[i].type == CONFIG_STRING || entries[i].type == CONFIG_LIST; @@ -586,39 +657,49 @@ int config_read(config_t *config, FILE *file) } else if (!strcmp(section, "bar")) { bar_section = true; - } else + } else { log_warn("Unknown section '%s'", section); + } + + log_debug("Reading section '%s'", section); } while ((key = any_ini_stream_next_key(&ini)) != NULL) { value = any_ini_stream_next_value(&ini); - log_value_trace("Reading entry", - "s:section", section, - "s:key", key, - "s:value", value, - "i:line", ini.line); + if (section == NULL) { + log_value_warn("Invalid entry outside any section", + "s:key", key, + "s:value", value, + "i:line", ini.line); + goto skip_pair; + } // Skip unknown sections - if (!bar_section && block == NULL && action == NULL) + if (!bar_section && block == NULL && action == NULL) { + log_value_trace("Skipping entry", + "s:key", key, + "s:value", value, + "i:line", ini.line); goto skip_pair; + } - config_type_t type; config_status_t status; + const config_entry_t *found = NULL; + void *result = NULL; if (bar_section) { - size_t index = 0; - status = config_read_entry(bar_entries, config, &index, key, value); + status = config_read_entry(bar_entries, config, &found, key, value); + result = config; // Try the block entries if (status == CONFIG_UNKNOWN) block = config->blocks[0]; - else - type = bar_entries[index].type; } if (block != NULL) { - status = config_read_block(block, &type, key, value); + status = config_read_block(block, &found, key, value); + result = block; } if (action != NULL) { @@ -627,16 +708,25 @@ int config_read(config_t *config, FILE *file) switch (status) { case CONFIG_SUCCESS: - log_value_debug("Parsed entry", - "s:section", section, - "s:key", key, - "s:value", value, - "s:type", config_type_to_string(type), - "i:line", ini.line); + if (result != NULL && found != NULL) { + result += found->offset; + log_value_debug("Parsed entry", + "s:key", key, + "g:value", config_formatters[found->type], result, + "s:type", config_type_to_string(found->type), + "i:line", ini.line); + } else { + log_value_debug("Parsed entry", + "s:key", key, + "s:value", value, + "i:line", ini.line); + } break; case CONFIG_INVALID: errors++; + + config_type_t type = found != NULL ? found->type : CONFIG_STRING; log_value_error("Invalid entry", "s:section", section, "s:key", key, |
