summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/loader.c9
-rw-r--r--main/manager.c10
-rw-r--r--main/pbx.c28
-rw-r--r--main/xmldoc.c108
4 files changed, 107 insertions, 48 deletions
diff --git a/main/loader.c b/main/loader.c
index 5fe84449f..6cd5ffbdb 100644
--- a/main/loader.c
+++ b/main/loader.c
@@ -96,6 +96,15 @@ struct ast_module {
static AST_LIST_HEAD_STATIC(module_list, ast_module);
+const char *ast_module_name(const struct ast_module *mod)
+{
+ if (!mod || !mod->info) {
+ return NULL;
+ }
+
+ return mod->info->name;
+}
+
/*
* module_list is cleared by its constructor possibly after
* we start accumulating embedded modules, so we need to
diff --git a/main/manager.c b/main/manager.c
index d4b1b9577..3beb815ac 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -5225,23 +5225,23 @@ int ast_manager_register2(const char *action, int auth, int (*func)(struct manse
cur->func = func;
#ifdef AST_XML_DOCS
if (ast_strlen_zero(synopsis) && ast_strlen_zero(description)) {
- tmpxml = ast_xmldoc_build_synopsis("manager", action);
+ tmpxml = ast_xmldoc_build_synopsis("manager", action, NULL);
ast_string_field_set(cur, synopsis, tmpxml);
ast_free(tmpxml);
- tmpxml = ast_xmldoc_build_syntax("manager", action);
+ tmpxml = ast_xmldoc_build_syntax("manager", action, NULL);
ast_string_field_set(cur, syntax, tmpxml);
ast_free(tmpxml);
- tmpxml = ast_xmldoc_build_description("manager", action);
+ tmpxml = ast_xmldoc_build_description("manager", action, NULL);
ast_string_field_set(cur, description, tmpxml);
ast_free(tmpxml);
- tmpxml = ast_xmldoc_build_seealso("manager", action);
+ tmpxml = ast_xmldoc_build_seealso("manager", action, NULL);
ast_string_field_set(cur, seealso, tmpxml);
ast_free(tmpxml);
- tmpxml = ast_xmldoc_build_arguments("manager", action);
+ tmpxml = ast_xmldoc_build_arguments("manager", action, NULL);
ast_string_field_set(cur, arguments, tmpxml);
ast_free(tmpxml);
diff --git a/main/pbx.c b/main/pbx.c
index 0e528fd4f..a10293d77 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -3552,27 +3552,27 @@ static int acf_retrieve_docs(struct ast_custom_function *acf)
}
/* load synopsis */
- tmpxml = ast_xmldoc_build_synopsis("function", acf->name);
+ tmpxml = ast_xmldoc_build_synopsis("function", acf->name, ast_module_name(acf->mod));
ast_string_field_set(acf, synopsis, tmpxml);
ast_free(tmpxml);
/* load description */
- tmpxml = ast_xmldoc_build_description("function", acf->name);
+ tmpxml = ast_xmldoc_build_description("function", acf->name, ast_module_name(acf->mod));
ast_string_field_set(acf, desc, tmpxml);
ast_free(tmpxml);
/* load syntax */
- tmpxml = ast_xmldoc_build_syntax("function", acf->name);
+ tmpxml = ast_xmldoc_build_syntax("function", acf->name, ast_module_name(acf->mod));
ast_string_field_set(acf, syntax, tmpxml);
ast_free(tmpxml);
/* load arguments */
- tmpxml = ast_xmldoc_build_arguments("function", acf->name);
+ tmpxml = ast_xmldoc_build_arguments("function", acf->name, ast_module_name(acf->mod));
ast_string_field_set(acf, arguments, tmpxml);
ast_free(tmpxml);
/* load seealso */
- tmpxml = ast_xmldoc_build_seealso("function", acf->name);
+ tmpxml = ast_xmldoc_build_seealso("function", acf->name, ast_module_name(acf->mod));
ast_string_field_set(acf, seealso, tmpxml);
ast_free(tmpxml);
@@ -5842,31 +5842,35 @@ int ast_register_application2(const char *app, int (*execute)(struct ast_channel
return -1;
}
+ strcpy(tmp->name, app);
+ tmp->execute = execute;
+ tmp->module = mod;
+
#ifdef AST_XML_DOCS
/* Try to lookup the docs in our XML documentation database */
if (ast_strlen_zero(synopsis) && ast_strlen_zero(description)) {
/* load synopsis */
- tmpxml = ast_xmldoc_build_synopsis("application", app);
+ tmpxml = ast_xmldoc_build_synopsis("application", app, ast_module_name(tmp->module));
ast_string_field_set(tmp, synopsis, tmpxml);
ast_free(tmpxml);
/* load description */
- tmpxml = ast_xmldoc_build_description("application", app);
+ tmpxml = ast_xmldoc_build_description("application", app, ast_module_name(tmp->module));
ast_string_field_set(tmp, description, tmpxml);
ast_free(tmpxml);
/* load syntax */
- tmpxml = ast_xmldoc_build_syntax("application", app);
+ tmpxml = ast_xmldoc_build_syntax("application", app, ast_module_name(tmp->module));
ast_string_field_set(tmp, syntax, tmpxml);
ast_free(tmpxml);
/* load arguments */
- tmpxml = ast_xmldoc_build_arguments("application", app);
+ tmpxml = ast_xmldoc_build_arguments("application", app, ast_module_name(tmp->module));
ast_string_field_set(tmp, arguments, tmpxml);
ast_free(tmpxml);
/* load seealso */
- tmpxml = ast_xmldoc_build_seealso("application", app);
+ tmpxml = ast_xmldoc_build_seealso("application", app, ast_module_name(tmp->module));
ast_string_field_set(tmp, seealso, tmpxml);
ast_free(tmpxml);
tmp->docsrc = AST_XML_DOC;
@@ -5879,10 +5883,6 @@ int ast_register_application2(const char *app, int (*execute)(struct ast_channel
}
#endif
- strcpy(tmp->name, app);
- tmp->execute = execute;
- tmp->module = mod;
-
/* Store in alphabetical order */
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {
if (strcasecmp(tmp->name, cur->name) < 0) {
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)