diff --git a/config.c b/config.c index 361ed65..6795208 100644 --- a/config.c +++ b/config.c @@ -123,6 +123,39 @@ load_channels_section(const config_setting_t *config_section) return result; } +static void +load_constants_section(const config_setting_t *config_section, ConstantRegistry *constants) +{ + ssize_t length = config_setting_length(config_section); + if (length <= 0) { + return; + } + for (ssize_t i = 0; i < length; ++i) { + config_setting_t *item = config_setting_get_elem(config_section, i); + if (!item) { + continue; + } + const char *name; + long long value; + if (!(name = config_setting_name(item))) { + config_setting_lookup_string(item, "name", &name); + } + if (!name) { + continue; + } + if (config_setting_is_scalar(item) == CONFIG_TRUE) { + value = config_setting_get_int64(item); + } else if (config_setting_is_group(item) == CONFIG_TRUE) { + if (config_setting_lookup_int64(item, "value", &value) == CONFIG_FALSE) { + continue; + } + } else { + continue; + } + hash_table_insert(constants, hash_table_key_from_cstr(name), &value); + } +} + bool load_config(const config_setting_t *config_root, FullConfig *config) { @@ -131,6 +164,9 @@ load_config(const config_setting_t *config_root, FullConfig *config) } const config_setting_t *node_config = config_setting_get_member(config_root, "nodes"); const config_setting_t *channel_config = config_setting_get_member(config_root, "channels"); + const config_setting_t *constants_config = config_setting_get_member(config_root, "constants"); + hash_table_init(&config->constants, NULL); + load_constants_section(constants_config, &config->constants); config->nodes = load_nodes_section(node_config); config->channels = load_channels_section(channel_config); return true; @@ -152,4 +188,25 @@ reset_config(FullConfig *config) config->channels.items = NULL; config->channels.length = 0; } + hash_table_deinit(&config->constants); +} + +long long +resolve_constant(const ConstantRegistry * registry, const config_setting_t * setting) +{ + if (!setting) { + return 0; + } + if (config_setting_type(setting) == CONFIG_TYPE_STRING) { + if (!registry) { + return 1; + } + const char *name = config_setting_get_string(setting); + HashTableIndex idx = hash_table_find(registry, hash_table_key_from_cstr(name)); + if (idx < 0) { + return 0; + } + return registry->value_array[idx]; + } + return config_setting_get_int64(setting); } diff --git a/config.cfg b/config.cfg index 5181dbd..3eb7e08 100644 --- a/config.cfg +++ b/config.cfg @@ -1,8 +1,13 @@ +constants = { + ns_stdin = 0; + ns_clickpad = 1; +}; + nodes = { stdin = { type = "getchar"; options = { - namespace = 0; + namespace = "ns_stdin"; }; }; print = { @@ -13,7 +18,7 @@ nodes = { type = "evdev"; options = { file = "/dev/input/event7"; - namespace = 1; + namespace = "ns_clickpad"; }; }; }; diff --git a/config.h b/config.h index 8e026c7..5083cd8 100644 --- a/config.h +++ b/config.h @@ -3,6 +3,7 @@ #include #include "defs.h" +#include "hash_table.h" typedef struct { const char *name; @@ -27,12 +28,16 @@ typedef struct { GraphChannelConfig *items; } GraphChannelConfigSection; +typedef TYPED_HASH_TABLE(long long) ConstantRegistry; + typedef struct { GraphNodeConfigSection nodes; GraphChannelConfigSection channels; + ConstantRegistry constants; } FullConfig; bool load_config(const config_setting_t *config_root, FullConfig *config); void reset_config(FullConfig *config); +long long resolve_constant(const ConstantRegistry * registry, const config_setting_t * setting); #endif /* end of include guard: CONFIG_H_ */ diff --git a/graph.c b/graph.c index 7c13fb7..45694eb 100644 --- a/graph.c +++ b/graph.c @@ -88,12 +88,12 @@ graph_channel_init(GraphChannel * ch, GraphNode * start, size_t start_idx, Graph } GraphNode * -graph_node_new(GraphNodeSpecification * spec, GraphNodeConfig * config) +graph_node_new(GraphNodeSpecification * spec, GraphNodeConfig * config, const ConstantRegistry * constants) { if (!spec || !spec->create) { return NULL; } - return spec->create(spec, config); + return spec->create(spec, config, constants); } void diff --git a/graph.h b/graph.h index 25cf6e6..b66e52f 100644 --- a/graph.h +++ b/graph.h @@ -29,14 +29,14 @@ struct graph_channel { }; struct graph_node_specification { - GraphNode * (*create)(GraphNodeSpecification * self, GraphNodeConfig * config); + GraphNode * (*create)(GraphNodeSpecification * self, GraphNodeConfig * config, const ConstantRegistry * constants); void (*destroy)(GraphNodeSpecification * self, GraphNode * target); void (*register_io)(GraphNodeSpecification * self, GraphNode * target, ProcessingState * state); char *name; }; void graph_channel_init(GraphChannel * ch, GraphNode * start, size_t start_idx, GraphNode * end, size_t end_idx); -GraphNode *graph_node_new(GraphNodeSpecification * spec, GraphNodeConfig * config); +GraphNode *graph_node_new(GraphNodeSpecification * spec, GraphNodeConfig * config, const ConstantRegistry * constants); void graph_node_delete(GraphNode * self); void graph_node_register_io(GraphNode * self, ProcessingState * state); void graph_channel_list_init(GraphChannelList * lst); diff --git a/main.c b/main.c index 137c9be..5766d6b 100644 --- a/main.c +++ b/main.c @@ -39,7 +39,7 @@ main(int argc, char ** argv) fprintf(stderr, "Unknown node type \"%s\" for node %ld \"%s\"\n", type_name, i, loaded_config.nodes.items[i].name); exit(1); } - if (!(nodes[i] = graph_node_new(spec, &loaded_config.nodes.items[i]))) { + if (!(nodes[i] = graph_node_new(spec, &loaded_config.nodes.items[i], &loaded_config.constants))) { perror("Failed to create node"); fprintf(stderr, "%ld \"%s\"\n", i, loaded_config.nodes.items[i].name); exit(1); diff --git a/nodes/evdev.c b/nodes/evdev.c index c8f9e47..e4ae62b 100644 --- a/nodes/evdev.c +++ b/nodes/evdev.c @@ -69,7 +69,7 @@ handle_io(EventPositionBase * self, int fd, bool is_output) } static GraphNode * -create(GraphNodeSpecification * spec, GraphNodeConfig * config) +create(GraphNodeSpecification * spec, GraphNodeConfig * config, const ConstantRegistry * constants) { EvdevGraphNode * node = T_ALLOC(1, EvdevGraphNode); if (!node) { @@ -77,7 +77,7 @@ create(GraphNodeSpecification * spec, GraphNodeConfig * config) } const char *filename = NULL; if (config) { - config_setting_lookup_int(config->options, "namespace", &node->namespace); + node->namespace = resolve_constant(constants, config_setting_get_member(config->options, "namespace")); config_setting_lookup_string(config->options, "file", &filename); } if (filename == NULL) { diff --git a/nodes/getchar.c b/nodes/getchar.c index 7e84ae9..967a916 100644 --- a/nodes/getchar.c +++ b/nodes/getchar.c @@ -49,7 +49,7 @@ handle_io(EventPositionBase * self, int fd, bool is_output) } static GraphNode * -create(GraphNodeSpecification * spec, GraphNodeConfig * config) +create(GraphNodeSpecification * spec, GraphNodeConfig * config, const ConstantRegistry * constants) { GetcharGraphNode * node = T_ALLOC(1, GetcharGraphNode); if (!node) { @@ -70,11 +70,8 @@ create(GraphNodeSpecification * spec, GraphNodeConfig * config) .handle_io = handle_io, .enabled = true, }, - .namespace = 0, + .namespace = resolve_constant(constants, config_setting_get_member(config->options, "namespace")), }; - if (config) { - config_setting_lookup_int(config->options, "namespace", &node->namespace); - } return &node->as_GraphNode; } diff --git a/nodes/print.c b/nodes/print.c index 543de2e..13e0f60 100644 --- a/nodes/print.c +++ b/nodes/print.c @@ -28,9 +28,10 @@ handle_event(EventPositionBase * self, EventNode * event) } static GraphNode * -create(GraphNodeSpecification * spec, GraphNodeConfig * config) +create(GraphNodeSpecification * spec, GraphNodeConfig * config, const ConstantRegistry * constants) { (void) config; + (void) constants; GraphNode * node = T_ALLOC(1, GraphNode); if (!node) { return node; diff --git a/nodes/tee.c b/nodes/tee.c index a02f8af..067ad9d 100644 --- a/nodes/tee.c +++ b/nodes/tee.c @@ -21,9 +21,10 @@ handle_event(EventPositionBase * self, EventNode * event) } static GraphNode * -create(GraphNodeSpecification * spec, GraphNodeConfig * config) +create(GraphNodeSpecification * spec, GraphNodeConfig * config, const ConstantRegistry * constants) { (void) config; + (void) constants; GraphNode * node = T_ALLOC(1, GraphNode); if (!node) { return node;