summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@cumulusnetworks.com>2016-08-05 16:41:42 +0000
committerQuentin Young <qlyoung@cumulusnetworks.com>2016-08-05 16:41:42 +0000
commit0aa2c2ff01c78e6c194c16ce1d9925af918e7e4f (patch)
tree52e9e08ef7d6419a797e6d01d5678b7ee15c9b43
parent39fb395f7d628279c02c245028a6ab6029d272d7 (diff)
lib: Add docstring support
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
-rw-r--r--lib/command_graph.h3
-rw-r--r--lib/command_parse.y30
-rw-r--r--lib/grammar_sandbox.c32
3 files changed, 61 insertions, 4 deletions
diff --git a/lib/command_graph.h b/lib/command_graph.h
index e1feb9f77f..c987213633 100644
--- a/lib/command_graph.h
+++ b/lib/command_graph.h
@@ -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
diff --git a/lib/command_parse.y b/lib/command_parse.y
index ac075e67a3..35fac1b7d5 100644
--- a/lib/command_parse.y
+++ b/lib/command_parse.y
@@ -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);
+}
diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c
index a2177c1767..d1779a9b6e 100644
--- a/lib/grammar_sandbox.c
+++ b/lib/grammar_sandbox.c
@@ -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);
}