From: Quentin Young Date: Tue, 13 Sep 2016 18:33:55 +0000 (+0000) Subject: lib: Move string completions out of command_match.c X-Git-Tag: frr-3.0-branchpoint~129^2~233 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=ee761cc086a1cbee6dd705fece71cb004b215e21;p=matthieu%2Ffrr.git lib: Move string completions out of command_match.c Signed-off-by: Quentin Young --- diff --git a/lib/command_match.c b/lib/command_match.c index 3faa059a44..ca2135a1c2 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -335,55 +335,6 @@ command_complete (struct graph *graph, return matcher_rv; } -/** - * TODO: move this logic to command.c - * Compare two completions. Tightly coupled to vector. - * - * @param[in] fst pointer to first item pointer in vector->index - * @param[in] snd pointer to second item poitner in vector->index - * @return integer compare code as determined by strcmp -int -compare_completions (const void *fst, const void *snd) -{ - const char *first = *((char **) fst); - const char *secnd = *((char **) snd); - return strcmp (first, secnd); -} - -enum matcher_rv -command_complete_str (struct graph_node *start, - vector vline, - vector completions) -{ - struct list *comps; - enum matcher_rv rv = command_complete (start, vline, &comps); - - // quick n' dirty deduplication fn here, prolly like O(n^n) - struct listnode *ln; - struct graph_node *gn; - unsigned int i; - for (ALL_LIST_ELEMENTS_RO(comps,ln,gn)) - { - // linear search for node text in completions vector - int exists = 0; - for (i = 0; i < vector_active (completions) && !exists; i++) - exists = !strcmp (gn->text, vector_slot (completions, i)); - - if (!exists) - vector_set (completions, XSTRDUP(MTYPE_TMP, gn->text)); - } - - // sort completions - qsort (completions->index, - vector_active (completions), - sizeof (void *), - &compare_completions); - - list_delete (comps); - return rv; -} -*/ - /** * 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. diff --git a/lib/command_match.h b/lib/command_match.h index 2bb0790337..728d9c1d95 100644 --- a/lib/command_match.h +++ b/lib/command_match.h @@ -92,18 +92,4 @@ command_complete (struct graph *cmdgraph, vector vline, struct list **completions); - -/** - * Compiles possible completions for a given line of user input. - * - * @param[in] start the start node of the DFA to match against - * @param[in] vline vectorized input string - * @param[in] completions vector to fill with string completions - * @return matcher status -enum matcher_rv -command_complete_str (struct graph *cmdgraph, - vector vline, - vector completions); - - */ #endif /* _ZEBRA_COMMAND_MATCH_H */ diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c index 1ba76babda..1fe46a87e5 100644 --- a/lib/grammar_sandbox.c +++ b/lib/grammar_sandbox.c @@ -43,6 +43,10 @@ void pretty_print_graph (struct graph_node *, int); void init_cmdgraph (struct graph **); +vector +completions_to_vec (struct list *); +int +compare_completions (const void *, const void *); /** shim interface commands **/ struct graph *nodegraph; @@ -86,25 +90,22 @@ DEFUN (grammar_test_complete, // print completions or relevant error message if (!MATCHER_ERROR(result)) { - struct listnode *ln; + vector comps = completions_to_vec (completions); struct cmd_token_t *tkn; // calculate length of longest tkn->text in completions - int width = 0; - for (ALL_LIST_ELEMENTS_RO (completions,ln,tkn)) { - if (tkn && tkn->text) { - int len = strlen (tkn->text); - width = len > width ? len : width; - } - else { - fprintf (stdout, "tkn: %p\n", tkn); - fprintf (stdout, "tkn->text: %p\n", tkn->text); - } + unsigned int width = 0, i = 0; + for (i = 0; i < vector_active (comps); i++) { + tkn = vector_slot (comps, i); + unsigned int len = strlen (tkn->text); + width = len > width ? len : width; } // print completions - for (ALL_LIST_ELEMENTS_RO (completions,ln,tkn)) + for (i = 0; i < vector_active (comps); i++) { + tkn = vector_slot (comps, i); fprintf (stdout, " %-*s %s%s", width, tkn->text, tkn->desc, "\n"); + } } else fprintf (stdout, "%% No match%s", "\n"); @@ -295,6 +296,46 @@ init_cmdgraph (struct graph **graph) fprintf (stdout, "initialized graph\n"); } +int +compare_completions (const void *fst, const void *snd) +{ + struct cmd_token_t *first = *(struct cmd_token_t **) fst, + *secnd = *(struct cmd_token_t **) 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_t *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_t *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; +} + struct cmd_token_t * new_cmd_token (enum cmd_token_type_t type, char *text, char *desc) { @@ -326,9 +367,12 @@ struct cmd_token_t * copy_cmd_token (struct cmd_token_t *token) { struct cmd_token_t *copy = new_cmd_token (token->type, NULL, NULL); - 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->value = token->value; + 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; return copy; }