diff --git a/config.h b/config.h index c7947ab2..c4a464aa 100644 --- a/config.h +++ b/config.h @@ -37,14 +37,14 @@ struct pattern_list { }; #define PATTERN_LIST_EMPTY ((struct pattern_list){.patc = 0}) -#define SUB(__sect, __name, __flags) SUBP(__sect, __name, opt_config_##__sect, __flags) // Generate value structs, struct config_SECTION. #define STRUCT(__sect) struct config_##__sect { #define NODE(__type, __name, __default, __parser, __flags, __comment) __type __name; #define ATOM(__type, __name, __default, __parser, __flags, __comment) __type __name; #define STRING(__size, __name, __default, __parser, __flags, __comment) char __name[__size + 1]; -#define SUBP(__sect, __name, __parser, __flags) struct config_##__sect __name; +#define SUB_STRUCT(__sect, __name, __flags) struct config_##__sect __name; +#define NODE_STRUCT(__sect, __name, __parser, __flags) struct config_##__sect __name; #define END_STRUCT }; #define ARRAY(__sect, __type, __size, __parser, __comment) struct config_##__sect { unsigned ac; struct { char label[41]; __type value; } av[(__size)]; }; #include "config_schema.h" @@ -52,7 +52,8 @@ struct pattern_list { #undef NODE #undef ATOM #undef STRING -#undef SUBP +#undef SUB_STRUCT +#undef NODE_STRUCT #undef END_STRUCT #undef ARRAY @@ -65,7 +66,9 @@ struct pattern_list { s->__name = (__default); #define STRING(__size, __name, __default, __parser, __flags, __comment) \ strncpy(s->__name, (__default), (__size))[(__size)] = '\0'; -#define SUBP(__sect, __name, __parser, __flags) \ +#define SUB_STRUCT(__sect, __name, __flags) \ + dfl_config_##__sect(&s->__name); +#define NODE_STRUCT(__sect, __name, __parser, __flags) \ dfl_config_##__sect(&s->__name); #define END_STRUCT \ return 0; \ @@ -80,7 +83,8 @@ struct pattern_list { #undef NODE #undef ATOM #undef STRING -#undef SUBP +#undef SUB_STRUCT +#undef NODE_STRUCT #undef END_STRUCT #undef ARRAY @@ -110,8 +114,10 @@ struct config_node { int __parser(__type *, const char *); #define STRING(__size, __name, __default, __parser, __flags, __comment) \ int __parser(char *, size_t, const char *); -#define SUBP(__sect, __name, __parser, __flags) \ - int __parser(struct config_##__sect *, const struct config_node *node); +#define SUB_STRUCT(__sect, __name, __flags) \ + int opt_config_##__sect(struct config_##__sect *, const struct config_node *); +#define NODE_STRUCT(__sect, __name, __parser, __flags) \ + int __parser(struct config_##__sect *, const struct config_node *); #define END_STRUCT #define ARRAY(__sect, __type, __size, __parser, __comment) \ int opt_config_##__sect(struct config_##__sect *, const struct config_node *); \ @@ -121,7 +127,8 @@ struct config_node { #undef NODE #undef ATOM #undef STRING -#undef SUBP +#undef SUB_STRUCT +#undef NODE_STRUCT #undef END_STRUCT #undef ARRAY diff --git a/config_schema.h b/config_schema.h index 8148b33d..ac25487b 100644 --- a/config_schema.h +++ b/config_schema.h @@ -1,44 +1,44 @@ STRUCT(log) -STRING(256, file, "", opt_absolute_path,, "Absolute path of log file") -ATOM(int, show_pid, 1, opt_boolean,, "If true, all log lines contain PID of logging process") -ATOM(int, show_time, 1, opt_boolean,, "If true, all log lines contain time stamp") +STRING(256, file, "", opt_absolute_path,, "Absolute path of log file") +ATOM(int, show_pid, 1, opt_boolean,, "If true, all log lines contain PID of logging process") +ATOM(int, show_time, 1, opt_boolean,, "If true, all log lines contain time stamp") END_STRUCT STRUCT(rhizomepeer) -STRING(25, protocol, "http", opt_protocol,, "Protocol name") -STRING(256, host, "", opt_str_nonempty, MANDATORY, "Host name or IP address") -ATOM(uint16_t, port, RHIZOME_HTTP_PORT, opt_port,, "Port number") +STRING(25, protocol, "http", opt_protocol,, "Protocol name") +STRING(256, host, "", opt_str_nonempty, MANDATORY, "Host name or IP address") +ATOM(uint16_t, port, RHIZOME_HTTP_PORT, opt_port,, "Port number") END_STRUCT ARRAY(peerlist, struct config_rhizomepeer, 10, opt_rhizome_peer, "Rhizome peers") STRUCT(rhizomedirect) -SUB(peerlist, peer,) +SUB_STRUCT(peerlist, peer,) END_STRUCT STRUCT(rhizome) -STRING(256, path, "", opt_absolute_path,, "Absolute path of rhizome directory") -ATOM(int, enabled, 1, opt_boolean,, "If true, Rhizome HTTP server is started") -SUB(rhizomedirect, direct,) +STRING(256, path, "", opt_absolute_path,, "Absolute path of rhizome directory") +ATOM(int, enabled, 1, opt_boolean,, "If true, Rhizome HTTP server is started") +SUB_STRUCT(rhizomedirect, direct,) END_STRUCT STRUCT(directory) -ATOM(sid_t, service, SID_NONE, opt_sid,, "Subscriber ID of Serval Directory Service") +ATOM(sid_t, service, SID_NONE, opt_sid,, "Subscriber ID of Serval Directory Service") END_STRUCT STRUCT(network_interface) -ATOM(struct pattern_list,match, PATTERN_LIST_EMPTY, opt_pattern_list, MANDATORY, "Names that match network interface") -ATOM(short, type, OVERLAY_INTERFACE_WIFI, opt_interface_type,, "Type of network interface") -ATOM(uint16_t, port, RHIZOME_HTTP_PORT, opt_port,, "Port number for network interface") -ATOM(uint64_t, speed, 1000000, opt_uint64_scaled,, "Speed in bits per second") +ATOM(struct pattern_list, match, PATTERN_LIST_EMPTY, opt_pattern_list, MANDATORY, "Names that match network interface") +ATOM(short, type, OVERLAY_INTERFACE_WIFI, opt_interface_type,, "Type of network interface") +ATOM(uint16_t, port, RHIZOME_HTTP_PORT, opt_port,, "Port number for network interface") +ATOM(uint64_t, speed, 1000000, opt_uint64_scaled,, "Speed in bits per second") END_STRUCT ARRAY(interface_list, struct config_network_interface, 10, opt_config_network_interface, "Network interfaces") STRUCT(main) -SUBP(interface_list, interfaces, opt_interface_list, MANDATORY) -SUB(log, log,) -NODE(debugflags_t, debug, 0, opt_debugflags, NO_TEXT, "Debug flags") -SUB(rhizome, rhizome,) -SUB(directory, directory,) +NODE_STRUCT(interface_list, interfaces, opt_interface_list, MANDATORY) +SUB_STRUCT(log, log,) +NODE(debugflags_t, debug, 0, opt_debugflags, USES_CHILDREN, "Debug flags") +SUB_STRUCT(rhizome, rhizome,) +SUB_STRUCT(directory, directory,) END_STRUCT diff --git a/config_test.c b/config_test.c index 7c47c93b..53c76fe8 100644 --- a/config_test.c +++ b/config_test.c @@ -442,10 +442,8 @@ int opt_protocol(char *str, size_t len, const char *text) int opt_rhizome_peer(struct config_rhizomepeer *rpeer, const struct config_node *node) { - if (!node->text) { - dfl_config_rhizomepeer(rpeer); + if (!node->text) return opt_config_rhizomepeer(rpeer, node); - } spurious_children(node); const char *protocol; size_t protolen; @@ -593,12 +591,9 @@ int opt_pattern_list(struct pattern_list *listp, const char *text) int opt_interface_list(struct config_interface_list *listp, const struct config_node *node) { - if (!node->text) { - dfl_config_interface_list(listp); - return opt_config_interface_list(listp, node); - } - spurious_children(node); - return CFINVALID; + if (node->text) + invalid_text(node, CFINVALID); + return opt_config_interface_list(listp, node); } void missing_node(const struct config_node *parent, const char *key); @@ -609,13 +604,13 @@ void list_omit_element(const struct config_node *node); // Schema item flags. #define __MANDATORY (1<<0) -#define __NO_TEXT (1<<1) -#define __NO_CHILDREN (1<<2) +#define __TEXT (1<<1) +#define __CHILDREN (1<<2) // Schema flag symbols, to be used in the '__flags' macro arguments. #define MANDATORY |__MANDATORY -#define NO_TEXT |__NO_TEXT -#define NO_CHILDREN |__NO_CHILDREN +#define USES_TEXT |__TEXT +#define USES_CHILDREN |__CHILDREN // Generate parsing functions, opt_config_SECTION() #define STRUCT(__sect) \ @@ -623,18 +618,14 @@ void list_omit_element(const struct config_node *node); if (node->text) unsupported_node(node); \ int result = CFOK; \ char used[node->nodc]; \ - memset(used, 0, node->nodc); + memset(used, 0, node->nodc * sizeof used[0]); #define __ITEM(__name, __flags, __parseexpr) \ { \ int i = get_child(node, #__name); \ const struct config_node *child = (i != -1) ? node->nodv[i] : NULL; \ int ret = CFMISSING; \ if (child) { \ - used[i] = 1; \ - if (((0 __flags) & __NO_TEXT) && child->text) \ - unsupported_node(child); \ - if (((0 __flags) & __NO_CHILDREN) && child->nodc) \ - unsupported_children(child); \ + used[i] |= (__flags); \ ret = (__parseexpr); \ } \ switch (ret) { \ @@ -642,7 +633,7 @@ void list_omit_element(const struct config_node *node); case CFERROR: \ return CFERROR; \ case CFMISSING: \ - if ((0 __flags) & __MANDATORY) { \ + if ((__flags) & __MANDATORY) { \ missing_node(node, #__name); \ if (result < CFMISSING) \ result = CFMISSING; \ @@ -658,25 +649,29 @@ void list_omit_element(const struct config_node *node); } \ } #define NODE(__type, __name, __default, __parser, __flags, __comment) \ - __ITEM(__name, __flags, __parser(&s->__name, child)) + __ITEM(__name, 0 __flags, __parser(&s->__name, child)) #define ATOM(__type, __name, __default, __parser, __flags, __comment) \ - __ITEM(__name, __flags NO_CHILDREN, child->text ? __parser(&s->__name, child->text) : CFMISSING) + __ITEM(__name, ((0 __flags)|__TEXT)&~__CHILDREN, child->text ? __parser(&s->__name, child->text) : CFMISSING) #define STRING(__size, __name, __default, __parser, __flags, __comment) \ - __ITEM(__name, __flags NO_CHILDREN, child->text ? __parser(s->__name, (__size) + 1, child->text) : CFMISSING) -#define SUBP(__sect, __name, __parser, __flags) \ - __ITEM(__name, __flags NO_TEXT, __parser(&s->__name, child)) + __ITEM(__name, ((0 __flags)|__TEXT)&~__CHILDREN, child->text ? __parser(s->__name, (__size) + 1, child->text) : CFMISSING) +#define SUB_STRUCT(__sect, __name, __flags) \ + __ITEM(__name, (0 __flags)|__CHILDREN, opt_config_##__sect(&s->__name, child)) +#define NODE_STRUCT(__sect, __name, __parser, __flags) \ + __ITEM(__name, (0 __flags)|__TEXT|__CHILDREN, __parser(&s->__name, child)) #define END_STRUCT \ { \ int i; \ - for (i = 0; i < node->nodc; ++i) \ - if (!used[i]) \ - unsupported_tree(node->nodv[i]); \ + for (i = 0; i < node->nodc; ++i) { \ + if (node->nodv[i]->text && !(used[i] & __TEXT)) \ + unsupported_node(node->nodv[i]); \ + if (node->nodv[i]->nodc && !(used[i] & __CHILDREN)) \ + unsupported_children(node->nodv[i]); \ + } \ } \ return result; \ } #define ARRAY(__sect, __type, __size, __parser, __comment) \ int opt_config_##__sect(struct config_##__sect *s, const struct config_node *node) { \ - if (node->text) unsupported_node(node); \ int result = CFOK; \ int i; \ for (i = 0; i < node->nodc && s->ac < NELS(s->av); ++i) { \ @@ -705,9 +700,11 @@ void list_omit_element(const struct config_node *node); #undef NODE #undef ATOM #undef STRING -#undef SUBP +#undef SUB_STRUCT +#undef NODE_STRUCT #undef END_STRUCT #undef ARRAY + int main(int argc, char **argv) { int i;