diff options
| author | Federico Angelilli <code@fedang.net> | 2024-09-18 14:49:59 +0200 |
|---|---|---|
| committer | Federico Angelilli <code@fedang.net> | 2024-09-18 14:49:59 +0200 |
| commit | 0eceb95c0a4b517d7eb537a464089f011e3804e2 (patch) | |
| tree | 54e2646d5a7c43b3fec074ebe98d4a33aefde025 /src/config.c | |
| parent | bc70dead7fb518f073fecb21a04fa374e9ad6dd0 (diff) | |
Add effect parsingeffect-conf
Diffstat (limited to 'src/config.c')
| -rw-r--r-- | src/config.c | 117 |
1 files changed, 107 insertions, 10 deletions
diff --git a/src/config.c b/src/config.c index 84804bc..1b88b06 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" @@ -43,6 +44,11 @@ static const config_entry_t block_entries[] = { { 0 }, }; +static const config_entry_t effect_entries[] = { + { "duration", CONFIG_TIME, NULL, offsetof(effect_t, duration) }, + { 0 }, +}; + static const config_entry_t block_group_entries[] = { { "spacing", CONFIG_UINT, NULL, offsetof(block_t, group.spacing) }, { "blocks", CONFIG_LIST, NULL, offsetof(block_t, group.children) }, @@ -350,6 +356,17 @@ static config_status_t config_read_block(const block_scheme_t *scheme, block_t * : config_read_entry(scheme->entries, block->state, type, section, key, value); } +static config_status_t config_read_effect(const effect_scheme_t *scheme, effect_t *effect, const char **type, + const char *section, const char *key, const char *value) +{ + config_status_t status = config_read_entry(effect_entries, effect, 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, effect->state, type, section, key, value); +} + void config_init(config_t *config) { const config_t config_default = { @@ -383,9 +400,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_t *effect = NULL; + if (section != NULL) { if (!strncmp(section, "block.", 6)) { config->blocks = realloc(config->blocks, ++config->n_blocks * sizeof(block_t)); @@ -451,6 +472,70 @@ void config_read(config_t *config, FILE *file) "i:line", ini.line); goto skip_pair; + } else if (!strncmp(section, "effect.", 7)) { + config->effects = realloc(config->effects, ++config->n_effects * sizeof(effect_t)); + assert(config->effects != NULL); + effect = &config->effects[config->n_effects - 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_effects - 1; i++) { + if (!strcmp(label, config->effects[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]; + effect_copy(effect, &escheme->effect); + free(effect->label); + effect->label = label; + + if (escheme->size != 0) { + effect->state = malloc(escheme->size); + memset(effect->state, 0, 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,25 +551,31 @@ 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 && effect == 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 (effect != NULL) { + status = config_read_effect(escheme, &config->effects[config->n_effects - 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) { case CONFIG_SUCCESS: break; @@ -522,6 +613,12 @@ skip_pair: else errors += !scheme->validate(block, scheme); } + if (effect != NULL && escheme != NULL && escheme->validate != NULL) { + if (errors != 0) + log_trace("Skipped validation for effect '%s'", section); + else + errors += !escheme->validate(effect, escheme); + } free(section); n_errors += errors; |
