gengtype.c (oprintf): Mostly revert changes from 2007-03-26...
authorZack Weinberg <zack@mrtock.ucsd.edu>
Thu, 29 Mar 2007 14:59:52 +0000 (14:59 +0000)
committerZack Weinberg <zack@gcc.gnu.org>
Thu, 29 Mar 2007 14:59:52 +0000 (14:59 +0000)
* gengtype.c (oprintf): Mostly revert changes from 2007-03-26;
add comment explaining why vsnprintf cannot be used.

From-SVN: r123332

gcc/ChangeLog
gcc/gengtype.c

index d6c580aa317eb9858dbda69ad89947239d93e1b5..755d3be1065b868568610491e6bb756f8c301fcd 100644 (file)
@@ -1,3 +1,8 @@
+2007-03-29  Zack Weinberg  <zack@mrtock.ucsd.edu>
+
+       * gengtype.c (oprintf): Mostly revert changes from 2007-03-26;
+       add comment explaining why vsnprintf cannot be used.
+
 2007-03-29  Douglas Gregor  <doug.gregor@gmail.com>
 
        PR tree-optimization/30666
index e0cd6c2599fd6fe246c3a8d9924d9e87e31be134..648246dbd66bf1b96a0e036a178450fa278e7774 100644 (file)
@@ -1475,24 +1475,26 @@ create_file (const char *name, const char *oname)
   return f;
 }
 
-/* Print, like fprintf, to O.  */
+/* Print, like fprintf, to O.  
+   N.B. You might think this could be implemented more efficiently
+   with vsnprintf().  Unfortunately, there are C libraries that
+   provide that function but without the C99 semantics for its return
+   value, making it impossible to know how much space is required.  */
 void
 oprintf (outf_p o, const char *format, ...)
 {
+  char *s;
   size_t slength;
+  va_list ap;
 
-  /* Try first with the assumption that there is enough space.  */
-  {
-    va_list ap;
-    va_start (ap, format);
-    slength = vsnprintf (o->buf + o->bufused, o->buflength - o->bufused,
-                        format, ap);
-    va_end (ap);
-  }
+  va_start (ap, format);
+  slength = vasprintf (&s, format, ap);
+  if (s == NULL || (int)slength < 0)
+    fatal ("out of memory");
+  va_end (ap);
 
-  if (o->bufused + slength >= o->buflength)
+  if (o->bufused + slength > o->buflength)
     {
-      /* There wasn't enough space.  */
       size_t new_len = o->buflength;
       if (new_len == 0)
        new_len = 1024;
@@ -1501,21 +1503,10 @@ oprintf (outf_p o, const char *format, ...)
       } while (o->bufused + slength >= new_len);
       o->buf = XRESIZEVEC (char, o->buf, new_len);
       o->buflength = new_len;
-
-      /* We now know that there is enough space. */
-      {
-       size_t slen2;
-       va_list ap;
-       va_start (ap, format);
-       slen2 = vsnprintf (o->buf + o->bufused, o->buflength - o->bufused,
-                          format, ap);
-       va_end (ap);
-
-       gcc_assert (slen2 == slength);
-       gcc_assert (o->bufused + slen2 < o->buflength);
-      }
     }
+  memcpy (o->buf + o->bufused, s, slength);
   o->bufused += slength;
+  free (s);
 }
 
 /* Open the global header file and the language-specific header files.  */