Compare commits

..

No commits in common. "e2ea8fed1edc0759b648ec62b7deaa10df17db50" and "f76eaa53f25e0f4a7313a90156260e03118ad4c1" have entirely different histories.

12 changed files with 10 additions and 122 deletions

View File

@ -33,7 +33,6 @@ struct graph_node_specification {
void (*destroy)(GraphNodeSpecification * self, GraphNode * target);
void (*register_io)(GraphNodeSpecification * self, GraphNode * target, ProcessingState * state);
char *name;
char *documentation;
};
void graph_channel_init(GraphChannel * ch, GraphNode * start, size_t start_idx, GraphNode * end, size_t end_idx);

84
main.c
View File

@ -1,89 +1,12 @@
#include <getopt.h>
#include <stdio.h>
#include "processing.h"
#include "hash_table.h"
#include "module_registry.h"
union __attribute__((transparent_union)) option_ident {
enum {
NCOPT_BASE = 0xFF,
NCOPT_MODULE_HELP,
} as_nonchar;
int as_int;
// No "as_char" field, because it can cause problems on big-endian CPUs
};
int
main(int argc, char ** argv)
{
const char* config_filename = "config.cfg";
while (true) {
static const struct option long_options [] = {
{"config", required_argument, NULL, 'c'},
{"help", no_argument, NULL, 'h'},
{"list-modules", no_argument, NULL, 'l'},
{"module-help", required_argument, NULL, NCOPT_MODULE_HELP},
{NULL, 0, NULL, 0}};
static const char help_fstring[] =
"Usage: %s <[options...]>\n"
"Options:\n"
"\t--config <filename>, -c <filename> read configuration from <filename>\n"
"\t instead of ./config.cfg\n"
"\t--help, -h show this message\n"
"\t--list-modules, -l list currently loaded node types\n"
"\t--module-help <name> print help information provided for node type <name>\n"
;
union option_ident opt = {.as_int = getopt_long(argc, argv, "c:hl", long_options, NULL)};
if (opt.as_int < 0) {
break;
}
switch (opt.as_int) {
case 'c':
config_filename = optarg;
break;
case 'h':
printf(help_fstring, argv[0]);
return 0;
case 'l':
{
const GraphNodeSpecificationRegistry * reg = get_graph_node_specification_registy();
for (size_t i = 0; i < reg->capacity; ++i) {
if (!reg->key_array[i].key.bytes) {
continue;
}
printf("%.*s\n", (int) reg->key_array[i].key.length, reg->key_array[i].key.bytes);
}
};
return 0;
case NCOPT_MODULE_HELP:
{
GraphNodeSpecification *spec = lookup_graph_node_specification(optarg);
if (!spec) {
fprintf(stderr, "Unknown node type \"%s\"\n", optarg);
return 1;
}
const char* module_help = spec->documentation;
if (module_help) {
printf("Help for node type \"%s\":\n", optarg);
printf("%s\n", module_help);
} else {
printf("No help provided for node type \"%s\"\n", optarg);
}
};
return 0;
default:
fprintf(stderr, "Unexpected option ");
if ((unsigned int) opt.as_int <= 0xFF) {
fprintf(stderr, "'%c'\n", (char) opt.as_int);
} else {
fprintf(stderr, "%d\n", opt.as_int);
}
return 1;
}
}
(void)argc;
(void)argv;
ProcessingState state = (ProcessingState) {
.wait_delay = NULL,
@ -95,7 +18,7 @@ main(int argc, char ** argv)
config_t config_tree;
FullConfig loaded_config;
config_init(&config_tree);
config_read_file(&config_tree, config_filename);
config_read_file(&config_tree, "config.cfg");
config_set_auto_convert(&config_tree, CONFIG_TRUE);
if (!load_config(config_root_setting(&config_tree), &loaded_config)) {
perror("Failed to load config");
@ -169,5 +92,6 @@ main(int argc, char ** argv)
io_subscription_list_deinit(&state.wait_output);
io_subscription_list_deinit(&state.wait_input);
destroy_graph_node_specification_registry();
return 0;
}

View File

@ -199,7 +199,7 @@ modifier_operation_parse(const char* name)
if (strcmp(name, "reset") == 0) {
return MODOP_UNSET;
}
if (strcmp(name, "toggle") == 0) {
if (strcmp(name, "togggle") == 0) {
return MODOP_TOGGLE;
}
return -1;

View File

@ -1,6 +1,7 @@
#include "module_registry.h"
#include "hash_table.h"
static GraphNodeSpecificationRegistry registry;
static TYPED_HASH_TABLE(GraphNodeSpecification*) registry;
static bool initialized = false;
static void
@ -33,14 +34,7 @@ lookup_graph_node_specification(const char * name)
return registry.value_array[idx];
}
const GraphNodeSpecificationRegistry *
get_graph_node_specification_registy()
{
ensure_initialized();
return &registry;
}
__attribute__((destructor)) void
void
destroy_graph_node_specification_registry()
{
ensure_initialized();

View File

@ -2,13 +2,9 @@
#define MODULE_REGISTRY_H_
#include "graph.h"
#include "hash_table.h"
typedef TYPED_HASH_TABLE(GraphNodeSpecification*) GraphNodeSpecificationRegistry;
void register_graph_node_specification(GraphNodeSpecification * spec);
GraphNodeSpecification * lookup_graph_node_specification(const char * name);
void destroy_graph_node_specification_registry();
const GraphNodeSpecificationRegistry * get_graph_node_specification_registy();
#endif /* end of include guard: MODULE_REGISTRY_H_ */

View File

@ -47,7 +47,7 @@ handle_io(EventPositionBase * self, int fd, bool is_output)
monotime = absolute_time_sub_relative(realtime, realtime_adj);
EventData data = {
.code = {
.ns = node->namespace,
.ns = 1,
.major = buf.type,
.minor = buf.code,
},
@ -139,10 +139,6 @@ GraphNodeSpecification nodespec_evdev = (GraphNodeSpecification) {
.destroy = &destroy,
.register_io = &register_io,
.name = "evdev",
.documentation = "Reads evdev events of the specified device\nDoes not accept events\nSends events on all connectors with major code, minor code, payload respectively set to evdev event type, code, value"
"\nOption 'namespace' (optional): set namespace for the generated events"
"\nOption 'file' (required): device file to read events from (like '/dev/input/eventN'), the process must have sufficient privileges to read the file"
,
};
MODULE_CONSTRUCTOR(init)

View File

@ -29,7 +29,7 @@ handle_io(EventPositionBase * self, int fd, bool is_output)
},
.ttl = 100,
.priority = 10,
.payload = (unsigned char) buf[0],
.payload = buf[0],
.modifiers = EMPTY_MODIFIER_SET,
.time = get_current_time(),
};
@ -95,9 +95,6 @@ GraphNodeSpecification nodespec_getchar = (GraphNodeSpecification) {
.destroy = &destroy,
.register_io = &register_io,
.name = "getchar",
.documentation = "Converts stdin bytes to events\nDoes not accept events\nSends events on all connectors with major and minor codes (0, 1) and the read byte as payload"
"\nOption 'namespace' (optional): set namespace for the generated events"
,
};
MODULE_CONSTRUCTOR(init)

View File

@ -91,10 +91,6 @@ GraphNodeSpecification nodespec_modifiers = (GraphNodeSpecification) {
.destroy = &destroy,
.register_io = NULL,
.name = "modifiers",
.documentation = "Sets/unsets/toggles modifiers in an event\nAccepts events on any connector\nSends events on all connectors"
"\nOption 'operation' (required): the operation to apply to the event modifier set ('set'/'unset'/'toggle')"
"\nOption 'modifiers' (required): collection of integers --- the set of modifiers to operate on"
,
};
MODULE_CONSTRUCTOR(init)

View File

@ -94,13 +94,6 @@ GraphNodeSpecification nodespec_modify_predicate = (GraphNodeSpecification) {
.destroy = &destroy,
.register_io = NULL,
.name = "modify_predicate",
.documentation = "Changes 'enabled' and 'inverted' flags of a predicate\nAccepts events on any connector\nDoes not send events"
"\nOption 'target' (required): the predicate to modify"
"\nOption 'enable_on' (optional): the predicate, satisfying events of which set 'enabled' flag of the target predicate to 1"
"\nOption 'disable_on' (optional): the predicate, satisfying events of which set 'enabled' flag of the target predicate to 0"
"\nOption 'invert_on' (optional): the predicate, satisfying events of which set 'inverted' flag of the target predicate to 1"
"\nOption 'uninvert_on' (optional): the predicate, satisfying events of which set 'inverted' flag of the target predicate to 0"
,
};
MODULE_CONSTRUCTOR(init)

View File

@ -60,8 +60,6 @@ GraphNodeSpecification nodespec_print = (GraphNodeSpecification) {
.destroy = &destroy,
.register_io = NULL,
.name = "print",
.documentation = "Prints received events\nAccepts events on any connector\nDoes not send events"
,
};
MODULE_CONSTRUCTOR(init)

View File

@ -88,9 +88,6 @@ GraphNodeSpecification nodespec_router = (GraphNodeSpecification) {
.destroy = &destroy,
.register_io = NULL,
.name = "router",
.documentation = "Conditionally copies the received events\nAccepts events on any connector\nSends events on all connectors with configured predicates"
"\nOption 'predicates' (required): collection of predicates in the order of output connectors from zero, a received event is copied to the given connector iff it satisfies the predicate"
,
};
MODULE_CONSTRUCTOR(init)

View File

@ -53,8 +53,6 @@ GraphNodeSpecification nodespec_tee = (GraphNodeSpecification) {
.destroy = &destroy,
.register_io = NULL,
.name = "tee",
.documentation = "Copies the received events\nAccepts events on any connector\nSends events on all connectors"
,
};
MODULE_CONSTRUCTOR(init)