[asterisk-commits] eliel: branch group/appdocsxml r137900 - /team/group/appdocsxml/main/pbx.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Aug 14 12:51:29 CDT 2008
Author: eliel
Date: Thu Aug 14 12:51:28 2008
New Revision: 137900
URL: http://svn.digium.com/view/asterisk?view=rev&rev=137900
Log:
Implement xmldoc_string_wrap() to justify a text to a number of columns.
Fix some formatting issues while implementing xmldoc_string_wrap().
Modified:
team/group/appdocsxml/main/pbx.c
Modified: team/group/appdocsxml/main/pbx.c
URL: http://svn.digium.com/view/asterisk/team/group/appdocsxml/main/pbx.c?view=diff&rev=137900&r1=137899&r2=137900
==============================================================================
--- team/group/appdocsxml/main/pbx.c (original)
+++ team/group/appdocsxml/main/pbx.c Thu Aug 14 12:51:28 2008
@@ -287,6 +287,8 @@
#ifdef XML_DOCUMENTATION
#define DEFAULT_DOCUMENTATION_LANGUAGE "en_US"
+#define XMLDOC_TEXT_COLUMNS 74
+#define XMLDOC_MAX_DIFF 5
/*! \brief XML documentation language. */
static char documentation_language[80];
/*! \brief XML documentation tree. */
@@ -2794,9 +2796,107 @@
}
#ifdef XML_DOCUMENTATION
+/*! \brief Justify a text to a number of columns.
+ * \param text Input text to be justified.
+ * \param columns Number of columns to preserve in the text.
+ * \param maxdiff Try to not cut a word when goinf down.
+ * \param postbr Put this chars after a \n.
+ * \param predatalen Length of the data already printed.
+ * \retval NULL on error.
+ * \retval The wrapped text.
+ */
+static char *xmldoc_string_wrap(const char *text, int columns, int maxdiff, const char *postbr, int predatalen)
+{
+ char *tmp, *ret, *t;
+ char *in = (char *)text;
+ int count = 1, tmplen = 0, i, postbrlen = 0, postbrreallen = 0;
+ int sep, needtobreak = 0, colmax;
+
+ if (postbr) {
+ for (i = 0; i < strlen(postbr); i++) {
+ if (postbr[i] == '\t') {
+ postbrreallen += 8 - (postbrreallen % 8);
+ } else {
+ postbrreallen++;
+ }
+ }
+ postbrlen = strlen(postbr);
+ }
+
+ if (!text) {
+ return NULL;
+ }
+
+ /* XXX: We could calculate better how much space do we need. */
+ tmp = ast_calloc(1, strlen(text) * ((postbrreallen ? postbrreallen : 1) + 1));
+
+ if (!tmp) {
+ return NULL;
+ }
+
+ colmax = columns - postbrreallen - predatalen;
+ while (*in) {
+ if (needtobreak || !(count % colmax)) {
+ if (*in == ' ') {
+ tmp[tmplen++] = '\n';
+ for (i = 0; i < postbrlen; i++) {
+ tmp[tmplen++] = postbr[i];
+ }
+ needtobreak = 0;
+ } else {
+ needtobreak = 1;
+ t = in;
+ sep = maxdiff;
+ while (*t && sep > 0) {
+ /* Wait for the next space? */
+ if (*(++t) == ' ') {
+ break;
+ }
+ sep--;
+ }
+ if (!sep) {
+ /* Try to look backwards */
+ t = in;
+ sep = (maxdiff % tmplen);
+ while (sep > 0) {
+ if (*(--t) == ' ') {
+ break;
+ }
+ sep--;
+ }
+ if (sep) {
+ needtobreak = 1;
+ tmplen -= (maxdiff % tmplen) - sep;
+ in = t;
+ continue;
+ }
+ tmp[tmplen++] = '-';
+ tmp[tmplen++] = '\n';
+ for (i = 0; i < postbrlen; i++) {
+ tmp[tmplen++] = postbr[i];
+ }
+ needtobreak = 0;
+ }
+ }
+ /* skip blanks after a \n */
+ while (*in == ' ') {
+ in++;
+ }
+ }
+ tmp[tmplen++] = *in;
+ count++;
+ in++;
+ }
+
+ ret = ast_strdup(tmp);
+ ast_free(tmp);
+
+ return ret;
+}
/*! \internal
- * \brief Cleanup spaces and tabs after a \n.
+ * \brief Cleanup spaces and tabs after a \n, and skips the spaces at the
+ * beginning and at the end of the string.
* \param text String to be cleaned up.
* \retval NULL on error.
* \retval A malloc'ed string with the output.
@@ -2804,7 +2904,7 @@
static char *xmldoc_string_cleanup(const char *text)
{
int retlen=0, c;
- char *rettmp, *rettext, *tmp;
+ char *rettmp, *rettext, *tmp, *trim;
/* Alloc a buffer of at least the same size as 'text' */
if (!text || !(rettmp = calloc(1, strlen(text) + 1))) {
@@ -2829,12 +2929,9 @@
tmp++;
}
- if (!(rettext = ast_malloc(retlen + 1))) {
- ast_free(rettmp);
- return NULL;
- }
-
- strcpy(rettext, rettmp);
+ trim = ast_trim_blanks(rettmp);
+
+ rettext = ast_strdup(trim);
ast_free(rettmp);
return rettext;
@@ -3120,13 +3217,14 @@
* \param buffer This must be NULL or an ast_malloc'ed buffer. It will be used
* to store the result (if already has something it will be appended to the current
* string).
+ * \param predatalen TODO
* \retval 1 on succes.
* \retval 0 on error.
*/
-static int xmldoc_parse_para(ast_xml_node *node, const char *tabs, const char *posttabs, int *len, char **buffer)
+static int xmldoc_parse_para(ast_xml_node *node, const char *tabs, const char *posttabs, int *len, char **buffer, int predatalen)
{
ast_xml_text *tmptext;
- char *cleantext;
+ char *cleantext, *wraptext;
if (!node || !node->AST_XML_CHILD) {
return 0;
@@ -3139,12 +3237,17 @@
/* Get the text inside the <para> element and append it to buffer. */
tmptext = ast_xml_get_text(node);
if (tmptext) {
- *buffer = ast_realloc(*buffer, *len + strlen(tmptext) + strlen(tabs) + strlen(posttabs) + 1);
/* Strip \n etc. */
cleantext = xmldoc_string_cleanup(tmptext);
- *len += sprintf(*buffer + *len, "%s%s%s", tabs, cleantext, posttabs);
+ ast_xml_free_text(tmptext);
+ /* wrapped text. */
+ wraptext = xmldoc_string_wrap(cleantext, XMLDOC_TEXT_COLUMNS, XMLDOC_MAX_DIFF, tabs, predatalen);
ast_free(cleantext);
- ast_xml_free_text(tmptext);
+ if (wraptext) {
+ *buffer = ast_realloc(*buffer, *len + strlen(tabs) + strlen(wraptext) + strlen(posttabs) + 1);
+ *len += sprintf(*buffer + *len, "%s%s%s", tabs, wraptext, posttabs);
+ ast_free(wraptext);
+ }
}
return 1;
@@ -3159,21 +3262,22 @@
* \param buffer This must be NULL or an ast_malloc'ed buffer. It will be used
* to store the result (if already has something it will be appended to the current
* string).
+ * \param varnamelen Variable name len.
*/
-static void xmldoc_parse_variable(ast_xml_node *node, const char *tabs, int *len, char **buffer)
+static void xmldoc_parse_variable(ast_xml_node *node, const char *tabs, int *len, char **buffer, int varnamelen)
{
ast_xml_node *tmp;
ast_xml_attr *valname;
ast_xml_text *tmptext;
+ char *wrap, *clean;
if (!node || !node->AST_XML_CHILD) {
return;
- }
+ }
tmp = node->AST_XML_CHILD;
while (tmp) {
- /* XXX: increment by one tab the tabs? */
- if (xmldoc_parse_para(tmp, tabs, "\n", len, buffer)) {
+ if (xmldoc_parse_para(tmp, "", "", len, buffer, varnamelen + 8 - (varnamelen % 8))) {
tmp = tmp->AST_XML_NEXT;
continue;
}
@@ -3192,9 +3296,19 @@
}
/* Check inside this node for any explanation about its meaning. */
if (tmptext) {
- *buffer = ast_realloc(*buffer, *len + strlen(tmptext) + strlen(tabs) + 3);
- *len += sprintf(*buffer + *len, "%s\t%s\n", tabs, tmptext);
+ /* Cleanup text. */
+ clean = xmldoc_string_cleanup(tmptext);
ast_xml_free_text(tmptext);
+ /* Wrap text (+5 for string formatting purposes: '\n: ') */
+ wrap = xmldoc_string_wrap(clean, XMLDOC_TEXT_COLUMNS, XMLDOC_MAX_DIFF, tabs, strlen(valname) + 5);
+ if (clean) {
+ ast_free(clean);
+ }
+ if (wrap) {
+ *buffer = ast_realloc(*buffer, *len + strlen(wrap) + 2);
+ *len += sprintf(*buffer + *len, " %s", wrap);
+ ast_free(wrap);
+ }
}
}
tmp = tmp->AST_XML_NEXT;
@@ -3230,7 +3344,7 @@
tmp = node->AST_XML_CHILD;
while (tmp) {
/* We can have a <para> element inside the variable list ?? */
- if ((xmldoc_parse_para(tmp, "", "", len, buffer))) {
+ if ((xmldoc_parse_para(tmp, "", "", len, buffer, 0))) {
tmp = tmp->AST_XML_NEXT;
continue;
}
@@ -3240,11 +3354,11 @@
varname = ast_xml_get_attribute(tmp, "name");
if (varname) {
*buffer = ast_realloc(*buffer, *len + strlen(varname) + strlen(tabs) + 4);
- *len += sprintf(*buffer + *len, "%s\n%s: ", tabs, varname);
+ *len += sprintf(*buffer + *len, "%s%s: ", tabs, varname);
ast_xml_free_attr(varname);
}
/* Parse the <variable> possible values. */
- xmldoc_parse_variable(tmp, "\t\t", len, buffer);
+ xmldoc_parse_variable(tmp, "\t", len, buffer, strlen(varname) + strlen(tabs) + 2);
}
tmp = tmp->AST_XML_NEXT;
}
@@ -3256,13 +3370,14 @@
* <para> and <variablelist> elements.
* \param node Parent node where content resides.
* \param raw If set, return the node's content without further processing.
+ * \param raw_wrap Wrap raw text.
* \retval NULL on error
* \retval Node content on success.
*/
-static char *xmldoc_get_formatted(ast_xml_node *node, int raw_output)
+static char *xmldoc_get_formatted(ast_xml_node *node, int raw_output, int raw_wrap)
{
ast_xml_node *tmp;
- char *ret = NULL, *notcleanret;
+ char *ret = NULL, *notcleanret, *notwrapped;
int len = 0;
if (!node || !node->AST_XML_CHILD) {
@@ -3271,13 +3386,19 @@
if (raw_output) {
notcleanret = ast_xml_get_text(node);
- ret = xmldoc_string_cleanup(notcleanret);
+ notwrapped = xmldoc_string_cleanup(notcleanret);
ast_xml_free_text(notcleanret);
+ if (raw_wrap) {
+ ret = xmldoc_string_wrap(notwrapped, XMLDOC_TEXT_COLUMNS, XMLDOC_MAX_DIFF, "", 0);
+ ast_free(notwrapped);
+ } else {
+ ret = notwrapped;
+ }
} else {
tmp = node->AST_XML_CHILD;
while (tmp) {
/* if found, parse a <para> element. */
- if (xmldoc_parse_para(tmp, "", "\n", &len, &ret)) {
+ if (xmldoc_parse_para(tmp, "", "\n", &len, &ret, 0)) {
tmp = tmp->AST_XML_NEXT;
continue;
}
@@ -3327,7 +3448,7 @@
return NULL;
}
- return xmldoc_get_formatted(node, raw);
+ return xmldoc_get_formatted(node, raw, raw);
}
#endif /* XML_DOCUMENTATION */
More information about the asterisk-commits
mailing list