fix typos in mathl
[gnulib.git] / lib / vasnprintf.c
index 1a74a44..74b3037 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)
@@ -3659,6 +3656,44 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                  }
 #endif
 
+               /* Decide whether to handle the precision ourselves.  */
+#if NEED_PRINTF_UNBOUNDED_PRECISION
+               switch (dp->conversion)
+                 {
+                 case 'd': case 'i': case 'u':
+                 case 'o':
+                 case 'x': case 'X': case 'p':
+                   prec_ourselves = has_precision && (precision > 0);
+                   break;
+                 default:
+                   prec_ourselves = 0;
+                   break;
+                 }
+#endif
+
+               /* Decide whether to perform the padding ourselves.  */
+#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
+                 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
+                    to perform the padding after this conversion.  Functions
+                    with unistdio extensions perform the padding based on
+                    character count rather than element count.  */
+                 case 'c': case 's':
+# endif
+# if NEED_PRINTF_FLAG_ZERO
+                 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
+                 case 'a': case 'A':
+# endif
+                   pad_ourselves = 1;
+                   break;
+                 default:
+                   pad_ourselves = prec_ourselves;
+                   break;
+                 }
+#endif
+
 #if !USE_SNPRINTF
                /* Allocate a temporary buffer of sufficient size for calling
                   sprintf.  */
@@ -3835,18 +3870,22 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                      abort ();
                    }
 
+                 if (!pad_ourselves)
+                   {
 # if ENABLE_UNISTDIO
-                 /* Padding considers the number of characters, therefore the
-                    number of elements after padding may be
-                      > max (tmp_length, width)
-                    but is certainly
-                      <= tmp_length + width.  */
-                 tmp_length = xsum (tmp_length, width);
+                     /* Padding considers the number of characters, therefore
+                        the number of elements after padding may be
+                          > max (tmp_length, width)
+                        but is certainly
+                          <= tmp_length + width.  */
+                     tmp_length = xsum (tmp_length, width);
 # else
-                 /* Padding considers the number of elements, says POSIX.  */
-                 if (tmp_length < width)
-                   tmp_length = width;
+                     /* Padding considers the number of elements,
+                        says POSIX.  */
+                     if (tmp_length < width)
+                       tmp_length = width;
 # endif
+                   }
 
                  tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
                }
@@ -3867,44 +3906,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                  }
 #endif
 
-               /* Decide whether to handle the precision ourselves.  */
-#if NEED_PRINTF_UNBOUNDED_PRECISION
-               switch (dp->conversion)
-                 {
-                 case 'd': case 'i': case 'u':
-                 case 'o':
-                 case 'x': case 'X': case 'p':
-                   prec_ourselves = has_precision && (precision > 0);
-                   break;
-                 default:
-                   prec_ourselves = 0;
-                   break;
-                 }
-#endif
-
-               /* Decide whether to perform the padding ourselves.  */
-#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
-               switch (dp->conversion)
-                 {
-# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
-                 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
-                    to perform the padding after this conversion.  Functions
-                    with unistdio extensions perform the padding based on
-                    character count rather than element count.  */
-                 case 'c': case 's':
-# endif
-# if NEED_PRINTF_FLAG_ZERO
-                 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
-                 case 'a': case 'A':
-# endif
-                   pad_ourselves = 1;
-                   break;
-                 default:
-                   pad_ourselves = prec_ourselves;
-                   break;
-                 }
-#endif
-
                /* Construct the format string for calling snprintf or
                   sprintf.  */
                fbp = buf;
@@ -4008,7 +4009,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 +4022,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
@@ -4386,14 +4402,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                      }
 #endif
 
-#if !DCHAR_IS_TCHAR
-# if !USE_SNPRINTF
+#if !USE_SNPRINTF
                    if (count >= tmp_length)
                      /* tmp_length was incorrectly calculated - fix the
                         code above!  */
                      abort ();
-# endif
+#endif
 
+#if !DCHAR_IS_TCHAR
                    /* Convert from TCHAR_T[] to DCHAR_T[].  */
                    if (dp->conversion == 'c' || dp->conversion == 's')
                      {
@@ -4494,7 +4510,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;
@@ -4511,7 +4527,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                        if (w < width)
                          {
                            size_t pad = width - w;
-# if USE_SNPRINTF
+
                            /* Make room for the result.  */
                            if (xsum (count, pad) > allocated - length)
                              {
@@ -4521,12 +4537,16 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                  xmax (xsum3 (length, count, pad),
                                        xtimes (allocated, 2));
 
+# if USE_SNPRINTF
                                length += count;
                                ENSURE_ALLOCATION (n);
                                length -= count;
+# else
+                               ENSURE_ALLOCATION (n);
+# endif
                              }
                            /* Here count + pad <= allocated - length.  */
-# endif
+
                            {
 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
                              DCHAR_T * const rp = result + length;
@@ -4536,7 +4556,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                              DCHAR_T *p = rp + count;
                              DCHAR_T *end = p + pad;
                              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.  */
@@ -4587,13 +4607,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                      }
 #endif
 
-#if DCHAR_IS_TCHAR && !USE_SNPRINTF
-                   if (count >= tmp_length)
-                     /* tmp_length was incorrectly calculated - fix the
-                        code above!  */
-                     abort ();
-#endif
-
                    /* Here still count <= allocated - length.  */
 
 #if !DCHAR_IS_TCHAR || USE_SNPRINTF