Compare commits
No commits in common. "e2ea8fed1edc0759b648ec62b7deaa10df17db50" and "f76eaa53f25e0f4a7313a90156260e03118ad4c1" have entirely different histories.
e2ea8fed1e
...
f76eaa53f2
1
graph.h
1
graph.h
|
@ -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
84
main.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ®istry;
|
||||
}
|
||||
|
||||
__attribute__((destructor)) void
|
||||
void
|
||||
destroy_graph_node_specification_registry()
|
||||
{
|
||||
ensure_initialized();
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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 = ®ister_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)
|
||||
|
|
|
@ -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 = ®ister_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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue