[asterisk-commits] eliel: branch group/appdocsxml r150561 - in /team/group/appdocsxml: ./ includ...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Oct 17 10:56:59 CDT 2008
Author: eliel
Date: Fri Oct 17 10:56:59 2008
New Revision: 150561
URL: http://svn.digium.com/view/asterisk?view=rev&rev=150561
Log:
Implements reading XML documentation from $(ASTDATADIR)/documentation & /documentation/thirdparty.
Every file named *-LANG.xml will be loaded from this directories where LANG is the actual language choice from asterisk.conf
option 'documentation_language'.
When searching for the documentation we look inside every loaded XML file.
Moved ast_load_documentation() from main/pbx.c to main/asterisk.c (this will fix the issue that appear in preloaded modules).
Fix a missing Synopsis in application 'Wait'.
Modified:
team/group/appdocsxml/Makefile
team/group/appdocsxml/include/asterisk/compat.h
team/group/appdocsxml/include/asterisk/pbx.h
team/group/appdocsxml/main/asterisk.c
team/group/appdocsxml/main/config.c
team/group/appdocsxml/main/pbx.c
Modified: team/group/appdocsxml/Makefile
URL: http://svn.digium.com/view/asterisk/team/group/appdocsxml/Makefile?view=diff&rev=150561&r1=150560&r2=150561
==============================================================================
--- team/group/appdocsxml/Makefile (original)
+++ team/group/appdocsxml/Makefile Fri Oct 17 10:56:59 2008
@@ -492,7 +492,7 @@
done ; \
done
@echo "</docs>" >> doc/core-en_US.xml
- @echo -e "\ndoc/core-en_US.xml --> $(ASTVARLIBDIR)/core-en_US.xml"
+ @echo -e "\ndoc/core-en_US.xml --> $(ASTDATADIR)/documentation/core-en_US.xml"
update:
@if [ -d .svn ]; then \
@@ -542,14 +542,16 @@
if [ -n "$(OLDHEADERS)" ]; then \
rm -f $(addprefix $(DESTDIR)$(ASTHEADERDIR)/,$(OLDHEADERS)) ;\
fi
+ mkdir -p $(DESTDIR)$(ASTDATADIR)/documentation
+ mkdir -p $(DESTDIR)$(ASTDATADIR)/documentation/thirdparty
mkdir -p $(DESTDIR)$(ASTLOGDIR)/cdr-csv
mkdir -p $(DESTDIR)$(ASTLOGDIR)/cdr-custom
mkdir -p $(DESTDIR)$(ASTDATADIR)/keys
mkdir -p $(DESTDIR)$(ASTDATADIR)/firmware
mkdir -p $(DESTDIR)$(ASTDATADIR)/firmware/iax
mkdir -p $(DESTDIR)$(ASTMANDIR)/man8
- $(INSTALL) -m 644 doc/core-*.xml $(ASTVARLIBDIR)
- $(INSTALL) -m 644 doc/appdocsxml.dtd $(ASTVARLIBDIR)
+ $(INSTALL) -m 644 doc/core-*.xml $(ASTDATADIR)/documentation
+ $(INSTALL) -m 644 doc/appdocsxml.dtd $(ASTVARLIBDIR)/documentation
$(INSTALL) -m 644 keys/iaxtel.pub $(DESTDIR)$(ASTDATADIR)/keys
$(INSTALL) -m 644 keys/freeworlddialup.pub $(DESTDIR)$(ASTDATADIR)/keys
$(INSTALL) -m 644 doc/asterisk.8 $(DESTDIR)$(ASTMANDIR)/man8
Modified: team/group/appdocsxml/include/asterisk/compat.h
URL: http://svn.digium.com/view/asterisk/team/group/appdocsxml/include/asterisk/compat.h?view=diff&rev=150561&r1=150560&r2=150561
==============================================================================
--- team/group/appdocsxml/include/asterisk/compat.h (original)
+++ team/group/appdocsxml/include/asterisk/compat.h Fri Oct 17 10:56:59 2008
@@ -182,4 +182,15 @@
typedef unsigned long long uint64_t;
#endif
+/* glob compat stuff */
+#if defined(__Darwin__) || defined(__CYGWIN__)
+#define GLOB_ABORTED GLOB_ABEND
#endif
+#include <glob.h>
+#ifdef SOLARIS
+#define MY_GLOB_FLAGS GLOB_NOCHECK
+#else
+#define MY_GLOB_FLAGS (GLOB_NOMAGIC|GLOB_BRACE)
+#endif
+
+#endif
Modified: team/group/appdocsxml/include/asterisk/pbx.h
URL: http://svn.digium.com/view/asterisk/team/group/appdocsxml/include/asterisk/pbx.h?view=diff&rev=150561&r1=150560&r2=150561
==============================================================================
--- team/group/appdocsxml/include/asterisk/pbx.h (original)
+++ team/group/appdocsxml/include/asterisk/pbx.h Fri Oct 17 10:56:59 2008
@@ -1019,6 +1019,9 @@
int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b);
unsigned int ast_hashtab_hash_contexts(const void *obj);
+/*! \brief Load XML documentation. */
+int ast_load_documentation(void);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
Modified: team/group/appdocsxml/main/asterisk.c
URL: http://svn.digium.com/view/asterisk/team/group/appdocsxml/main/asterisk.c?view=diff&rev=150561&r1=150560&r2=150561
==============================================================================
--- team/group/appdocsxml/main/asterisk.c (original)
+++ team/group/appdocsxml/main/asterisk.c Fri Oct 17 10:56:59 2008
@@ -117,6 +117,7 @@
#include "asterisk/devicestate.h"
#include "asterisk/module.h"
#include "asterisk/dsp.h"
+#include "asterisk/xml.h"
#include "asterisk/doxyref.h" /* Doxygen documentation */
@@ -3328,6 +3329,11 @@
exit(1);
}
+#ifdef XML_DOCUMENTATION
+ /* Load XML documentation. */
+ ast_load_documentation();
+#endif
+
if (load_modules(1)) { /* Load modules, pre-load only */
printf("%s", term_quit());
exit(1);
Modified: team/group/appdocsxml/main/config.c
URL: http://svn.digium.com/view/asterisk/team/group/appdocsxml/main/config.c?view=diff&rev=150561&r1=150560&r2=150561
==============================================================================
--- team/group/appdocsxml/main/config.c (original)
+++ team/group/appdocsxml/main/config.c Fri Oct 17 10:56:59 2008
@@ -38,24 +38,6 @@
#include <math.h> /* HUGE_VAL */
#define AST_INCLUDE_GLOB 1
-
-#ifdef AST_INCLUDE_GLOB
-/* glob compat stuff - eventually this should go in compat.h or some
- * header in include/asterisk/
- */
-#if defined(__Darwin__) || defined(__CYGWIN__)
-#define GLOB_ABORTED GLOB_ABEND
-#endif
-
-#include <glob.h>
-
-#ifdef SOLARIS
-#define MY_GLOB_FLAGS GLOB_NOCHECK
-#else
-#define MY_GLOB_FLAGS (GLOB_NOMAGIC|GLOB_BRACE)
-#endif
-
-#endif
#include "asterisk/config.h"
#include "asterisk/cli.h"
Modified: team/group/appdocsxml/main/pbx.c
URL: http://svn.digium.com/view/asterisk/team/group/appdocsxml/main/pbx.c?view=diff&rev=150561&r1=150560&r2=150561
==============================================================================
--- team/group/appdocsxml/main/pbx.c (original)
+++ team/group/appdocsxml/main/pbx.c Fri Oct 17 10:56:59 2008
@@ -555,6 +555,7 @@
</application>
<application name="Wait" language="en_US">
<synopsis>
+ Waits for some time.
</synopsis>
<syntax>
<parameter name="seconds" required="true">
@@ -825,11 +826,16 @@
#ifdef XML_DOCUMENTATION
#define DEFAULT_DOCUMENTATION_LANGUAGE "en_US"
#define XMLDOC_TEXT_COLUMNS 74
-#define XMLDOC_MAX_DIFF 5
+#define XMLDOC_MAX_DIFF 5
/*! \brief XML documentation language. */
static char documentation_language[80];
/*! \brief XML documentation tree. */
-static ast_xml_doc *documentation_tree = NULL;
+struct documentation_tree {
+ char *filename;
+ ast_xml_doc *doc;
+ AST_LIST_ENTRY(documentation_tree) entry;
+};
+static AST_LIST_HEAD_STATIC(xmldoc_tree, documentation_tree);
#endif
static int pbx_builtin_answer(struct ast_channel *, void *);
@@ -3434,49 +3440,55 @@
/*! \internal
* \brief Get the application/function node for 'name' application/function with language 'language'
* if we don't find any, get the first application with 'name' no matter which language with.
- * \param doc XML documentation tree structure.
* \param type 'application', 'function', ...
* \param name Application or Function name.
* \param language Try to get this language (if not found try with en_US)
* \retval NULL on error.
* \retval A node of type ast_xml_node.
*/
-static ast_xml_node *xmldoc_get_node(ast_xml_doc *doc, const char *type, const char *name, const char *language)
+static ast_xml_node *xmldoc_get_node(const char *type, const char *name, const char *language)
{
ast_xml_node *node;
+ struct documentation_tree *doctree;
char *lang;
- node = ast_xml_get_root(doc);
- if (!node) {
- ast_log(LOG_ERROR, "No XML root node found while reading %s %s documentation\n", name, type);
- return NULL;
- }
- node = node->AST_XML_CHILD;
- while (node) {
- node = ast_xml_find_element(node, type, "name", name);
- if (node) {
- /* Check language */
- lang = ast_xml_get_attribute(node, "language");
- if (lang && !strcmp(lang, language)) {
- ast_xml_free_attr(lang);
- break;
- } else if (lang) {
- ast_xml_free_attr(lang);
- }
- node = node->AST_XML_NEXT;
- }
- }
-
- if (!node || !node->AST_XML_CHILD) {
- /* We didn't find the application documentation for the specified language,
- so, try to load documentation for any language */
- node = ast_xml_get_root(documentation_tree);
- if (node && node->AST_XML_CHILD) {
- node = ast_xml_find_element(node->AST_XML_CHILD, type, "name", name);
- }
- }
-
- return node;
+ AST_LIST_LOCK(&xmldoc_tree);
+ AST_LIST_TRAVERSE(&xmldoc_tree, doctree, entry) {
+
+ node = ast_xml_get_root(doctree->doc);
+ node = node->AST_XML_CHILD;
+ while (node) {
+ node = ast_xml_find_element(node, type, "name", name);
+ if (node) {
+ /* Check language */
+ lang = ast_xml_get_attribute(node, "language");
+ if (lang && !strcmp(lang, language)) {
+ ast_xml_free_attr(lang);
+ break;
+ } else if (lang) {
+ ast_xml_free_attr(lang);
+ }
+ node = node->AST_XML_NEXT;
+ }
+ }
+ if (!node || !node->AST_XML_CHILD) {
+ /* We didn't find the application documentation for the specified language,
+ so, try to load documentation for any language */
+ node = ast_xml_get_root(doctree->doc);
+ if (node->AST_XML_CHILD) {
+ if ((node = ast_xml_find_element(node->AST_XML_CHILD, type, "name", name))) {
+ AST_LIST_UNLOCK(&xmldoc_tree);
+ return node;
+ }
+ }
+ } else {
+ AST_LIST_UNLOCK(&xmldoc_tree);
+ return node;
+ }
+ }
+ AST_LIST_UNLOCK(&xmldoc_tree);
+
+ return NULL;
}
/*! \internal
@@ -3784,7 +3796,7 @@
ast_xml_node *node;
char *syntax = NULL;
- node = xmldoc_get_node(documentation_tree, type, name, documentation_language);
+ node = xmldoc_get_node(type, name, documentation_language);
if (!node || !node->AST_XML_CHILD) {
return NULL;
}
@@ -4096,7 +4108,7 @@
}
/* get the application/function root node. */
- node = xmldoc_get_node(documentation_tree, type, name, documentation_language);
+ node = xmldoc_get_node(type, name, documentation_language);
if (!node || !node->AST_XML_CHILD) {
return NULL;
}
@@ -4402,7 +4414,7 @@
return NULL;
}
- node = xmldoc_get_node(documentation_tree, type, name, documentation_language);
+ node = xmldoc_get_node(type, name, documentation_language);
if (!node || !node->AST_XML_CHILD) {
return NULL;
@@ -4506,20 +4518,14 @@
struct ast_str *formatted;
if (ast_strlen_zero(type) || ast_strlen_zero(name)) {
- ast_log(LOG_WARNING, "Tried to look in XML tree with faulty values.\n");
+ ast_log(LOG_ERROR, "Tried to look in XML tree with faulty values.\n");
return ret;
}
- /* not fully initted yet */
- if (!documentation_tree) {
- ast_log(LOG_DEBUG, "Parsing Documentation XML Error\n");
- return ret;
- }
-
- node = xmldoc_get_node(documentation_tree, type, name, documentation_language);
+ node = xmldoc_get_node(type, name, documentation_language);
if (!node) {
- ast_log(LOG_ERROR, "Counldn't find %s %s in XML documentation\n", type, name);
+ ast_log(LOG_WARNING, "Counldn't find %s %s in XML documentation\n", type, name);
return ret;
}
@@ -6308,59 +6314,101 @@
}
#ifdef XML_DOCUMENTATION
-
-/*! \brief Load XML Document into buffer for parsing into a list.
- * \retval 1 on error.
- * \retval 0 on success.
- */
-static int ast_load_documentation(void)
+int ast_load_documentation(void)
{
ast_xml_node *root_node;
- char *path;
-
- documentation_tree = NULL;
-
- /* Initialize the libxml*/
+ ast_xml_doc *tmpdoc;
+ struct documentation_tree *doc_tree;
+ char *xmlpattern;
+ struct ast_config *cfg = NULL;
+ struct ast_variable *var = NULL;
+ struct ast_flags cnfflags = { 0 };
+ int globret, i;
+ glob_t globbuf;
+
+ /* setup default XML documentation language */
+ snprintf(documentation_language, sizeof(documentation_language), DEFAULT_DOCUMENTATION_LANGUAGE);
+
+ if (!(cfg = ast_config_load("asterisk.conf", cnfflags))) {
+ ast_log(LOG_ERROR, "No asterisk.conf? That cannot be good.\n");
+ }
+
+ for (var = ast_variable_browse(cfg, "options"); var; var = var->next) {
+ if (!strcasecmp(var->name, "documentation_language")) {
+ if (!ast_strlen_zero(var->value)) {
+ snprintf(documentation_language, sizeof(documentation_language), "%s", var->value);
+ }
+ }
+ }
+ ast_config_destroy(cfg);
+
+ /* initialize the XML library. */
ast_xml_init();
- /* This memory is automagically freed */
- path = alloca(strlen(ast_config_AST_DATA_DIR) + strlen(documentation_language) + strlen("/core-.xml") + 1);
- sprintf(path, "%s/core-%s.xml", ast_config_AST_DATA_DIR, documentation_language);
-
- documentation_tree = ast_xml_open(path);
-
- if (!documentation_tree) {
- ast_log(LOG_ERROR, "Could not open XML Doc at '%s'\n", path);
- if (!strcmp(documentation_language, "en_US")) {
- ast_xml_finish();
- return 1;
- }
- path = alloca(strlen(ast_config_AST_DATA_DIR) + strlen("en_US") + strlen("/core-.xml") + 1);
- sprintf(path, "%s/core-%s.xml", ast_config_AST_DATA_DIR, "en_US");
- ast_log(LOG_WARNING, "Trying to load documentation XML in '%s'\n", path);
- if (!(documentation_tree = ast_xml_open(path))) {
- ast_log(LOG_WARNING, "Also failed trying to load default documentation\n");
- ast_xml_finish();
- return 1;
- }
-
- }
-
- /* Get doc root node and check if it starts with '<doc>' */
- root_node = ast_xml_get_root(documentation_tree);
- if (!root_node) {
- ast_log(LOG_ERROR, "Error getting documentation root node");
- ast_xml_close(documentation_tree);
- ast_xml_finish();
+ /* Get every *-LANG.xml file inside $(ASTDATADIR)/documentation */
+ ast_asprintf(&xmlpattern, "%s/documentation/*-%s.xml", ast_config_AST_DATA_DIR, documentation_language);
+ globbuf.gl_offs = 0; /* initialize it to silence gcc */
+ globret = glob(xmlpattern, MY_GLOB_FLAGS, NULL, &globbuf);
+ if (globret == GLOB_NOSPACE) {
+ ast_log(LOG_WARNING, "Glob Expansion of pattern '%s' failed: Not enough memory\n", xmlpattern);
+ ast_free(xmlpattern);
return 1;
- }
-
- if (strcmp((char *)root_node->AST_XML_NAME, "docs")) {
- ast_log(LOG_ERROR, "Documentation file is not well formed!\n");
- ast_xml_close(documentation_tree);
- ast_xml_finish();
+ } else if (globret == GLOB_ABORTED) {
+ ast_log(LOG_WARNING, "Glob Expansion of pattern '%s' failed: Read error\n", xmlpattern);
+ ast_free(xmlpattern);
return 1;
}
+
+ /* Get every *-LANG.xml file inside $(ASTDATADIR)/documentation/thirdparty */
+ ast_free(xmlpattern);
+ ast_asprintf(&xmlpattern, "%s/documentation/thirdparty/*-%s.xml", ast_config_AST_DATA_DIR, documentation_language);
+ globret = glob(xmlpattern, MY_GLOB_FLAGS | GLOB_APPEND, NULL, &globbuf);
+ if (globret == GLOB_NOSPACE) {
+ ast_log(LOG_WARNING, "Glob Expansion of pattern '%s' failed: Not enough memory\n", xmlpattern);
+ ast_free(xmlpattern);
+ globfree(&globbuf);
+ return 1;
+ } else if (globret == GLOB_ABORTED) {
+ ast_log(LOG_WARNING, "Glob Expansion of pattern '%s' failed: Read error\n", xmlpattern);
+ ast_free(xmlpattern);
+ globfree(&globbuf);
+ return 1;
+ }
+ AST_LIST_LOCK(&xmldoc_tree);
+ /* loop over expanded files */
+ for (i = 0; i < globbuf.gl_pathc; i++) {
+ tmpdoc = NULL;
+ tmpdoc = ast_xml_open(globbuf.gl_pathv[i]);
+ if (!tmpdoc) {
+ ast_log(LOG_ERROR, "Could not open XML documentation at '%s'\n", globbuf.gl_pathv[i]);
+ continue;
+ }
+ /* Get doc root node and check if it starts with '<docs>' */
+ root_node = ast_xml_get_root(tmpdoc);
+ if (!root_node) {
+ ast_log(LOG_ERROR, "Error getting documentation root node");
+ ast_xml_close(tmpdoc);
+ continue;
+ }
+ /* Check root node name for malformed xmls. */
+ if (strcmp((char *)root_node->AST_XML_NAME, "docs")) {
+ ast_log(LOG_ERROR, "Documentation file is not well formed!\n");
+ ast_xml_close(tmpdoc);
+ continue;
+ }
+ doc_tree = ast_calloc(1, sizeof(*doc_tree));
+ if (!doc_tree) {
+ ast_log(LOG_ERROR, "Unable to allocate documentation_tree structure!\n");
+ continue;
+ }
+ doc_tree->doc = tmpdoc;
+ doc_tree->filename = ast_strdup(globbuf.gl_pathv[i]);
+ AST_LIST_INSERT_TAIL(&xmldoc_tree, doc_tree, entry);
+ }
+ AST_LIST_UNLOCK(&xmldoc_tree);
+
+ globfree(&globbuf);
+ ast_free(xmlpattern);
return 0;
}
@@ -10439,32 +10487,6 @@
int load_pbx(void)
{
int x;
-#ifdef XML_DOCUMENTATION
- struct ast_config *cfg = NULL;
- struct ast_variable *var = NULL;
- struct ast_flags cnfflags = { 0 };
-#endif
-
-#ifdef XML_DOCUMENTATION
- /* setup default language */
- snprintf(documentation_language, sizeof(documentation_language), DEFAULT_DOCUMENTATION_LANGUAGE);
-
- if (!(cfg = ast_config_load("asterisk.conf", cnfflags))) {
- ast_log(LOG_ERROR, "No asterisk.conf? That cannot be good.\n");
- }
-
- for (var = ast_variable_browse(cfg, "options"); var; var = var->next) {
- if (!strcasecmp(var->name, "documentation_language")) {
- if (!ast_strlen_zero(var->value)) {
- snprintf(documentation_language, sizeof(documentation_language), "%s", var->value);
- }
- }
- }
- ast_config_destroy(cfg);
-
- /* Load Documentation XML Blob */
- ast_load_documentation();
-#endif
/* Initialize the PBX */
ast_verb(1, "Asterisk PBX Core Initializing\n");
More information about the asterisk-commits
mailing list