[m-dev.] diff: MR_make_string improvement

Peter Ross peter.ross at miscrit.be
Thu Aug 17 02:05:22 AEST 2000


Hi,


===================================================================


Estimated hours taken: 0.5

runtime/mercury_string.c:
	Modify MR_make_string so that it first tries printing into a
	fixed size buffer.  Only if that buffer is not big enough do we
	allocate a buffer on the heap.


Index: mercury_string.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_string.c,v
retrieving revision 1.5
diff -u -r1.5 mercury_string.c
--- mercury_string.c	2000/08/11 13:49:58	1.5
+++ mercury_string.c	2000/08/16 15:57:33
@@ -13,49 +13,70 @@
   #define vsnprintf	_vsnprintf
 #endif
 
+#define SIZE	4096
+
 MR_String
 MR_make_string(MR_Code *proclabel, const char *fmt, ...) {
 	va_list		ap;
 	MR_String	result;
 	int 		n;
+	char		*p;
 
 #if defined(HAVE_VSNPRINTF) || defined(HAVE__VSNPRINTF)
-	/* Guess that 100 bytes should be sufficient */
-	int 		size = 100;
-	char		*p;
+	int 		size = 2 * SIZE;
+	char		fixed[SIZE];
+	int		dynamically_allocated = FALSE;
 	
-	p = MR_NEW_ARRAY(char, size);
+	va_start(ap, fmt);
+	n = vsnprintf(fixed, SIZE, fmt, ap);
+	va_end(ap);
 
-	while (1) {
-		/* Try to print in the allocated space. */
-		va_start(ap, fmt);
-		n = vsnprintf(p, size, fmt, ap);
-		va_end(ap);
-
-		/* If that worked, return the string.  */
-		if (n > -1 && n < size) {
-			break;
-		}
+	/*
+	** If that didn't work, use a dynamically allocated array twice
+	** the size of the fixed array and keep growing the array until
+	** the string fits.
+	*/
+	if (!(n > -1 && n < size)) {
+		p = MR_NEW_ARRAY(char, size);
+
+		while (1) {
+			dynamically_allocated = TRUE;
+
+			/* Try to print in the allocated space. */
+			va_start(ap, fmt);
+			n = vsnprintf(p, size, fmt, ap);
+			va_end(ap);
+
+			/* If that worked, return the string.  */
+			if (n > -1 && n < size) {
+				break;
+			}
+
+			/* Else try again with more space.  */
+			if (n > -1) {	/* glibc 2.1 */
+				size = n + 1; /* precisely what is needed */
+			} else {	/* glibc 2.0 */
+				size *= 2;  /* twice the old size */
+			}
 
-		/* Else try again with more space.  */
-		if (n > -1) {	/* glibc 2.1 */
-			size = n + 1; /* precisely what is needed */
-		} else {	/* glibc 2.0 */
-			size *= 2;  /* twice the old size */
+			MR_RESIZE_ARRAY(p, char, size);
 		}
-
-		MR_RESIZE_ARRAY(p, char, size);
+	} else {
+		p = fixed;
 	}
+
 #else
 		/* 
 		** It is possible for this buffer to overflow and
 		** then bad things may happen
 		*/
-	char p[40960];
+	char fixed[40960];
 
 	va_start(ap, fmt);
-	n = vsprintf(p, fmt, ap);
+	n = vsprintf(fixed, fmt, ap);
 	va_end(ap);
+
+	p = fixed;
 #endif
 	      
 	MR_allocate_aligned_string_msg(result, strlen(p),
@@ -63,7 +84,9 @@
 	strcpy(result, p);
 
 #ifdef HAVE_VSNPRINTF
-	MR_free(p);
+	if (dynamically_allocated) {
+		MR_free(p);
+	}
 #endif
 
 	return result;

--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list