+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.
#include <config.h>
+#include <limits.h>
#include <setjmp.h>
#include "lisp.h"
#include "blockinput.h"
#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! */
{
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);