diff options
| author | Federico Angelilli <code@fedang.net> | 2024-09-08 13:07:22 +0200 |
|---|---|---|
| committer | Federico Angelilli <code@fedang.net> | 2024-09-08 13:07:22 +0200 |
| commit | 43238419974e599a84f17b5faa8fb52401bdfe90 (patch) | |
| tree | 6b27b61d081e4f4c8399b3caf8551d1ba75adf1e | |
| parent | 6d0ce31b0ae5df97d4a340c54b66d95598b336a4 (diff) | |
Refactor config parsing
| -rw-r--r-- | src/block.c | 5 | ||||
| -rw-r--r-- | src/block.h | 11 | ||||
| -rw-r--r-- | src/blocks/group.c | 15 | ||||
| -rw-r--r-- | src/blocks/info.h | 12 | ||||
| -rw-r--r-- | src/blocks/ram.c | 22 | ||||
| -rw-r--r-- | src/blocks/scheme.c | 5 | ||||
| -rw-r--r-- | src/blocks/scheme.h | 17 | ||||
| -rw-r--r-- | src/blocks/text.c | 16 | ||||
| -rw-r--r-- | src/config.c | 129 | ||||
| -rw-r--r-- | src/config.h | 21 |
10 files changed, 122 insertions, 131 deletions
diff --git a/src/block.c b/src/block.c index bfe2ec5..a3e7acb 100644 --- a/src/block.c +++ b/src/block.c @@ -57,4 +57,9 @@ void block_free(block_t *block) free(block->group.children); } + + if (block->finalize_cb != NULL) + block->finalize_cb(block); + + free(block->state); } diff --git a/src/block.h b/src/block.h index 5301a7b..1ceedf1 100644 --- a/src/block.h +++ b/src/block.h @@ -7,6 +7,7 @@ #include "event.h" #include "util.h" +#include "config.h" // Element or text alignment // @@ -33,19 +34,23 @@ typedef void (*block_event_t)(block_t *block, event_t event); // typedef void (*block_update_t)(block_t *block); +// Block finalization routine +// +typedef void (*block_finalize_t)(block_t *block); + // Block struct // struct block { block_type_t type; char *label; bool active; + bool hidden; + void *state; struct timespec update_interval; struct timespec update_last; block_update_t update_cb; block_event_t event_cb; - void *info; - - bool hidden; + block_finalize_t finalize_cb; color_t color; color_t line_color; int line_width; diff --git a/src/blocks/group.c b/src/blocks/group.c deleted file mode 100644 index 00afb00..0000000 --- a/src/blocks/group.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "info.h" - -static const config_entry_t block_group_entries[] = { - { "spacing", CONFIG_INT, offsetof(block_t, group.spacing) }, - { 0 }, -}; - -// TODO -const config_block_t block_group_info = { - .type_name = "group", - .type_size = 0, - .base = { 0 }, - .entries = block_group_entries, - .apply = NULL, -}; diff --git a/src/blocks/info.h b/src/blocks/info.h deleted file mode 100644 index 2b42c72..0000000 --- a/src/blocks/info.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef COMET_BLOCKS_H -#define COMET_BLOCKS_H - -#include "../config.h" - -extern const config_block_t block_text_info; - -extern const config_block_t block_group_info; - -extern const config_block_t block_ram_info; - -#endif diff --git a/src/blocks/ram.c b/src/blocks/ram.c deleted file mode 100644 index 2190b20..0000000 --- a/src/blocks/ram.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "info.h" - -static bool block_ram_apply(block_t *block, void *result) -{ - return true; -} - -static const config_entry_t block_ram_entries[] = { - { "text", CONFIG_STRING, offsetof(block_t, text.text) }, - { "text-color", CONFIG_COLOR, offsetof(block_t, text.text_color) }, - { "text-size", CONFIG_INT, offsetof(block_t, text.text_size) }, - { 0 }, -}; - -const config_block_t block_ram_info = { - .type_name = "ram", - .type_size = 0, - .base = { 0 }, - .entries = block_ram_entries, - .apply = block_ram_apply, -}; - diff --git a/src/blocks/scheme.c b/src/blocks/scheme.c new file mode 100644 index 0000000..7a49b90 --- /dev/null +++ b/src/blocks/scheme.c @@ -0,0 +1,5 @@ +#include "scheme.h" + +const block_scheme_t *block_schemes[] = { + NULL, +}; diff --git a/src/blocks/scheme.h b/src/blocks/scheme.h new file mode 100644 index 0000000..b73f181 --- /dev/null +++ b/src/blocks/scheme.h @@ -0,0 +1,17 @@ +#ifndef COMET_SCHEME_H +#define COMET_SCHEME_H + +#include "../block.h" + +typedef struct block_scheme { + const char *name; + block_t block; + size_t size; + const config_entry_t *entries; + + bool (*block_scheme_verify_t)(block_t *block, struct block_scheme *scheme); +} block_scheme_t; + +extern const block_scheme_t *block_schemes[]; + +#endif diff --git a/src/blocks/text.c b/src/blocks/text.c deleted file mode 100644 index 74df3c3..0000000 --- a/src/blocks/text.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "info.h" - -static const config_entry_t block_text_entries[] = { - { "text", CONFIG_STRING, offsetof(block_t, text.text) }, - { "text-color", CONFIG_COLOR, offsetof(block_t, text.text_color) }, - { "text-size", CONFIG_INT, offsetof(block_t, text.text_size) }, - { 0 }, -}; - -const config_block_t block_text_info = { - .type_name = "text", - .type_size = 0, - .base = { 0 }, - .entries = block_text_entries, - .apply = NULL, -}; diff --git a/src/config.c b/src/config.c index cfeb70f..76551fa 100644 --- a/src/config.c +++ b/src/config.c @@ -9,7 +9,7 @@ #include "config.h" #include "util.h" #include "block.h" -#include "blocks/info.h" +#include "blocks/scheme.h" #define ANY_INI_IMPLEMENT #include "any_ini.h" @@ -21,24 +21,44 @@ typedef enum { } config_status_t; static const config_entry_t bar_entries[] = { - { "width", CONFIG_UINT, offsetof(config_t, width) }, - { "height", CONFIG_UINT, offsetof(config_t, height) }, - { "font", CONFIG_STRING, offsetof(config_t, font) }, - { "monitor", CONFIG_STRING, offsetof(config_t, monitor) }, - { "override-redirect", CONFIG_BOOL, offsetof(config_t, override_redirect) }, - { "background", CONFIG_COLOR, offsetof(config_t, background) }, + { "width", CONFIG_UINT, NULL, offsetof(config_t, width) }, + { "height", CONFIG_UINT, NULL, offsetof(config_t, height) }, + { "font", CONFIG_STRING, NULL, offsetof(config_t, font) }, + { "monitor", CONFIG_STRING, NULL, offsetof(config_t, monitor) }, + { "override-redirect", CONFIG_BOOL, NULL, offsetof(config_t, override_redirect) }, + { "background", CONFIG_COLOR, NULL, offsetof(config_t, background) }, { 0 }, }; static const config_entry_t block_entries[] = { - { "hidden", CONFIG_BOOL, offsetof(block_t, hidden) }, - { "color", CONFIG_COLOR, offsetof(block_t, color) }, - { "line-color", CONFIG_COLOR, offsetof(block_t, line_color) }, - { "line-width", CONFIG_INT, offsetof(block_t, line_width) }, - { "x-padding", CONFIG_INT, offsetof(block_t, x_padding) }, - { "y-padding", CONFIG_INT, offsetof(block_t, y_padding) }, - { "min-width", CONFIG_INT, offsetof(block_t, min_width) }, - { "max-width", CONFIG_INT, offsetof(block_t, max_width) }, + { "hidden", CONFIG_BOOL, NULL, offsetof(block_t, hidden) }, + { "color", CONFIG_COLOR, NULL, offsetof(block_t, color) }, + { "line-color", CONFIG_COLOR, NULL, offsetof(block_t, line_color) }, + { "line-width", CONFIG_INT, NULL, offsetof(block_t, line_width) }, + { "x-padding", CONFIG_INT, NULL, offsetof(block_t, x_padding) }, + { "y-padding", CONFIG_INT, NULL, offsetof(block_t, y_padding) }, + { "min-width", CONFIG_INT, NULL, offsetof(block_t, min_width) }, + { "max-width", CONFIG_INT, NULL, offsetof(block_t, max_width) }, + { 0 }, +}; + +static const config_entry_t block_group_entries[] = { + { "spacing", CONFIG_INT, NULL, offsetof(block_t, group.spacing) }, + { 0 }, +}; + +static config_enum_t text_align_enum[] = { + { "left", ALIGN_LEFT }, + { "center", ALIGN_CENTER }, + { "right", ALIGN_RIGHT }, + { 0 }, +}; + +static const config_entry_t block_text_entries[] = { + { "text", CONFIG_STRING, NULL, offsetof(block_t, text.text) }, + { "text-color", CONFIG_COLOR, NULL, offsetof(block_t, text.text_color) }, + { "text-size", CONFIG_INT, NULL, offsetof(block_t, text.text_size) }, + { "text-align", CONFIG_ENUM, text_align_enum, offsetof(block_t, text.text_size) }, { 0 }, }; @@ -91,14 +111,12 @@ static bool config_read_double(const char *value, double *result) static bool config_read_bool(const char *value, bool *result) { - size_t lenght = strlen(value); - - if (lenght == 5 && !strcmp(value, "false")) { + if (!strcmp(value, "false")) { *result = false; return true; } - if (lenght == 4 && !strcmp(value, "true")) { + if (!strcmp(value, "true")) { *result = true; return true; } @@ -152,6 +170,19 @@ static bool config_read_color(const char *value, color_t *result) return false; } +static bool config_read_enum(const char *value, config_enum_t *data, int *result) +{ + for (int i = 0; data[i].label != NULL; i++) { + if (!strcmp(value, data[i].label)) { + *result = data[i].value; + return true; + } + } + + log_debug("Invalid enum value '%s'", value); + return false; +} + static config_status_t config_read_entry(const config_entry_t *entries, void *result, const char **type, const char *section, const char *key, const char *value) { @@ -218,6 +249,13 @@ static config_status_t config_read_entry(const config_entry_t *entries, void *re } break; + case CONFIG_ENUM: + if (config_read_enum(value, (config_enum_t *)entries[i].data, (int *)result)) { + log_debug("Set '%s.%s' to '%d'", section, key, *(int *)result); + return CONFIG_SUCCESS; + } + break; + default: unreachable(); } @@ -229,13 +267,18 @@ static config_status_t config_read_entry(const config_entry_t *entries, void *re return CONFIG_UNKNOWN; } -static config_status_t config_read_block(const config_block_t *info, block_t *block, void *result, const char **type, +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); - return status != CONFIG_UNKNOWN - ? status - : config_read_entry(info->entries, result, type, section, key, value); + 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); + + return status != CONFIG_UNKNOWN || scheme->entries != NULL + ? status + : config_read_entry(scheme->entries, block->state, type, section, key, value); } void config_init(config_t *config) @@ -265,9 +308,8 @@ void config_read(config_t *config, FILE *file) char *key = NULL, *value = NULL; int errors = 0; - const config_block_t *info = NULL; + const block_scheme_t *scheme = NULL; const config_entry_t *entries = NULL; - void *result = NULL; block_t *block = NULL; if (section != NULL) { @@ -303,27 +345,18 @@ void config_read(config_t *config, FILE *file) goto skip_pair; } - - // FIXME: Move this somewhere else - const config_block_t block_infos[] = { - block_text_info, - block_group_info, - block_ram_info, - { 0 } - }; - - for (int i = 0; block_infos[i].type_name != NULL; i++) { - if (strcmp(block_infos[i].type_name, value)) + for (int i = 0; block_schemes[i] != NULL; i++) { + if (strcmp(block_schemes[i]->name, value)) continue; - info = &block_infos[i]; - block_copy(block, &info->base); + + scheme = block_schemes[i]; + block_copy(block, &scheme->block); free(block->label); block->label = label; - if (info->type_size == 0) - result = block; - else - block->info = result = malloc(info->type_size); + if (scheme->size != 0) + block->state = malloc(scheme->size); + goto skip_pair; } @@ -338,7 +371,6 @@ void config_read(config_t *config, FILE *file) // TODO } else if (!strcmp(section, "bar")) { entries = bar_entries; - result = config; } else log_warn("Unknown section '%s'", section); } @@ -357,10 +389,10 @@ void config_read(config_t *config, FILE *file) config_status_t status; if (block != NULL) - status = config_read_block(info, &config->blocks[config->n_blocks - 1], result, + status = config_read_block(scheme, &config->blocks[config->n_blocks - 1], &type, section, key, value); else if (entries != NULL) - status = config_read_entry(entries, result, &type, section, key, value); + status = config_read_entry(entries, config, &type, section, key, value); else goto skip_pair; @@ -395,13 +427,6 @@ skip_pair: free(value); } - if (block != NULL && info->apply != NULL) { - if (errors != 0) - log_trace("Skipped '%s' apply for '%s'", info->type_name, section); - else - errors += !info->apply(block, result); - } - free(section); n_errors += errors; } while ((section = any_ini_stream_next_section(&ini)) != NULL); diff --git a/src/config.h b/src/config.h index d76c515..024b6f6 100644 --- a/src/config.h +++ b/src/config.h @@ -4,7 +4,9 @@ #include <stdio.h> #include <stdint.h> -#include "block.h" +#include "util.h" + +typedef struct block block_t; typedef enum { CONFIG_STRING, @@ -13,24 +15,16 @@ typedef enum { CONFIG_DOUBLE, CONFIG_BOOL, CONFIG_COLOR, + CONFIG_ENUM, } config_type_t; typedef struct { const char *key; config_type_t type; + void *data; size_t offset; } config_entry_t; -typedef bool (*config_block_apply_t)(block_t *block, void *result); - -typedef struct { - const char *type_name; - size_t type_size; - block_t base; - const config_entry_t *entries; - config_block_apply_t apply; -} config_block_t; - typedef struct { size_t n_blocks; block_t *blocks; @@ -42,6 +36,11 @@ typedef struct { color_t background; } config_t; +typedef struct { + const char *label; + int value; +} config_enum_t; + void config_init(config_t *config); void config_read(config_t *config, FILE *file); |
