Fri Nov 12 12:11:10 2010

Asterisk developer's documentation


xmldoc.c File Reference

XML Documentation API. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include "asterisk/linkedlists.h"
#include "asterisk/strings.h"
#include "asterisk/config.h"
#include "asterisk/term.h"
#include "asterisk/xmldoc.h"
Include dependency graph for xmldoc.c:

Go to the source code of this file.

Data Structures

struct  documentation_tree
 XML documentation tree. More...
struct  strcolorized_tags
struct  strspecial_tags
struct  strsyntaxtype
 Mapping between type of node and type of syntax to generate. More...
struct  xmldoc_tree
 Container of documentation trees. More...

Defines

#define GOTONEXT(__rev, __a)   (__rev ? ast_xml_node_get_prev(__a) : ast_xml_node_get_next(__a))
#define ISLAST(__rev, __a)   (__rev == 1 ? (ast_xml_node_get_prev(__a) ? 0 : 1) : (ast_xml_node_get_next(__a) ? 0 : 1))
#define MP(__a)   ((multiple ? __a : ""))

Enumerations

enum  syntaxtype { FUNCTION_SYNTAX, COMMAND_SYNTAX }
 

Types of syntax that we are able to generate.

More...

Functions

char * ast_xmldoc_build_arguments (const char *type, const char *name)
 Generate the [arguments] tag based on type of node ('application', 'function' or 'agi') and name.
char * ast_xmldoc_build_description (const char *type, const char *name)
 Generate description documentation from XML.
char * ast_xmldoc_build_seealso (const char *type, const char *name)
 Parse the <see-also> node content.
char * ast_xmldoc_build_synopsis (const char *type, const char *name)
 Generate synopsis documentation from XML.
char * ast_xmldoc_build_syntax (const char *type, const char *name)
 Get the syntax for a specified application or function.
int ast_xmldoc_load_documentation (void)
 Load XML documentation. Provided by xmldoc.c.
char * ast_xmldoc_printable (const char *bwinput, int withcolors)
 Colorize and put delimiters (instead of tags) to the xmldoc output.
static char * xmldoc_build_field (const char *type, const char *name, const char *var, int raw)
 Get the content of a field (synopsis, description, etc) from an asterisk document tree.
static int xmldoc_foundspace_backward (const char *text, int currentpos, int maxdiff)
static struct ast_strxmldoc_get_formatted (struct ast_xml_node *node, int raw_output, int raw_wrap)
static struct ast_xml_node * xmldoc_get_node (const char *type, const char *name, const char *language)
static char * xmldoc_get_syntax_cmd (struct ast_xml_node *fixnode, const char *name, int printname)
static char * xmldoc_get_syntax_fun (struct ast_xml_node *rootnode, const char *rootname, const char *childname, int printparenthesis, int printrootname)
static enum syntaxtype xmldoc_get_syntax_type (const char *type)
static int xmldoc_has_inside (struct ast_xml_node *fixnode, const char *what)
static int xmldoc_has_nodes (struct ast_xml_node *fixnode)
static int xmldoc_has_specialtags (struct ast_xml_node *fixnode)
static int xmldoc_parse_argument (struct ast_xml_node *fixnode, int insideparameter, const char *paramtabs, const char *tabs, struct ast_str **buffer)
static char * xmldoc_parse_cmd_enumlist (struct ast_xml_node *fixnode)
static int xmldoc_parse_enum (struct ast_xml_node *fixnode, const char *tabs, struct ast_str **buffer)
static int xmldoc_parse_enumlist (struct ast_xml_node *fixnode, const char *tabs, struct ast_str **buffer)
static int xmldoc_parse_option (struct ast_xml_node *fixnode, const char *tabs, struct ast_str **buffer)
static void xmldoc_parse_optionlist (struct ast_xml_node *fixnode, const char *tabs, struct ast_str **buffer)
static int xmldoc_parse_para (struct ast_xml_node *node, const char *tabs, const char *posttabs, struct ast_str **buffer)
static void xmldoc_parse_parameter (struct ast_xml_node *fixnode, const char *tabs, struct ast_str **buffer)
static int xmldoc_parse_specialtags (struct ast_xml_node *fixnode, const char *tabs, const char *posttabs, struct ast_str **buffer)
static int xmldoc_parse_variable (struct ast_xml_node *node, const char *tabs, struct ast_str **buffer)
static int xmldoc_parse_variablelist (struct ast_xml_node *node, const char *tabs, struct ast_str **buffer)
static int xmldoc_postbrlen (const char *postbr)
static void xmldoc_reverse_helper (int reverse, int *len, char **syntax, const char *fmt,...)
static void xmldoc_setpostbr (char *postbr, size_t len, const char *text)
static void xmldoc_string_cleanup (const char *text, struct ast_str **output, int lastspaces)
static char * xmldoc_string_wrap (const char *text, int columns, int maxdiff)
static void xmldoc_unload_documentation (void)
 Close and unload XML documentation.
static int xmldoc_wait_nextspace (const char *text, int currentpos, int maxdiff)

Variables

static struct strcolorized_tags colorized_tags []
static const char default_documentation_language [] = "en_US"
 Default documentation language.
static char documentation_language [6]
 XML documentation language.
static struct strspecial_tags special_tags []
struct strsyntaxtype stxtype []
 Mapping between type of node and type of syntax to generate.
static const int xmldoc_max_diff = 5
 This is a value that we will use to let the wrapping mechanism move the cursor backward and forward xmldoc_max_diff positions before cutting the middle of a word, trying to find a space or a
.
static const int xmldoc_text_columns = 74
 Number of columns to print when showing the XML documentation with a 'core show application/function *' CLI command. Used in text wrapping.

Detailed Description

XML Documentation API.

Author:
Eliel C. Sardanons (LU1ALY) <eliels@gmail.com>

Definition in file xmldoc.c.


Define Documentation

#define GOTONEXT ( __rev,
__a   )     (__rev ? ast_xml_node_get_prev(__a) : ast_xml_node_get_next(__a))

Referenced by xmldoc_get_syntax_fun().

#define ISLAST ( __rev,
__a   )     (__rev == 1 ? (ast_xml_node_get_prev(__a) ? 0 : 1) : (ast_xml_node_get_next(__a) ? 0 : 1))

Referenced by xmldoc_get_syntax_fun().

#define MP ( __a   )     ((multiple ? __a : ""))

Referenced by xmldoc_get_syntax_fun().


Enumeration Type Documentation

enum syntaxtype

Types of syntax that we are able to generate.

Enumerator:
FUNCTION_SYNTAX 
COMMAND_SYNTAX 

Definition at line 988 of file xmldoc.c.

00988                 {
00989    FUNCTION_SYNTAX,
00990    COMMAND_SYNTAX
00991 };


Function Documentation

char* ast_xmldoc_build_arguments ( const char *  type,
const char *  name 
)

Generate the [arguments] tag based on type of node ('application', 'function' or 'agi') and name.

Parameters:
type 'application', 'function' or 'agi' ?
name Name of the application or function to build the 'arguments' tag.
Return values:
NULL on error.
Output buffer with the [arguments] tag content.

Definition at line 1611 of file xmldoc.c.

References ast_free, ast_str_buffer(), ast_str_create(), ast_str_strlen(), ast_str_truncate(), ast_strdup, ast_strlen_zero(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), buf, xmldoc_get_node(), and xmldoc_parse_parameter().

Referenced by acf_retrieve_docs(), and ast_register_application2().

01612 {
01613    struct ast_xml_node *node;
01614    struct ast_str *ret = ast_str_create(128);
01615    char *retstr = NULL;
01616 
01617    if (ast_strlen_zero(type) || ast_strlen_zero(name)) {
01618       return NULL;
01619    }
01620 
01621    node = xmldoc_get_node(type, name, documentation_language);
01622 
01623    if (!node || !ast_xml_node_get_children(node)) {
01624       return NULL;
01625    }
01626 
01627    /* Find the syntax field. */
01628    for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
01629       if (!strcasecmp(ast_xml_node_get_name(node), "syntax")) {
01630          break;
01631       }
01632    }
01633 
01634    if (!node || !ast_xml_node_get_children(node)) {
01635       /* We couldn't find the syntax node. */
01636       return NULL;
01637    }
01638 
01639    for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
01640       xmldoc_parse_parameter(node, "", &ret);
01641    }
01642 
01643    if (ast_str_strlen(ret) > 0) {
01644       /* remove last '\n' */
01645       char *buf = ast_str_buffer(ret);
01646       if (buf[ast_str_strlen(ret) - 1] == '\n') {
01647          ast_str_truncate(ret, -1);
01648       }
01649       retstr = ast_strdup(ast_str_buffer(ret));
01650    }
01651    ast_free(ret);
01652 
01653    return retstr;
01654 }

char* ast_xmldoc_build_description ( const char *  type,
const char *  name 
)

Generate description documentation from XML.

Parameters:
type The source of documentation (application, function, etc).
name The name of the application, function, etc.
Return values:
NULL on error.
A malloc'ed string with the formatted description.

Definition at line 1745 of file xmldoc.c.

References xmldoc_build_field().

Referenced by acf_retrieve_docs(), ast_agi_register(), and ast_register_application2().

01746 {
01747    return xmldoc_build_field(type, name, "description", 0);
01748 }

char* ast_xmldoc_build_seealso ( const char *  type,
const char *  name 
)

Parse the <see-also> node content.

Parameters:
type 'application', 'function' or 'agi'.
name Application or functions name.
Return values:
NULL on error.
Content of the see-also node.

Definition at line 1318 of file xmldoc.c.

References ast_free, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_strdup, ast_strlen_zero(), ast_xml_free_attr(), ast_xml_free_text(), ast_xml_get_attribute(), ast_xml_get_text(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), first, and xmldoc_get_node().

Referenced by acf_retrieve_docs(), ast_agi_register(), and ast_register_application2().

01319 {
01320    struct ast_str *outputstr;
01321    char *output;
01322    struct ast_xml_node *node;
01323    const char *typename;
01324    const char *content;
01325    int first = 1;
01326 
01327    if (ast_strlen_zero(type) || ast_strlen_zero(name)) {
01328       return NULL;
01329    }
01330 
01331    /* get the application/function root node. */
01332    node = xmldoc_get_node(type, name, documentation_language);
01333    if (!node || !ast_xml_node_get_children(node)) {
01334       return NULL;
01335    }
01336 
01337    /* Find the <see-also> node. */
01338    for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
01339       if (!strcasecmp(ast_xml_node_get_name(node), "see-also")) {
01340          break;
01341       }
01342    }
01343 
01344    if (!node || !ast_xml_node_get_children(node)) {
01345       /* we couldnt find a <see-also> node. */
01346       return NULL;
01347    }
01348 
01349    /* prepare the output string. */
01350    outputstr = ast_str_create(128);
01351    if (!outputstr) {
01352       return NULL;
01353    }
01354 
01355    /* get into the <see-also> node. */
01356    for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
01357       if (strcasecmp(ast_xml_node_get_name(node), "ref")) {
01358          continue;
01359       }
01360 
01361       /* parse the <ref> node. 'type' attribute is required. */
01362       typename = ast_xml_get_attribute(node, "type");
01363       if (!typename) {
01364          continue;
01365       }
01366       content = ast_xml_get_text(node);
01367       if (!content) {
01368          ast_xml_free_attr(typename);
01369          continue;
01370       }
01371       if (!strcasecmp(typename, "application")) {
01372          ast_str_append(&outputstr, 0, "%s%s()",   (first ? "" : ", "), content);
01373       } else if (!strcasecmp(typename, "function")) {
01374          ast_str_append(&outputstr, 0, "%s%s", (first ? "" : ", "), content);
01375       } else if (!strcasecmp(typename, "astcli")) {
01376          ast_str_append(&outputstr, 0, "%s<astcli>%s</astcli>", (first ? "" : ", "), content);
01377       } else {
01378          ast_str_append(&outputstr, 0, "%s%s", (first ? "" : ", "), content);
01379       }
01380       first = 0;
01381       ast_xml_free_text(content);
01382       ast_xml_free_attr(typename);
01383    }
01384 
01385    output = ast_strdup(ast_str_buffer(outputstr));
01386    ast_free(outputstr);
01387 
01388    return output;
01389 }

char* ast_xmldoc_build_synopsis ( const char *  type,
const char *  name 
)

Generate synopsis documentation from XML.

Parameters:
type The source of documentation (application, function, etc).
name The name of the application, function, etc.
Return values:
NULL on error.
A malloc'ed string with the synopsis.

Definition at line 1740 of file xmldoc.c.

References xmldoc_build_field().

Referenced by acf_retrieve_docs(), ast_agi_register(), and ast_register_application2().

01741 {
01742    return xmldoc_build_field(type, name, "synopsis", 1);
01743 }

char* ast_xmldoc_build_syntax ( const char *  type,
const char *  name 
)

Get the syntax for a specified application or function.

Parameters:
type Application, Function or AGI ?
name Name of the application or function.
Return values:
NULL on error.
The generated syntax in a ast_malloc'ed string.

Definition at line 1020 of file xmldoc.c.

References ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), FUNCTION_SYNTAX, xmldoc_get_node(), xmldoc_get_syntax_cmd(), xmldoc_get_syntax_fun(), and xmldoc_get_syntax_type().

Referenced by acf_retrieve_docs(), ast_agi_register(), and ast_register_application2().

01021 {
01022    struct ast_xml_node *node;
01023    char *syntax = NULL;
01024 
01025    node = xmldoc_get_node(type, name, documentation_language);
01026    if (!node) {
01027       return NULL;
01028    }
01029 
01030    for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
01031       if (!strcasecmp(ast_xml_node_get_name(node), "syntax")) {
01032          break;
01033       }
01034    }
01035 
01036    if (node) {
01037       if (xmldoc_get_syntax_type(type) == FUNCTION_SYNTAX) {
01038          syntax = xmldoc_get_syntax_fun(node, name, "parameter", 1, 1);
01039       } else {
01040          syntax = xmldoc_get_syntax_cmd(node, name, 1);
01041       }
01042    }
01043    return syntax;
01044 }

int ast_xmldoc_load_documentation ( void   ) 

Load XML documentation. Provided by xmldoc.c.

Return values:
1 on error.
0 on success.

Definition at line 1765 of file xmldoc.c.

References ast_asprintf, ast_calloc, ast_config_AST_DATA_DIR, ast_config_destroy(), ast_config_load2(), ast_free, ast_log(), ast_register_atexit(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_strlen_zero(), ast_variable_browse(), ast_xml_close(), ast_xml_get_root(), ast_xml_init(), ast_xml_node_get_name(), ast_xml_open(), CONFIG_STATUS_FILEINVALID, documentation_tree::doc, documentation_tree::entry, documentation_tree::filename, GLOB_ABORTED, LOG_ERROR, LOG_WARNING, MY_GLOB_FLAGS, ast_variable::name, ast_variable::next, ast_variable::value, var, and xmldoc_unload_documentation().

Referenced by main().

01766 {
01767    struct ast_xml_node *root_node;
01768    struct ast_xml_doc *tmpdoc;
01769    struct documentation_tree *doc_tree;
01770    char *xmlpattern;
01771    struct ast_config *cfg = NULL;
01772    struct ast_variable *var = NULL;
01773    struct ast_flags cnfflags = { 0 };
01774    int globret, i, dup, duplicate;
01775    glob_t globbuf;
01776 
01777    /* setup default XML documentation language */
01778    snprintf(documentation_language, sizeof(documentation_language), default_documentation_language);
01779 
01780    if ((cfg = ast_config_load2("asterisk.conf", "" /* core can't reload */, cnfflags)) && cfg != CONFIG_STATUS_FILEINVALID) {
01781       for (var = ast_variable_browse(cfg, "options"); var; var = var->next) {
01782          if (!strcasecmp(var->name, "documentation_language")) {
01783             if (!ast_strlen_zero(var->value)) {
01784                snprintf(documentation_language, sizeof(documentation_language), "%s", var->value);
01785             }
01786          }
01787       }
01788       ast_config_destroy(cfg);
01789    }
01790 
01791    /* initialize the XML library. */
01792    ast_xml_init();
01793 
01794    /* register function to be run when asterisk finish. */
01795    ast_register_atexit(xmldoc_unload_documentation);
01796 
01797    /* Get every *-LANG.xml file inside $(ASTDATADIR)/documentation */
01798    ast_asprintf(&xmlpattern, "%s/documentation{/thirdparty/,/}*-{%s,%.2s_??,%s}.xml", ast_config_AST_DATA_DIR,
01799          documentation_language, documentation_language, default_documentation_language);
01800    globbuf.gl_offs = 0;    /* initialize it to silence gcc */
01801    globret = glob(xmlpattern, MY_GLOB_FLAGS, NULL, &globbuf);
01802    if (globret == GLOB_NOSPACE) {
01803       ast_log(LOG_WARNING, "Glob Expansion of pattern '%s' failed: Not enough memory\n", xmlpattern);
01804       ast_free(xmlpattern);
01805       return 1;
01806    } else if (globret  == GLOB_ABORTED) {
01807       ast_log(LOG_WARNING, "Glob Expansion of pattern '%s' failed: Read error\n", xmlpattern);
01808       ast_free(xmlpattern);
01809       return 1;
01810    }
01811    ast_free(xmlpattern);
01812 
01813    AST_RWLIST_WRLOCK(&xmldoc_tree);
01814    /* loop over expanded files */
01815    for (i = 0; i < globbuf.gl_pathc; i++) {
01816       /* check for duplicates (if we already [try to] open the same file. */
01817       duplicate = 0;
01818       for (dup = 0; dup < i; dup++) {
01819          if (!strcmp(globbuf.gl_pathv[i], globbuf.gl_pathv[dup])) {
01820             duplicate = 1;
01821             break;
01822          }
01823       }
01824       if (duplicate) {
01825          continue;
01826       }
01827       tmpdoc = NULL;
01828       tmpdoc = ast_xml_open(globbuf.gl_pathv[i]);
01829       if (!tmpdoc) {
01830          ast_log(LOG_ERROR, "Could not open XML documentation at '%s'\n", globbuf.gl_pathv[i]);
01831          continue;
01832       }
01833       /* Get doc root node and check if it starts with '<docs>' */
01834       root_node = ast_xml_get_root(tmpdoc);
01835       if (!root_node) {
01836          ast_log(LOG_ERROR, "Error getting documentation root node");
01837          ast_xml_close(tmpdoc);
01838          continue;
01839       }
01840       /* Check root node name for malformed xmls. */
01841       if (strcmp(ast_xml_node_get_name(root_node), "docs")) {
01842          ast_log(LOG_ERROR, "Documentation file is not well formed!\n");
01843          ast_xml_close(tmpdoc);
01844          continue;
01845       }
01846       doc_tree = ast_calloc(1, sizeof(*doc_tree));
01847       if (!doc_tree) {
01848          ast_log(LOG_ERROR, "Unable to allocate documentation_tree structure!\n");
01849          ast_xml_close(tmpdoc);
01850          continue;
01851       }
01852       doc_tree->doc = tmpdoc;
01853       doc_tree->filename = ast_strdup(globbuf.gl_pathv[i]);
01854       AST_RWLIST_INSERT_TAIL(&xmldoc_tree, doc_tree, entry);
01855    }
01856    AST_RWLIST_UNLOCK(&xmldoc_tree);
01857 
01858    globfree(&globbuf);
01859 
01860    return 0;
01861 }

char* ast_xmldoc_printable ( const char *  bwinput,
int  withcolors 
)

Colorize and put delimiters (instead of tags) to the xmldoc output.

Parameters:
bwinput Not colorized input with tags.
withcolors Result output with colors.
Return values:
NULL on error.
New malloced buffer colorized and with delimiters.

Definition at line 309 of file xmldoc.c.

References ARRAY_LEN, ast_copy_string(), ast_free, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_term_color_code(), buf, COLOR_CYAN, colorized_tags, len(), term_end(), and xmldoc_string_wrap().

Referenced by handle_cli_agi_show(), handle_show_function(), print_app_docs(), and write_htmldump().

00310 {
00311    struct ast_str *colorized;
00312    char *wrapped = NULL;
00313    int i, c, len, colorsection;
00314    char *tmp;
00315    size_t bwinputlen;
00316    static const int base_fg = COLOR_CYAN;
00317 
00318    if (!bwinput) {
00319       return NULL;
00320    }
00321 
00322    bwinputlen = strlen(bwinput);
00323 
00324    if (!(colorized = ast_str_create(256))) {
00325       return NULL;
00326    }
00327 
00328    if (withcolors) {
00329       ast_term_color_code(&colorized, base_fg, 0);
00330       if (!colorized) {
00331          return NULL;
00332       }
00333    }
00334 
00335    for (i = 0; i < bwinputlen; i++) {
00336       colorsection = 0;
00337       /* Check if we are at the beginning of a tag to be colorized. */
00338       for (c = 0; c < ARRAY_LEN(colorized_tags); c++) {
00339          if (strncasecmp(bwinput + i, colorized_tags[c].inittag, strlen(colorized_tags[c].inittag))) {
00340             continue;
00341          }
00342 
00343          if (!(tmp = strcasestr(bwinput + i + strlen(colorized_tags[c].inittag), colorized_tags[c].endtag))) {
00344             continue;
00345          }
00346 
00347          len = tmp - (bwinput + i + strlen(colorized_tags[c].inittag));
00348 
00349          /* Setup color */
00350          if (withcolors) {
00351             ast_term_color_code(&colorized, colorized_tags[c].colorfg, 0);
00352             if (!colorized) {
00353                return NULL;
00354             }
00355          }
00356 
00357          /* copy initial string replace */
00358          ast_str_append(&colorized, 0, "%s", colorized_tags[c].init);
00359          if (!colorized) {
00360             return NULL;
00361          }
00362          {
00363             char buf[len + 1];
00364             ast_copy_string(buf, bwinput + i + strlen(colorized_tags[c].inittag), sizeof(buf));
00365             ast_str_append(&colorized, 0, "%s", buf);
00366          }
00367          if (!colorized) {
00368             return NULL;
00369          }
00370 
00371          /* copy the ending string replace */
00372          ast_str_append(&colorized, 0, "%s", colorized_tags[c].end);
00373          if (!colorized) {
00374             return NULL;
00375          }
00376 
00377          /* Continue with the last color. */
00378          if (withcolors) {
00379             ast_term_color_code(&colorized, base_fg, 0);
00380             if (!colorized) {
00381                return NULL;
00382             }
00383          }
00384 
00385          i += len + strlen(colorized_tags[c].endtag) + strlen(colorized_tags[c].inittag) - 1;
00386          colorsection = 1;
00387          break;
00388       }
00389 
00390       if (!colorsection) {
00391          ast_str_append(&colorized, 0, "%c", bwinput[i]);
00392          if (!colorized) {
00393             return NULL;
00394          }
00395       }
00396    }
00397 
00398    if (withcolors) {
00399       ast_str_append(&colorized, 0, "%s", term_end());
00400       if (!colorized) {
00401          return NULL;
00402       }
00403    }
00404 
00405    /* Wrap the text, notice that string wrap will avoid cutting an ESC sequence. */
00406    wrapped = xmldoc_string_wrap(ast_str_buffer(colorized), xmldoc_text_columns, xmldoc_max_diff);
00407 
00408    ast_free(colorized);
00409 
00410    return wrapped;
00411 }

static char* xmldoc_build_field ( const char *  type,
const char *  name,
const char *  var,
int  raw 
) [static]

Get the content of a field (synopsis, description, etc) from an asterisk document tree.

Parameters:
type Type of element (application, function, ...).
name Name of element (Dial, Echo, Playback, ...).
var Name of field to return (synopsis, description, etc).
raw Field only contains text, no other elements inside it.
Return values:
NULL On error.
Field text content on success.

Definition at line 1706 of file xmldoc.c.

References ast_free, ast_log(), ast_str_buffer(), ast_str_strlen(), ast_strdup, ast_strlen_zero(), ast_xml_find_element(), ast_xml_node_get_children(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, xmldoc_get_formatted(), and xmldoc_get_node().

Referenced by ast_xmldoc_build_description(), and ast_xmldoc_build_synopsis().

01707 {
01708    struct ast_xml_node *node;
01709    char *ret = NULL;
01710    struct ast_str *formatted;
01711 
01712    if (ast_strlen_zero(type) || ast_strlen_zero(name)) {
01713       ast_log(LOG_ERROR, "Tried to look in XML tree with faulty values.\n");
01714       return ret;
01715    }
01716 
01717    node = xmldoc_get_node(type, name, documentation_language);
01718 
01719    if (!node) {
01720       ast_log(LOG_WARNING, "Counldn't find %s %s in XML documentation\n", type, name);
01721       return ret;
01722    }
01723 
01724    node = ast_xml_find_element(ast_xml_node_get_children(node), var, NULL, NULL);
01725 
01726    if (!node || !ast_xml_node_get_children(node)) {
01727       ast_log(LOG_DEBUG, "Cannot find variable '%s' in tree '%s'\n", name, var);
01728       return ret;
01729    }
01730 
01731    formatted = xmldoc_get_formatted(node, raw, raw);
01732    if (ast_str_strlen(formatted) > 0) {
01733       ret = ast_strdup(ast_str_buffer(formatted));
01734    }
01735    ast_free(formatted);
01736 
01737    return ret;
01738 }

static int xmldoc_foundspace_backward ( const char *  text,
int  currentpos,
int  maxdiff 
) [static]

Definition at line 203 of file xmldoc.c.

Referenced by xmldoc_string_wrap().

00204 {
00205    int i;
00206 
00207    for (i = currentpos; i > 0; i--) {
00208       if (text[i] == ' ' || text[i] == '\n') {
00209          return (currentpos - i);
00210       } else if (text[i] == 'm' && (text[i - 1] >= '0' || text[i - 1] <= '9')) {
00211          /* give up, we found the end of a possible ESC sequence. */
00212          return 0;
00213       } else if (currentpos - i > maxdiff) {
00214          /* give up, we can't move anymore. */
00215          return 0;
00216       }
00217    }
00218 
00219    /* we found the beginning of the text */
00220 
00221    return 0;
00222 }

static struct ast_str* xmldoc_get_formatted ( struct ast_xml_node *  node,
int  raw_output,
int  raw_wrap 
) [static, read]

Definition at line 1664 of file xmldoc.c.

References ast_skip_blanks(), ast_str_buffer(), ast_str_create(), ast_str_strlen(), ast_str_truncate(), ast_xml_free_text(), ast_xml_get_text(), ast_xml_node_get_children(), ast_xml_node_get_next(), xmldoc_parse_enumlist(), xmldoc_parse_para(), xmldoc_parse_specialtags(), xmldoc_parse_variablelist(), and xmldoc_string_cleanup().

Referenced by xmldoc_build_field().

01665 {
01666    struct ast_xml_node *tmp;
01667    const char *notcleanret, *tmpstr;
01668    struct ast_str *ret = ast_str_create(128);
01669 
01670    if (raw_output) {
01671       notcleanret = ast_xml_get_text(node);
01672       tmpstr = notcleanret;
01673       xmldoc_string_cleanup(ast_skip_blanks(notcleanret), &ret, 0);
01674       ast_xml_free_text(tmpstr);
01675    } else {
01676       for (tmp = ast_xml_node_get_children(node); tmp; tmp = ast_xml_node_get_next(tmp)) {
01677          /* if found, parse a <para> element. */
01678          if (xmldoc_parse_para(tmp, "", "\n", &ret)) {
01679             continue;
01680          } else if (xmldoc_parse_specialtags(tmp, "", "\n", &ret)) {
01681             continue;
01682          }
01683          /* if found, parse a <variablelist> element. */
01684          xmldoc_parse_variablelist(tmp, "", &ret);
01685          xmldoc_parse_enumlist(tmp, "    ", &ret);
01686       }
01687       /* remove last '\n' */
01688       /* XXX Don't modify ast_str internals manually */
01689       tmpstr = ast_str_buffer(ret);
01690       if (tmpstr[ast_str_strlen(ret) - 1] == '\n') {
01691          ast_str_truncate(ret, -1);
01692       }
01693    }
01694    return ret;
01695 }

static struct ast_xml_node* xmldoc_get_node ( const char *  type,
const char *  name,
const char *  language 
) [static, read]

Definition at line 465 of file xmldoc.c.

References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_xml_find_element(), ast_xml_free_attr(), ast_xml_get_attribute(), ast_xml_get_root(), ast_xml_node_get_children(), documentation_tree::doc, and documentation_tree::entry.

Referenced by ast_xmldoc_build_arguments(), ast_xmldoc_build_seealso(), ast_xmldoc_build_syntax(), and xmldoc_build_field().

00466 {
00467    struct ast_xml_node *node = NULL;
00468    struct documentation_tree *doctree;
00469    const char *lang;
00470 
00471    AST_RWLIST_RDLOCK(&xmldoc_tree);
00472    AST_LIST_TRAVERSE(&xmldoc_tree, doctree, entry) {
00473       /* the core xml documents have priority over thirdparty document. */
00474       node = ast_xml_get_root(doctree->doc);
00475       while ((node = ast_xml_find_element(node, type, "name", name))) {
00476          /* Check language */
00477          lang = ast_xml_get_attribute(node, "language");
00478          if (lang && !strcmp(lang, language)) {
00479             ast_xml_free_attr(lang);
00480             break;
00481          } else if (lang) {
00482             ast_xml_free_attr(lang);
00483          }
00484       }
00485 
00486       if (node && ast_xml_node_get_children(node)) {
00487          break;
00488       }
00489 
00490       /* We didn't find the application documentation for the specified language,
00491       so, try to load documentation for any language */
00492       node = ast_xml_get_root(doctree->doc);
00493       if (ast_xml_node_get_children(node)) {
00494          if ((node = ast_xml_find_element(ast_xml_node_get_children(node), type, "name", name))) {
00495             break;
00496          }
00497       }
00498    }
00499    AST_RWLIST_UNLOCK(&xmldoc_tree);
00500 
00501    return node;
00502 }

static char * xmldoc_get_syntax_cmd ( struct ast_xml_node *  fixnode,
const char *  name,
int  printname 
) [static]

Definition at line 898 of file xmldoc.c.

References ast_free, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_strdup, ast_true(), ast_xml_free_attr(), ast_xml_get_attribute(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), first, xmldoc_has_inside(), and xmldoc_parse_cmd_enumlist().

Referenced by ast_xmldoc_build_syntax(), and xmldoc_parse_cmd_enumlist().

00899 {
00900    struct ast_str *syntax;
00901    struct ast_xml_node *tmpnode, *node = fixnode;
00902    char *ret, *paramname;
00903    const char *paramtype, *attrname, *literal;
00904    int required, isenum, first = 1, isliteral;
00905 
00906    syntax = ast_str_create(128);
00907    if (!syntax) {
00908       /* at least try to return something... */
00909       return ast_strdup(name);
00910    }
00911 
00912    /* append name to output string. */
00913    if (printname) {
00914       ast_str_append(&syntax, 0, "%s", name);
00915       first = 0;
00916    }
00917 
00918    for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
00919       if (strcasecmp(ast_xml_node_get_name(node), "parameter")) {
00920          continue;
00921       }
00922 
00923       if (xmldoc_has_inside(node, "parameter")) {
00924          /* is this a recursive parameter. */
00925          paramname = xmldoc_get_syntax_cmd(node, "", 0);
00926          isenum = 1;
00927       } else if (!xmldoc_has_inside(node, "enumlist")) {
00928          /* this is a simple parameter. */
00929          attrname = ast_xml_get_attribute(node, "name");
00930          if (!attrname) {
00931             /* ignore this bogus parameter and continue. */
00932             continue;
00933          }
00934          paramname = ast_strdup(attrname);
00935          ast_xml_free_attr(attrname);
00936          isenum = 0;
00937       } else {
00938          /* parse enumlist (note that this is a special enumlist
00939          that is used to describe a syntax like {<param1>|<param2>|...} */
00940          for (tmpnode = ast_xml_node_get_children(node); tmpnode; tmpnode = ast_xml_node_get_next(tmpnode)) {
00941             if (!strcasecmp(ast_xml_node_get_name(tmpnode), "enumlist")) {
00942                break;
00943             }
00944          }
00945          paramname = xmldoc_parse_cmd_enumlist(tmpnode);
00946          isenum = 1;
00947       }
00948 
00949       /* Is this parameter required? */
00950       required = 0;
00951       paramtype = ast_xml_get_attribute(node, "required");
00952       if (paramtype) {
00953          required = ast_true(paramtype);
00954          ast_xml_free_attr(paramtype);
00955       }
00956 
00957       /* Is this a replaceable value or a fixed parameter value? */
00958       isliteral = 0;
00959       literal = ast_xml_get_attribute(node, "literal");
00960       if (literal) {
00961          isliteral = ast_true(literal);
00962          ast_xml_free_attr(literal);
00963       }
00964 
00965       /* if required="false" print with [...].
00966        * if literal="true" or is enum print without <..>.
00967        * if not first print a space at the beginning.
00968        */
00969       ast_str_append(&syntax, 0, "%s%s%s%s%s%s",
00970             (first ? "" : " "),
00971             (required ? "" : "["),
00972             (isenum || isliteral ? "" : "<"),
00973             paramname,
00974             (isenum || isliteral ? "" : ">"),
00975             (required ? "" : "]"));
00976       first = 0;
00977       ast_free(paramname);
00978    }
00979 
00980    /* return a common string. */
00981    ret = ast_strdup(ast_str_buffer(syntax));
00982    ast_free(syntax);
00983 
00984    return ret;
00985 }

static char* xmldoc_get_syntax_fun ( struct ast_xml_node *  rootnode,
const char *  rootname,
const char *  childname,
int  printparenthesis,
int  printrootname 
) [static]

Definition at line 620 of file xmldoc.c.

References ast_asprintf, ast_free, ast_log(), ast_strdup, ast_strlen_zero(), ast_true(), ast_xml_free_attr(), ast_xml_get_attribute(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), GOTONEXT, ISLAST, len(), LOG_WARNING, MP, xmldoc_has_inside(), and xmldoc_reverse_helper().

Referenced by ast_xmldoc_build_syntax(), and xmldoc_parse_optionlist().

00621 {
00622 #define GOTONEXT(__rev, __a) (__rev ? ast_xml_node_get_prev(__a) : ast_xml_node_get_next(__a))
00623 #define ISLAST(__rev, __a)  (__rev == 1 ? (ast_xml_node_get_prev(__a) ? 0 : 1) : (ast_xml_node_get_next(__a) ? 0 : 1))
00624 #define MP(__a) ((multiple ? __a : ""))
00625    struct ast_xml_node *node = NULL, *firstparam = NULL, *lastparam = NULL;
00626    const char *paramtype, *multipletype, *paramnameattr, *attrargsep, *parenthesis, *argname;
00627    int reverse, required, paramcount = 0, openbrackets = 0, len = 0, hasparams=0;
00628    int reqfinode = 0, reqlanode = 0, optmidnode = 0, prnparenthesis, multiple;
00629    char *syntax = NULL, *argsep, *paramname;
00630 
00631    if (ast_strlen_zero(rootname) || ast_strlen_zero(childname)) {
00632       ast_log(LOG_WARNING, "Tried to look in XML tree with faulty rootname or childname while creating a syntax.\n");
00633       return NULL;
00634    }
00635 
00636    if (!rootnode || !ast_xml_node_get_children(rootnode)) {
00637       /* If the rootnode field is not found, at least print name. */
00638       ast_asprintf(&syntax, "%s%s", (printrootname ? rootname : ""), (printparenthesis ? "()" : ""));
00639       return syntax;
00640    }
00641 
00642    /* Get the argument separator from the root node attribute name 'argsep', if not found
00643    defaults to ','. */
00644    attrargsep = ast_xml_get_attribute(rootnode, "argsep");
00645    if (attrargsep) {
00646       argsep = ast_strdupa(attrargsep);
00647       ast_xml_free_attr(attrargsep);
00648    } else {
00649       argsep = ast_strdupa(",");
00650    }
00651 
00652    /* Get order of evaluation. */
00653    for (node = ast_xml_node_get_children(rootnode); node; node = ast_xml_node_get_next(node)) {
00654       if (strcasecmp(ast_xml_node_get_name(node), childname)) {
00655          continue;
00656       }
00657       required = 0;
00658       hasparams = 1;
00659       if ((paramtype = ast_xml_get_attribute(node, "required"))) {
00660          if (ast_true(paramtype)) {
00661             required = 1;
00662          }
00663          ast_xml_free_attr(paramtype);
00664       }
00665 
00666       lastparam = node;
00667       reqlanode = required;
00668 
00669       if (!firstparam) {
00670          /* first parameter node */
00671          firstparam = node;
00672          reqfinode = required;
00673       }
00674    }
00675 
00676    if (!hasparams) {
00677       /* This application, function, option, etc, doesn't have any params. */
00678       ast_asprintf(&syntax, "%s%s", (printrootname ? rootname : ""), (printparenthesis ? "()" : ""));
00679       return syntax;
00680    }
00681 
00682    if (reqfinode && reqlanode) {
00683       /* check midnode */
00684       for (node = ast_xml_node_get_children(rootnode); node; node = ast_xml_node_get_next(node)) {
00685          if (strcasecmp(ast_xml_node_get_name(node), childname)) {
00686             continue;
00687          }
00688          if (node != firstparam && node != lastparam) {
00689             if ((paramtype = ast_xml_get_attribute(node, "required"))) {
00690                if (!ast_true(paramtype)) {
00691                   optmidnode = 1;
00692                   break;
00693                }
00694                ast_xml_free_attr(paramtype);
00695             }
00696          }
00697       }
00698    }
00699 
00700    if ((!reqfinode && reqlanode) || (reqfinode && reqlanode && optmidnode)) {
00701       reverse = 1;
00702       node = lastparam;
00703    } else {
00704       reverse = 0;
00705       node = firstparam;
00706    }
00707 
00708    /* init syntax string. */
00709    if (reverse) {
00710       xmldoc_reverse_helper(reverse, &len, &syntax,
00711          (printrootname ? (printrootname == 2 ? ")]" : ")"): ""));
00712    } else {
00713       xmldoc_reverse_helper(reverse, &len, &syntax, "%s%s", (printrootname ? rootname : ""),
00714          (printrootname ? (printrootname == 2 ? "[(" : "(") : ""));
00715    }
00716 
00717    for (; node; node = GOTONEXT(reverse, node)) {
00718       if (strcasecmp(ast_xml_node_get_name(node), childname)) {
00719          continue;
00720       }
00721 
00722       /* Get the argument name, if it is not the leaf, go inside that parameter. */
00723       if (xmldoc_has_inside(node, "argument")) {
00724          parenthesis = ast_xml_get_attribute(node, "hasparams");
00725          prnparenthesis = 0;
00726          if (parenthesis) {
00727             prnparenthesis = ast_true(parenthesis);
00728             if (!strcasecmp(parenthesis, "optional")) {
00729                prnparenthesis = 2;
00730             }
00731             ast_xml_free_attr(parenthesis);
00732          }
00733          argname = ast_xml_get_attribute(node, "name");
00734          if (argname) {
00735             paramname = xmldoc_get_syntax_fun(node, argname, "argument", prnparenthesis, prnparenthesis);
00736             ast_xml_free_attr(argname);
00737          } else {
00738             /* Malformed XML, print **UNKOWN** */
00739             paramname = ast_strdup("**unknown**");
00740          }
00741       } else {
00742          paramnameattr = ast_xml_get_attribute(node, "name");
00743          if (!paramnameattr) {
00744             ast_log(LOG_WARNING, "Malformed XML %s: no %s name\n", rootname, childname);
00745             if (syntax) {
00746                /* Free already allocated syntax */
00747                ast_free(syntax);
00748             }
00749             /* to give up is ok? */
00750             ast_asprintf(&syntax, "%s%s", (printrootname ? rootname : ""), (printparenthesis ? "()" : ""));
00751             return syntax;
00752          }
00753          paramname = ast_strdup(paramnameattr);
00754          ast_xml_free_attr(paramnameattr);
00755       }
00756 
00757       /* Defaults to 'false'. */
00758       multiple = 0;
00759       if ((multipletype = ast_xml_get_attribute(node, "multiple"))) {
00760          if (ast_true(multipletype)) {
00761             multiple = 1;
00762          }
00763          ast_xml_free_attr(multipletype);
00764       }
00765 
00766       required = 0;  /* Defaults to 'false'. */
00767       if ((paramtype = ast_xml_get_attribute(node, "required"))) {
00768          if (ast_true(paramtype)) {
00769             required = 1;
00770          }
00771          ast_xml_free_attr(paramtype);
00772       }
00773 
00774       /* build syntax core. */
00775 
00776       if (required) {
00777          /* First parameter */
00778          if (!paramcount) {
00779             xmldoc_reverse_helper(reverse, &len, &syntax, "%s%s%s%s", paramname, MP("["), MP(argsep), MP("...]"));
00780          } else {
00781             /* Time to close open brackets. */
00782             while (openbrackets > 0) {
00783                xmldoc_reverse_helper(reverse, &len, &syntax, (reverse ? "[" : "]"));
00784                openbrackets--;
00785             }
00786             if (reverse) {
00787                xmldoc_reverse_helper(reverse, &len, &syntax, "%s%s", paramname, argsep);
00788             } else {
00789                xmldoc_reverse_helper(reverse, &len, &syntax, "%s%s", argsep, paramname);
00790             }
00791             xmldoc_reverse_helper(reverse, &len, &syntax, "%s%s%s", MP("["), MP(argsep), MP("...]"));
00792          }
00793       } else {
00794          /* First parameter */
00795          if (!paramcount) {
00796             xmldoc_reverse_helper(reverse, &len, &syntax, "[%s%s%s%s]", paramname, MP("["), MP(argsep), MP("...]"));
00797          } else {
00798             if (ISLAST(reverse, node)) {
00799                /* This is the last parameter. */
00800                if (reverse) {
00801                   xmldoc_reverse_helper(reverse, &len, &syntax, "[%s%s%s%s]%s", paramname,
00802                            MP("["), MP(argsep), MP("...]"), argsep);
00803                } else {
00804                   xmldoc_reverse_helper(reverse, &len, &syntax, "%s[%s%s%s%s]", argsep, paramname,
00805                            MP("["), MP(argsep), MP("...]"));
00806                }
00807             } else {
00808                if (reverse) {
00809                   xmldoc_reverse_helper(reverse, &len, &syntax, "%s%s%s%s%s]", paramname, argsep,
00810                            MP("["), MP(argsep), MP("...]"));
00811                } else {
00812                   xmldoc_reverse_helper(reverse, &len, &syntax, "[%s%s%s%s%s", argsep, paramname,
00813                            MP("["), MP(argsep), MP("...]"));
00814                }
00815                openbrackets++;
00816             }
00817          }
00818       }
00819       ast_free(paramname);
00820 
00821       paramcount++;
00822    }
00823 
00824    /* Time to close open brackets. */
00825    while (openbrackets > 0) {
00826       xmldoc_reverse_helper(reverse, &len, &syntax, (reverse ? "[" : "]"));
00827       openbrackets--;
00828    }
00829 
00830    /* close syntax string. */
00831    if (reverse) {
00832       xmldoc_reverse_helper(reverse, &len, &syntax, "%s%s", (printrootname ? rootname : ""),
00833          (printrootname ? (printrootname == 2 ? "[(" : "(") : ""));
00834    } else {
00835       xmldoc_reverse_helper(reverse, &len, &syntax, (printrootname ? (printrootname == 2 ? ")]" : ")") : ""));
00836    }
00837 
00838    return syntax;
00839 #undef ISLAST
00840 #undef GOTONEXT
00841 #undef MP
00842 }

static enum syntaxtype xmldoc_get_syntax_type ( const char *  type  )  [static]

Definition at line 1008 of file xmldoc.c.

References ARRAY_LEN, FUNCTION_SYNTAX, strsyntaxtype::stxtype, and stxtype.

Referenced by ast_xmldoc_build_syntax().

01009 {
01010    int i;
01011    for (i=0; i < ARRAY_LEN(stxtype); i++) {
01012       if (!strcasecmp(stxtype[i].type, type)) {
01013          return stxtype[i].stxtype;
01014       }
01015    }
01016 
01017    return FUNCTION_SYNTAX;
01018 }

static int xmldoc_has_inside ( struct ast_xml_node *  fixnode,
const char *  what 
) [static]

Definition at line 559 of file xmldoc.c.

References ast_xml_node_get_children(), ast_xml_node_get_name(), and ast_xml_node_get_next().

Referenced by xmldoc_get_syntax_cmd(), xmldoc_get_syntax_fun(), xmldoc_parse_argument(), and xmldoc_parse_parameter().

00560 {
00561    struct ast_xml_node *node = fixnode;
00562 
00563    for (node = ast_xml_node_get_children(fixnode); node; node = ast_xml_node_get_next(node)) {
00564       if (!strcasecmp(ast_xml_node_get_name(node), what)) {
00565          return 1;
00566       }
00567    }
00568    return 0;
00569 }

static int xmldoc_has_nodes ( struct ast_xml_node *  fixnode  )  [static]

Definition at line 577 of file xmldoc.c.

References ast_xml_node_get_children(), ast_xml_node_get_name(), and ast_xml_node_get_next().

Referenced by xmldoc_parse_parameter().

00578 {
00579    struct ast_xml_node *node = fixnode;
00580 
00581    for (node = ast_xml_node_get_children(fixnode); node; node = ast_xml_node_get_next(node)) {
00582       if (strcasecmp(ast_xml_node_get_name(node), "text")) {
00583          return 1;
00584       }
00585    }
00586    return 0;
00587 }

static int xmldoc_has_specialtags ( struct ast_xml_node *  fixnode  )  [static]

Definition at line 595 of file xmldoc.c.

References ARRAY_LEN, ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), and special_tags.

Referenced by xmldoc_parse_argument().

00596 {
00597    struct ast_xml_node *node = fixnode;
00598    int i;
00599 
00600    for (node = ast_xml_node_get_children(fixnode); node; node = ast_xml_node_get_next(node)) {
00601       for (i = 0; i < ARRAY_LEN(special_tags); i++) {
00602          if (!strcasecmp(ast_xml_node_get_name(node), special_tags[i].tagname)) {
00603             return 1;
00604          }
00605       }
00606    }
00607    return 0;
00608 }

static int xmldoc_parse_argument ( struct ast_xml_node *  fixnode,
int  insideparameter,
const char *  paramtabs,
const char *  tabs,
struct ast_str **  buffer 
) [static]

Definition at line 1162 of file xmldoc.c.

References ast_str_append(), ast_xml_free_attr(), ast_xml_get_attribute(), ast_xml_node_get_children(), ast_xml_node_get_next(), xmldoc_has_inside(), xmldoc_has_specialtags(), xmldoc_parse_para(), and xmldoc_parse_specialtags().

Referenced by xmldoc_parse_option(), and xmldoc_parse_parameter().

01163 {
01164    struct ast_xml_node *node = fixnode;
01165    const char *argname;
01166    int count = 0, ret = 0;
01167 
01168    if (!node || !ast_xml_node_get_children(node)) {
01169       return ret;
01170    }
01171 
01172    /* Print the argument names */
01173    argname = ast_xml_get_attribute(node, "name");
01174    if (!argname) {
01175       return 0;
01176    }
01177    if (xmldoc_has_inside(node, "para") || xmldoc_has_specialtags(node)) {
01178       ast_str_append(buffer, 0, "%s%s%s", tabs, argname, (insideparameter ? "\n" : ""));
01179       ast_xml_free_attr(argname);
01180    } else {
01181       ast_xml_free_attr(argname);
01182       return 0;
01183    }
01184 
01185    for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
01186       if (xmldoc_parse_para(node, (insideparameter ? paramtabs : (!count ? " - " : tabs)), "\n", buffer) == 2) {
01187          count++;
01188          ret = 1;
01189       } else if (xmldoc_parse_specialtags(node, (insideparameter ? paramtabs : (!count ? " - " : tabs)), "\n", buffer) == 2) {
01190          count++;
01191          ret = 1;
01192       }
01193    }
01194 
01195    return ret;
01196 }

static char* xmldoc_parse_cmd_enumlist ( struct ast_xml_node *  fixnode  )  [static]

Definition at line 851 of file xmldoc.c.

References ast_free, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_strdup, ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), first, and xmldoc_get_syntax_cmd().

Referenced by xmldoc_get_syntax_cmd().

00852 {
00853    struct ast_xml_node *node = fixnode;
00854    struct ast_str *paramname;
00855    char *enumname, *ret;
00856    int first = 1;
00857 
00858    paramname = ast_str_create(128);
00859    if (!paramname) {
00860       return ast_strdup("{<unkown>}");
00861    }
00862 
00863    ast_str_append(&paramname, 0, "{");
00864 
00865    for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
00866       if (strcasecmp(ast_xml_node_get_name(node), "enum")) {
00867          continue;
00868       }
00869 
00870       enumname = xmldoc_get_syntax_cmd(node, "", 0);
00871       if (!enumname) {
00872          continue;
00873       }
00874       if (!first) {
00875          ast_str_append(&paramname, 0, "|");
00876       }
00877       ast_str_append(&paramname, 0, "%s", enumname);
00878       first = 0;
00879       ast_free(enumname);
00880    }
00881 
00882    ast_str_append(&paramname, 0, "}");
00883 
00884    ret = ast_strdup(ast_str_buffer(paramname));
00885    ast_free(paramname);
00886 
00887    return ret;
00888 }

static int xmldoc_parse_enum ( struct ast_xml_node *  fixnode,
const char *  tabs,
struct ast_str **  buffer 
) [static]

Definition at line 1398 of file xmldoc.c.

References ast_asprintf, ast_free, ast_xml_node_get_children(), ast_xml_node_get_next(), xmldoc_parse_enumlist(), xmldoc_parse_para(), and xmldoc_parse_specialtags().

Referenced by xmldoc_parse_enumlist().

01399 {
01400    struct ast_xml_node *node = fixnode;
01401    int ret = 0;
01402    char *optiontabs;
01403 
01404    ast_asprintf(&optiontabs, "%s    ", tabs);
01405 
01406    for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
01407       if ((xmldoc_parse_para(node, (ret ? tabs : " - "), "\n", buffer))) {
01408          ret = 1;
01409       } else if ((xmldoc_parse_specialtags(node, (ret ? tabs : " - "), "\n", buffer))) {
01410          ret = 1;
01411       }
01412 
01413       xmldoc_parse_enumlist(node, optiontabs, buffer);
01414    }
01415 
01416    ast_free(optiontabs);
01417 
01418    return ret;
01419 }

static int xmldoc_parse_enumlist ( struct ast_xml_node *  fixnode,
const char *  tabs,
struct ast_str **  buffer 
) [static]

Definition at line 1428 of file xmldoc.c.

References ast_str_append(), ast_xml_free_attr(), ast_xml_get_attribute(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), and xmldoc_parse_enum().

Referenced by xmldoc_get_formatted(), xmldoc_parse_enum(), xmldoc_parse_option(), and xmldoc_parse_parameter().

01429 {
01430    struct ast_xml_node *node = fixnode;
01431    const char *enumname;
01432    int ret = 0;
01433 
01434    for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
01435       if (strcasecmp(ast_xml_node_get_name(node), "enum")) {
01436          continue;
01437       }
01438 
01439       enumname = ast_xml_get_attribute(node, "name");
01440       if (enumname) {
01441          ast_str_append(buffer, 0, "%s<enum>%s</enum>", tabs, enumname);
01442          ast_xml_free_attr(enumname);
01443 
01444          /* parse only enum elements inside a enumlist node. */
01445          if ((xmldoc_parse_enum(node, tabs, buffer))) {
01446             ret = 1;
01447          } else {
01448             ast_str_append(buffer, 0, "\n");
01449          }
01450       }
01451    }
01452    return ret;
01453 }

static int xmldoc_parse_option ( struct ast_xml_node *  fixnode,
const char *  tabs,
struct ast_str **  buffer 
) [static]

Definition at line 1464 of file xmldoc.c.

References ast_asprintf, ast_free, ast_str_append(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), xmldoc_parse_argument(), xmldoc_parse_enumlist(), xmldoc_parse_para(), xmldoc_parse_specialtags(), and xmldoc_parse_variablelist().

Referenced by xmldoc_parse_optionlist().

01465 {
01466    struct ast_xml_node *node;
01467    int ret = 0;
01468    char *optiontabs;
01469 
01470    ast_asprintf(&optiontabs, "%s    ", tabs);
01471    if (!optiontabs) {
01472       return ret;
01473    }
01474    for (node = ast_xml_node_get_children(fixnode); node; node = ast_xml_node_get_next(node)) {
01475       if (!strcasecmp(ast_xml_node_get_name(node), "argument")) {
01476          /* if this is the first data appended to buffer, print a \n*/
01477          if (!ret && ast_xml_node_get_children(node)) {
01478             /* print \n */
01479             ast_str_append(buffer, 0, "\n");
01480          }
01481          if (xmldoc_parse_argument(node, 0, NULL, optiontabs, buffer)) {
01482             ret = 1;
01483          }
01484          continue;
01485       }
01486 
01487       if (xmldoc_parse_para(node, (ret ? tabs :  ""), "\n", buffer)) {
01488          ret = 1;
01489       } else if (xmldoc_parse_specialtags(node, (ret ? tabs :  ""), "\n", buffer)) {
01490          ret = 1;
01491       }
01492 
01493       xmldoc_parse_variablelist(node, optiontabs, buffer);
01494 
01495       xmldoc_parse_enumlist(node, optiontabs, buffer);
01496    }
01497    ast_free(optiontabs);
01498 
01499    return ret;
01500 }

static void xmldoc_parse_optionlist ( struct ast_xml_node *  fixnode,
const char *  tabs,
struct ast_str **  buffer 
) [static]

Definition at line 1509 of file xmldoc.c.

References ast_str_append(), ast_xml_free_attr(), ast_xml_get_attribute(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), xmldoc_get_syntax_fun(), and xmldoc_parse_option().

Referenced by xmldoc_parse_parameter().

01510 {
01511    struct ast_xml_node *node;
01512    const char *optname, *hasparams;
01513    char *optionsyntax;
01514    int optparams;
01515 
01516    for (node = ast_xml_node_get_children(fixnode); node; node = ast_xml_node_get_next(node)) {
01517       /* Start appending every option tag. */
01518       if (strcasecmp(ast_xml_node_get_name(node), "option")) {
01519          continue;
01520       }
01521 
01522       /* Get the option name. */
01523       optname = ast_xml_get_attribute(node, "name");
01524       if (!optname) {
01525          continue;
01526       }
01527 
01528       optparams = 1;
01529       hasparams = ast_xml_get_attribute(node, "hasparams");
01530       if (hasparams && !strcasecmp(hasparams, "optional")) {
01531          optparams = 2;
01532       }
01533 
01534       optionsyntax = xmldoc_get_syntax_fun(node, optname, "argument", 0, optparams);
01535       if (!optionsyntax) {
01536          ast_xml_free_attr(optname);
01537          ast_xml_free_attr(hasparams);
01538          continue;
01539       }
01540 
01541       ast_str_append(buffer, 0, "%s%s: ", tabs, optionsyntax);
01542 
01543       if (!xmldoc_parse_option(node, tabs, buffer)) {
01544          ast_str_append(buffer, 0, "\n");
01545       }
01546       ast_xml_free_attr(optname);
01547       ast_xml_free_attr(hasparams);
01548    }
01549 }

static int xmldoc_parse_para ( struct ast_xml_node *  node,
const char *  tabs,
const char *  posttabs,
struct ast_str **  buffer 
) [static]

Definition at line 1058 of file xmldoc.c.

References ast_free, ast_str_append(), ast_str_buffer(), ast_xml_free_text(), ast_xml_get_text(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), and xmldoc_string_cleanup().

Referenced by xmldoc_get_formatted(), xmldoc_parse_argument(), xmldoc_parse_enum(), xmldoc_parse_option(), xmldoc_parse_parameter(), xmldoc_parse_specialtags(), xmldoc_parse_variable(), and xmldoc_parse_variablelist().

01059 {
01060    const char *tmptext;
01061    struct ast_xml_node *tmp;
01062    int ret = 0;
01063    struct ast_str *tmpstr;
01064 
01065    if (!node || !ast_xml_node_get_children(node)) {
01066       return ret;
01067    }
01068 
01069    if (strcasecmp(ast_xml_node_get_name(node), "para")) {
01070       return ret;
01071    }
01072 
01073    ast_str_append(buffer, 0, "%s", tabs);
01074 
01075    ret = 1;
01076 
01077    for (tmp = ast_xml_node_get_children(node); tmp; tmp = ast_xml_node_get_next(tmp)) {
01078       /* Get the text inside the <para> element and append it to buffer. */
01079       tmptext = ast_xml_get_text(tmp);
01080       if (tmptext) {
01081          /* Strip \n etc. */
01082          xmldoc_string_cleanup(tmptext, &tmpstr, 0);
01083          ast_xml_free_text(tmptext);
01084          if (tmpstr) {
01085             if (strcasecmp(ast_xml_node_get_name(tmp), "text")) {
01086                ast_str_append(buffer, 0, "<%s>%s</%s>", ast_xml_node_get_name(tmp),
01087                      ast_str_buffer(tmpstr), ast_xml_node_get_name(tmp));
01088             } else {
01089                ast_str_append(buffer, 0, "%s", ast_str_buffer(tmpstr));
01090             }
01091             ast_free(tmpstr);
01092             ret = 2;
01093          }
01094       }
01095    }
01096 
01097    ast_str_append(buffer, 0, "%s", posttabs);
01098 
01099    return ret;
01100 }

static void xmldoc_parse_parameter ( struct ast_xml_node *  fixnode,
const char *  tabs,
struct ast_str **  buffer 
) [static]

Definition at line 1558 of file xmldoc.c.

References ast_asprintf, ast_free, ast_str_append(), ast_xml_free_attr(), ast_xml_get_attribute(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), xmldoc_has_inside(), xmldoc_has_nodes(), xmldoc_parse_argument(), xmldoc_parse_enumlist(), xmldoc_parse_optionlist(), xmldoc_parse_para(), and xmldoc_parse_specialtags().

Referenced by ast_xmldoc_build_arguments().

01559 {
01560    const char *paramname;
01561    struct ast_xml_node *node = fixnode;
01562    int hasarguments, printed = 0;
01563    char *internaltabs;
01564 
01565    if (strcasecmp(ast_xml_node_get_name(node), "parameter")) {
01566       return;
01567    }
01568 
01569    hasarguments = xmldoc_has_inside(node, "argument");
01570    if (!(paramname = ast_xml_get_attribute(node, "name"))) {
01571       /* parameter MUST have an attribute name. */
01572       return;
01573    }
01574 
01575    ast_asprintf(&internaltabs, "%s    ", tabs);
01576    if (!internaltabs) {
01577       return;
01578    }
01579 
01580    if (!hasarguments && xmldoc_has_nodes(node)) {
01581       ast_str_append(buffer, 0, "%s\n", paramname);
01582       ast_xml_free_attr(paramname);
01583       printed = 1;
01584    }
01585 
01586    for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
01587       if (!strcasecmp(ast_xml_node_get_name(node), "optionlist")) {
01588          xmldoc_parse_optionlist(node, internaltabs, buffer);
01589       } else if (!strcasecmp(ast_xml_node_get_name(node), "enumlist")) {
01590          xmldoc_parse_enumlist(node, internaltabs, buffer);
01591       } else if (!strcasecmp(ast_xml_node_get_name(node), "argument")) {
01592          xmldoc_parse_argument(node, 1, internaltabs, (!hasarguments ? "        " : ""), buffer);
01593       } else if (!strcasecmp(ast_xml_node_get_name(node), "para")) {
01594          if (!printed) {
01595             ast_str_append(buffer, 0, "%s\n", paramname);
01596             ast_xml_free_attr(paramname);
01597             printed = 1;
01598          }
01599          xmldoc_parse_para(node, internaltabs, "\n", buffer);
01600          continue;
01601       } else if ((xmldoc_parse_specialtags(node, internaltabs, "\n", buffer))) {
01602          continue;
01603       }
01604    }
01605    if (!printed) {
01606       ast_xml_free_attr(paramname);
01607    }
01608    ast_free(internaltabs);
01609 }

static int xmldoc_parse_specialtags ( struct ast_xml_node *  fixnode,
const char *  tabs,
const char *  posttabs,
struct ast_str **  buffer 
) [static]

Definition at line 1112 of file xmldoc.c.

References ARRAY_LEN, ast_str_append(), ast_strlen_zero(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), special_tags, and xmldoc_parse_para().

Referenced by xmldoc_get_formatted(), xmldoc_parse_argument(), xmldoc_parse_enum(), xmldoc_parse_option(), xmldoc_parse_parameter(), xmldoc_parse_variable(), and xmldoc_parse_variablelist().

01113 {
01114    struct ast_xml_node *node = fixnode;
01115    int ret = 0, i, count = 0;
01116 
01117    if (!node || !ast_xml_node_get_children(node)) {
01118       return ret;
01119    }
01120 
01121    for (i = 0; i < ARRAY_LEN(special_tags); i++) {
01122       if (strcasecmp(ast_xml_node_get_name(node), special_tags[i].tagname)) {
01123          continue;
01124       }
01125 
01126       ret = 1;
01127       /* This is a special tag. */
01128 
01129       /* concat data */
01130       if (!ast_strlen_zero(special_tags[i].init)) {
01131          ast_str_append(buffer, 0, "%s%s", tabs, special_tags[i].init);
01132       }
01133 
01134       /* parse <para> elements inside special tags. */
01135       for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
01136          /* first <para> just print it without tabs at the begining. */
01137          if (xmldoc_parse_para(node, (!count ? "" : tabs), posttabs, buffer) == 2) {
01138             ret = 2;
01139          }
01140       }
01141 
01142       if (!ast_strlen_zero(special_tags[i].end)) {
01143          ast_str_append(buffer, 0, "%s%s", special_tags[i].end, posttabs);
01144       }
01145 
01146       break;
01147    }
01148 
01149    return ret;
01150 }

static int xmldoc_parse_variable ( struct ast_xml_node *  node,
const char *  tabs,
struct ast_str **  buffer 
) [static]

Definition at line 1209 of file xmldoc.c.

References ast_free, ast_str_append(), ast_str_buffer(), ast_str_strlen(), ast_xml_free_attr(), ast_xml_free_text(), ast_xml_get_attribute(), ast_xml_get_text(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), xmldoc_parse_para(), xmldoc_parse_specialtags(), and xmldoc_string_cleanup().

Referenced by xmldoc_parse_variablelist().

01210 {
01211    struct ast_xml_node *tmp;
01212    const char *valname;
01213    const char *tmptext;
01214    struct ast_str *cleanstr;
01215    int ret = 0, printedpara=0;
01216 
01217    for (tmp = ast_xml_node_get_children(node); tmp; tmp = ast_xml_node_get_next(tmp)) {
01218       if (xmldoc_parse_para(tmp, (ret ? tabs : ""), "\n", buffer)) {
01219          printedpara = 1;
01220          continue;
01221       } else if (xmldoc_parse_specialtags(tmp, (ret ? tabs : ""), "\n", buffer)) {
01222          printedpara = 1;
01223          continue;
01224       }
01225 
01226       if (strcasecmp(ast_xml_node_get_name(tmp), "value")) {
01227          continue;
01228       }
01229 
01230       /* Parse a <value> tag only. */
01231       if (!printedpara) {
01232          ast_str_append(buffer, 0, "\n");
01233          printedpara = 1;
01234       }
01235       /* Parse each <value name='valuename'>desciption</value> */
01236       valname = ast_xml_get_attribute(tmp, "name");
01237       if (valname) {
01238          ret = 1;
01239          ast_str_append(buffer, 0, "%s<value>%s</value>", tabs, valname);
01240          ast_xml_free_attr(valname);
01241       }
01242       tmptext = ast_xml_get_text(tmp);
01243       /* Check inside this node for any explanation about its meaning. */
01244       if (tmptext) {
01245          /* Cleanup text. */
01246          xmldoc_string_cleanup(tmptext, &cleanstr, 1);
01247          ast_xml_free_text(tmptext);
01248          if (cleanstr && ast_str_strlen(cleanstr) > 0) {
01249             ast_str_append(buffer, 0, ":%s", ast_str_buffer(cleanstr));
01250          }
01251          ast_free(cleanstr);
01252       }
01253       ast_str_append(buffer, 0, "\n");
01254    }
01255 
01256    return ret;
01257 }

static int xmldoc_parse_variablelist ( struct ast_xml_node *  node,
const char *  tabs,
struct ast_str **  buffer 
) [static]

Definition at line 1270 of file xmldoc.c.

References ast_asprintf, ast_free, ast_str_append(), ast_xml_free_attr(), ast_xml_get_attribute(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), xmldoc_parse_para(), xmldoc_parse_specialtags(), and xmldoc_parse_variable().

Referenced by xmldoc_get_formatted(), and xmldoc_parse_option().

01271 {
01272    struct ast_xml_node *tmp;
01273    const char *varname;
01274    char *vartabs;
01275    int ret = 0;
01276 
01277    if (!node || !ast_xml_node_get_children(node)) {
01278       return ret;
01279    }
01280 
01281    if (strcasecmp(ast_xml_node_get_name(node), "variablelist")) {
01282       return ret;
01283    }
01284 
01285    /* use this spacing (add 4 spaces) inside a variablelist node. */
01286    ast_asprintf(&vartabs, "%s    ", tabs);
01287    if (!vartabs) {
01288       return ret;
01289    }
01290    for (tmp = ast_xml_node_get_children(node); tmp; tmp = ast_xml_node_get_next(tmp)) {
01291       /* We can have a <para> element inside the variable list */
01292       if ((xmldoc_parse_para(tmp, (ret ? tabs : ""), "\n", buffer))) {
01293          ret = 1;
01294          continue;
01295       } else if ((xmldoc_parse_specialtags(tmp, (ret ? tabs : ""), "\n", buffer))) {
01296          ret = 1;
01297          continue;
01298       }
01299 
01300       if (!strcasecmp(ast_xml_node_get_name(tmp), "variable")) {
01301          /* Store the variable name in buffer. */
01302          varname = ast_xml_get_attribute(tmp, "name");
01303          if (varname) {
01304             ast_str_append(buffer, 0, "%s<variable>%s</variable>: ", tabs, varname);
01305             ast_xml_free_attr(varname);
01306             /* Parse the <variable> possible values. */
01307             xmldoc_parse_variable(tmp, vartabs, buffer);
01308             ret = 1;
01309          }
01310       }
01311    }
01312 
01313    ast_free(vartabs);
01314 
01315    return ret;
01316 }

static int xmldoc_postbrlen ( const char *  postbr  )  [static]

Definition at line 109 of file xmldoc.c.

Referenced by xmldoc_string_wrap().

00110 {
00111    int postbrreallen = 0, i;
00112    size_t postbrlen;
00113 
00114    if (!postbr) {
00115       return 0;
00116    }
00117    postbrlen = strlen(postbr);
00118    for (i = 0; i < postbrlen; i++) {
00119       if (postbr[i] == '\t') {
00120          postbrreallen += 8 - (postbrreallen % 8);
00121       } else {
00122          postbrreallen++;
00123       }
00124    }
00125    return postbrreallen;
00126 }

static void xmldoc_reverse_helper ( int  reverse,
int *  len,
char **  syntax,
const char *  fmt,
  ... 
) [static]

Definition at line 513 of file xmldoc.c.

References ast_free, ast_realloc, and ast_vasprintf.

Referenced by xmldoc_get_syntax_fun().

00514 {
00515    int totlen, tmpfmtlen;
00516    char *tmpfmt, tmp;
00517    va_list ap;
00518 
00519    va_start(ap, fmt);
00520    if (ast_vasprintf(&tmpfmt, fmt, ap) < 0) {
00521       va_end(ap);
00522       return;
00523    }
00524    va_end(ap);
00525 
00526    tmpfmtlen = strlen(tmpfmt);
00527    totlen = *len + tmpfmtlen + 1;
00528 
00529    *syntax = ast_realloc(*syntax, totlen);
00530 
00531    if (!*syntax) {
00532       ast_free(tmpfmt);
00533       return;
00534    }
00535 
00536    if (reverse) {
00537       memmove(*syntax + tmpfmtlen, *syntax, *len);
00538       /* Save this char, it will be overwritten by the \0 of strcpy. */
00539       tmp = (*syntax)[0];
00540       strcpy(*syntax, tmpfmt);
00541       /* Restore the already saved char. */
00542       (*syntax)[tmpfmtlen] = tmp;
00543       (*syntax)[totlen - 1] = '\0';
00544    } else {
00545       strcpy(*syntax + *len, tmpfmt);
00546    }
00547 
00548    *len = totlen - 1;
00549    ast_free(tmpfmt);
00550 }

static void xmldoc_setpostbr ( char *  postbr,
size_t  len,
const char *  text 
) [static]

Definition at line 135 of file xmldoc.c.

Referenced by xmldoc_string_wrap().

00136 {
00137    int c, postbrlen = 0;
00138 
00139    if (!text) {
00140       return;
00141    }
00142 
00143    for (c = 0; c < len; c++) {
00144       if (text[c] == '\t' || text[c] == ' ') {
00145          postbr[postbrlen++] = text[c];
00146       } else {
00147          break;
00148       }
00149    }
00150    postbr[postbrlen] = '\0';
00151 }

static void xmldoc_string_cleanup ( const char *  text,
struct ast_str **  output,
int  lastspaces 
) [static]

Definition at line 419 of file xmldoc.c.

References ast_log(), ast_str_append(), ast_str_create(), ast_str_trim_blanks(), and LOG_ERROR.

Referenced by xmldoc_get_formatted(), xmldoc_parse_para(), and xmldoc_parse_variable().

00420 {
00421    int i;
00422    size_t textlen;
00423 
00424    if (!text) {
00425       *output = NULL;
00426       return;
00427    }
00428 
00429    textlen = strlen(text);
00430 
00431    *output = ast_str_create(textlen);
00432    if (!(*output)) {
00433       ast_log(LOG_ERROR, "Problem allocating output buffer\n");
00434       return;
00435    }
00436 
00437    for (i = 0; i < textlen; i++) {
00438       if (text[i] == '\n' || text[i] == '\r') {
00439          /* remove spaces/tabs/\n after a \n. */
00440          while (text[i + 1] == '\t' || text[i + 1] == '\r' || text[i + 1] == '\n') {
00441             i++;
00442          }
00443          ast_str_append(output, 0, " ");
00444          continue;
00445       } else {
00446          ast_str_append(output, 0, "%c", text[i]);
00447       }
00448    }
00449 
00450    /* remove last spaces (we dont want always to remove the trailing spaces). */
00451    if (lastspaces) {
00452       ast_str_trim_blanks(*output);
00453    }
00454 }

static char* xmldoc_string_wrap ( const char *  text,
int  columns,
int  maxdiff 
) [static]

Definition at line 232 of file xmldoc.c.

References ast_free, ast_log(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_truncate(), ast_strdup, ESC, LOG_WARNING, xmldoc_foundspace_backward(), xmldoc_postbrlen(), xmldoc_setpostbr(), and xmldoc_wait_nextspace().

Referenced by ast_xmldoc_printable().

00233 {
00234    struct ast_str *tmp;
00235    char *ret, postbr[160];
00236    int count = 1, i, backspace, needtobreak = 0, colmax, textlen;
00237 
00238    /* sanity check */
00239    if (!text || columns <= 0 || maxdiff < 0) {
00240       ast_log(LOG_WARNING, "Passing wrong arguments while trying to wrap the text\n");
00241       return NULL;
00242    }
00243 
00244    tmp = ast_str_create(strlen(text) * 3);
00245 
00246    if (!tmp) {
00247       return NULL;
00248    }
00249 
00250    /* Check for blanks and tabs and put them in postbr. */
00251    xmldoc_setpostbr(postbr, sizeof(postbr), text);
00252    colmax = columns - xmldoc_postbrlen(postbr);
00253 
00254    textlen = strlen(text);
00255    for (i = 0; i < textlen; i++) {
00256       if (needtobreak || !(count % colmax)) {
00257          if (text[i] == ' ') {
00258             ast_str_append(&tmp, 0, "\n%s", postbr);
00259             needtobreak = 0;
00260             count = 1;
00261          } else if (text[i] != '\n') {
00262             needtobreak = 1;
00263             if (xmldoc_wait_nextspace(text, i, maxdiff)) {
00264                /* wait for the next space */
00265                ast_str_append(&tmp, 0, "%c", text[i]);
00266                continue;
00267             }
00268             /* Try to look backwards */
00269             backspace = xmldoc_foundspace_backward(text, i, maxdiff);
00270             if (backspace) {
00271                needtobreak = 1;
00272                ast_str_truncate(tmp, -backspace);
00273                i -= backspace + 1;
00274                continue;
00275             }
00276             ast_str_append(&tmp, 0, "\n%s", postbr);
00277             needtobreak = 0;
00278             count = 1;
00279          }
00280          /* skip blanks after a \n */
00281          while (text[i] == ' ') {
00282             i++;
00283          }
00284       }
00285       if (text[i] == '\n') {
00286          xmldoc_setpostbr(postbr, sizeof(postbr), &text[i] + 1);
00287          colmax = columns - xmldoc_postbrlen(postbr);
00288          needtobreak = 0;
00289          count = 1;
00290       }
00291       if (text[i] == ESC) {
00292          /* Ignore Escape sequences. */
00293          do {
00294             ast_str_append(&tmp, 0, "%c", text[i]);
00295             i++;
00296          } while (i < textlen && text[i] != 'm');
00297       } else {
00298          count++;
00299       }
00300       ast_str_append(&tmp, 0, "%c", text[i]);
00301    }
00302 
00303    ret = ast_strdup(ast_str_buffer(tmp));
00304    ast_free(tmp);
00305 
00306    return ret;
00307 }

static void xmldoc_unload_documentation ( void   )  [static]

Close and unload XML documentation.

Definition at line 1751 of file xmldoc.c.

References ast_free, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_xml_close(), ast_xml_finish(), documentation_tree::doc, documentation_tree::entry, and documentation_tree::filename.

Referenced by ast_xmldoc_load_documentation().

01752 {
01753         struct documentation_tree *doctree;
01754 
01755    AST_RWLIST_WRLOCK(&xmldoc_tree);
01756    while ((doctree = AST_RWLIST_REMOVE_HEAD(&xmldoc_tree, entry))) {
01757       ast_free(doctree->filename);
01758       ast_xml_close(doctree->doc);
01759    }
01760    AST_RWLIST_UNLOCK(&xmldoc_tree);
01761 
01762    ast_xml_finish();
01763 }

static int xmldoc_wait_nextspace ( const char *  text,
int  currentpos,
int  maxdiff 
) [static]

Definition at line 163 of file xmldoc.c.

References ESC.

Referenced by xmldoc_string_wrap().

00164 {
00165    int i, textlen;
00166 
00167    if (!text) {
00168       return 0;
00169    }
00170 
00171    textlen = strlen(text);
00172    for (i = currentpos; i < textlen; i++) {
00173       if (text[i] == ESC) {
00174          /* Move to the end of the escape sequence */
00175          while (i < textlen && text[i] != 'm') {
00176             i++;
00177          }
00178       } else if (text[i] == ' ' || text[i] == '\n') {
00179          /* Found the next space or linefeed */
00180          return 1;
00181       } else if (i - currentpos > maxdiff) {
00182          /* We have looked the max distance and didn't find it */
00183          return 0;
00184       }
00185    }
00186 
00187    /* Reached the end and did not find it */
00188 
00189    return 0;
00190 }


Variable Documentation

struct strcolorized_tags colorized_tags[] [static]

Referenced by ast_xmldoc_printable().

const char default_documentation_language[] = "en_US" [static]

Default documentation language.

Definition at line 39 of file xmldoc.c.

char documentation_language[6] [static]

XML documentation language.

Definition at line 51 of file xmldoc.c.

struct strspecial_tags special_tags[] [static]

Mapping between type of node and type of syntax to generate.

Referenced by xmldoc_get_syntax_type().

const int xmldoc_max_diff = 5 [static]

This is a value that we will use to let the wrapping mechanism move the cursor backward and forward xmldoc_max_diff positions before cutting the middle of a word, trying to find a space or a
.

Definition at line 48 of file xmldoc.c.

const int xmldoc_text_columns = 74 [static]

Number of columns to print when showing the XML documentation with a 'core show application/function *' CLI command. Used in text wrapping.

Definition at line 43 of file xmldoc.c.


Generated by  doxygen 1.6.2