Modify MR_make_string so that it first tries printing into a

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.
This commit is contained in:
Peter Ross
2000-08-16 16:02:21 +00:00
parent d2592cd1d2
commit b5c0e0d4cf

View File

@@ -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 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);
/* If that worked, return the string. */
if (n > -1 && n < size) {
break;
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 */
}
MR_RESIZE_ARRAY(p, char, 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);
} 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 @@ MR_make_string(MR_Code *proclabel, const char *fmt, ...) {
strcpy(result, p);
#ifdef HAVE_VSNPRINTF
MR_free(p);
if (dynamically_allocated) {
MR_free(p);
}
#endif
return result;