]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: Move string completions out of command_match.c
authorQuentin Young <qlyoung@cumulusnetworks.com>
Tue, 13 Sep 2016 18:33:55 +0000 (18:33 +0000)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Tue, 13 Sep 2016 18:33:55 +0000 (18:33 +0000)
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
lib/command_match.c
lib/command_match.h
lib/grammar_sandbox.c

index 3faa059a440bd62778ffb66fe3b94ea92b9b613d..ca2135a1c22f59146bc98e0747173b6c11152c7a 100644 (file)
@@ -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.
index 2bb079033749d1f7302fd9293ea5cf9a238e84a0..728d9c1d95c32c32f22cc97ed7f5dc4795ee5545 100644 (file)
@@ -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 */
index 1ba76babda4e41d4db98d518f65e0d333d2eef82..1fe46a87e51efc31165d490665a02c8d73d0b19f 100644 (file)
@@ -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;
 }