summaryrefslogtreecommitdiff
path: root/main/xmldoc.c
diff options
context:
space:
mode:
authorMatthew Nicholson <mnicholson@digium.com>2011-10-10 14:16:27 +0000
committerMatthew Nicholson <mnicholson@digium.com>2011-10-10 14:16:27 +0000
commitbb07ca66a174bdf92bbdfcc4f58c9065c90b3af3 (patch)
tree51dd35a6ca2c2285c9414e4bcec538b835fc0ddc /main/xmldoc.c
parent7cb2ac866495b44b5525fc34650478114f40182e (diff)
Merged revisions 340109 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/10 ................ r340109 | mnicholson | 2011-10-10 09:15:41 -0500 (Mon, 10 Oct 2011) | 18 lines Merged revisions 340108 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ........ r340108 | mnicholson | 2011-10-10 09:14:48 -0500 (Mon, 10 Oct 2011) | 11 lines Load the proper XML documentation when multiple modules document the same application. This patch adds an optional "module" attribute to the XML documentation spec that allows the documentation processor to match apps with identical names from different modules to their documentation. This patch also fixes a number of bugs with the documentation processor and should make it a little more efficient. Support for multiple languages has also been properly implemented. ASTERISK-18130 Review: https://reviewboard.asterisk.org/r/1485/ ........ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@340110 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/xmldoc.c')
-rw-r--r--main/xmldoc.c108
1 files changed, 79 insertions, 29 deletions
diff --git a/main/xmldoc.c b/main/xmldoc.c
index bbbb590e4..6dfca7192 100644
--- a/main/xmldoc.c
+++ b/main/xmldoc.c
@@ -456,46 +456,96 @@ static void xmldoc_string_cleanup(const char *text, struct ast_str **output, int
}
/*! \internal
+ * \brief Check if the given attribute on the given node matches the given value.
+ * \param node the node to match
+ * \param attr the name of the attribute
+ * \param value the expected value of the attribute
+ * \retval true if the given attribute contains the given value
+ * \retval false if the given attribute does not exist or does not contain the given value
+ */
+static int xmldoc_attribute_match(struct ast_xml_node *node, const char *attr, const char *value)
+{
+ const char *attr_value = ast_xml_get_attribute(node, attr);
+ int match = attr_value && !strcmp(attr_value, value);
+ ast_xml_free_attr(attr_value);
+ return match;
+}
+
+/*! \internal
* \brief Get the application/function node for 'name' application/function with language 'language'
- * if we don't find any, get the first application with 'name' no matter which language with.
+ * and module 'module' if we don't find any, get the first application
+ * with 'name' no matter which language or module.
* \param type 'application', 'function', ...
* \param name Application or Function name.
+ * \param module Module item is in.
* \param language Try to get this language (if not found try with en_US)
* \retval NULL on error.
* \retval A node of type ast_xml_node.
*/
-static struct ast_xml_node *xmldoc_get_node(const char *type, const char *name, const char *language)
+static struct ast_xml_node *xmldoc_get_node(const char *type, const char *name, const char *module, const char *language)
{
struct ast_xml_node *node = NULL;
+ struct ast_xml_node *first_match = NULL;
+ struct ast_xml_node *lang_match = NULL;
struct documentation_tree *doctree;
- const char *lang;
AST_RWLIST_RDLOCK(&xmldoc_tree);
AST_LIST_TRAVERSE(&xmldoc_tree, doctree, entry) {
/* the core xml documents have priority over thirdparty document. */
node = ast_xml_get_root(doctree->doc);
+ if (!node) {
+ break;
+ }
+
+ node = ast_xml_node_get_children(node);
while ((node = ast_xml_find_element(node, type, "name", name))) {
+ if (!ast_xml_node_get_children(node)) {
+ /* ignore empty nodes */
+ node = ast_xml_node_get_next(node);
+ continue;
+ }
+
+ if (!first_match) {
+ first_match = node;
+ }
+
/* Check language */
- lang = ast_xml_get_attribute(node, "language");
- if (lang && !strcmp(lang, language)) {
- ast_xml_free_attr(lang);
- break;
- } else if (lang) {
- ast_xml_free_attr(lang);
+ if (xmldoc_attribute_match(node, "language", language)) {
+ if (!lang_match) {
+ lang_match = node;
+ }
+
+ /* if module is empty we have a match */
+ if (ast_strlen_zero(module)) {
+ break;
+ }
+
+ /* Check module */
+ if (xmldoc_attribute_match(node, "module", module)) {
+ break;
+ }
}
+
+ node = ast_xml_node_get_next(node);
}
- if (node && ast_xml_node_get_children(node)) {
+ /* if we matched lang and module return this match */
+ if (node) {
break;
}
- /* We didn't find the application documentation for the specified language,
- so, try to load documentation for any language */
- node = ast_xml_get_root(doctree->doc);
- if (ast_xml_node_get_children(node)) {
- if ((node = ast_xml_find_element(ast_xml_node_get_children(node), type, "name", name))) {
- break;
- }
+ /* we didn't match lang and module, just return the first
+ * result with a matching language if we have one */
+ if (lang_match) {
+ node = lang_match;
+ break;
+ }
+
+ /* we didn't match with only the language, just return the
+ * first match */
+ if (first_match) {
+ node = first_match;
+ break;
}
}
AST_RWLIST_UNLOCK(&xmldoc_tree);
@@ -1077,12 +1127,12 @@ static enum syntaxtype xmldoc_get_syntax_type(const char *type)
return FUNCTION_SYNTAX;
}
-char *ast_xmldoc_build_syntax(const char *type, const char *name)
+char *ast_xmldoc_build_syntax(const char *type, const char *name, const char *module)
{
struct ast_xml_node *node;
char *syntax = NULL;
- node = xmldoc_get_node(type, name, documentation_language);
+ node = xmldoc_get_node(type, name, module, documentation_language);
if (!node) {
return NULL;
}
@@ -1383,7 +1433,7 @@ static int xmldoc_parse_variablelist(struct ast_xml_node *node, const char *tabs
return ret;
}
-char *ast_xmldoc_build_seealso(const char *type, const char *name)
+char *ast_xmldoc_build_seealso(const char *type, const char *name, const char *module)
{
struct ast_str *outputstr;
char *output;
@@ -1397,7 +1447,7 @@ char *ast_xmldoc_build_seealso(const char *type, const char *name)
}
/* get the application/function root node. */
- node = xmldoc_get_node(type, name, documentation_language);
+ node = xmldoc_get_node(type, name, module, documentation_language);
if (!node || !ast_xml_node_get_children(node)) {
return NULL;
}
@@ -1677,7 +1727,7 @@ static void xmldoc_parse_parameter(struct ast_xml_node *fixnode, const char *tab
ast_free(internaltabs);
}
-char *ast_xmldoc_build_arguments(const char *type, const char *name)
+char *ast_xmldoc_build_arguments(const char *type, const char *name, const char *module)
{
struct ast_xml_node *node;
struct ast_str *ret = ast_str_create(128);
@@ -1687,7 +1737,7 @@ char *ast_xmldoc_build_arguments(const char *type, const char *name)
return NULL;
}
- node = xmldoc_get_node(type, name, documentation_language);
+ node = xmldoc_get_node(type, name, module, documentation_language);
if (!node || !ast_xml_node_get_children(node)) {
return NULL;
@@ -1772,7 +1822,7 @@ static struct ast_str *xmldoc_get_formatted(struct ast_xml_node *node, int raw_o
* \retval NULL On error.
* \retval Field text content on success.
*/
-static char *xmldoc_build_field(const char *type, const char *name, const char *var, int raw)
+static char *xmldoc_build_field(const char *type, const char *name, const char *module, const char *var, int raw)
{
struct ast_xml_node *node;
char *ret = NULL;
@@ -1783,7 +1833,7 @@ static char *xmldoc_build_field(const char *type, const char *name, const char *
return ret;
}
- node = xmldoc_get_node(type, name, documentation_language);
+ node = xmldoc_get_node(type, name, module, documentation_language);
if (!node) {
ast_log(LOG_WARNING, "Couldn't find %s %s in XML documentation\n", type, name);
@@ -1806,14 +1856,14 @@ static char *xmldoc_build_field(const char *type, const char *name, const char *
return ret;
}
-char *ast_xmldoc_build_synopsis(const char *type, const char *name)
+char *ast_xmldoc_build_synopsis(const char *type, const char *name, const char *module)
{
- return xmldoc_build_field(type, name, "synopsis", 1);
+ return xmldoc_build_field(type, name, module, "synopsis", 1);
}
-char *ast_xmldoc_build_description(const char *type, const char *name)
+char *ast_xmldoc_build_description(const char *type, const char *name, const char *module)
{
- return xmldoc_build_field(type, name, "description", 0);
+ return xmldoc_build_field(type, name, module, "description", 0);
}
#if !defined(HAVE_GLOB_NOMAGIC) || !defined(HAVE_GLOB_BRACE) || defined(DEBUG_NONGNU)