Use module 'EOVERFLOW' rather than defining an EOVERFLOW replacement in the C
[pspp] / lib / vasnprintf.c
index 19cc009a3e80920f9ed90e633f49c6a749f8ac26..bf3f5dc65e4adfc5502dd68abcb876c340313cde 100644 (file)
 # include "fpucw.h"
 #endif
 
-/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW.  */
-#ifndef EOVERFLOW
-# define EOVERFLOW E2BIG
-#endif
-
 #if HAVE_WCHAR_T
 # if HAVE_WCSLEN
 #  define local_wcslen wcslen
@@ -3566,7 +3561,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
              {
                arg_type type = a.arg[dp->arg_index].type;
                int flags = dp->flags;
-#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
                int has_width;
                size_t width;
 #endif
@@ -3579,7 +3574,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 #else
 #              define prec_ourselves 0
 #endif
-#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+#if NEED_PRINTF_FLAG_LEFTADJUST
+#              define pad_ourselves 1
+#elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
                int pad_ourselves;
 #else
 #              define pad_ourselves 0
@@ -3593,7 +3590,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                TCHAR_T *tmp;
 #endif
 
-#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
                has_width = 0;
                width = 0;
                if (dp->width_start != dp->width_end)
@@ -3883,7 +3880,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 #endif
 
                /* Decide whether to perform the padding ourselves.  */
-#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+#if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
                switch (dp->conversion)
                  {
 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
@@ -4008,7 +4005,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 #endif
                  *fbp = dp->conversion;
 #if USE_SNPRINTF
-# if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3))
+# if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
                fbp[1] = '%';
                fbp[2] = 'n';
                fbp[3] = '\0';
@@ -4021,6 +4018,21 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                   in format strings in writable memory may crash the program
                   (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
                   in this situation.  */
+               /* On native Win32 systems (such as mingw), we can avoid using
+                  %n because:
+                    - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
+                      snprintf does not write more than the specified number
+                      of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
+                      '4', '5', '6' into buf, not '4', '5', '\0'.)
+                    - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
+                      allows us to recognize the case of an insufficient
+                      buffer size: it returns -1 in this case.
+                  On native Win32 systems (such as mingw) where the OS is
+                  Windows Vista, the use of %n in format strings by default
+                  crashes the program. See
+                    <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
+                    <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
+                  So we should avoid %n in this situation.  */
                fbp[1] = '\0';
 # endif
 #else
@@ -4494,7 +4506,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                    /* Here count <= allocated - length.  */
 
                    /* Perform padding.  */
-#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
                    if (pad_ourselves && has_width)
                      {
                        size_t w;
@@ -4535,15 +4547,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 # endif
                              DCHAR_T *p = rp + count;
                              DCHAR_T *end = p + pad;
-# if NEED_PRINTF_FLAG_ZERO
                              DCHAR_T *pad_ptr;
-#  if !DCHAR_IS_TCHAR
+# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
                              if (dp->conversion == 'c'
                                  || dp->conversion == 's')
                                /* No zero-padding for string directives.  */
                                pad_ptr = NULL;
                              else
-#  endif
+# endif
                                {
                                  pad_ptr = (*rp == '-' ? rp + 1 : rp);
                                  /* No zero-padding of "inf" and "nan".  */
@@ -4551,7 +4562,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                      || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
                                    pad_ptr = NULL;
                                }
-# endif
                              /* The generated string now extends from rp to p,
                                 with the zero padding insertion point being at
                                 pad_ptr.  */
@@ -4564,7 +4574,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                  for (; pad > 0; pad--)
                                    *p++ = ' ';
                                }
-# if NEED_PRINTF_FLAG_ZERO
                              else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
                                {
                                  /* Pad with zeroes.  */
@@ -4575,7 +4584,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                  for (; pad > 0; pad--)
                                    *p++ = '0';
                                }
-# endif
                              else
                                {
                                  /* Pad with spaces on the left.  */