aboutsummaryrefslogtreecommitdiffstats
path: root/src/vty
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-11-18 23:14:24 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2012-07-25 11:58:58 +0200
commit8297c819e985ba0d46752971b274b174098afceb (patch)
tree51ac1f236957dfa6c1ce45574f25c6b875eef822 /src/vty
parentaa5d0e88944fe3258260aedfbce9101301e35b44 (diff)
vty: Add xsd and a command that can generate the documentation.
When building the doxygen documentation do not remove the other VTY documentation files in the doc/vty folder. Create a command that can be installed to dump all nodes and commands as XML on the given VTY. Create a schema for the XML file and a XSL-T script that can merge the generated file with additional information.
Diffstat (limited to 'src/vty')
-rw-r--r--src/vty/command.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/vty/command.c b/src/vty/command.c
index c84c612d..7f83a5e4 100644
--- a/src/vty/command.c
+++ b/src/vty/command.c
@@ -405,6 +405,145 @@ const char *cmd_prompt(enum node_type node)
return cnode->prompt;
}
+static char *xml_escape(const char *inp)
+{
+ int _strlen;
+ char *out, *out_ptr;
+ int len = 0, i, j;
+
+ if (!inp)
+ return NULL;
+ _strlen = strlen(inp);
+
+ for (i = 0; i < _strlen; ++i) {
+ switch (inp[i]) {
+ case '"':
+ len += 6;
+ break;
+ case '\'':
+ len += 6;
+ break;
+ case '<':
+ len += 4;
+ break;
+ case '>':
+ len += 4;
+ break;
+ case '&':
+ len += 5;
+ break;
+ default:
+ len += 1;
+ break;
+ }
+ }
+
+ out = talloc_size(NULL, len + 1);
+ if (!out)
+ return NULL;
+
+ out_ptr = out;
+
+#define ADD(out, str) \
+ for (j = 0; j < strlen(str); ++j) \
+ *(out++) = str[j];
+
+ for (i = 0; i < _strlen; ++i) {
+ switch (inp[i]) {
+ case '"':
+ ADD(out_ptr, "&quot;");
+ break;
+ case '\'':
+ ADD(out_ptr, "&apos;");
+ break;
+ case '<':
+ ADD(out_ptr, "&lt;");
+ break;
+ case '>':
+ ADD(out_ptr, "&gt;");
+ break;
+ case '&':
+ ADD(out_ptr, "&amp;");
+ break;
+ default:
+ *(out_ptr++) = inp[i];
+ break;
+ }
+ }
+
+#undef ADD
+
+ out_ptr[0] = '\0';
+ return out;
+}
+
+/*
+ * Write one cmd_element as XML to the given VTY.
+ */
+static int vty_dump_element(struct cmd_element *cmd, struct vty *vty)
+{
+ char *xml_string = xml_escape(cmd->string);
+
+ vty_out(vty, " <command id='%s'>%s", xml_string, VTY_NEWLINE);
+ vty_out(vty, " <params>%s", VTY_NEWLINE);
+
+ int j;
+ for (j = 0; j < vector_count(cmd->strvec); ++j) {
+ vector descvec = vector_slot(cmd->strvec, j);
+ int i;
+ for (i = 0; i < vector_active(descvec); ++i) {
+ char *xml_param, *xml_doc;
+ struct desc *desc = vector_slot(descvec, i);
+ if (desc == NULL)
+ continue;
+
+ xml_param = xml_escape(desc->cmd);
+ xml_doc = xml_escape(desc->str);
+ vty_out(vty, " <param name='%s' doc='%s' />%s",
+ xml_param, xml_doc, VTY_NEWLINE);
+ talloc_free(xml_param);
+ talloc_free(xml_doc);
+ }
+ }
+
+ vty_out(vty, " </params>%s", VTY_NEWLINE);
+ vty_out(vty, " </command>%s", VTY_NEWLINE);
+
+ talloc_free(xml_string);
+ return 0;
+}
+
+/*
+ * Dump all nodes and commands associated with a given node as XML to the VTY.
+ */
+static int vty_dump_nodes(struct vty *vty)
+{
+ int i, j;
+
+ vty_out(vty, "<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'>%s", VTY_NEWLINE);
+
+ for (i = 0; i < vector_active(cmdvec); ++i) {
+ struct cmd_node *cnode;
+ cnode = vector_slot(cmdvec, i);
+ if (!cnode)
+ continue;
+
+ vty_out(vty, " <node id='%d'>%s", i, VTY_NEWLINE);
+
+ for (j = 0; j < vector_active(cnode->cmd_vector); ++j) {
+ struct cmd_element *elem;
+ elem = vector_slot(cnode->cmd_vector, j);
+ vty_dump_element(elem, vty);
+ }
+
+ vty_out(vty, " </node>%s", VTY_NEWLINE);
+ }
+
+ vty_out(vty, "</vtydoc>%s", VTY_NEWLINE);
+
+ return 0;
+}
+
/*! \brief Install a command into a node
* \param[in] ntype Node Type
* \param[cmd] element to be installed
@@ -2232,6 +2371,13 @@ DEFUN(show_version,
return CMD_SUCCESS;
}
+DEFUN(show_online_help,
+ show_online_help_cmd, "show online-help", SHOW_STR "Online help\n")
+{
+ vty_dump_nodes(vty);
+ return CMD_SUCCESS;
+}
+
/* Help display function for all node. */
gDEFUN(config_help,
config_help_cmd, "help", "Description of the interactive help system\n")
@@ -3269,6 +3415,7 @@ void cmd_init(int terminal)
/* Each node's basic commands. */
install_element(VIEW_NODE, &show_version_cmd);
+ install_element(VIEW_NODE, &show_online_help_cmd);
if (terminal) {
install_element(VIEW_NODE, &config_list_cmd);
install_element(VIEW_NODE, &config_exit_cmd);
@@ -3288,6 +3435,7 @@ void cmd_init(int terminal)
}
install_element (ENABLE_NODE, &show_startup_config_cmd);
install_element(ENABLE_NODE, &show_version_cmd);
+ install_element(ENABLE_NODE, &show_online_help_cmd);
if (terminal) {
install_element(ENABLE_NODE, &config_terminal_length_cmd);