summaryrefslogtreecommitdiff
path: root/main/xmldoc.c
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2012-07-19 22:17:13 +0000
committerMatthew Jordan <mjordan@digium.com>2012-07-19 22:17:13 +0000
commit86ff5585fd4de538c65bcbdce54cd9ef74b4e784 (patch)
treeec6bdea2bbe0e590e472ef43d47fd51bd15d39d6 /main/xmldoc.c
parentf80278792480fe432a32608773f172576dc84839 (diff)
Add the ability to specify technology specific documentation
A number of applications/AMI commands in Asterisk have specific behavioral differences depending on the resource or channel technology those applications are executed on. For example, the MessageSend application/ command is technology agnostic, but how the channel drivers that support that functionality behave is dependant on the protocols and channel driver implementation. Prior to this patch, those details were either documented in the application/command documentation itself, or were left undocumented. This patch adds a new element to the documentation schema, <info/>. An info node is essentially a piece of technology specific reference information that can be included by any top level XML documentation node. For example, the MessageSend application can now include XMPP/SIP specific information, where that technology specific information can be defined in chan_motif/res_xmpp/ chan_sip. Likewise, that information can also be included in the MessageSend AMI command. Review: https://reviewboard.asterisk.org/r/2049 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@370278 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/xmldoc.c')
-rw-r--r--main/xmldoc.c117
1 files changed, 94 insertions, 23 deletions
diff --git a/main/xmldoc.c b/main/xmldoc.c
index 631444431..e8383511e 100644
--- a/main/xmldoc.c
+++ b/main/xmldoc.c
@@ -65,6 +65,10 @@ struct documentation_tree {
static char *xmldoc_get_syntax_cmd(struct ast_xml_node *fixnode, const char *name, int printname);
static int xmldoc_parse_enumlist(struct ast_xml_node *fixnode, const char *tabs, struct ast_str **buffer);
+static int xmldoc_parse_info(struct ast_xml_node *node, const char *tabs, const char *posttabs, struct ast_str **buffer);
+static int xmldoc_parse_para(struct ast_xml_node *node, const char *tabs, const char *posttabs, struct ast_str **buffer);
+static int xmldoc_parse_specialtags(struct ast_xml_node *fixnode, const char *tabs, const char *posttabs, struct ast_str **buffer);
+
/*!
* \brief Container of documentation trees
@@ -1197,6 +1201,26 @@ char *ast_xmldoc_build_syntax(const char *type, const char *name, const char *mo
}
/*! \internal
+ * \brief Parse common internal elements. This includes paragraphs, special
+ * tags, and information nodes.
+ * \param node The element to parse
+ * \param tabs Add this string before the content of the parsed element.
+ * \param posttabs Add this string after the content of the parsed element.
+ * \param buffer This must be an already allocated ast_str. It will be used to
+ * store the result (if something has already been placed in the
+ * buffer, the parsed elements will be appended)
+ * \retval 1 if any data was appended to the buffer
+ * \retval 2 if the data appended to the buffer contained a text paragraph
+ * \retval 0 if no data was appended to the buffer
+ */
+static int xmldoc_parse_common_elements(struct ast_xml_node *node, const char *tabs, const char *posttabs, struct ast_str **buffer)
+{
+ return (xmldoc_parse_para(node, tabs, posttabs, buffer)
+ || xmldoc_parse_specialtags(node, tabs, posttabs, buffer)
+ || xmldoc_parse_info(node, tabs, posttabs, buffer));
+}
+
+/*! \internal
* \brief Parse a <para> element.
* \param node The <para> element pointer.
* \param tabs Added this string before the content of the <para> element.
@@ -1287,7 +1311,8 @@ static int xmldoc_parse_specialtags(struct ast_xml_node *fixnode, const char *ta
/* parse <para> elements inside special tags. */
for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
/* first <para> just print it without tabs at the begining. */
- if (xmldoc_parse_para(node, (!count ? "" : tabs), posttabs, buffer) == 2) {
+ if ((xmldoc_parse_para(node, (!count ? "" : tabs), posttabs, buffer) == 2)
+ || (xmldoc_parse_info(node, (!count ? "": tabs), posttabs, buffer) == 2)) {
ret = 2;
}
}
@@ -1303,6 +1328,55 @@ static int xmldoc_parse_specialtags(struct ast_xml_node *fixnode, const char *ta
}
/*! \internal
+ * \brief Parse an 'info' tag inside an element.
+ * \param node A pointer to the 'info' xml node.
+ * \param tabs A string to be appended at the beginning of each line being printed
+ * inside 'buffer'
+ * \param posttabs Add this string after the content of the <para> element, if one exists
+ * \param String buffer to put values found inide the info element.
+ * \ret 2 if the information contained a para element, and it returned a value of 2
+ * \ret 1 if information was put into the buffer
+ * \ret 0 if no information was put into the buffer or error
+ */
+static int xmldoc_parse_info(struct ast_xml_node *node, const char *tabs, const char *posttabs, struct ast_str **buffer)
+{
+ const char *tech;
+ char *internaltabs;
+ int internal_ret;
+ int ret = 0;
+
+ if (strcasecmp(ast_xml_node_get_name(node), "info")) {
+ return ret;
+ }
+
+ ast_asprintf(&internaltabs, "%s ", tabs);
+ if (!internaltabs) {
+ return ret;
+ }
+
+ tech = ast_xml_get_attribute(node, "tech");
+ if (tech) {
+ ast_str_append(buffer, 0, "%s<note>Technology: %s</note>\n", internaltabs, tech);
+ ast_xml_free_attr(tech);
+ }
+
+ ret = 1;
+
+ for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
+ if (!strcasecmp(ast_xml_node_get_name(node), "enumlist")) {
+ xmldoc_parse_enumlist(node, internaltabs, buffer);
+ } else if ((internal_ret = xmldoc_parse_common_elements(node, internaltabs, posttabs, buffer))) {
+ if (internal_ret > ret) {
+ ret = internal_ret;
+ }
+ }
+ }
+ ast_free(internaltabs);
+
+ return ret;
+}
+
+/*! \internal
* \brief Parse an <argument> element from the xml documentation.
* \param fixnode Pointer to the 'argument' xml node.
* \param insideparameter If we are parsing an <argument> inside a <parameter>.
@@ -1327,7 +1401,7 @@ static int xmldoc_parse_argument(struct ast_xml_node *fixnode, int insideparamet
if (!argname) {
return 0;
}
- if (xmldoc_has_inside(node, "para") || xmldoc_has_specialtags(node)) {
+ if (xmldoc_has_inside(node, "para") || xmldoc_has_inside(node, "info") || xmldoc_has_specialtags(node)) {
ast_str_append(buffer, 0, "%s%s%s", tabs, argname, (insideparameter ? "\n" : ""));
ast_xml_free_attr(argname);
} else {
@@ -1336,10 +1410,7 @@ static int xmldoc_parse_argument(struct ast_xml_node *fixnode, int insideparamet
}
for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
- if (xmldoc_parse_para(node, (insideparameter ? paramtabs : (!count ? " - " : tabs)), "\n", buffer) == 2) {
- count++;
- ret = 1;
- } else if (xmldoc_parse_specialtags(node, (insideparameter ? paramtabs : (!count ? " - " : tabs)), "\n", buffer) == 2) {
+ if (xmldoc_parse_common_elements(node, (insideparameter ? paramtabs : (!count ? " - " : tabs)), "\n", buffer) == 2) {
count++;
ret = 1;
}
@@ -1368,10 +1439,7 @@ static int xmldoc_parse_variable(struct ast_xml_node *node, const char *tabs, st
int ret = 0, printedpara=0;
for (tmp = ast_xml_node_get_children(node); tmp; tmp = ast_xml_node_get_next(tmp)) {
- if (xmldoc_parse_para(tmp, (ret ? tabs : ""), "\n", buffer)) {
- printedpara = 1;
- continue;
- } else if (xmldoc_parse_specialtags(tmp, (ret ? tabs : ""), "\n", buffer)) {
+ if (xmldoc_parse_common_elements(tmp, (ret ? tabs : ""), "\n", buffer)) {
printedpara = 1;
continue;
}
@@ -1442,10 +1510,7 @@ static int xmldoc_parse_variablelist(struct ast_xml_node *node, const char *tabs
}
for (tmp = ast_xml_node_get_children(node); tmp; tmp = ast_xml_node_get_next(tmp)) {
/* We can have a <para> element inside the variable list */
- if ((xmldoc_parse_para(tmp, (ret ? tabs : ""), "\n", buffer))) {
- ret = 1;
- continue;
- } else if ((xmldoc_parse_specialtags(tmp, (ret ? tabs : ""), "\n", buffer))) {
+ if (xmldoc_parse_common_elements(tmp, (ret ? tabs : ""), "\n", buffer)) {
ret = 1;
continue;
}
@@ -1579,9 +1644,7 @@ static int xmldoc_parse_enum(struct ast_xml_node *fixnode, const char *tabs, str
ast_asprintf(&optiontabs, "%s ", tabs);
for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
- if ((xmldoc_parse_para(node, (ret ? tabs : " - "), "\n", buffer))) {
- ret = 1;
- } else if ((xmldoc_parse_specialtags(node, (ret ? tabs : " - "), "\n", buffer))) {
+ if (xmldoc_parse_common_elements(node, (ret ? tabs : " - "), "\n", buffer)) {
ret = 1;
}
@@ -1659,9 +1722,7 @@ static int xmldoc_parse_option(struct ast_xml_node *fixnode, const char *tabs, s
continue;
}
- if (xmldoc_parse_para(node, (ret ? tabs : ""), "\n", buffer)) {
- ret = 1;
- } else if (xmldoc_parse_specialtags(node, (ret ? tabs : ""), "\n", buffer)) {
+ if (xmldoc_parse_common_elements(node, (ret ? tabs : ""), "\n", buffer)) {
ret = 1;
}
@@ -1779,6 +1840,18 @@ static void xmldoc_parse_parameter(struct ast_xml_node *fixnode, const char *tab
continue;
}
continue;
+ } else if (!strcasecmp(ast_xml_node_get_name(node), "info")) {
+ if (!printed) {
+ ast_str_append(buffer, 0, "%s\n", paramname);
+ ast_xml_free_attr(paramname);
+ printed = 1;
+ }
+ if (xmldoc_parse_info(node, internaltabs, "\n", buffer)) {
+ /* If anything ever goes in below this condition before the continue below,
+ * we should probably continue immediately. */
+ continue;
+ }
+ continue;
} else if ((xmldoc_parse_specialtags(node, internaltabs, "\n", buffer))) {
continue;
}
@@ -1881,9 +1954,7 @@ static struct ast_str *xmldoc_get_formatted(struct ast_xml_node *node, int raw_o
} else {
for (tmp = ast_xml_node_get_children(node); tmp; tmp = ast_xml_node_get_next(tmp)) {
/* if found, parse a <para> element. */
- if (xmldoc_parse_para(tmp, "", "\n", &ret)) {
- continue;
- } else if (xmldoc_parse_specialtags(tmp, "", "\n", &ret)) {
+ if (xmldoc_parse_common_elements(tmp, "", "\n", &ret)) {
continue;
}
/* if found, parse a <variablelist> element. */