]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: Add docstring support
authorQuentin Young <qlyoung@cumulusnetworks.com>
Fri, 5 Aug 2016 16:41:42 +0000 (16:41 +0000)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Fri, 5 Aug 2016 16:41:42 +0000 (16:41 +0000)
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
lib/command_graph.h
lib/command_parse.y
lib/grammar_sandbox.c

index e1feb9f77f4f15c146f7f87c3fe4de1698dd65f2..c987213633088e09ea9fe1c232f5cd5f24b09697 100644 (file)
@@ -27,7 +27,8 @@ struct graph_node
   vector children;          // this node's children
   struct graph_node * end;  // pointer to end for SELECTOR_GN & OPTION_GN
 
-  char* text;               // for WORD_GN and VARIABLE_GN
+  char *text;               // original format text
+  char *doc;                // docstring for this node
   long long value;          // for NUMBER_GN
   long long min, max;       // for RANGE_GN
 
index ac075e67a30fc186f0b95d35e2ddb097921a7e22..35fac1b7d5f700ab99d8bf02010dab7582b6f753 100644 (file)
@@ -15,6 +15,8 @@ struct graph_node *
 node_exists(struct graph_node *, struct graph_node *);
 struct graph_node *
 node_replace(struct graph_node *, struct graph_node *);
+char *
+doc_next(void);
 
 #define DECIMAL_STRLEN_MAX 20
 
@@ -55,6 +57,7 @@ struct graph_node *selnode_start,   // start node for selector set
                   *selnode_end;     // end node for selector set
 
 struct cmd_element *command;        // command we're parsing
+char *docstring;
 %}
 
 %token <string> WORD
@@ -128,6 +131,7 @@ sentence_root: WORD
 {
   struct graph_node *root = new_node(WORD_GN);
   root->text = XSTRDUP(MTYPE_CMD_TOKENS, $1);
+  root->doc = doc_next();
 
   if ((currnode = node_replace(startnode, root)) != root)
     free (root);
@@ -173,36 +177,42 @@ placeholder_token:
 {
   $$ = new_node(IPV4_GN);
   $$->text = XSTRDUP(MTYPE_CMD_TOKENS, $1);
+  $$->doc = doc_next();
   free ($1);
 }
 | IPV4_PREFIX
 {
   $$ = new_node(IPV4_PREFIX_GN);
   $$->text = XSTRDUP(MTYPE_CMD_TOKENS, $1);
+  $$->doc = doc_next();
   free ($1);
 }
 | IPV6
 {
   $$ = new_node(IPV6_GN);
   $$->text = XSTRDUP(MTYPE_CMD_TOKENS, $1);
+  $$->doc = doc_next();
   free ($1);
 }
 | IPV6_PREFIX
 {
   $$ = new_node(IPV6_PREFIX_GN);
   $$->text = XSTRDUP(MTYPE_CMD_TOKENS, $1);
+  $$->doc = doc_next();
   free ($1);
 }
 | VARIABLE
 {
   $$ = new_node(VARIABLE_GN);
   $$->text = XSTRDUP(MTYPE_CMD_TOKENS, $1);
+  $$->doc = doc_next();
   free ($1);
 }
 | RANGE
 {
   $$ = new_node(RANGE_GN);
   $$->text = XSTRDUP(MTYPE_CMD_TOKENS, $1);
+  $$->doc = doc_next();
 
   // get the numbers out
   yylval.string++;
@@ -222,12 +232,16 @@ literal_token:
 {
   $$ = new_node(WORD_GN);
   $$->text = XSTRDUP(MTYPE_CMD_TOKENS, $1);
+  $$->doc = doc_next();
   free ($1);
 }
 | NUMBER
 {
   $$ = new_node(NUMBER_GN);
   $$->value = yylval.integer;
+  $$->text = XCALLOC(MTYPE_CMD_TOKENS, DECIMAL_STRLEN_MAX+1);
+  snprintf($$->text, DECIMAL_STRLEN_MAX, "%lld", $$->value);
+  $$->doc = doc_next();
 }
 ;
 
@@ -354,12 +368,17 @@ parse_command_format(struct graph_node *start, struct cmd_element *cmd)
 
   // trace parser
   yydebug = 0;
-  // command string
+  // command element
   command = cmd;
+  // copy docstring and keep a pointer to the copy
+  char *doc = docstring = cmd->doc ? XSTRDUP(MTYPE_TMP, cmd->doc) : NULL;
   // make flex read from a string
   set_buffer_string(command->string);
   // parse command into DFA
   yyparse();
+  // cleanup
+  free (doc);
+  doc = NULL;
   // startnode points to command DFA
   return startnode;
 }
@@ -386,3 +405,12 @@ node_replace(struct graph_node *parent, struct graph_node *child)
 
   return existing;
 }
+
+char *
+doc_next()
+{
+  char *piece = NULL;
+  if (!docstring || !(piece = strsep(&docstring, "\n")))
+    return NULL;
+  return XSTRDUP(MTYPE_CMD_TOKENS, piece);
+}
index a2177c176713d9bb1ab2199f1e45c8d5061e79e0..d1779a9b6e805b4b9f4adf8cdafe21c2c2d1de97 100644 (file)
@@ -24,6 +24,33 @@ DEFUN (grammar_test,
   return CMD_SUCCESS;
 }
 
+DEFUN (grammar_test_doc,
+       grammar_test_doc_cmd,
+       "grammar test docstring",
+       GRAMMAR_STR
+       "Test function for docstring\n"
+       "Command end\n")
+{
+  struct cmd_element *cmd = malloc(sizeof(struct cmd_element));
+  cmd->string = "test docstring <example|selector follow> (1-255) end VARIABLE [OPTION|set lol] . VARARG";
+  cmd->doc = "Test stuff\n"
+             "docstring thing\n"
+             "first example\n"
+             "second example\n"
+             "follow\n"
+             "random range\n"
+             "end thingy\n"
+             "variable\n"
+             "optional variable\n"
+             "optional set\n"
+             "optional lol\n"
+             "vararg!\n";
+  cmd->func = NULL;
+  cmd->tokens = vector_init(VECTOR_MIN_SIZE);
+  parse_command_format(nodegraph, cmd);
+  return CMD_SUCCESS;
+}
+
 DEFUN (grammar_test_show,
        grammar_test_show_cmd,
        "grammar tree",
@@ -52,7 +79,7 @@ DEFUN (grammar_test_complete,
   else
   {
     fprintf(stderr, "%% Matched full input, possible completions:\n");
-    char* desc = malloc(50);
+    char* desc = malloc(30);
     struct listnode *node;
     struct graph_node *cnode;
     // print possible next hops, if any
@@ -60,7 +87,7 @@ DEFUN (grammar_test_complete,
       if (cnode->type == END_GN)
         fprintf(stderr, "<cr> %p\n", cnode->element->func);
       else
-        fprintf(stderr, "%s\n", describe_node(cnode, desc, 50));
+        fprintf(stderr, "%-30s%s\n", describe_node(cnode, desc, 30), cnode->doc);
     }
     free(desc);
   }
@@ -118,4 +145,5 @@ void grammar_sandbox_init() {
   install_element (ENABLE_NODE, &grammar_test_show_cmd);
   install_element (ENABLE_NODE, &grammar_test_match_cmd);
   install_element (ENABLE_NODE, &grammar_test_complete_cmd);
+  install_element (ENABLE_NODE, &grammar_test_doc_cmd);
 }