From: Paul Eggert Date: Fri, 8 Apr 2011 23:28:52 +0000 (-0700) Subject: * eval.c: Port to Windows vsnprintf (Bug#8435). X-Git-Tag: emacs-pretest-24.0.90~104^2~275^2~356^2~19 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=eb3f1cc8dfe6a96505f1c5f9174b2712998cb52f;p=emacs.git * eval.c: Port to Windows vsnprintf (Bug#8435). Include . (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. --- diff --git a/src/ChangeLog b/src/ChangeLog index 0993b67cbca..68f3dbdedcb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,14 @@ +2011-04-08 Paul Eggert + + * eval.c: Port to Windows vsnprintf (Bug#8435). + Include . + (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 * eval.c (verror): Initial buffer size is 4000 (not 200) bytes. diff --git a/src/eval.c b/src/eval.c index f794a18da7d..0f9e012b823 100644 --- a/src/eval.c +++ b/src/eval.c @@ -18,6 +18,7 @@ along with GNU Emacs. If not, see . */ #include +#include #include #include "lisp.h" #include "blockinput.h" @@ -30,6 +31,10 @@ along with GNU Emacs. If not, see . */ #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);