mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-20 05:37:57 +00:00
Improve new "config dump" command
No more SEGV. Omits invalid (default) values. Logs unconditional DEBUG output, to be removed before merging into development. Still missing cf_cmp_ functions to prune out default values. Improved config Object Model iterator logic to barf on internal NULL nodes.
This commit is contained in:
parent
14b859616e
commit
46eeacb823
@ -1170,13 +1170,15 @@ int app_config_dump(const struct cli_parsed *parsed, void *context)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
struct cf_om_iterator it;
|
struct cf_om_iterator it;
|
||||||
for (cf_om_iter_start(&it, root); it.node; cf_om_iter_next(&it))
|
for (cf_om_iter_start(&it, root); it.node; cf_om_iter_next(&it)) {
|
||||||
|
//DEBUGF("%s text=%s nodc=%d", it.node->fullkey, alloca_str_toprint(it.node->text), it.node->nodc);
|
||||||
if (it.node->text) {
|
if (it.node->text) {
|
||||||
cli_puts(it.node->fullkey);
|
cli_puts(it.node->fullkey);
|
||||||
cli_delim("=");
|
cli_delim("=");
|
||||||
cli_puts(it.node->text);
|
cli_puts(it.node->text);
|
||||||
cli_delim("\n");
|
cli_delim("\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
cf_om_free_node(&root);
|
cf_om_free_node(&root);
|
||||||
return ret == CFOK ? 0 : 1;
|
return ret == CFOK ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
17
conf_om.c
17
conf_om.c
@ -148,6 +148,11 @@ static int cf_om_make_child(struct cf_om_node **const parentp, const char *const
|
|||||||
assert(i <= (*parentp)->nodc);
|
assert(i <= (*parentp)->nodc);
|
||||||
if ((child = emalloc_zero(sizeof *child)) == NULL)
|
if ((child = emalloc_zero(sizeof *child)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
if (!(child->fullkey = strn_edup(fullkey, keyend - fullkey))) {
|
||||||
|
free(child);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
child->key = child->fullkey + (key - fullkey);
|
||||||
++(*parentp)->nodc;
|
++(*parentp)->nodc;
|
||||||
if ((*parentp)->nodc > NELS((*parentp)->nodv))
|
if ((*parentp)->nodc > NELS((*parentp)->nodv))
|
||||||
*parentp = realloc(*parentp, sizeof(**parentp) + sizeof((*parentp)->nodv[0]) * ((*parentp)->nodc - NELS((*parentp)->nodv)));
|
*parentp = realloc(*parentp, sizeof(**parentp) + sizeof((*parentp)->nodv[0]) * ((*parentp)->nodc - NELS((*parentp)->nodv)));
|
||||||
@ -155,11 +160,6 @@ static int cf_om_make_child(struct cf_om_node **const parentp, const char *const
|
|||||||
for (j = (*parentp)->nodc - 1; j > i; --j)
|
for (j = (*parentp)->nodc - 1; j > i; --j)
|
||||||
(*parentp)->nodv[j] = (*parentp)->nodv[j-1];
|
(*parentp)->nodv[j] = (*parentp)->nodv[j-1];
|
||||||
(*parentp)->nodv[i] = child;
|
(*parentp)->nodv[i] = child;
|
||||||
if (!(child->fullkey = strn_edup(fullkey, keyend - fullkey))) {
|
|
||||||
free(child);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
child->key = child->fullkey + (key - fullkey);
|
|
||||||
//DEBUGF(" insert i=%d", i);
|
//DEBUGF(" insert i=%d", i);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -193,7 +193,7 @@ int cf_om_get_child(const struct cf_om_node *parent, const char *key, const char
|
|||||||
|
|
||||||
void cf_om_remove_child(struct cf_om_node **parentp, unsigned n)
|
void cf_om_remove_child(struct cf_om_node **parentp, unsigned n)
|
||||||
{
|
{
|
||||||
if (n < (*parentp)->nodc && (*parentp)->nodv[n]) {
|
if (n < (*parentp)->nodc) {
|
||||||
cf_om_free_node(&(*parentp)->nodv[n]);
|
cf_om_free_node(&(*parentp)->nodv[n]);
|
||||||
--(*parentp)->nodc;
|
--(*parentp)->nodc;
|
||||||
for (; n < (*parentp)->nodc; ++n)
|
for (; n < (*parentp)->nodc; ++n)
|
||||||
@ -271,6 +271,7 @@ int cf_om_parse(const char *source, const char *buf, size_t len, struct cf_om_no
|
|||||||
void cf_om_free_node(struct cf_om_node **nodep)
|
void cf_om_free_node(struct cf_om_node **nodep)
|
||||||
{
|
{
|
||||||
if (*nodep) {
|
if (*nodep) {
|
||||||
|
//DEBUGF("%s text=%s nodc=%d", (*nodep)->fullkey, alloca_str_toprint((*nodep)->text), (*nodep)->nodc);
|
||||||
while ((*nodep)->nodc)
|
while ((*nodep)->nodc)
|
||||||
cf_om_free_node(&(*nodep)->nodv[--(*nodep)->nodc]);
|
cf_om_free_node(&(*nodep)->nodv[--(*nodep)->nodc]);
|
||||||
if ((*nodep)->fullkey) {
|
if ((*nodep)->fullkey) {
|
||||||
@ -428,8 +429,10 @@ int cf_om_iter_next(struct cf_om_iterator *it)
|
|||||||
int i = it->stack[it->sp].index++;
|
int i = it->stack[it->sp].index++;
|
||||||
if (i < parent->nodc) {
|
if (i < parent->nodc) {
|
||||||
it->node = parent->nodv[i];
|
it->node = parent->nodv[i];
|
||||||
|
if (it->node == NULL)
|
||||||
|
return WHY("null node");
|
||||||
if (it->sp >= NELS(it->stack))
|
if (it->sp >= NELS(it->stack))
|
||||||
return -1;
|
return WHY("stack overflow");
|
||||||
++it->sp;
|
++it->sp;
|
||||||
it->stack[it->sp].node = it->node;
|
it->stack[it->sp].node = it->node;
|
||||||
it->stack[it->sp].index = 0;
|
it->stack[it->sp].index = 0;
|
||||||
|
138
conf_parse.c
138
conf_parse.c
@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
Serval DNA configuration
|
Serval DNA configuration
|
||||||
Copyright (C) 2012 Serval Project Inc.
|
Copyright (C) 2012 Serval Project Inc.
|
||||||
|
|
||||||
@ -279,6 +279,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#undef VALUE_NODE
|
#undef VALUE_NODE
|
||||||
#undef VALUE_SUB_STRUCT
|
#undef VALUE_SUB_STRUCT
|
||||||
#undef VALUE_NODE_STRUCT
|
#undef VALUE_NODE_STRUCT
|
||||||
|
#undef __ARRAY_KEY
|
||||||
|
#undef __ARRAY_VALUE
|
||||||
#undef END_ARRAY
|
#undef END_ARRAY
|
||||||
|
|
||||||
// Generate config array search-by-key functions.
|
// Generate config array search-by-key functions.
|
||||||
@ -421,24 +423,46 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
DEBUGF("STRUCT(" #__name ", " #__validator ")"); \
|
DEBUGF("STRUCT(" #__name ", " #__validator ")"); \
|
||||||
int result = CFOK; \
|
int result = CFOK; \
|
||||||
int ret;
|
int ret;
|
||||||
#define __HANDLE_TEXT(__elementstr) \
|
#define __FMT_TEXT(__fmtfunc, __eltname, __eltexpr) \
|
||||||
WHYF(" ret=%s", strbuf_str(strbuf_cf_flags(strbuf_alloca(300), ret))); \
|
{ \
|
||||||
if (ret == CFOK) { \
|
const char *text = NULL; \
|
||||||
int n; \
|
ret = __fmtfunc(&text, __eltexpr); \
|
||||||
if (text == NULL) { \
|
if (ret != CFOK) \
|
||||||
WHY(" text=NULL"); \
|
WHYF(" ret=%s", strbuf_str(strbuf_cf_flags(strbuf_alloca(300), ret))); \
|
||||||
ret = CFERROR; \
|
if (ret == CFOK) { \
|
||||||
} else if ((n = cf_om_add_child(parentp, __elementstr)) == -1) { \
|
int n; \
|
||||||
WHY(" cf_om_add_child() returned -1"); \
|
if (text == NULL) { \
|
||||||
ret = CFERROR; \
|
WHY(" text=NULL"); \
|
||||||
} else { \
|
ret = CFERROR; \
|
||||||
(*parentp)->nodv[n]->text = text; \
|
} else if ((n = cf_om_add_child(parentp, __eltname)) == -1) { \
|
||||||
|
WHY(" cf_om_add_child() returned -1"); \
|
||||||
|
ret = CFERROR; \
|
||||||
|
} else { \
|
||||||
|
(*parentp)->nodv[n]->text = text; \
|
||||||
|
text = NULL; \
|
||||||
|
DEBUGF(" %s text=%s", (*parentp)->nodv[n]->fullkey, alloca_str_toprint((*parentp)->nodv[n]->text)); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
if (text) { \
|
||||||
|
free((char *)text); \
|
||||||
text = NULL; \
|
text = NULL; \
|
||||||
} \
|
} \
|
||||||
} \
|
__HANDLE_RET \
|
||||||
if (text) { \
|
}
|
||||||
free((char *)text); \
|
#define __FMT_NODE(__fmtfunc, __element) \
|
||||||
text = NULL; \
|
{ \
|
||||||
|
int n = cf_om_add_child(parentp, #__element); \
|
||||||
|
ret = (n != -1) ? __fmtfunc(&(*parentp)->nodv[n], &strct->__element) : CFERROR; \
|
||||||
|
if (ret != CFOK) \
|
||||||
|
WHYF(" ret=%s", strbuf_str(strbuf_cf_flags(strbuf_alloca(300), ret))); \
|
||||||
|
__REMOVE_EMPTY \
|
||||||
|
__HANDLE_RET \
|
||||||
|
}
|
||||||
|
#define __REMOVE_EMPTY \
|
||||||
|
if (n != -1 && ((*parentp)->nodv[n] == NULL || ((*parentp)->nodv[n]->text == NULL && (*parentp)->nodv[n]->nodc == 0))) { \
|
||||||
|
WHYF(" child n=%d empty", n); \
|
||||||
|
cf_om_remove_child(parentp, n); \
|
||||||
|
ret |= CFEMPTY; \
|
||||||
}
|
}
|
||||||
#define __HANDLE_RET \
|
#define __HANDLE_RET \
|
||||||
if (ret == CFERROR) \
|
if (ret == CFERROR) \
|
||||||
@ -447,32 +471,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
result |= (ret & CF__SUBFLAGS) | CFSUB(ret & CF__FLAGS);
|
result |= (ret & CF__SUBFLAGS) | CFSUB(ret & CF__FLAGS);
|
||||||
#define NODE(__type, __element, __default, __repr, __flags, __comment) \
|
#define NODE(__type, __element, __default, __repr, __flags, __comment) \
|
||||||
DEBUGF(" NODE(" #__type ", " #__element ", " #__repr ")"); \
|
DEBUGF(" NODE(" #__type ", " #__element ", " #__repr ")"); \
|
||||||
ret = cf_fmt_##__repr(parentp, &strct->__element); \
|
__FMT_NODE(cf_fmt_##__repr, __element)
|
||||||
__HANDLE_RET
|
|
||||||
#define ATOM(__type, __element, __default, __repr, __flags, __comment) \
|
#define ATOM(__type, __element, __default, __repr, __flags, __comment) \
|
||||||
DEBUGF(" ATOM(" #__type ", " #__element ", " #__repr ")"); \
|
DEBUGF(" ATOM(" #__type ", " #__element ", " #__repr ")"); \
|
||||||
{ \
|
__FMT_TEXT(cf_fmt_##__repr, #__element, &strct->__element)
|
||||||
const char *text = NULL; \
|
|
||||||
ret = cf_fmt_##__repr(&text, &strct->__element);\
|
|
||||||
__HANDLE_TEXT(#__element) \
|
|
||||||
__HANDLE_RET \
|
|
||||||
}
|
|
||||||
#define STRING(__size, __element, __default, __repr, __flags, __comment) \
|
#define STRING(__size, __element, __default, __repr, __flags, __comment) \
|
||||||
DEBUGF(" STRING(" #__size ", " #__element ", " #__repr ")"); \
|
DEBUGF(" STRING(" #__size ", " #__element ", " #__repr ")"); \
|
||||||
{ \
|
__FMT_TEXT(cf_fmt_##__repr, #__element, &strct->__element[0])
|
||||||
const char *text = NULL; \
|
|
||||||
ret = cf_fmt_##__repr(&text, &strct->__element[0]);\
|
|
||||||
__HANDLE_TEXT(#__element) \
|
|
||||||
__HANDLE_RET \
|
|
||||||
}
|
|
||||||
#define SUB_STRUCT(__structname, __element, __flags) \
|
#define SUB_STRUCT(__structname, __element, __flags) \
|
||||||
DEBUGF(" SUB_STRUCT(" #__structname ", " #__element ")"); \
|
DEBUGF(" SUB_STRUCT(" #__structname ", " #__element ")"); \
|
||||||
ret = cf_fmt_config_##__structname(parentp, &strct->__element); \
|
__FMT_NODE(cf_fmt_config_##__structname, __element)
|
||||||
__HANDLE_RET
|
|
||||||
#define NODE_STRUCT(__structname, __element, __repr, __flags) \
|
#define NODE_STRUCT(__structname, __element, __repr, __flags) \
|
||||||
DEBUGF(" SUB_STRUCT(" #__structname ", " #__element ", " #__repr ")"); \
|
DEBUGF(" SUB_STRUCT(" #__structname ", " #__element ", " #__repr ")"); \
|
||||||
ret = cf_fmt_##__repr(parentp, &strct->__element); \
|
__FMT_NODE(cf_fmt_##__repr, __element)
|
||||||
__HANDLE_RET
|
|
||||||
#define END_STRUCT \
|
#define END_STRUCT \
|
||||||
if ((*parentp)->nodc == 0) \
|
if ((*parentp)->nodc == 0) \
|
||||||
cf_om_free_node(parentp); \
|
cf_om_free_node(parentp); \
|
||||||
@ -485,32 +496,24 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
int (*eltcmp)(const struct config_##__name##__element *, const struct config_##__name##__element *) = __cmp_config_##__name; \
|
int (*eltcmp)(const struct config_##__name##__element *, const struct config_##__name##__element *) = __cmp_config_##__name; \
|
||||||
int result = CFOK; \
|
int result = CFOK; \
|
||||||
int i; \
|
int i; \
|
||||||
for (i = 0; i < array->ac; ++i) { \
|
for (i = 0; i < array->ac; ++i) {
|
||||||
int ret; \
|
#define __ARRAY_KEY(__keyfunc, __keyexpr) \
|
||||||
const char *key = NULL; \
|
const char *key = NULL; \
|
||||||
int n = -1; \
|
int ret = __keyfunc(&key, __keyexpr); \
|
||||||
struct cf_om_node *child = NULL;
|
|
||||||
#define __HANDLE_KEY \
|
|
||||||
if (key == NULL) \
|
if (key == NULL) \
|
||||||
ret = CFERROR; \
|
ret = CFERROR; \
|
||||||
if (ret == CFOK) { \
|
int n = ret == CFOK ? cf_om_add_child(parentp, key) : -1; \
|
||||||
if ((n = cf_om_add_child(parentp, key)) == -1) \
|
|
||||||
ret = CFERROR; \
|
|
||||||
else \
|
|
||||||
child = (*parentp)->nodv[n]; \
|
|
||||||
} \
|
|
||||||
if (key) { \
|
if (key) { \
|
||||||
free((char *)key); \
|
free((char *)key); \
|
||||||
key = NULL; \
|
key = NULL; \
|
||||||
} \
|
} \
|
||||||
if (!child) \
|
if (n == -1) { \
|
||||||
continue;
|
result |= CFSUB(CFINVALID); \
|
||||||
#define __HANDLE_VALUE \
|
continue; \
|
||||||
if (child->text == NULL) \
|
}
|
||||||
ret = CFERROR;
|
|
||||||
#define END_ARRAY(__size) \
|
#define END_ARRAY(__size) \
|
||||||
if (child && child->nodc == 0) \
|
__REMOVE_EMPTY \
|
||||||
cf_om_remove_child(parentp, n); \
|
__HANDLE_RET \
|
||||||
} \
|
} \
|
||||||
if ((*parentp)->nodc == 0) \
|
if ((*parentp)->nodc == 0) \
|
||||||
cf_om_free_node(parentp); \
|
cf_om_free_node(parentp); \
|
||||||
@ -518,39 +521,25 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
}
|
}
|
||||||
#define KEY_ATOM(__type, __keyrepr, __cmpfunc...) \
|
#define KEY_ATOM(__type, __keyrepr, __cmpfunc...) \
|
||||||
DEBUGF(" KEY_ATOM(" #__type ", " #__keyrepr ", " #__cmpfunc ")"); \
|
DEBUGF(" KEY_ATOM(" #__type ", " #__keyrepr ", " #__cmpfunc ")"); \
|
||||||
ret = cf_fmt_##__keyrepr(&key, &array->av[i].key); \
|
__ARRAY_KEY(cf_fmt_##__keyrepr, &array->av[i].key);
|
||||||
__HANDLE_KEY \
|
|
||||||
__HANDLE_RET
|
|
||||||
#define KEY_STRING(__strsize, __keyrepr, __cmpfunc...) \
|
#define KEY_STRING(__strsize, __keyrepr, __cmpfunc...) \
|
||||||
DEBUGF(" KEY_STRING(" #__strsize ", " #__keyrepr ", " #__cmpfunc ")"); \
|
DEBUGF(" KEY_STRING(" #__strsize ", " #__keyrepr ", " #__cmpfunc ")"); \
|
||||||
ret = cf_fmt_##__keyrepr(&key, &array->av[i].key[0]); \
|
__ARRAY_KEY(cf_fmt_##__keyrepr, &array->av[i].key[0]);
|
||||||
__HANDLE_KEY \
|
|
||||||
__HANDLE_RET
|
|
||||||
#define VALUE_ATOM(__type, __eltrepr) \
|
#define VALUE_ATOM(__type, __eltrepr) \
|
||||||
DEBUGF(" VALUE_ATOM(" #__type ", " #__eltrepr ")"); \
|
DEBUGF(" VALUE_ATOM(" #__type ", " #__eltrepr ")"); \
|
||||||
ret = cf_fmt_##__eltrepr(&child->text, &array->av[i].value); \
|
ret = cf_fmt_##__eltrepr(&(*parentp)->nodv[n]->text, &array->av[i].value);
|
||||||
__HANDLE_VALUE \
|
|
||||||
__HANDLE_RET
|
|
||||||
#define VALUE_STRING(__strsize, __eltrepr) \
|
#define VALUE_STRING(__strsize, __eltrepr) \
|
||||||
DEBUGF(" VALUE_STRING(" #__strsize ", " #__eltrepr ")"); \
|
DEBUGF(" VALUE_STRING(" #__strsize ", " #__eltrepr ")"); \
|
||||||
ret = cf_fmt_##__eltrepr(&child->text, &array->av[i].value[0]); \
|
ret = cf_fmt_##__eltrepr(&(*parentp)->nodv[n]->text, &array->av[i].value[0]);
|
||||||
__HANDLE_VALUE \
|
|
||||||
__HANDLE_RET
|
|
||||||
#define VALUE_NODE(__type, __eltrepr) \
|
#define VALUE_NODE(__type, __eltrepr) \
|
||||||
DEBUGF(" VALUE_NODE(" #__type ", " #__eltrepr ")"); \
|
DEBUGF(" VALUE_NODE(" #__type ", " #__eltrepr ")"); \
|
||||||
ret = cf_fmt_##__eltrepr(&child, &array->av[i].value); \
|
ret = cf_fmt_##__eltrepr(&(*parentp)->nodv[n], &array->av[i].value);
|
||||||
__HANDLE_VALUE \
|
|
||||||
__HANDLE_RET
|
|
||||||
#define VALUE_SUB_STRUCT(__structname) \
|
#define VALUE_SUB_STRUCT(__structname) \
|
||||||
DEBUGF(" VALUE_SUB_STRUCT(" #__structname ")"); \
|
DEBUGF(" VALUE_SUB_STRUCT(" #__structname ")"); \
|
||||||
ret = cf_fmt_config_##__structname(&child, &array->av[i].value); \
|
ret = cf_fmt_config_##__structname(&(*parentp)->nodv[n], &array->av[i].value);
|
||||||
__HANDLE_VALUE \
|
|
||||||
__HANDLE_RET
|
|
||||||
#define VALUE_NODE_STRUCT(__structname, __eltrepr) \
|
#define VALUE_NODE_STRUCT(__structname, __eltrepr) \
|
||||||
DEBUGF(" VALUE_NODE_STRUCT(" #__structname ", " #__eltrepr ")"); \
|
DEBUGF(" VALUE_NODE_STRUCT(" #__structname ", " #__eltrepr ")"); \
|
||||||
ret = cf_fmt_##__eltrepr(&child, &array->av[i].value); \
|
ret = cf_fmt_##__eltrepr(&(*parentp)->nodv[n], &array->av[i].value);
|
||||||
__HANDLE_VALUE \
|
|
||||||
__HANDLE_RET
|
|
||||||
#include "conf_schema.h"
|
#include "conf_schema.h"
|
||||||
#undef STRUCT
|
#undef STRUCT
|
||||||
#undef NODE
|
#undef NODE
|
||||||
@ -567,5 +556,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#undef VALUE_NODE
|
#undef VALUE_NODE
|
||||||
#undef VALUE_SUB_STRUCT
|
#undef VALUE_SUB_STRUCT
|
||||||
#undef VALUE_NODE_STRUCT
|
#undef VALUE_NODE_STRUCT
|
||||||
|
#undef __ARRAY_KEY
|
||||||
#undef END_ARRAY
|
#undef END_ARRAY
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user