From 5ff06872e924383e2139b63e9f6e8344b183c283 Mon Sep 17 00:00:00 2001 From: Lou Berger Date: Thu, 12 Jan 2017 08:30:17 -0500 Subject: bgpd: add vrf-policy config using existing vnc code add add/clear vrf prefix + Modified for FRR master parser Signed-off-by: Lou Berger --- lib/command.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/command.c') diff --git a/lib/command.c b/lib/command.c index 6294e994e7..4ac1d1abe5 100644 --- a/lib/command.c +++ b/lib/command.c @@ -741,6 +741,7 @@ node_parent ( enum node_type node ) case BGP_VPNV6_NODE: case BGP_ENCAP_NODE: case BGP_ENCAPV6_NODE: + case BGP_VRF_POLICY_NODE: case BGP_VNC_DEFAULTS_NODE: case BGP_VNC_NVE_GROUP_NODE: case BGP_VNC_L2_GROUP_NODE: @@ -1106,6 +1107,7 @@ cmd_exit (struct vty *vty) case BGP_VPNV6_NODE: case BGP_ENCAP_NODE: case BGP_ENCAPV6_NODE: + case BGP_VRF_POLICY_NODE: case BGP_VNC_DEFAULTS_NODE: case BGP_VNC_NVE_GROUP_NODE: case BGP_VNC_L2_GROUP_NODE: @@ -1169,6 +1171,7 @@ DEFUN (config_end, case BGP_NODE: case BGP_ENCAP_NODE: case BGP_ENCAPV6_NODE: + case BGP_VRF_POLICY_NODE: case BGP_VNC_DEFAULTS_NODE: case BGP_VNC_NVE_GROUP_NODE: case BGP_VNC_L2_GROUP_NODE: -- cgit v1.2.3 From 0bf5b1cbe3812e748d459fa4c4fb6596e072e7bd Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 16 Dec 2016 22:30:36 +0100 Subject: lib: parser: simplify OPTION_TKN & SELECTOR_TKN These are functionally identical as "fork" tokens. Signed-off-by: David Lamparter --- lib/command.c | 2 +- lib/command.h | 7 ++++--- lib/command_match.c | 36 ++++++++++++++++----------------- lib/command_parse.y | 17 ++++++++-------- lib/grammar_sandbox.c | 5 ++--- lib/grammar_sandbox.h | 56 --------------------------------------------------- tools/permutations.c | 2 +- 7 files changed, 33 insertions(+), 92 deletions(-) delete mode 100644 lib/grammar_sandbox.h (limited to 'lib/command.c') diff --git a/lib/command.c b/lib/command.c index 6294e994e7..cb1f54fbbd 100644 --- a/lib/command.c +++ b/lib/command.c @@ -1268,7 +1268,7 @@ permute (struct graph_node *start, struct vty *vty) for (ALL_LIST_ELEMENTS_RO (position,ln,gnn)) { struct cmd_token *tt = gnn->data; - if (tt->type < SELECTOR_TKN) + if (tt->type < SPECIAL_TKN) vty_out (vty, " %s", tt->text); } if (gn == start) diff --git a/lib/command.h b/lib/command.h index 1e1698fc7d..dd940f0d57 100644 --- a/lib/command.h +++ b/lib/command.h @@ -176,11 +176,12 @@ enum cmd_token_type IPV6_PREFIX_TKN, // IPV6 network prefixes /* plumbing types */ - SELECTOR_TKN, // marks beginning of selector - OPTION_TKN, // marks beginning of option - NUL_TKN, // dummy token + FORK_TKN, // marks subgraph beginning + JOIN_TKN, // marks subgraph end START_TKN, // first token in line END_TKN, // last token in line + + SPECIAL_TKN = FORK_TKN, }; /* Command attributes */ diff --git a/lib/command_match.c b/lib/command_match.c index d228563240..c3eec53bbc 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -459,7 +459,7 @@ command_complete (struct graph *graph, /** * Adds all children that are reachable by one parser hop to the given list. - * NUL_TKN, SELECTOR_TKN, and OPTION_TKN nodes are treated as transparent. + * special tokens except END_TKN are treated as transparent. * * @param[in] list to add the nexthops to * @param[in] node to start calculating nexthops from @@ -490,26 +490,24 @@ add_nexthops (struct list *list, struct graph_node *node, if (j != stackpos) continue; } - switch (token->type) + if (token->type >= SPECIAL_TKN && token->type != END_TKN) { - case OPTION_TKN: - case SELECTOR_TKN: - case NUL_TKN: - added += add_nexthops (list, child, stack, stackpos); - break; - default: - if (stack) - { - nextstack = XMALLOC (MTYPE_CMD_MATCHSTACK, - (stackpos + 1) * sizeof(struct graph_node *)); - nextstack[0] = child; - memcpy(nextstack + 1, stack, stackpos * sizeof(struct graph_node *)); + added += add_nexthops (list, child, stack, stackpos); + } + else + { + if (stack) + { + nextstack = XMALLOC (MTYPE_CMD_MATCHSTACK, + (stackpos + 1) * sizeof(struct graph_node *)); + nextstack[0] = child; + memcpy(nextstack + 1, stack, stackpos * sizeof(struct graph_node *)); - listnode_add (list, nextstack); - } - else - listnode_add (list, child); - added++; + listnode_add (list, nextstack); + } + else + listnode_add (list, child); + added++; } } diff --git a/lib/command_parse.y b/lib/command_parse.y index c920e11380..478ba0537c 100644 --- a/lib/command_parse.y +++ b/lib/command_parse.y @@ -274,8 +274,8 @@ placeholder_token: selector: '<' selector_seq_seq '>' { $$ = malloc (sizeof (struct subgraph)); - $$->start = new_token_node (ctx, SELECTOR_TKN, NULL, NULL); - $$->end = new_token_node (ctx, NUL_TKN, NULL, NULL); + $$->start = new_token_node (ctx, FORK_TKN, NULL, NULL); + $$->end = new_token_node (ctx, JOIN_TKN, NULL, NULL); for (unsigned int i = 0; i < vector_active ($2->start->to); i++) { struct graph_node *sn = vector_slot ($2->start->to, i), @@ -329,8 +329,8 @@ selector_seq_seq: selector: '{' selector_seq_seq '}' { $$ = malloc (sizeof (struct subgraph)); - $$->start = new_token_node (ctx, SELECTOR_TKN, NULL, NULL); - $$->end = new_token_node (ctx, NUL_TKN, NULL, NULL); + $$->start = new_token_node (ctx, FORK_TKN, NULL, NULL); + $$->end = new_token_node (ctx, JOIN_TKN, NULL, NULL); graph_add_edge ($$->start, $$->end); for (unsigned int i = 0; i < vector_active ($2->start->to); i++) { @@ -377,8 +377,8 @@ option: '[' option_token_seq ']' { // make a new option $$ = malloc (sizeof (struct subgraph)); - $$->start = new_token_node (ctx, OPTION_TKN, NULL, NULL); - $$->end = new_token_node (ctx, NUL_TKN, NULL, NULL); + $$->start = new_token_node (ctx, FORK_TKN, NULL, NULL); + $$->end = new_token_node (ctx, JOIN_TKN, NULL, NULL); // add a path through the sequence to the end graph_add_edge ($$->start, $2->start); graph_add_edge ($2->end, $$->end); @@ -575,8 +575,7 @@ cmp_token (struct cmd_token *first, struct cmd_token *second) * cases; ultimately this forks the graph, but the matcher can handle * this regardless */ - case SELECTOR_TKN: - case OPTION_TKN: + case FORK_TKN: return 0; /* end nodes are always considered equal, since each node may only @@ -584,7 +583,7 @@ cmp_token (struct cmd_token *first, struct cmd_token *second) */ case START_TKN: case END_TKN: - case NUL_TKN: + case JOIN_TKN: default: break; } diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c index 0239ca44ac..b5ac36c41f 100644 --- a/lib/grammar_sandbox.c +++ b/lib/grammar_sandbox.c @@ -275,9 +275,8 @@ struct message tokennames[] = { item(IPV6_PREFIX_TKN), // IPV6 network prefixes /* plumbing types */ - item(SELECTOR_TKN), // marks beginning of selector - item(OPTION_TKN), // marks beginning of option - item(NUL_TKN), // dummy token + item(FORK_TKN), + item(JOIN_TKN), item(START_TKN), // first token in line item(END_TKN), // last token in line { 0, NULL } diff --git a/lib/grammar_sandbox.h b/lib/grammar_sandbox.h deleted file mode 100644 index 5da0b05d09..0000000000 --- a/lib/grammar_sandbox.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef _GRAMMAR_SANDBOX_H -#define _GRAMMAR_SANDBOX_H - -/** - * Houses functionality for testing shim as well as code that should go into - * command.h and command.c during integration. - */ -#include "memory.h" - -#define CMD_CR_TEXT "" - -void -grammar_sandbox_init (void); - -/** - * Types for tokens. - * - * The type determines what kind of data the token can match (in the - * matching use case) or hold (in the argv use case). - */ -enum cmd_token_type_t -{ - WORD_TKN, // words - NUMBER_TKN, // integral numbers - VARIABLE_TKN, // almost anything - RANGE_TKN, // integer range - IPV4_TKN, // IPV4 addresses - IPV4_PREFIX_TKN, // IPV4 network prefixes - IPV6_TKN, // IPV6 prefixes - IPV6_PREFIX_TKN, // IPV6 network prefixes - - /* plumbing types */ - SELECTOR_TKN, // marks beginning of selector - OPTION_TKN, // marks beginning of option - NUL_TKN, // dummy token - START_TKN, // first token in line - END_TKN, // last token in line -}; - -/** - * Token struct. - */ -struct cmd_token_t -{ - enum cmd_token_type_t type; // token type - - char *text; // token text - char *desc; // token description - - long long value; // for numeric types - long long min, max; // for ranges - - char *arg; // user input that matches this token -}; - -#endif /* _GRAMMAR_SANDBOX_H */ diff --git a/tools/permutations.c b/tools/permutations.c index 8db51ee037..0ca980b259 100644 --- a/tools/permutations.c +++ b/tools/permutations.c @@ -70,7 +70,7 @@ permute (struct graph_node *start) for (ALL_LIST_ELEMENTS_RO (position,ln,gnn)) { struct cmd_token *tt = gnn->data; - if (tt->type < SELECTOR_TKN) + if (tt->type < SPECIAL_TKN) fprintf (stdout, "%s ", tt->text); } fprintf (stdout, "\n"); -- cgit v1.2.3 From af2567b646a9bdf22c3f47caeedc8f2de1dac81c Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 16 Dec 2016 08:11:37 +0100 Subject: grammar_sandbox: add into daemons if DEV_BUILD Also adds "grammar access " to test/dump an existing command node (e.g. BGP_NODE). Signed-off-by: David Lamparter --- lib/Makefile.am | 3 +- lib/command.c | 6 ++- lib/command.h | 4 ++ lib/grammar_sandbox.c | 123 +++++++++++++-------------------------------- lib/grammar_sandbox_main.c | 64 +++++++++++++++++++++++ 5 files changed, 109 insertions(+), 91 deletions(-) create mode 100644 lib/grammar_sandbox_main.c (limited to 'lib/command.c') diff --git a/lib/Makefile.am b/lib/Makefile.am index f2c076c475..b048720673 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -26,6 +26,7 @@ libzebra_la_SOURCES = \ imsg-buffer.c imsg.c skiplist.c \ qobj.c wheel.c \ event_counter.c \ + grammar_sandbox.c \ strlcpy.c \ strlcat.c @@ -53,7 +54,7 @@ noinst_HEADERS = \ noinst_PROGRAMS = grammar_sandbox -grammar_sandbox_SOURCES = grammar_sandbox.c +grammar_sandbox_SOURCES = grammar_sandbox_main.c grammar_sandbox_LDADD = libzebra.la EXTRA_DIST = \ diff --git a/lib/command.c b/lib/command.c index cb1f54fbbd..6fad28ce6c 100644 --- a/lib/command.c +++ b/lib/command.c @@ -523,7 +523,7 @@ compare_completions (const void *fst, const void *snd) * @param completions linked list of cmd_token * @return deduplicated and sorted vector with */ -static vector +vector completions_to_vec (struct list *completions) { vector comps = vector_init (VECTOR_MIN_SIZE); @@ -2398,6 +2398,10 @@ cmd_init (int terminal) vrf_install_commands (); } srandom(time(NULL)); + +#ifdef DEV_BUILD + grammar_sandbox_init(); +#endif } struct cmd_token * diff --git a/lib/command.h b/lib/command.h index b71142fdce..3da77d3af3 100644 --- a/lib/command.h +++ b/lib/command.h @@ -422,6 +422,9 @@ extern void cmd_terminate (void); extern void cmd_exit (struct vty *vty); extern int cmd_list_cmds (struct vty *vty, int do_permute); +/* NOT safe for general use; call this only if DEV_BUILD! */ +extern void grammar_sandbox_init (void); + /* memory management for cmd_token */ struct cmd_token * new_cmd_token (enum cmd_token_type, u_char attr, char *, char *); @@ -430,6 +433,7 @@ del_cmd_token (struct cmd_token *); struct cmd_token * copy_cmd_token (struct cmd_token *); +extern vector completions_to_vec (struct list *completions); extern void command_parse_format (struct graph *graph, struct cmd_element *cmd); /* Export typical functions. */ diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c index 98c75ca6e3..f92c78de55 100644 --- a/lib/grammar_sandbox.c +++ b/lib/grammar_sandbox.c @@ -3,11 +3,6 @@ * * This unit defines a number of commands in the old engine that can * be used to test and interact with the new engine. - * - * This shim should be removed upon integration. It is currently hooked in - * vtysh/vtysh.c. It has no header, vtysh.c merely includes this entire unit - * since it clutters up the makefiles less and this is only a temporary shim. - * * -- * Copyright (C) 2016 Cumulus Networks, Inc. * @@ -51,13 +46,9 @@ pretty_print_dot (FILE *ofd, unsigned opts, struct graph_node *start, struct graph_node **visited, size_t *visitpos); void init_cmdgraph (struct vty *, struct graph **); -vector -completions_to_vec (struct list *); -int -compare_completions (const void *, const void *); /** shim interface commands **/ -struct graph *nodegraph; +struct graph *nodegraph = NULL, *nodegraph_free = NULL; DEFUN (grammar_test, grammar_test_cmd, @@ -280,11 +271,41 @@ DEFUN (grammar_init_graph, GRAMMAR_STR "(re)initialize graph\n") { - graph_delete_graph (nodegraph); + if (nodegraph_free) + graph_delete_graph (nodegraph_free); + nodegraph_free = NULL; + init_cmdgraph (vty, &nodegraph); return CMD_SUCCESS; } +extern vector cmdvec; + +DEFUN (grammar_access, + grammar_access_cmd, + "grammar access (0-65535)", + GRAMMAR_STR + "access node graph\n" + "node number\n") +{ + if (nodegraph_free) + graph_delete_graph (nodegraph_free); + nodegraph_free = NULL; + + struct cmd_node *cnode; + + cnode = vector_slot (cmdvec, atoi (argv[2]->arg)); + if (!cnode) + { + vty_out (vty, "%% no such node%s", VTY_NEWLINE); + return CMD_WARNING; + } + + vty_out (vty, "node %d%s", (int)cnode->node, VTY_NEWLINE); + nodegraph = cnode->cmdgraph; + return CMD_SUCCESS; +} + /* this is called in vtysh.c to set up the testing shim */ void grammar_sandbox_init(void) { init_cmdgraph (NULL, &nodegraph); @@ -297,6 +318,7 @@ void grammar_sandbox_init(void) { install_element (ENABLE_NODE, &grammar_test_complete_cmd); install_element (ENABLE_NODE, &grammar_test_doc_cmd); install_element (ENABLE_NODE, &grammar_init_graph_cmd); + install_element (ENABLE_NODE, &grammar_access_cmd); } #define item(x) { x, #x } @@ -463,86 +485,9 @@ init_cmdgraph (struct vty *vty, struct graph **graph) { // initialize graph, add start noe *graph = graph_new (); + nodegraph_free = *graph; struct cmd_token *token = new_cmd_token (START_TKN, 0, NULL, NULL); graph_new_node (*graph, token, (void (*)(void *)) &del_cmd_token); if (vty) vty_out (vty, "initialized graph%s", VTY_NEWLINE); } - -int -compare_completions (const void *fst, const void *snd) -{ - struct cmd_token *first = *(struct cmd_token **) fst, - *secnd = *(struct cmd_token **) snd; - return strcmp (first->text, secnd->text); -} - -vector -completions_to_vec (struct list *completions) -{ - vector comps = vector_init (VECTOR_MIN_SIZE); - - struct listnode *ln; - struct cmd_token *token; - unsigned int i, exists; - for (ALL_LIST_ELEMENTS_RO(completions,ln,token)) - { - // linear search for token in completions vector - exists = 0; - for (i = 0; i < vector_active (comps) && !exists; i++) - { - struct cmd_token *curr = vector_slot (comps, i); - exists = !strcmp (curr->text, token->text) && - !strcmp (curr->desc, token->desc); - } - - if (!exists) - vector_set (comps, copy_cmd_token (token)); - } - - // sort completions - qsort (comps->index, - vector_active (comps), - sizeof (void *), - &compare_completions); - - return comps; -} - -static void vty_do_exit(void) -{ - printf ("\nend.\n"); - exit (0); -} - -struct thread_master *master; - -int main(int argc, char **argv) -{ - struct thread thread; - - master = thread_master_create (); - - zlog_default = openzlog ("grammar_sandbox", ZLOG_NONE, 0, - LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON); - zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED); - zlog_set_level (NULL, ZLOG_DEST_STDOUT, LOG_DEBUG); - zlog_set_level (NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED); - - /* Library inits. */ - cmd_init (1); - host.name = strdup ("test"); - - vty_init (master); - memory_init (); - grammar_sandbox_init(); - - vty_stdio (vty_do_exit); - - /* Fetch next active thread. */ - while (thread_fetch (master, &thread)) - thread_call (&thread); - - /* Not reached. */ - exit (0); -} diff --git a/lib/grammar_sandbox_main.c b/lib/grammar_sandbox_main.c new file mode 100644 index 0000000000..5deef406c1 --- /dev/null +++ b/lib/grammar_sandbox_main.c @@ -0,0 +1,64 @@ +/* + * Testing shim and API examples for the new CLI backend. + * + * Minimal main() to run grammar_sandbox standalone. + * [split off grammar_sandbox.c 2017-01-23] + * -- + * Copyright (C) 2016 Cumulus Networks, Inc. + * Copyright (C) 2017 David Lamparter for NetDEF, Inc. + * + * This file is part of FreeRangeRouting (FRR). + * + * FRR is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2, or (at your option) any later version. + * + * FRR is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along + * with FRR; see the file COPYING. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "command.h" +#include "memory_vty.h" + +static void vty_do_exit(void) +{ + printf ("\nend.\n"); + exit (0); +} + +struct thread_master *master; + +int main(int argc, char **argv) +{ + struct thread thread; + + master = thread_master_create (); + + zlog_default = openzlog ("grammar_sandbox", ZLOG_NONE, 0, + LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON); + zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED); + zlog_set_level (NULL, ZLOG_DEST_STDOUT, LOG_DEBUG); + zlog_set_level (NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED); + + /* Library inits. */ + cmd_init (1); + host.name = strdup ("test"); + + vty_init (master); + memory_init (); + + vty_stdio (vty_do_exit); + + /* Fetch next active thread. */ + while (thread_fetch (master, &thread)) + thread_call (&thread); + + /* Not reached. */ + exit (0); +} -- cgit v1.2.3 From 83364d20d5667c3b43e1e672d2166c22b6fd8cf5 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 25 Jan 2017 02:27:29 +0100 Subject: lib: parser: fix memory management command.c had: DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command desc") while command_match.c had: DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command Tokens") ... which means that there are 2 distinct MTYPE_CMD_TOKENS. (The description text being different does not matter, even with the same text it'd be 2 distinct types.) command_match.c allocates token->arg in command_match_r() while command.c frees it in del_cmd_token(). Therefore with each command being executed, the allocation count goes up on one, down on the other. => clean up parser allocation counting. Also, use separate MTYPEs for the different fields in struct cmd_token. Fixes: #108 / ee9216cf ("lib, ripngd: clean up merge leftovers") Signed-off-by: David Lamparter Cc: Quentin Young --- lib/command.c | 24 ++++++++++++++---------- lib/command.h | 11 +++++------ lib/command_match.c | 3 +-- lib/command_parse.y | 31 ++++++++++++++----------------- 4 files changed, 34 insertions(+), 35 deletions(-) (limited to 'lib/command.c') diff --git a/lib/command.c b/lib/command.c index b5dae5f28e..781f627bb5 100644 --- a/lib/command.c +++ b/lib/command.c @@ -43,7 +43,10 @@ DEFINE_MTYPE( LIB, HOST, "Host config") DEFINE_MTYPE( LIB, STRVEC, "String vector") -DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command desc") +DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command Tokens") +DEFINE_MTYPE_STATIC(LIB, CMD_DESC, "Command Token Text") +DEFINE_MTYPE_STATIC(LIB, CMD_TEXT, "Command Token Help") +DEFINE_MTYPE( LIB, CMD_ARG, "Command Argument") /* Command vector which includes some level of command lists. Normally each daemon maintains each own cmdvec. */ @@ -2405,13 +2408,14 @@ cmd_init (int terminal) } struct cmd_token * -new_cmd_token (enum cmd_token_type type, u_char attr, char *text, char *desc) +new_cmd_token (enum cmd_token_type type, u_char attr, + const char *text, const char *desc) { struct cmd_token *token = XCALLOC (MTYPE_CMD_TOKENS, sizeof (struct cmd_token)); token->type = type; token->attr = attr; - token->text = text; - token->desc = desc; + token->text = text ? XSTRDUP (MTYPE_CMD_TEXT, text) : NULL; + token->desc = desc ? XSTRDUP (MTYPE_CMD_DESC, desc) : NULL; token->arg = NULL; token->allowrepeat = false; @@ -2424,11 +2428,11 @@ del_cmd_token (struct cmd_token *token) if (!token) return; if (token->text) - XFREE (MTYPE_CMD_TOKENS, token->text); + XFREE (MTYPE_CMD_TEXT, token->text); if (token->desc) - XFREE (MTYPE_CMD_TOKENS, token->desc); + XFREE (MTYPE_CMD_DESC, token->desc); if (token->arg) - XFREE (MTYPE_CMD_TOKENS, token->arg); + XFREE (MTYPE_CMD_ARG, token->arg); XFREE (MTYPE_CMD_TOKENS, token); } @@ -2439,9 +2443,9 @@ copy_cmd_token (struct cmd_token *token) struct cmd_token *copy = new_cmd_token (token->type, token->attr, NULL, NULL); copy->max = token->max; copy->min = token->min; - copy->text = token->text ? XSTRDUP (MTYPE_CMD_TOKENS, token->text) : NULL; - copy->desc = token->desc ? XSTRDUP (MTYPE_CMD_TOKENS, token->desc) : NULL; - copy->arg = token->arg ? XSTRDUP (MTYPE_CMD_TOKENS, token->arg) : NULL; + 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; return copy; } diff --git a/lib/command.h b/lib/command.h index 1e1698fc7d..1e490cc4cd 100644 --- a/lib/command.h +++ b/lib/command.h @@ -31,6 +31,7 @@ #include "hash.h" DECLARE_MTYPE(HOST) +DECLARE_MTYPE(CMD_ARG) /* for test-commands.c */ DECLARE_MTYPE(STRVEC) @@ -420,12 +421,10 @@ extern void cmd_exit (struct vty *vty); extern int cmd_list_cmds (struct vty *vty, int do_permute); /* memory management for cmd_token */ -struct cmd_token * -new_cmd_token (enum cmd_token_type, u_char attr, char *, char *); -void -del_cmd_token (struct cmd_token *); -struct cmd_token * -copy_cmd_token (struct cmd_token *); +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 command_parse_format (struct graph *graph, struct cmd_element *cmd); diff --git a/lib/command_match.c b/lib/command_match.c index d228563240..aa58313134 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -27,7 +27,6 @@ #include "command_match.h" #include "memory.h" -DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command Tokens") DEFINE_MTYPE_STATIC(LIB, CMD_MATCHSTACK, "Command Match Stack") #define MAXDEPTH 64 @@ -322,7 +321,7 @@ command_match_r (struct graph_node *start, vector vline, unsigned int n, // copy token, set arg and prepend to currbest struct cmd_token *token = start->data; struct cmd_token *copy = copy_cmd_token (token); - copy->arg = XSTRDUP (MTYPE_CMD_TOKENS, input_token); + copy->arg = XSTRDUP (MTYPE_CMD_ARG, input_token); listnode_add_before (currbest, currbest->head, copy); matcher_rv = MATCHER_OK; } diff --git a/lib/command_parse.y b/lib/command_parse.y index c920e11380..7f98704f90 100644 --- a/lib/command_parse.y +++ b/lib/command_parse.y @@ -115,7 +115,7 @@ }; /* helper functions for parser */ - static char * + static const char * doc_next (struct parser_ctx *ctx); static struct graph_node * @@ -130,8 +130,8 @@ static struct graph_node * new_token_node (struct parser_ctx *, enum cmd_token_type type, - char *text, - char *doc); + const char *text, + const char *doc); static void terminate_graph (struct parser_ctx *ctx, @@ -222,7 +222,7 @@ compound_token: literal_token: WORD { - $$ = new_token_node (ctx, WORD_TKN, strdup($1), doc_next(ctx)); + $$ = new_token_node (ctx, WORD_TKN, $1, doc_next(ctx)); free ($1); } ; @@ -230,32 +230,32 @@ literal_token: WORD placeholder_token: IPV4 { - $$ = new_token_node (ctx, IPV4_TKN, strdup($1), doc_next(ctx)); + $$ = new_token_node (ctx, IPV4_TKN, $1, doc_next(ctx)); free ($1); } | IPV4_PREFIX { - $$ = new_token_node (ctx, IPV4_PREFIX_TKN, strdup($1), doc_next(ctx)); + $$ = new_token_node (ctx, IPV4_PREFIX_TKN, $1, doc_next(ctx)); free ($1); } | IPV6 { - $$ = new_token_node (ctx, IPV6_TKN, strdup($1), doc_next(ctx)); + $$ = new_token_node (ctx, IPV6_TKN, $1, doc_next(ctx)); free ($1); } | IPV6_PREFIX { - $$ = new_token_node (ctx, IPV6_PREFIX_TKN, strdup($1), doc_next(ctx)); + $$ = new_token_node (ctx, IPV6_PREFIX_TKN, $1, doc_next(ctx)); free ($1); } | VARIABLE { - $$ = new_token_node (ctx, VARIABLE_TKN, strdup($1), doc_next(ctx)); + $$ = new_token_node (ctx, VARIABLE_TKN, $1, doc_next(ctx)); free ($1); } | RANGE { - $$ = new_token_node (ctx, RANGE_TKN, strdup($1), doc_next(ctx)); + $$ = new_token_node (ctx, RANGE_TKN, $1, doc_next(ctx)); struct cmd_token *token = $$->data; // get the numbers out @@ -462,10 +462,7 @@ terminate_graph (struct parser_ctx *ctx, struct graph_node *finalnode) // * -> finalnode -> END_TKN -> cmd_element struct cmd_element *element = ctx->el; struct graph_node *end_token_node = - new_token_node (ctx, - END_TKN, - strdup (CMD_CR_TEXT), - strdup ("")); + new_token_node (ctx, END_TKN, CMD_CR_TEXT, ""); struct graph_node *end_element_node = graph_new_node (ctx->graph, element, NULL); @@ -476,7 +473,7 @@ terminate_graph (struct parser_ctx *ctx, struct graph_node *finalnode) graph_add_edge (end_token_node, end_element_node); } -static char * +static const char * doc_next (struct parser_ctx *ctx) { const char *piece = ctx->docstr ? strsep (&ctx->docstr, "\n") : ""; @@ -486,12 +483,12 @@ doc_next (struct parser_ctx *ctx) piece = ""; } - return strdup (piece); + return piece; } static struct graph_node * new_token_node (struct parser_ctx *ctx, enum cmd_token_type type, - char *text, char *doc) + const char *text, const char *doc) { struct cmd_token *token = new_cmd_token (type, ctx->el->attr, text, doc); return graph_new_node (ctx->graph, token, (void (*)(void *)) &del_cmd_token); -- cgit v1.2.3