[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