Mon Mar 12 2012 21:46:55

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, MANAGER_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, const char *module)
 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, const char *module)
 Generate description documentation from XML.
char * ast_xmldoc_build_seealso (const char *type, const char *name, const char *module)
 Parse the <see-also> node content.
char * ast_xmldoc_build_synopsis (const char *type, const char *name, const char *module)
 Generate synopsis documentation from XML.
char * ast_xmldoc_build_syntax (const char *type, const char *name, const char *module)
 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 int xmldoc_attribute_match (struct ast_xml_node *node, const char *attr, const char *value)
static char * xmldoc_build_field (const char *type, const char *name, const char *module, 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 *module, 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 char * xmldoc_get_syntax_manager (struct ast_xml_node *fixnode, const char *name)
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 []
static struct strsyntaxtype stxtype []
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.
static struct xmldoc_tree xmldoc_tree

Detailed Description

XML Documentation API.

Author:
Eliel C. Sardanons (LU1ALY) <eliels@gmail.com>
ExtRef:
libxml2 http://www.xmlsoft.org/

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 
MANAGER_SYNTAX 
COMMAND_SYNTAX 

Definition at line 1096 of file xmldoc.c.


Function Documentation

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

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

Parameters:
type'application', 'function' or 'agi' ?
nameName of the application or function to build the 'arguments' tag.
moduleThe module the item is in (optional, can be NULL)
Return values:
NULLon error.
Outputbuffer with the [arguments] tag content.

Definition at line 1730 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(), xmldoc_get_node(), and xmldoc_parse_parameter().

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

{
   struct ast_xml_node *node;
   struct ast_str *ret = ast_str_create(128);
   char *retstr = NULL;

   if (ast_strlen_zero(type) || ast_strlen_zero(name)) {
      return NULL;
   }

   node = xmldoc_get_node(type, name, module, documentation_language);

   if (!node || !ast_xml_node_get_children(node)) {
      return NULL;
   }

   /* Find the syntax field. */
   for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
      if (!strcasecmp(ast_xml_node_get_name(node), "syntax")) {
         break;
      }
   }

   if (!node || !ast_xml_node_get_children(node)) {
      /* We couldn't find the syntax node. */
      return NULL;
   }

   for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
      xmldoc_parse_parameter(node, "", &ret);
   }

   if (ast_str_strlen(ret) > 0) {
      /* remove last '\n' */
      char *buf = ast_str_buffer(ret);
      if (buf[ast_str_strlen(ret) - 1] == '\n') {
         ast_str_truncate(ret, -1);
      }
      retstr = ast_strdup(ast_str_buffer(ret));
   }
   ast_free(ret);

   return retstr;
}
char* ast_xmldoc_build_description ( const char *  type,
const char *  name,
const char *  module 
)

Generate description documentation from XML.

Parameters:
typeThe source of documentation (application, function, etc).
nameThe name of the application, function, etc.
moduleThe module the item is in (optional, can be NULL)
Return values:
NULLon error.
Amalloc'ed string with the formatted description.

Definition at line 1864 of file xmldoc.c.

References xmldoc_build_field().

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

{
   return xmldoc_build_field(type, name, module, "description", 0);
}
char* ast_xmldoc_build_seealso ( const char *  type,
const char *  name,
const char *  module 
)

Parse the <see-also> node content.

Parameters:
type'application', 'function' or 'agi'.
nameApplication or functions name.
moduleThe module the item is in (optional, can be NULL)
Return values:
NULLon error.
Contentof the see-also node.

Definition at line 1436 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(), ast_manager_register2(), and ast_register_application2().

{
   struct ast_str *outputstr;
   char *output;
   struct ast_xml_node *node;
   const char *typename;
   const char *content;
   int first = 1;

   if (ast_strlen_zero(type) || ast_strlen_zero(name)) {
      return NULL;
   }

   /* get the application/function root node. */
   node = xmldoc_get_node(type, name, module, documentation_language);
   if (!node || !ast_xml_node_get_children(node)) {
      return NULL;
   }

   /* Find the <see-also> 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), "see-also")) {
         break;
      }
   }

   if (!node || !ast_xml_node_get_children(node)) {
      /* we couldnt find a <see-also> node. */
      return NULL;
   }

   /* prepare the output string. */
   outputstr = ast_str_create(128);
   if (!outputstr) {
      return NULL;
   }

   /* get into the <see-also> 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), "ref")) {
         continue;
      }

      /* parse the <ref> node. 'type' attribute is required. */
      typename = ast_xml_get_attribute(node, "type");
      if (!typename) {
         continue;
      }
      content = ast_xml_get_text(node);
      if (!content) {
         ast_xml_free_attr(typename);
         continue;
      }
      if (!strcasecmp(typename, "application")) {
         ast_str_append(&outputstr, 0, "%s%s()",   (first ? "" : ", "), content);
      } else if (!strcasecmp(typename, "function")) {
         ast_str_append(&outputstr, 0, "%s%s", (first ? "" : ", "), content);
      } else if (!strcasecmp(typename, "astcli")) {
         ast_str_append(&outputstr, 0, "%s<astcli>%s</astcli>", (first ? "" : ", "), content);
      } else {
         ast_str_append(&outputstr, 0, "%s%s", (first ? "" : ", "), content);
      }
      first = 0;
      ast_xml_free_text(content);
      ast_xml_free_attr(typename);
   }

   output = ast_strdup(ast_str_buffer(outputstr));
   ast_free(outputstr);

   return output;
}
char* ast_xmldoc_build_synopsis ( const char *  type,
const char *  name,
const char *  module 
)

Generate synopsis documentation from XML.

Parameters:
typeThe source of documentation (application, function, etc).
nameThe name of the application, function, etc.
moduleThe module the item is in (optional, can be NULL)
Return values:
NULLon error.
Amalloc'ed string with the synopsis.

Definition at line 1859 of file xmldoc.c.

References xmldoc_build_field().

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

{
   return xmldoc_build_field(type, name, module, "synopsis", 1);
}
char* ast_xmldoc_build_syntax ( const char *  type,
const char *  name,
const char *  module 
)

Get the syntax for a specified application or function.

Parameters:
typeApplication, Function or AGI ?
nameName of the application or function.
moduleThe module the item is in (optional, can be NULL)
Return values:
NULLon error.
Thegenerated syntax in a ast_malloc'ed string.

Definition at line 1130 of file xmldoc.c.

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

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

{
   struct ast_xml_node *node;
   char *syntax = NULL;

   node = xmldoc_get_node(type, name, module, documentation_language);
   if (!node) {
      return NULL;
   }

   for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
      if (!strcasecmp(ast_xml_node_get_name(node), "syntax")) {
         break;
      }
   }

   if (node) {
      switch (xmldoc_get_syntax_type(type)) {
      case FUNCTION_SYNTAX:
         syntax = xmldoc_get_syntax_fun(node, name, "parameter", 1, 1);
         break;
      case COMMAND_SYNTAX:
         syntax = xmldoc_get_syntax_cmd(node, name, 1);
         break;
      case MANAGER_SYNTAX:
         syntax = xmldoc_get_syntax_manager(node, name);
         break;
      default:
         syntax = xmldoc_get_syntax_fun(node, name, "parameter", 1, 1);
      }
   }
   return syntax;
}
char* ast_xmldoc_printable ( const char *  bwinput,
int  withcolors 
)

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

Parameters:
bwinputNot colorized input with tags.
withcolorsResult output with colors.
Return values:
NULLon error.
Newmalloced buffer colorized and with delimiters.

Definition at line 311 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(), COLOR_CYAN, colorized_tags, len(), strcasestr(), term_end(), and xmldoc_string_wrap().

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

{
   struct ast_str *colorized;
   char *wrapped = NULL;
   int i, c, len, colorsection;
   char *tmp;
   size_t bwinputlen;
   static const int base_fg = COLOR_CYAN;

   if (!bwinput) {
      return NULL;
   }

   bwinputlen = strlen(bwinput);

   if (!(colorized = ast_str_create(256))) {
      return NULL;
   }

   if (withcolors) {
      ast_term_color_code(&colorized, base_fg, 0);
      if (!colorized) {
         return NULL;
      }
   }

   for (i = 0; i < bwinputlen; i++) {
      colorsection = 0;
      /* Check if we are at the beginning of a tag to be colorized. */
      for (c = 0; c < ARRAY_LEN(colorized_tags); c++) {
         if (strncasecmp(bwinput + i, colorized_tags[c].inittag, strlen(colorized_tags[c].inittag))) {
            continue;
         }

         if (!(tmp = strcasestr(bwinput + i + strlen(colorized_tags[c].inittag), colorized_tags[c].endtag))) {
            continue;
         }

         len = tmp - (bwinput + i + strlen(colorized_tags[c].inittag));

         /* Setup color */
         if (withcolors) {
            ast_term_color_code(&colorized, colorized_tags[c].colorfg, 0);
            if (!colorized) {
               return NULL;
            }
         }

         /* copy initial string replace */
         ast_str_append(&colorized, 0, "%s", colorized_tags[c].init);
         if (!colorized) {
            return NULL;
         }
         {
            char buf[len + 1];
            ast_copy_string(buf, bwinput + i + strlen(colorized_tags[c].inittag), sizeof(buf));
            ast_str_append(&colorized, 0, "%s", buf);
         }
         if (!colorized) {
            return NULL;
         }

         /* copy the ending string replace */
         ast_str_append(&colorized, 0, "%s", colorized_tags[c].end);
         if (!colorized) {
            return NULL;
         }

         /* Continue with the last color. */
         if (withcolors) {
            ast_term_color_code(&colorized, base_fg, 0);
            if (!colorized) {
               return NULL;
            }
         }

         i += len + strlen(colorized_tags[c].endtag) + strlen(colorized_tags[c].inittag) - 1;
         colorsection = 1;
         break;
      }

      if (!colorsection) {
         ast_str_append(&colorized, 0, "%c", bwinput[i]);
         if (!colorized) {
            return NULL;
         }
      }
   }

   if (withcolors) {
      ast_str_append(&colorized, 0, "%s", term_end());
      if (!colorized) {
         return NULL;
      }
   }

   /* Wrap the text, notice that string wrap will avoid cutting an ESC sequence. */
   wrapped = xmldoc_string_wrap(ast_str_buffer(colorized), xmldoc_text_columns, xmldoc_max_diff);

   ast_free(colorized);

   return wrapped;
}
static int xmldoc_attribute_match ( struct ast_xml_node *  node,
const char *  attr,
const char *  value 
) [static]

Definition at line 466 of file xmldoc.c.

References ast_xml_free_attr(), ast_xml_get_attribute(), and match().

Referenced by xmldoc_get_node().

{
   const char *attr_value = ast_xml_get_attribute(node, attr);
   int match = attr_value && !strcmp(attr_value, value);
   ast_xml_free_attr(attr_value);
   return match;
}
static char* xmldoc_build_field ( const char *  type,
const char *  name,
const char *  module,
const char *  var,
int  raw 
) [static]

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

Parameters:
typeType of element (application, function, ...).
nameName of element (Dial, Echo, Playback, ...).
varName of field to return (synopsis, description, etc).
rawField only contains text, no other elements inside it.
Return values:
NULLOn error.
Fieldtext content on success.

Definition at line 1825 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().

{
   struct ast_xml_node *node;
   char *ret = NULL;
   struct ast_str *formatted;

   if (ast_strlen_zero(type) || ast_strlen_zero(name)) {
      ast_log(LOG_ERROR, "Tried to look in XML tree with faulty values.\n");
      return ret;
   }

   node = xmldoc_get_node(type, name, module, documentation_language);

   if (!node) {
      ast_log(LOG_WARNING, "Couldn't find %s %s in XML documentation\n", type, name);
      return ret;
   }

   node = ast_xml_find_element(ast_xml_node_get_children(node), var, NULL, NULL);

   if (!node || !ast_xml_node_get_children(node)) {
      ast_log(LOG_DEBUG, "Cannot find variable '%s' in tree '%s'\n", var, name);
      return ret;
   }

   formatted = xmldoc_get_formatted(node, raw, raw);
   if (ast_str_strlen(formatted) > 0) {
      ret = ast_strdup(ast_str_buffer(formatted));
   }
   ast_free(formatted);

   return ret;
}
static int xmldoc_foundspace_backward ( const char *  text,
int  currentpos,
int  maxdiff 
) [static]

Definition at line 205 of file xmldoc.c.

Referenced by xmldoc_string_wrap().

{
   int i;

   for (i = currentpos; i > 0; i--) {
      if (text[i] == ' ' || text[i] == '\n') {
         return (currentpos - i);
      } else if (text[i] == 'm' && (text[i - 1] >= '0' || text[i - 1] <= '9')) {
         /* give up, we found the end of a possible ESC sequence. */
         return 0;
      } else if (currentpos - i > maxdiff) {
         /* give up, we can't move anymore. */
         return 0;
      }
   }

   /* we found the beginning of the text */

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

Definition at line 1783 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().

{
   struct ast_xml_node *tmp;
   const char *notcleanret, *tmpstr;
   struct ast_str *ret = ast_str_create(128);

   if (raw_output) {
      notcleanret = ast_xml_get_text(node);
      tmpstr = notcleanret;
      xmldoc_string_cleanup(ast_skip_blanks(notcleanret), &ret, 0);
      ast_xml_free_text(tmpstr);
   } else {
      for (tmp = ast_xml_node_get_children(node); tmp; tmp = ast_xml_node_get_next(tmp)) {
         /* if found, parse a <para> element. */
         if (xmldoc_parse_para(tmp, "", "\n", &ret)) {
            continue;
         } else if (xmldoc_parse_specialtags(tmp, "", "\n", &ret)) {
            continue;
         }
         /* if found, parse a <variablelist> element. */
         xmldoc_parse_variablelist(tmp, "", &ret);
         xmldoc_parse_enumlist(tmp, "    ", &ret);
      }
      /* remove last '\n' */
      /* XXX Don't modify ast_str internals manually */
      tmpstr = ast_str_buffer(ret);
      if (tmpstr[ast_str_strlen(ret) - 1] == '\n') {
         ast_str_truncate(ret, -1);
      }
   }
   return ret;
}
static struct ast_xml_node* xmldoc_get_node ( const char *  type,
const char *  name,
const char *  module,
const char *  language 
) [static, read]

Definition at line 485 of file xmldoc.c.

References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_strlen_zero(), ast_xml_find_element(), ast_xml_get_root(), ast_xml_node_get_children(), ast_xml_node_get_next(), documentation_tree::doc, and xmldoc_attribute_match().

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

{
   struct ast_xml_node *node = NULL;
   struct ast_xml_node *first_match = NULL;
   struct ast_xml_node *lang_match = NULL;
   struct documentation_tree *doctree;

   AST_RWLIST_RDLOCK(&xmldoc_tree);
   AST_LIST_TRAVERSE(&xmldoc_tree, doctree, entry) {
      /* the core xml documents have priority over thirdparty document. */
      node = ast_xml_get_root(doctree->doc);
      if (!node) {
         break;
      }

      node = ast_xml_node_get_children(node);
      while ((node = ast_xml_find_element(node, type, "name", name))) {
         if (!ast_xml_node_get_children(node)) {
            /* ignore empty nodes */
            node = ast_xml_node_get_next(node);
            continue;
         }

         if (!first_match) {
            first_match = node;
         }

         /* Check language */
         if (xmldoc_attribute_match(node, "language", language)) {
            if (!lang_match) {
               lang_match = node;
            }

            /* if module is empty we have a match */
            if (ast_strlen_zero(module)) {
               break;
            }

            /* Check module */
            if (xmldoc_attribute_match(node, "module", module)) {
               break;
            }
         }

         node = ast_xml_node_get_next(node);
      }

      /* if we matched lang and module return this match */
      if (node) {
         break;
      }

      /* we didn't match lang and module, just return the first
       * result with a matching language if we have one */
      if (lang_match) {
         node = lang_match;
         break;
      }

      /* we didn't match with only the language, just return the
       * first match */
      if (first_match) {
         node = first_match;
         break;
      }
   }
   AST_RWLIST_UNLOCK(&xmldoc_tree);

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

Definition at line 950 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().

{
   struct ast_str *syntax;
   struct ast_xml_node *tmpnode, *node = fixnode;
   char *ret, *paramname;
   const char *paramtype, *attrname, *literal;
   int required, isenum, first = 1, isliteral;

   syntax = ast_str_create(128);
   if (!syntax) {
      /* at least try to return something... */
      return ast_strdup(name);
   }

   /* append name to output string. */
   if (printname) {
      ast_str_append(&syntax, 0, "%s", name);
      first = 0;
   }

   for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
      if (strcasecmp(ast_xml_node_get_name(node), "parameter")) {
         continue;
      }

      if (xmldoc_has_inside(node, "parameter")) {
         /* is this a recursive parameter. */
         paramname = xmldoc_get_syntax_cmd(node, "", 0);
         isenum = 1;
      } else if (!xmldoc_has_inside(node, "enumlist")) {
         /* this is a simple parameter. */
         attrname = ast_xml_get_attribute(node, "name");
         if (!attrname) {
            /* ignore this bogus parameter and continue. */
            continue;
         }
         paramname = ast_strdup(attrname);
         ast_xml_free_attr(attrname);
         isenum = 0;
      } else {
         /* parse enumlist (note that this is a special enumlist
         that is used to describe a syntax like {<param1>|<param2>|...} */
         for (tmpnode = ast_xml_node_get_children(node); tmpnode; tmpnode = ast_xml_node_get_next(tmpnode)) {
            if (!strcasecmp(ast_xml_node_get_name(tmpnode), "enumlist")) {
               break;
            }
         }
         paramname = xmldoc_parse_cmd_enumlist(tmpnode);
         isenum = 1;
      }

      /* Is this parameter required? */
      required = 0;
      paramtype = ast_xml_get_attribute(node, "required");
      if (paramtype) {
         required = ast_true(paramtype);
         ast_xml_free_attr(paramtype);
      }

      /* Is this a replaceable value or a fixed parameter value? */
      isliteral = 0;
      literal = ast_xml_get_attribute(node, "literal");
      if (literal) {
         isliteral = ast_true(literal);
         ast_xml_free_attr(literal);
      }

      /* if required="false" print with [...].
       * if literal="true" or is enum print without <..>.
       * if not first print a space at the beginning.
       */
      ast_str_append(&syntax, 0, "%s%s%s%s%s%s",
            (first ? "" : " "),
            (required ? "" : "["),
            (isenum || isliteral ? "" : "<"),
            paramname,
            (isenum || isliteral ? "" : ">"),
            (required ? "" : "]"));
      first = 0;
      ast_free(paramname);
   }

   /* return a common string. */
   ret = ast_strdup(ast_str_buffer(syntax));
   ast_free(syntax);

   return ret;
}
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 672 of file xmldoc.c.

References ast_asprintf, ast_free, ast_log(), ast_strdup, ast_strdupa, 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().

{
#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 : ""))
   struct ast_xml_node *node = NULL, *firstparam = NULL, *lastparam = NULL;
   const char *paramtype, *multipletype, *paramnameattr, *attrargsep, *parenthesis, *argname;
   int reverse, required, paramcount = 0, openbrackets = 0, len = 0, hasparams=0;
   int reqfinode = 0, reqlanode = 0, optmidnode = 0, prnparenthesis, multiple;
   char *syntax = NULL, *argsep, *paramname;

   if (ast_strlen_zero(rootname) || ast_strlen_zero(childname)) {
      ast_log(LOG_WARNING, "Tried to look in XML tree with faulty rootname or childname while creating a syntax.\n");
      return NULL;
   }

   if (!rootnode || !ast_xml_node_get_children(rootnode)) {
      /* If the rootnode field is not found, at least print name. */
      ast_asprintf(&syntax, "%s%s", (printrootname ? rootname : ""), (printparenthesis ? "()" : ""));
      return syntax;
   }

   /* Get the argument separator from the root node attribute name 'argsep', if not found
   defaults to ','. */
   attrargsep = ast_xml_get_attribute(rootnode, "argsep");
   if (attrargsep) {
      argsep = ast_strdupa(attrargsep);
      ast_xml_free_attr(attrargsep);
   } else {
      argsep = ast_strdupa(",");
   }

   /* Get order of evaluation. */
   for (node = ast_xml_node_get_children(rootnode); node; node = ast_xml_node_get_next(node)) {
      if (strcasecmp(ast_xml_node_get_name(node), childname)) {
         continue;
      }
      required = 0;
      hasparams = 1;
      if ((paramtype = ast_xml_get_attribute(node, "required"))) {
         if (ast_true(paramtype)) {
            required = 1;
         }
         ast_xml_free_attr(paramtype);
      }

      lastparam = node;
      reqlanode = required;

      if (!firstparam) {
         /* first parameter node */
         firstparam = node;
         reqfinode = required;
      }
   }

   if (!hasparams) {
      /* This application, function, option, etc, doesn't have any params. */
      ast_asprintf(&syntax, "%s%s", (printrootname ? rootname : ""), (printparenthesis ? "()" : ""));
      return syntax;
   }

   if (reqfinode && reqlanode) {
      /* check midnode */
      for (node = ast_xml_node_get_children(rootnode); node; node = ast_xml_node_get_next(node)) {
         if (strcasecmp(ast_xml_node_get_name(node), childname)) {
            continue;
         }
         if (node != firstparam && node != lastparam) {
            if ((paramtype = ast_xml_get_attribute(node, "required"))) {
               if (!ast_true(paramtype)) {
                  optmidnode = 1;
                  break;
               }
               ast_xml_free_attr(paramtype);
            }
         }
      }
   }

   if ((!reqfinode && reqlanode) || (reqfinode && reqlanode && optmidnode)) {
      reverse = 1;
      node = lastparam;
   } else {
      reverse = 0;
      node = firstparam;
   }

   /* init syntax string. */
   if (reverse) {
      xmldoc_reverse_helper(reverse, &len, &syntax,
         (printrootname ? (printrootname == 2 ? ")]" : ")"): ""));
   } else {
      xmldoc_reverse_helper(reverse, &len, &syntax, "%s%s", (printrootname ? rootname : ""),
         (printrootname ? (printrootname == 2 ? "[(" : "(") : ""));
   }

   for (; node; node = GOTONEXT(reverse, node)) {
      if (strcasecmp(ast_xml_node_get_name(node), childname)) {
         continue;
      }

      /* Get the argument name, if it is not the leaf, go inside that parameter. */
      if (xmldoc_has_inside(node, "argument")) {
         parenthesis = ast_xml_get_attribute(node, "hasparams");
         prnparenthesis = 0;
         if (parenthesis) {
            prnparenthesis = ast_true(parenthesis);
            if (!strcasecmp(parenthesis, "optional")) {
               prnparenthesis = 2;
            }
            ast_xml_free_attr(parenthesis);
         }
         argname = ast_xml_get_attribute(node, "name");
         if (argname) {
            paramname = xmldoc_get_syntax_fun(node, argname, "argument", prnparenthesis, prnparenthesis);
            ast_xml_free_attr(argname);
         } else {
            /* Malformed XML, print **UNKOWN** */
            paramname = ast_strdup("**unknown**");
         }
      } else {
         paramnameattr = ast_xml_get_attribute(node, "name");
         if (!paramnameattr) {
            ast_log(LOG_WARNING, "Malformed XML %s: no %s name\n", rootname, childname);
            if (syntax) {
               /* Free already allocated syntax */
               ast_free(syntax);
            }
            /* to give up is ok? */
            ast_asprintf(&syntax, "%s%s", (printrootname ? rootname : ""), (printparenthesis ? "()" : ""));
            return syntax;
         }
         paramname = ast_strdup(paramnameattr);
         ast_xml_free_attr(paramnameattr);
      }

      /* Defaults to 'false'. */
      multiple = 0;
      if ((multipletype = ast_xml_get_attribute(node, "multiple"))) {
         if (ast_true(multipletype)) {
            multiple = 1;
         }
         ast_xml_free_attr(multipletype);
      }

      required = 0;  /* Defaults to 'false'. */
      if ((paramtype = ast_xml_get_attribute(node, "required"))) {
         if (ast_true(paramtype)) {
            required = 1;
         }
         ast_xml_free_attr(paramtype);
      }

      /* build syntax core. */

      if (required) {
         /* First parameter */
         if (!paramcount) {
            xmldoc_reverse_helper(reverse, &len, &syntax, "%s%s%s%s", paramname, MP("["), MP(argsep), MP("...]"));
         } else {
            /* Time to close open brackets. */
            while (openbrackets > 0) {
               xmldoc_reverse_helper(reverse, &len, &syntax, (reverse ? "[" : "]"));
               openbrackets--;
            }
            if (reverse) {
               xmldoc_reverse_helper(reverse, &len, &syntax, "%s%s", paramname, argsep);
            } else {
               xmldoc_reverse_helper(reverse, &len, &syntax, "%s%s", argsep, paramname);
            }
            xmldoc_reverse_helper(reverse, &len, &syntax, "%s%s%s", MP("["), MP(argsep), MP("...]"));
         }
      } else {
         /* First parameter */
         if (!paramcount) {
            xmldoc_reverse_helper(reverse, &len, &syntax, "[%s%s%s%s]", paramname, MP("["), MP(argsep), MP("...]"));
         } else {
            if (ISLAST(reverse, node)) {
               /* This is the last parameter. */
               if (reverse) {
                  xmldoc_reverse_helper(reverse, &len, &syntax, "[%s%s%s%s]%s", paramname,
                           MP("["), MP(argsep), MP("...]"), argsep);
               } else {
                  xmldoc_reverse_helper(reverse, &len, &syntax, "%s[%s%s%s%s]", argsep, paramname,
                           MP("["), MP(argsep), MP("...]"));
               }
            } else {
               if (reverse) {
                  xmldoc_reverse_helper(reverse, &len, &syntax, "%s%s%s%s%s]", paramname, argsep,
                           MP("["), MP(argsep), MP("...]"));
               } else {
                  xmldoc_reverse_helper(reverse, &len, &syntax, "[%s%s%s%s%s", argsep, paramname,
                           MP("["), MP(argsep), MP("...]"));
               }
               openbrackets++;
            }
         }
      }
      ast_free(paramname);

      paramcount++;
   }

   /* Time to close open brackets. */
   while (openbrackets > 0) {
      xmldoc_reverse_helper(reverse, &len, &syntax, (reverse ? "[" : "]"));
      openbrackets--;
   }

   /* close syntax string. */
   if (reverse) {
      xmldoc_reverse_helper(reverse, &len, &syntax, "%s%s", (printrootname ? rootname : ""),
         (printrootname ? (printrootname == 2 ? "[(" : "(") : ""));
   } else {
      xmldoc_reverse_helper(reverse, &len, &syntax, (printrootname ? (printrootname == 2 ? ")]" : ")") : ""));
   }

   return syntax;
#undef ISLAST
#undef GOTONEXT
#undef MP
}
static char* xmldoc_get_syntax_manager ( struct ast_xml_node *  fixnode,
const char *  name 
) [static]

Definition at line 1046 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(), and ast_xml_node_get_next().

Referenced by ast_xmldoc_build_syntax().

{
   struct ast_str *syntax;
   struct ast_xml_node *node = fixnode;
   const char *paramtype, *attrname;
   int required;
   char *ret;

   syntax = ast_str_create(128);
   if (!syntax) {
      return ast_strdup(name);
   }

   ast_str_append(&syntax, 0, "Action: %s", name);

   for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
      if (strcasecmp(ast_xml_node_get_name(node), "parameter")) {
         continue;
      }

      /* Is this parameter required? */
      required = 0;
      paramtype = ast_xml_get_attribute(node, "required");
      if (paramtype) {
         required = ast_true(paramtype);
         ast_xml_free_attr(paramtype);
      }

      attrname = ast_xml_get_attribute(node, "name");
      if (!attrname) {
         /* ignore this bogus parameter and continue. */
         continue;
      }

      ast_str_append(&syntax, 0, "\n%s%s:%s <value>",
         (required ? "" : "["),
         attrname,
         (required ? "" : "]"));

      ast_xml_free_attr(attrname);
   }

   /* return a common string. */
   ret = ast_strdup(ast_str_buffer(syntax));
   ast_free(syntax);

   return ret;
}
static enum syntaxtype xmldoc_get_syntax_type ( const char *  type) [static]

Definition at line 1118 of file xmldoc.c.

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

Referenced by ast_xmldoc_build_syntax().

{
   int i;
   for (i=0; i < ARRAY_LEN(stxtype); i++) {
      if (!strcasecmp(stxtype[i].type, type)) {
         return stxtype[i].stxtype;
      }
   }

   return FUNCTION_SYNTAX;
}
static int xmldoc_has_inside ( struct ast_xml_node *  fixnode,
const char *  what 
) [static]

Definition at line 611 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().

{
   struct ast_xml_node *node = fixnode;

   for (node = ast_xml_node_get_children(fixnode); node; node = ast_xml_node_get_next(node)) {
      if (!strcasecmp(ast_xml_node_get_name(node), what)) {
         return 1;
      }
   }
   return 0;
}
static int xmldoc_has_nodes ( struct ast_xml_node *  fixnode) [static]

Definition at line 629 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().

{
   struct ast_xml_node *node = fixnode;

   for (node = ast_xml_node_get_children(fixnode); node; node = ast_xml_node_get_next(node)) {
      if (strcasecmp(ast_xml_node_get_name(node), "text")) {
         return 1;
      }
   }
   return 0;
}
static int xmldoc_has_specialtags ( struct ast_xml_node *  fixnode) [static]

Definition at line 647 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().

{
   struct ast_xml_node *node = fixnode;
   int i;

   for (node = ast_xml_node_get_children(fixnode); node; node = ast_xml_node_get_next(node)) {
      for (i = 0; i < ARRAY_LEN(special_tags); i++) {
         if (!strcasecmp(ast_xml_node_get_name(node), special_tags[i].tagname)) {
            return 1;
         }
      }
   }
   return 0;
}
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 1280 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().

{
   struct ast_xml_node *node = fixnode;
   const char *argname;
   int count = 0, ret = 0;

   if (!node || !ast_xml_node_get_children(node)) {
      return ret;
   }

   /* Print the argument names */
   argname = ast_xml_get_attribute(node, "name");
   if (!argname) {
      return 0;
   }
   if (xmldoc_has_inside(node, "para") || xmldoc_has_specialtags(node)) {
      ast_str_append(buffer, 0, "%s%s%s", tabs, argname, (insideparameter ? "\n" : ""));
      ast_xml_free_attr(argname);
   } else {
      ast_xml_free_attr(argname);
      return 0;
   }

   for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
      if (xmldoc_parse_para(node, (insideparameter ? paramtabs : (!count ? " - " : tabs)), "\n", buffer) == 2) {
         count++;
         ret = 1;
      } else if (xmldoc_parse_specialtags(node, (insideparameter ? paramtabs : (!count ? " - " : tabs)), "\n", buffer) == 2) {
         count++;
         ret = 1;
      }
   }

   return ret;
}
static char* xmldoc_parse_cmd_enumlist ( struct ast_xml_node *  fixnode) [static]

Definition at line 903 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().

{
   struct ast_xml_node *node = fixnode;
   struct ast_str *paramname;
   char *enumname, *ret;
   int first = 1;

   paramname = ast_str_create(128);
   if (!paramname) {
      return ast_strdup("{<unkown>}");
   }

   ast_str_append(&paramname, 0, "{");

   for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
      if (strcasecmp(ast_xml_node_get_name(node), "enum")) {
         continue;
      }

      enumname = xmldoc_get_syntax_cmd(node, "", 0);
      if (!enumname) {
         continue;
      }
      if (!first) {
         ast_str_append(&paramname, 0, "|");
      }
      ast_str_append(&paramname, 0, "%s", enumname);
      first = 0;
      ast_free(enumname);
   }

   ast_str_append(&paramname, 0, "}");

   ret = ast_strdup(ast_str_buffer(paramname));
   ast_free(paramname);

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

Definition at line 1516 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().

{
   struct ast_xml_node *node = fixnode;
   int ret = 0;
   char *optiontabs;

   ast_asprintf(&optiontabs, "%s    ", tabs);

   for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
      if ((xmldoc_parse_para(node, (ret ? tabs : " - "), "\n", buffer))) {
         ret = 1;
      } else if ((xmldoc_parse_specialtags(node, (ret ? tabs : " - "), "\n", buffer))) {
         ret = 1;
      }

      xmldoc_parse_enumlist(node, optiontabs, buffer);
   }

   ast_free(optiontabs);

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

Definition at line 1546 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().

{
   struct ast_xml_node *node = fixnode;
   const char *enumname;
   int ret = 0;

   for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
      if (strcasecmp(ast_xml_node_get_name(node), "enum")) {
         continue;
      }

      enumname = ast_xml_get_attribute(node, "name");
      if (enumname) {
         ast_str_append(buffer, 0, "%s<enum>%s</enum>", tabs, enumname);
         ast_xml_free_attr(enumname);

         /* parse only enum elements inside a enumlist node. */
         if ((xmldoc_parse_enum(node, tabs, buffer))) {
            ret = 1;
         } else {
            ast_str_append(buffer, 0, "\n");
         }
      }
   }
   return ret;
}
static int xmldoc_parse_option ( struct ast_xml_node *  fixnode,
const char *  tabs,
struct ast_str **  buffer 
) [static]

Definition at line 1582 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().

{
   struct ast_xml_node *node;
   int ret = 0;
   char *optiontabs;

   ast_asprintf(&optiontabs, "%s    ", tabs);
   if (!optiontabs) {
      return ret;
   }
   for (node = ast_xml_node_get_children(fixnode); node; node = ast_xml_node_get_next(node)) {
      if (!strcasecmp(ast_xml_node_get_name(node), "argument")) {
         /* if this is the first data appended to buffer, print a \n*/
         if (!ret && ast_xml_node_get_children(node)) {
            /* print \n */
            ast_str_append(buffer, 0, "\n");
         }
         if (xmldoc_parse_argument(node, 0, NULL, optiontabs, buffer)) {
            ret = 1;
         }
         continue;
      }

      if (xmldoc_parse_para(node, (ret ? tabs :  ""), "\n", buffer)) {
         ret = 1;
      } else if (xmldoc_parse_specialtags(node, (ret ? tabs :  ""), "\n", buffer)) {
         ret = 1;
      }

      xmldoc_parse_variablelist(node, optiontabs, buffer);

      xmldoc_parse_enumlist(node, optiontabs, buffer);
   }
   ast_free(optiontabs);

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

Definition at line 1627 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().

{
   struct ast_xml_node *node;
   const char *optname, *hasparams;
   char *optionsyntax;
   int optparams;

   for (node = ast_xml_node_get_children(fixnode); node; node = ast_xml_node_get_next(node)) {
      /* Start appending every option tag. */
      if (strcasecmp(ast_xml_node_get_name(node), "option")) {
         continue;
      }

      /* Get the option name. */
      optname = ast_xml_get_attribute(node, "name");
      if (!optname) {
         continue;
      }

      optparams = 1;
      hasparams = ast_xml_get_attribute(node, "hasparams");
      if (hasparams && !strcasecmp(hasparams, "optional")) {
         optparams = 2;
      }

      optionsyntax = xmldoc_get_syntax_fun(node, optname, "argument", 0, optparams);
      if (!optionsyntax) {
         ast_xml_free_attr(optname);
         ast_xml_free_attr(hasparams);
         continue;
      }

      ast_str_append(buffer, 0, "%s%s: ", tabs, optionsyntax);

      if (!xmldoc_parse_option(node, tabs, buffer)) {
         ast_str_append(buffer, 0, "\n");
      }
      ast_str_append(buffer, 0, "\n");
      ast_xml_free_attr(optname);
      ast_xml_free_attr(hasparams);
   }
}
static int xmldoc_parse_para ( struct ast_xml_node *  node,
const char *  tabs,
const char *  posttabs,
struct ast_str **  buffer 
) [static]

Definition at line 1176 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().

{
   const char *tmptext;
   struct ast_xml_node *tmp;
   int ret = 0;
   struct ast_str *tmpstr;

   if (!node || !ast_xml_node_get_children(node)) {
      return ret;
   }

   if (strcasecmp(ast_xml_node_get_name(node), "para")) {
      return ret;
   }

   ast_str_append(buffer, 0, "%s", tabs);

   ret = 1;

   for (tmp = ast_xml_node_get_children(node); tmp; tmp = ast_xml_node_get_next(tmp)) {
      /* Get the text inside the <para> element and append it to buffer. */
      tmptext = ast_xml_get_text(tmp);
      if (tmptext) {
         /* Strip \n etc. */
         xmldoc_string_cleanup(tmptext, &tmpstr, 0);
         ast_xml_free_text(tmptext);
         if (tmpstr) {
            if (strcasecmp(ast_xml_node_get_name(tmp), "text")) {
               ast_str_append(buffer, 0, "<%s>%s</%s>", ast_xml_node_get_name(tmp),
                     ast_str_buffer(tmpstr), ast_xml_node_get_name(tmp));
            } else {
               ast_str_append(buffer, 0, "%s", ast_str_buffer(tmpstr));
            }
            ast_free(tmpstr);
            ret = 2;
         }
      }
   }

   ast_str_append(buffer, 0, "%s", posttabs);

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

Definition at line 1677 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().

{
   const char *paramname;
   struct ast_xml_node *node = fixnode;
   int hasarguments, printed = 0;
   char *internaltabs;

   if (strcasecmp(ast_xml_node_get_name(node), "parameter")) {
      return;
   }

   hasarguments = xmldoc_has_inside(node, "argument");
   if (!(paramname = ast_xml_get_attribute(node, "name"))) {
      /* parameter MUST have an attribute name. */
      return;
   }

   ast_asprintf(&internaltabs, "%s    ", tabs);
   if (!internaltabs) {
      return;
   }

   if (!hasarguments && xmldoc_has_nodes(node)) {
      ast_str_append(buffer, 0, "%s\n", paramname);
      ast_xml_free_attr(paramname);
      printed = 1;
   }

   for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
      if (!strcasecmp(ast_xml_node_get_name(node), "optionlist")) {
         xmldoc_parse_optionlist(node, internaltabs, buffer);
      } else if (!strcasecmp(ast_xml_node_get_name(node), "enumlist")) {
         xmldoc_parse_enumlist(node, internaltabs, buffer);
      } else if (!strcasecmp(ast_xml_node_get_name(node), "argument")) {
         xmldoc_parse_argument(node, 1, internaltabs, (!hasarguments ? "        " : ""), buffer);
      } else if (!strcasecmp(ast_xml_node_get_name(node), "para")) {
         if (!printed) {
            ast_str_append(buffer, 0, "%s\n", paramname);
            ast_xml_free_attr(paramname);
            printed = 1;
         }
         xmldoc_parse_para(node, internaltabs, "\n", buffer);
         continue;
      } else if ((xmldoc_parse_specialtags(node, internaltabs, "\n", buffer))) {
         continue;
      }
   }
   if (!printed) {
      ast_xml_free_attr(paramname);
   }
   ast_free(internaltabs);
}
static int xmldoc_parse_specialtags ( struct ast_xml_node *  fixnode,
const char *  tabs,
const char *  posttabs,
struct ast_str **  buffer 
) [static]

Definition at line 1230 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().

{
   struct ast_xml_node *node = fixnode;
   int ret = 0, i, count = 0;

   if (!node || !ast_xml_node_get_children(node)) {
      return ret;
   }

   for (i = 0; i < ARRAY_LEN(special_tags); i++) {
      if (strcasecmp(ast_xml_node_get_name(node), special_tags[i].tagname)) {
         continue;
      }

      ret = 1;
      /* This is a special tag. */

      /* concat data */
      if (!ast_strlen_zero(special_tags[i].init)) {
         ast_str_append(buffer, 0, "%s%s", tabs, special_tags[i].init);
      }

      /* parse <para> elements inside special tags. */
      for (node = ast_xml_node_get_children(node); node; node = ast_xml_node_get_next(node)) {
         /* first <para> just print it without tabs at the begining. */
         if (xmldoc_parse_para(node, (!count ? "" : tabs), posttabs, buffer) == 2) {
            ret = 2;
         }
      }

      if (!ast_strlen_zero(special_tags[i].end)) {
         ast_str_append(buffer, 0, "%s%s", special_tags[i].end, posttabs);
      }

      break;
   }

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

Definition at line 1327 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().

{
   struct ast_xml_node *tmp;
   const char *valname;
   const char *tmptext;
   struct ast_str *cleanstr;
   int ret = 0, printedpara=0;

   for (tmp = ast_xml_node_get_children(node); tmp; tmp = ast_xml_node_get_next(tmp)) {
      if (xmldoc_parse_para(tmp, (ret ? tabs : ""), "\n", buffer)) {
         printedpara = 1;
         continue;
      } else if (xmldoc_parse_specialtags(tmp, (ret ? tabs : ""), "\n", buffer)) {
         printedpara = 1;
         continue;
      }

      if (strcasecmp(ast_xml_node_get_name(tmp), "value")) {
         continue;
      }

      /* Parse a <value> tag only. */
      if (!printedpara) {
         ast_str_append(buffer, 0, "\n");
         printedpara = 1;
      }
      /* Parse each <value name='valuename'>desciption</value> */
      valname = ast_xml_get_attribute(tmp, "name");
      if (valname) {
         ret = 1;
         ast_str_append(buffer, 0, "%s<value>%s</value>", tabs, valname);
         ast_xml_free_attr(valname);
      }
      tmptext = ast_xml_get_text(tmp);
      /* Check inside this node for any explanation about its meaning. */
      if (tmptext) {
         /* Cleanup text. */
         xmldoc_string_cleanup(tmptext, &cleanstr, 1);
         ast_xml_free_text(tmptext);
         if (cleanstr && ast_str_strlen(cleanstr) > 0) {
            ast_str_append(buffer, 0, ":%s", ast_str_buffer(cleanstr));
         }
         ast_free(cleanstr);
      }
      ast_str_append(buffer, 0, "\n");
   }

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

Definition at line 1388 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().

{
   struct ast_xml_node *tmp;
   const char *varname;
   char *vartabs;
   int ret = 0;

   if (!node || !ast_xml_node_get_children(node)) {
      return ret;
   }

   if (strcasecmp(ast_xml_node_get_name(node), "variablelist")) {
      return ret;
   }

   /* use this spacing (add 4 spaces) inside a variablelist node. */
   ast_asprintf(&vartabs, "%s    ", tabs);
   if (!vartabs) {
      return ret;
   }
   for (tmp = ast_xml_node_get_children(node); tmp; tmp = ast_xml_node_get_next(tmp)) {
      /* We can have a <para> element inside the variable list */
      if ((xmldoc_parse_para(tmp, (ret ? tabs : ""), "\n", buffer))) {
         ret = 1;
         continue;
      } else if ((xmldoc_parse_specialtags(tmp, (ret ? tabs : ""), "\n", buffer))) {
         ret = 1;
         continue;
      }

      if (!strcasecmp(ast_xml_node_get_name(tmp), "variable")) {
         /* Store the variable name in buffer. */
         varname = ast_xml_get_attribute(tmp, "name");
         if (varname) {
            ast_str_append(buffer, 0, "%s<variable>%s</variable>: ", tabs, varname);
            ast_xml_free_attr(varname);
            /* Parse the <variable> possible values. */
            xmldoc_parse_variable(tmp, vartabs, buffer);
            ret = 1;
         }
      }
   }

   ast_free(vartabs);

   return ret;
}
static int xmldoc_postbrlen ( const char *  postbr) [static]

Definition at line 111 of file xmldoc.c.

Referenced by xmldoc_string_wrap().

{
   int postbrreallen = 0, i;
   size_t postbrlen;

   if (!postbr) {
      return 0;
   }
   postbrlen = strlen(postbr);
   for (i = 0; i < postbrlen; i++) {
      if (postbr[i] == '\t') {
         postbrreallen += 8 - (postbrreallen % 8);
      } else {
         postbrreallen++;
      }
   }
   return postbrreallen;
}
static void xmldoc_reverse_helper ( int  reverse,
int *  len,
char **  syntax,
const char *  fmt,
  ... 
) [static]

Definition at line 565 of file xmldoc.c.

References ast_free, ast_realloc, and ast_vasprintf.

Referenced by xmldoc_get_syntax_fun().

{
   int totlen, tmpfmtlen;
   char *tmpfmt, tmp;
   va_list ap;

   va_start(ap, fmt);
   if (ast_vasprintf(&tmpfmt, fmt, ap) < 0) {
      va_end(ap);
      return;
   }
   va_end(ap);

   tmpfmtlen = strlen(tmpfmt);
   totlen = *len + tmpfmtlen + 1;

   *syntax = ast_realloc(*syntax, totlen);

   if (!*syntax) {
      ast_free(tmpfmt);
      return;
   }

   if (reverse) {
      memmove(*syntax + tmpfmtlen, *syntax, *len);
      /* Save this char, it will be overwritten by the \0 of strcpy. */
      tmp = (*syntax)[0];
      strcpy(*syntax, tmpfmt);
      /* Restore the already saved char. */
      (*syntax)[tmpfmtlen] = tmp;
      (*syntax)[totlen - 1] = '\0';
   } else {
      strcpy(*syntax + *len, tmpfmt);
   }

   *len = totlen - 1;
   ast_free(tmpfmt);
}
static void xmldoc_setpostbr ( char *  postbr,
size_t  len,
const char *  text 
) [static]

Definition at line 137 of file xmldoc.c.

References len().

Referenced by xmldoc_string_wrap().

{
   int c, postbrlen = 0;

   if (!text) {
      return;
   }

   for (c = 0; c < len; c++) {
      if (text[c] == '\t' || text[c] == ' ') {
         postbr[postbrlen++] = text[c];
      } else {
         break;
      }
   }
   postbr[postbrlen] = '\0';
}
static void xmldoc_string_cleanup ( const char *  text,
struct ast_str **  output,
int  lastspaces 
) [static]

Definition at line 421 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().

{
   int i;
   size_t textlen;

   if (!text) {
      *output = NULL;
      return;
   }

   textlen = strlen(text);

   *output = ast_str_create(textlen);
   if (!(*output)) {
      ast_log(LOG_ERROR, "Problem allocating output buffer\n");
      return;
   }

   for (i = 0; i < textlen; i++) {
      if (text[i] == '\n' || text[i] == '\r') {
         /* remove spaces/tabs/\n after a \n. */
         while (text[i + 1] == '\t' || text[i + 1] == '\r' || text[i + 1] == '\n') {
            i++;
         }
         ast_str_append(output, 0, " ");
         continue;
      } else {
         ast_str_append(output, 0, "%c", text[i]);
      }
   }

   /* remove last spaces (we don't want always to remove the trailing spaces). */
   if (lastspaces) {
      ast_str_trim_blanks(*output);
   }
}
static char* xmldoc_string_wrap ( const char *  text,
int  columns,
int  maxdiff 
) [static]

Definition at line 234 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().

{
   struct ast_str *tmp;
   char *ret, postbr[160];
   int count = 1, i, backspace, needtobreak = 0, colmax, textlen;

   /* sanity check */
   if (!text || columns <= 0 || maxdiff < 0) {
      ast_log(LOG_WARNING, "Passing wrong arguments while trying to wrap the text\n");
      return NULL;
   }

   tmp = ast_str_create(strlen(text) * 3);

   if (!tmp) {
      return NULL;
   }

   /* Check for blanks and tabs and put them in postbr. */
   xmldoc_setpostbr(postbr, sizeof(postbr), text);
   colmax = columns - xmldoc_postbrlen(postbr);

   textlen = strlen(text);
   for (i = 0; i < textlen; i++) {
      if (needtobreak || !(count % colmax)) {
         if (text[i] == ' ') {
            ast_str_append(&tmp, 0, "\n%s", postbr);
            needtobreak = 0;
            count = 1;
         } else if (text[i] != '\n') {
            needtobreak = 1;
            if (xmldoc_wait_nextspace(text, i, maxdiff)) {
               /* wait for the next space */
               ast_str_append(&tmp, 0, "%c", text[i]);
               continue;
            }
            /* Try to look backwards */
            backspace = xmldoc_foundspace_backward(text, i, maxdiff);
            if (backspace) {
               needtobreak = 1;
               ast_str_truncate(tmp, -backspace);
               i -= backspace + 1;
               continue;
            }
            ast_str_append(&tmp, 0, "\n%s", postbr);
            needtobreak = 0;
            count = 1;
         }
         /* skip blanks after a \n */
         while (text[i] == ' ') {
            i++;
         }
      }
      if (text[i] == '\n') {
         xmldoc_setpostbr(postbr, sizeof(postbr), &text[i] + 1);
         colmax = columns - xmldoc_postbrlen(postbr);
         needtobreak = 0;
         count = 1;
      }
      if (text[i] == ESC) {
         /* Ignore Escape sequences. */
         do {
            ast_str_append(&tmp, 0, "%c", text[i]);
            i++;
         } while (i < textlen && text[i] != 'm');
      } else {
         count++;
      }
      ast_str_append(&tmp, 0, "%c", text[i]);
   }

   ret = ast_strdup(ast_str_buffer(tmp));
   ast_free(tmp);

   return ret;
}
static void xmldoc_unload_documentation ( void  ) [static]
static int xmldoc_wait_nextspace ( const char *  text,
int  currentpos,
int  maxdiff 
) [static]

Definition at line 165 of file xmldoc.c.

References ESC.

Referenced by xmldoc_string_wrap().

{
   int i, textlen;

   if (!text) {
      return 0;
   }

   textlen = strlen(text);
   for (i = currentpos; i < textlen; i++) {
      if (text[i] == ESC) {
         /* Move to the end of the escape sequence */
         while (i < textlen && text[i] != 'm') {
            i++;
         }
      } else if (text[i] == ' ' || text[i] == '\n') {
         /* Found the next space or linefeed */
         return 1;
      } else if (i - currentpos > maxdiff) {
         /* We have looked the max distance and didn't find it */
         return 0;
      }
   }

   /* Reached the end and did not find it */

   return 0;
}

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 41 of file xmldoc.c.

char documentation_language[6] [static]

XML documentation language.

Definition at line 53 of file xmldoc.c.

struct strsyntaxtype stxtype[] [static]

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 50 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 45 of file xmldoc.c.

struct xmldoc_tree xmldoc_tree [static]