mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-24 07:16:43 +00:00
Support 'config get' var pattern matching
This commit is contained in:
parent
c869e00421
commit
96d524200c
@ -1001,13 +1001,13 @@ int app_config_get(int argc, const char *const *argv, const struct command_line_
|
|||||||
{
|
{
|
||||||
if (debug & DEBUG_VERBOSE) DEBUG_argv("command", argc, argv);
|
if (debug & DEBUG_VERBOSE) DEBUG_argv("command", argc, argv);
|
||||||
const char *var;
|
const char *var;
|
||||||
if (cli_arg(argc, argv, o, "variable", &var, is_configvarname, NULL) == -1)
|
if (cli_arg(argc, argv, o, "variable", &var, is_configvarpattern, NULL) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
if (create_serval_instance_dir() == -1)
|
if (create_serval_instance_dir() == -1)
|
||||||
return -1;
|
return -1;
|
||||||
if (cf_om_reload() == -1)
|
if (cf_om_reload() == -1)
|
||||||
return -1;
|
return -1;
|
||||||
if (var) {
|
if (var && is_configvarname(var)) {
|
||||||
const char *value = cf_om_get(cf_om_root, var);
|
const char *value = cf_om_get(cf_om_root, var);
|
||||||
if (value) {
|
if (value) {
|
||||||
cli_puts(var);
|
cli_puts(var);
|
||||||
@ -1018,6 +1018,8 @@ int app_config_get(int argc, const char *const *argv, const struct command_line_
|
|||||||
} else {
|
} else {
|
||||||
struct cf_om_iterator it;
|
struct cf_om_iterator it;
|
||||||
for (cf_om_iter_start(&it, cf_om_root); it.node; cf_om_iter_next(&it)) {
|
for (cf_om_iter_start(&it, cf_om_root); it.node; cf_om_iter_next(&it)) {
|
||||||
|
if (var && cf_om_match(var, it.node) <= 0)
|
||||||
|
continue;
|
||||||
if (it.node->text) {
|
if (it.node->text) {
|
||||||
cli_puts(it.node->fullkey);
|
cli_puts(it.node->fullkey);
|
||||||
cli_delim("=");
|
cli_delim("=");
|
||||||
|
2
conf.h
2
conf.h
@ -232,6 +232,7 @@ struct cf_om_node {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int is_configvarname(const char *);
|
int is_configvarname(const char *);
|
||||||
|
int is_configvarpattern(const char *);
|
||||||
int cf_om_parse(const char *source, const char *buf, size_t len, struct cf_om_node **rootp);
|
int cf_om_parse(const char *source, const char *buf, size_t len, struct cf_om_node **rootp);
|
||||||
int cf_om_get_child(const struct cf_om_node *parent, const char *key, const char *keyend);
|
int cf_om_get_child(const struct cf_om_node *parent, const char *key, const char *keyend);
|
||||||
const char *cf_om_get(const struct cf_om_node *root, const char *fullkey);
|
const char *cf_om_get(const struct cf_om_node *root, const char *fullkey);
|
||||||
@ -239,6 +240,7 @@ 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_add_child(struct cf_om_node **const parentp, const char *const key);
|
||||||
void cf_om_free_node(struct cf_om_node **nodep);
|
void cf_om_free_node(struct cf_om_node **nodep);
|
||||||
void cf_om_dump_node(const struct cf_om_node *node, int indent);
|
void cf_om_dump_node(const struct cf_om_node *node, int indent);
|
||||||
|
int cf_om_match(const char *pattern, const struct cf_om_node *node);
|
||||||
|
|
||||||
struct cf_om_iterator {
|
struct cf_om_iterator {
|
||||||
const struct cf_om_node *node;
|
const struct cf_om_node *node;
|
||||||
|
92
conf_om.c
92
conf_om.c
@ -44,8 +44,30 @@ static const char *cf_find_keyend(const char *const key, const char *const fullk
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *cf_find_keypattern_end(const char *const key, const char *const fullkeyend)
|
||||||
|
{
|
||||||
|
const char *s = cf_find_keyend(key, fullkeyend);
|
||||||
|
if (s == NULL) {
|
||||||
|
s = key;
|
||||||
|
if (s < fullkeyend && *s == '*')
|
||||||
|
++s;
|
||||||
|
if (s + 1 == fullkeyend && *s == '*')
|
||||||
|
++s;
|
||||||
|
if (s == key || (s < fullkeyend && *s != '.'))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
/* This predicate function defines the constraints on configuration option names.
|
/* This predicate function defines the constraints on configuration option names.
|
||||||
* Valid:
|
*
|
||||||
|
* OPTION_NAME ::= ( KEY "." )* LASTKEY
|
||||||
|
* KEY ::= ( ALPHA | "_") ( ALPHANUM | "_" )*
|
||||||
|
* LASTKEY ::= KEY
|
||||||
|
* ALPHA ::= "A" .. "Z" | "a" .. "z"
|
||||||
|
* ALPHANUM ::= ALPHA | "0" .. "9"
|
||||||
|
*
|
||||||
|
* Valid examples:
|
||||||
* foo
|
* foo
|
||||||
* foo.bar
|
* foo.bar
|
||||||
* foo.bar.chow
|
* foo.bar.chow
|
||||||
@ -72,6 +94,25 @@ int is_configvarname(const char *text)
|
|||||||
return keyend != NULL;
|
return keyend != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This predicate function defines the constraints on configuration option patterns.
|
||||||
|
* Similar to is_configvarname().
|
||||||
|
*
|
||||||
|
* OPTION_PATTERN ::= ( KEY_PATTERN "." )* LASTKEY_PATTERN
|
||||||
|
* KEY_PATTERN ::= "*" | KEY
|
||||||
|
* LASTKEY_PATTERN ::= "**" | KEY_PATTERN
|
||||||
|
*
|
||||||
|
* @author Andrew Bettison <andrew@servalproject.com>
|
||||||
|
*/
|
||||||
|
int is_configvarpattern(const char *text)
|
||||||
|
{
|
||||||
|
const char *const textend = text + strlen(text);
|
||||||
|
const char *key = text;
|
||||||
|
const char *keyend = NULL;
|
||||||
|
while (key <= textend && (keyend = cf_find_keypattern_end(key, textend)) != NULL)
|
||||||
|
key = keyend + 1;
|
||||||
|
return keyend != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int cf_om_make_child(struct cf_om_node **const parentp, const char *const fullkey, const char *const key, const char *const keyend)
|
static int cf_om_make_child(struct cf_om_node **const parentp, const char *const fullkey, const char *const key, const char *const keyend)
|
||||||
{
|
{
|
||||||
// Allocate parent node if it is not present.
|
// Allocate parent node if it is not present.
|
||||||
@ -253,6 +294,55 @@ void cf_om_dump_node(const struct cf_om_node *node, int indent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cf_om_match(const char *pattern, const struct cf_om_node *node)
|
||||||
|
{
|
||||||
|
if (node == NULL) {
|
||||||
|
//DEBUGF("pattern='%s' node=NULL", pattern);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (node->fullkey == NULL) {
|
||||||
|
//DEBUGF("pattern='%s' node->fullkey=NULL", pattern);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
DEBUGF("pattern='%s' node->fullkey=%s node->nodc=%d node->text=%s",
|
||||||
|
pattern,
|
||||||
|
alloca_str_toprint(node->fullkey),
|
||||||
|
node->nodc,
|
||||||
|
alloca_str_toprint(node->text)
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
if (!pattern[0])
|
||||||
|
return -1;
|
||||||
|
const char *const pattern_end = pattern + strlen(pattern);
|
||||||
|
const char *pat = pattern;
|
||||||
|
const char *key = node->fullkey;
|
||||||
|
const char *const fullkeyend = node->fullkey + strlen(node->fullkey);
|
||||||
|
const char *keyend = NULL;
|
||||||
|
const char *patend = pat;
|
||||||
|
//DEBUGF(" pat=%s key=%s", alloca_str_toprint(pat), alloca_str_toprint(key));
|
||||||
|
while (pat < pattern_end && key <= fullkeyend && (keyend = cf_find_keyend(key, fullkeyend)) && (patend = cf_find_keypattern_end(pat, pattern_end))) {
|
||||||
|
if (pat[0] == '*') {
|
||||||
|
if (pat[1] == '*')
|
||||||
|
return 1;
|
||||||
|
pat = patend;
|
||||||
|
key = keyend;
|
||||||
|
} else {
|
||||||
|
while (pat < patend && key < fullkeyend && *pat == *key)
|
||||||
|
++pat, ++key;
|
||||||
|
if (pat != patend || key != keyend)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (*pat)
|
||||||
|
++pat;
|
||||||
|
if (*key)
|
||||||
|
++key;
|
||||||
|
//DEBUGF(" pat=%s key=%s", alloca_str_toprint(pat), alloca_str_toprint(key));
|
||||||
|
}
|
||||||
|
//DEBUGF(" patend=%s keyend=%s", alloca_str_toprint(patend), alloca_str_toprint(keyend));
|
||||||
|
return patend == NULL ? -1 : keyend && keyend == fullkeyend && pat == pattern_end;
|
||||||
|
}
|
||||||
|
|
||||||
const char *cf_om_get(const struct cf_om_node *node, const char *fullkey)
|
const char *cf_om_get(const struct cf_om_node *node, const char *fullkey)
|
||||||
{
|
{
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
|
Loading…
Reference in New Issue
Block a user