From eb3f1cc8dfe6a96505f1c5f9174b2712998cb52f Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 8 Apr 2011 16:28:52 -0700 Subject: [PATCH] * 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. --- src/ChangeLog | 11 +++++++++++ src/eval.c | 40 +++++++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 17 deletions(-) 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); -- 2.39.2