lib: Fix various minor bugs

- cmd_make_strvec returns null pointer if str
  begins with a '#'
- disallow options nested options
- NULL out state variable in parser
- flip backwards comparison
- fix memory leak in lexer

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
Quentin Young 2016-08-09 17:37:01 +00:00
parent 1ab84bf32f
commit 4427e9b3ee
4 changed files with 27 additions and 8 deletions

View file

@ -25,7 +25,9 @@
%{ %{
#include "command_parse.h" #include "command_parse.h"
extern void set_buffer_string(const char *); extern void set_lexer_string (const char *);
extern void cleanup_lexer (void);
YY_BUFFER_STATE buffer;
%} %}
WORD (\-|\+)?[a-z\*][-+_a-zA-Z0-9\*]* WORD (\-|\+)?[a-z\*][-+_a-zA-Z0-9\*]*
@ -62,7 +64,13 @@ RANGE \({NUMBER}[ ]?\-[ ]?{NUMBER}\)
%% %%
void void
set_buffer_string(const char *string) set_lexer_string (const char *string)
{ {
yy_scan_string(string); buffer = yy_scan_string (XSTRDUP(MTYPE_TMP, string));
}
void
cleanup_lexer ()
{
yy_delete_buffer (buffer);
} }

View file

@ -158,6 +158,8 @@ match_command (struct graph_node *start,
static struct list * static struct list *
match_command_r (struct graph_node *start, vector vline, unsigned int n) match_command_r (struct graph_node *start, vector vline, unsigned int n)
{ {
assert (n < vector_active (vline));
// get the minimum match level that can count as a full match // get the minimum match level that can count as a full match
enum match_type minmatch = min_match_level (start->type); enum match_type minmatch = min_match_level (start->type);

View file

@ -41,7 +41,10 @@
yylex (void); yylex (void);
extern void extern void
set_buffer_string (const char *); set_lexer_string (const char *);
extern void
cleanup_lexer (void);
} }
/* functionality this unit exports */ /* functionality this unit exports */
@ -135,7 +138,7 @@
optnode_start = optnode_end = NULL; optnode_start = optnode_end = NULL;
/* set string to parse */ /* set string to parse */
set_buffer_string (element->string); set_lexer_string (element->string);
/* copy docstring and keep a pointer to the copy */ /* copy docstring and keep a pointer to the copy */
docstr = element->doc ? XSTRDUP(MTYPE_TMP, element->doc) : NULL; docstr = element->doc ? XSTRDUP(MTYPE_TMP, element->doc) : NULL;
@ -341,7 +344,6 @@ selector_element_root:
selector_token: selector_token:
selector_element_root selector_element_root
| option
; ;
/* [option|set] productions */ /* [option|set] productions */
@ -368,6 +370,7 @@ option_element:
add_node (optnode_start, seqhead); add_node (optnode_start, seqhead);
add_node ($1, optnode_end); add_node ($1, optnode_end);
seqhead = NULL;
} }
option_token_seq: option_token_seq:
@ -412,6 +415,9 @@ cleanup()
/* free resources */ /* free resources */
free (docstr_start); free (docstr_start);
/* cleanup lexer */
cleanup_lexer();
/* clear state pointers */ /* clear state pointers */
seqhead = NULL; seqhead = NULL;
currnode = NULL; currnode = NULL;

View file

@ -63,7 +63,7 @@ DEFUN (grammar_test,
// initialize a pretend cmd_element // initialize a pretend cmd_element
struct cmd_element *cmd = XCALLOC(MTYPE_CMD_TOKENS, sizeof(struct cmd_element)); struct cmd_element *cmd = XCALLOC(MTYPE_CMD_TOKENS, sizeof(struct cmd_element));
cmd->string = command; cmd->string = XSTRDUP(MTYPE_TMP, command);
cmd->doc = NULL; cmd->doc = NULL;
cmd->func = NULL; cmd->func = NULL;
cmd->tokens = vector_init(VECTOR_MIN_SIZE); cmd->tokens = vector_init(VECTOR_MIN_SIZE);
@ -132,6 +132,9 @@ DEFUN (grammar_test_match,
"command to match") "command to match")
{ {
char *cmdstr = argv_concat(argv, argc, 0); char *cmdstr = argv_concat(argv, argc, 0);
if (cmdstr[0] == '#')
return CMD_SUCCESS;
vector command = cmd_make_strvec (cmdstr); vector command = cmd_make_strvec (cmdstr);
struct list *argvv = NULL; struct list *argvv = NULL;
@ -145,7 +148,7 @@ DEFUN (grammar_test_match,
struct listnode *ln; struct listnode *ln;
struct graph_node *gn; struct graph_node *gn;
for (ALL_LIST_ELEMENTS_RO(argvv,ln,gn)) for (ALL_LIST_ELEMENTS_RO(argvv,ln,gn))
if (gn->type != END_GN) if (gn->type == END_GN)
zlog_info ("func: %p", gn->element->func); zlog_info ("func: %p", gn->element->func);
else else
zlog_info ("%s -- %s", gn->text, gn->arg); zlog_info ("%s -- %s", gn->text, gn->arg);