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

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Aug 12 21:31:21 CDT 2008


Author: eliel
Date: Tue Aug 12 21:31:20 2008
New Revision: 137400

URL: http://svn.digium.com/view/asterisk?view=rev&rev=137400
Log:
An improved xmldoc_reverse_helper() implementation, making use of a va_list to pass
more than just the parameter name.
We are allocating the buffer to the exact needed space, so the use of strcpy is safe.

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=137400&r1=137399&r2=137400
==============================================================================
--- team/group/appdocsxml/main/pbx.c (original)
+++ team/group/appdocsxml/main/pbx.c Tue Aug 12 21:31:20 2008
@@ -2837,48 +2837,48 @@
 }
 
 /*! \brief Helper function used to build the syntax, it allocates the needed buffer (or reallocates it),
- *         and based on the reverse value it makes use of fmt or fmtrev to print paramname inside the 
+ *         and based on the reverse value it makes use of fmt or fmtrev to print the parameter list inside the 
  *         realloced buffer (syntax).
- *  \param reverse We are goinf backwards while generating the syntax?
+ *  \param reverse We are going backwards while generating the syntax?
  *  \param len Current length of 'syntax' buffer.
  *  \param syntax Output buffer for the concatenated values.
- *  \param paramname Parameter name, it can't be NULL! at least put "".
- *  \param fmt A format string that will be used in a sprintf call, it must always have a %s inside it, even if
- *         not needed!.
- *  \param fmtrev A format string that will be used in a sprintf call when reverse=1, it must always have a %s
- *         inside it, event if not used.
+ *  \param fmt A format string that will be used in a sprintf call
+ *  \param fmtrev A format string that will be used in a sprintf call when reverse=1
  */
-static void xmldoc_reverse_helper(int reverse, int *len, char **syntax, const char *paramname, char *fmt, char *fmtrev)
-{
-	int fmtlen = (reverse ? strlen(fmtrev) : strlen(fmt));
-	int i;
-	char *usefmt = (reverse ? fmtrev : fmt), tmp;
-	int totlen = *len + fmtlen + strlen(paramname) + 1 - 2; /* -2 to remove %s */
-
-	if (!paramname) {
-		paramname = "";
-	}
-
-	/* '- 2' do not count %s that is always present! */
+static void xmldoc_reverse_helper(int reverse, int *len, char **syntax, const char *fmt, const char *fmtrev, ...)
+{
+	int totlen, tmpfmtlen;
+	char *tmpfmt = NULL, tmp;
+	va_list ap;
+
+	va_start(ap, fmtrev);
+	ast_vasprintf(&tmpfmt, (reverse ? fmtrev : fmt), ap);
+	va_end(ap);
+
+	tmpfmtlen = strlen(tmpfmt);
+	totlen = *len + tmpfmtlen + 1;
+
 	*syntax = ast_realloc(*syntax, totlen);
 
 	if (!*syntax) {
-		/* memory allocation failure. */
+		ast_free(tmpfmt);
 		return;
 	}
 
 	if (reverse) {
-		memmove(*syntax + totlen - *len - 1, *syntax, *len);
+		memmove(*syntax + tmpfmtlen, *syntax, *len);
+		/* Save this char, it will be overwritten by the \0 of strcpy. */
+		tmp = (*syntax)[0];
+		strcpy(*syntax, tmpfmt);
+		/* Restore the already saved char. */
+		(*syntax)[tmpfmtlen] = tmp;
 		(*syntax)[totlen - 1] = '\0';
-		/* This char will be overwritten by the '\0', so save it. */
-		tmp = (*syntax)[0];
-		i = sprintf(*syntax, usefmt, paramname);
-		(*syntax)[i] = tmp;
-		/* Recover the over written char. */
-		*len = totlen - 1;
 	} else {
-		*len += sprintf(*syntax + *len, usefmt, paramname);
-	}
+		strcpy(*syntax + *len, tmpfmt);
+	}
+
+	*len = totlen - 1;
+	ast_free(tmpfmt);
 }
 
 /*! \brief Build the syntax for an application or a function.
@@ -2986,11 +2986,7 @@
 	}
 
 	/* init syntax string. */
-	if (!reverse) {
-		xmldoc_reverse_helper(reverse, &len, &syntax, name, "%s(", "");
-	} else {
-		xmldoc_reverse_helper(reverse, &len, &syntax, "", "", "%s)");
-	}
+	xmldoc_reverse_helper(reverse, &len, &syntax, "%s(", ")", name);
 
 	while (node) {
 		if (strcasecmp((char *)node->AST_XML_NAME, "parameter")) {
@@ -3025,23 +3021,23 @@
 		if (required) {
 			/* First parameter */
 			if (!paramcount) {
-				xmldoc_reverse_helper(reverse, &len, &syntax, (const char *)paramname, "%s", "%s");
+				xmldoc_reverse_helper(reverse, &len, &syntax, "%s", "%s", paramname);
 			} else {
 				while (openbrackets > 0) {
-					xmldoc_reverse_helper(reverse, &len, &syntax, "", "%s]", "[%s");
+					xmldoc_reverse_helper(reverse, &len, &syntax, "]", "[");
 					openbrackets--;
 				}
-				xmldoc_reverse_helper(reverse, &len, &syntax, (const char *)paramname, ",%s", "%s,");
+				xmldoc_reverse_helper(reverse, &len, &syntax, ",%s", "%s,", paramname);
 			}
 		} else {
 			/* First parameter */
 			if (!paramcount) {
-				xmldoc_reverse_helper(reverse, &len, &syntax, (const char *)paramname, "[%s]", "[%s]");
+				xmldoc_reverse_helper(reverse, &len, &syntax, "[%s]", "[%s]", paramname);
 			} else {
 				if (ISLAST(reverse, node)) {
-					xmldoc_reverse_helper(reverse, &len, &syntax, (const char *)paramname, ",[%s]", "[%s],");
+					xmldoc_reverse_helper(reverse, &len, &syntax, ",[%s]", "[%s],", paramname);
 				} else {
-					xmldoc_reverse_helper(reverse, &len, &syntax, (const char *)paramname, "[,%s", "%s,]");
+					xmldoc_reverse_helper(reverse, &len, &syntax, "[,%s", "%s,]", paramname);
 					openbrackets++;
 				}
 			}
@@ -3054,16 +3050,12 @@
 	}
 
 	while (openbrackets > 0) {
-		xmldoc_reverse_helper(reverse, &len, &syntax, "", "%s]", "%s[");
+		xmldoc_reverse_helper(reverse, &len, &syntax, "]", "[");
 		openbrackets--;
 	}
 
 	/* close syntax string. */
-	if (!reverse) {	
-		xmldoc_reverse_helper(reverse, &len, &syntax, "", "%s)", "");
-	} else {
-		xmldoc_reverse_helper(reverse, &len, &syntax, name, "", "%s(");
-	}
+	xmldoc_reverse_helper(reverse, &len, &syntax, ")", "%s(", name);
 
 	return syntax;
 #undef ISLAST




More information about the svn-commits mailing list