forked from Mirror/frr
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:
parent
6d53a10e4c
commit
1a8c390d4a
20
feed.x
Normal file → Executable file
20
feed.x
Normal file → Executable 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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}\)
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 *
|
||||||
|
|
Loading…
Reference in a new issue