mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-03 03:20:57 +00:00
docs: Enable since/version handling for XML, CLI and ARI documentation
* Added the "since" element to the XML configObject and configOption elements
in appdocsxml.dtd.
* Added the "Since" section to the following CLI output:
```
config show help <module> <object>
config show help <module> <object> <option>
core show application <app>
core show function <func>
manager show command <command>
manager show event <event>
agi show commands topic <topic>
```
* Refactored the commands above to output their sections in the same order:
Synopsis, Since, Description, Syntax, Arguments, SeeAlso
* Refactored the commands above so they all use the same pattern for writing
the output to the CLI.
* Fixed several memory leaks caused by failure to free temporary output
buffers.
* Added a "since" array to the mustache template for the top-level resources
(Channel, Endpoint, etc.) and to the paths/methods underneath them. These
will be added to the generated markdown if present.
Example:
```
"resourcePath": "/api-docs/channels.{format}",
"requiresModules": [
"res_stasis_answer",
"res_stasis_playback",
"res_stasis_recording",
"res_stasis_snoop"
],
"since": [
"18.0.0",
"21.0.0"
],
"apis": [
{
"path": "/channels",
"description": "Active channels",
"operations": [
{
"httpMethod": "GET",
"since": [
"18.6.0",
"21.8.0"
],
"summary": "List all active channels in Asterisk.",
"nickname": "list",
"responseClass": "List[Channel]"
},
```
NOTE: No versioning information is actually added in this commit.
Those will be added separately and instructions for adding and maintaining
them will be published on the documentation site at a later date.
(cherry picked from commit 3e28ddce78
)
This commit is contained in:
committed by
Asterisk Development Team
parent
d468918359
commit
24c077f1fb
@@ -72,10 +72,10 @@
|
||||
<!ELEMENT configFile (configObject|xi:include)+>
|
||||
<!ATTLIST configFile name CDATA #REQUIRED>
|
||||
|
||||
<!ELEMENT configObject (synopsis?|description?|syntax?|see-also?|(configOption|xi:include))*>
|
||||
<!ELEMENT configObject (since?|synopsis?|description?|syntax?|see-also?|(configOption|xi:include))*>
|
||||
<!ATTLIST configObject name CDATA #REQUIRED>
|
||||
|
||||
<!ELEMENT configOption (synopsis,description?,syntax?,see-also?)*>
|
||||
<!ELEMENT configOption (since?,synopsis,description?,syntax?,see-also?)*>
|
||||
<!ATTLIST configOption name CDATA #REQUIRED>
|
||||
<!ATTLIST configOption regex (yes|no|true|false) "false">
|
||||
<!ATTLIST configOption default CDATA #IMPLIED>
|
||||
|
@@ -60,6 +60,10 @@ typedef struct agi_command {
|
||||
struct ast_module *mod;
|
||||
/*! Linked list pointer */
|
||||
AST_LIST_ENTRY(agi_command) list;
|
||||
/*! Since content */
|
||||
const char * const since;
|
||||
/*! Syntax arguments content */
|
||||
const char * const arguments;
|
||||
} agi_command;
|
||||
|
||||
/*!
|
||||
|
@@ -181,6 +181,7 @@ struct manager_action {
|
||||
* function and unregistering the AMI action object.
|
||||
*/
|
||||
unsigned int registered:1;
|
||||
AST_STRING_FIELD_EXTENDED(since); /*!< Documentation "since" element */
|
||||
};
|
||||
|
||||
/*! \brief External routines may register/unregister manager callbacks this way
|
||||
|
@@ -150,6 +150,7 @@ struct ast_custom_function {
|
||||
* \since 12 */
|
||||
|
||||
AST_RWLIST_ENTRY(ast_custom_function) acflist;
|
||||
AST_STRING_FIELD_EXTENDED(since); /*!< Since text for 'show functions' */
|
||||
};
|
||||
|
||||
/*! \brief All switch functions have the same interface, so define a type for them */
|
||||
|
@@ -78,6 +78,8 @@ struct ast_xml_doc_item {
|
||||
struct ast_xml_node *node;
|
||||
/*! The next XML documentation item that matches the same name/item type */
|
||||
AST_LIST_ENTRY(ast_xml_doc_item) next;
|
||||
/*! Since tagged information, if it exists */
|
||||
struct ast_str *since;
|
||||
};
|
||||
|
||||
/*! \brief Execute an XPath query on the loaded XML documentation
|
||||
@@ -110,6 +112,16 @@ char *ast_xmldoc_build_syntax(const char *type, const char *name, const char *mo
|
||||
*/
|
||||
char *ast_xmldoc_build_seealso(const char *type, const char *name, const char *module);
|
||||
|
||||
/*!
|
||||
* \brief Parse the <since> node content.
|
||||
* \param type 'application', 'function' or 'agi'.
|
||||
* \param name Application or functions name.
|
||||
* \param module The module the item is in (optional, can be NULL)
|
||||
* \retval NULL on error.
|
||||
* \retval Content of the since node.
|
||||
*/
|
||||
char *ast_xmldoc_build_since(const char *type, const char *name, const char *module);
|
||||
|
||||
/*!
|
||||
* \brief Generate the [arguments] tag based on type of node ('application',
|
||||
* 'function' or 'agi') and name.
|
||||
|
@@ -1244,10 +1244,14 @@ static void cli_show_module_types(struct ast_cli_args *a)
|
||||
}
|
||||
|
||||
if (ast_str_strlen(item->synopsis)) {
|
||||
ast_cli(a->fd, "%s\n\n", ast_xmldoc_printable(ast_str_buffer(item->synopsis), 1));
|
||||
char *value = ast_xmldoc_printable(ast_str_buffer(item->synopsis), 1);
|
||||
ast_cli(a->fd, "%s\n\n", value);
|
||||
ast_free(value);
|
||||
}
|
||||
if (ast_str_strlen(item->description)) {
|
||||
ast_cli(a->fd, "%s\n\n", ast_xmldoc_printable(ast_str_buffer(item->description), 1));
|
||||
char *value = ast_xmldoc_printable(ast_str_buffer(item->description), 1);
|
||||
ast_cli(a->fd, "%s\n\n",value);
|
||||
ast_free(value);
|
||||
}
|
||||
|
||||
tmp = item;
|
||||
@@ -1267,8 +1271,8 @@ static void cli_show_module_type(struct ast_cli_args *a)
|
||||
{
|
||||
RAII_VAR(struct ast_xml_doc_item *, item, NULL, ao2_cleanup);
|
||||
struct ast_xml_doc_item *tmp;
|
||||
char option_type[64];
|
||||
int match = 0;
|
||||
char *synopsis, *since, *description, *syntax, *seealso;
|
||||
|
||||
ast_assert(a->argc == 5);
|
||||
|
||||
@@ -1281,19 +1285,48 @@ static void cli_show_module_type(struct ast_cli_args *a)
|
||||
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));
|
||||
ast_cli(a->fd, "%s", option_type);
|
||||
if (ast_str_strlen(tmp->syntax)) {
|
||||
ast_cli(a->fd, ": [%s]\n\n", ast_xmldoc_printable(ast_str_buffer(tmp->syntax), 1));
|
||||
} else {
|
||||
ast_cli(a->fd, "\n\n");
|
||||
}
|
||||
if (ast_str_strlen(tmp->synopsis)) {
|
||||
ast_cli(a->fd, "%s\n\n", ast_xmldoc_printable(ast_str_buffer(tmp->synopsis), 1));
|
||||
}
|
||||
if (ast_str_strlen(tmp->description)) {
|
||||
ast_cli(a->fd, "%s\n\n", ast_xmldoc_printable(ast_str_buffer(tmp->description), 1));
|
||||
|
||||
synopsis = ast_xmldoc_printable(AS_OR(tmp->synopsis, "Not available"), 1);
|
||||
since = ast_xmldoc_printable(AS_OR(tmp->since, "Not available"), 1);
|
||||
description = ast_xmldoc_printable(AS_OR(tmp->description, "Not available"), 1);
|
||||
syntax = ast_xmldoc_printable(AS_OR(tmp->syntax, "Not available"), 1);
|
||||
seealso = ast_xmldoc_printable(AS_OR(tmp->seealso, "Not available"), 1);
|
||||
|
||||
if (!synopsis || !since || !description || !syntax || !seealso ) {
|
||||
ast_free(synopsis);
|
||||
ast_free(since);
|
||||
ast_free(description);
|
||||
ast_free(syntax);
|
||||
ast_free(seealso);
|
||||
ast_cli(a->fd, "Error: Memory allocation failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ast_cli(a->fd, "\n"
|
||||
"%s -= Info about Config Object '%s:%s' =- %s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s [%s]\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n",
|
||||
ast_term_color(COLOR_MAGENTA, 0), a->argv[3], tmp->name, ast_term_reset(),
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Since]"), since,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"), tmp->name, syntax,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso
|
||||
);
|
||||
ast_free(synopsis);
|
||||
ast_free(since);
|
||||
ast_free(description);
|
||||
ast_free(syntax);
|
||||
ast_free(seealso);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1304,6 +1337,8 @@ static void cli_show_module_type(struct ast_cli_args *a)
|
||||
|
||||
/* Now iterate over the options for the type */
|
||||
tmp = item;
|
||||
ast_cli(a->fd, COLORIZE_FMT "\n", COLORIZE(COLOR_MAGENTA, 0, "[Config Options]"));
|
||||
|
||||
while ((tmp = AST_LIST_NEXT(tmp, next))) {
|
||||
if (!strcasecmp(tmp->type, "configOption") && !strcasecmp(tmp->ref, a->argv[4])) {
|
||||
ast_cli(a->fd, "%-25s -- %-120.120s\n", tmp->name,
|
||||
@@ -1319,8 +1354,8 @@ static void cli_show_module_options(struct ast_cli_args *a)
|
||||
{
|
||||
RAII_VAR(struct ast_xml_doc_item *, item, NULL, ao2_cleanup);
|
||||
struct ast_xml_doc_item *tmp;
|
||||
char option_name[64];
|
||||
int match = 0;
|
||||
char *synopsis, *since, *description, *syntax, *seealso;
|
||||
|
||||
ast_assert(a->argc == 6);
|
||||
|
||||
@@ -1334,20 +1369,47 @@ static void cli_show_module_options(struct ast_cli_args *a)
|
||||
if (match) {
|
||||
ast_cli(a->fd, "\n");
|
||||
}
|
||||
term_color(option_name, tmp->ref, COLOR_MAGENTA, COLOR_BLACK, sizeof(option_name));
|
||||
ast_cli(a->fd, "[%s%s]\n", option_name, ast_term_reset());
|
||||
if (ast_str_strlen(tmp->syntax)) {
|
||||
ast_cli(a->fd, "%s\n", ast_xmldoc_printable(ast_str_buffer(tmp->syntax), 1));
|
||||
}
|
||||
ast_cli(a->fd, "%s\n\n", ast_xmldoc_printable(AS_OR(tmp->synopsis, "No information available"), 1));
|
||||
if (ast_str_strlen(tmp->description)) {
|
||||
ast_cli(a->fd, "%s\n\n", ast_xmldoc_printable(ast_str_buffer(tmp->description), 1));
|
||||
|
||||
synopsis = ast_xmldoc_printable(AS_OR(tmp->synopsis, "Not available"), 1);
|
||||
since = ast_xmldoc_printable(AS_OR(tmp->since, "Not available"), 1);
|
||||
description = ast_xmldoc_printable(AS_OR(tmp->description, "Not available"), 1);
|
||||
syntax = ast_xmldoc_printable(AS_OR(tmp->syntax, "Not available"), 1);
|
||||
seealso = ast_xmldoc_printable(AS_OR(tmp->seealso, "Not available"), 1);
|
||||
|
||||
if (!synopsis || !since || !description || !syntax || !seealso ) {
|
||||
ast_free(synopsis);
|
||||
ast_free(since);
|
||||
ast_free(description);
|
||||
ast_free(syntax);
|
||||
ast_free(seealso);
|
||||
ast_cli(a->fd, "Error: Memory allocation failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (ast_str_strlen(tmp->seealso)) {
|
||||
ast_cli(a->fd, "See Also:\n");
|
||||
ast_cli(a->fd, "%s\n\n", ast_xmldoc_printable(ast_str_buffer(tmp->seealso), 1));
|
||||
}
|
||||
ast_cli(a->fd, "\n"
|
||||
"%s -= Info about Config Option '%s:%s:%s' =- %s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n",
|
||||
ast_term_color(COLOR_MAGENTA, 0), a->argv[3], a->argv[4], tmp->name, ast_term_reset(),
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Since]"), since,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"), syntax,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso
|
||||
);
|
||||
ast_free(synopsis);
|
||||
ast_free(since);
|
||||
ast_free(description);
|
||||
ast_free(syntax);
|
||||
ast_free(seealso);
|
||||
|
||||
match = 1;
|
||||
}
|
||||
|
158
main/manager.c
158
main/manager.c
@@ -1084,10 +1084,6 @@ static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_
|
||||
int num;
|
||||
int l;
|
||||
const char *auth_str;
|
||||
#ifdef AST_XML_DOCS
|
||||
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) {
|
||||
case CLI_INIT:
|
||||
@@ -1115,18 +1111,6 @@ static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_
|
||||
|
||||
authority = ast_str_alloca(MAX_AUTH_PERM_STRING);
|
||||
|
||||
#ifdef AST_XML_DOCS
|
||||
/* setup the titles */
|
||||
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);
|
||||
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);
|
||||
AST_RWLIST_TRAVERSE(&actions, cur, list) {
|
||||
for (num = 3; num < a->argc; num++) {
|
||||
@@ -1135,22 +1119,24 @@ static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_
|
||||
|
||||
#ifdef AST_XML_DOCS
|
||||
if (cur->docsrc == AST_XML_DOC) {
|
||||
char *syntax = ast_xmldoc_printable(S_OR(cur->syntax, "Not available"), 1);
|
||||
char *synopsis = ast_xmldoc_printable(S_OR(cur->synopsis, "Not available"), 1);
|
||||
char *since = ast_xmldoc_printable(S_OR(cur->since, "Not available"), 1);
|
||||
char *description = ast_xmldoc_printable(S_OR(cur->description, "Not available"), 1);
|
||||
char *syntax = ast_xmldoc_printable(S_OR(cur->syntax, "Not available"), 1);
|
||||
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(auth_str, "Not available"), 1);
|
||||
char *seealso = ast_xmldoc_printable(S_OR(cur->seealso, "Not available"), 1);
|
||||
char *responses = ast_xmldoc_printable("None", 1);
|
||||
|
||||
if (!syntax || !synopsis || !description || !arguments
|
||||
|| !seealso || !privilege || !responses) {
|
||||
ast_free(syntax);
|
||||
if (!synopsis || !since || !description || !syntax || !arguments
|
||||
|| !privilege || !seealso || !responses) {
|
||||
ast_free(synopsis);
|
||||
ast_free(since);
|
||||
ast_free(description);
|
||||
ast_free(syntax);
|
||||
ast_free(arguments);
|
||||
ast_free(seealso);
|
||||
ast_free(privilege);
|
||||
ast_free(seealso);
|
||||
ast_free(responses);
|
||||
ast_cli(a->fd, "Allocation failure.\n");
|
||||
AST_RWLIST_UNLOCK(&actions);
|
||||
@@ -1158,14 +1144,33 @@ static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_
|
||||
return CLI_FAILURE;
|
||||
}
|
||||
|
||||
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,
|
||||
list_responses_title);
|
||||
ast_cli(a->fd, "\n"
|
||||
"%s -= Info about Manager Command '%s' =- %s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n",
|
||||
ast_term_color(COLOR_MAGENTA, 0), cur->action, ast_term_reset(),
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Since]"), since,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"), syntax,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"), arguments,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Privilege]"), privilege,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[List Responses]")
|
||||
);
|
||||
|
||||
if (!cur->list_responses) {
|
||||
ast_cli(a->fd, "%s\n\n", responses);
|
||||
@@ -1176,22 +1181,33 @@ static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_
|
||||
print_event_instance(a, temp);
|
||||
}
|
||||
}
|
||||
ast_cli(a->fd,
|
||||
COLORIZE_FMT "\n",
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[End List Responses]")
|
||||
);
|
||||
|
||||
ast_cli(a->fd, "%s", final_response_title);
|
||||
|
||||
ast_cli(a->fd, "\n"
|
||||
COLORIZE_FMT "\n",
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Final Response]")
|
||||
);
|
||||
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);
|
||||
}
|
||||
ast_cli(a->fd,
|
||||
COLORIZE_FMT "\n",
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[End Final Response]")
|
||||
);
|
||||
|
||||
ast_free(syntax);
|
||||
ast_free(synopsis);
|
||||
ast_free(since);
|
||||
ast_free(description);
|
||||
ast_free(syntax);
|
||||
ast_free(arguments);
|
||||
ast_free(seealso);
|
||||
ast_free(privilege);
|
||||
ast_free(seealso);
|
||||
ast_free(responses);
|
||||
} else
|
||||
#endif
|
||||
@@ -7754,6 +7770,11 @@ int ast_manager_register2(const char *action, int auth, int (*func)(struct manse
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ast_string_field_init_extended(cur, since)) {
|
||||
ao2_t_ref(cur, -1, "action object creation failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cur->action = action;
|
||||
cur->authority = auth;
|
||||
cur->func = func;
|
||||
@@ -7762,6 +7783,10 @@ int ast_manager_register2(const char *action, int auth, int (*func)(struct manse
|
||||
if (ast_strlen_zero(synopsis) && ast_strlen_zero(description)) {
|
||||
char *tmpxml;
|
||||
|
||||
tmpxml = ast_xmldoc_build_since("manager", action, NULL);
|
||||
ast_string_field_set(cur, since, tmpxml);
|
||||
ast_free(tmpxml);
|
||||
|
||||
tmpxml = ast_xmldoc_build_synopsis("manager", action, NULL);
|
||||
ast_string_field_set(cur, synopsis, tmpxml);
|
||||
ast_free(tmpxml);
|
||||
@@ -9174,40 +9199,51 @@ static char *handle_manager_show_events(struct ast_cli_entry *e, int cmd, struct
|
||||
|
||||
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];
|
||||
char *since, *syntax, *description, *synopsis, *seealso, *arguments;
|
||||
|
||||
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);
|
||||
synopsis = ast_xmldoc_printable(AS_OR(instance->synopsis, "Not available"), 1);
|
||||
since = ast_xmldoc_printable(AS_OR(instance->since, "Not available"), 1);
|
||||
description = ast_xmldoc_printable(AS_OR(instance->description, "Not available"), 1);
|
||||
syntax = ast_xmldoc_printable(AS_OR(instance->syntax, "Not available"), 1);
|
||||
arguments = ast_xmldoc_printable(AS_OR(instance->arguments, "Not available"), 1);
|
||||
seealso = ast_xmldoc_printable(AS_OR(instance->seealso, "Not available"), 1);
|
||||
|
||||
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);
|
||||
if (!synopsis || !since || !description || !syntax || !arguments || !seealso) {
|
||||
ast_cli(a->fd, "Error: Memory allocation failed\n");
|
||||
goto free_docs;
|
||||
}
|
||||
|
||||
ast_cli(a->fd, "\n"
|
||||
"%s -= Info about Manager Event '%s' =- %s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n",
|
||||
ast_term_color(COLOR_MAGENTA, 0), instance->name, ast_term_reset(),
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Since]"), since,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"), syntax,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"), arguments,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso
|
||||
);
|
||||
|
||||
free_docs:
|
||||
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(since);
|
||||
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(syntax);
|
||||
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)
|
||||
{
|
||||
|
102
main/pbx_app.c
102
main/pbx_app.c
@@ -46,6 +46,7 @@ struct ast_app {
|
||||
int (*execute)(struct ast_channel *chan, const char *data);
|
||||
AST_DECLARE_STRING_FIELDS(
|
||||
AST_STRING_FIELD(synopsis); /*!< Synopsis text for 'show applications' */
|
||||
AST_STRING_FIELD(since); /*!< Since text for 'show applications' */
|
||||
AST_STRING_FIELD(description); /*!< Description (help text) for 'show application <name>' */
|
||||
AST_STRING_FIELD(syntax); /*!< Syntax text for 'core show applications' */
|
||||
AST_STRING_FIELD(arguments); /*!< Arguments description */
|
||||
@@ -142,6 +143,11 @@ int ast_register_application2(const char *app, int (*execute)(struct ast_channel
|
||||
ast_string_field_set(tmp, synopsis, tmpxml);
|
||||
ast_free(tmpxml);
|
||||
|
||||
/* load since */
|
||||
tmpxml = ast_xmldoc_build_since("application", app, ast_module_name(tmp->module));
|
||||
ast_string_field_set(tmp, since, tmpxml);
|
||||
ast_free(tmpxml);
|
||||
|
||||
/* load description */
|
||||
tmpxml = ast_xmldoc_build_description("application", app, ast_module_name(tmp->module));
|
||||
ast_string_field_set(tmp, description, tmpxml);
|
||||
@@ -191,67 +197,61 @@ int ast_register_application2(const char *app, int (*execute)(struct ast_channel
|
||||
|
||||
static void print_app_docs(struct ast_app *aa, int fd)
|
||||
{
|
||||
char *synopsis = NULL, *since = NULL, *description = NULL, *syntax = NULL, *arguments = NULL, *seealso = NULL;
|
||||
|
||||
#ifdef AST_XML_DOCS
|
||||
char *synopsis = NULL, *description = NULL, *arguments = NULL, *seealso = NULL;
|
||||
if (aa->docsrc == AST_XML_DOC) {
|
||||
synopsis = ast_xmldoc_printable(S_OR(aa->synopsis, "Not available"), 1);
|
||||
since = ast_xmldoc_printable(S_OR(aa->since, "Not available"), 1);
|
||||
description = ast_xmldoc_printable(S_OR(aa->description, "Not available"), 1);
|
||||
syntax = ast_xmldoc_printable(S_OR(aa->syntax, "Not available"), 1);
|
||||
arguments = ast_xmldoc_printable(S_OR(aa->arguments, "Not available"), 1);
|
||||
seealso = ast_xmldoc_printable(S_OR(aa->seealso, "Not available"), 1);
|
||||
if (!synopsis || !description || !arguments || !seealso) {
|
||||
goto free_docs;
|
||||
}
|
||||
ast_cli(fd, "\n"
|
||||
"%s -= Info about application '%s' =- %s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s%s%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n",
|
||||
ast_term_color(COLOR_MAGENTA, 0), aa->name, ast_term_reset(),
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"),
|
||||
ast_term_color(COLOR_CYAN, 0), S_OR(aa->syntax, "Not available"), ast_term_reset(),
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"), arguments,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso);
|
||||
free_docs:
|
||||
ast_free(synopsis);
|
||||
ast_free(description);
|
||||
ast_free(arguments);
|
||||
ast_free(seealso);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ast_cli(fd, "\n"
|
||||
"%s -= Info about application '%s' =- %s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
COLORIZE_FMT "\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
COLORIZE_FMT "\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
COLORIZE_FMT "\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
COLORIZE_FMT "\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
COLORIZE_FMT "\n",
|
||||
ast_term_color(COLOR_MAGENTA, 0), aa->name, ast_term_reset(),
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"),
|
||||
COLORIZE(COLOR_CYAN, 0, S_OR(aa->synopsis, "Not available")),
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Description]"),
|
||||
COLORIZE(COLOR_CYAN, 0, S_OR(aa->description, "Not available")),
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"),
|
||||
COLORIZE(COLOR_CYAN, 0, S_OR(aa->syntax, "Not available")),
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"),
|
||||
COLORIZE(COLOR_CYAN, 0, S_OR(aa->arguments, "Not available")),
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[See Also]"),
|
||||
COLORIZE(COLOR_CYAN, 0, S_OR(aa->seealso, "Not available")));
|
||||
synopsis = ast_strdup(S_OR(aa->synopsis, "Not Available"));
|
||||
since = ast_strdup(S_OR(aa->since, "Not Available"));
|
||||
description = ast_strdup(S_OR(aa->description, "Not Available"));
|
||||
syntax = ast_strdup(S_OR(aa->syntax, "Not Available"));
|
||||
arguments = ast_strdup(S_OR(aa->arguments, "Not Available"));
|
||||
seealso = ast_strdup(S_OR(aa->seealso, "Not Available"));
|
||||
}
|
||||
/* check allocated memory. */
|
||||
if (!synopsis || !since || !description || !syntax || !arguments || !seealso) {
|
||||
goto free_docs;
|
||||
}
|
||||
|
||||
ast_cli(fd, "\n"
|
||||
"%s -= Info about Application '%s' =- %s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n",
|
||||
ast_term_color(COLOR_MAGENTA, 0), aa->name, ast_term_reset(),
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Since]"), since,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"), syntax,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"), arguments,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso
|
||||
);
|
||||
|
||||
free_docs:
|
||||
ast_free(synopsis);
|
||||
ast_free(since);
|
||||
ast_free(description);
|
||||
ast_free(syntax);
|
||||
ast_free(arguments);
|
||||
ast_free(seealso);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@@ -144,10 +144,8 @@ static char *handle_show_function(struct ast_cli_entry *e, int cmd, struct ast_c
|
||||
{
|
||||
struct ast_custom_function *acf;
|
||||
/* Maximum number of characters added by terminal coloring is 22 */
|
||||
char infotitle[64 + AST_MAX_APP + 22], syntitle[40], desctitle[40], argtitle[40], seealsotitle[40];
|
||||
char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL, *seealso = NULL;
|
||||
char stxtitle[40], *syntax = NULL, *arguments = NULL;
|
||||
int syntax_size, description_size, synopsis_size, arguments_size, seealso_size;
|
||||
char *synopsis = NULL, *since = NULL, *description = NULL, *syntax = NULL, *arguments = NULL, *seealso = NULL;
|
||||
char *rtn = CLI_SUCCESS;
|
||||
|
||||
switch (cmd) {
|
||||
case CLI_INIT:
|
||||
@@ -170,71 +168,62 @@ static char *handle_show_function(struct ast_cli_entry *e, int cmd, struct ast_c
|
||||
return CLI_FAILURE;
|
||||
}
|
||||
|
||||
syntax_size = strlen(S_OR(acf->syntax, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
|
||||
syntax = ast_malloc(syntax_size);
|
||||
if (!syntax) {
|
||||
ast_cli(a->fd, "Memory allocation failure!\n");
|
||||
|
||||
return CLI_FAILURE;
|
||||
}
|
||||
|
||||
snprintf(info, sizeof(info), "\n -= Info about function '%s' =- \n\n", acf->name);
|
||||
term_color(infotitle, info, COLOR_MAGENTA, 0, sizeof(infotitle));
|
||||
term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
|
||||
term_color(desctitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
|
||||
term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
|
||||
term_color(argtitle, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
|
||||
term_color(seealsotitle, "[See Also]\n", COLOR_MAGENTA, 0, 40);
|
||||
term_color(syntax, S_OR(acf->syntax, "Not available"), COLOR_CYAN, 0, syntax_size);
|
||||
#ifdef AST_XML_DOCS
|
||||
if (acf->docsrc == AST_XML_DOC) {
|
||||
arguments = ast_xmldoc_printable(S_OR(acf->arguments, "Not available"), 1);
|
||||
synopsis = ast_xmldoc_printable(S_OR(acf->synopsis, "Not available"), 1);
|
||||
since = ast_xmldoc_printable(S_OR(acf->since, "Not available"), 1);
|
||||
description = ast_xmldoc_printable(S_OR(acf->desc, "Not available"), 1);
|
||||
syntax = ast_xmldoc_printable(S_OR(acf->syntax, "Not available"), 1);
|
||||
arguments = ast_xmldoc_printable(S_OR(acf->arguments, "Not available"), 1);
|
||||
seealso = ast_xmldoc_printable(S_OR(acf->seealso, "Not available"), 1);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
synopsis_size = strlen(S_OR(acf->synopsis, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
|
||||
synopsis = ast_malloc(synopsis_size);
|
||||
|
||||
description_size = strlen(S_OR(acf->desc, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
|
||||
description = ast_malloc(description_size);
|
||||
|
||||
arguments_size = strlen(S_OR(acf->arguments, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
|
||||
arguments = ast_malloc(arguments_size);
|
||||
|
||||
seealso_size = strlen(S_OR(acf->seealso, "Not Available")) + AST_TERM_MAX_ESCAPE_CHARS;
|
||||
seealso = ast_malloc(seealso_size);
|
||||
|
||||
synopsis = ast_strdup(S_OR(acf->synopsis, "Not Available"));
|
||||
since = ast_strdup(S_OR(acf->since, "Not Available"));
|
||||
description = ast_strdup(S_OR(acf->desc, "Not Available"));
|
||||
syntax = ast_strdup(S_OR(acf->syntax, "Not Available"));
|
||||
arguments = ast_strdup(S_OR(acf->arguments, "Not Available"));
|
||||
seealso = ast_strdup(S_OR(acf->seealso, "Not Available"));
|
||||
}
|
||||
/* check allocated memory. */
|
||||
if (!synopsis || !description || !arguments || !seealso) {
|
||||
ast_free(synopsis);
|
||||
ast_free(description);
|
||||
ast_free(arguments);
|
||||
ast_free(seealso);
|
||||
ast_free(syntax);
|
||||
|
||||
return CLI_FAILURE;
|
||||
if (!synopsis || !since || !description || !syntax || !arguments || !seealso) {
|
||||
rtn = CLI_FAILURE;
|
||||
goto free_docs;
|
||||
}
|
||||
|
||||
term_color(arguments, S_OR(acf->arguments, "Not available"), COLOR_CYAN, 0, arguments_size);
|
||||
term_color(synopsis, S_OR(acf->synopsis, "Not available"), COLOR_CYAN, 0, synopsis_size);
|
||||
term_color(description, S_OR(acf->desc, "Not available"), COLOR_CYAN, 0, description_size);
|
||||
term_color(seealso, S_OR(acf->seealso, "Not available"), COLOR_CYAN, 0, seealso_size);
|
||||
}
|
||||
ast_cli(a->fd, "\n"
|
||||
"%s -= Info about Function '%s' =- %s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n",
|
||||
ast_term_color(COLOR_MAGENTA, 0), acf->name, ast_term_reset(),
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Since]"), since,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"), syntax,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"), arguments,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso
|
||||
);
|
||||
|
||||
ast_cli(a->fd, "%s%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n",
|
||||
infotitle, syntitle, synopsis, desctitle, description,
|
||||
stxtitle, syntax, argtitle, arguments, seealsotitle, seealso);
|
||||
|
||||
ast_free(arguments);
|
||||
free_docs:
|
||||
ast_free(synopsis);
|
||||
ast_free(since);
|
||||
ast_free(description);
|
||||
ast_free(seealso);
|
||||
ast_free(syntax);
|
||||
ast_free(arguments);
|
||||
ast_free(seealso);
|
||||
|
||||
return CLI_SUCCESS;
|
||||
return rtn;
|
||||
}
|
||||
|
||||
static struct ast_custom_function *ast_custom_function_find_nolock(const char *name)
|
||||
@@ -339,11 +328,21 @@ static int acf_retrieve_docs(struct ast_custom_function *acf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ast_string_field_init_extended(acf, since)) {
|
||||
ast_string_field_free_memory(acf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* load synopsis */
|
||||
tmpxml = ast_xmldoc_build_synopsis("function", acf->name, ast_module_name(acf->mod));
|
||||
ast_string_field_set(acf, synopsis, tmpxml);
|
||||
ast_free(tmpxml);
|
||||
|
||||
/* load since */
|
||||
tmpxml = ast_xmldoc_build_since("function", acf->name, ast_module_name(acf->mod));
|
||||
ast_string_field_set(acf, since, tmpxml);
|
||||
ast_free(tmpxml);
|
||||
|
||||
/* load description */
|
||||
tmpxml = ast_xmldoc_build_description("function", acf->name, ast_module_name(acf->mod));
|
||||
ast_string_field_set(acf, desc, tmpxml);
|
||||
|
144
main/xmldoc.c
144
main/xmldoc.c
@@ -1722,6 +1722,91 @@ char *ast_xmldoc_build_seealso(const char *type, const char *name, const char *m
|
||||
return output;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Build since information for an item
|
||||
*
|
||||
* \param node The since 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 malloc'd character pointer to the since information of the item
|
||||
* \retval NULL on failure
|
||||
*
|
||||
* \since 22
|
||||
*/
|
||||
static char *_ast_xmldoc_build_since(struct ast_xml_node *node)
|
||||
{
|
||||
char *output;
|
||||
struct ast_str *outputstr;
|
||||
const char *content;
|
||||
int first = 1;
|
||||
|
||||
/* Find the <since> node. */
|
||||
for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
|
||||
if (!strcasecmp(ast_xml_node_get_name(node), "since")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!node || !ast_xml_node_get_children(node)) {
|
||||
/* we couldnt find a <since> node. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* prepare the output string. */
|
||||
outputstr = ast_str_create(128);
|
||||
if (!outputstr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get into the <since> node. */
|
||||
for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
|
||||
if (strcasecmp(ast_xml_node_get_name(node), "version")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
content = ast_xml_get_text(node);
|
||||
if (!content) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ast_str_append(&outputstr, 0, "%s%s", (first ? "" : ", "), content);
|
||||
|
||||
first = 0;
|
||||
ast_xml_free_text(content);
|
||||
}
|
||||
|
||||
output = ast_strdup(ast_str_buffer(outputstr));
|
||||
ast_free(outputstr);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
char *ast_xmldoc_build_since(const char *type, const char *name, const char *module)
|
||||
{
|
||||
char *output;
|
||||
struct ast_xml_node *node;
|
||||
|
||||
if (ast_strlen_zero(type) || ast_strlen_zero(name)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get the application/function root node. */
|
||||
AST_RWLIST_RDLOCK(&xmldoc_tree);
|
||||
node = xmldoc_get_node(type, name, module, documentation_language);
|
||||
if (!node || !ast_xml_node_get_children(node)) {
|
||||
AST_RWLIST_UNLOCK(&xmldoc_tree);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
output = _ast_xmldoc_build_since(node);
|
||||
AST_RWLIST_UNLOCK(&xmldoc_tree);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Parse a \<enum\> node.
|
||||
@@ -2286,11 +2371,12 @@ static void ast_xml_doc_item_destructor(void *obj)
|
||||
return;
|
||||
}
|
||||
|
||||
ast_free(doc->syntax);
|
||||
ast_free(doc->seealso);
|
||||
ast_free(doc->arguments);
|
||||
ast_free(doc->synopsis);
|
||||
ast_free(doc->since);
|
||||
ast_free(doc->description);
|
||||
ast_free(doc->syntax);
|
||||
ast_free(doc->arguments);
|
||||
ast_free(doc->seealso);
|
||||
ast_string_field_free_memory(doc);
|
||||
|
||||
if (AST_LIST_NEXT(doc, next)) {
|
||||
@@ -2318,11 +2404,13 @@ static struct ast_xml_doc_item *ast_xml_doc_item_alloc(const char *name, const c
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( !(item->syntax = ast_str_create(128))
|
||||
|| !(item->seealso = ast_str_create(128))
|
||||
if ( !(item->synopsis = ast_str_create(128))
|
||||
|| !(item->since = ast_str_create(128))
|
||||
|| !(item->description = ast_str_create(128))
|
||||
|| !(item->syntax = ast_str_create(128))
|
||||
|| !(item->arguments = ast_str_create(128))
|
||||
|| !(item->synopsis = ast_str_create(128))
|
||||
|| !(item->description = ast_str_create(128))) {
|
||||
|| !(item->seealso = ast_str_create(128))
|
||||
) {
|
||||
ast_log(AST_LOG_ERROR, "Failed to allocate strings for ast_xml_doc_item instance\n");
|
||||
goto ast_xml_doc_item_failure;
|
||||
}
|
||||
@@ -2381,44 +2469,50 @@ static int ast_xml_doc_item_cmp(void *obj, void *arg, int flags)
|
||||
static struct ast_xml_doc_item *xmldoc_build_documentation_item(struct ast_xml_node *node, const char *name, const char *type)
|
||||
{
|
||||
struct ast_xml_doc_item *item;
|
||||
char *syntax;
|
||||
char *seealso;
|
||||
char *arguments;
|
||||
char *synopsis;
|
||||
char *since;
|
||||
char *description;
|
||||
char *syntax;
|
||||
char *arguments;
|
||||
char *seealso;
|
||||
|
||||
if (!(item = ast_xml_doc_item_alloc(name, type))) {
|
||||
return NULL;
|
||||
}
|
||||
item->node = node;
|
||||
|
||||
syntax = _ast_xmldoc_build_syntax(node, type, name);
|
||||
seealso = _ast_xmldoc_build_seealso(node);
|
||||
arguments = _ast_xmldoc_build_arguments(node);
|
||||
synopsis = _ast_xmldoc_build_synopsis(node);
|
||||
since = _ast_xmldoc_build_since(node);
|
||||
description = _ast_xmldoc_build_description(node);
|
||||
syntax = _ast_xmldoc_build_syntax(node, type, name);
|
||||
arguments = _ast_xmldoc_build_arguments(node);
|
||||
seealso = _ast_xmldoc_build_seealso(node);
|
||||
|
||||
if (syntax) {
|
||||
ast_str_set(&item->syntax, 0, "%s", syntax);
|
||||
}
|
||||
if (seealso) {
|
||||
ast_str_set(&item->seealso, 0, "%s", seealso);
|
||||
}
|
||||
if (arguments) {
|
||||
ast_str_set(&item->arguments, 0, "%s", arguments);
|
||||
}
|
||||
if (synopsis) {
|
||||
ast_str_set(&item->synopsis, 0, "%s", synopsis);
|
||||
}
|
||||
if (since) {
|
||||
ast_str_set(&item->since, 0, "%s", since);
|
||||
}
|
||||
if (description) {
|
||||
ast_str_set(&item->description, 0, "%s", description);
|
||||
}
|
||||
if (syntax) {
|
||||
ast_str_set(&item->syntax, 0, "%s", syntax);
|
||||
}
|
||||
if (arguments) {
|
||||
ast_str_set(&item->arguments, 0, "%s", arguments);
|
||||
}
|
||||
if (seealso) {
|
||||
ast_str_set(&item->seealso, 0, "%s", seealso);
|
||||
}
|
||||
|
||||
ast_free(syntax);
|
||||
ast_free(seealso);
|
||||
ast_free(arguments);
|
||||
ast_free(synopsis);
|
||||
ast_free(since);
|
||||
ast_free(description);
|
||||
ast_free(syntax);
|
||||
ast_free(arguments);
|
||||
ast_free(seealso);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
@@ -3834,8 +3834,10 @@ int AST_OPTIONAL_API_NAME(ast_agi_register)(struct ast_module *mod, agi_command
|
||||
if (ast_strlen_zero(cmd->summary) && ast_strlen_zero(cmd->usage)) {
|
||||
#ifdef AST_XML_DOCS
|
||||
*((char **) &cmd->summary) = ast_xmldoc_build_synopsis("agi", fullcmd, NULL);
|
||||
*((char **) &cmd->since) = ast_xmldoc_build_since("agi", fullcmd, NULL);
|
||||
*((char **) &cmd->usage) = ast_xmldoc_build_description("agi", fullcmd, NULL);
|
||||
*((char **) &cmd->syntax) = ast_xmldoc_build_syntax("agi", fullcmd, NULL);
|
||||
*((char **) &cmd->arguments) = ast_xmldoc_build_arguments("agi", fullcmd, NULL);
|
||||
*((char **) &cmd->seealso) = ast_xmldoc_build_seealso("agi", fullcmd, NULL);
|
||||
*((enum ast_doc_src *) &cmd->docsrc) = AST_XML_DOC;
|
||||
#endif
|
||||
@@ -3882,12 +3884,16 @@ int AST_OPTIONAL_API_NAME(ast_agi_unregister)(agi_command *cmd)
|
||||
#ifdef AST_XML_DOCS
|
||||
if (e->docsrc == AST_XML_DOC) {
|
||||
ast_free((char *) e->summary);
|
||||
ast_free((char *) e->since);
|
||||
ast_free((char *) e->usage);
|
||||
ast_free((char *) e->syntax);
|
||||
ast_free((char *) e->arguments);
|
||||
ast_free((char *) e->seealso);
|
||||
*((char **) &e->summary) = NULL;
|
||||
*((char **) &e->since) = NULL;
|
||||
*((char **) &e->usage) = NULL;
|
||||
*((char **) &e->syntax) = NULL;
|
||||
*((char **) &e->arguments) = NULL;
|
||||
*((char **) &e->seealso) = NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -4346,72 +4352,66 @@ static char *handle_cli_agi_show(struct ast_cli_entry *e, int cmd, struct ast_cl
|
||||
if (a->argc > e->args - 1) {
|
||||
command = find_command(a->argv + e->args, 1);
|
||||
if (command) {
|
||||
char *synopsis = NULL, *description = NULL, *syntax = NULL, *seealso = NULL;
|
||||
char info[30 + MAX_CMD_LEN]; /* '-= Info about...' */
|
||||
char infotitle[30 + MAX_CMD_LEN + AST_TERM_MAX_ESCAPE_CHARS]; /* '-= Info about...' with colors */
|
||||
char syntitle[11 + AST_TERM_MAX_ESCAPE_CHARS]; /* [Syntax]\n with colors */
|
||||
char desctitle[15 + AST_TERM_MAX_ESCAPE_CHARS]; /* [Description]\n with colors */
|
||||
char deadtitle[13 + AST_TERM_MAX_ESCAPE_CHARS]; /* [Runs Dead]\n with colors */
|
||||
char deadcontent[3 + AST_TERM_MAX_ESCAPE_CHARS]; /* 'Yes' or 'No' with colors */
|
||||
char seealsotitle[12 + AST_TERM_MAX_ESCAPE_CHARS]; /* [See Also]\n with colors */
|
||||
char stxtitle[10 + AST_TERM_MAX_ESCAPE_CHARS]; /* [Syntax]\n with colors */
|
||||
size_t synlen, desclen, seealsolen, stxlen;
|
||||
|
||||
term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, sizeof(syntitle));
|
||||
term_color(desctitle, "[Description]\n", COLOR_MAGENTA, 0, sizeof(desctitle));
|
||||
term_color(deadtitle, "[Runs Dead]\n", COLOR_MAGENTA, 0, sizeof(deadtitle));
|
||||
term_color(seealsotitle, "[See Also]\n", COLOR_MAGENTA, 0, sizeof(seealsotitle));
|
||||
term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, sizeof(stxtitle));
|
||||
term_color(deadcontent, command->dead ? "Yes" : "No", COLOR_CYAN, 0, sizeof(deadcontent));
|
||||
char *synopsis = NULL, *since = NULL, *description = NULL, *syntax = NULL, *arguments = NULL, *seealso = NULL;
|
||||
|
||||
ast_join(fullcmd, sizeof(fullcmd), a->argv + e->args);
|
||||
snprintf(info, sizeof(info), "\n -= Info about agi '%s' =- ", fullcmd);
|
||||
term_color(infotitle, info, COLOR_CYAN, 0, sizeof(infotitle));
|
||||
|
||||
#ifdef AST_XML_DOCS
|
||||
if (command->docsrc == AST_XML_DOC) {
|
||||
synopsis = ast_xmldoc_printable(S_OR(command->summary, "Not available"), 1);
|
||||
since = ast_xmldoc_printable(S_OR(command->since, "Not available"), 1);
|
||||
description = ast_xmldoc_printable(S_OR(command->usage, "Not available"), 1);
|
||||
syntax = ast_xmldoc_printable(S_OR(command->syntax, "Not available"), 1);
|
||||
arguments = ast_xmldoc_printable(S_OR(command->arguments, "Not available"), 1);
|
||||
seealso = ast_xmldoc_printable(S_OR(command->seealso, "Not available"), 1);
|
||||
if (!seealso || !description || !synopsis) {
|
||||
error = 1;
|
||||
goto return_cleanup;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
synlen = strlen(S_OR(command->summary, "Not available")) + AST_TERM_MAX_ESCAPE_CHARS;
|
||||
synopsis = ast_malloc(synlen);
|
||||
synopsis = ast_strdup(S_OR(command->summary, "Not Available"));
|
||||
since = ast_strdup(S_OR(command->since, "Not Available"));
|
||||
description = ast_strdup(S_OR(command->usage, "Not Available"));
|
||||
syntax = ast_strdup(S_OR(command->syntax, "Not Available"));
|
||||
arguments = ast_strdup(S_OR(command->arguments, "Not Available"));
|
||||
seealso = ast_strdup(S_OR(command->seealso, "Not Available"));
|
||||
}
|
||||
|
||||
desclen = strlen(S_OR(command->usage, "Not available")) + AST_TERM_MAX_ESCAPE_CHARS;
|
||||
description = ast_malloc(desclen);
|
||||
|
||||
seealsolen = strlen(S_OR(command->seealso, "Not available")) + AST_TERM_MAX_ESCAPE_CHARS;
|
||||
seealso = ast_malloc(seealsolen);
|
||||
|
||||
if (!synopsis || !description || !seealso) {
|
||||
if (!synopsis || !since || !description || !syntax || !arguments || !seealso) {
|
||||
error = 1;
|
||||
goto return_cleanup;
|
||||
}
|
||||
term_color(synopsis, S_OR(command->summary, "Not available"), COLOR_CYAN, 0, synlen);
|
||||
term_color(description, S_OR(command->usage, "Not available"), COLOR_CYAN, 0, desclen);
|
||||
term_color(seealso, S_OR(command->seealso, "Not available"), COLOR_CYAN, 0, seealsolen);
|
||||
}
|
||||
|
||||
stxlen = strlen(S_OR(command->syntax, "Not available")) + AST_TERM_MAX_ESCAPE_CHARS;
|
||||
syntax = ast_malloc(stxlen);
|
||||
if (!syntax) {
|
||||
error = 1;
|
||||
goto return_cleanup;
|
||||
}
|
||||
term_color(syntax, S_OR(command->syntax, "Not available"), COLOR_CYAN, 0, stxlen);
|
||||
ast_cli(a->fd, "\n"
|
||||
"%s -= Info about AGI '%s' =- %s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n"
|
||||
COLORIZE_FMT "\n"
|
||||
"%s\n\n",
|
||||
ast_term_color(COLOR_MAGENTA, 0), fullcmd, ast_term_reset(),
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Since]"), since,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"), syntax,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"), arguments,
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[Runs Dead]"), command->dead ? "Yes" : "No",
|
||||
COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso
|
||||
);
|
||||
|
||||
ast_cli(a->fd, "%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n", infotitle, stxtitle, syntax,
|
||||
desctitle, description, syntitle, synopsis, deadtitle, deadcontent,
|
||||
seealsotitle, seealso);
|
||||
return_cleanup:
|
||||
ast_free(synopsis);
|
||||
ast_free(since);
|
||||
ast_free(description);
|
||||
ast_free(syntax);
|
||||
ast_free(arguments);
|
||||
ast_free(seealso);
|
||||
} else {
|
||||
if (find_command(a->argv + e->args, -1)) {
|
||||
|
@@ -1,11 +1,14 @@
|
||||
{{#api_declaration}}
|
||||
# {{name_title}}
|
||||
{{#since}}
|
||||
## Since: {{since}}
|
||||
{{/since}}
|
||||
|
||||
| Method | Path (Parameters are case-sensitive) | Return Model | Summary |
|
||||
|:------ |:------------------------------------ |:------------ |:------- |
|
||||
| Method | Path (Parameters are case-sensitive) | Return Model | Summary | Since |
|
||||
|:------ |:------------------------------------ |:------------ |:------- |:----- |
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
| {{http_method}} | [{{wiki_path}}](#{{nickname_lc}}) | {{#response_class}}{{#is_primitive}}{{name}}{{/is_primitive}}{{^is_primitive}}[{{wiki_name}}]({{wiki_prefix}}Asterisk_REST_Data_Models#{{lc_singular_name}}){{/is_primitive}}{{/response_class}} | {{{summary}}} |
|
||||
| {{http_method}} | [{{wiki_path}}](#{{nickname_lc}}) | {{#response_class}}{{#is_primitive}}{{name}}{{/is_primitive}}{{^is_primitive}}[{{wiki_name}}]({{wiki_prefix}}Asterisk_REST_Data_Models#{{lc_singular_name}}){{/is_primitive}}{{/response_class}} | {{{summary}}} | {{since}} |
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{#apis}}
|
||||
@@ -14,6 +17,9 @@
|
||||
---
|
||||
[//]: # (anchor:{{nickname_lc}})
|
||||
## {{nickname}}
|
||||
{{#since}}
|
||||
### Since: {{since}}
|
||||
{{/since}}
|
||||
### {{http_method}} {{wiki_path}}
|
||||
{{{wiki_summary}}}{{#wiki_notes}} {{{wiki_notes}}}{{/wiki_notes}}
|
||||
{{#has_path_parameters}}
|
||||
|
@@ -373,6 +373,7 @@ class Operation(Stringify):
|
||||
self.summary = None
|
||||
self.notes = None
|
||||
self.error_responses = []
|
||||
self.since = []
|
||||
|
||||
def load(self, op_json, processor, context):
|
||||
context = context.next_stack(op_json, 'nickname')
|
||||
@@ -383,6 +384,8 @@ class Operation(Stringify):
|
||||
response_class = op_json.get('responseClass')
|
||||
self.response_class = response_class and SwaggerType().load(
|
||||
response_class, processor, context)
|
||||
since = op_json.get('since') or []
|
||||
self.since = ", ".join(since)
|
||||
|
||||
# Specifying WebSocket URL's is our own extension
|
||||
self.is_websocket = op_json.get('upgrade') == 'websocket'
|
||||
@@ -611,6 +614,7 @@ class ApiDeclaration(Stringify):
|
||||
self.api_version = None
|
||||
self.base_path = None
|
||||
self.resource_path = None
|
||||
self.since = []
|
||||
self.apis = []
|
||||
self.models = []
|
||||
|
||||
@@ -658,6 +662,8 @@ class ApiDeclaration(Stringify):
|
||||
self.base_path = api_decl_json.get('basePath')
|
||||
self.resource_path = api_decl_json.get('resourcePath')
|
||||
self.requires_modules = api_decl_json.get('requiresModules') or []
|
||||
since = api_decl_json.get('since') or []
|
||||
self.since = ", ".join(since)
|
||||
api_json = api_decl_json.get('apis') or []
|
||||
self.apis = [
|
||||
Api().load(j, processor, context) for j in api_json]
|
||||
|
Reference in New Issue
Block a user