[asterisk-commits] russell: branch group/appdocsxml r152130 - in /team/group/appdocsxml: apps/ i...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Oct 27 00:22:35 CDT 2008


Author: russell
Date: Mon Oct 27 00:22:34 2008
New Revision: 152130

URL: http://svn.digium.com/view/asterisk?view=rev&rev=152130
Log:
- Fix a few spelling errors
- Add a new API call, ast_term_color_code(), which lets you append a color
  escape sequence to an ast_str
- Document term_color_code()
- Rename ast_xmldoc_src to ast_doc_src
- Tweak formatting of some things for alignment
- Add MAX_ESCAPE_CHARS define to replace the magic use of 23 throughout pbx.c
  (This is not new to this code)
- Modify xmldoc code to not try to set a background color, to be friendlier
  to light-background terminals
- Simplify code for calculating needed string length
- Print Synopsis and Description first, before Syntax and Arguments
- Restructure bits of code to reduce indentation
- Heavily modify xmldoc_colorization() to use ast_str.  This simplified
  some of the operations done here, and got rid of a complicated loop to
  calculate the output string length up front
- Mark one place that we need to change so that it is not modifying the
  internals of an ast_str
- Break various code out into functions

Modified:
    team/group/appdocsxml/apps/app_dial.c
    team/group/appdocsxml/include/asterisk/pbx.h
    team/group/appdocsxml/include/asterisk/term.h
    team/group/appdocsxml/main/pbx.c
    team/group/appdocsxml/main/term.c

Modified: team/group/appdocsxml/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/group/appdocsxml/apps/app_dial.c?view=diff&rev=152130&r1=152129&r2=152130
==============================================================================
--- team/group/appdocsxml/apps/app_dial.c (original)
+++ team/group/appdocsxml/apps/app_dial.c Mon Oct 27 00:22:34 2008
@@ -286,7 +286,7 @@
 					it is provided. The current extension is used if a database family/key is not specified.</para>
 				</option>
 				<option name="r">
-					<para>Indicate ringing to the calling party, even if the called party isn't actuallying rininging. Pass no audio to the calling
+					<para>Indicate ringing to the calling party, even if the called party isn't actually ringing. Pass no audio to the calling
 					party until the called channel has answered.</para>
 				</option>
 				<option name="S">
@@ -402,11 +402,11 @@
 					<value name="CANCEL" />
 					<value name="DONTCALL">
 						For the Privacy and Screening Modes.
-						Will be set if the called party chooses to send the calling partey to the 'Go Away' script.
+						Will be set if the called party chooses to send the calling party to the 'Go Away' script.
 					</value>
 					<value name="TORTURE">
 						For the Privacy and Screening Modes.
-						Will be set if the called party chooses to send the calling partey to the 'torture' script.
+						Will be set if the called party chooses to send the calling party to the 'torture' script.
 					</value>
 					<value name="INVALIDARGS" />
 				</variable>
@@ -448,8 +448,6 @@
  ***/
 
 static char *app = "Dial";
-
-/* RetryDial App by Anthony Minessale II <anthmct at yahoo.com> Jan/2005 */
 static char *rapp = "RetryDial";
 
 enum {

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=152130&r1=152129&r2=152130
==============================================================================
--- team/group/appdocsxml/include/asterisk/pbx.h (original)
+++ team/group/appdocsxml/include/asterisk/pbx.h Mon Oct 27 00:22:34 2008
@@ -74,7 +74,7 @@
 typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data);
 
 /*! \brief From where the documentation come from */
-enum ast_xmldoc_src {
+enum ast_doc_src {
 	AST_XML_DOC,            /*!< From XML documentation */
 	AST_STATIC_DOC          /*!< From application/function registration */
 };
@@ -89,7 +89,7 @@
 		AST_STRING_FIELD(arguments);    /*!< Arguments description */
 		AST_STRING_FIELD(seealso);      /*!< See also */
 	);
-	enum ast_xmldoc_src docsrc;		/*!< Where the documentation come from */
+	enum ast_doc_src docsrc;		/*!< Where the documentation come from */
 	int (*read)(struct ast_channel *, const char *, char *, char *, size_t);	/*!< Read function, if read is supported */
 	int (*write)(struct ast_channel *, const char *, char *, const char *);		/*!< Write function, if write is supported */
 	struct ast_module *mod;         /*!< Module this custom function belongs to */

Modified: team/group/appdocsxml/include/asterisk/term.h
URL: http://svn.digium.com/view/asterisk/team/group/appdocsxml/include/asterisk/term.h?view=diff&rev=152130&r1=152129&r2=152130
==============================================================================
--- team/group/appdocsxml/include/asterisk/term.h (original)
+++ team/group/appdocsxml/include/asterisk/term.h Mon Oct 27 00:22:34 2008
@@ -64,6 +64,28 @@
 
 char *term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout);
 
+/*!
+ * \brief Append a color sequence to an ast_str
+ *
+ * \param str The string to append to
+ * \param fgcolor foreground color
+ * \param bgcolor background color
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_term_color_code(struct ast_str **str, int fgcolor, int bgcolor);
+
+/*!
+ * \brief Write a color sequence to a string
+ *
+ * \param outbuf the location to write to
+ * \param fgcolor foreground color
+ * \param bgcolor background color
+ * \param maxout maximum number of characters to write
+ *
+ * \return outbuf
+ */
 char *term_color_code(char *outbuf, int fgcolor, int bgcolor, int maxout);
 
 char *term_strip(char *outbuf, char *inbuf, int maxout);

Modified: team/group/appdocsxml/main/pbx.c
URL: http://svn.digium.com/view/asterisk/team/group/appdocsxml/main/pbx.c?view=diff&rev=152130&r1=152129&r2=152130
==============================================================================
--- team/group/appdocsxml/main/pbx.c (original)
+++ team/group/appdocsxml/main/pbx.c Mon Oct 27 00:22:34 2008
@@ -12,7 +12,7 @@
  * channels for your use.
  *
  * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
+* the GNU General Public License Version 2. See the LICENSE file
  * at the top of the source tree.
  */
 
@@ -760,13 +760,13 @@
 struct ast_app {
 	int (*execute)(struct ast_channel *chan, void *data);
 	AST_DECLARE_STRING_FIELDS(
-		AST_STRING_FIELD(synopsis);	/*!< Synopsis text for 'show applications' */
-		AST_STRING_FIELD(description);	/*!< Description (help text) for 'show application &lt;name&gt;' */
-		AST_STRING_FIELD(syntax);	/*!< Syntax text for 'core show applications' */
-		AST_STRING_FIELD(arguments);	/*!< Arguments description */
-		AST_STRING_FIELD(seealso);	/*!< See also */
+		AST_STRING_FIELD(synopsis);     /*!< Synopsis text for 'show applications' */
+		AST_STRING_FIELD(description);  /*!< Description (help text) for 'show application &lt;name&gt;' */
+		AST_STRING_FIELD(syntax);       /*!< Syntax text for 'core show applications' */
+		AST_STRING_FIELD(arguments);    /*!< Arguments description */
+		AST_STRING_FIELD(seealso);      /*!< See also */
 	);
-	enum ast_xmldoc_src docsrc;		/*!< Where the documentation come from. */
+	enum ast_doc_src docsrc;/*!< Where the documentation come from. */
 	AST_RWLIST_ENTRY(ast_app) list;		/*!< Next app in list */
 	struct ast_module *module;		/*!< Module this app belongs to */
 	char name[0];				/*!< Name of the application */
@@ -854,6 +854,9 @@
  */
 static AST_RWLIST_HEAD_STATIC(xmldoc_tree, documentation_tree);
 #endif
+
+/*! \brief Maximum number of characters needed for a color escape sequence, plus a null char */
+#define MAX_ESCAPE_CHARS   23
 
 static int pbx_builtin_answer(struct ast_channel *, void *);
 static int pbx_builtin_goto(struct ast_channel *, void *);
@@ -901,7 +904,7 @@
 static unsigned int hashtab_hash_labels(const void *obj);
 static void __ast_internal_context_destroy( struct ast_context *con);
 #ifdef AST_XML_DOCS
-static char *xmldoc_colorization(const char *bwinput, int base_fg, int base_bg);
+static char *xmldoc_colorization(const char *bwinput);
 #endif
 
 /* a func for qsort to use to sort a char array */
@@ -1015,33 +1018,33 @@
 	/* These applications are built into the PBX core and do not
 	   need separate modules */
 
-	{ "Answer", pbx_builtin_answer },
-	{ "BackGround", pbx_builtin_background },
-	{ "Busy", pbx_builtin_busy },
-	{ "Congestion", pbx_builtin_congestion },
-	{ "ExecIfTime", pbx_builtin_execiftime },
-	{ "Goto", pbx_builtin_goto },
-	{ "GotoIf", pbx_builtin_gotoif },
-	{ "GotoIfTime", pbx_builtin_gotoiftime },
-	{ "ImportVar", pbx_builtin_importvar },
-	{ "Hangup", pbx_builtin_hangup },
-	{ "Incomplete", pbx_builtin_incomplete },
-	{ "KeepAlive", pbx_builtin_keepalive },
-	{ "NoOp", pbx_builtin_noop },
-	{ "Proceeding", pbx_builtin_proceeding },
-	{ "Progress", pbx_builtin_progress },
+	{ "Answer",         pbx_builtin_answer },
+	{ "BackGround",     pbx_builtin_background },
+	{ "Busy",           pbx_builtin_busy },
+	{ "Congestion",     pbx_builtin_congestion },
+	{ "ExecIfTime",     pbx_builtin_execiftime },
+	{ "Goto",           pbx_builtin_goto },
+	{ "GotoIf",         pbx_builtin_gotoif },
+	{ "GotoIfTime",     pbx_builtin_gotoiftime },
+	{ "ImportVar",      pbx_builtin_importvar },
+	{ "Hangup",         pbx_builtin_hangup },
+	{ "Incomplete",     pbx_builtin_incomplete },
+	{ "KeepAlive",      pbx_builtin_keepalive },
+	{ "NoOp",           pbx_builtin_noop },
+	{ "Proceeding",     pbx_builtin_proceeding },
+	{ "Progress",       pbx_builtin_progress },
 	{ "RaiseException", pbx_builtin_raise_exception },
-	{ "ResetCDR", pbx_builtin_resetcdr },
-	{ "Ringing", pbx_builtin_ringing },
-	{ "SayAlpha", pbx_builtin_saycharacters },
-	{ "SayDigits", pbx_builtin_saydigits },
-	{ "SayNumber", pbx_builtin_saynumber },
-	{ "SayPhonetic", pbx_builtin_sayphonetic },
-	{ "Set", pbx_builtin_setvar },
-	{ "MSet", pbx_builtin_setvar_multiple },
-	{ "SetAMAFlags", pbx_builtin_setamaflags },
-	{ "Wait", pbx_builtin_wait },
-	{ "WaitExten", pbx_builtin_waitexten }
+	{ "ResetCDR",       pbx_builtin_resetcdr },
+	{ "Ringing",        pbx_builtin_ringing },
+	{ "SayAlpha",       pbx_builtin_saycharacters },
+	{ "SayDigits",      pbx_builtin_saydigits },
+	{ "SayNumber",      pbx_builtin_saynumber },
+	{ "SayPhonetic",    pbx_builtin_sayphonetic },
+	{ "Set",            pbx_builtin_setvar },
+	{ "MSet",           pbx_builtin_setvar_multiple },
+	{ "SetAMAFlags",    pbx_builtin_setamaflags },
+	{ "Wait",           pbx_builtin_wait },
+	{ "WaitExten",      pbx_builtin_waitexten }
 };
 
 static struct ast_context *contexts;
@@ -3022,59 +3025,39 @@
 		return CLI_FAILURE;
 	}
 
-	if (!ast_strlen_zero(acf->syntax)) {
-		syntax_size = strlen(acf->syntax) + 23;
-	} else {
-		syntax_size = strlen("Not available") + 23;
-	}
-	syntax = ast_malloc(syntax_size);
-	if (!syntax) {
+	syntax_size = strlen(S_OR(acf->syntax, "Not Available")) + MAX_ESCAPE_CHARS;
+	if (!(syntax = ast_malloc(syntax_size))) {
 		ast_cli(a->fd, "Memory allocation failure!\n");
 		return CLI_FAILURE;
 	}
 
 	snprintf(info, sizeof(info), "\n  -= Info about function '%s' =- \n\n", acf->name);
 	term_color(infotitle, info, COLOR_MAGENTA, 0, sizeof(infotitle));
+	term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
+	term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
 	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);
 	term_color(seealsotitle, "[See Also]\n", COLOR_MAGENTA, 0, 40);
 	term_color(syntax, S_OR(acf->syntax, "Not available"), COLOR_CYAN, 0, syntax_size);
 #ifdef AST_XML_DOCS
 	if (acf->docsrc == AST_XML_DOC) {
-		arguments = xmldoc_colorization(S_OR(acf->arguments, "Not available"), COLOR_CYAN, COLOR_BLACK);
-		synopsis = xmldoc_colorization(S_OR(acf->synopsis, "Not available"), COLOR_CYAN, COLOR_BLACK);
-		description = xmldoc_colorization(S_OR(acf->desc, "Not available"), COLOR_CYAN, COLOR_BLACK);
-		seealso = xmldoc_colorization(S_OR(acf->seealso, "Not available"), COLOR_CYAN, COLOR_BLACK);
-	} else {
+		arguments = xmldoc_colorization(S_OR(acf->arguments, "Not available"));
+		synopsis = xmldoc_colorization(S_OR(acf->synopsis, "Not available"));
+		description = xmldoc_colorization(S_OR(acf->desc, "Not available"));
+		seealso = xmldoc_colorization(S_OR(acf->seealso, "Not available"));
+	} else 
 #endif
-		if (!ast_strlen_zero(acf->synopsis)) {
-			synopsis_size = strlen(acf->synopsis) + 23;
-		} else {
-			synopsis_size = strlen("Not available") + 23;
-		}
+	{
+		synopsis_size = strlen(S_OR(acf->synopsis, "Not Available")) + MAX_ESCAPE_CHARS;
 		synopsis = ast_malloc(synopsis_size);
 
-		if (!ast_strlen_zero(acf->desc)) {
-			description_size = strlen(acf->desc) + 23;
-		} else {
-			description_size = strlen("Not available") + 23;
-		}
+		description_size = strlen(S_OR(acf->desc, "Not Available")) + MAX_ESCAPE_CHARS;
 		description = ast_malloc(description_size);
 
-		if (!ast_strlen_zero(acf->arguments)) {
-			arguments_size = strlen(acf->arguments) + 23;
-		} else {
-			arguments_size = strlen("Not available") + 23;
-		}
+		arguments_size = strlen(S_OR(acf->arguments, "Not Available")) + MAX_ESCAPE_CHARS;
 		arguments = ast_malloc(arguments_size);
 
-		if (!ast_strlen_zero(acf->seealso)) {
-			seealso_size = strlen(acf->seealso) + 23;
-		} else {
-			seealso_size = strlen("Not available") + 23;
-		}
+		seealso_size = strlen(S_OR(acf->seealso, "Not Available")) + MAX_ESCAPE_CHARS;
 		seealso = ast_malloc(seealso_size);
 
 		/* check allocated memory. */
@@ -3091,12 +3074,11 @@
 		term_color(synopsis, S_OR(acf->synopsis, "Not available"), COLOR_CYAN, 0, synopsis_size);
 		term_color(description, S_OR(acf->desc, "Not available"), COLOR_CYAN, 0, description_size);
 		term_color(seealso, S_OR(acf->seealso, "Not available"), COLOR_CYAN, 0, seealso_size);
-#ifdef AST_XML_DOCS
-	}
-#endif
-
-	ast_cli(a->fd,"%s%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, argtitle, arguments,
-		syntitle, synopsis, destitle, description, seealsotitle, seealso);
+	}
+
+	ast_cli(a->fd,"%s%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n", 
+			infotitle, syntitle, synopsis, destitle, description, 
+			stxtitle, syntax, argtitle, arguments, seealsotitle, seealso);
 
 	ast_free(arguments);
 	ast_free(synopsis);
@@ -3130,11 +3112,9 @@
 
 	AST_RWLIST_WRLOCK(&acf_root);
 	if ((cur = AST_RWLIST_REMOVE(&acf_root, acf, acflist))) {
-#ifdef AST_XML_DOCS
 		if (cur->docsrc == AST_XML_DOC) {
 			ast_string_field_free_memory(acf);
 		}
-#endif
 		ast_verb(2, "Unregistered custom function %s\n", cur->name);
 	}
 	AST_RWLIST_UNLOCK(&acf_root);
@@ -3144,26 +3124,25 @@
 
 #ifdef AST_XML_DOCS
 static const struct strcolorized_tags {
-	const char *init;		/*!< Replace initial tag with this string. */
-	const char *end;		/*!< Replace end tag with this string. */
-	const int colorfg;		/*!< Foreground color. */
-	const int colorbg;		/*!< Background color. */
-	const char *inittag;		/*!< Initial tag description. */
-	const char *endtag;		/*!< Ending tag description. */
+	const char *init;      /*!< Replace initial tag with this string. */
+	const char *end;       /*!< Replace end tag with this string. */
+	const int colorfg;     /*!< Foreground color. */
+	const char *inittag;   /*!< Initial tag description. */
+	const 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>" },
-	{ "\"", "\"", COLOR_CYAN, COLOR_BLACK, "<directory>", "</directory>" },
-	{ "${", "}", COLOR_GREEN, COLOR_BLACK, "<variable>", "</variable>" },
-	{ "", "", COLOR_BLUE, COLOR_BLACK, "<value>", "</value>" },
-	{ "", "", COLOR_BLUE, COLOR_BLACK, "<enum>", "</enum>" },
-	{ "\'", "\'", COLOR_GRAY, COLOR_BLACK, "<astcli>", "</astcli>" },
+	{ "<",  ">",  COLOR_GREEN,  "<replaceable>", "</replaceable>" },
+	{ "\'", "\'", COLOR_BLUE,   "<literal>",     "</literal>" },
+	{ "*",  "*",  COLOR_RED,    "<emphasis>",    "</emphasis>" },
+	{ "\"", "\"", COLOR_YELLOW, "<filename>",    "</filename>" },
+	{ "\"", "\"", COLOR_CYAN,   "<directory>",   "</directory>" },
+	{ "${", "}",  COLOR_GREEN,  "<variable>",    "</variable>" },
+	{ "",   "",   COLOR_BLUE,   "<value>",       "</value>" },
+	{ "",   "",   COLOR_BLUE,   "<enum>",        "</enum>" },
+	{ "\'", "\'", COLOR_GRAY,   "<astcli>",      "</astcli>" },
 
 	/* Special tags */
-	{ "", "", COLOR_YELLOW, COLOR_BLACK, "<note>", "</note>" },
-	{ "", "", COLOR_RED, COLOR_BLACK, "<warning>", "</warning>" }
+	{ "", "", COLOR_YELLOW, "<note>",   "</note>" },
+	{ "", "", COLOR_RED,   "<warning>", "</warning>" }
 };
 
 static const struct strspecial_tags {
@@ -3171,10 +3150,9 @@
 	const char *init;		/*!< Print this at the beginning. */
 	const char *end;		/*!< Print this at the end. */
 } special_tags[] = {
-	{ "note", "<note>NOTE:</note> ", "" },
+	{ "note",    "<note>NOTE:</note> ",             "" },
 	{ "warning", "<warning>WARNING!!!:</warning> ", "" }
 };
-
 
 /*! \internal
  *  \brief Calculate the space in bytes used by a format string
@@ -3243,20 +3221,25 @@
 	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;
-		}
-		if (i - currentpos > maxdiff) {
+		} 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;
 }
 
@@ -3278,7 +3261,7 @@
 	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')) {
+		} 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) {
@@ -3286,7 +3269,9 @@
 			return 0;
 		}
 	}
+
 	/* we found the beginning of the text */
+
 	return 0;
 }
 
@@ -3321,7 +3306,6 @@
 	colmax = columns - xmldoc_postbrlen(postbr);
 
 	textlen = strlen(text);
-
 	for (i = 0; i < textlen; i++) {
 		if (needtobreak || !(count % colmax)) {
 			if (text[i] == ' ') {
@@ -3380,91 +3364,101 @@
 /*! \internal
  *  \brief Colorize the xmldoc output.
  *  \param bwinput Not colorized input.
- *  \param base_fg Initial foreground color.
- *  \param base_bg Initial background color.
  *  \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;
+static char *xmldoc_colorization(const char *bwinput)
+{
+	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);
 
-	/* Calculate output string size. Try to figure out the needed space. */
-	for (i = 0; i < bwinputlen;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 = ast_str_create(256))) {
+		return NULL;
+	}
+
+	ast_term_color_code(&colorized, base_fg, 0);
 	if (!colorized) {
 		return NULL;
 	}
 
-	term_color_code(colorized, base_fg, base_bg, 23);
-	actual_len = strlen(colorized);
-
-	for (i = 0; i < bwinputlen;i++) {
+	for (i = 0; i < bwinputlen; i++) {
 		colorsection = 0;
-		/* Check if we are at the begining of a tag to be colorized. */
+		/* 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))) {
-				tmp = strcasestr(bwinput + i + strlen(colorized_tags[c].inittag), colorized_tags[c].endtag);
-
-				if (!tmp) {
-					continue;
-				}
-
-				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 (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 */
+			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. */
+			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) {
-			colorized[actual_len++] = bwinput[i];
-		}
-	}
-
-	term_color_code(colorized + strlen(colorized), COLOR_BRWHITE, 0, 23);
+			ast_str_append(&colorized, 0, "%c", bwinput[i]);
+			if (!colorized) {
+				return NULL;
+			}
+		}
+	}
+
+	ast_term_color_code(&colorized, COLOR_BRWHITE, 0);
+	if (!colorized) {
+		return NULL;
+	}
 
 	/* 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);
-	}
+	wrapped = xmldoc_string_wrap(colorized->str, xmldoc_text_columns, xmldoc_max_diff);
+
+	ast_free(colorized);
 
 	return wrapped;
 }
@@ -3484,6 +3478,7 @@
 		*output = NULL;
 		return;
 	}
+	
 	textlen = strlen(text);
 
 	*output = ast_str_create(textlen);
@@ -3494,7 +3489,7 @@
 
 	for (i = 0; i < textlen; i++) {
 		if (text[i] == '\n' || text[i] == '\r') {
-			while (text[i+1] == '\t' || text[i+1] == '\r' || text[i+1] == '\n') {
+			while (text[i + 1] == '\t' || text[i + 1] == '\r' || text[i + 1] == '\n') {
 				i++;
 			}
 			ast_str_append(output, 0, " ");
@@ -3503,6 +3498,7 @@
 			ast_str_append(output, 0, "%c", text[i]);
 		}
 	}
+
 	/* remove last spaces (we dont want always to remove the trailing spaces). */
 	if (lastspaces) {
 		ast_str_trim_blanks(*output);
@@ -3520,7 +3516,7 @@
  */
 static ast_xml_node *xmldoc_get_node(const char *type, const char *name, const char *language)
 {
-	ast_xml_node *node;
+	ast_xml_node *node = NULL;
 	struct documentation_tree *doctree;
 	char *lang;
 
@@ -3528,37 +3524,33 @@
 	AST_LIST_TRAVERSE(&xmldoc_tree, doctree, entry) {
 		/* the core xml documents have priority over thirdparty document. */
 		node = ast_xml_get_root(doctree->doc);
-		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);
-				}
-			}
-		}
-		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_RWLIST_UNLOCK(&xmldoc_tree);
-					return node;
-				}
-			}
-		} else {
-			AST_RWLIST_UNLOCK(&xmldoc_tree);
-			return node;
+		while ((node = ast_xml_find_element(node, type, "name", name))) {
+			/* 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);
+			}
+		}
+
+		if (node && node->AST_XML_CHILD) {
+			break;
+		}
+
+		/* 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))) {
+				break;
+			}
 		}
 	}
 	AST_RWLIST_UNLOCK(&xmldoc_tree);
 
-	return NULL;
+	return node;
 }
 
 /*! \internal
@@ -3946,31 +3938,34 @@
 	}
 
 	for (i = 0; i < ARRAY_LEN(special_tags); i++) {
-		if (!strcasecmp((const char *) node->AST_XML_NAME, special_tags[i].tagname)) {
-			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 = node->AST_XML_CHILD; node; node = node->AST_XML_NEXT) {
-				/* 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;
+		if (strcasecmp((const char *) node->AST_XML_NAME, 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 = node->AST_XML_CHILD; node; node = node->AST_XML_NEXT) {
+			/* 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;
 }
 
 /*! \internal
@@ -4495,6 +4490,7 @@
 			xmldoc_parse_enumlist(tmp, "    ", &ret);
 		}
 		/* remove last '\n' */
+		/* XXX Don't modify ast_str internals manually */
 		if (ret->str[ret->used-1] == '\n') {
 			ret->str[ret->used-1] = '\0';
 			ret->used--;
@@ -4547,55 +4543,67 @@
 }
 #endif /* AST_XML_DOCS */
 
+static int acf_retrieve_docs(struct ast_custom_function *acf)
+{
+#ifdef AST_XML_DOCS
+	char *tmpxml;
+
+	/* Let's try to find it in the Documentation XML */
+	if (!ast_strlen_zero(acf->desc) || !ast_strlen_zero(acf->synopsis)) {
+		return 0;
+	}
+
+	if (ast_string_field_init(acf, 128)) {
+		return -1;
+	}
+
+	/* load synopsis */
+	tmpxml = xmldoc_build_field("function", acf->name, "synopsis", 1);
+	ast_string_field_set(acf, synopsis, tmpxml);
+	ast_free(tmpxml);
+
+	/* load description */
+	tmpxml = xmldoc_build_field("function", acf->name, "description", 0);
+	ast_string_field_set(acf, desc, tmpxml);
+	ast_free(tmpxml);
+
+	/* load syntax */
+	tmpxml = xmldoc_build_syntax("function", acf->name);
+	ast_string_field_set(acf, syntax, tmpxml);
+	ast_free(tmpxml);
+
+	/* load arguments */
+	tmpxml = xmldoc_build_arguments("function", acf->name);
+	ast_string_field_set(acf, arguments, tmpxml);
+	ast_free(tmpxml);
+
+	/* load seealso */
+	tmpxml = xmldoc_build_seealso("function", acf->name);
+	ast_string_field_set(acf, seealso, tmpxml);
+	ast_free(tmpxml);
+
+	acf->docsrc = AST_XML_DOC;
+
+	return 0;
+#endif
+	return -1;
+}
+
 int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod)
 {
 	struct ast_custom_function *cur;
 	char tmps[80];
-#ifdef AST_XML_DOCS
-	char *tmpxml;
-#endif
-
-	if (!acf)
+
+	if (!acf) {
 		return -1;
+	}
 
 	acf->mod = mod;
 	acf->docsrc = AST_STATIC_DOC;
 
-#ifdef AST_XML_DOCS
-	/* Let's try to find it in the Documentation XML */
-	if (ast_strlen_zero(acf->desc) && ast_strlen_zero(acf->synopsis)) {
-		if (ast_string_field_init(acf, 128)) {
-			return -1;
-		}
-
-		/* load synopsis */
-		tmpxml = xmldoc_build_field("function", acf->name, "synopsis", 1);
-		ast_string_field_set(acf, synopsis, tmpxml);
-		ast_free(tmpxml);
-
-		/* load description */
-		tmpxml = xmldoc_build_field("function", acf->name, "description", 0);
-		ast_string_field_set(acf, desc, tmpxml);
-		ast_free(tmpxml);
-
-		/* load syntax */
-		tmpxml = xmldoc_build_syntax("function", acf->name);
-		ast_string_field_set(acf, syntax, tmpxml);
-		ast_free(tmpxml);
-
-		/* load arguments */
-		tmpxml = xmldoc_build_arguments("function", acf->name);
-		ast_string_field_set(acf, arguments, tmpxml);
-		ast_free(tmpxml);
-
-		/* load seealso */
-		tmpxml = xmldoc_build_seealso("function", acf->name);
-		ast_string_field_set(acf, seealso, tmpxml);
-		ast_free(tmpxml);
-
-		acf->docsrc = AST_XML_DOC;
-	}
-#endif
+	if (acf_retrieve_docs(acf)) {
+		return -1;
+	}
 
 	AST_RWLIST_WRLOCK(&acf_root);
 
@@ -4615,8 +4623,10 @@
 		}
 	}
 	AST_RWLIST_TRAVERSE_SAFE_END;
-	if (!cur)
+
+	if (!cur) {
 		AST_RWLIST_INSERT_TAIL(&acf_root, acf, acflist);
+	}
 
 	AST_RWLIST_UNLOCK(&acf_root);
 
@@ -6518,6 +6528,78 @@
  * Help for CLI commands ...
  */
 
+static void print_app_docs(struct ast_app *aa, int fd)
+{
+	/* 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 seealsotitle[40];
+	char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL, *syntax = NULL, *arguments = NULL;
+	char *seealso = NULL;
+	int syntax_size, synopsis_size, description_size, arguments_size, seealso_size;
+
+	snprintf(info, sizeof(info), "\n  -= Info about application '%s' =- \n\n", aa->name);
+	term_color(infotitle, info, COLOR_MAGENTA, 0, sizeof(infotitle));
+
+	term_color(syntitle, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
+	term_color(destitle, "[Description]\n", COLOR_MAGENTA, 0, 40);
+	term_color(stxtitle, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
+	term_color(argtitle, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
+	term_color(seealsotitle, "[See Also]\n", COLOR_MAGENTA, 0, 40);
+
+#ifdef AST_XML_DOCS
+	if (aa->docsrc == AST_XML_DOC) {
+		description = xmldoc_colorization(S_OR(aa->description, "Not available"));
+		arguments = xmldoc_colorization(S_OR(aa->arguments, "Not available"));
+		synopsis = xmldoc_colorization(S_OR(aa->synopsis, "Not available"));
+		seealso = xmldoc_colorization(S_OR(aa->seealso, "Not available"));
+		
+		if (!synopsis || !description || !arguments || !seealso) {
+			goto return_cleanup;
+		}
+	} else 
+#endif
+	{
+		synopsis_size = strlen(S_OR(aa->synopsis, "Not Available")) + MAX_ESCAPE_CHARS;
+		synopsis = ast_malloc(synopsis_size);
+
+		description_size = strlen(S_OR(aa->description, "Not Available")) + MAX_ESCAPE_CHARS;
+		description = ast_malloc(description_size);
+
+		arguments_size = strlen(S_OR(aa->arguments, "Not Available")) + MAX_ESCAPE_CHARS;
+		arguments = ast_malloc(arguments_size);
+
+		seealso_size = strlen(S_OR(aa->seealso, "Not Available")) + MAX_ESCAPE_CHARS;
+		seealso = ast_malloc(seealso_size);
+
+		if (!synopsis || !description || !arguments || !seealso) {
+			goto return_cleanup;
+		}
+
+		term_color(synopsis, S_OR(aa->synopsis, "Not available"), COLOR_CYAN, 0, synopsis_size);
+		term_color(description, S_OR(aa->description, "Not available"),	COLOR_CYAN, 0, description_size);
+		term_color(arguments, S_OR(aa->arguments, "Not available"), COLOR_CYAN, 0, arguments_size);
+		term_color(seealso, S_OR(aa->seealso, "Not available"), COLOR_CYAN, 0, seealso_size);
+	}
+
+	/* Handle the syntax the same for both XML and raw docs */
+	syntax_size = strlen(S_OR(aa->syntax, "Not Available")) + MAX_ESCAPE_CHARS;
+	if (!(syntax = ast_malloc(syntax_size))) {
+		goto return_cleanup;
+	}
+	term_color(syntax, S_OR(aa->syntax, "Not available"), COLOR_CYAN, 0, syntax_size);
+
+	ast_cli(fd, "%s%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n", 
+			infotitle, syntitle, synopsis, destitle, description, 
+			stxtitle, syntax, argtitle, arguments, seealsotitle, seealso);
+
+return_cleanup:
+	ast_free(description);
+	ast_free(arguments);
+	ast_free(synopsis);
+	ast_free(seealso);
+	ast_free(syntax);
+}
+
 /*
  * \brief 'show application' CLI command implementation function...
  */
@@ -6560,110 +6642,18 @@
 		return CLI_SHOWUSAGE;
 	}
 
-	/* ... go through all applications ... */
 	AST_RWLIST_RDLOCK(&apps);
 	AST_RWLIST_TRAVERSE(&apps, aa, list) {
-		/* ... compare this application name with all arguments given
-		 * to 'show application' command ... */
+		/* Check for each app that was supplied as an argument */
 		for (app = 3; app < a->argc; app++) {
-			if (!strcasecmp(aa->name, a->argv[app])) {
-				/* 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 seealsotitle[40];
-				char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL, *syntax = NULL, *arguments = NULL;
-				char *seealso = NULL;
-				int syntax_size, synopsis_size, description_size, arguments_size, seealso_size;
-
-				no_registered_app = 0;
-
-				snprintf(info, sizeof(info), "\n  -= Info about application '%s' =- \n\n", aa->name);
-				term_color(infotitle, info, COLOR_MAGENTA, 0, sizeof(infotitle));
-				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);
-				term_color(seealsotitle, "[See Also]\n", COLOR_MAGENTA, 0, 40);
-#ifdef AST_XML_DOCS
-				if (aa->docsrc == AST_XML_DOC) {
-					description = xmldoc_colorization(S_OR(aa->description, "Not available"), COLOR_CYAN, COLOR_BLACK);
-					arguments = xmldoc_colorization(S_OR(aa->arguments, "Not available"), COLOR_CYAN, COLOR_BLACK);
-					synopsis = xmldoc_colorization(S_OR(aa->synopsis, "Not available"), COLOR_CYAN, COLOR_BLACK);
-					seealso = xmldoc_colorization(S_OR(aa->seealso, "Not available"), COLOR_CYAN, COLOR_BLACK);
-				} else {
-#endif
-					if (!ast_strlen_zero(aa->synopsis)) {
-						synopsis_size = strlen(aa->synopsis) + 23;
-					} else {
-						synopsis_size = strlen("Not available") + 23;
-					}
-					synopsis = ast_malloc(synopsis_size);
-
-					if (!ast_strlen_zero(aa->description)) {
-						description_size = strlen(aa->description) + 23;
-					} else {
-						description_size = strlen("Not available") + 23;
-					}
-					description = ast_malloc(description_size);
-
-					if (!ast_strlen_zero(aa->arguments)) {
-						arguments_size = strlen(aa->arguments) + 23;
-					} else {
-						arguments_size = strlen("Not available") + 23;
-					}
-					arguments = ast_malloc(arguments_size);
-
-					if (!ast_strlen_zero(aa->seealso)) {
-						seealso_size = strlen(aa->seealso) + 23;
-					} else {
-						seealso_size = strlen("Not available") + 23;
-					}
-					seealso = ast_malloc(seealso_size);
-
-					if (!synopsis || !description || !arguments || !seealso) {
-						ast_free(synopsis);
-						ast_free(description);
-						ast_free(arguments);
-						ast_free(seealso);
-						continue;
-					}
-					term_color(synopsis, S_OR(aa->synopsis, "Not available"), COLOR_CYAN, 0, synopsis_size);
-					term_color(description, S_OR(aa->description, "Not available"),	COLOR_CYAN, 0, description_size);
-					term_color(arguments, S_OR(aa->arguments, "Not available"), COLOR_CYAN, 0, arguments_size);
-					term_color(seealso, S_OR(aa->seealso, "Not available"), COLOR_CYAN, 0, seealso_size);
-#ifdef AST_XML_DOCS
-				}
-#endif
-				if (!ast_strlen_zero(aa->syntax)) {
-					syntax_size = strlen(aa->syntax) + 23;
-				} else {
-					syntax_size = strlen("Not available") + 23;
-				}
-				syntax = ast_malloc(syntax_size);
-				if (syntax && synopsis && arguments && description && seealso) {
-					term_color(syntax, S_OR(aa->syntax, "Not available"), COLOR_CYAN, 0, syntax_size);
-					ast_cli(a->fd,"%s%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, argtitle,
-						arguments, syntitle, synopsis, destitle, description, seealsotitle, seealso);
-				} else {
-					/* ... one of our applications, show info ...*/
-					ast_cli(a->fd,"\n  -= Info about application '%s' =- \n\n"
-						"[Syntax]\n  %s\n\n"
-						"[Arguments]\n%s\n\n"
-						"[Synopsis]\n  %s\n\n"
-						"[Description]\n%s\n"
-						"[See Also]\n%s\n",
-						aa->name,
-						S_OR(aa->syntax, "Not available"),
-						S_OR(aa->arguments, "Not available"),
-						S_OR(aa->synopsis, "Not available"),
-						S_OR(aa->description, "Not available"),
-						S_OR(aa->seealso, "Not available"));
-				}
-				ast_free(description);
-				ast_free(arguments);
-				ast_free(synopsis);
-				ast_free(seealso);
-				ast_free(syntax);
-			}
+			if (strcasecmp(aa->name, a->argv[app])) {
+				continue;
+			}
+
+			/* We found it! */
+			no_registered_app = 0;
+
+			print_app_docs(aa, a->fd);
 		}
 	}
 	AST_RWLIST_UNLOCK(&apps);

Modified: team/group/appdocsxml/main/term.c
URL: http://svn.digium.com/view/asterisk/team/group/appdocsxml/main/term.c?view=diff&rev=152130&r1=152129&r2=152130
==============================================================================
--- team/group/appdocsxml/main/term.c (original)
+++ team/group/appdocsxml/main/term.c Mon Oct 27 00:22:34 2008
@@ -199,32 +199,72 @@
 	return outbuf;
 }
 
+static void check_fgcolor(int *fgcolor, int *attr)
+{
+	if (*fgcolor & 128) {
+		*attr = ast_opt_light_background ? 0 : ATTR_BRIGHT;
+		*fgcolor &= ~128;
+	}
+	
+	if (ast_opt_light_background) {
+		*fgcolor = opposite(*fgcolor);
+	}
+}
+
+static void check_bgcolor(int *bgcolor)
+{
+	if (*bgcolor) {
+		*bgcolor &= ~128;
+	}
+}
+
+static int check_colors_allowed(int fgcolor)
+{
+	return (!vt100compat || !fgcolor) ? 0 : 1;
+}
+
+int ast_term_color_code(struct ast_str **str, int fgcolor, int bgcolor)
+{
+	int attr = 0;
+
+	if (!check_colors_allowed(fgcolor)) {
+		return -1;
+	}
+
+	check_fgcolor(&fgcolor, &attr);
+	check_bgcolor(&bgcolor);
+	

[... 48 lines stripped ...]



More information about the asterisk-commits mailing list