lib: Fixed bad node copy, modified token regex

When building argv for matched command, only the
last node was being copied to argv; the rest were
added by reference. Additionally the regex for
certain tokens was too restrictive and disallowed
characters allowed by the old parser; these have
been reinstated.

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
Quentin Young 2016-08-01 17:03:39 +00:00
parent 6d53a10e4c
commit 1a8c390d4a
6 changed files with 53 additions and 51 deletions

20
feed.x Normal file → Executable file
View file

@ -1,14 +1,26 @@
#!/bin/expect #!/usr/bin/expect
set f [open "copt.txt"] # takes a list of command format strings
# and feeds them to the test grammar
# parser
set f [open [lindex $argv 0]]
set cmds [split [read $f] "\n"] set cmds [split [read $f] "\n"]
close $f close $f
spawn vtysh spawn vtysh
foreach command $cmds { foreach command $cmds {
expect "dell-s6000-16#" expect {
send "$command\r" "dell-s6000-16#" {
send "grammar parse $command\r"
}
"Grammar error" {
send_user "$command"
send "exit\r"
exit
}
}
} }
interact interact

View file

@ -88,29 +88,12 @@ new_node(enum graph_node_type type)
return node; return node;
} }
struct graph_node *
copy_node (struct graph_node *node)
{
struct graph_node *new = new_node(node->type);
new->children = NULL;
new->is_start = node->is_start;
new->end = node->end;
new->text = node->text ? XSTRDUP(MTYPE_CMD_TOKENS, node->text) : NULL;
new->value = node->value;
new->min = node->min;
new->max = node->max;
new->element = node->element ? copy_cmd_element(node->element) : NULL;
new->arg = node->arg ? XSTRDUP(MTYPE_CMD_TOKENS, node->arg) : NULL;
new->refs = 0;
return new;
}
void void
free_node (struct graph_node *node) free_node (struct graph_node *node)
{ {
if (!node) return; if (!node) return;
vector_free (node->children); if (node->children) vector_free (node->children);
free_cmd_element (node->element); if (node->element) free_cmd_element (node->element);
free (node->text); free (node->text);
free (node->arg); free (node->arg);
free (node); free (node);

View file

@ -77,18 +77,6 @@ cmp_node(struct graph_node *, struct graph_node *);
struct graph_node * struct graph_node *
new_node(enum graph_node_type); new_node(enum graph_node_type);
/**
* Copies a node.
* The children vector is copied, but the pointers the vector
* holds point to the same data as the original vector.
* The element, if it exists, is copied.
*
* @param[in] pointer to node to copy
* @return pointer to copied node
*/
struct graph_node *
copy_node(struct graph_node *);
/** /**
* Frees the data associated with a graph_node. * Frees the data associated with a graph_node.
* @param[out] pointer to graph_node to free * @param[out] pointer to graph_node to free

View file

@ -4,12 +4,12 @@
extern void set_buffer_string(const char *); extern void set_buffer_string(const char *);
%} %}
WORD [a-z][-_a-z0-9]+ WORD [-+a-z\*][-+_a-zA-Z0-9\*]*
IPV4 A\.B\.C\.D IPV4 A\.B\.C\.D
IPV4_PREFIX A\.B\.C\.D\/M IPV4_PREFIX A\.B\.C\.D\/M
IPV6 X:X::X:X IPV6 X:X::X:X
IPV6_PREFIX X:X::X:X\/M IPV6_PREFIX X:X::X:X\/M
VARIABLE [A-Z][A-Z_:]+ VARIABLE [A-Z][-_a-zA-Z:0-9]+
NUMBER [0-9]{1,20} NUMBER [0-9]{1,20}
RANGE \({NUMBER}\-{NUMBER}\) RANGE \({NUMBER}\-{NUMBER}\)

View file

@ -46,6 +46,24 @@ match_token (struct graph_node *, char *, enum filter_type);
/* matching functions */ /* matching functions */
static struct graph_node *
copy_node (struct graph_node *node)
{
struct graph_node *new = new_node(node->type);
new->children = NULL;
new->is_start = node->is_start;
new->end = NULL;
new->text = node->text ? XSTRDUP(MTYPE_CMD_TOKENS, node->text) : NULL;
new->value = node->value;
new->min = node->min;
new->max = node->max;
new->element = node->element ? copy_cmd_element(node->element) : NULL;
new->arg = node->arg ? XSTRDUP(MTYPE_CMD_TOKENS, node->arg) : NULL;
new->refs = 0;
return new;
}
/* Linked list data deletion callback */ /* Linked list data deletion callback */
static void static void
free_nodelist (void *node) { free_nodelist (void *node) {
@ -68,8 +86,8 @@ match_command (struct graph_node *start, const char *line, struct list **argv)
if (*argv) break; if (*argv) break;
} }
// walk the list, find the END_GN, return that
if (*argv) { if (*argv) {
// copy the nodes we need
struct listnode *ln; struct listnode *ln;
struct graph_node *gn; struct graph_node *gn;
char buf[50]; char buf[50];
@ -147,9 +165,6 @@ match_command_r (struct graph_node *start, vector vline, unsigned int n)
if (match_token(start, vector_slot(vline, n), FILTER_RELAXED) < minmatch) if (match_token(start, vector_slot(vline, n), FILTER_RELAXED) < minmatch)
return NULL; return NULL;
// arg list for this subgraph
struct list *argv;
// pointers for iterating linklist // pointers for iterating linklist
struct graph_node *gn; struct graph_node *gn;
struct listnode *ln; struct listnode *ln;
@ -165,11 +180,11 @@ match_command_r (struct graph_node *start, vector vline, unsigned int n)
struct graph_node *curr = copy_node(start); struct graph_node *curr = copy_node(start);
curr->arg = XSTRDUP(MTYPE_CMD_TOKENS, vector_slot(vline, n)); curr->arg = XSTRDUP(MTYPE_CMD_TOKENS, vector_slot(vline, n));
// initialize a new argument list // initialize a new argument list
argv = list_new(); struct list *argv = list_new();
argv->del = &free_nodelist; argv->del = &free_nodelist;
// push the currnode // add the current node
listnode_add(argv, curr); listnode_add(argv, copy_node(curr));
// push the endnode // push the end node
listnode_add(argv, copy_node(gn)); listnode_add(argv, copy_node(gn));
// clean up // clean up
list_delete (next); list_delete (next);
@ -215,13 +230,12 @@ match_command_r (struct graph_node *start, vector vline, unsigned int n)
} }
if (bestmatch) { if (bestmatch) {
argv = list_new(); struct graph_node *curr = copy_node(start);
listnode_add(argv, start); curr->arg = XSTRDUP(MTYPE_CMD_TOKENS, vector_slot(vline, n));
list_add_list(argv, bestmatch); list_add_node_prev (bestmatch, bestmatch->head, curr);
list_free (bestmatch); // cleanup
list_delete (next); list_delete (next);
start->arg = XSTRDUP(MTYPE_CMD_TOKENS, vector_slot(vline, n)); return bestmatch;
return argv;
} }
else else
return NULL; return NULL;

View file

@ -310,6 +310,11 @@ option_token:
void yyerror(char const *message) { void yyerror(char const *message) {
// fail on bad parse // fail on bad parse
fprintf(stderr, "Grammar error: %s\n", message); fprintf(stderr, "Grammar error: %s\n", message);
fprintf(stderr, "Token on error: ");
if (yylval.string) fprintf(stderr, "%s\n", yylval.string);
else if (yylval.node) fprintf(stderr, "%s\n", yylval.node->text);
else fprintf(stderr, "%d\n", yylval.integer);
} }
struct graph_node * struct graph_node *