diff options
| author | Federico Angelilli <code@fedang.net> | 2024-09-20 23:57:19 +0200 |
|---|---|---|
| committer | Federico Angelilli <code@fedang.net> | 2024-09-20 23:57:19 +0200 |
| commit | ae59c294bfd4b73f6e751a3103c2ee7501068492 (patch) | |
| tree | efbcded195dfd24f9534f69f47f728ecca34b762 /src/config.c | |
| parent | bc70dead7fb518f073fecb21a04fa374e9ad6dd0 (diff) | |
Start parsing effects
Diffstat (limited to 'src/config.c')
| -rw-r--r-- | src/config.c | 119 |
1 files changed, 108 insertions, 11 deletions
diff --git a/src/config.c b/src/config.c index 84804bc..54d32eb 100644 --- a/src/config.c +++ b/src/config.c @@ -10,6 +10,7 @@ #include "util.h" #include "block.h" #include "blocks/scheme.h" +#include "effects/scheme.h" #define ANY_INI_IMPLEMENT #include "any_ini.h" @@ -30,6 +31,11 @@ static const config_entry_t bar_entries[] = { { 0 }, }; +static const config_entry_t effect_entries[] = { + { "duration", CONFIG_TIME, NULL, offsetof(effect_info_t, duration) }, + { 0 }, +}; + static const config_entry_t block_entries[] = { { "hidden", CONFIG_BOOL, NULL, offsetof(block_t, hidden) }, { "color", CONFIG_COLOR, NULL, offsetof(block_t, color) }, @@ -336,11 +342,24 @@ static config_status_t config_read_entry(const config_entry_t *entries, void *re return CONFIG_UNKNOWN; } +static config_status_t config_read_effect(const effect_scheme_t *scheme, effect_info_t *info, const char **type, + const char *section, const char *key, const char *value) +{ + config_status_t status = config_read_entry(effect_entries, info, type, section, key, value); + if (status != CONFIG_UNKNOWN) + return status; + + return status != CONFIG_UNKNOWN || scheme == NULL || scheme->entries == NULL + ? status + : config_read_entry(scheme->entries, info->state, type, section, key, value); +} + static config_status_t config_read_block(const block_scheme_t *scheme, block_t *block, const char **type, const char *section, const char *key, const char *value) { config_status_t status = config_read_entry(block_entries, block, type, section, key, value); - if (status != CONFIG_UNKNOWN) return status; + if (status != CONFIG_UNKNOWN) + return status; status = config_read_entry(block->type == BLOCK_GROUP ? block_group_entries : block_text_entries, block, type, section, key, value); @@ -383,9 +402,13 @@ void config_read(config_t *config, FILE *file) int errors = 0; bool bar_section = false; + const block_scheme_t *scheme = NULL; block_t *block = NULL; + const effect_scheme_t *escheme = NULL; + effect_info_t *info = NULL; + if (section != NULL) { if (!strncmp(section, "block.", 6)) { config->blocks = realloc(config->blocks, ++config->n_blocks * sizeof(block_t)); @@ -451,6 +474,68 @@ void config_read(config_t *config, FILE *file) "i:line", ini.line); goto skip_pair; + } else if (!strncmp(section, "effect.", 7)) { + config->infos = realloc(config->infos, ++config->n_infos * sizeof(effect_info_t)); + assert(config->infos != NULL); + info = &config->infos[config->n_infos - 1]; + + char *label = strcopy(section + 6); + if (label == NULL || *label == '\0') { + ++errors; + log_value_error("Effect section must have a valid label", + "s:section", section, + "i:line", ini.line); + } else { + for (size_t i = 0; i < config->n_infos - 1; i++) { + if (!strcmp(label, config->infos[i].label)) { + ++errors; + log_value_error("Effect section must have a unique label", + "s:section", section, + "i:line", ini.line); + } + } + } + + if ((key = any_ini_stream_next_key(&ini)) == NULL || strcmp(key, "type")) { + ++errors; + log_value_error("Effect section must start with a 'type' pair", + "s:section", section, + "s:wrong_key", key, + "i:line", ini.line); + goto skip_pair; + } + + value = any_ini_stream_next_value(&ini); + if (value == NULL) { + ++errors; + log_value_error("Effect type must be non-empty", + "s:section", section, + "i:line", ini.line); + goto skip_pair; + } + + for (int i = 0; effect_schemes[i] != NULL; i++) { + if (strcmp(effect_schemes[i]->name, value)) + continue; + + escheme = effect_schemes[i]; + memcpy(info, &escheme->info, sizeof(effect_info_t)); + + free(info->label); + info->label = label; + + if (escheme->size != 0) + info->state = calloc(1, escheme->size); + goto skip_pair; + } + + ++errors; + log_value_error("Effect type not supported", + "s:section", section, + "s:type", value, + "i:line", ini.line); + + goto skip_pair; } else if (!strcmp(section, "bar")) { bar_section = true; } else @@ -466,23 +551,28 @@ void config_read(config_t *config, FILE *file) "s:value", value, "i:line", ini.line); - if (!bar_section && block == NULL) + if (!bar_section && block == NULL && info == NULL) goto skip_pair; const char *type; config_status_t status; - if (bar_section) { - status = config_read_entry(bar_entries, config, &type, section, key, value); + if (info != NULL) { + status = config_read_effect(escheme, &config->infos[config->n_infos - 1], + &type, section, key, value); + } else { + if (bar_section) { + status = config_read_entry(bar_entries, config, &type, section, key, value); - // Try the block entries - if (status == CONFIG_UNKNOWN) - block = config->blocks; - } + // Try the block entries + if (status == CONFIG_UNKNOWN) + block = config->blocks; + } - if (block != NULL) { - status = config_read_block(scheme, &config->blocks[config->n_blocks - 1], - &type, section, key, value); + if (block != NULL) { + status = config_read_block(scheme, &config->blocks[config->n_blocks - 1], + &type, section, key, value); + } } switch (status) { @@ -523,6 +613,13 @@ skip_pair: errors += !scheme->validate(block, scheme); } + if (info != NULL && escheme != NULL && escheme->validate != NULL) { + if (errors != 0) + log_trace("Skipped validation for effect '%s'", section); + else + errors += !escheme->validate(info, escheme); + } + free(section); n_errors += errors; } while ((section = any_ini_stream_next_section(&ini)) != NULL); |
