diff options
| -rw-r--r-- | lib/command.c | 34 | ||||
| -rw-r--r-- | lib/command.h | 6 |
2 files changed, 37 insertions, 3 deletions
diff --git a/lib/command.c b/lib/command.c index 4f5b727ac5..56c262a647 100644 --- a/lib/command.c +++ b/lib/command.c @@ -224,6 +224,18 @@ argv_concat (const char **argv, int argc, int shift) return str; } +static unsigned int +cmd_hash_key (void *p) +{ + return (uintptr_t) p; +} + +static int +cmd_hash_cmp (const void *a, const void *b) +{ + return a == b; +} + /* Install top node of command vector. */ void install_node (struct cmd_node *node, @@ -232,6 +244,7 @@ install_node (struct cmd_node *node, vector_set_index (cmdvec, node->node, node); node->func = func; node->cmd_vector = vector_init (VECTOR_MIN_SIZE); + node->cmd_hash = hash_create (cmd_hash_key, cmd_hash_cmp); } /* Breaking up string into each command piece. I assume given @@ -704,7 +717,11 @@ install_element (enum node_type ntype, struct cmd_element *cmd) /* cmd_init hasn't been called */ if (!cmdvec) - return; + { + fprintf (stderr, "%s called before cmd_init, breakage likely\n", + __func__); + return; + } cnode = vector_slot (cmdvec, ntype); @@ -714,7 +731,17 @@ install_element (enum node_type ntype, struct cmd_element *cmd) ntype); exit (1); } - + + if (hash_lookup (cnode->cmd_hash, cmd) != NULL) + { + fprintf (stderr, + "Multiple command installs to node %d of command:\n%s\n", + ntype, cmd->string); + return; + } + + assert (hash_get (cnode->cmd_hash, cmd, hash_alloc_intern)); + vector_set (cnode->cmd_vector, cmd); if (cmd->tokens == NULL) cmd->tokens = cmd_parse_format(cmd->string, cmd->doc); @@ -4364,6 +4391,9 @@ cmd_terminate () cmd_terminate_element(cmd_element); vector_free (cmd_node_v); + hash_clean (cmd_node->cmd_hash, NULL); + hash_free (cmd_node->cmd_hash); + cmd_node->cmd_hash = NULL; } vector_free (cmdvec); diff --git a/lib/command.h b/lib/command.h index ad9ccf505e..e4aa10196f 100644 --- a/lib/command.h +++ b/lib/command.h @@ -27,6 +27,7 @@ #include "vty.h" #include "lib/route_types.h" #include "memory.h" +#include "hash.h" DECLARE_MTYPE(HOST) @@ -147,7 +148,10 @@ struct cmd_node int (*func) (struct vty *); /* Vector of this node's command list. */ - vector cmd_vector; + vector cmd_vector; + + /* Hashed index of command node list, for de-dupping primarily */ + struct hash *cmd_hash; }; enum |
