changeset 147:0f50f1badd75

*** empty log message ***
author Richard M. Stallman <rms@gnu.org>
date Wed, 26 Dec 1990 22:28:51 +0000
parents db0041ccc1e6
children a099f0c77321
files src/doprnt.c
diffstat 1 files changed, 52 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/doprnt.c	Tue Dec 25 23:11:33 1990 +0000
+++ b/src/doprnt.c	Wed Dec 26 22:28:51 1990 +0000
@@ -23,6 +23,14 @@
 #include <stdio.h>
 #include <ctype.h>
 
+/* Generate output from a format-spec FORMAT,
+   terminated at position FORMAT_END.
+   Output goes in BUFFER, which has room for BUFSIZE chars.
+   If the output does not fit, truncate it to fit.
+   Returns the number of characters stored into BUFFER.
+   ARGS points to the vector of arguments, and NARGS says how many.
+   A double counts as two arguments.  */
+
 doprnt (buffer, bufsize, format, format_end, nargs, args)
      char *buffer;
      register int bufsize;
@@ -34,7 +42,14 @@
   int cnt = 0;			/* Number of arg to gobble next */
   register char *fmt = format;	/* Pointer into format string */
   register char *bufptr = buffer; /* Pointer into output buffer.. */
-  char tembuf[512];
+  /* Use this for sprintf unless we need something really big.  */
+  char tembuf[100];
+  /* Size of sprintf_buffer.  */
+  int size_allocated = 100;
+  /* Buffer to use for sprintf.  Either tembuf or same as BIG_BUFFER.  */
+  char *sprintf_buffer = tembuf;
+  /* Buffer we have got with malloc.  */
+  char *big_buffer = 0;
   register int tem;
   char *string;
   char fmtcpy[20];
@@ -50,6 +65,8 @@
     {
       if (*fmt == '%')	/* Check for a '%' character */
 	{
+	  int size_bound;
+
 	  fmt++;
 	  /* Copy this one %-spec into fmtcopy.  */
 	  string = fmtcpy;
@@ -62,6 +79,18 @@
 	      fmt++;
 	    }
 	  *string = 0;
+	  /* Get an idea of how much space we might need.  */
+	  size_bound = atoi (&fmtcpy[1]) + 50;
+	  /* Make sure we have that much.  */
+	  if (size_bound > size_allocated)
+	    {
+	      if (big_buffer)
+		big_buffer = (char *) xrealloc (big_buffer, size_bound);
+	      else
+		big_buffer = (char *) xmalloc (size_bound);
+	      sprintf_buffer = big_buffer;
+	      size_allocated = size_bound;
+	    }
 	  minlen = 0;
 	  switch (*fmt++)
 	    {
@@ -74,11 +103,26 @@
 	    case 'x':
 	      if (cnt == nargs)
 		error ("Format string wants too many arguments");
-	      sprintf (tembuf, fmtcpy, args[cnt++]);
-	      /* Now copy tembuf into final output, truncating as nec.  */
-	      string = tembuf;
+	      sprintf (sprintf_buffer, fmtcpy, args[cnt++]);
+	      /* Now copy into final output, truncating as nec.  */
+	      string = sprintf_buffer;
 	      goto doit;
 
+	    case 'f':
+	    case 'e':
+	    case 'g':
+	      {
+		union { double d; char *half[2]; } u;
+		if (cnt + 1 == nargs)
+		  error ("Format string wants too many arguments");
+		u.half[0] = args[cnt++];
+		u.half[1] = args[cnt++];
+		sprintf (sprintf_buffer, fmtcpy, u.d);
+		/* Now copy into final output, truncating as nec.  */
+		string = sprintf_buffer;
+		goto doit;
+	      }
+
 	    case 'S':
 	      string[-1] = 's';
 	    case 's':
@@ -132,6 +176,10 @@
       bufsize--;
     };
 
+  /* If we had to malloc something, free it.  */
+  if (big_buffer)
+    free (big_buffer);
+
   *bufptr = 0;		/* Make sure our string end with a '\0' */
   return bufptr - buffer;
 }