diff options
| author | Quentin Young <qlyoung@cumulusnetworks.com> | 2016-08-01 13:18:25 +0000 |
|---|---|---|
| committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2016-08-01 13:18:25 +0000 |
| commit | 6d53a10e4cf873ff61a3dada644d15be83dd54c0 (patch) | |
| tree | c5c59a7b402956be4e78a5028a93554a3141d8d1 /lib | |
| parent | 3a7f5493619d20e7087536edbe694f9f2761ace5 (diff) | |
lib: Add partial matching support
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/.command.h.swo | bin | 0 -> 16384 bytes | |||
| -rw-r--r-- | lib/command_graph.c | 2 | ||||
| -rw-r--r-- | lib/command_lex.l | 2 | ||||
| -rw-r--r-- | lib/command_match.c | 40 | ||||
| -rw-r--r-- | lib/grammar_sandbox.c | 2 |
5 files changed, 35 insertions, 11 deletions
diff --git a/lib/.command.h.swo b/lib/.command.h.swo Binary files differnew file mode 100644 index 0000000000..71a42cc20a --- /dev/null +++ b/lib/.command.h.swo diff --git a/lib/command_graph.c b/lib/command_graph.c index 7c09a5cd6c..3e52f42598 100644 --- a/lib/command_graph.c +++ b/lib/command_graph.c @@ -92,7 +92,7 @@ struct graph_node * copy_node (struct graph_node *node) { struct graph_node *new = new_node(node->type); - new->children = vector_copy (node->children); + new->children = NULL; new->is_start = node->is_start; new->end = node->end; new->text = node->text ? XSTRDUP(MTYPE_CMD_TOKENS, node->text) : NULL; diff --git a/lib/command_lex.l b/lib/command_lex.l index 5a0e76d418..ce09c5bf28 100644 --- a/lib/command_lex.l +++ b/lib/command_lex.l @@ -9,7 +9,7 @@ IPV4 A\.B\.C\.D IPV4_PREFIX A\.B\.C\.D\/M IPV6 X:X::X:X IPV6_PREFIX X:X::X:X\/M -VARIABLE [A-Z][A-Z_]+ +VARIABLE [A-Z][A-Z_:]+ NUMBER [0-9]{1,20} RANGE \({NUMBER}\-{NUMBER}\) diff --git a/lib/command_match.c b/lib/command_match.c index f02b7c821a..7b9c5f15d8 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -13,6 +13,9 @@ match_command_r (struct graph_node *, vector, unsigned int); static int score_precedence (struct graph_node *); +static enum match_type +min_match_level(enum node_type type); + /* token matcher prototypes */ static enum match_type match_ipv4 (const char *); @@ -30,7 +33,7 @@ static enum match_type match_range (struct graph_node *, const char *str); static enum match_type -match_word (struct graph_node *, enum filter_type, const char *); +match_word (struct graph_node *, const char *, enum filter_type); static enum match_type match_number (struct graph_node *, const char *); @@ -137,8 +140,11 @@ match_command (struct graph_node *start, const char *line, struct list **argv) static struct list * match_command_r (struct graph_node *start, vector vline, unsigned int n) { + // get the minimum match level that can count as a full match + enum match_type minmatch = min_match_level(start->type); + // if we don't match this node, die - if (match_token(start, vector_slot(vline, n), FILTER_STRICT) != exact_match) + if (match_token(start, vector_slot(vline, n), FILTER_RELAXED) < minmatch) return NULL; // arg list for this subgraph @@ -313,12 +319,30 @@ add_nexthops(struct list *l, struct graph_node *node) /* matching utility functions */ +/** + * Determines the minimum acceptable matching level + * for a given node type that can be accepted as a + * full match. Used for things like abbreviating + * commands, e.g. `conf t`. + */ +static enum match_type +min_match_level(enum node_type type) +{ + switch (type) { + case WORD_GN: + return partly_match; + default: + return exact_match; + } +} + static int score_precedence (struct graph_node *node) { switch (node->type) { - // these should be mutually exclusive + // these should be mutually exclusive, + // or never compared case IPV4_GN: case IPV4_PREFIX_GN: case IPV6_GN: @@ -344,11 +368,11 @@ match_token (struct graph_node *node, char *token, enum filter_type filter) case IPV4_GN: return match_ipv4 (token); case IPV4_PREFIX_GN: - return match_ipv4_prefix (token, filter); + return match_ipv4_prefix (token); case IPV6_GN: - return match_ipv6 (token, filter); + return match_ipv6 (token); case IPV6_PREFIX_GN: - return match_ipv6_prefix (token, filter); + return match_ipv6_prefix (token); case RANGE_GN: return match_range (node, token); case NUMBER_GN: @@ -584,8 +608,8 @@ match_range (struct graph_node *rangenode, const char *str) static enum match_type match_word(struct graph_node *wordnode, - enum filter_type filter, - const char *word) + const char *word, + enum filter_type filter) { if (filter == FILTER_RELAXED) { diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c index 2443b8471c..66e530595b 100644 --- a/lib/grammar_sandbox.c +++ b/lib/grammar_sandbox.c @@ -56,7 +56,7 @@ DEFUN (grammar_test_complete, // print possible next hops, if any for (ALL_LIST_ELEMENTS_RO(result,node,cnode)) { if (cnode->type == END_GN) - fprintf(stderr, "<cr>\n"); + fprintf(stderr, "<cr> %p\n", cnode->element->func); else fprintf(stderr, "%s\n", describe_node(cnode, desc, 50)); } |
