summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/appdocsxml.dtd6
-rw-r--r--include/asterisk/manager.h4
-rw-r--r--include/asterisk/xmldoc.h37
-rw-r--r--main/config_options.c16
-rw-r--r--main/manager.c109
-rw-r--r--main/manager_bridges.c20
-rw-r--r--main/xmldoc.c181
7 files changed, 304 insertions, 69 deletions
diff --git a/doc/appdocsxml.dtd b/doc/appdocsxml.dtd
index a81b64400..65167d559 100644
--- a/doc/appdocsxml.dtd
+++ b/doc/appdocsxml.dtd
@@ -26,11 +26,15 @@
<!ATTLIST agi language CDATA #REQUIRED>
<!ATTLIST agi module CDATA #IMPLIED>
- <!ELEMENT manager (synopsis?,syntax?,description?,see-also?)>
+ <!ELEMENT manager (synopsis?,syntax?,description?,see-also?,responses?)>
<!ATTLIST manager name CDATA #REQUIRED>
<!ATTLIST manager language CDATA #REQUIRED>
<!ATTLIST manager module CDATA #IMPLIED>
+ <!ELEMENT responses (list-elements?,(managerEvent|xi:include))>
+
+ <!ELEMENT list-elements (managerEvent+|xi:include+)>
+
<!ELEMENT managerEvent (managerEventInstance+)>
<!ATTLIST managerEvent name CDATA #REQUIRED>
<!ATTLIST managerEvent language CDATA #REQUIRED>
diff --git a/include/asterisk/manager.h b/include/asterisk/manager.h
index 66dafb1be..fad7af1e7 100644
--- a/include/asterisk/manager.h
+++ b/include/asterisk/manager.h
@@ -148,6 +148,10 @@ struct manager_action {
AST_STRING_FIELD(arguments); /*!< Description of each argument. */
AST_STRING_FIELD(seealso); /*!< See also */
);
+ /*! Possible list element response events. */
+ struct ast_xml_doc_item *list_responses;
+ /*! Final response event. */
+ struct ast_xml_doc_item *final_response;
/*! Permission required for action. EVENT_FLAG_* */
int authority;
/*! Function to be called */
diff --git a/include/asterisk/xmldoc.h b/include/asterisk/xmldoc.h
index c09f693c8..782fa1e94 100644
--- a/include/asterisk/xmldoc.h
+++ b/include/asterisk/xmldoc.h
@@ -37,6 +37,13 @@ enum ast_doc_src {
struct ao2_container;
struct ast_xml_node;
+/*!
+ * \brief The struct to be used as the head of an ast_xml_doc_item list
+ * when being manipulated
+ * \since 13.0.0
+ */
+AST_LIST_HEAD(ast_xml_doc_item_list, ast_xml_doc_item);
+
/*! \brief Struct that contains the XML documentation for a particular item. Note
* that this is an ao2 ref counted object.
*
@@ -70,7 +77,7 @@ struct ast_xml_doc_item {
*/
struct ast_xml_node *node;
/*! The next XML documentation item that matches the same name/item type */
- struct ast_xml_doc_item *next;
+ AST_LIST_ENTRY(ast_xml_doc_item) next;
};
/*! \brief Execute an XPath query on the loaded XML documentation
@@ -115,6 +122,34 @@ char *ast_xmldoc_build_seealso(const char *type, const char *name, const char *m
char *ast_xmldoc_build_arguments(const char *type, const char *name, const char *module);
/*!
+ * \brief Generate the [final response] tag based on type of node ('application',
+ * 'function' or 'agi') and name.
+ *
+ * \param type 'application', 'function' or 'agi'
+ * \param name Name of the application or function to build the 'responses' tag.
+ * \param module The module the item is in (optional, can be NULL)
+ *
+ * \return An XMLDoc item list with the [final response] tag content.
+ *
+ * \since 13.0.0
+ */
+struct ast_xml_doc_item *ast_xmldoc_build_final_response(const char *type, const char *name, const char *module);
+
+/*!
+ * \brief Generate the [list responses] tag based on type of node ('application',
+ * 'function' or 'agi') and name.
+ *
+ * \param type 'application', 'function' or 'agi'
+ * \param name Name of the application or function to build the 'responses' tag.
+ * \param module The module the item is in (optional, can be NULL)
+ *
+ * \return An XMLDoc item list with the [list responses] tag content.
+ *
+ * \since 13.0.0
+ */
+struct ast_xml_doc_item *ast_xmldoc_build_list_responses(const char *type, const char *name, const char *module);
+
+/*!
* \brief Colorize and put delimiters (instead of tags) to the xmldoc output.
* \param bwinput Not colorized input with tags.
* \param withcolors Result output with colors.
diff --git a/main/config_options.c b/main/config_options.c
index c86db0247..89b19e05b 100644
--- a/main/config_options.c
+++ b/main/config_options.c
@@ -249,7 +249,7 @@ static struct ast_xml_doc_item *find_xmldoc_option(struct ast_xml_doc_item *conf
return NULL;
}
/* First is just the configInfo, we can skip it */
- while ((iter = iter->next)) {
+ while ((iter = AST_LIST_NEXT(iter, next))) {
size_t x;
if (strcasecmp(iter->name, name)) {
continue;
@@ -274,7 +274,7 @@ static struct ast_xml_doc_item *find_xmldoc_type(struct ast_xml_doc_item *config
return NULL;
}
/* First is just the config Info, skip it */
- while ((iter = iter->next)) {
+ while ((iter = AST_LIST_NEXT(iter, next))) {
if (!strcasecmp(iter->type, "configObject") && !strcasecmp(iter->name, name)) {
break;
}
@@ -915,7 +915,7 @@ static char *complete_config_type(const char *module, const char *word, int pos,
}
cur = info;
- while ((cur = cur->next)) {
+ while ((cur = AST_LIST_NEXT(cur, next))) {
if (!strcasecmp(cur->type, "configObject") && !strncasecmp(word, cur->name, wordlen) && ++which > state) {
c = ast_strdup(cur->name);
break;
@@ -944,7 +944,7 @@ static char *complete_config_option(const char *module, const char *option, cons
}
cur = info;
- while ((cur = cur->next)) {
+ while ((cur = AST_LIST_NEXT(cur, next))) {
if (!strcasecmp(cur->type, "configOption") && !strcasecmp(cur->ref, option) && !strncasecmp(word, cur->name, wordlen) && ++which > state) {
c = ast_strdup(cur->name);
break;
@@ -1109,7 +1109,7 @@ static void cli_show_module_types(struct ast_cli_args *a)
tmp = item;
ast_cli(a->fd, "Configuration option types for %s:\n", tmp->name);
- while ((tmp = tmp->next)) {
+ while ((tmp = AST_LIST_NEXT(tmp, next))) {
if (!strcasecmp(tmp->type, "configObject")) {
ast_cli(a->fd, "%-25s -- %-65.65s\n", tmp->name,
ast_str_buffer(tmp->synopsis));
@@ -1135,7 +1135,7 @@ static void cli_show_module_type(struct ast_cli_args *a)
}
tmp = item;
- while ((tmp = tmp->next)) {
+ while ((tmp = AST_LIST_NEXT(tmp, next))) {
if (!strcasecmp(tmp->type, "configObject") && !strcasecmp(tmp->name, a->argv[4])) {
match = 1;
term_color(option_type, tmp->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(option_type));
@@ -1161,7 +1161,7 @@ static void cli_show_module_type(struct ast_cli_args *a)
/* Now iterate over the options for the type */
tmp = item;
- while ((tmp = tmp->next)) {
+ while ((tmp = AST_LIST_NEXT(tmp, next))) {
if (!strcasecmp(tmp->type, "configOption") && !strcasecmp(tmp->ref, a->argv[4])) {
ast_cli(a->fd, "%-25s -- %-65.65s\n", tmp->name,
ast_str_buffer(tmp->synopsis));
@@ -1186,7 +1186,7 @@ static void cli_show_module_options(struct ast_cli_args *a)
return;
}
tmp = item;
- while ((tmp = tmp->next)) {
+ while ((tmp = AST_LIST_NEXT(tmp, next))) {
if (!strcasecmp(tmp->type, "configOption") && !strcasecmp(tmp->ref, a->argv[4]) && !strcasecmp(tmp->name, a->argv[5])) {
if (match) {
ast_cli(a->fd, "\n");
diff --git a/main/manager.c b/main/manager.c
index f5d00d1d3..47a909b68 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -1912,6 +1912,8 @@ static int manager_displayconnects(struct mansession_session *session)
return ret;
}
+static void print_event_instance(struct ast_cli_args *a, struct ast_xml_doc_item *instance);
+
static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
struct manager_action *cur;
@@ -1919,7 +1921,8 @@ static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_
int num, l, which;
char *ret = NULL;
#ifdef AST_XML_DOCS
- char syntax_title[64], description_title[64], synopsis_title[64], seealso_title[64], arguments_title[64], privilege_title[64];
+ char syntax_title[64], description_title[64], synopsis_title[64], seealso_title[64];
+ char arguments_title[64], privilege_title[64], final_response_title[64], list_responses_title[64];
#endif
switch (cmd) {
@@ -1955,6 +1958,8 @@ static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_
term_color(seealso_title, "[See Also]\n", COLOR_MAGENTA, 0, 40);
term_color(arguments_title, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
term_color(privilege_title, "[Privilege]\n", COLOR_MAGENTA, 0, 40);
+ term_color(final_response_title, "[Final Response]\n", COLOR_MAGENTA, 0, 40);
+ term_color(list_responses_title, "[List Responses]\n", COLOR_MAGENTA, 0, 40);
#endif
AST_RWLIST_RDLOCK(&actions);
@@ -1971,13 +1976,34 @@ static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_
char *arguments = ast_xmldoc_printable(S_OR(cur->arguments, "Not available"), 1);
char *seealso = ast_xmldoc_printable(S_OR(cur->seealso, "Not available"), 1);
char *privilege = ast_xmldoc_printable(S_OR(authority->str, "Not available"), 1);
- ast_cli(a->fd, "%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n",
+ char *responses = ast_xmldoc_printable("None", 1);
+ ast_cli(a->fd, "%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s",
syntax_title, syntax,
synopsis_title, synopsis,
description_title, description,
arguments_title, arguments,
seealso_title, seealso,
- privilege_title, privilege);
+ privilege_title, privilege,
+ list_responses_title);
+
+ if (!cur->list_responses) {
+ ast_cli(a->fd, "%s\n\n", responses);
+ } else {
+ struct ast_xml_doc_item *temp;
+ for (temp = cur->list_responses; temp; temp = AST_LIST_NEXT(temp, next)) {
+ ast_cli(a->fd, "Event: %s\n", temp->name);
+ print_event_instance(a, temp);
+ }
+ }
+
+ ast_cli(a->fd, "%s", final_response_title);
+
+ if (!cur->final_response) {
+ ast_cli(a->fd, "%s\n\n", responses);
+ } else {
+ ast_cli(a->fd, "Event: %s\n", cur->final_response->name);
+ print_event_instance(a, cur->final_response);
+ }
} else
#endif
{
@@ -6309,6 +6335,8 @@ static void action_destroy(void *obj)
/* The string fields were initialized. */
ast_string_field_free_memory(doomed);
}
+ ao2_cleanup(doomed->final_response);
+ ao2_cleanup(doomed->list_responses);
}
/*! \brief register a new command with manager, including online help. This is
@@ -6354,6 +6382,9 @@ int ast_manager_register2(const char *action, int auth, int (*func)(struct manse
ast_string_field_set(cur, arguments, tmpxml);
ast_free(tmpxml);
+ cur->final_response = ast_xmldoc_build_final_response("manager", action, NULL);
+ cur->list_responses = ast_xmldoc_build_list_responses("manager", action, NULL);
+
cur->docsrc = AST_XML_DOC;
} else
#endif
@@ -7745,6 +7776,43 @@ static char *handle_manager_show_events(struct ast_cli_entry *e, int cmd, struct
return CLI_SUCCESS;
}
+static void print_event_instance(struct ast_cli_args *a, struct ast_xml_doc_item *instance)
+{
+ char syntax_title[64], description_title[64], synopsis_title[64], seealso_title[64], arguments_title[64];
+
+ term_color(synopsis_title, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
+ term_color(description_title, "[Description]\n", COLOR_MAGENTA, 0, 40);
+ term_color(syntax_title, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
+ term_color(seealso_title, "[See Also]\n", COLOR_MAGENTA, 0, 40);
+ term_color(arguments_title, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
+
+ if (!ast_strlen_zero(ast_str_buffer(instance->synopsis))) {
+ char *synopsis = ast_xmldoc_printable(ast_str_buffer(instance->synopsis), 1);
+ ast_cli(a->fd, "%s%s\n\n", synopsis_title, synopsis);
+ ast_free(synopsis);
+ }
+ if (!ast_strlen_zero(ast_str_buffer(instance->syntax))) {
+ char *syntax = ast_xmldoc_printable(ast_str_buffer(instance->syntax), 1);
+ ast_cli(a->fd, "%s%s\n\n", syntax_title, syntax);
+ ast_free(syntax);
+ }
+ if (!ast_strlen_zero(ast_str_buffer(instance->description))) {
+ char *description = ast_xmldoc_printable(ast_str_buffer(instance->description), 1);
+ ast_cli(a->fd, "%s%s\n\n", description_title, description);
+ ast_free(description);
+ }
+ if (!ast_strlen_zero(ast_str_buffer(instance->arguments))) {
+ char *arguments = ast_xmldoc_printable(ast_str_buffer(instance->arguments), 1);
+ ast_cli(a->fd, "%s%s\n\n", arguments_title, arguments);
+ ast_free(arguments);
+ }
+ if (!ast_strlen_zero(ast_str_buffer(instance->seealso))) {
+ char *seealso = ast_xmldoc_printable(ast_str_buffer(instance->seealso), 1);
+ ast_cli(a->fd, "%s%s\n\n", seealso_title, seealso);
+ ast_free(seealso);
+ }
+}
+
static char *handle_manager_show_event(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
RAII_VAR(struct ao2_container *, events, NULL, ao2_cleanup);
@@ -7753,7 +7821,6 @@ static char *handle_manager_show_event(struct ast_cli_entry *e, int cmd, struct
int length;
int which;
char *match = NULL;
- char syntax_title[64], description_title[64], synopsis_title[64], seealso_title[64], arguments_title[64];
if (cmd == CLI_INIT) {
e->command = "manager show event";
@@ -7794,39 +7861,9 @@ static char *handle_manager_show_event(struct ast_cli_entry *e, int cmd, struct
return CLI_SUCCESS;
}
- term_color(synopsis_title, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
- term_color(description_title, "[Description]\n", COLOR_MAGENTA, 0, 40);
- term_color(syntax_title, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
- term_color(seealso_title, "[See Also]\n", COLOR_MAGENTA, 0, 40);
- term_color(arguments_title, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
-
ast_cli(a->fd, "Event: %s\n", a->argv[3]);
- for (temp = item; temp; temp = temp->next) {
- if (!ast_strlen_zero(ast_str_buffer(temp->synopsis))) {
- char *synopsis = ast_xmldoc_printable(ast_str_buffer(temp->synopsis), 1);
- ast_cli(a->fd, "%s%s\n\n", synopsis_title, synopsis);
- ast_free(synopsis);
- }
- if (!ast_strlen_zero(ast_str_buffer(temp->syntax))) {
- char *syntax = ast_xmldoc_printable(ast_str_buffer(temp->syntax), 1);
- ast_cli(a->fd, "%s%s\n\n", syntax_title, syntax);
- ast_free(syntax);
- }
- if (!ast_strlen_zero(ast_str_buffer(temp->description))) {
- char *description = ast_xmldoc_printable(ast_str_buffer(temp->description), 1);
- ast_cli(a->fd, "%s%s\n\n", description_title, description);
- ast_free(description);
- }
- if (!ast_strlen_zero(ast_str_buffer(temp->arguments))) {
- char *arguments = ast_xmldoc_printable(ast_str_buffer(temp->arguments), 1);
- ast_cli(a->fd, "%s%s\n\n", arguments_title, arguments);
- ast_free(arguments);
- }
- if (!ast_strlen_zero(ast_str_buffer(temp->seealso))) {
- char *seealso = ast_xmldoc_printable(ast_str_buffer(temp->seealso), 1);
- ast_cli(a->fd, "%s%s\n\n", seealso_title, seealso);
- ast_free(seealso);
- }
+ for (temp = item; temp; temp = AST_LIST_NEXT(temp, next)) {
+ print_event_instance(a, temp);
}
ao2_ref(item, -1);
diff --git a/main/manager_bridges.c b/main/manager_bridges.c
index 63a927246..26b0e7882 100644
--- a/main/manager_bridges.c
+++ b/main/manager_bridges.c
@@ -100,6 +100,26 @@ static struct stasis_message_router *bridge_state_router;
<description>
<para>Returns detailed information about a bridge and the channels in it.</para>
</description>
+ <responses>
+ <list-elements>
+ <managerEvent language="en_US" name="BridgeInfoChannel">
+ <managerEventInstance class="EVENT_FLAG_COMMAND">
+ <synopsis>Information about a channel in a bridge.</synopsis>
+ <syntax>
+ <channel_snapshot/>
+ </syntax>
+ </managerEventInstance>
+ </managerEvent>
+ </list-elements>
+ <managerEvent language="en_US" name="BridgeInfoComplete">
+ <managerEventInstance class="EVENT_FLAG_COMMAND">
+ <synopsis>Information about a bridge.</synopsis>
+ <syntax>
+ <bridge_snapshot/>
+ </syntax>
+ </managerEventInstance>
+ </managerEvent>
+ </responses>
</manager>
<manager name="BridgeDestroy" language="en_US">
<synopsis>
diff --git a/main/xmldoc.c b/main/xmldoc.c
index 28bea86bd..a84b05982 100644
--- a/main/xmldoc.c
+++ b/main/xmldoc.c
@@ -2300,9 +2300,9 @@ static void ast_xml_doc_item_destructor(void *obj)
ast_free(doc->description);
ast_string_field_free_memory(doc);
- if (doc->next) {
- ao2_ref(doc->next, -1);
- doc->next = NULL;
+ if (AST_LIST_NEXT(doc, next)) {
+ ao2_ref(AST_LIST_NEXT(doc, next), -1);
+ AST_LIST_NEXT(doc, next) = NULL;
}
}
@@ -2428,6 +2428,139 @@ static struct ast_xml_doc_item *xmldoc_build_documentation_item(struct ast_xml_n
return item;
}
+/*!
+ * \internal
+ * \brief Build the list responses for an item
+ *
+ * \param manager_action The action node to parse
+ *
+ * \note This method exists for when you already have the node. This
+ * prevents having to lock the documentation tree twice
+ *
+ * \retval A list of ast_xml_doc_items
+ * \retval NULL on failure
+ *
+ * \since 13.0.0
+ */
+static struct ast_xml_doc_item *xmldoc_build_list_responses(struct ast_xml_node *manager_action)
+{
+ struct ast_xml_node *event;
+ struct ast_xml_node *responses;
+ struct ast_xml_node *list_elements;
+ struct ast_xml_doc_item_list root;
+
+ AST_LIST_HEAD_INIT(&root);
+
+ responses = ast_xml_find_element(ast_xml_node_get_children(manager_action), "responses", NULL, NULL);
+ if (!responses) {
+ return NULL;
+ }
+
+ list_elements = ast_xml_find_element(ast_xml_node_get_children(responses), "list-elements", NULL, NULL);
+ if (!list_elements) {
+ return NULL;
+ }
+
+ /* Iterate over managerEvent nodes */
+ for (event = ast_xml_node_get_children(list_elements); event; event = ast_xml_node_get_next(event)) {
+ struct ast_xml_node *event_instance;
+ const char *name = ast_xml_get_attribute(event, "name");
+ struct ast_xml_doc_item *new_item;
+
+ if (!name || strcmp(ast_xml_node_get_name(event), "managerEvent")) {
+ continue;
+ }
+
+ event_instance = ast_xml_find_element(ast_xml_node_get_children(event),
+ "managerEventInstance", NULL, NULL);
+ new_item = xmldoc_build_documentation_item(event_instance, name, "managerEvent");
+ if (!new_item) {
+ ao2_cleanup(AST_LIST_FIRST(&root));
+ return NULL;
+ }
+
+ AST_LIST_INSERT_TAIL(&root, new_item, next);
+ }
+
+ return AST_LIST_FIRST(&root);
+}
+
+struct ast_xml_doc_item *ast_xmldoc_build_list_responses(const char *type, const char *name, const char *module)
+{
+ struct ast_xml_node *node;
+
+ if (ast_strlen_zero(type) || ast_strlen_zero(name)) {
+ return NULL;
+ }
+
+ node = xmldoc_get_node(type, name, module, documentation_language);
+
+ if (!node || !ast_xml_node_get_children(node)) {
+ return NULL;
+ }
+
+ return xmldoc_build_list_responses(node);
+}
+
+/*!
+ * \internal
+ * \brief Build the final response for an item
+ *
+ * \param manager_action The action node to parse
+ *
+ * \note This method exists for when you already have the node. This
+ * prevents having to lock the documentation tree twice
+ *
+ * \retval An ast_xml_doc_item
+ * \retval NULL on failure
+ *
+ * \since 13.0.0
+ */
+static struct ast_xml_doc_item *xmldoc_build_final_response(struct ast_xml_node *manager_action)
+{
+ struct ast_xml_node *responses;
+ struct ast_xml_node *final_response_event;
+ struct ast_xml_node *event_instance;
+
+ responses = ast_xml_find_element(ast_xml_node_get_children(manager_action),
+ "responses", NULL, NULL);
+ if (!responses) {
+ return NULL;
+ }
+
+ final_response_event = ast_xml_find_element(ast_xml_node_get_children(responses),
+ "managerEvent", NULL, NULL);
+ if (!final_response_event) {
+ return NULL;
+ }
+
+ event_instance = ast_xml_find_element(ast_xml_node_get_children(final_response_event),
+ "managerEventInstance", NULL, NULL);
+ if (!event_instance) {
+ return NULL;
+ }
+
+ return xmldoc_build_documentation_item(event_instance,
+ ast_xml_get_attribute(final_response_event, "name"), "managerEvent");
+}
+
+struct ast_xml_doc_item *ast_xmldoc_build_final_response(const char *type, const char *name, const char *module)
+{
+ struct ast_xml_node *node;
+
+ if (ast_strlen_zero(type) || ast_strlen_zero(name)) {
+ return NULL;
+ }
+
+ node = xmldoc_get_node(type, name, module, documentation_language);
+
+ if (!node || !ast_xml_node_get_children(node)) {
+ return NULL;
+ }
+
+ return xmldoc_build_final_response(node);
+}
+
struct ast_xml_xpath_results *__attribute__((format(printf, 1, 2))) ast_xmldoc_query(const char *fmt, ...)
{
struct ast_xml_xpath_results *results = NULL;
@@ -2455,7 +2588,7 @@ struct ast_xml_xpath_results *__attribute__((format(printf, 1, 2))) ast_xmldoc_q
return results;
}
-static void build_config_docs(struct ast_xml_node *cur, struct ast_xml_doc_item **tail)
+static void build_config_docs(struct ast_xml_node *cur, struct ast_xml_doc_item_list *root)
{
struct ast_xml_node *iter;
struct ast_xml_doc_item *item;
@@ -2478,9 +2611,8 @@ static void build_config_docs(struct ast_xml_node *cur, struct ast_xml_doc_item
ast_string_field_set(item, ref, name);
ast_xml_free_attr(name);
}
- (*tail)->next = item;
- *tail = (*tail)->next;
- build_config_docs(iter, tail);
+ AST_LIST_INSERT_TAIL(root, item, next);
+ build_config_docs(iter, root);
}
}
@@ -2536,7 +2668,6 @@ int ast_xmldoc_regenerate_doc_item(struct ast_xml_doc_item *item)
struct ao2_container *ast_xmldoc_build_documentation(const char *type)
{
struct ao2_container *docs;
- struct ast_xml_doc_item *item = NULL, *root = NULL;
struct ast_xml_node *node = NULL, *instance = NULL;
struct documentation_tree *doctree;
const char *name;
@@ -2555,6 +2686,8 @@ struct ao2_container *ast_xmldoc_build_documentation(const char *type)
}
for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
+ struct ast_xml_doc_item *item = NULL;
+
/* Ignore empty nodes or nodes that aren't of the type requested */
if (!ast_xml_node_get_children(node) || strcasecmp(ast_xml_node_get_name(node), type)) {
continue;
@@ -2566,6 +2699,10 @@ struct ao2_container *ast_xmldoc_build_documentation(const char *type)
switch (xmldoc_get_syntax_type(type)) {
case MANAGER_EVENT_SYNTAX:
+ {
+ struct ast_xml_doc_item_list root;
+
+ AST_LIST_HEAD_INIT(&root);
for (instance = ast_xml_node_get_children(node); instance; instance = ast_xml_node_get_next(instance)) {
struct ast_xml_doc_item *temp;
if (!ast_xml_node_get_children(instance) || strcasecmp(ast_xml_node_get_name(instance), "managerEventInstance")) {
@@ -2575,28 +2712,27 @@ struct ao2_container *ast_xmldoc_build_documentation(const char *type)
if (!temp) {
break;
}
- if (!item) {
- item = temp;
- root = item;
- } else {
- item->next = temp;
- item = temp;
- }
+ AST_LIST_INSERT_TAIL(&root, temp, next);
}
- item = root;
+ item = AST_LIST_FIRST(&root);
break;
+ }
case CONFIG_INFO_SYNTAX:
{
- struct ast_xml_doc_item *tail;
RAII_VAR(const char *, name, ast_xml_get_attribute(node, "name"), ast_xml_free_attr);
- if (item || !ast_xml_node_get_children(node) || strcasecmp(ast_xml_node_get_name(node), "configInfo")) {
+
+ if (!ast_xml_node_get_children(node) || strcasecmp(ast_xml_node_get_name(node), "configInfo")) {
break;
}
- if (!(item = xmldoc_build_documentation_item(node, name, "configInfo"))) {
- break;
+
+ item = xmldoc_build_documentation_item(node, name, "configInfo");
+ if (item) {
+ struct ast_xml_doc_item_list root;
+
+ AST_LIST_HEAD_INIT(&root);
+ AST_LIST_INSERT_TAIL(&root, item, next);
+ build_config_docs(node, &root);
}
- tail = item;
- build_config_docs(node, &tail);
break;
}
default:
@@ -2607,7 +2743,6 @@ struct ao2_container *ast_xmldoc_build_documentation(const char *type)
if (item) {
ao2_link(docs, item);
ao2_t_ref(item, -1, "Dispose of creation ref");
- item = NULL;
}
}
}