summaryrefslogtreecommitdiffstats
path: root/gl/vasnprintf.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/vasnprintf.c')
-rw-r--r--gl/vasnprintf.c361
1 files changed, 272 insertions, 89 deletions
diff --git a/gl/vasnprintf.c b/gl/vasnprintf.c
index d5b40286..93aef6f2 100644
--- a/gl/vasnprintf.c
+++ b/gl/vasnprintf.c
@@ -95,7 +95,7 @@
95 95
96#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL 96#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
97# include <math.h> 97# include <math.h>
98# include "isnand.h" 98# include "isnand-nolibm.h"
99#endif 99#endif
100 100
101#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL 101#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
@@ -106,7 +106,7 @@
106 106
107#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL 107#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
108# include <math.h> 108# include <math.h>
109# include "isnand.h" 109# include "isnand-nolibm.h"
110# include "printf-frexp.h" 110# include "printf-frexp.h"
111#endif 111#endif
112 112
@@ -117,11 +117,6 @@
117# include "fpucw.h" 117# include "fpucw.h"
118#endif 118#endif
119 119
120/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */
121#ifndef EOVERFLOW
122# define EOVERFLOW E2BIG
123#endif
124
125#if HAVE_WCHAR_T 120#if HAVE_WCHAR_T
126# if HAVE_WCSLEN 121# if HAVE_WCSLEN
127# define local_wcslen wcslen 122# define local_wcslen wcslen
@@ -182,10 +177,12 @@ local_wcslen (const wchar_t *s)
182# endif 177# endif
183#else 178#else
184 /* TCHAR_T is char. */ 179 /* TCHAR_T is char. */
185# /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'. 180 /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
186 But don't use it on BeOS, since BeOS snprintf produces no output if the 181 But don't use it on BeOS, since BeOS snprintf produces no output if the
187 size argument is >= 0x3000000. */ 182 size argument is >= 0x3000000.
188# if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ 183 Also don't use it on Linux libc5, since there snprintf with size = 1
184 writes any output without bounds, like sprintf. */
185# if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
189# define USE_SNPRINTF 1 186# define USE_SNPRINTF 1
190# else 187# else
191# define USE_SNPRINTF 0 188# define USE_SNPRINTF 0
@@ -203,7 +200,22 @@ local_wcslen (const wchar_t *s)
203/* Here we need to call the native sprintf, not rpl_sprintf. */ 200/* Here we need to call the native sprintf, not rpl_sprintf. */
204#undef sprintf 201#undef sprintf
205 202
206#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL 203/* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
204 warnings in this file. Use -Dlint to suppress them. */
205#ifdef lint
206# define IF_LINT(Code) Code
207#else
208# define IF_LINT(Code) /* empty */
209#endif
210
211/* Avoid some warnings from "gcc -Wshadow".
212 This file doesn't use the exp() and remainder() functions. */
213#undef exp
214#define exp expo
215#undef remainder
216#define remainder rem
217
218#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
207/* Determine the decimal-point character according to the current locale. */ 219/* Determine the decimal-point character according to the current locale. */
208# ifndef decimal_point_char_defined 220# ifndef decimal_point_char_defined
209# define decimal_point_char_defined 1 221# define decimal_point_char_defined 1
@@ -243,11 +255,11 @@ is_infinite_or_zero (double x)
243 255
244#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL 256#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
245 257
246/* Equivalent to !isfinite(x), but does not require libm. */ 258/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
247static int 259static int
248is_infinitel (long double x) 260is_infinite_or_zerol (long double x)
249{ 261{
250 return isnanl (x) || (x + x == x && x != 0.0L); 262 return isnanl (x) || x + x == x;
251} 263}
252 264
253#endif 265#endif
@@ -1201,7 +1213,7 @@ scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
1201static char * 1213static char *
1202scale10_round_decimal_long_double (long double x, int n) 1214scale10_round_decimal_long_double (long double x, int n)
1203{ 1215{
1204 int e; 1216 int e IF_LINT(= 0);
1205 mpn_t m; 1217 mpn_t m;
1206 void *memory = decode_long_double (x, &e, &m); 1218 void *memory = decode_long_double (x, &e, &m);
1207 return scale10_round_decimal_decoded (e, m, memory, n); 1219 return scale10_round_decimal_decoded (e, m, memory, n);
@@ -1219,7 +1231,7 @@ scale10_round_decimal_long_double (long double x, int n)
1219static char * 1231static char *
1220scale10_round_decimal_double (double x, int n) 1232scale10_round_decimal_double (double x, int n)
1221{ 1233{
1222 int e; 1234 int e IF_LINT(= 0);
1223 mpn_t m; 1235 mpn_t m;
1224 void *memory = decode_double (x, &e, &m); 1236 void *memory = decode_double (x, &e, &m);
1225 return scale10_round_decimal_decoded (e, m, memory, n); 1237 return scale10_round_decimal_decoded (e, m, memory, n);
@@ -1306,9 +1318,9 @@ floorlog10l (long double x)
1306 } 1318 }
1307 /* Now 0.95 <= z <= 1.01. */ 1319 /* Now 0.95 <= z <= 1.01. */
1308 z = 1 - z; 1320 z = 1 - z;
1309 /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ... 1321 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1310 Four terms are enough to get an approximation with error < 10^-7. */ 1322 Four terms are enough to get an approximation with error < 10^-7. */
1311 l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25))); 1323 l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1312 /* Finally multiply with log(2)/log(10), yields an approximation for 1324 /* Finally multiply with log(2)/log(10), yields an approximation for
1313 log10(x). */ 1325 log10(x). */
1314 l *= 0.30102999566398119523; 1326 l *= 0.30102999566398119523;
@@ -1397,9 +1409,9 @@ floorlog10 (double x)
1397 } 1409 }
1398 /* Now 0.95 <= z <= 1.01. */ 1410 /* Now 0.95 <= z <= 1.01. */
1399 z = 1 - z; 1411 z = 1 - z;
1400 /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ... 1412 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1401 Four terms are enough to get an approximation with error < 10^-7. */ 1413 Four terms are enough to get an approximation with error < 10^-7. */
1402 l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25))); 1414 l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1403 /* Finally multiply with log(2)/log(10), yields an approximation for 1415 /* Finally multiply with log(2)/log(10), yields an approximation for
1404 log10(x). */ 1416 log10(x). */
1405 l *= 0.30102999566398119523; 1417 l *= 0.30102999566398119523;
@@ -1409,6 +1421,20 @@ floorlog10 (double x)
1409 1421
1410# endif 1422# endif
1411 1423
1424/* Tests whether a string of digits consists of exactly PRECISION zeroes and
1425 a single '1' digit. */
1426static int
1427is_borderline (const char *digits, size_t precision)
1428{
1429 for (; precision > 0; precision--, digits++)
1430 if (*digits != '0')
1431 return 0;
1432 if (*digits != '1')
1433 return 0;
1434 digits++;
1435 return *digits == '\0';
1436}
1437
1412#endif 1438#endif
1413 1439
1414DCHAR_T * 1440DCHAR_T *
@@ -2552,8 +2578,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
2552# elif NEED_PRINTF_INFINITE_LONG_DOUBLE 2578# elif NEED_PRINTF_INFINITE_LONG_DOUBLE
2553 || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE 2579 || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2554 /* Some systems produce wrong output for Inf, 2580 /* Some systems produce wrong output for Inf,
2555 -Inf, and NaN. */ 2581 -Inf, and NaN. Some systems in this category
2556 && is_infinitel (a.arg[dp->arg_index].a.a_longdouble)) 2582 (IRIX 5.3) also do so for -0.0. Therefore we
2583 treat this case here as well. */
2584 && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
2557# endif 2585# endif
2558 )) 2586 ))
2559 { 2587 {
@@ -2635,9 +2663,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
2635 2663
2636 /* POSIX specifies the default precision to be 6 for %f, %F, 2664 /* POSIX specifies the default precision to be 6 for %f, %F,
2637 %e, %E, but not for %g, %G. Implementations appear to use 2665 %e, %E, but not for %g, %G. Implementations appear to use
2638 the same default precision also for %g, %G. */ 2666 the same default precision also for %g, %G. But for %a, %A,
2667 the default precision is 0. */
2639 if (!has_precision) 2668 if (!has_precision)
2640 precision = 6; 2669 if (!(dp->conversion == 'a' || dp->conversion == 'A'))
2670 precision = 6;
2641 2671
2642 /* Allocate a temporary buffer of sufficient size. */ 2672 /* Allocate a temporary buffer of sufficient size. */
2643# if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE 2673# if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
@@ -2858,8 +2888,32 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
2858 exponent += 1; 2888 exponent += 1;
2859 adjusted = 1; 2889 adjusted = 1;
2860 } 2890 }
2861
2862 /* Here ndigits = precision+1. */ 2891 /* Here ndigits = precision+1. */
2892 if (is_borderline (digits, precision))
2893 {
2894 /* Maybe the exponent guess was too high
2895 and a smaller exponent can be reached
2896 by turning a 10...0 into 9...9x. */
2897 char *digits2 =
2898 scale10_round_decimal_long_double (arg,
2899 (int)precision - exponent + 1);
2900 if (digits2 == NULL)
2901 {
2902 free (digits);
2903 END_LONG_DOUBLE_ROUNDING ();
2904 goto out_of_memory;
2905 }
2906 if (strlen (digits2) == precision + 1)
2907 {
2908 free (digits);
2909 digits = digits2;
2910 exponent -= 1;
2911 }
2912 else
2913 free (digits2);
2914 }
2915 /* Here ndigits = precision+1. */
2916
2863 *p++ = digits[--ndigits]; 2917 *p++ = digits[--ndigits];
2864 if ((flags & FLAG_ALT) || precision > 0) 2918 if ((flags & FLAG_ALT) || precision > 0)
2865 { 2919 {
@@ -2971,6 +3025,30 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
2971 adjusted = 1; 3025 adjusted = 1;
2972 } 3026 }
2973 /* Here ndigits = precision. */ 3027 /* Here ndigits = precision. */
3028 if (is_borderline (digits, precision - 1))
3029 {
3030 /* Maybe the exponent guess was too high
3031 and a smaller exponent can be reached
3032 by turning a 10...0 into 9...9x. */
3033 char *digits2 =
3034 scale10_round_decimal_long_double (arg,
3035 (int)(precision - 1) - exponent + 1);
3036 if (digits2 == NULL)
3037 {
3038 free (digits);
3039 END_LONG_DOUBLE_ROUNDING ();
3040 goto out_of_memory;
3041 }
3042 if (strlen (digits2) == precision)
3043 {
3044 free (digits);
3045 digits = digits2;
3046 exponent -= 1;
3047 }
3048 else
3049 free (digits2);
3050 }
3051 /* Here ndigits = precision. */
2974 3052
2975 /* Determine the number of trailing zeroes 3053 /* Determine the number of trailing zeroes
2976 that have to be dropped. */ 3054 that have to be dropped. */
@@ -3065,7 +3143,65 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
3065 abort (); 3143 abort ();
3066# else 3144# else
3067 /* arg is finite. */ 3145 /* arg is finite. */
3068 abort (); 3146 if (!(arg == 0.0L))
3147 abort ();
3148
3149 pad_ptr = p;
3150
3151 if (dp->conversion == 'f' || dp->conversion == 'F')
3152 {
3153 *p++ = '0';
3154 if ((flags & FLAG_ALT) || precision > 0)
3155 {
3156 *p++ = decimal_point_char ();
3157 for (; precision > 0; precision--)
3158 *p++ = '0';
3159 }
3160 }
3161 else if (dp->conversion == 'e' || dp->conversion == 'E')
3162 {
3163 *p++ = '0';
3164 if ((flags & FLAG_ALT) || precision > 0)
3165 {
3166 *p++ = decimal_point_char ();
3167 for (; precision > 0; precision--)
3168 *p++ = '0';
3169 }
3170 *p++ = dp->conversion; /* 'e' or 'E' */
3171 *p++ = '+';
3172 *p++ = '0';
3173 *p++ = '0';
3174 }
3175 else if (dp->conversion == 'g' || dp->conversion == 'G')
3176 {
3177 *p++ = '0';
3178 if (flags & FLAG_ALT)
3179 {
3180 size_t ndigits =
3181 (precision > 0 ? precision - 1 : 0);
3182 *p++ = decimal_point_char ();
3183 for (; ndigits > 0; --ndigits)
3184 *p++ = '0';
3185 }
3186 }
3187 else if (dp->conversion == 'a' || dp->conversion == 'A')
3188 {
3189 *p++ = '0';
3190 *p++ = dp->conversion - 'A' + 'X';
3191 pad_ptr = p;
3192 *p++ = '0';
3193 if ((flags & FLAG_ALT) || precision > 0)
3194 {
3195 *p++ = decimal_point_char ();
3196 for (; precision > 0; precision--)
3197 *p++ = '0';
3198 }
3199 *p++ = dp->conversion - 'A' + 'P';
3200 *p++ = '+';
3201 *p++ = '0';
3202 }
3203 else
3204 abort ();
3069# endif 3205# endif
3070 } 3206 }
3071 3207
@@ -3211,8 +3347,31 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
3211 exponent += 1; 3347 exponent += 1;
3212 adjusted = 1; 3348 adjusted = 1;
3213 } 3349 }
3214
3215 /* Here ndigits = precision+1. */ 3350 /* Here ndigits = precision+1. */
3351 if (is_borderline (digits, precision))
3352 {
3353 /* Maybe the exponent guess was too high
3354 and a smaller exponent can be reached
3355 by turning a 10...0 into 9...9x. */
3356 char *digits2 =
3357 scale10_round_decimal_double (arg,
3358 (int)precision - exponent + 1);
3359 if (digits2 == NULL)
3360 {
3361 free (digits);
3362 goto out_of_memory;
3363 }
3364 if (strlen (digits2) == precision + 1)
3365 {
3366 free (digits);
3367 digits = digits2;
3368 exponent -= 1;
3369 }
3370 else
3371 free (digits2);
3372 }
3373 /* Here ndigits = precision+1. */
3374
3216 *p++ = digits[--ndigits]; 3375 *p++ = digits[--ndigits];
3217 if ((flags & FLAG_ALT) || precision > 0) 3376 if ((flags & FLAG_ALT) || precision > 0)
3218 { 3377 {
@@ -3337,6 +3496,29 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
3337 adjusted = 1; 3496 adjusted = 1;
3338 } 3497 }
3339 /* Here ndigits = precision. */ 3498 /* Here ndigits = precision. */
3499 if (is_borderline (digits, precision - 1))
3500 {
3501 /* Maybe the exponent guess was too high
3502 and a smaller exponent can be reached
3503 by turning a 10...0 into 9...9x. */
3504 char *digits2 =
3505 scale10_round_decimal_double (arg,
3506 (int)(precision - 1) - exponent + 1);
3507 if (digits2 == NULL)
3508 {
3509 free (digits);
3510 goto out_of_memory;
3511 }
3512 if (strlen (digits2) == precision)
3513 {
3514 free (digits);
3515 digits = digits2;
3516 exponent -= 1;
3517 }
3518 else
3519 free (digits2);
3520 }
3521 /* Here ndigits = precision. */
3340 3522
3341 /* Determine the number of trailing zeroes 3523 /* Determine the number of trailing zeroes
3342 that have to be dropped. */ 3524 that have to be dropped. */
@@ -3588,7 +3770,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
3588#endif 3770#endif
3589 TCHAR_T *fbp; 3771 TCHAR_T *fbp;
3590 unsigned int prefix_count; 3772 unsigned int prefix_count;
3591 int prefixes[2]; 3773 int prefixes[2] IF_LINT (= { 0 });
3592#if !USE_SNPRINTF 3774#if !USE_SNPRINTF
3593 size_t tmp_length; 3775 size_t tmp_length;
3594 TCHAR_T tmpbuf[700]; 3776 TCHAR_T tmpbuf[700];
@@ -3661,6 +3843,44 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
3661 } 3843 }
3662#endif 3844#endif
3663 3845
3846 /* Decide whether to handle the precision ourselves. */
3847#if NEED_PRINTF_UNBOUNDED_PRECISION
3848 switch (dp->conversion)
3849 {
3850 case 'd': case 'i': case 'u':
3851 case 'o':
3852 case 'x': case 'X': case 'p':
3853 prec_ourselves = has_precision && (precision > 0);
3854 break;
3855 default:
3856 prec_ourselves = 0;
3857 break;
3858 }
3859#endif
3860
3861 /* Decide whether to perform the padding ourselves. */
3862#if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
3863 switch (dp->conversion)
3864 {
3865# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
3866 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
3867 to perform the padding after this conversion. Functions
3868 with unistdio extensions perform the padding based on
3869 character count rather than element count. */
3870 case 'c': case 's':
3871# endif
3872# if NEED_PRINTF_FLAG_ZERO
3873 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
3874 case 'a': case 'A':
3875# endif
3876 pad_ourselves = 1;
3877 break;
3878 default:
3879 pad_ourselves = prec_ourselves;
3880 break;
3881 }
3882#endif
3883
3664#if !USE_SNPRINTF 3884#if !USE_SNPRINTF
3665 /* Allocate a temporary buffer of sufficient size for calling 3885 /* Allocate a temporary buffer of sufficient size for calling
3666 sprintf. */ 3886 sprintf. */
@@ -3837,18 +4057,22 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
3837 abort (); 4057 abort ();
3838 } 4058 }
3839 4059
4060 if (!pad_ourselves)
4061 {
3840# if ENABLE_UNISTDIO 4062# if ENABLE_UNISTDIO
3841 /* Padding considers the number of characters, therefore the 4063 /* Padding considers the number of characters, therefore
3842 number of elements after padding may be 4064 the number of elements after padding may be
3843 > max (tmp_length, width) 4065 > max (tmp_length, width)
3844 but is certainly 4066 but is certainly
3845 <= tmp_length + width. */ 4067 <= tmp_length + width. */
3846 tmp_length = xsum (tmp_length, width); 4068 tmp_length = xsum (tmp_length, width);
3847# else 4069# else
3848 /* Padding considers the number of elements, says POSIX. */ 4070 /* Padding considers the number of elements,
3849 if (tmp_length < width) 4071 says POSIX. */
3850 tmp_length = width; 4072 if (tmp_length < width)
4073 tmp_length = width;
3851# endif 4074# endif
4075 }
3852 4076
3853 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ 4077 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3854 } 4078 }
@@ -3869,44 +4093,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
3869 } 4093 }
3870#endif 4094#endif
3871 4095
3872 /* Decide whether to handle the precision ourselves. */
3873#if NEED_PRINTF_UNBOUNDED_PRECISION
3874 switch (dp->conversion)
3875 {
3876 case 'd': case 'i': case 'u':
3877 case 'o':
3878 case 'x': case 'X': case 'p':
3879 prec_ourselves = has_precision && (precision > 0);
3880 break;
3881 default:
3882 prec_ourselves = 0;
3883 break;
3884 }
3885#endif
3886
3887 /* Decide whether to perform the padding ourselves. */
3888#if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
3889 switch (dp->conversion)
3890 {
3891# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
3892 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
3893 to perform the padding after this conversion. Functions
3894 with unistdio extensions perform the padding based on
3895 character count rather than element count. */
3896 case 'c': case 's':
3897# endif
3898# if NEED_PRINTF_FLAG_ZERO
3899 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
3900 case 'a': case 'A':
3901# endif
3902 pad_ourselves = 1;
3903 break;
3904 default:
3905 pad_ourselves = prec_ourselves;
3906 break;
3907 }
3908#endif
3909
3910 /* Construct the format string for calling snprintf or 4096 /* Construct the format string for calling snprintf or
3911 sprintf. */ 4097 sprintf. */
3912 fbp = buf; 4098 fbp = buf;
@@ -4052,7 +4238,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
4052 abort (); 4238 abort ();
4053 prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int; 4239 prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
4054 } 4240 }
4055 if (dp->precision_arg_index != ARG_NONE) 4241 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
4056 { 4242 {
4057 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) 4243 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4058 abort (); 4244 abort ();
@@ -4403,14 +4589,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
4403 } 4589 }
4404#endif 4590#endif
4405 4591
4406#if !DCHAR_IS_TCHAR 4592#if !USE_SNPRINTF
4407# if !USE_SNPRINTF
4408 if (count >= tmp_length) 4593 if (count >= tmp_length)
4409 /* tmp_length was incorrectly calculated - fix the 4594 /* tmp_length was incorrectly calculated - fix the
4410 code above! */ 4595 code above! */
4411 abort (); 4596 abort ();
4412# endif 4597#endif
4413 4598
4599#if !DCHAR_IS_TCHAR
4414 /* Convert from TCHAR_T[] to DCHAR_T[]. */ 4600 /* Convert from TCHAR_T[] to DCHAR_T[]. */
4415 if (dp->conversion == 'c' || dp->conversion == 's') 4601 if (dp->conversion == 'c' || dp->conversion == 's')
4416 { 4602 {
@@ -4528,7 +4714,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
4528 if (w < width) 4714 if (w < width)
4529 { 4715 {
4530 size_t pad = width - w; 4716 size_t pad = width - w;
4531# if USE_SNPRINTF 4717
4532 /* Make room for the result. */ 4718 /* Make room for the result. */
4533 if (xsum (count, pad) > allocated - length) 4719 if (xsum (count, pad) > allocated - length)
4534 { 4720 {
@@ -4538,12 +4724,16 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
4538 xmax (xsum3 (length, count, pad), 4724 xmax (xsum3 (length, count, pad),
4539 xtimes (allocated, 2)); 4725 xtimes (allocated, 2));
4540 4726
4727# if USE_SNPRINTF
4541 length += count; 4728 length += count;
4542 ENSURE_ALLOCATION (n); 4729 ENSURE_ALLOCATION (n);
4543 length -= count; 4730 length -= count;
4731# else
4732 ENSURE_ALLOCATION (n);
4733# endif
4544 } 4734 }
4545 /* Here count + pad <= allocated - length. */ 4735 /* Here count + pad <= allocated - length. */
4546# endif 4736
4547 { 4737 {
4548# if !DCHAR_IS_TCHAR || USE_SNPRINTF 4738# if !DCHAR_IS_TCHAR || USE_SNPRINTF
4549 DCHAR_T * const rp = result + length; 4739 DCHAR_T * const rp = result + length;
@@ -4553,7 +4743,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
4553 DCHAR_T *p = rp + count; 4743 DCHAR_T *p = rp + count;
4554 DCHAR_T *end = p + pad; 4744 DCHAR_T *end = p + pad;
4555 DCHAR_T *pad_ptr; 4745 DCHAR_T *pad_ptr;
4556# if !DCHAR_IS_TCHAR 4746# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4557 if (dp->conversion == 'c' 4747 if (dp->conversion == 'c'
4558 || dp->conversion == 's') 4748 || dp->conversion == 's')
4559 /* No zero-padding for string directives. */ 4749 /* No zero-padding for string directives. */
@@ -4604,13 +4794,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
4604 } 4794 }
4605#endif 4795#endif
4606 4796
4607#if DCHAR_IS_TCHAR && !USE_SNPRINTF
4608 if (count >= tmp_length)
4609 /* tmp_length was incorrectly calculated - fix the
4610 code above! */
4611 abort ();
4612#endif
4613
4614 /* Here still count <= allocated - length. */ 4797 /* Here still count <= allocated - length. */
4615 4798
4616#if !DCHAR_IS_TCHAR || USE_SNPRINTF 4799#if !DCHAR_IS_TCHAR || USE_SNPRINTF