From: David Lamparter Date: Fri, 18 Nov 2016 11:06:57 +0000 (+0100) Subject: lib: parser: add named variables in CLI X-Git-Tag: reindent-master-before~168 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=16705ecc653dd657c5b8149934d8734e89c27c07;p=mirror%2Ffrr.git lib: parser: add named variables in CLI struct cmd_token now has a "varname" field which is derived from the DEFUN's string definition. It can be manually specified with "$name" after some token, e.g. "foo WORD$var". A later commit adds code to automatically fill the value if nothing is specified. Signed-off-by: David Lamparter --- diff --git a/lib/command.c b/lib/command.c index 2b8eee8de3..06d9422f70 100644 --- a/lib/command.c +++ b/lib/command.c @@ -2772,6 +2772,7 @@ new_cmd_token (enum cmd_token_type type, u_char attr, token->refcnt = 1; token->arg = NULL; token->allowrepeat = false; + token->varname = NULL; return token; } @@ -2800,10 +2801,18 @@ copy_cmd_token (struct cmd_token *token) copy->text = token->text ? XSTRDUP (MTYPE_CMD_TEXT, token->text) : NULL; copy->desc = token->desc ? XSTRDUP (MTYPE_CMD_DESC, token->desc) : NULL; copy->arg = token->arg ? XSTRDUP (MTYPE_CMD_ARG, token->arg) : NULL; + copy->varname = token->varname ? XSTRDUP (MTYPE_CMD_ARG, token->varname) : NULL; return copy; } +void +cmd_set_varname (struct cmd_token *token, const char *varname) +{ + XFREE (MTYPE_CMD_VAR, token->varname); + token->varname = varname ? XSTRDUP (MTYPE_CMD_VAR, varname) : NULL; +} + void cmd_terminate () { diff --git a/lib/command.h b/lib/command.h index 8f6abc85ba..9b2af57991 100644 --- a/lib/command.h +++ b/lib/command.h @@ -210,6 +210,7 @@ struct cmd_token char *desc; // token description long long min, max; // for ranges char *arg; // user input that matches this token + char *varname; struct graph_node *forkjoin; // paired FORK/JOIN for JOIN/FORK }; @@ -446,6 +447,7 @@ extern struct cmd_token *new_cmd_token (enum cmd_token_type, u_char attr, const char *text, const char *desc); extern void del_cmd_token (struct cmd_token *); extern struct cmd_token *copy_cmd_token (struct cmd_token *); +extern void cmd_set_varname(struct cmd_token *token, const char *varname); extern vector completions_to_vec (struct list *completions); extern void cmd_merge_graphs (struct graph *old, struct graph *new, int direction); diff --git a/lib/command_parse.y b/lib/command_parse.y index 0c415af3aa..7e7a68ffdd 100644 --- a/lib/command_parse.y +++ b/lib/command_parse.y @@ -104,12 +104,15 @@ %type start %type literal_token %type placeholder_token +%type placeholder_token_real %type simple_token %type selector %type selector_token %type selector_token_seq %type selector_seq_seq +%type varname_token + %code { /* bison declarations */ @@ -184,6 +187,16 @@ start: } ; +varname_token: '$' WORD +{ + $$ = XSTRDUP (MTYPE_LEX, $2); +} +| /* empty */ +{ + $$ = NULL; +} +; + cmd_token_seq: /* empty */ | cmd_token_seq cmd_token @@ -207,14 +220,16 @@ simple_token: | placeholder_token ; -literal_token: WORD +literal_token: WORD varname_token { $$ = new_token_node (ctx, WORD_TKN, $1, doc_next(ctx)); + cmd_set_varname ($$->data, $2); + XFREE (MTYPE_LEX, $2); XFREE (MTYPE_LEX, $1); } ; -placeholder_token: +placeholder_token_real: IPV4 { $$ = new_token_node (ctx, IPV4_TKN, $1, doc_next(ctx)); @@ -257,10 +272,22 @@ placeholder_token: XFREE (MTYPE_LEX, $1); } +placeholder_token: + placeholder_token_real varname_token +{ + struct cmd_token *token = $$->data; + $$ = $1; + cmd_set_varname (token, $2); + XFREE (MTYPE_LEX, $2); +}; + + /* productions */ -selector: '<' selector_seq_seq '>' +selector: '<' selector_seq_seq '>' varname_token { $$ = $2; + cmd_set_varname ($2.end->data, $4); + XFREE (MTYPE_LEX, $4); }; selector_seq_seq: @@ -283,7 +310,7 @@ selector_seq_seq: ; /* {keyword} productions */ -selector: '{' selector_seq_seq '}' +selector: '{' selector_seq_seq '}' varname_token { $$ = $2; graph_add_edge ($$.end, $$.start); @@ -293,6 +320,9 @@ selector: '{' selector_seq_seq '}' * loop-avoidal fails to handle * just use [{a|b}] if neccessary, that will work perfectly fine, and reason * #1 is good enough to keep it this way. */ + + cmd_set_varname ($2.end->data, $4); + XFREE (MTYPE_LEX, $4); }; @@ -315,10 +345,12 @@ selector_token_seq: ; /* [option] productions */ -selector: '[' selector_seq_seq ']' +selector: '[' selector_seq_seq ']' varname_token { $$ = $2; graph_add_edge ($$.start, $$.end); + cmd_set_varname ($2.end->data, $4); + XFREE (MTYPE_LEX, $4); } ; diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c index 0da7981fc1..f35b8beffd 100644 --- a/lib/grammar_sandbox.c +++ b/lib/grammar_sandbox.c @@ -526,6 +526,8 @@ pretty_print_graph (struct vty *vty, struct graph_node *start, int level, vty_out(vty, "%s", LOOKUP_DEF(tokennames, tok->type, tokennum)); if (tok->text) vty_out(vty, ":\"%s\"", tok->text); + if (tok->varname) + vty_out(vty, " => %s", tok->varname); if (desc) vty_out(vty, " ?'%s'", tok->desc); vty_out(vty, " ");