Improve new config prototype code

Refactor and rename, improve logic for reporting unsupported nodes.
This commit is contained in:
Andrew Bettison 2012-11-23 19:13:02 +10:30
parent 8c36b23417
commit 98c3af967d
3 changed files with 62 additions and 58 deletions

View File

@ -37,14 +37,14 @@ struct pattern_list {
}; };
#define PATTERN_LIST_EMPTY ((struct pattern_list){.patc = 0}) #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. // Generate value structs, struct config_SECTION.
#define STRUCT(__sect) struct config_##__sect { #define STRUCT(__sect) struct config_##__sect {
#define NODE(__type, __name, __default, __parser, __flags, __comment) __type __name; #define NODE(__type, __name, __default, __parser, __flags, __comment) __type __name;
#define ATOM(__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 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 END_STRUCT };
#define ARRAY(__sect, __type, __size, __parser, __comment) struct config_##__sect { unsigned ac; struct { char label[41]; __type value; } av[(__size)]; }; #define ARRAY(__sect, __type, __size, __parser, __comment) struct config_##__sect { unsigned ac; struct { char label[41]; __type value; } av[(__size)]; };
#include "config_schema.h" #include "config_schema.h"
@ -52,7 +52,8 @@ struct pattern_list {
#undef NODE #undef NODE
#undef ATOM #undef ATOM
#undef STRING #undef STRING
#undef SUBP #undef SUB_STRUCT
#undef NODE_STRUCT
#undef END_STRUCT #undef END_STRUCT
#undef ARRAY #undef ARRAY
@ -65,7 +66,9 @@ struct pattern_list {
s->__name = (__default); s->__name = (__default);
#define STRING(__size, __name, __default, __parser, __flags, __comment) \ #define STRING(__size, __name, __default, __parser, __flags, __comment) \
strncpy(s->__name, (__default), (__size))[(__size)] = '\0'; 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); dfl_config_##__sect(&s->__name);
#define END_STRUCT \ #define END_STRUCT \
return 0; \ return 0; \
@ -80,7 +83,8 @@ struct pattern_list {
#undef NODE #undef NODE
#undef ATOM #undef ATOM
#undef STRING #undef STRING
#undef SUBP #undef SUB_STRUCT
#undef NODE_STRUCT
#undef END_STRUCT #undef END_STRUCT
#undef ARRAY #undef ARRAY
@ -110,8 +114,10 @@ struct config_node {
int __parser(__type *, const char *); int __parser(__type *, const char *);
#define STRING(__size, __name, __default, __parser, __flags, __comment) \ #define STRING(__size, __name, __default, __parser, __flags, __comment) \
int __parser(char *, size_t, const char *); int __parser(char *, size_t, const char *);
#define SUBP(__sect, __name, __parser, __flags) \ #define SUB_STRUCT(__sect, __name, __flags) \
int __parser(struct config_##__sect *, const struct config_node *node); 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 END_STRUCT
#define ARRAY(__sect, __type, __size, __parser, __comment) \ #define ARRAY(__sect, __type, __size, __parser, __comment) \
int opt_config_##__sect(struct config_##__sect *, const struct config_node *); \ int opt_config_##__sect(struct config_##__sect *, const struct config_node *); \
@ -121,7 +127,8 @@ struct config_node {
#undef NODE #undef NODE
#undef ATOM #undef ATOM
#undef STRING #undef STRING
#undef SUBP #undef SUB_STRUCT
#undef NODE_STRUCT
#undef END_STRUCT #undef END_STRUCT
#undef ARRAY #undef ARRAY

View File

@ -1,44 +1,44 @@
STRUCT(log) STRUCT(log)
STRING(256, file, "", opt_absolute_path,, "Absolute path of log file") 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_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") ATOM(int, show_time, 1, opt_boolean,, "If true, all log lines contain time stamp")
END_STRUCT END_STRUCT
STRUCT(rhizomepeer) STRUCT(rhizomepeer)
STRING(25, protocol, "http", opt_protocol,, "Protocol name") STRING(25, protocol, "http", opt_protocol,, "Protocol name")
STRING(256, host, "", opt_str_nonempty, MANDATORY, "Host name or IP address") STRING(256, host, "", opt_str_nonempty, MANDATORY, "Host name or IP address")
ATOM(uint16_t, port, RHIZOME_HTTP_PORT, opt_port,, "Port number") ATOM(uint16_t, port, RHIZOME_HTTP_PORT, opt_port,, "Port number")
END_STRUCT END_STRUCT
ARRAY(peerlist, struct config_rhizomepeer, 10, opt_rhizome_peer, "Rhizome peers") ARRAY(peerlist, struct config_rhizomepeer, 10, opt_rhizome_peer, "Rhizome peers")
STRUCT(rhizomedirect) STRUCT(rhizomedirect)
SUB(peerlist, peer,) SUB_STRUCT(peerlist, peer,)
END_STRUCT END_STRUCT
STRUCT(rhizome) STRUCT(rhizome)
STRING(256, path, "", opt_absolute_path,, "Absolute path of rhizome directory") STRING(256, path, "", opt_absolute_path,, "Absolute path of rhizome directory")
ATOM(int, enabled, 1, opt_boolean,, "If true, Rhizome HTTP server is started") ATOM(int, enabled, 1, opt_boolean,, "If true, Rhizome HTTP server is started")
SUB(rhizomedirect, direct,) SUB_STRUCT(rhizomedirect, direct,)
END_STRUCT END_STRUCT
STRUCT(directory) 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 END_STRUCT
STRUCT(network_interface) STRUCT(network_interface)
ATOM(struct pattern_list,match, PATTERN_LIST_EMPTY, opt_pattern_list, MANDATORY, "Names that match 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(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(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(uint64_t, speed, 1000000, opt_uint64_scaled,, "Speed in bits per second")
END_STRUCT END_STRUCT
ARRAY(interface_list, struct config_network_interface, 10, opt_config_network_interface, "Network interfaces") ARRAY(interface_list, struct config_network_interface, 10, opt_config_network_interface, "Network interfaces")
STRUCT(main) STRUCT(main)
SUBP(interface_list, interfaces, opt_interface_list, MANDATORY) NODE_STRUCT(interface_list, interfaces, opt_interface_list, MANDATORY)
SUB(log, log,) SUB_STRUCT(log, log,)
NODE(debugflags_t, debug, 0, opt_debugflags, NO_TEXT, "Debug flags") NODE(debugflags_t, debug, 0, opt_debugflags, USES_CHILDREN, "Debug flags")
SUB(rhizome, rhizome,) SUB_STRUCT(rhizome, rhizome,)
SUB(directory, directory,) SUB_STRUCT(directory, directory,)
END_STRUCT END_STRUCT

View File

@ -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) int opt_rhizome_peer(struct config_rhizomepeer *rpeer, const struct config_node *node)
{ {
if (!node->text) { if (!node->text)
dfl_config_rhizomepeer(rpeer);
return opt_config_rhizomepeer(rpeer, node); return opt_config_rhizomepeer(rpeer, node);
}
spurious_children(node); spurious_children(node);
const char *protocol; const char *protocol;
size_t protolen; 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) int opt_interface_list(struct config_interface_list *listp, const struct config_node *node)
{ {
if (!node->text) { if (node->text)
dfl_config_interface_list(listp); invalid_text(node, CFINVALID);
return opt_config_interface_list(listp, node); return opt_config_interface_list(listp, node);
}
spurious_children(node);
return CFINVALID;
} }
void missing_node(const struct config_node *parent, const char *key); 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. // Schema item flags.
#define __MANDATORY (1<<0) #define __MANDATORY (1<<0)
#define __NO_TEXT (1<<1) #define __TEXT (1<<1)
#define __NO_CHILDREN (1<<2) #define __CHILDREN (1<<2)
// Schema flag symbols, to be used in the '__flags' macro arguments. // Schema flag symbols, to be used in the '__flags' macro arguments.
#define MANDATORY |__MANDATORY #define MANDATORY |__MANDATORY
#define NO_TEXT |__NO_TEXT #define USES_TEXT |__TEXT
#define NO_CHILDREN |__NO_CHILDREN #define USES_CHILDREN |__CHILDREN
// Generate parsing functions, opt_config_SECTION() // Generate parsing functions, opt_config_SECTION()
#define STRUCT(__sect) \ #define STRUCT(__sect) \
@ -623,18 +618,14 @@ void list_omit_element(const struct config_node *node);
if (node->text) unsupported_node(node); \ if (node->text) unsupported_node(node); \
int result = CFOK; \ int result = CFOK; \
char used[node->nodc]; \ char used[node->nodc]; \
memset(used, 0, node->nodc); memset(used, 0, node->nodc * sizeof used[0]);
#define __ITEM(__name, __flags, __parseexpr) \ #define __ITEM(__name, __flags, __parseexpr) \
{ \ { \
int i = get_child(node, #__name); \ int i = get_child(node, #__name); \
const struct config_node *child = (i != -1) ? node->nodv[i] : NULL; \ const struct config_node *child = (i != -1) ? node->nodv[i] : NULL; \
int ret = CFMISSING; \ int ret = CFMISSING; \
if (child) { \ if (child) { \
used[i] = 1; \ used[i] |= (__flags); \
if (((0 __flags) & __NO_TEXT) && child->text) \
unsupported_node(child); \
if (((0 __flags) & __NO_CHILDREN) && child->nodc) \
unsupported_children(child); \
ret = (__parseexpr); \ ret = (__parseexpr); \
} \ } \
switch (ret) { \ switch (ret) { \
@ -642,7 +633,7 @@ void list_omit_element(const struct config_node *node);
case CFERROR: \ case CFERROR: \
return CFERROR; \ return CFERROR; \
case CFMISSING: \ case CFMISSING: \
if ((0 __flags) & __MANDATORY) { \ if ((__flags) & __MANDATORY) { \
missing_node(node, #__name); \ missing_node(node, #__name); \
if (result < CFMISSING) \ if (result < CFMISSING) \
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) \ #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) \ #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) \ #define STRING(__size, __name, __default, __parser, __flags, __comment) \
__ITEM(__name, __flags NO_CHILDREN, child->text ? __parser(s->__name, (__size) + 1, child->text) : CFMISSING) __ITEM(__name, ((0 __flags)|__TEXT)&~__CHILDREN, child->text ? __parser(s->__name, (__size) + 1, child->text) : CFMISSING)
#define SUBP(__sect, __name, __parser, __flags) \ #define SUB_STRUCT(__sect, __name, __flags) \
__ITEM(__name, __flags NO_TEXT, __parser(&s->__name, child)) __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 \ #define END_STRUCT \
{ \ { \
int i; \ int i; \
for (i = 0; i < node->nodc; ++i) \ for (i = 0; i < node->nodc; ++i) { \
if (!used[i]) \ if (node->nodv[i]->text && !(used[i] & __TEXT)) \
unsupported_tree(node->nodv[i]); \ unsupported_node(node->nodv[i]); \
if (node->nodv[i]->nodc && !(used[i] & __CHILDREN)) \
unsupported_children(node->nodv[i]); \
} \
} \ } \
return result; \ return result; \
} }
#define ARRAY(__sect, __type, __size, __parser, __comment) \ #define ARRAY(__sect, __type, __size, __parser, __comment) \
int opt_config_##__sect(struct config_##__sect *s, const struct config_node *node) { \ int opt_config_##__sect(struct config_##__sect *s, const struct config_node *node) { \
if (node->text) unsupported_node(node); \
int result = CFOK; \ int result = CFOK; \
int i; \ int i; \
for (i = 0; i < node->nodc && s->ac < NELS(s->av); ++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 NODE
#undef ATOM #undef ATOM
#undef STRING #undef STRING
#undef SUBP #undef SUB_STRUCT
#undef NODE_STRUCT
#undef END_STRUCT #undef END_STRUCT
#undef ARRAY #undef ARRAY
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int i; int i;