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"]
close $f
spawn vtysh
foreach command $cmds {
expect "dell-s6000-16#"
send "$command\r"
expect {
"dell-s6000-16#" {
send "grammar parse $command\r"
}
"Grammar error" {
send_user "$command"
send "exit\r"
exit
}
}
}
interact

View file

@ -88,29 +88,12 @@ new_node(enum graph_node_type type)
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
free_node (struct graph_node *node)
{
if (!node) return;
vector_free (node->children);
free_cmd_element (node->element);
if (node->children) vector_free (node->children);
if (node->element) free_cmd_element (node->element);
free (node->text);
free (node->arg);
free (node);

View file

@ -77,18 +77,6 @@ cmp_node(struct graph_node *, struct graph_node *);
struct graph_node *
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.
* @param[out] pointer to graph_node to free

View file

@ -4,12 +4,12 @@
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_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-zA-Z:0-9]+
NUMBER [0-9]{1,20}
RANGE \({NUMBER}\-{NUMBER}\)

View file

@ -46,6 +46,24 @@ match_token (struct graph_node *, char *, enum filter_type);
/* 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 */
static void
free_nodelist (void *node) {
@ -68,8 +86,8 @@ match_command (struct graph_node *start, const char *line, struct list **argv)
if (*argv) break;
}
// walk the list, find the END_GN, return that
if (*argv) {
// copy the nodes we need
struct listnode *ln;
struct graph_node *gn;
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)
return NULL;
// arg list for this subgraph
struct list *argv;
// pointers for iterating linklist
struct graph_node *gn;
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);
curr->arg = XSTRDUP(MTYPE_CMD_TOKENS, vector_slot(vline, n));
// initialize a new argument list
argv = list_new();
struct list *argv = list_new();
argv->del = &free_nodelist;
// push the currnode
listnode_add(argv, curr);
// push the endnode
// add the current node
listnode_add(argv, copy_node(curr));
// push the end node
listnode_add(argv, copy_node(gn));
// clean up
list_delete (next);
@ -215,13 +230,12 @@ match_command_r (struct graph_node *start, vector vline, unsigned int n)
}
if (bestmatch) {
argv = list_new();
listnode_add(argv, start);
list_add_list(argv, bestmatch);
list_free (bestmatch);
struct graph_node *curr = copy_node(start);
curr->arg = XSTRDUP(MTYPE_CMD_TOKENS, vector_slot(vline, n));
list_add_node_prev (bestmatch, bestmatch->head, curr);
// cleanup
list_delete (next);
start->arg = XSTRDUP(MTYPE_CMD_TOKENS, vector_slot(vline, n));
return argv;
return bestmatch;
}
else
return NULL;

View file

@ -310,6 +310,11 @@ option_token:
void yyerror(char const *message) {
// fail on bad parse
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 *