Improve "config dump" command

All STRUCT cf_fmt_config_xxx() functions omit invalid values, silently
if the invalid value is the default, otherwise with a non-CFOK return
value.

The "config dump --full" option includes all options with valid values,
otherwise omits options having default values.
This commit is contained in:
Andrew Bettison 2013-02-28 15:18:48 +10:30
parent 5939aa9edc
commit ae787339ec
4 changed files with 89 additions and 47 deletions

View File

@ -1161,6 +1161,7 @@ int app_config_dump(const struct cli_parsed *parsed, void *context)
{
if (config.debug.verbose)
DEBUG_cli_parsed(parsed);
int full = 0 == cli_arg(parsed, "--full", NULL, NULL, NULL);
if (create_serval_instance_dir() == -1)
return -1;
struct cf_om_node *root = NULL;
@ -1171,8 +1172,7 @@ int app_config_dump(const struct cli_parsed *parsed, void *context)
}
struct cf_om_iterator 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 && (full || it.node->line_number)) {
cli_puts(it.node->fullkey);
cli_delim("=");
cli_puts(it.node->text);
@ -2369,7 +2369,7 @@ struct cli_schema command_line_options[]={
"Trace through the network to the specified node via MDP."},
{app_config_schema,{"config","schema",NULL},CLIFLAG_STANDALONE|CLIFLAG_PERMISSIVE_CONFIG,
"Display configuration schema."},
{app_config_dump,{"config","dump",NULL},CLIFLAG_STANDALONE|CLIFLAG_PERMISSIVE_CONFIG,
{app_config_dump,{"config","dump","[--full]",NULL},CLIFLAG_STANDALONE|CLIFLAG_PERMISSIVE_CONFIG,
"Dump configuration settings."},
{app_config_set,{"config","set","<variable>","<value>","...",NULL},CLIFLAG_STANDALONE|CLIFLAG_PERMISSIVE_CONFIG,
"Set and del specified configuration variables."},

2
conf.h
View File

@ -238,6 +238,8 @@ int cf_om_get_child(const struct cf_om_node *parent, const char *key, const char
const char *cf_om_get(const struct cf_om_node *root, const char *fullkey);
int cf_om_set(struct cf_om_node **nodep, const char *fullkey, const char *text);
int cf_om_add_child(struct cf_om_node **const parentp, const char *const key);
int cf_om_remove_null_child(struct cf_om_node **parentp, unsigned n);
int cf_om_remove_empty_child(struct cf_om_node **parentp, unsigned n);
void cf_om_remove_child(struct cf_om_node **parent, unsigned n);
void cf_om_free_node(struct cf_om_node **nodep);
void cf_om_dump_node(const struct cf_om_node *node, int indent);

View File

@ -191,14 +191,33 @@ int cf_om_get_child(const struct cf_om_node *parent, const char *key, const char
return -1;
}
int cf_om_remove_null_child(struct cf_om_node **parentp, unsigned n)
{
assert(n < (*parentp)->nodc);
if ((*parentp)->nodv[n] == NULL) {
cf_om_remove_child(parentp, n);
return 1;
}
return 0;
}
int cf_om_remove_empty_child(struct cf_om_node **parentp, unsigned n)
{
assert(n < (*parentp)->nodc);
if ((*parentp)->nodv[n] && (*parentp)->nodv[n]->text == NULL && (*parentp)->nodv[n]->nodc == 0) {
cf_om_remove_child(parentp, n);
return 1;
}
return 0;
}
void cf_om_remove_child(struct cf_om_node **parentp, unsigned n)
{
if (n < (*parentp)->nodc) {
cf_om_free_node(&(*parentp)->nodv[n]);
--(*parentp)->nodc;
for (; n < (*parentp)->nodc; ++n)
(*parentp)->nodv[n] = (*parentp)->nodv[n+1];
}
assert(n < (*parentp)->nodc);
cf_om_free_node(&(*parentp)->nodv[n]);
--(*parentp)->nodc;
for (; n < (*parentp)->nodc; ++n)
(*parentp)->nodv[n] = (*parentp)->nodv[n+1];
}
int cf_om_parse(const char *source, const char *buf, size_t len, struct cf_om_node **rootp)

View File

@ -423,12 +423,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
DEBUGF("STRUCT(" #__name ", " #__validator ")"); \
int result = CFOK; \
int ret;
#define __FMT_TEXT(__fmtfunc, __eltname, __eltexpr) \
{ \
#define __FMT_TEXT(__repr, __eltname, __eltexpr, __defaultvar) \
const char *text = NULL; \
ret = __fmtfunc(&text, __eltexpr); \
if (ret != CFOK) \
WHYF(" ret=%s", strbuf_str(strbuf_cf_flags(strbuf_alloca(300), ret))); \
ret = cf_fmt_##__repr(&text, __eltexpr); \
if (ret == CFOK) { \
int n; \
if (text == NULL) { \
@ -439,45 +436,56 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
ret = CFERROR; \
} else { \
(*parentp)->nodv[n]->text = text; \
(*parentp)->nodv[n]->line_number = is_default ? 0 : 1; \
text = NULL; \
DEBUGF(" %s text=%s", (*parentp)->nodv[n]->fullkey, alloca_str_toprint((*parentp)->nodv[n]->text)); \
} \
} \
} else \
WHYF(" ret=%s", strbuf_str(strbuf_cf_flags(strbuf_alloca(300), ret))); \
if (text) { \
free((char *)text); \
text = NULL; \
} \
__HANDLE_RET \
}
if (ret == CFERROR) \
return CFERROR; \
else if (ret != CFOK && !is_default) \
result |= (ret & CF__SUBFLAGS) | CFSUB(ret & CF__FLAGS);
#define __FMT_NODE(__fmtfunc, __element) \
{ \
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 \
if (n == -1) \
ret = CFERROR; \
else { \
ret = __fmtfunc(&(*parentp)->nodv[n], &strct->__element); \
cf_om_remove_null_child(parentp, n); \
if (ret != CFOK) \
WHYF(" ret=%s", strbuf_str(strbuf_cf_flags(strbuf_alloca(300), ret))); \
if (n < (*parentp)->nodc && cf_om_remove_empty_child(parentp, n)) { \
WHYF(" " #__fmtfunc "() returned empty node, n=%d", n); \
ret = CFERROR; \
} \
} \
if (ret == CFERROR) \
return CFERROR; \
else if (ret != CFOK) \
result |= (ret & CF__SUBFLAGS) | CFSUB(ret & CF__FLAGS); \
}
#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 \
if (ret == CFERROR) \
return CFERROR; \
else if (ret != CFOK) \
result |= (ret & CF__SUBFLAGS) | CFSUB(ret & CF__FLAGS);
#define NODE(__type, __element, __default, __repr, __flags, __comment) \
DEBUGF(" NODE(" #__type ", " #__element ", " #__repr ")"); \
__FMT_NODE(cf_fmt_##__repr, __element)
#define ATOM(__type, __element, __default, __repr, __flags, __comment) \
DEBUGF(" ATOM(" #__type ", " #__element ", " #__repr ")"); \
__FMT_TEXT(cf_fmt_##__repr, #__element, &strct->__element)
{ \
__type dfl = __default; \
int is_default = cf_cmp_##__repr(&strct->__element, &dfl) == 0; \
__FMT_TEXT(__repr, #__element, &strct->__element, __default) \
}
#define STRING(__size, __element, __default, __repr, __flags, __comment) \
DEBUGF(" STRING(" #__size ", " #__element ", " #__repr ")"); \
__FMT_TEXT(cf_fmt_##__repr, #__element, &strct->__element[0])
{ \
int is_default = cf_cmp_##__repr(&strct->__element[0], __default) == 0; \
__FMT_TEXT(__repr, #__element, &strct->__element[0], __default) \
}
#define SUB_STRUCT(__structname, __element, __flags) \
DEBUGF(" SUB_STRUCT(" #__structname ", " #__element ")"); \
__FMT_NODE(cf_fmt_config_##__structname, __element)
@ -492,28 +500,43 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define ARRAY(__name, __flags, __validator...) \
int cf_fmt_config_##__name(struct cf_om_node **parentp, const struct config_##__name *array) { \
DEBUGF("ARRAY(" #__name ", " #__flags ", " #__validator ")"); \
int flags = (0 __flags); \
int (*eltcmp)(const struct config_##__name##__element *, const struct config_##__name##__element *) = __cmp_config_##__name; \
int result = CFOK; \
int i; \
for (i = 0; i < array->ac; ++i) {
#define __ARRAY_KEY(__keyfunc, __keyexpr) \
const char *key = NULL; \
int ret = __keyfunc(&key, __keyexpr); \
if (key == NULL) \
int n = -1; \
if (ret != CFOK) { \
WHYF(" ret=%s", strbuf_str(strbuf_cf_flags(strbuf_alloca(300), ret))); \
} else if (key == NULL) { \
WHY(" key=NULL"); \
ret = CFERROR; \
int n = ret == CFOK ? cf_om_add_child(parentp, key) : -1; \
} else { \
n = cf_om_add_child(parentp, key); \
if (n == -1) { \
WHYF(" cf_om_add_child() returned -1"); \
ret = CFERROR; \
} \
} \
if (key) { \
free((char *)key); \
key = NULL; \
} \
if (n == -1) { \
result |= CFSUB(CFINVALID); \
continue; \
}
if (ret == CFOK) {
#define END_ARRAY(__size) \
__REMOVE_EMPTY \
__HANDLE_RET \
cf_om_remove_null_child(parentp, n); \
if (ret != CFOK) \
WHYF(" ret=%s", strbuf_str(strbuf_cf_flags(strbuf_alloca(300), ret))); \
if (n < (*parentp)->nodc && cf_om_remove_empty_child(parentp, n)) { \
WHYF(" returned empty node, n=%d", n); \
ret = CFERROR; \
} \
} \
if (ret == CFERROR) \
return CFERROR; \
else if (ret != CFOK) \
result |= (ret & CF__SUBFLAGS) | CFSUB(ret & CF__FLAGS); \
} \
if ((*parentp)->nodc == 0) \
cf_om_free_node(parentp); \
@ -550,8 +573,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#undef END_STRUCT
#undef __FMT_TEXT
#undef __FMT_NODE
#undef __REMOVE_EMPTY
#undef __HANDLE_RET
#undef ARRAY
#undef KEY_ATOM
#undef KEY_STRING