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

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Aug 27 15:04:03 CDT 2008


Author: eliel
Date: Wed Aug 27 15:04:02 2008
New Revision: 140300

URL: http://svn.digium.com/view/asterisk?view=rev&rev=140300
Log:
Implement 'core show application <appname>' colorization.

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=140300&r1=140299&r2=140300
==============================================================================
--- team/group/appdocsxml/main/pbx.c (original)
+++ team/group/appdocsxml/main/pbx.c Wed Aug 27 15:04:02 2008
@@ -341,6 +341,9 @@
 static unsigned int hashtab_hash_priority(const void *obj);
 static unsigned int hashtab_hash_labels(const void *obj);
 static void __ast_internal_context_destroy( struct ast_context *con);
+#ifdef XML_DOCUMENTATION
+static char *xmldoc_colorization(const char *bwinput, int base_fg, int base_bg);
+#endif
 
 /* a func for qsort to use to sort a char array */
 static int compare_char(const void *a, const void *b)
@@ -2685,7 +2688,10 @@
 	char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40], argtitle[40];
 	char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL;
 	char stxtitle[40], *syntax = NULL, *arguments = NULL;
-	int synopsis_size, description_size, syntax_size, arguments_size;
+	int syntax_size;
+#ifndef XML_DOCUMENTATION
+	int description_size, synopsis_size, arguments_size;
+#endif
 	char *ret = NULL;
 	int which = 0;
 	int wordlen;
@@ -2720,7 +2726,7 @@
 		return CLI_FAILURE;
 
 	}
-
+#ifndef XML_DOCUMENTATION
 	if (acf->synopsis)
 		synopsis_size = strlen(acf->synopsis) + 23;
 	else
@@ -2733,17 +2739,17 @@
 		description_size = strlen("Not available") + 23;
 	description = alloca(description_size);
 
+	if (acf->arguments)
+		arguments_size = strlen(acf->arguments) + 23;
+	else
+		arguments_size = strlen("Not available") + 23;
+	arguments = alloca(arguments_size);
+#endif
 	if (acf->syntax)
 		syntax_size = strlen(acf->syntax) + 23;
 	else
 		syntax_size = strlen("Not available") + 23;
 	syntax = alloca(syntax_size);
-
-	if (acf->arguments)
-		arguments_size = strlen(acf->arguments) + 23;
-	else
-		arguments_size = strlen("Not available") + 23;
-	arguments = alloca(arguments_size);
 
 	snprintf(info, 64 + AST_MAX_APP, "\n  -= Info about function '%s' =- \n\n", acf->name);
 	term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
@@ -2754,18 +2760,29 @@
 	term_color(syntax,
 		   acf->syntax ? acf->syntax : "Not available",
 		   COLOR_CYAN, 0, syntax_size);
+#ifdef XML_DOCUMENTATION
+	arguments = xmldoc_colorization(acf->arguments ? acf->arguments : "Not available", COLOR_CYAN, COLOR_BLACK);
+	synopsis = xmldoc_colorization(acf->synopsis ? acf->synopsis : "Not available", COLOR_CYAN, COLOR_BLACK);
+	description = xmldoc_colorization(acf->desc ? acf->desc : "Not available", COLOR_CYAN, COLOR_BLACK);
+#else
 	term_color(arguments,
-		   acf->arguments ? acf->arguments : "Not available",
-		   COLOR_CYAN, 0, arguments_size);
+		  acf->arguments ? acf->arguments : "Not available",
+		  COLOR_CYAN, 0, arguments_size);
 	term_color(synopsis,
-		   acf->synopsis ? acf->synopsis : "Not available",
-		   COLOR_CYAN, 0, synopsis_size);
+		  acf->synopsis ? acf->synopsis : "Not available",
+		  COLOR_CYAN, 0, synopsis_size);
 	term_color(description,
-		   acf->desc ? acf->desc : "Not available",
-		   COLOR_CYAN, 0, description_size);
+		  acf->desc ? acf->desc : "Not available",
+		  COLOR_CYAN, 0, description_size);
+#endif
 
 	ast_cli(a->fd,"%s%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, argtitle, arguments, 
 		syntitle, synopsis, destitle, description);
+#ifdef XML_DOCUMENTATION
+	ast_free(arguments);
+	ast_free(synopsis);
+	ast_free(description);
+#endif
 
 	return CLI_SUCCESS;
 }
@@ -2814,6 +2831,20 @@
 }
 
 #ifdef XML_DOCUMENTATION
+static const struct strcolorized_tags {
+	char *init;		/*!< Replace initial tag with this string. */
+	char *end;		/*!< Replace end tag with this string. */
+	int colorfg;		/*!< Foreground color. */
+	int colorbg;		/*!< Background color. */
+	char *inittag;		/*!< Initial tag description. */
+	char *endtag;		/*!< Ending tag description. */
+} colorized_tags[] = {
+	{ "<", ">", COLOR_GREEN, COLOR_BLACK, "<replaceable>", "</replaceable>" },
+	{ "\'", "\'", COLOR_BLUE, COLOR_BLACK, "<literal>", "</literal>" },
+	{ "*", "*", COLOR_RED, COLOR_BLACK, "<emphasis>", "</emphasis>" },
+	{ "\"", "\"", COLOR_YELLOW, COLOR_BLACK, "<filename>", "</filename>" }
+};
+
 /*! \internal
  *  \brief Calculate the space in bytes used by a format string
  *         that will be passed to a sprintf function.
@@ -2946,9 +2977,17 @@
 			colmax = columns - postbrreallen;
 			needtobreak = 0, count = 1;
 		}
-		tmp[tmplen++] = *in;
-		count++;
-		in++;
+		if (*in == ESC) {
+			/* Ignore Escape sequences. */
+			while (*in && *in != 'm') {
+				tmp[tmplen++] = *in;
+				in++;
+			}
+		} else {
+			tmp[tmplen++] = *in;
+			count++;
+			in++;
+		}
 	}
 
 	ret = ast_strdup(tmp);
@@ -2958,19 +2997,102 @@
 }	
 
 /*! \internal
- *  \brief Cleanup spaces and tabs after a \n, and skips the spaces at the 
- *         beginning and at the end of the string.
+ *  \brief Colorize the xmldoc output.
+ *  \param bwinput Not colorized input.
+ *  \retval NULL on error.
+ *  \retval New malloced buffer colorized.
+ */
+static char *xmldoc_colorization(const char *bwinput, int base_fg, int base_bg)
+{
+	char *colorized = NULL, *wrapped = NULL;
+	int i, c, colorized_len = 1, actual_len=0, len, colorsection;
+	char *tmp;
+
+	/* Calculate output string size. Try to figure out the needed space. */
+	for (i = 0;i < strlen(bwinput);i++) {
+		colorized_len++;
+		for (c = 0; c < ARRAY_LEN(colorized_tags); c++) {
+			if (!strcasecmp(colorized_tags[c].inittag, bwinput + i)) {
+				colorized_len += 46 + strlen(colorized_tags[c].init);
+				i += strlen(colorized_tags[c].inittag);
+				break;
+			} else if (!strcasecmp(colorized_tags[c].endtag, bwinput + i)) {
+				colorized_len += strlen(colorized_tags[c].end);
+				i += strlen(colorized_tags[c].endtag);
+				break;
+			}
+		}
+	}
+
+	colorized = ast_calloc(1, colorized_len + 46);
+	if (!colorized) {
+		return NULL;
+	}
+
+	term_color_code(colorized, base_fg, base_bg, 23);
+	actual_len = strlen(colorized);
+
+	for (i = 0; i < strlen(bwinput);i++) {
+		colorsection = 0;
+		/* Check if we are at the begining 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))) {
+				tmp = strcasestr(bwinput + i + strlen(colorized_tags[c].inittag), colorized_tags[c].endtag);
+
+				if (tmp) {
+					len = tmp - (bwinput + i + strlen(colorized_tags[c].inittag));
+					/* Setup color */
+					term_color_code(colorized + strlen(colorized), colorized_tags[c].colorfg, colorized_tags[c].colorbg, 23);
+
+					/* copy initial string replace */
+					ast_copy_string(colorized + strlen(colorized), colorized_tags[c].init, strlen(colorized_tags[c].init) + 1);
+
+					ast_copy_string(colorized + strlen(colorized), bwinput + i + strlen(colorized_tags[c].inittag), len + 1);
+					
+					/* copy the ending string replace */
+					ast_copy_string(colorized + strlen(colorized), colorized_tags[c].end, strlen(colorized_tags[c].end) + 1);
+				
+					/* Continue with the last color. */
+					term_color_code(colorized + strlen(colorized), base_fg, base_bg, 23);
+
+					i += len + strlen(colorized_tags[c].endtag) + strlen(colorized_tags[c].inittag) - 1;
+					actual_len = strlen(colorized);
+					colorsection = 1;
+					break;
+				}
+			}
+		}
+		if (!colorsection) {
+			colorized[actual_len++] = bwinput[i];
+		}
+	}
+
+	term_color_code(colorized + strlen(colorized), COLOR_BRWHITE, 0, 23);
+
+	/* Wrap the text, notice that string wrap will avoid cutting an ESC sequence. */
+	if (colorized) {
+		wrapped = xmldoc_string_wrap(colorized, XMLDOC_TEXT_COLUMNS, XMLDOC_MAX_DIFF);
+		ast_free(colorized);
+	}
+
+	return wrapped;
+}
+
+
+
+/*! \internal
+ *  \brief Cleanup spaces and tabs after a \n
  *  \param text String to be cleaned up.
  *  \retval NULL on error.
- *  \retval A malloc'ed string with the output.
+ *  \retval A malloc'ed string with the output (a clean string).
  */
 static char *xmldoc_string_cleanup(const char *text)
 {
-	int retlen=0, c;
+	int retlen=0;
 	char *rettmp, *rettext, *tmp;
 
 	/* Alloc a buffer of at least the same size as 'text' */
-	if (!text || !(rettmp = calloc(1, strlen(text) + 1))) {
+	if (!text || !(rettmp = ast_calloc(1, strlen(text) + 1))) {
 		return NULL;
 	}
 
@@ -2978,13 +3100,10 @@
 	while (*tmp) {
 		if (*tmp == '\n' || *tmp == '\r') {
 			tmp++;
-			c = 0;
 			while (*tmp == '\t' || *tmp == '\r' || *tmp == '\n') {
-				tmp++, c++;
-			}
-			if (c) {
-				rettmp[retlen++] = ' ';
-			}
+				tmp++;
+			}
+			rettmp[retlen++] = ' ';
 			continue;
 		} else {
 			rettmp[retlen++] = *tmp;
@@ -3352,7 +3471,6 @@
 	ast_xml_text *tmptext;
 	ast_xml_node *tmp;
 	char *cleantext;
-	char *sepinit, *sepend;
 	int ret = 0;
 
 	if (!node || !node->AST_XML_CHILD) {
@@ -3370,17 +3488,6 @@
 
 	tmp = node->AST_XML_CHILD;
 	while (tmp) {
-		if (!strcasecmp((char *)tmp->AST_XML_NAME, "literal")) {
-			sepinit = sepend = "'";
-		} else if (!strcasecmp((char *)tmp->AST_XML_NAME, "replaceable")) {
-			sepinit = "<";
-			sepend = ">";
-		} else if (!strcasecmp((char *)tmp->AST_XML_NAME, "emphasis")) {
-			sepinit = sepend = "*";
-		} else {
-			sepinit = sepend = "";
-		}
-
 		/* Get the text inside the <para> element and append it to buffer. */
 		tmptext = ast_xml_get_text(tmp);
 		if (tmptext) {
@@ -3388,8 +3495,16 @@
 			cleantext = xmldoc_string_cleanup(tmptext);
 			ast_xml_free_text(tmptext);
 			if (cleantext) {
-				*buffer = ast_realloc(*buffer, *len + strlen(cleantext) + strlen(sepinit) + strlen(sepend) + 3);
-				*len += sprintf(*buffer + *len, "%s%s%s", sepinit, cleantext, sepend);
+				if (strcasecmp((char *)tmp->AST_XML_NAME, "text")) {
+					/* + 6 for= " <></>" */
+					*buffer = ast_realloc(*buffer, *len + strlen(cleantext) + (strlen((char *)tmp->AST_XML_NAME) * 2) + 6 + 1);
+					/* The last space is not returned by getContent? */
+					*len += sprintf(*buffer + *len, " <%s>%s</%s>", tmp->AST_XML_NAME, cleantext, tmp->AST_XML_NAME);
+				} else {
+					*buffer = ast_realloc(*buffer, *len + strlen(cleantext) + 1);
+					ast_copy_string(*buffer + *len, cleantext, strlen(cleantext));
+					*len += strlen(cleantext) - 1;
+				}
 				ast_free(cleantext);
 				ret = 2;
 			}
@@ -3727,7 +3842,7 @@
 static char *xmldoc_build_arguments(const char *type, const char *name)
 {
 	ast_xml_node *node;
-	char *retnotwrapped = NULL, *ret = NULL;
+	char *ret = NULL;
 	int len = 0;
 	
 	if (ast_strlen_zero(type) || ast_strlen_zero(name)) {
@@ -3756,13 +3871,8 @@
 
 	node = node->AST_XML_CHILD;
 	while (node) {
-		xmldoc_parse_parameter(&retnotwrapped, &len, node);
+		xmldoc_parse_parameter(&ret, &len, node);
 		node = node->AST_XML_NEXT;
-	}
-
-	if (retnotwrapped) {
-		ret = xmldoc_string_wrap(retnotwrapped, XMLDOC_TEXT_COLUMNS, XMLDOC_MAX_DIFF);
-		ast_free(retnotwrapped);
 	}
 
 	return ret;
@@ -3819,7 +3929,7 @@
 static char *xmldoc_get_field(const char *type, const char *name, const char *var, int raw)
 {
 	ast_xml_node *node;
-	char *formatted, *ret = NULL;
+	char *ret = NULL, *formatted;
 
 	if (ast_strlen_zero(type) || ast_strlen_zero(name)) {
 		ast_log(LOG_WARNING, "Tried to look in XML tree with faulty values.\n");
@@ -3847,12 +3957,8 @@
 	}
 
 	formatted = xmldoc_get_formatted(node, raw, raw);
-	if (formatted) {
-		ret = xmldoc_string_wrap(formatted, XMLDOC_TEXT_COLUMNS, XMLDOC_MAX_DIFF);
-		ast_free(formatted);
-	}
-
-	return ret;
+
+	return formatted;
 }
 #endif /* XML_DOCUMENTATION */
 
@@ -5759,10 +5865,13 @@
 				/* Maximum number of characters added by terminal coloring is 22 */
 				char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40], stxtitle[40], argtitle[40];
 				char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL, *syntax = NULL, *arguments = NULL;
-				int synopsis_size, description_size, syntax_size, arguments_size;
+				int syntax_size;
+#ifndef XML_DOCUMENTATION
+				int synopsis_size, description_size, arguments_size; 
+#endif
 
 				no_registered_app = 0;
-
+#ifndef XML_DOCUMENTATION
 				if (aa->synopsis)
 					synopsis_size = strlen(aa->synopsis) + 23;
 				else
@@ -5774,41 +5883,56 @@
 				else
 					description_size = strlen("Not available") + 23;
 				description = alloca(description_size);
-
+#endif
 				if (aa->syntax)
 					syntax_size = strlen(aa->syntax) + 23;
 				else
 					syntax_size = strlen("Not available") + 23;
 				syntax = alloca(syntax_size);
-
+#ifndef XML_DOCUMENTATION
 				if (aa->arguments)
 					arguments_size = strlen(aa->arguments) + 23;
 				else
 					arguments_size = strlen("Not available") + 23;
 				arguments = alloca(arguments_size);
-
-				if (synopsis && description) {
+#endif
+
+#ifdef XML_DOCUMENTATION
+				if (syntax) {
+#else
+				if (syntax && description && arguments && synopsis) {
+#endif
 					snprintf(info, 64 + AST_MAX_APP, "\n  -= Info about application '%s' =- \n\n", aa->name);
 					term_color(infotitle, info, COLOR_MAGENTA, 0, 64 + AST_MAX_APP + 22);
 					term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
 					term_color(argtitle, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
 					term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
 					term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
+#ifdef XML_DOCUMENTATION
+					description = xmldoc_colorization(aa->description ? aa->description : "Not available", COLOR_CYAN, COLOR_BLACK);
+					arguments = xmldoc_colorization(aa->arguments ? aa->arguments : "Not available", COLOR_CYAN, COLOR_BLACK);
+					synopsis = xmldoc_colorization(aa->synopsis ? aa->synopsis : "Not available", COLOR_CYAN, COLOR_BLACK);
+#else
 					term_color(synopsis,
 									aa->synopsis ? aa->synopsis : "Not available",
 									COLOR_CYAN, 0, synopsis_size);
+
 					term_color(description,
 									aa->description ? aa->description : "Not available",
 									COLOR_CYAN, 0, description_size);
+					term_color(arguments,
+									aa->arguments ? aa->arguments : "Not available",
+									COLOR_CYAN, 0, arguments_size);
+#endif
 					term_color(syntax,
 									aa->syntax ? aa->syntax : "Not available",
 									COLOR_CYAN, 0, syntax_size);
-					term_color(arguments,
-									aa->arguments ? aa->arguments : "Not available",
-									COLOR_CYAN, 0, arguments_size);
 
 					ast_cli(a->fd,"%s%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, argtitle, 
 						arguments, syntitle, synopsis, destitle, description);
+					ast_free(description);
+					ast_free(arguments);
+					ast_free(synopsis);
 				} else {
 					/* ... one of our applications, show info ...*/
 					ast_cli(a->fd,"\n  -= Info about application '%s' =- \n\n"




More information about the svn-commits mailing list