Improve new config prototype code

Refactor ARRAY_xxx() schema declaration macros to fix problem in ARRAY_STRING().

Add dna.helper.executable, dna.helper.argv and server.chdir to config schema.
This commit is contained in:
Andrew Bettison 2012-11-26 17:33:54 +10:30
parent 0091cf082b
commit cf3c069f83
3 changed files with 111 additions and 35 deletions

View File

@ -139,25 +139,33 @@ struct pattern_list {
};
#define PATTERN_LIST_EMPTY ((struct pattern_list){.patc = 0})
#define ARRAY_ATOM(__name, __size, __type, __parser, __comment) \
__ARRAY(__name, __size, __type, __type value, __parser, char *, __comment)
#define ARRAY_STRING(__name, __size, __strsize, __parser, __comment) \
__ARRAY(__name, __size, char *, char value[__strsize], __parser, char *, __comment)
#define ARRAY_NODE(__name, __size, __type, __parser, __comment) \
__ARRAY(__name, __size, __type, __type value, __parser, struct cf_om_node *, __comment)
#define ARRAY_STRUCT(__name, __size, __structname, __comment) \
ARRAY_NODE(__name, __size, struct config_##__structname, opt_config_##__structname, __comment)
// Generate value structs, struct config_SECTION.
#define STRUCT(__name) struct config_##__name {
#define NODE(__type, __element, __default, __parser, __flags, __comment) __type __element;
#define ATOM(__type, __element, __default, __parser, __flags, __comment) __type __element;
#define STRING(__size, __element, __default, __parser, __flags, __comment) char __element[__size + 1];
#define SUB_STRUCT(__name, __element, __flags) struct config_##__name __element;
#define NODE_STRUCT(__name, __element, __parser, __flags) struct config_##__name __element;
#define END_STRUCT };
#define __ARRAY(__name, __size, __type, __decl, __parser, __parsearg, __comment) \
struct config_##__name { unsigned ac; struct { char label[41]; __decl; } av[(__size)]; };
#define STRUCT(__name) \
struct config_##__name {
#define NODE(__type, __element, __default, __parser, __flags, __comment) \
__type __element;
#define ATOM(__type, __element, __default, __parser, __flags, __comment) \
__type __element;
#define STRING(__size, __element, __default, __parser, __flags, __comment) \
char __element[__size + 1];
#define SUB_STRUCT(__name, __element, __flags) \
struct config_##__name __element;
#define NODE_STRUCT(__name, __element, __parser, __flags) \
struct config_##__name __element;
#define END_STRUCT \
};
#define __ARRAY(__name, __size, __decl) \
struct config_##__name { \
unsigned ac; \
struct { \
char label[41]; \
__decl; \
} av[(__size)]; \
};
#define ARRAY_ATOM(__name, __size, __type, __parser, __comment) __ARRAY(__name, __size, __type value)
#define ARRAY_STRING(__name, __size, __strsize, __parser, __comment) __ARRAY(__name, __size, char value[(__strsize) + 1])
#define ARRAY_NODE(__name, __size, __type, __parser, __comment) __ARRAY(__name, __size, __type value)
#define ARRAY_STRUCT(__name, __size, __structname, __comment) __ARRAY(__name, __size, struct config_##__structname value)
#include "config_schema.h"
#undef STRUCT
#undef NODE
@ -167,6 +175,10 @@ struct pattern_list {
#undef NODE_STRUCT
#undef END_STRUCT
#undef __ARRAY
#undef ARRAY_ATOM
#undef ARRAY_STRING
#undef ARRAY_NODE
#undef ARRAY_STRUCT
/* Return bit flags for schema default dfl_ and parsing opt_ functions. */
@ -201,11 +213,15 @@ strbuf strbuf_cf_flags(strbuf, int);
#define END_STRUCT \
return CFOK; \
}
#define __ARRAY(__name, __size, __type, __decl, __parser, __parsearg, __comment) \
#define __ARRAY(__name) \
int dfl_config_##__name(struct config_##__name *a) { \
a->ac = 0; \
return CFOK; \
}
#define ARRAY_ATOM(__name, __size, __type, __parser, __comment) __ARRAY(__name)
#define ARRAY_STRING(__name, __size, __strsize, __parser, __comment) __ARRAY(__name)
#define ARRAY_NODE(__name, __size, __type, __parser, __comment) __ARRAY(__name)
#define ARRAY_STRUCT(__name, __size, __structname, __comment) __ARRAY(__name)
#include "config_schema.h"
#undef STRUCT
#undef NODE
@ -215,6 +231,10 @@ strbuf strbuf_cf_flags(strbuf, int);
#undef NODE_STRUCT
#undef END_STRUCT
#undef __ARRAY
#undef ARRAY_ATOM
#undef ARRAY_STRING
#undef ARRAY_NODE
#undef ARRAY_STRUCT
/* The Configuration Object Model (COM). The config file is parsed into a tree of these structures
* first, then those structures are passed as arguments to the schema parsing functions.
@ -244,9 +264,20 @@ struct cf_om_node {
#define NODE_STRUCT(__name, __element, __parser, __flags) \
int __parser(struct config_##__name *, const struct cf_om_node *);
#define END_STRUCT
#define __ARRAY(__name, __size, __type, __decl, __parser, __parsearg, __comment) \
int opt_config_##__name(struct config_##__name *, const struct cf_om_node *); \
int __parser(__type *, const __parsearg);
#define __ARRAY(__name) \
int opt_config_##__name(struct config_##__name *, const struct cf_om_node *);
#define ARRAY_ATOM(__name, __size, __type, __parser, __comment) \
__ARRAY(__name) \
int __parser(__type *, const struct cf_om_node *);
#define ARRAY_STRING(__name, __size, __strsize, __parser, __comment) \
__ARRAY(__name) \
int __parser(char *, size_t, const char *);
#define ARRAY_NODE(__name, __size, __type, __parser, __comment) \
__ARRAY(__name) \
int __parser(__type *, const struct cf_om_node *);
#define ARRAY_STRUCT(__name, __size, __structname, __comment) \
__ARRAY(__name) \
int opt_config_##__structname(struct config_##__structname *, const struct cf_om_node *);
#include "config_schema.h"
#undef STRUCT
#undef NODE
@ -256,5 +287,9 @@ struct cf_om_node {
#undef NODE_STRUCT
#undef END_STRUCT
#undef __ARRAY
#undef ARRAY_ATOM
#undef ARRAY_STRING
#undef ARRAY_NODE
#undef ARRAY_STRUCT
#endif //__SERVALDNA_CONFIG_H

View File

@ -88,7 +88,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* END_STRUCT
*
* ARRAY_ATOM(name, size, type, parsefunc, comment)
* ARRAY_STRING(name, size, parsefunc, comment)
* ARRAY_STRING(name, size, strsize, parsefunc, comment)
* ARRAY_NODE(name, size, type, parsefunc, comment)
* ARRAY_STRUCT(name, size, structname, comment)
*
@ -136,6 +136,21 @@ ATOM(int, show_pid, 1, opt_boolean,, "If true, all log lines
ATOM(int, show_time, 1, opt_boolean,, "If true, all log lines contain time stamp")
END_STRUCT
STRUCT(server)
STRING(256, chdir, "/", opt_absolute_path,, "Absolute path of chdir(2) for server process")
END_STRUCT
ARRAY_STRING(argv, 8, 128, opt_str, "Array of arguments to pass to command")
STRUCT(dnahelper)
STRING(256, executable, "", opt_absolute_path,, "Absolute path of dna helper executable")
SUB_STRUCT(argv, argv,)
END_STRUCT
STRUCT(dna)
SUB_STRUCT(dnahelper, helper,)
END_STRUCT
STRUCT(rhizomepeer)
STRING(25, protocol, "http", opt_protocol,, "Protocol name")
STRING(256, host, "", opt_str_nonempty, MANDATORY, "Host name or IP address")
@ -171,6 +186,8 @@ ARRAY_STRUCT(interface_list, 10, network_interface, "Network interfaces")
STRUCT(main)
NODE_STRUCT(interface_list, interfaces, opt_interface_list, MANDATORY)
SUB_STRUCT(log, log,)
SUB_STRUCT(server, server,)
SUB_STRUCT(dna, dna,)
NODE(debugflags_t, debug, 0, opt_debugflags, USES_CHILDREN, "Debug flags")
SUB_STRUCT(rhizome, rhizome,)
SUB_STRUCT(directory, directory,)

View File

@ -360,6 +360,7 @@ int opt_boolean(int *booleanp, const char *text);
int opt_absolute_path(char *str, size_t len, const char *text);
int opt_debugflags(debugflags_t *flagsp, const struct cf_om_node *node);
int opt_rhizome_peer(struct config_rhizomepeer *, const struct cf_om_node *node);
int opt_str(char *str, size_t len, const char *text);
int opt_str_nonempty(char *str, size_t len, const char *text);
int opt_uint64_scaled(uint64_t *intp, const char *text);
int opt_protocol(char *str, size_t len, const char *text);
@ -541,19 +542,22 @@ invalid:
return CFINVALID;
}
int opt_str(char *str, size_t len, const char *text)
{
if (strlen(text) >= len)
return CFSTRINGOVERFLOW;
strncpy(str, text, len);
assert(str[len - 1] == '\0');
return CFOK;
}
int opt_str_nonempty(char *str, size_t len, const char *text)
{
if (!text[0]) {
//invalid_text(node, "empty string");
return CFINVALID;
}
if (strlen(text) >= len) {
//invalid_text(node, "string overflow");
return CFSTRINGOVERFLOW;
}
strncpy(str, text, len);
assert(str[len - 1] == '\0');
return CFOK;
return opt_str(str, len, text);
}
int opt_uint64_scaled(uint64_t *intp, const char *text)
@ -851,22 +855,23 @@ void list_omit_element(const struct cf_om_node *node);
} \
return result; \
}
#define __ARRAY(__name, __size, __type, __decl, __parser, __parsearg, __comment) \
#define __ARRAY(__name, __parseexpr) \
int opt_config_##__name(struct config_##__name *s, const struct cf_om_node *node) { \
int result = CFOK; \
int i; \
for (i = 0; i < node->nodc && s->ac < NELS(s->av); ++i) { \
const struct cf_om_node *elt = node->nodv[i]; \
int ret = __parser(&s->av[s->ac].value, elt); \
const struct cf_om_node *child = node->nodv[i]; \
int ret = (__parseexpr); \
switch (ret) { \
case CFERROR: return CFERROR; \
case CFOK: \
strncpy(s->av[s->ac].label, elt->key, sizeof s->av[s->ac].label - 1)\
strncpy(s->av[s->ac].label, child->key, sizeof s->av[s->ac].label - 1)\
[sizeof s->av[s->ac].label - 1] = '\0'; \
++s->ac; \
break; \
default: \
list_omit_element(elt); \
list_omit_element(child); \
break; \
} \
} \
@ -878,7 +883,17 @@ void list_omit_element(const struct cf_om_node *node);
result |= CFEMPTY; \
return result; \
}
#define ARRAY_ATOM(__name, __size, __type, __parser, __comment) \
__ARRAY(__name, child->text ? __parser(&s->av[s->ac].value, child->text) : CFEMPTY)
#define ARRAY_STRING(__name, __size, __strsize, __parser, __comment) \
__ARRAY(__name, child->text ? __parser(s->av[s->ac].value, (__strsize) + 1, child->text) : CFEMPTY)
#define ARRAY_NODE(__name, __size, __type, __parser, __comment) \
__ARRAY(__name, __parser(&s->av[s->ac].value, child))
#define ARRAY_STRUCT(__name, __size, __structname, __comment) \
__ARRAY(__name, opt_config_##__structname(&s->av[s->ac].value, child))
#include "config_schema.h"
#undef STRUCT
#undef NODE
#undef ATOM
@ -888,6 +903,11 @@ void list_omit_element(const struct cf_om_node *node);
#undef END_STRUCT
#undef __ARRAY
#undef ARRAY_ATOM
#undef ARRAY_STRING
#undef ARRAY_NODE
#undef ARRAY_STRUCT
int main(int argc, char **argv)
{
int i;
@ -921,9 +941,13 @@ int main(int argc, char **argv)
DEBUGF("config.log.file = %s", alloca_str(config.log.file));
DEBUGF("config.log.show_pid = %d", config.log.show_pid);
DEBUGF("config.log.show_time = %d", config.log.show_time);
DEBUGF("config.server.chdir = %s", alloca_str(config.server.chdir));
DEBUGF("config.debug = %llx", (unsigned long long) config.debug);
DEBUGF("config.directory.service = %s", alloca_tohex(config.directory.service.binary, SID_SIZE));
int j;
for (j = 0; j < config.dna.helper.argv.ac; ++j) {
DEBUGF("config.dna.helper.argv.%s=%s", config.dna.helper.argv.av[j].label, config.dna.helper.argv.av[j].value);
}
for (j = 0; j < config.rhizome.direct.peer.ac; ++j) {
DEBUGF("config.rhizome.direct.peer.%s", config.rhizome.direct.peer.av[j].label);
DEBUGF(" .protocol = %s", alloca_str(config.rhizome.direct.peer.av[j].value.protocol));