aboutsummaryrefslogtreecommitdiff
path: root/src/config.c
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2024-09-20 23:57:19 +0200
committerFederico Angelilli <code@fedang.net>2024-09-20 23:57:19 +0200
commitae59c294bfd4b73f6e751a3103c2ee7501068492 (patch)
treeefbcded195dfd24f9534f69f47f728ecca34b762 /src/config.c
parentbc70dead7fb518f073fecb21a04fa374e9ad6dd0 (diff)
Start parsing effects
Diffstat (limited to 'src/config.c')
-rw-r--r--src/config.c119
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);