[svn-commits] eliel: branch group/appdocsxml r137900 - /team/group/appdocsxml/main/pbx.c

SVN commits to the Digium repositories svn-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 svn-commits mailing list