]> git.eshelyaron.com Git - emacs.git/commitdiff
* eval.c: Port to Windows vsnprintf (Bug#8435).
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 8 Apr 2011 23:28:52 +0000 (16:28 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 8 Apr 2011 23:28:52 +0000 (16:28 -0700)
Include <limits.h>.
(SIZE_MAX): Define if the headers do not.
(verror): Do not give up if vsnprintf returns a negative count.
Instead, grow the buffer.  This ports to Windows vsnprintf, which
does not conform to C99.  Problem reported by Eli Zaretskii.
Also, simplify the allocation scheme, by avoiding the need for
calling realloc, and removing the ALLOCATED variable.

src/ChangeLog
src/eval.c

index 0993b67cbca297634b2255d017846a70eabca8fa..68f3dbdedcba90d951824e276711b843830428a4 100644 (file)
@@ -1,3 +1,14 @@
+2011-04-08  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * eval.c: Port to Windows vsnprintf (Bug#8435).
+       Include <limits.h>.
+       (SIZE_MAX): Define if the headers do not.
+       (verror): Do not give up if vsnprintf returns a negative count.
+       Instead, grow the buffer.  This ports to Windows vsnprintf, which
+       does not conform to C99.  Problem reported by Eli Zaretskii.
+       Also, simplify the allocation scheme, by avoiding the need for
+       calling realloc, and removing the ALLOCATED variable.
+
 2011-04-07  Paul Eggert  <eggert@cs.ucla.edu>
 
        * eval.c (verror): Initial buffer size is 4000 (not 200) bytes.
index f794a18da7d9552ad442b8f5236892e6a5017f1f..0f9e012b823163711cdd5d0e2571ebcfc3af5012 100644 (file)
@@ -18,6 +18,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 #include <config.h>
+#include <limits.h>
 #include <setjmp.h>
 #include "lisp.h"
 #include "blockinput.h"
@@ -30,6 +31,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "xterm.h"
 #endif
 
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+
 /* This definition is duplicated in alloc.c and keyboard.c.  */
 /* Putting it in lisp.h makes cc bomb out!  */
 
@@ -1978,36 +1983,37 @@ verror (const char *m, va_list ap)
 {
   char buf[4000];
   size_t size = sizeof buf;
-  size_t size_max = (size_t) -1;
+  size_t size_max =
+    min (MOST_POSITIVE_FIXNUM, min (INT_MAX, SIZE_MAX - 1)) + 1;
   char *buffer = buf;
-  int allocated = 0;
   int used;
   Lisp_Object string;
 
   while (1)
     {
       used = vsnprintf (buffer, size, m, ap);
+
       if (used < 0)
-       used = 0;
-      if (used < size)
-       break;
-      if (size <= size_max / 2)
-       size *= 2;
-      else if (size < size_max)
-       size = size_max;
-      else
-       memory_full ();
-      if (allocated)
-       buffer = (char *) xrealloc (buffer, size);
-      else
        {
-         buffer = (char *) xmalloc (size);
-         allocated = 1;
+         /* Non-C99 vsnprintf, such as w32, returns -1 when SIZE is too small.
+            Guess a larger USED to work around the incompatibility.  */
+         used = (size <= size_max / 2 ? 2 * size
+                 : size < size_max ? size_max - 1
+                 : size_max);
        }
+      else if (used < size)
+       break;
+      if (size_max <= used)
+       memory_full ();
+      size = used + 1;
+
+      if (buffer != buf)
+       xfree (buffer);
+      buffer = (char *) xmalloc (size);
     }
 
   string = make_string (buffer, used);
-  if (allocated)
+  if (buffer != buf)
     xfree (buffer);
 
   xsignal1 (Qerror, string);