Add some more cases to the app-id unit tests
[glib.git] / glib / gnulib / vasnprintf.c
blob9933d163ced3344814bcbec3d89abdd106d22471
1 /* vsprintf with automatic memory allocation.
2 Copyright (C) 1999, 2002-2015 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, see <http://www.gnu.org/licenses/>. */
17 /* This file can be parametrized with the following macros:
18 VASNPRINTF The name of the function being defined.
19 FCHAR_T The element type of the format string.
20 DCHAR_T The element type of the destination (result) string.
21 FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
22 in the format string are ASCII. MUST be set if
23 FCHAR_T and DCHAR_T are not the same type.
24 DIRECTIVE Structure denoting a format directive.
25 Depends on FCHAR_T.
26 DIRECTIVES Structure denoting the set of format directives of a
27 format string. Depends on FCHAR_T.
28 PRINTF_PARSE Function that parses a format string.
29 Depends on FCHAR_T.
30 DCHAR_CPY memcpy like function for DCHAR_T[] arrays.
31 DCHAR_SET memset like function for DCHAR_T[] arrays.
32 DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays.
33 SNPRINTF The system's snprintf (or similar) function.
34 This may be either snprintf or swprintf.
35 TCHAR_T The element type of the argument and result string
36 of the said SNPRINTF function. This may be either
37 char or wchar_t. The code exploits that
38 sizeof (TCHAR_T) | sizeof (DCHAR_T) and
39 alignof (TCHAR_T) <= alignof (DCHAR_T).
40 DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type.
41 DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
42 DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t.
43 DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t.
44 DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */
46 #ifndef _WIN32
47 /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
48 This must come before <config.h> because <config.h> may include
49 <features.h>, and once <features.h> has been included, it's too late. */
50 #ifndef _GNU_SOURCE
51 # define _GNU_SOURCE 1
52 #endif
53 #endif
55 #ifndef VASNPRINTF
56 # include <config.h>
57 #endif
58 #include "glib/galloca.h"
60 #include "g-gnulib.h"
62 /* Specification. */
63 #include "vasnprintf.h"
65 #include <locale.h> /* localeconv() */
66 #include <stdio.h> /* snprintf(), sprintf() */
67 #include <stdlib.h> /* abort(), malloc(), realloc(), free() */
68 #include <string.h> /* memcpy(), strlen() */
69 #include <errno.h> /* errno */
70 #include <limits.h> /* CHAR_BIT */
71 #include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
72 # include "printf-parse.h"
74 #include "xsize.h"
76 #include "verify.h"
78 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
79 # include <math.h>
80 # include "float+.h"
81 #endif
83 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
84 # include <math.h>
85 # include "isnand-nolibm.h"
86 #endif
88 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
89 # include <math.h>
90 # include "isnanl-nolibm.h"
91 # include "fpucw.h"
92 #endif
94 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
95 # include <math.h>
96 # include "isnand-nolibm.h"
97 # include "printf-frexp.h"
98 #endif
100 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
101 # include <math.h>
102 # include "isnanl-nolibm.h"
103 # include "printf-frexpl.h"
104 # include "fpucw.h"
105 #endif
107 /* Default parameters. */
108 #ifndef VASNPRINTF
109 # if WIDE_CHAR_VERSION
110 # define VASNPRINTF vasnwprintf
111 # define FCHAR_T wchar_t
112 # define DCHAR_T wchar_t
113 # define TCHAR_T wchar_t
114 # define DCHAR_IS_TCHAR 1
115 # define DIRECTIVE wchar_t_directive
116 # define DIRECTIVES wchar_t_directives
117 # define PRINTF_PARSE wprintf_parse
118 # define DCHAR_CPY wmemcpy
119 # define DCHAR_SET wmemset
120 # else
121 # define VASNPRINTF vasnprintf
122 # define FCHAR_T char
123 # define DCHAR_T char
124 # define TCHAR_T char
125 # define DCHAR_IS_TCHAR 1
126 # define DIRECTIVE char_directive
127 # define DIRECTIVES char_directives
128 # define PRINTF_PARSE printf_parse
129 # define DCHAR_CPY memcpy
130 # define DCHAR_SET memset
131 # endif
132 #endif
133 #if WIDE_CHAR_VERSION
134 /* TCHAR_T is wchar_t. */
135 # define USE_SNPRINTF 1
136 # if HAVE_DECL__SNWPRINTF
137 /* On Windows, the function swprintf() has a different signature than
138 on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
139 instead. The mingw function snwprintf() has fewer bugs than the
140 MSVCRT function _snwprintf(), so prefer that. */
141 # if defined __MINGW32__
142 # define SNPRINTF snwprintf
143 # else
144 # define SNPRINTF _snwprintf
145 # endif
146 # else
147 /* Unix. */
148 # define SNPRINTF swprintf
149 # endif
150 #else
151 /* TCHAR_T is char. */
152 /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
153 But don't use it on BeOS, since BeOS snprintf produces no output if the
154 size argument is >= 0x3000000.
155 Also don't use it on Linux libc5, since there snprintf with size = 1
156 writes any output without bounds, like sprintf. */
157 # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
158 # define USE_SNPRINTF 1
159 # else
160 # define USE_SNPRINTF 0
161 # endif
162 # if HAVE_DECL__SNPRINTF
163 /* Windows. The mingw function snprintf() has fewer bugs than the MSVCRT
164 function _snprintf(), so prefer that. */
165 # if defined __MINGW32__
166 # define SNPRINTF snprintf
167 /* Here we need to call the native snprintf, not rpl_snprintf. */
168 # undef snprintf
169 # else
170 # define SNPRINTF _snprintf
171 # endif
172 # else
173 /* Unix. */
174 # define SNPRINTF snprintf
175 /* Here we need to call the native snprintf, not rpl_snprintf. */
176 # undef snprintf
177 # endif
178 #endif
179 /* Here we need to call the native sprintf, not rpl_sprintf. */
180 #undef sprintf
182 /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
183 warnings in this file. Use -Dlint to suppress them. */
184 #ifdef lint
185 # define IF_LINT(Code) Code
186 #else
187 # define IF_LINT(Code) /* empty */
188 #endif
190 /* Avoid some warnings from "gcc -Wshadow".
191 This file doesn't use the exp() and remainder() functions. */
192 #undef exp
193 #define exp expo
194 #undef remainder
195 #define remainder rem
197 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION
198 # if (HAVE_STRNLEN && !defined _AIX)
199 # define local_strnlen strnlen
200 # else
201 # ifndef local_strnlen_defined
202 # define local_strnlen_defined 1
203 static size_t
204 local_strnlen (const char *string, size_t maxlen)
206 const char *end = memchr (string, '\0', maxlen);
207 return end ? (size_t) (end - string) : maxlen;
209 # endif
210 # endif
211 #endif
213 #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
214 # if HAVE_WCSLEN
215 # define local_wcslen wcslen
216 # else
217 /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
218 a dependency towards this library, here is a local substitute.
219 Define this substitute only once, even if this file is included
220 twice in the same compilation unit. */
221 # ifndef local_wcslen_defined
222 # define local_wcslen_defined 1
223 static size_t
224 local_wcslen (const wchar_t *s)
226 const wchar_t *ptr;
228 for (ptr = s; *ptr != (wchar_t) 0; ptr++)
230 return ptr - s;
232 # endif
233 # endif
234 #endif
236 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
237 # if HAVE_WCSNLEN
238 # define local_wcsnlen wcsnlen
239 # else
240 # ifndef local_wcsnlen_defined
241 # define local_wcsnlen_defined 1
242 static size_t
243 local_wcsnlen (const wchar_t *s, size_t maxlen)
245 const wchar_t *ptr;
247 for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
249 return ptr - s;
251 # endif
252 # endif
253 #endif
255 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
256 /* Determine the decimal-point character according to the current locale. */
257 # ifndef decimal_point_char_defined
258 # define decimal_point_char_defined 1
259 static char
260 decimal_point_char (void)
262 const char *point;
263 /* Determine it in a multithread-safe way. We know nl_langinfo is
264 multithread-safe on glibc systems and Mac OS X systems, but is not required
265 to be multithread-safe by POSIX. sprintf(), however, is multithread-safe.
266 localeconv() is rarely multithread-safe. */
267 # if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__))
268 point = nl_langinfo (RADIXCHAR);
269 # elif 1
270 char pointbuf[5];
271 sprintf (pointbuf, "%#.0f", 1.0);
272 point = &pointbuf[1];
273 # else
274 point = localeconv () -> decimal_point;
275 # endif
276 /* The decimal point is always a single byte: either '.' or ','. */
277 return (point[0] != '\0' ? point[0] : '.');
279 # endif
280 #endif
282 #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
284 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
285 static int
286 is_infinite_or_zero (double x)
288 return isnand (x) || x + x == x;
291 #endif
293 #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
295 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
296 static int
297 is_infinite_or_zerol (long double x)
299 return isnanl (x) || x + x == x;
302 #endif
304 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
306 /* Converting 'long double' to decimal without rare rounding bugs requires
307 real bignums. We use the naming conventions of GNU gmp, but vastly simpler
308 (and slower) algorithms. */
310 typedef unsigned int mp_limb_t;
311 # define GMP_LIMB_BITS 32
312 verify (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS);
314 typedef unsigned long long mp_twolimb_t;
315 # define GMP_TWOLIMB_BITS 64
316 verify (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS);
318 /* Representation of a bignum >= 0. */
319 typedef struct
321 size_t nlimbs;
322 mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */
323 } mpn_t;
325 /* Compute the product of two bignums >= 0.
326 Return the allocated memory in case of success, NULL in case of memory
327 allocation failure. */
328 static void *
329 multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
331 const mp_limb_t *p1;
332 const mp_limb_t *p2;
333 size_t len1;
334 size_t len2;
336 if (src1.nlimbs <= src2.nlimbs)
338 len1 = src1.nlimbs;
339 p1 = src1.limbs;
340 len2 = src2.nlimbs;
341 p2 = src2.limbs;
343 else
345 len1 = src2.nlimbs;
346 p1 = src2.limbs;
347 len2 = src1.nlimbs;
348 p2 = src1.limbs;
350 /* Now 0 <= len1 <= len2. */
351 if (len1 == 0)
353 /* src1 or src2 is zero. */
354 dest->nlimbs = 0;
355 dest->limbs = (mp_limb_t *) malloc (1);
357 else
359 /* Here 1 <= len1 <= len2. */
360 size_t dlen;
361 mp_limb_t *dp;
362 size_t k, i, j;
364 dlen = len1 + len2;
365 dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
366 if (dp == NULL)
367 return NULL;
368 for (k = len2; k > 0; )
369 dp[--k] = 0;
370 for (i = 0; i < len1; i++)
372 mp_limb_t digit1 = p1[i];
373 mp_twolimb_t carry = 0;
374 for (j = 0; j < len2; j++)
376 mp_limb_t digit2 = p2[j];
377 carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
378 carry += dp[i + j];
379 dp[i + j] = (mp_limb_t) carry;
380 carry = carry >> GMP_LIMB_BITS;
382 dp[i + len2] = (mp_limb_t) carry;
384 /* Normalise. */
385 while (dlen > 0 && dp[dlen - 1] == 0)
386 dlen--;
387 dest->nlimbs = dlen;
388 dest->limbs = dp;
390 return dest->limbs;
393 /* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
394 a is written as a = q * b + r with 0 <= r < b. q is the quotient, r
395 the remainder.
396 Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
397 q is incremented.
398 Return the allocated memory in case of success, NULL in case of memory
399 allocation failure. */
400 static void *
401 divide (mpn_t a, mpn_t b, mpn_t *q)
403 /* Algorithm:
404 First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
405 with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
406 If m<n, then q:=0 and r:=a.
407 If m>=n=1, perform a single-precision division:
408 r:=0, j:=m,
409 while j>0 do
410 {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
411 = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
412 j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
413 Normalise [q[m-1],...,q[0]], yields q.
414 If m>=n>1, perform a multiple-precision division:
415 We have a/b < beta^(m-n+1).
416 s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
417 Shift a and b left by s bits, copying them. r:=a.
418 r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
419 For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
420 Compute q* :
421 q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
422 In case of overflow (q* >= beta) set q* := beta-1.
423 Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
424 and c3 := b[n-2] * q*.
425 {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
426 occurred. Furthermore 0 <= c3 < beta^2.
427 If there was overflow and
428 r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
429 the next test can be skipped.}
430 While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
431 Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
432 If q* > 0:
433 Put r := r - b * q* * beta^j. In detail:
434 [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
435 hence: u:=0, for i:=0 to n-1 do
436 u := u + q* * b[i],
437 r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
438 u:=u div beta (+ 1, if carry in subtraction)
439 r[n+j]:=r[n+j]-u.
440 {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
441 < q* + 1 <= beta,
442 the carry u does not overflow.}
443 If a negative carry occurs, put q* := q* - 1
444 and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
445 Set q[j] := q*.
446 Normalise [q[m-n],..,q[0]]; this yields the quotient q.
447 Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
448 rest r.
449 The room for q[j] can be allocated at the memory location of r[n+j].
450 Finally, round-to-even:
451 Shift r left by 1 bit.
452 If r > b or if r = b and q[0] is odd, q := q+1.
454 const mp_limb_t *a_ptr = a.limbs;
455 size_t a_len = a.nlimbs;
456 const mp_limb_t *b_ptr = b.limbs;
457 size_t b_len = b.nlimbs;
458 mp_limb_t *roomptr;
459 mp_limb_t *tmp_roomptr = NULL;
460 mp_limb_t *q_ptr;
461 size_t q_len;
462 mp_limb_t *r_ptr;
463 size_t r_len;
465 /* Allocate room for a_len+2 digits.
466 (Need a_len+1 digits for the real division and 1 more digit for the
467 final rounding of q.) */
468 roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
469 if (roomptr == NULL)
470 return NULL;
472 /* Normalise a. */
473 while (a_len > 0 && a_ptr[a_len - 1] == 0)
474 a_len--;
476 /* Normalise b. */
477 for (;;)
479 if (b_len == 0)
480 /* Division by zero. */
481 abort ();
482 if (b_ptr[b_len - 1] == 0)
483 b_len--;
484 else
485 break;
488 /* Here m = a_len >= 0 and n = b_len > 0. */
490 if (a_len < b_len)
492 /* m<n: trivial case. q=0, r := copy of a. */
493 r_ptr = roomptr;
494 r_len = a_len;
495 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
496 q_ptr = roomptr + a_len;
497 q_len = 0;
499 else if (b_len == 1)
501 /* n=1: single precision division.
502 beta^(m-1) <= a < beta^m ==> beta^(m-2) <= a/b < beta^m */
503 r_ptr = roomptr;
504 q_ptr = roomptr + 1;
506 mp_limb_t den = b_ptr[0];
507 mp_limb_t remainder = 0;
508 const mp_limb_t *sourceptr = a_ptr + a_len;
509 mp_limb_t *destptr = q_ptr + a_len;
510 size_t count;
511 for (count = a_len; count > 0; count--)
513 mp_twolimb_t num =
514 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
515 *--destptr = num / den;
516 remainder = num % den;
518 /* Normalise and store r. */
519 if (remainder > 0)
521 r_ptr[0] = remainder;
522 r_len = 1;
524 else
525 r_len = 0;
526 /* Normalise q. */
527 q_len = a_len;
528 if (q_ptr[q_len - 1] == 0)
529 q_len--;
532 else
534 /* n>1: multiple precision division.
535 beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n ==>
536 beta^(m-n-1) <= a/b < beta^(m-n+1). */
537 /* Determine s. */
538 size_t s;
540 mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
541 /* Determine s = GMP_LIMB_BITS - integer_length (msd).
542 Code copied from gnulib's integer_length.c. */
543 # if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
544 s = __builtin_clz (msd);
545 # else
546 # if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
547 if (GMP_LIMB_BITS <= DBL_MANT_BIT)
549 /* Use 'double' operations.
550 Assumes an IEEE 754 'double' implementation. */
551 # define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
552 # define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1)
553 # define NWORDS \
554 ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
555 union { double value; unsigned int word[NWORDS]; } m;
557 /* Use a single integer to floating-point conversion. */
558 m.value = msd;
560 s = GMP_LIMB_BITS
561 - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK)
562 - DBL_EXP_BIAS);
564 else
565 # undef NWORDS
566 # endif
568 s = 31;
569 if (msd >= 0x10000)
571 msd = msd >> 16;
572 s -= 16;
574 if (msd >= 0x100)
576 msd = msd >> 8;
577 s -= 8;
579 if (msd >= 0x10)
581 msd = msd >> 4;
582 s -= 4;
584 if (msd >= 0x4)
586 msd = msd >> 2;
587 s -= 2;
589 if (msd >= 0x2)
591 msd = msd >> 1;
592 s -= 1;
595 # endif
597 /* 0 <= s < GMP_LIMB_BITS.
598 Copy b, shifting it left by s bits. */
599 if (s > 0)
601 tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
602 if (tmp_roomptr == NULL)
604 free (roomptr);
605 return NULL;
608 const mp_limb_t *sourceptr = b_ptr;
609 mp_limb_t *destptr = tmp_roomptr;
610 mp_twolimb_t accu = 0;
611 size_t count;
612 for (count = b_len; count > 0; count--)
614 accu += (mp_twolimb_t) *sourceptr++ << s;
615 *destptr++ = (mp_limb_t) accu;
616 accu = accu >> GMP_LIMB_BITS;
618 /* accu must be zero, since that was how s was determined. */
619 if (accu != 0)
620 abort ();
622 b_ptr = tmp_roomptr;
624 /* Copy a, shifting it left by s bits, yields r.
625 Memory layout:
626 At the beginning: r = roomptr[0..a_len],
627 at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len] */
628 r_ptr = roomptr;
629 if (s == 0)
631 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
632 r_ptr[a_len] = 0;
634 else
636 const mp_limb_t *sourceptr = a_ptr;
637 mp_limb_t *destptr = r_ptr;
638 mp_twolimb_t accu = 0;
639 size_t count;
640 for (count = a_len; count > 0; count--)
642 accu += (mp_twolimb_t) *sourceptr++ << s;
643 *destptr++ = (mp_limb_t) accu;
644 accu = accu >> GMP_LIMB_BITS;
646 *destptr++ = (mp_limb_t) accu;
648 q_ptr = roomptr + b_len;
649 q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
651 size_t j = a_len - b_len; /* m-n */
652 mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
653 mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
654 mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
655 ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
656 /* Division loop, traversed m-n+1 times.
657 j counts down, b is unchanged, beta/2 <= b[n-1] < beta. */
658 for (;;)
660 mp_limb_t q_star;
661 mp_limb_t c1;
662 if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
664 /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow. */
665 mp_twolimb_t num =
666 ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
667 | r_ptr[j + b_len - 1];
668 q_star = num / b_msd;
669 c1 = num % b_msd;
671 else
673 /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1]. */
674 q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
675 /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
676 <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
677 <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
678 {<= beta !}.
679 If yes, jump directly to the subtraction loop.
680 (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
681 <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
682 if (r_ptr[j + b_len] > b_msd
683 || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
684 /* r[j+n] >= b[n-1]+1 or
685 r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
686 carry. */
687 goto subtract;
689 /* q_star = q*,
690 c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta). */
692 mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
693 ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
694 mp_twolimb_t c3 = /* b[n-2] * q* */
695 (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
696 /* While c2 < c3, increase c2 and decrease c3.
697 Consider c3-c2. While it is > 0, decrease it by
698 b[n-1]*beta+b[n-2]. Because of b[n-1]*beta+b[n-2] >= beta^2/2
699 this can happen only twice. */
700 if (c3 > c2)
702 q_star = q_star - 1; /* q* := q* - 1 */
703 if (c3 - c2 > b_msdd)
704 q_star = q_star - 1; /* q* := q* - 1 */
707 if (q_star > 0)
708 subtract:
710 /* Subtract r := r - b * q* * beta^j. */
711 mp_limb_t cr;
713 const mp_limb_t *sourceptr = b_ptr;
714 mp_limb_t *destptr = r_ptr + j;
715 mp_twolimb_t carry = 0;
716 size_t count;
717 for (count = b_len; count > 0; count--)
719 /* Here 0 <= carry <= q*. */
720 carry =
721 carry
722 + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
723 + (mp_limb_t) ~(*destptr);
724 /* Here 0 <= carry <= beta*q* + beta-1. */
725 *destptr++ = ~(mp_limb_t) carry;
726 carry = carry >> GMP_LIMB_BITS; /* <= q* */
728 cr = (mp_limb_t) carry;
730 /* Subtract cr from r_ptr[j + b_len], then forget about
731 r_ptr[j + b_len]. */
732 if (cr > r_ptr[j + b_len])
734 /* Subtraction gave a carry. */
735 q_star = q_star - 1; /* q* := q* - 1 */
736 /* Add b back. */
738 const mp_limb_t *sourceptr = b_ptr;
739 mp_limb_t *destptr = r_ptr + j;
740 mp_limb_t carry = 0;
741 size_t count;
742 for (count = b_len; count > 0; count--)
744 mp_limb_t source1 = *sourceptr++;
745 mp_limb_t source2 = *destptr;
746 *destptr++ = source1 + source2 + carry;
747 carry =
748 (carry
749 ? source1 >= (mp_limb_t) ~source2
750 : source1 > (mp_limb_t) ~source2);
753 /* Forget about the carry and about r[j+n]. */
756 /* q* is determined. Store it as q[j]. */
757 q_ptr[j] = q_star;
758 if (j == 0)
759 break;
760 j--;
763 r_len = b_len;
764 /* Normalise q. */
765 if (q_ptr[q_len - 1] == 0)
766 q_len--;
767 # if 0 /* Not needed here, since we need r only to compare it with b/2, and
768 b is shifted left by s bits. */
769 /* Shift r right by s bits. */
770 if (s > 0)
772 mp_limb_t ptr = r_ptr + r_len;
773 mp_twolimb_t accu = 0;
774 size_t count;
775 for (count = r_len; count > 0; count--)
777 accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
778 accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
779 *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
782 # endif
783 /* Normalise r. */
784 while (r_len > 0 && r_ptr[r_len - 1] == 0)
785 r_len--;
787 /* Compare r << 1 with b. */
788 if (r_len > b_len)
789 goto increment_q;
791 size_t i;
792 for (i = b_len;;)
794 mp_limb_t r_i =
795 (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
796 | (i < r_len ? r_ptr[i] << 1 : 0);
797 mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
798 if (r_i > b_i)
799 goto increment_q;
800 if (r_i < b_i)
801 goto keep_q;
802 if (i == 0)
803 break;
804 i--;
807 if (q_len > 0 && ((q_ptr[0] & 1) != 0))
808 /* q is odd. */
809 increment_q:
811 size_t i;
812 for (i = 0; i < q_len; i++)
813 if (++(q_ptr[i]) != 0)
814 goto keep_q;
815 q_ptr[q_len++] = 1;
817 keep_q:
818 if (tmp_roomptr != NULL)
819 free (tmp_roomptr);
820 q->limbs = q_ptr;
821 q->nlimbs = q_len;
822 return roomptr;
825 /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
826 representation.
827 Destroys the contents of a.
828 Return the allocated memory - containing the decimal digits in low-to-high
829 order, terminated with a NUL character - in case of success, NULL in case
830 of memory allocation failure. */
831 static char *
832 convert_to_decimal (mpn_t a, size_t extra_zeroes)
834 mp_limb_t *a_ptr = a.limbs;
835 size_t a_len = a.nlimbs;
836 /* 0.03345 is slightly larger than log(2)/(9*log(10)). */
837 size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
838 char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes));
839 if (c_ptr != NULL)
841 char *d_ptr = c_ptr;
842 for (; extra_zeroes > 0; extra_zeroes--)
843 *d_ptr++ = '0';
844 while (a_len > 0)
846 /* Divide a by 10^9, in-place. */
847 mp_limb_t remainder = 0;
848 mp_limb_t *ptr = a_ptr + a_len;
849 size_t count;
850 for (count = a_len; count > 0; count--)
852 mp_twolimb_t num =
853 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
854 *ptr = num / 1000000000;
855 remainder = num % 1000000000;
857 /* Store the remainder as 9 decimal digits. */
858 for (count = 9; count > 0; count--)
860 *d_ptr++ = '0' + (remainder % 10);
861 remainder = remainder / 10;
863 /* Normalize a. */
864 if (a_ptr[a_len - 1] == 0)
865 a_len--;
867 /* Remove leading zeroes. */
868 while (d_ptr > c_ptr && d_ptr[-1] == '0')
869 d_ptr--;
870 /* But keep at least one zero. */
871 if (d_ptr == c_ptr)
872 *d_ptr++ = '0';
873 /* Terminate the string. */
874 *d_ptr = '\0';
876 return c_ptr;
879 # if NEED_PRINTF_LONG_DOUBLE
881 /* Assuming x is finite and >= 0:
882 write x as x = 2^e * m, where m is a bignum.
883 Return the allocated memory in case of success, NULL in case of memory
884 allocation failure. */
885 static void *
886 decode_long_double (long double x, int *ep, mpn_t *mp)
888 mpn_t m;
889 int exp;
890 long double y;
891 size_t i;
893 /* Allocate memory for result. */
894 m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
895 m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
896 if (m.limbs == NULL)
897 return NULL;
898 /* Split into exponential part and mantissa. */
899 y = frexpl (x, &exp);
900 if (!(y >= 0.0L && y < 1.0L))
901 abort ();
902 /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the
903 latter is an integer. */
904 /* Convert the mantissa (y * 2^LDBL_MANT_BIT) to a sequence of limbs.
905 I'm not sure whether it's safe to cast a 'long double' value between
906 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
907 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
908 doesn't matter). */
909 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
910 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
912 mp_limb_t hi, lo;
913 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
914 hi = (int) y;
915 y -= hi;
916 if (!(y >= 0.0L && y < 1.0L))
917 abort ();
918 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
919 lo = (int) y;
920 y -= lo;
921 if (!(y >= 0.0L && y < 1.0L))
922 abort ();
923 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
925 # else
927 mp_limb_t d;
928 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
929 d = (int) y;
930 y -= d;
931 if (!(y >= 0.0L && y < 1.0L))
932 abort ();
933 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
935 # endif
936 # endif
937 for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
939 mp_limb_t hi, lo;
940 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
941 hi = (int) y;
942 y -= hi;
943 if (!(y >= 0.0L && y < 1.0L))
944 abort ();
945 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
946 lo = (int) y;
947 y -= lo;
948 if (!(y >= 0.0L && y < 1.0L))
949 abort ();
950 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
952 # if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
953 precision. */
954 if (!(y == 0.0L))
955 abort ();
956 # endif
957 /* Normalise. */
958 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
959 m.nlimbs--;
960 *mp = m;
961 *ep = exp - LDBL_MANT_BIT;
962 return m.limbs;
965 # endif
967 # if NEED_PRINTF_DOUBLE
969 /* Assuming x is finite and >= 0:
970 write x as x = 2^e * m, where m is a bignum.
971 Return the allocated memory in case of success, NULL in case of memory
972 allocation failure. */
973 static void *
974 decode_double (double x, int *ep, mpn_t *mp)
976 mpn_t m;
977 int exp;
978 double y;
979 size_t i;
981 /* Allocate memory for result. */
982 m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
983 m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
984 if (m.limbs == NULL)
985 return NULL;
986 /* Split into exponential part and mantissa. */
987 y = frexp (x, &exp);
988 if (!(y >= 0.0 && y < 1.0))
989 abort ();
990 /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * 2^DBL_MANT_BIT), and the
991 latter is an integer. */
992 /* Convert the mantissa (y * 2^DBL_MANT_BIT) to a sequence of limbs.
993 I'm not sure whether it's safe to cast a 'double' value between
994 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
995 'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
996 doesn't matter). */
997 # if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
998 # if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
1000 mp_limb_t hi, lo;
1001 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
1002 hi = (int) y;
1003 y -= hi;
1004 if (!(y >= 0.0 && y < 1.0))
1005 abort ();
1006 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1007 lo = (int) y;
1008 y -= lo;
1009 if (!(y >= 0.0 && y < 1.0))
1010 abort ();
1011 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1013 # else
1015 mp_limb_t d;
1016 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
1017 d = (int) y;
1018 y -= d;
1019 if (!(y >= 0.0 && y < 1.0))
1020 abort ();
1021 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
1023 # endif
1024 # endif
1025 for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1027 mp_limb_t hi, lo;
1028 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1029 hi = (int) y;
1030 y -= hi;
1031 if (!(y >= 0.0 && y < 1.0))
1032 abort ();
1033 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1034 lo = (int) y;
1035 y -= lo;
1036 if (!(y >= 0.0 && y < 1.0))
1037 abort ();
1038 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1040 if (!(y == 0.0))
1041 abort ();
1042 /* Normalise. */
1043 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
1044 m.nlimbs--;
1045 *mp = m;
1046 *ep = exp - DBL_MANT_BIT;
1047 return m.limbs;
1050 # endif
1052 /* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
1053 Returns the decimal representation of round (x * 10^n).
1054 Return the allocated memory - containing the decimal digits in low-to-high
1055 order, terminated with a NUL character - in case of success, NULL in case
1056 of memory allocation failure. */
1057 static char *
1058 scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
1060 int s;
1061 size_t extra_zeroes;
1062 unsigned int abs_n;
1063 unsigned int abs_s;
1064 mp_limb_t *pow5_ptr;
1065 size_t pow5_len;
1066 unsigned int s_limbs;
1067 unsigned int s_bits;
1068 mpn_t pow5;
1069 mpn_t z;
1070 void *z_memory;
1071 char *digits;
1073 if (memory == NULL)
1074 return NULL;
1075 /* x = 2^e * m, hence
1076 y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
1077 = round (2^s * 5^n * m). */
1078 s = e + n;
1079 extra_zeroes = 0;
1080 /* Factor out a common power of 10 if possible. */
1081 if (s > 0 && n > 0)
1083 extra_zeroes = (s < n ? s : n);
1084 s -= extra_zeroes;
1085 n -= extra_zeroes;
1087 /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
1088 Before converting to decimal, we need to compute
1089 z = round (2^s * 5^n * m). */
1090 /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
1091 sign. 2.322 is slightly larger than log(5)/log(2). */
1092 abs_n = (n >= 0 ? n : -n);
1093 abs_s = (s >= 0 ? s : -s);
1094 pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
1095 + abs_s / GMP_LIMB_BITS + 1)
1096 * sizeof (mp_limb_t));
1097 if (pow5_ptr == NULL)
1099 free (memory);
1100 return NULL;
1102 /* Initialize with 1. */
1103 pow5_ptr[0] = 1;
1104 pow5_len = 1;
1105 /* Multiply with 5^|n|. */
1106 if (abs_n > 0)
1108 static mp_limb_t const small_pow5[13 + 1] =
1110 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
1111 48828125, 244140625, 1220703125
1113 unsigned int n13;
1114 for (n13 = 0; n13 <= abs_n; n13 += 13)
1116 mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
1117 size_t j;
1118 mp_twolimb_t carry = 0;
1119 for (j = 0; j < pow5_len; j++)
1121 mp_limb_t digit2 = pow5_ptr[j];
1122 carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
1123 pow5_ptr[j] = (mp_limb_t) carry;
1124 carry = carry >> GMP_LIMB_BITS;
1126 if (carry > 0)
1127 pow5_ptr[pow5_len++] = (mp_limb_t) carry;
1130 s_limbs = abs_s / GMP_LIMB_BITS;
1131 s_bits = abs_s % GMP_LIMB_BITS;
1132 if (n >= 0 ? s >= 0 : s <= 0)
1134 /* Multiply with 2^|s|. */
1135 if (s_bits > 0)
1137 mp_limb_t *ptr = pow5_ptr;
1138 mp_twolimb_t accu = 0;
1139 size_t count;
1140 for (count = pow5_len; count > 0; count--)
1142 accu += (mp_twolimb_t) *ptr << s_bits;
1143 *ptr++ = (mp_limb_t) accu;
1144 accu = accu >> GMP_LIMB_BITS;
1146 if (accu > 0)
1148 *ptr = (mp_limb_t) accu;
1149 pow5_len++;
1152 if (s_limbs > 0)
1154 size_t count;
1155 for (count = pow5_len; count > 0;)
1157 count--;
1158 pow5_ptr[s_limbs + count] = pow5_ptr[count];
1160 for (count = s_limbs; count > 0;)
1162 count--;
1163 pow5_ptr[count] = 0;
1165 pow5_len += s_limbs;
1167 pow5.limbs = pow5_ptr;
1168 pow5.nlimbs = pow5_len;
1169 if (n >= 0)
1171 /* Multiply m with pow5. No division needed. */
1172 z_memory = multiply (m, pow5, &z);
1174 else
1176 /* Divide m by pow5 and round. */
1177 z_memory = divide (m, pow5, &z);
1180 else
1182 pow5.limbs = pow5_ptr;
1183 pow5.nlimbs = pow5_len;
1184 if (n >= 0)
1186 /* n >= 0, s < 0.
1187 Multiply m with pow5, then divide by 2^|s|. */
1188 mpn_t numerator;
1189 mpn_t denominator;
1190 void *tmp_memory;
1191 tmp_memory = multiply (m, pow5, &numerator);
1192 if (tmp_memory == NULL)
1194 free (pow5_ptr);
1195 free (memory);
1196 return NULL;
1198 /* Construct 2^|s|. */
1200 mp_limb_t *ptr = pow5_ptr + pow5_len;
1201 size_t i;
1202 for (i = 0; i < s_limbs; i++)
1203 ptr[i] = 0;
1204 ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
1205 denominator.limbs = ptr;
1206 denominator.nlimbs = s_limbs + 1;
1208 z_memory = divide (numerator, denominator, &z);
1209 free (tmp_memory);
1211 else
1213 /* n < 0, s > 0.
1214 Multiply m with 2^s, then divide by pow5. */
1215 mpn_t numerator;
1216 mp_limb_t *num_ptr;
1217 num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
1218 * sizeof (mp_limb_t));
1219 if (num_ptr == NULL)
1221 free (pow5_ptr);
1222 free (memory);
1223 return NULL;
1226 mp_limb_t *destptr = num_ptr;
1228 size_t i;
1229 for (i = 0; i < s_limbs; i++)
1230 *destptr++ = 0;
1232 if (s_bits > 0)
1234 const mp_limb_t *sourceptr = m.limbs;
1235 mp_twolimb_t accu = 0;
1236 size_t count;
1237 for (count = m.nlimbs; count > 0; count--)
1239 accu += (mp_twolimb_t) *sourceptr++ << s_bits;
1240 *destptr++ = (mp_limb_t) accu;
1241 accu = accu >> GMP_LIMB_BITS;
1243 if (accu > 0)
1244 *destptr++ = (mp_limb_t) accu;
1246 else
1248 const mp_limb_t *sourceptr = m.limbs;
1249 size_t count;
1250 for (count = m.nlimbs; count > 0; count--)
1251 *destptr++ = *sourceptr++;
1253 numerator.limbs = num_ptr;
1254 numerator.nlimbs = destptr - num_ptr;
1256 z_memory = divide (numerator, pow5, &z);
1257 free (num_ptr);
1260 free (pow5_ptr);
1261 free (memory);
1263 /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */
1265 if (z_memory == NULL)
1266 return NULL;
1267 digits = convert_to_decimal (z, extra_zeroes);
1268 free (z_memory);
1269 return digits;
1272 # if NEED_PRINTF_LONG_DOUBLE
1274 /* Assuming x is finite and >= 0, and n is an integer:
1275 Returns the decimal representation of round (x * 10^n).
1276 Return the allocated memory - containing the decimal digits in low-to-high
1277 order, terminated with a NUL character - in case of success, NULL in case
1278 of memory allocation failure. */
1279 static char *
1280 scale10_round_decimal_long_double (long double x, int n)
1282 int e IF_LINT(= 0);
1283 mpn_t m;
1284 void *memory = decode_long_double (x, &e, &m);
1285 return scale10_round_decimal_decoded (e, m, memory, n);
1288 # endif
1290 # if NEED_PRINTF_DOUBLE
1292 /* Assuming x is finite and >= 0, and n is an integer:
1293 Returns the decimal representation of round (x * 10^n).
1294 Return the allocated memory - containing the decimal digits in low-to-high
1295 order, terminated with a NUL character - in case of success, NULL in case
1296 of memory allocation failure. */
1297 static char *
1298 scale10_round_decimal_double (double x, int n)
1300 int e IF_LINT(= 0);
1301 mpn_t m;
1302 void *memory = decode_double (x, &e, &m);
1303 return scale10_round_decimal_decoded (e, m, memory, n);
1306 # endif
1308 # if NEED_PRINTF_LONG_DOUBLE
1310 /* Assuming x is finite and > 0:
1311 Return an approximation for n with 10^n <= x < 10^(n+1).
1312 The approximation is usually the right n, but may be off by 1 sometimes. */
1313 static int
1314 floorlog10l (long double x)
1316 int exp;
1317 long double y;
1318 double z;
1319 double l;
1321 /* Split into exponential part and mantissa. */
1322 y = frexpl (x, &exp);
1323 if (!(y >= 0.0L && y < 1.0L))
1324 abort ();
1325 if (y == 0.0L)
1326 return INT_MIN;
1327 if (y < 0.5L)
1329 while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1331 y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1332 exp -= GMP_LIMB_BITS;
1334 if (y < (1.0L / (1 << 16)))
1336 y *= 1.0L * (1 << 16);
1337 exp -= 16;
1339 if (y < (1.0L / (1 << 8)))
1341 y *= 1.0L * (1 << 8);
1342 exp -= 8;
1344 if (y < (1.0L / (1 << 4)))
1346 y *= 1.0L * (1 << 4);
1347 exp -= 4;
1349 if (y < (1.0L / (1 << 2)))
1351 y *= 1.0L * (1 << 2);
1352 exp -= 2;
1354 if (y < (1.0L / (1 << 1)))
1356 y *= 1.0L * (1 << 1);
1357 exp -= 1;
1360 if (!(y >= 0.5L && y < 1.0L))
1361 abort ();
1362 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1363 l = exp;
1364 z = y;
1365 if (z < 0.70710678118654752444)
1367 z *= 1.4142135623730950488;
1368 l -= 0.5;
1370 if (z < 0.8408964152537145431)
1372 z *= 1.1892071150027210667;
1373 l -= 0.25;
1375 if (z < 0.91700404320467123175)
1377 z *= 1.0905077326652576592;
1378 l -= 0.125;
1380 if (z < 0.9576032806985736469)
1382 z *= 1.0442737824274138403;
1383 l -= 0.0625;
1385 /* Now 0.95 <= z <= 1.01. */
1386 z = 1 - z;
1387 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1388 Four terms are enough to get an approximation with error < 10^-7. */
1389 l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1390 /* Finally multiply with log(2)/log(10), yields an approximation for
1391 log10(x). */
1392 l *= 0.30102999566398119523;
1393 /* Round down to the next integer. */
1394 return (int) l + (l < 0 ? -1 : 0);
1397 # endif
1399 # if NEED_PRINTF_DOUBLE
1401 /* Assuming x is finite and > 0:
1402 Return an approximation for n with 10^n <= x < 10^(n+1).
1403 The approximation is usually the right n, but may be off by 1 sometimes. */
1404 static int
1405 floorlog10 (double x)
1407 int exp;
1408 double y;
1409 double z;
1410 double l;
1412 /* Split into exponential part and mantissa. */
1413 y = frexp (x, &exp);
1414 if (!(y >= 0.0 && y < 1.0))
1415 abort ();
1416 if (y == 0.0)
1417 return INT_MIN;
1418 if (y < 0.5)
1420 while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1422 y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1423 exp -= GMP_LIMB_BITS;
1425 if (y < (1.0 / (1 << 16)))
1427 y *= 1.0 * (1 << 16);
1428 exp -= 16;
1430 if (y < (1.0 / (1 << 8)))
1432 y *= 1.0 * (1 << 8);
1433 exp -= 8;
1435 if (y < (1.0 / (1 << 4)))
1437 y *= 1.0 * (1 << 4);
1438 exp -= 4;
1440 if (y < (1.0 / (1 << 2)))
1442 y *= 1.0 * (1 << 2);
1443 exp -= 2;
1445 if (y < (1.0 / (1 << 1)))
1447 y *= 1.0 * (1 << 1);
1448 exp -= 1;
1451 if (!(y >= 0.5 && y < 1.0))
1452 abort ();
1453 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1454 l = exp;
1455 z = y;
1456 if (z < 0.70710678118654752444)
1458 z *= 1.4142135623730950488;
1459 l -= 0.5;
1461 if (z < 0.8408964152537145431)
1463 z *= 1.1892071150027210667;
1464 l -= 0.25;
1466 if (z < 0.91700404320467123175)
1468 z *= 1.0905077326652576592;
1469 l -= 0.125;
1471 if (z < 0.9576032806985736469)
1473 z *= 1.0442737824274138403;
1474 l -= 0.0625;
1476 /* Now 0.95 <= z <= 1.01. */
1477 z = 1 - z;
1478 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1479 Four terms are enough to get an approximation with error < 10^-7. */
1480 l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1481 /* Finally multiply with log(2)/log(10), yields an approximation for
1482 log10(x). */
1483 l *= 0.30102999566398119523;
1484 /* Round down to the next integer. */
1485 return (int) l + (l < 0 ? -1 : 0);
1488 # endif
1490 /* Tests whether a string of digits consists of exactly PRECISION zeroes and
1491 a single '1' digit. */
1492 static int
1493 is_borderline (const char *digits, size_t precision)
1495 for (; precision > 0; precision--, digits++)
1496 if (*digits != '0')
1497 return 0;
1498 if (*digits != '1')
1499 return 0;
1500 digits++;
1501 return *digits == '\0';
1504 #endif
1506 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99
1508 /* Use a different function name, to make it possible that the 'wchar_t'
1509 parametrization and the 'char' parametrization get compiled in the same
1510 translation unit. */
1511 # if WIDE_CHAR_VERSION
1512 # define MAX_ROOM_NEEDED wmax_room_needed
1513 # else
1514 # define MAX_ROOM_NEEDED max_room_needed
1515 # endif
1517 /* Returns the number of TCHAR_T units needed as temporary space for the result
1518 of sprintf or SNPRINTF of a single conversion directive. */
1519 static size_t
1520 MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
1521 arg_type type, int flags, size_t width, int has_precision,
1522 size_t precision, int pad_ourselves)
1524 size_t tmp_length;
1526 switch (conversion)
1528 case 'd': case 'i': case 'u':
1529 # if HAVE_LONG_LONG
1530 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1531 tmp_length =
1532 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1533 * 0.30103 /* binary -> decimal */
1535 + 1; /* turn floor into ceil */
1536 else
1537 # endif
1538 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1539 tmp_length =
1540 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1541 * 0.30103 /* binary -> decimal */
1543 + 1; /* turn floor into ceil */
1544 else
1545 tmp_length =
1546 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1547 * 0.30103 /* binary -> decimal */
1549 + 1; /* turn floor into ceil */
1550 if (tmp_length < precision)
1551 tmp_length = precision;
1552 /* Multiply by 2, as an estimate for FLAG_GROUP. */
1553 tmp_length = xsum (tmp_length, tmp_length);
1554 /* Add 1, to account for a leading sign. */
1555 tmp_length = xsum (tmp_length, 1);
1556 break;
1558 case 'o':
1559 # if HAVE_LONG_LONG
1560 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1561 tmp_length =
1562 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1563 * 0.333334 /* binary -> octal */
1565 + 1; /* turn floor into ceil */
1566 else
1567 # endif
1568 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1569 tmp_length =
1570 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1571 * 0.333334 /* binary -> octal */
1573 + 1; /* turn floor into ceil */
1574 else
1575 tmp_length =
1576 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1577 * 0.333334 /* binary -> octal */
1579 + 1; /* turn floor into ceil */
1580 if (tmp_length < precision)
1581 tmp_length = precision;
1582 /* Add 1, to account for a leading sign. */
1583 tmp_length = xsum (tmp_length, 1);
1584 break;
1586 case 'x': case 'X':
1587 # if HAVE_LONG_LONG
1588 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1589 tmp_length =
1590 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1591 * 0.25 /* binary -> hexadecimal */
1593 + 1; /* turn floor into ceil */
1594 else
1595 # endif
1596 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1597 tmp_length =
1598 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1599 * 0.25 /* binary -> hexadecimal */
1601 + 1; /* turn floor into ceil */
1602 else
1603 tmp_length =
1604 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1605 * 0.25 /* binary -> hexadecimal */
1607 + 1; /* turn floor into ceil */
1608 if (tmp_length < precision)
1609 tmp_length = precision;
1610 /* Add 2, to account for a leading sign or alternate form. */
1611 tmp_length = xsum (tmp_length, 2);
1612 break;
1614 case 'f': case 'F':
1615 if (type == TYPE_LONGDOUBLE)
1616 tmp_length =
1617 (unsigned int) (LDBL_MAX_EXP
1618 * 0.30103 /* binary -> decimal */
1619 * 2 /* estimate for FLAG_GROUP */
1621 + 1 /* turn floor into ceil */
1622 + 10; /* sign, decimal point etc. */
1623 else
1624 tmp_length =
1625 (unsigned int) (DBL_MAX_EXP
1626 * 0.30103 /* binary -> decimal */
1627 * 2 /* estimate for FLAG_GROUP */
1629 + 1 /* turn floor into ceil */
1630 + 10; /* sign, decimal point etc. */
1631 tmp_length = xsum (tmp_length, precision);
1632 break;
1634 case 'e': case 'E': case 'g': case 'G':
1635 tmp_length =
1636 12; /* sign, decimal point, exponent etc. */
1637 tmp_length = xsum (tmp_length, precision);
1638 break;
1640 case 'a': case 'A':
1641 if (type == TYPE_LONGDOUBLE)
1642 tmp_length =
1643 (unsigned int) (LDBL_DIG
1644 * 0.831 /* decimal -> hexadecimal */
1646 + 1; /* turn floor into ceil */
1647 else
1648 tmp_length =
1649 (unsigned int) (DBL_DIG
1650 * 0.831 /* decimal -> hexadecimal */
1652 + 1; /* turn floor into ceil */
1653 if (tmp_length < precision)
1654 tmp_length = precision;
1655 /* Account for sign, decimal point etc. */
1656 tmp_length = xsum (tmp_length, 12);
1657 break;
1659 case 'c':
1660 # if HAVE_WINT_T && !WIDE_CHAR_VERSION
1661 if (type == TYPE_WIDE_CHAR)
1662 tmp_length = MB_CUR_MAX;
1663 else
1664 # endif
1665 tmp_length = 1;
1666 break;
1668 case 's':
1669 # if HAVE_WCHAR_T
1670 if (type == TYPE_WIDE_STRING)
1672 # if WIDE_CHAR_VERSION
1673 /* ISO C says about %ls in fwprintf:
1674 "If the precision is not specified or is greater than the size
1675 of the array, the array shall contain a null wide character."
1676 So if there is a precision, we must not use wcslen. */
1677 const wchar_t *arg = ap->arg[arg_index].a.a_wide_string;
1679 if (has_precision)
1680 tmp_length = local_wcsnlen (arg, precision);
1681 else
1682 tmp_length = local_wcslen (arg);
1683 # else
1684 /* ISO C says about %ls in fprintf:
1685 "If a precision is specified, no more than that many bytes are
1686 written (including shift sequences, if any), and the array
1687 shall contain a null wide character if, to equal the multibyte
1688 character sequence length given by the precision, the function
1689 would need to access a wide character one past the end of the
1690 array."
1691 So if there is a precision, we must not use wcslen. */
1692 /* This case has already been handled separately in VASNPRINTF. */
1693 abort ();
1694 # endif
1696 else
1697 # endif
1699 # if WIDE_CHAR_VERSION
1700 /* ISO C says about %s in fwprintf:
1701 "If the precision is not specified or is greater than the size
1702 of the converted array, the converted array shall contain a
1703 null wide character."
1704 So if there is a precision, we must not use strlen. */
1705 /* This case has already been handled separately in VASNPRINTF. */
1706 abort ();
1707 # else
1708 /* ISO C says about %s in fprintf:
1709 "If the precision is not specified or greater than the size of
1710 the array, the array shall contain a null character."
1711 So if there is a precision, we must not use strlen. */
1712 const char *arg = ap->arg[arg_index].a.a_string;
1714 if (has_precision)
1715 tmp_length = local_strnlen (arg, precision);
1716 else
1717 tmp_length = strlen (arg);
1718 # endif
1720 break;
1722 case 'p':
1723 tmp_length =
1724 (unsigned int) (sizeof (void *) * CHAR_BIT
1725 * 0.25 /* binary -> hexadecimal */
1727 + 1 /* turn floor into ceil */
1728 + 2; /* account for leading 0x */
1729 break;
1731 default:
1732 abort ();
1735 if (!pad_ourselves)
1737 # if ENABLE_UNISTDIO
1738 /* Padding considers the number of characters, therefore the number of
1739 elements after padding may be
1740 > max (tmp_length, width)
1741 but is certainly
1742 <= tmp_length + width. */
1743 tmp_length = xsum (tmp_length, width);
1744 # else
1745 /* Padding considers the number of elements, says POSIX. */
1746 if (tmp_length < width)
1747 tmp_length = width;
1748 # endif
1751 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
1753 return tmp_length;
1756 #endif
1758 DCHAR_T *
1759 VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
1760 const FCHAR_T *format, va_list args)
1762 DIRECTIVES d;
1763 arguments a;
1765 if (PRINTF_PARSE (format, &d, &a) < 0)
1766 /* errno is already set. */
1767 return NULL;
1769 #define CLEANUP() \
1770 if (d.dir != d.direct_alloc_dir) \
1771 free (d.dir); \
1772 if (a.arg != a.direct_alloc_arg) \
1773 free (a.arg);
1775 if (PRINTF_FETCHARGS (args, &a) < 0)
1777 CLEANUP ();
1778 errno = EINVAL;
1779 return NULL;
1783 size_t buf_neededlength;
1784 TCHAR_T *buf;
1785 TCHAR_T *buf_malloced;
1786 const FCHAR_T *cp;
1787 size_t i;
1788 DIRECTIVE *dp;
1789 /* Output string accumulator. */
1790 DCHAR_T *result;
1791 size_t allocated;
1792 size_t length;
1794 /* Allocate a small buffer that will hold a directive passed to
1795 sprintf or snprintf. */
1796 buf_neededlength =
1797 xsum4 (7, d.max_width_length, d.max_precision_length, 6);
1798 #if HAVE_ALLOCA
1799 if (buf_neededlength < 4000 / sizeof (TCHAR_T))
1801 buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
1802 buf_malloced = NULL;
1804 else
1805 #endif
1807 size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
1808 if (size_overflow_p (buf_memsize))
1809 goto out_of_memory_1;
1810 buf = (TCHAR_T *) malloc (buf_memsize);
1811 if (buf == NULL)
1812 goto out_of_memory_1;
1813 buf_malloced = buf;
1816 if (resultbuf != NULL)
1818 result = resultbuf;
1819 allocated = *lengthp;
1821 else
1823 result = NULL;
1824 allocated = 0;
1826 length = 0;
1827 /* Invariants:
1828 result is either == resultbuf or == NULL or malloc-allocated.
1829 If length > 0, then result != NULL. */
1831 /* Ensures that allocated >= needed. Aborts through a jump to
1832 out_of_memory if needed is SIZE_MAX or otherwise too big. */
1833 #define ENSURE_ALLOCATION(needed) \
1834 if ((needed) > allocated) \
1836 size_t memory_size; \
1837 DCHAR_T *memory; \
1839 allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \
1840 if ((needed) > allocated) \
1841 allocated = (needed); \
1842 memory_size = xtimes (allocated, sizeof (DCHAR_T)); \
1843 if (size_overflow_p (memory_size)) \
1844 goto out_of_memory; \
1845 if (result == resultbuf || result == NULL) \
1846 memory = (DCHAR_T *) malloc (memory_size); \
1847 else \
1848 memory = (DCHAR_T *) realloc (result, memory_size); \
1849 if (memory == NULL) \
1850 goto out_of_memory; \
1851 if (result == resultbuf && length > 0) \
1852 DCHAR_CPY (memory, result, length); \
1853 result = memory; \
1856 for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
1858 if (cp != dp->dir_start)
1860 size_t n = dp->dir_start - cp;
1861 size_t augmented_length = xsum (length, n);
1863 ENSURE_ALLOCATION (augmented_length);
1864 /* This copies a piece of FCHAR_T[] into a DCHAR_T[]. Here we
1865 need that the format string contains only ASCII characters
1866 if FCHAR_T and DCHAR_T are not the same type. */
1867 if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
1869 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
1870 length = augmented_length;
1872 else
1875 result[length++] = *cp++;
1876 while (--n > 0);
1879 if (i == d.count)
1880 break;
1882 /* Execute a single directive. */
1883 if (dp->conversion == '%')
1885 size_t augmented_length;
1887 if (!(dp->arg_index == ARG_NONE))
1888 abort ();
1889 augmented_length = xsum (length, 1);
1890 ENSURE_ALLOCATION (augmented_length);
1891 result[length] = '%';
1892 length = augmented_length;
1894 else
1896 if (!(dp->arg_index != ARG_NONE))
1897 abort ();
1899 if (dp->conversion == 'n')
1901 switch (a.arg[dp->arg_index].type)
1903 case TYPE_COUNT_SCHAR_POINTER:
1904 *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
1905 break;
1906 case TYPE_COUNT_SHORT_POINTER:
1907 *a.arg[dp->arg_index].a.a_count_short_pointer = length;
1908 break;
1909 case TYPE_COUNT_INT_POINTER:
1910 *a.arg[dp->arg_index].a.a_count_int_pointer = length;
1911 break;
1912 case TYPE_COUNT_LONGINT_POINTER:
1913 *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
1914 break;
1915 #if HAVE_LONG_LONG
1916 case TYPE_COUNT_LONGLONGINT_POINTER:
1917 *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
1918 break;
1919 #endif
1920 default:
1921 abort ();
1924 #if ENABLE_UNISTDIO
1925 /* The unistdio extensions. */
1926 else if (dp->conversion == 'U')
1928 arg_type type = a.arg[dp->arg_index].type;
1929 int flags = dp->flags;
1930 int has_width;
1931 size_t width;
1932 int has_precision;
1933 size_t precision;
1935 has_width = 0;
1936 width = 0;
1937 if (dp->width_start != dp->width_end)
1939 if (dp->width_arg_index != ARG_NONE)
1941 int arg;
1943 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
1944 abort ();
1945 arg = a.arg[dp->width_arg_index].a.a_int;
1946 width = arg;
1947 if (arg < 0)
1949 /* "A negative field width is taken as a '-' flag
1950 followed by a positive field width." */
1951 flags |= FLAG_LEFT;
1952 width = -width;
1955 else
1957 const FCHAR_T *digitp = dp->width_start;
1960 width = xsum (xtimes (width, 10), *digitp++ - '0');
1961 while (digitp != dp->width_end);
1963 has_width = 1;
1966 has_precision = 0;
1967 precision = 0;
1968 if (dp->precision_start != dp->precision_end)
1970 if (dp->precision_arg_index != ARG_NONE)
1972 int arg;
1974 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1975 abort ();
1976 arg = a.arg[dp->precision_arg_index].a.a_int;
1977 /* "A negative precision is taken as if the precision
1978 were omitted." */
1979 if (arg >= 0)
1981 precision = arg;
1982 has_precision = 1;
1985 else
1987 const FCHAR_T *digitp = dp->precision_start + 1;
1989 precision = 0;
1990 while (digitp != dp->precision_end)
1991 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
1992 has_precision = 1;
1996 switch (type)
1998 case TYPE_U8_STRING:
2000 const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
2001 const uint8_t *arg_end;
2002 size_t characters;
2004 if (has_precision)
2006 /* Use only PRECISION characters, from the left. */
2007 arg_end = arg;
2008 characters = 0;
2009 for (; precision > 0; precision--)
2011 int count = u8_strmblen (arg_end);
2012 if (count == 0)
2013 break;
2014 if (count < 0)
2016 if (!(result == resultbuf || result == NULL))
2017 free (result);
2018 if (buf_malloced != NULL)
2019 free (buf_malloced);
2020 CLEANUP ();
2021 errno = EILSEQ;
2022 return NULL;
2024 arg_end += count;
2025 characters++;
2028 else if (has_width)
2030 /* Use the entire string, and count the number of
2031 characters. */
2032 arg_end = arg;
2033 characters = 0;
2034 for (;;)
2036 int count = u8_strmblen (arg_end);
2037 if (count == 0)
2038 break;
2039 if (count < 0)
2041 if (!(result == resultbuf || result == NULL))
2042 free (result);
2043 if (buf_malloced != NULL)
2044 free (buf_malloced);
2045 CLEANUP ();
2046 errno = EILSEQ;
2047 return NULL;
2049 arg_end += count;
2050 characters++;
2053 else
2055 /* Use the entire string. */
2056 arg_end = arg + u8_strlen (arg);
2057 /* The number of characters doesn't matter. */
2058 characters = 0;
2061 if (characters < width && !(dp->flags & FLAG_LEFT))
2063 size_t n = width - characters;
2064 ENSURE_ALLOCATION (xsum (length, n));
2065 DCHAR_SET (result + length, ' ', n);
2066 length += n;
2069 # if DCHAR_IS_UINT8_T
2071 size_t n = arg_end - arg;
2072 ENSURE_ALLOCATION (xsum (length, n));
2073 DCHAR_CPY (result + length, arg, n);
2074 length += n;
2076 # else
2077 { /* Convert. */
2078 DCHAR_T *converted = result + length;
2079 size_t converted_len = allocated - length;
2080 # if DCHAR_IS_TCHAR
2081 /* Convert from UTF-8 to locale encoding. */
2082 converted =
2083 u8_conv_to_encoding (locale_charset (),
2084 iconveh_question_mark,
2085 arg, arg_end - arg, NULL,
2086 converted, &converted_len);
2087 # else
2088 /* Convert from UTF-8 to UTF-16/UTF-32. */
2089 converted =
2090 U8_TO_DCHAR (arg, arg_end - arg,
2091 converted, &converted_len);
2092 # endif
2093 if (converted == NULL)
2095 int saved_errno = errno;
2096 if (!(result == resultbuf || result == NULL))
2097 free (result);
2098 if (buf_malloced != NULL)
2099 free (buf_malloced);
2100 CLEANUP ();
2101 errno = saved_errno;
2102 return NULL;
2104 if (converted != result + length)
2106 ENSURE_ALLOCATION (xsum (length, converted_len));
2107 DCHAR_CPY (result + length, converted, converted_len);
2108 free (converted);
2110 length += converted_len;
2112 # endif
2114 if (characters < width && (dp->flags & FLAG_LEFT))
2116 size_t n = width - characters;
2117 ENSURE_ALLOCATION (xsum (length, n));
2118 DCHAR_SET (result + length, ' ', n);
2119 length += n;
2122 break;
2124 case TYPE_U16_STRING:
2126 const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
2127 const uint16_t *arg_end;
2128 size_t characters;
2130 if (has_precision)
2132 /* Use only PRECISION characters, from the left. */
2133 arg_end = arg;
2134 characters = 0;
2135 for (; precision > 0; precision--)
2137 int count = u16_strmblen (arg_end);
2138 if (count == 0)
2139 break;
2140 if (count < 0)
2142 if (!(result == resultbuf || result == NULL))
2143 free (result);
2144 if (buf_malloced != NULL)
2145 free (buf_malloced);
2146 CLEANUP ();
2147 errno = EILSEQ;
2148 return NULL;
2150 arg_end += count;
2151 characters++;
2154 else if (has_width)
2156 /* Use the entire string, and count the number of
2157 characters. */
2158 arg_end = arg;
2159 characters = 0;
2160 for (;;)
2162 int count = u16_strmblen (arg_end);
2163 if (count == 0)
2164 break;
2165 if (count < 0)
2167 if (!(result == resultbuf || result == NULL))
2168 free (result);
2169 if (buf_malloced != NULL)
2170 free (buf_malloced);
2171 CLEANUP ();
2172 errno = EILSEQ;
2173 return NULL;
2175 arg_end += count;
2176 characters++;
2179 else
2181 /* Use the entire string. */
2182 arg_end = arg + u16_strlen (arg);
2183 /* The number of characters doesn't matter. */
2184 characters = 0;
2187 if (characters < width && !(dp->flags & FLAG_LEFT))
2189 size_t n = width - characters;
2190 ENSURE_ALLOCATION (xsum (length, n));
2191 DCHAR_SET (result + length, ' ', n);
2192 length += n;
2195 # if DCHAR_IS_UINT16_T
2197 size_t n = arg_end - arg;
2198 ENSURE_ALLOCATION (xsum (length, n));
2199 DCHAR_CPY (result + length, arg, n);
2200 length += n;
2202 # else
2203 { /* Convert. */
2204 DCHAR_T *converted = result + length;
2205 size_t converted_len = allocated - length;
2206 # if DCHAR_IS_TCHAR
2207 /* Convert from UTF-16 to locale encoding. */
2208 converted =
2209 u16_conv_to_encoding (locale_charset (),
2210 iconveh_question_mark,
2211 arg, arg_end - arg, NULL,
2212 converted, &converted_len);
2213 # else
2214 /* Convert from UTF-16 to UTF-8/UTF-32. */
2215 converted =
2216 U16_TO_DCHAR (arg, arg_end - arg,
2217 converted, &converted_len);
2218 # endif
2219 if (converted == NULL)
2221 int saved_errno = errno;
2222 if (!(result == resultbuf || result == NULL))
2223 free (result);
2224 if (buf_malloced != NULL)
2225 free (buf_malloced);
2226 CLEANUP ();
2227 errno = saved_errno;
2228 return NULL;
2230 if (converted != result + length)
2232 ENSURE_ALLOCATION (xsum (length, converted_len));
2233 DCHAR_CPY (result + length, converted, converted_len);
2234 free (converted);
2236 length += converted_len;
2238 # endif
2240 if (characters < width && (dp->flags & FLAG_LEFT))
2242 size_t n = width - characters;
2243 ENSURE_ALLOCATION (xsum (length, n));
2244 DCHAR_SET (result + length, ' ', n);
2245 length += n;
2248 break;
2250 case TYPE_U32_STRING:
2252 const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
2253 const uint32_t *arg_end;
2254 size_t characters;
2256 if (has_precision)
2258 /* Use only PRECISION characters, from the left. */
2259 arg_end = arg;
2260 characters = 0;
2261 for (; precision > 0; precision--)
2263 int count = u32_strmblen (arg_end);
2264 if (count == 0)
2265 break;
2266 if (count < 0)
2268 if (!(result == resultbuf || result == NULL))
2269 free (result);
2270 if (buf_malloced != NULL)
2271 free (buf_malloced);
2272 CLEANUP ();
2273 errno = EILSEQ;
2274 return NULL;
2276 arg_end += count;
2277 characters++;
2280 else if (has_width)
2282 /* Use the entire string, and count the number of
2283 characters. */
2284 arg_end = arg;
2285 characters = 0;
2286 for (;;)
2288 int count = u32_strmblen (arg_end);
2289 if (count == 0)
2290 break;
2291 if (count < 0)
2293 if (!(result == resultbuf || result == NULL))
2294 free (result);
2295 if (buf_malloced != NULL)
2296 free (buf_malloced);
2297 CLEANUP ();
2298 errno = EILSEQ;
2299 return NULL;
2301 arg_end += count;
2302 characters++;
2305 else
2307 /* Use the entire string. */
2308 arg_end = arg + u32_strlen (arg);
2309 /* The number of characters doesn't matter. */
2310 characters = 0;
2313 if (characters < width && !(dp->flags & FLAG_LEFT))
2315 size_t n = width - characters;
2316 ENSURE_ALLOCATION (xsum (length, n));
2317 DCHAR_SET (result + length, ' ', n);
2318 length += n;
2321 # if DCHAR_IS_UINT32_T
2323 size_t n = arg_end - arg;
2324 ENSURE_ALLOCATION (xsum (length, n));
2325 DCHAR_CPY (result + length, arg, n);
2326 length += n;
2328 # else
2329 { /* Convert. */
2330 DCHAR_T *converted = result + length;
2331 size_t converted_len = allocated - length;
2332 # if DCHAR_IS_TCHAR
2333 /* Convert from UTF-32 to locale encoding. */
2334 converted =
2335 u32_conv_to_encoding (locale_charset (),
2336 iconveh_question_mark,
2337 arg, arg_end - arg, NULL,
2338 converted, &converted_len);
2339 # else
2340 /* Convert from UTF-32 to UTF-8/UTF-16. */
2341 converted =
2342 U32_TO_DCHAR (arg, arg_end - arg,
2343 converted, &converted_len);
2344 # endif
2345 if (converted == NULL)
2347 int saved_errno = errno;
2348 if (!(result == resultbuf || result == NULL))
2349 free (result);
2350 if (buf_malloced != NULL)
2351 free (buf_malloced);
2352 CLEANUP ();
2353 errno = saved_errno;
2354 return NULL;
2356 if (converted != result + length)
2358 ENSURE_ALLOCATION (xsum (length, converted_len));
2359 DCHAR_CPY (result + length, converted, converted_len);
2360 free (converted);
2362 length += converted_len;
2364 # endif
2366 if (characters < width && (dp->flags & FLAG_LEFT))
2368 size_t n = width - characters;
2369 ENSURE_ALLOCATION (xsum (length, n));
2370 DCHAR_SET (result + length, ' ', n);
2371 length += n;
2374 break;
2376 default:
2377 abort ();
2380 #endif
2381 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
2382 else if (dp->conversion == 's'
2383 # if WIDE_CHAR_VERSION
2384 && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
2385 # else
2386 && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
2387 # endif
2390 /* The normal handling of the 's' directive below requires
2391 allocating a temporary buffer. The determination of its
2392 length (tmp_length), in the case when a precision is
2393 specified, below requires a conversion between a char[]
2394 string and a wchar_t[] wide string. It could be done, but
2395 we have no guarantee that the implementation of sprintf will
2396 use the exactly same algorithm. Without this guarantee, it
2397 is possible to have buffer overrun bugs. In order to avoid
2398 such bugs, we implement the entire processing of the 's'
2399 directive ourselves. */
2400 int flags = dp->flags;
2401 int has_width;
2402 size_t width;
2403 int has_precision;
2404 size_t precision;
2406 has_width = 0;
2407 width = 0;
2408 if (dp->width_start != dp->width_end)
2410 if (dp->width_arg_index != ARG_NONE)
2412 int arg;
2414 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2415 abort ();
2416 arg = a.arg[dp->width_arg_index].a.a_int;
2417 width = arg;
2418 if (arg < 0)
2420 /* "A negative field width is taken as a '-' flag
2421 followed by a positive field width." */
2422 flags |= FLAG_LEFT;
2423 width = -width;
2426 else
2428 const FCHAR_T *digitp = dp->width_start;
2431 width = xsum (xtimes (width, 10), *digitp++ - '0');
2432 while (digitp != dp->width_end);
2434 has_width = 1;
2437 has_precision = 0;
2438 precision = 6;
2439 if (dp->precision_start != dp->precision_end)
2441 if (dp->precision_arg_index != ARG_NONE)
2443 int arg;
2445 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2446 abort ();
2447 arg = a.arg[dp->precision_arg_index].a.a_int;
2448 /* "A negative precision is taken as if the precision
2449 were omitted." */
2450 if (arg >= 0)
2452 precision = arg;
2453 has_precision = 1;
2456 else
2458 const FCHAR_T *digitp = dp->precision_start + 1;
2460 precision = 0;
2461 while (digitp != dp->precision_end)
2462 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2463 has_precision = 1;
2467 # if WIDE_CHAR_VERSION
2468 /* %s in vasnwprintf. See the specification of fwprintf. */
2470 const char *arg = a.arg[dp->arg_index].a.a_string;
2471 const char *arg_end;
2472 size_t characters;
2474 if (has_precision)
2476 /* Use only as many bytes as needed to produce PRECISION
2477 wide characters, from the left. */
2478 # if HAVE_MBRTOWC
2479 mbstate_t state;
2480 memset (&state, '\0', sizeof (mbstate_t));
2481 # endif
2482 arg_end = arg;
2483 characters = 0;
2484 for (; precision > 0; precision--)
2486 int count;
2487 # if HAVE_MBRTOWC
2488 count = mbrlen (arg_end, MB_CUR_MAX, &state);
2489 # else
2490 count = mblen (arg_end, MB_CUR_MAX);
2491 # endif
2492 if (count == 0)
2493 /* Found the terminating NUL. */
2494 break;
2495 if (count < 0)
2497 /* Invalid or incomplete multibyte character. */
2498 if (!(result == resultbuf || result == NULL))
2499 free (result);
2500 if (buf_malloced != NULL)
2501 free (buf_malloced);
2502 CLEANUP ();
2503 errno = EILSEQ;
2504 return NULL;
2506 arg_end += count;
2507 characters++;
2510 else if (has_width)
2512 /* Use the entire string, and count the number of wide
2513 characters. */
2514 # if HAVE_MBRTOWC
2515 mbstate_t state;
2516 memset (&state, '\0', sizeof (mbstate_t));
2517 # endif
2518 arg_end = arg;
2519 characters = 0;
2520 for (;;)
2522 int count;
2523 # if HAVE_MBRTOWC
2524 count = mbrlen (arg_end, MB_CUR_MAX, &state);
2525 # else
2526 count = mblen (arg_end, MB_CUR_MAX);
2527 # endif
2528 if (count == 0)
2529 /* Found the terminating NUL. */
2530 break;
2531 if (count < 0)
2533 /* Invalid or incomplete multibyte character. */
2534 if (!(result == resultbuf || result == NULL))
2535 free (result);
2536 if (buf_malloced != NULL)
2537 free (buf_malloced);
2538 CLEANUP ();
2539 errno = EILSEQ;
2540 return NULL;
2542 arg_end += count;
2543 characters++;
2546 else
2548 /* Use the entire string. */
2549 arg_end = arg + strlen (arg);
2550 /* The number of characters doesn't matter. */
2551 characters = 0;
2554 if (characters < width && !(dp->flags & FLAG_LEFT))
2556 size_t n = width - characters;
2557 ENSURE_ALLOCATION (xsum (length, n));
2558 DCHAR_SET (result + length, ' ', n);
2559 length += n;
2562 if (has_precision || has_width)
2564 /* We know the number of wide characters in advance. */
2565 size_t remaining;
2566 # if HAVE_MBRTOWC
2567 mbstate_t state;
2568 memset (&state, '\0', sizeof (mbstate_t));
2569 # endif
2570 ENSURE_ALLOCATION (xsum (length, characters));
2571 for (remaining = characters; remaining > 0; remaining--)
2573 wchar_t wc;
2574 int count;
2575 # if HAVE_MBRTOWC
2576 count = mbrtowc (&wc, arg, arg_end - arg, &state);
2577 # else
2578 count = mbtowc (&wc, arg, arg_end - arg);
2579 # endif
2580 if (count <= 0)
2581 /* mbrtowc not consistent with mbrlen, or mbtowc
2582 not consistent with mblen. */
2583 abort ();
2584 result[length++] = wc;
2585 arg += count;
2587 if (!(arg == arg_end))
2588 abort ();
2590 else
2592 # if HAVE_MBRTOWC
2593 mbstate_t state;
2594 memset (&state, '\0', sizeof (mbstate_t));
2595 # endif
2596 while (arg < arg_end)
2598 wchar_t wc;
2599 int count;
2600 # if HAVE_MBRTOWC
2601 count = mbrtowc (&wc, arg, arg_end - arg, &state);
2602 # else
2603 count = mbtowc (&wc, arg, arg_end - arg);
2604 # endif
2605 if (count <= 0)
2606 /* mbrtowc not consistent with mbrlen, or mbtowc
2607 not consistent with mblen. */
2608 abort ();
2609 ENSURE_ALLOCATION (xsum (length, 1));
2610 result[length++] = wc;
2611 arg += count;
2615 if (characters < width && (dp->flags & FLAG_LEFT))
2617 size_t n = width - characters;
2618 ENSURE_ALLOCATION (xsum (length, n));
2619 DCHAR_SET (result + length, ' ', n);
2620 length += n;
2623 # else
2624 /* %ls in vasnprintf. See the specification of fprintf. */
2626 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
2627 const wchar_t *arg_end;
2628 size_t characters;
2629 # if !DCHAR_IS_TCHAR
2630 /* This code assumes that TCHAR_T is 'char'. */
2631 verify (sizeof (TCHAR_T) == 1);
2632 TCHAR_T *tmpsrc;
2633 DCHAR_T *tmpdst;
2634 size_t tmpdst_len;
2635 # endif
2636 size_t w;
2638 if (has_precision)
2640 /* Use only as many wide characters as needed to produce
2641 at most PRECISION bytes, from the left. */
2642 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2643 mbstate_t state;
2644 memset (&state, '\0', sizeof (mbstate_t));
2645 # endif
2646 arg_end = arg;
2647 characters = 0;
2648 while (precision > 0)
2650 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2651 int count;
2653 if (*arg_end == 0)
2654 /* Found the terminating null wide character. */
2655 break;
2656 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2657 count = wcrtomb (cbuf, *arg_end, &state);
2658 # else
2659 count = wctomb (cbuf, *arg_end);
2660 # endif
2661 if (count < 0)
2663 /* Cannot convert. */
2664 if (!(result == resultbuf || result == NULL))
2665 free (result);
2666 if (buf_malloced != NULL)
2667 free (buf_malloced);
2668 CLEANUP ();
2669 errno = EILSEQ;
2670 return NULL;
2672 if (precision < count)
2673 break;
2674 arg_end++;
2675 characters += count;
2676 precision -= count;
2679 # if DCHAR_IS_TCHAR
2680 else if (has_width)
2681 # else
2682 else
2683 # endif
2685 /* Use the entire string, and count the number of
2686 bytes. */
2687 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2688 mbstate_t state;
2689 memset (&state, '\0', sizeof (mbstate_t));
2690 # endif
2691 arg_end = arg;
2692 characters = 0;
2693 for (;;)
2695 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2696 int count;
2698 if (*arg_end == 0)
2699 /* Found the terminating null wide character. */
2700 break;
2701 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2702 count = wcrtomb (cbuf, *arg_end, &state);
2703 # else
2704 count = wctomb (cbuf, *arg_end);
2705 # endif
2706 if (count < 0)
2708 /* Cannot convert. */
2709 if (!(result == resultbuf || result == NULL))
2710 free (result);
2711 if (buf_malloced != NULL)
2712 free (buf_malloced);
2713 CLEANUP ();
2714 errno = EILSEQ;
2715 return NULL;
2717 arg_end++;
2718 characters += count;
2721 # if DCHAR_IS_TCHAR
2722 else
2724 /* Use the entire string. */
2725 arg_end = arg + local_wcslen (arg);
2726 /* The number of bytes doesn't matter. */
2727 characters = 0;
2729 # endif
2731 # if !DCHAR_IS_TCHAR
2732 /* Convert the string into a piece of temporary memory. */
2733 tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
2734 if (tmpsrc == NULL)
2735 goto out_of_memory;
2737 TCHAR_T *tmpptr = tmpsrc;
2738 size_t remaining;
2739 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2740 mbstate_t state;
2741 memset (&state, '\0', sizeof (mbstate_t));
2742 # endif
2743 for (remaining = characters; remaining > 0; )
2745 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2746 int count;
2748 if (*arg == 0)
2749 abort ();
2750 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2751 count = wcrtomb (cbuf, *arg, &state);
2752 # else
2753 count = wctomb (cbuf, *arg);
2754 # endif
2755 if (count <= 0)
2756 /* Inconsistency. */
2757 abort ();
2758 memcpy (tmpptr, cbuf, count);
2759 tmpptr += count;
2760 arg++;
2761 remaining -= count;
2763 if (!(arg == arg_end))
2764 abort ();
2767 /* Convert from TCHAR_T[] to DCHAR_T[]. */
2768 tmpdst =
2769 DCHAR_CONV_FROM_ENCODING (locale_charset (),
2770 iconveh_question_mark,
2771 tmpsrc, characters,
2772 NULL,
2773 NULL, &tmpdst_len);
2774 if (tmpdst == NULL)
2776 int saved_errno = errno;
2777 free (tmpsrc);
2778 if (!(result == resultbuf || result == NULL))
2779 free (result);
2780 if (buf_malloced != NULL)
2781 free (buf_malloced);
2782 CLEANUP ();
2783 errno = saved_errno;
2784 return NULL;
2786 free (tmpsrc);
2787 # endif
2789 if (has_width)
2791 # if ENABLE_UNISTDIO
2792 /* Outside POSIX, it's preferable to compare the width
2793 against the number of _characters_ of the converted
2794 value. */
2795 w = DCHAR_MBSNLEN (result + length, characters);
2796 # else
2797 /* The width is compared against the number of _bytes_
2798 of the converted value, says POSIX. */
2799 w = characters;
2800 # endif
2802 else
2803 /* w doesn't matter. */
2804 w = 0;
2806 if (w < width && !(dp->flags & FLAG_LEFT))
2808 size_t n = width - w;
2809 ENSURE_ALLOCATION (xsum (length, n));
2810 DCHAR_SET (result + length, ' ', n);
2811 length += n;
2814 # if DCHAR_IS_TCHAR
2815 if (has_precision || has_width)
2817 /* We know the number of bytes in advance. */
2818 size_t remaining;
2819 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2820 mbstate_t state;
2821 memset (&state, '\0', sizeof (mbstate_t));
2822 # endif
2823 ENSURE_ALLOCATION (xsum (length, characters));
2824 for (remaining = characters; remaining > 0; )
2826 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2827 int count;
2829 if (*arg == 0)
2830 abort ();
2831 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2832 count = wcrtomb (cbuf, *arg, &state);
2833 # else
2834 count = wctomb (cbuf, *arg);
2835 # endif
2836 if (count <= 0)
2837 /* Inconsistency. */
2838 abort ();
2839 memcpy (result + length, cbuf, count);
2840 length += count;
2841 arg++;
2842 remaining -= count;
2844 if (!(arg == arg_end))
2845 abort ();
2847 else
2849 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2850 mbstate_t state;
2851 memset (&state, '\0', sizeof (mbstate_t));
2852 # endif
2853 while (arg < arg_end)
2855 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2856 int count;
2858 if (*arg == 0)
2859 abort ();
2860 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2861 count = wcrtomb (cbuf, *arg, &state);
2862 # else
2863 count = wctomb (cbuf, *arg);
2864 # endif
2865 if (count <= 0)
2867 /* Cannot convert. */
2868 if (!(result == resultbuf || result == NULL))
2869 free (result);
2870 if (buf_malloced != NULL)
2871 free (buf_malloced);
2872 CLEANUP ();
2873 errno = EILSEQ;
2874 return NULL;
2876 ENSURE_ALLOCATION (xsum (length, count));
2877 memcpy (result + length, cbuf, count);
2878 length += count;
2879 arg++;
2882 # else
2883 ENSURE_ALLOCATION (xsum (length, tmpdst_len));
2884 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
2885 free (tmpdst);
2886 length += tmpdst_len;
2887 # endif
2889 if (w < width && (dp->flags & FLAG_LEFT))
2891 size_t n = width - w;
2892 ENSURE_ALLOCATION (xsum (length, n));
2893 DCHAR_SET (result + length, ' ', n);
2894 length += n;
2897 # endif
2899 #endif
2900 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
2901 else if ((dp->conversion == 'a' || dp->conversion == 'A')
2902 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
2903 && (0
2904 # if NEED_PRINTF_DOUBLE
2905 || a.arg[dp->arg_index].type == TYPE_DOUBLE
2906 # endif
2907 # if NEED_PRINTF_LONG_DOUBLE
2908 || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2909 # endif
2911 # endif
2914 arg_type type = a.arg[dp->arg_index].type;
2915 int flags = dp->flags;
2916 size_t width;
2917 int has_precision;
2918 size_t precision;
2919 size_t tmp_length;
2920 size_t count;
2921 DCHAR_T tmpbuf[700];
2922 DCHAR_T *tmp;
2923 DCHAR_T *pad_ptr;
2924 DCHAR_T *p;
2926 width = 0;
2927 if (dp->width_start != dp->width_end)
2929 if (dp->width_arg_index != ARG_NONE)
2931 int arg;
2933 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2934 abort ();
2935 arg = a.arg[dp->width_arg_index].a.a_int;
2936 width = arg;
2937 if (arg < 0)
2939 /* "A negative field width is taken as a '-' flag
2940 followed by a positive field width." */
2941 flags |= FLAG_LEFT;
2942 width = -width;
2945 else
2947 const FCHAR_T *digitp = dp->width_start;
2950 width = xsum (xtimes (width, 10), *digitp++ - '0');
2951 while (digitp != dp->width_end);
2955 has_precision = 0;
2956 precision = 0;
2957 if (dp->precision_start != dp->precision_end)
2959 if (dp->precision_arg_index != ARG_NONE)
2961 int arg;
2963 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2964 abort ();
2965 arg = a.arg[dp->precision_arg_index].a.a_int;
2966 /* "A negative precision is taken as if the precision
2967 were omitted." */
2968 if (arg >= 0)
2970 precision = arg;
2971 has_precision = 1;
2974 else
2976 const FCHAR_T *digitp = dp->precision_start + 1;
2978 precision = 0;
2979 while (digitp != dp->precision_end)
2980 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2981 has_precision = 1;
2985 /* Allocate a temporary buffer of sufficient size. */
2986 if (type == TYPE_LONGDOUBLE)
2987 tmp_length =
2988 (unsigned int) ((LDBL_DIG + 1)
2989 * 0.831 /* decimal -> hexadecimal */
2991 + 1; /* turn floor into ceil */
2992 else
2993 tmp_length =
2994 (unsigned int) ((DBL_DIG + 1)
2995 * 0.831 /* decimal -> hexadecimal */
2997 + 1; /* turn floor into ceil */
2998 if (tmp_length < precision)
2999 tmp_length = precision;
3000 /* Account for sign, decimal point etc. */
3001 tmp_length = xsum (tmp_length, 12);
3003 if (tmp_length < width)
3004 tmp_length = width;
3006 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3008 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3009 tmp = tmpbuf;
3010 else
3012 size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3014 if (size_overflow_p (tmp_memsize))
3015 /* Overflow, would lead to out of memory. */
3016 goto out_of_memory;
3017 tmp = (DCHAR_T *) malloc (tmp_memsize);
3018 if (tmp == NULL)
3019 /* Out of memory. */
3020 goto out_of_memory;
3023 pad_ptr = NULL;
3024 p = tmp;
3025 if (type == TYPE_LONGDOUBLE)
3027 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
3028 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3030 if (isnanl (arg))
3032 if (dp->conversion == 'A')
3034 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3036 else
3038 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3041 else
3043 int sign = 0;
3044 DECL_LONG_DOUBLE_ROUNDING
3046 BEGIN_LONG_DOUBLE_ROUNDING ();
3048 if (signbit (arg)) /* arg < 0.0L or negative zero */
3050 sign = -1;
3051 arg = -arg;
3054 if (sign < 0)
3055 *p++ = '-';
3056 else if (flags & FLAG_SHOWSIGN)
3057 *p++ = '+';
3058 else if (flags & FLAG_SPACE)
3059 *p++ = ' ';
3061 if (arg > 0.0L && arg + arg == arg)
3063 if (dp->conversion == 'A')
3065 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3067 else
3069 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3072 else
3074 int exponent;
3075 long double mantissa;
3077 if (arg > 0.0L)
3078 mantissa = printf_frexpl (arg, &exponent);
3079 else
3081 exponent = 0;
3082 mantissa = 0.0L;
3085 if (has_precision
3086 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
3088 /* Round the mantissa. */
3089 long double tail = mantissa;
3090 size_t q;
3092 for (q = precision; ; q--)
3094 int digit = (int) tail;
3095 tail -= digit;
3096 if (q == 0)
3098 if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
3099 tail = 1 - tail;
3100 else
3101 tail = - tail;
3102 break;
3104 tail *= 16.0L;
3106 if (tail != 0.0L)
3107 for (q = precision; q > 0; q--)
3108 tail *= 0.0625L;
3109 mantissa += tail;
3112 *p++ = '0';
3113 *p++ = dp->conversion - 'A' + 'X';
3114 pad_ptr = p;
3116 int digit;
3118 digit = (int) mantissa;
3119 mantissa -= digit;
3120 *p++ = '0' + digit;
3121 if ((flags & FLAG_ALT)
3122 || mantissa > 0.0L || precision > 0)
3124 *p++ = decimal_point_char ();
3125 /* This loop terminates because we assume
3126 that FLT_RADIX is a power of 2. */
3127 while (mantissa > 0.0L)
3129 mantissa *= 16.0L;
3130 digit = (int) mantissa;
3131 mantissa -= digit;
3132 *p++ = digit
3133 + (digit < 10
3134 ? '0'
3135 : dp->conversion - 10);
3136 if (precision > 0)
3137 precision--;
3139 while (precision > 0)
3141 *p++ = '0';
3142 precision--;
3146 *p++ = dp->conversion - 'A' + 'P';
3147 # if WIDE_CHAR_VERSION
3149 static const wchar_t decimal_format[] =
3150 { '%', '+', 'd', '\0' };
3151 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3153 while (*p != '\0')
3154 p++;
3155 # else
3156 if (sizeof (DCHAR_T) == 1)
3158 sprintf ((char *) p, "%+d", exponent);
3159 while (*p != '\0')
3160 p++;
3162 else
3164 char expbuf[6 + 1];
3165 const char *ep;
3166 sprintf (expbuf, "%+d", exponent);
3167 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3168 p++;
3170 # endif
3173 END_LONG_DOUBLE_ROUNDING ();
3175 # else
3176 abort ();
3177 # endif
3179 else
3181 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
3182 double arg = a.arg[dp->arg_index].a.a_double;
3184 if (isnand (arg))
3186 if (dp->conversion == 'A')
3188 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3190 else
3192 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3195 else
3197 int sign = 0;
3199 if (signbit (arg)) /* arg < 0.0 or negative zero */
3201 sign = -1;
3202 arg = -arg;
3205 if (sign < 0)
3206 *p++ = '-';
3207 else if (flags & FLAG_SHOWSIGN)
3208 *p++ = '+';
3209 else if (flags & FLAG_SPACE)
3210 *p++ = ' ';
3212 if (arg > 0.0 && arg + arg == arg)
3214 if (dp->conversion == 'A')
3216 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3218 else
3220 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3223 else
3225 int exponent;
3226 double mantissa;
3228 if (arg > 0.0)
3229 mantissa = printf_frexp (arg, &exponent);
3230 else
3232 exponent = 0;
3233 mantissa = 0.0;
3236 if (has_precision
3237 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
3239 /* Round the mantissa. */
3240 double tail = mantissa;
3241 size_t q;
3243 for (q = precision; ; q--)
3245 int digit = (int) tail;
3246 tail -= digit;
3247 if (q == 0)
3249 if (digit & 1 ? tail >= 0.5 : tail > 0.5)
3250 tail = 1 - tail;
3251 else
3252 tail = - tail;
3253 break;
3255 tail *= 16.0;
3257 if (tail != 0.0)
3258 for (q = precision; q > 0; q--)
3259 tail *= 0.0625;
3260 mantissa += tail;
3263 *p++ = '0';
3264 *p++ = dp->conversion - 'A' + 'X';
3265 pad_ptr = p;
3267 int digit;
3269 digit = (int) mantissa;
3270 mantissa -= digit;
3271 *p++ = '0' + digit;
3272 if ((flags & FLAG_ALT)
3273 || mantissa > 0.0 || precision > 0)
3275 *p++ = decimal_point_char ();
3276 /* This loop terminates because we assume
3277 that FLT_RADIX is a power of 2. */
3278 while (mantissa > 0.0)
3280 mantissa *= 16.0;
3281 digit = (int) mantissa;
3282 mantissa -= digit;
3283 *p++ = digit
3284 + (digit < 10
3285 ? '0'
3286 : dp->conversion - 10);
3287 if (precision > 0)
3288 precision--;
3290 while (precision > 0)
3292 *p++ = '0';
3293 precision--;
3297 *p++ = dp->conversion - 'A' + 'P';
3298 # if WIDE_CHAR_VERSION
3300 static const wchar_t decimal_format[] =
3301 { '%', '+', 'd', '\0' };
3302 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3304 while (*p != '\0')
3305 p++;
3306 # else
3307 if (sizeof (DCHAR_T) == 1)
3309 sprintf ((char *) p, "%+d", exponent);
3310 while (*p != '\0')
3311 p++;
3313 else
3315 char expbuf[6 + 1];
3316 const char *ep;
3317 sprintf (expbuf, "%+d", exponent);
3318 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3319 p++;
3321 # endif
3324 # else
3325 abort ();
3326 # endif
3329 /* The generated string now extends from tmp to p, with the
3330 zero padding insertion point being at pad_ptr. */
3331 count = p - tmp;
3333 if (count < width)
3335 size_t pad = width - count;
3336 DCHAR_T *end = p + pad;
3338 if (flags & FLAG_LEFT)
3340 /* Pad with spaces on the right. */
3341 for (; pad > 0; pad--)
3342 *p++ = ' ';
3344 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3346 /* Pad with zeroes. */
3347 DCHAR_T *q = end;
3349 while (p > pad_ptr)
3350 *--q = *--p;
3351 for (; pad > 0; pad--)
3352 *p++ = '0';
3354 else
3356 /* Pad with spaces on the left. */
3357 DCHAR_T *q = end;
3359 while (p > tmp)
3360 *--q = *--p;
3361 for (; pad > 0; pad--)
3362 *p++ = ' ';
3365 p = end;
3368 count = p - tmp;
3370 if (count >= tmp_length)
3371 /* tmp_length was incorrectly calculated - fix the
3372 code above! */
3373 abort ();
3375 /* Make room for the result. */
3376 if (count >= allocated - length)
3378 size_t n = xsum (length, count);
3380 ENSURE_ALLOCATION (n);
3383 /* Append the result. */
3384 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3385 if (tmp != tmpbuf)
3386 free (tmp);
3387 length += count;
3389 #endif
3390 #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
3391 else if ((dp->conversion == 'f' || dp->conversion == 'F'
3392 || dp->conversion == 'e' || dp->conversion == 'E'
3393 || dp->conversion == 'g' || dp->conversion == 'G'
3394 || dp->conversion == 'a' || dp->conversion == 'A')
3395 && (0
3396 # if NEED_PRINTF_DOUBLE
3397 || a.arg[dp->arg_index].type == TYPE_DOUBLE
3398 # elif NEED_PRINTF_INFINITE_DOUBLE
3399 || (a.arg[dp->arg_index].type == TYPE_DOUBLE
3400 /* The systems (mingw) which produce wrong output
3401 for Inf, -Inf, and NaN also do so for -0.0.
3402 Therefore we treat this case here as well. */
3403 && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
3404 # endif
3405 # if NEED_PRINTF_LONG_DOUBLE
3406 || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3407 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
3408 || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3409 /* Some systems produce wrong output for Inf,
3410 -Inf, and NaN. Some systems in this category
3411 (IRIX 5.3) also do so for -0.0. Therefore we
3412 treat this case here as well. */
3413 && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
3414 # endif
3417 # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
3418 arg_type type = a.arg[dp->arg_index].type;
3419 # endif
3420 int flags = dp->flags;
3421 size_t width;
3422 size_t count;
3423 int has_precision;
3424 size_t precision;
3425 size_t tmp_length;
3426 DCHAR_T tmpbuf[700];
3427 DCHAR_T *tmp;
3428 DCHAR_T *pad_ptr;
3429 DCHAR_T *p;
3431 width = 0;
3432 if (dp->width_start != dp->width_end)
3434 if (dp->width_arg_index != ARG_NONE)
3436 int arg;
3438 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3439 abort ();
3440 arg = a.arg[dp->width_arg_index].a.a_int;
3441 width = arg;
3442 if (arg < 0)
3444 /* "A negative field width is taken as a '-' flag
3445 followed by a positive field width." */
3446 flags |= FLAG_LEFT;
3447 width = -width;
3450 else
3452 const FCHAR_T *digitp = dp->width_start;
3455 width = xsum (xtimes (width, 10), *digitp++ - '0');
3456 while (digitp != dp->width_end);
3460 has_precision = 0;
3461 precision = 0;
3462 if (dp->precision_start != dp->precision_end)
3464 if (dp->precision_arg_index != ARG_NONE)
3466 int arg;
3468 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3469 abort ();
3470 arg = a.arg[dp->precision_arg_index].a.a_int;
3471 /* "A negative precision is taken as if the precision
3472 were omitted." */
3473 if (arg >= 0)
3475 precision = arg;
3476 has_precision = 1;
3479 else
3481 const FCHAR_T *digitp = dp->precision_start + 1;
3483 precision = 0;
3484 while (digitp != dp->precision_end)
3485 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3486 has_precision = 1;
3490 /* POSIX specifies the default precision to be 6 for %f, %F,
3491 %e, %E, but not for %g, %G. Implementations appear to use
3492 the same default precision also for %g, %G. But for %a, %A,
3493 the default precision is 0. */
3494 if (!has_precision)
3495 if (!(dp->conversion == 'a' || dp->conversion == 'A'))
3496 precision = 6;
3498 /* Allocate a temporary buffer of sufficient size. */
3499 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3500 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
3501 # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3502 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
3503 # elif NEED_PRINTF_LONG_DOUBLE
3504 tmp_length = LDBL_DIG + 1;
3505 # elif NEED_PRINTF_DOUBLE
3506 tmp_length = DBL_DIG + 1;
3507 # else
3508 tmp_length = 0;
3509 # endif
3510 if (tmp_length < precision)
3511 tmp_length = precision;
3512 # if NEED_PRINTF_LONG_DOUBLE
3513 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3514 if (type == TYPE_LONGDOUBLE)
3515 # endif
3516 if (dp->conversion == 'f' || dp->conversion == 'F')
3518 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3519 if (!(isnanl (arg) || arg + arg == arg))
3521 /* arg is finite and nonzero. */
3522 int exponent = floorlog10l (arg < 0 ? -arg : arg);
3523 if (exponent >= 0 && tmp_length < exponent + precision)
3524 tmp_length = exponent + precision;
3527 # endif
3528 # if NEED_PRINTF_DOUBLE
3529 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3530 if (type == TYPE_DOUBLE)
3531 # endif
3532 if (dp->conversion == 'f' || dp->conversion == 'F')
3534 double arg = a.arg[dp->arg_index].a.a_double;
3535 if (!(isnand (arg) || arg + arg == arg))
3537 /* arg is finite and nonzero. */
3538 int exponent = floorlog10 (arg < 0 ? -arg : arg);
3539 if (exponent >= 0 && tmp_length < exponent + precision)
3540 tmp_length = exponent + precision;
3543 # endif
3544 /* Account for sign, decimal point etc. */
3545 tmp_length = xsum (tmp_length, 12);
3547 if (tmp_length < width)
3548 tmp_length = width;
3550 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3552 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3553 tmp = tmpbuf;
3554 else
3556 size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3558 if (size_overflow_p (tmp_memsize))
3559 /* Overflow, would lead to out of memory. */
3560 goto out_of_memory;
3561 tmp = (DCHAR_T *) malloc (tmp_memsize);
3562 if (tmp == NULL)
3563 /* Out of memory. */
3564 goto out_of_memory;
3567 pad_ptr = NULL;
3568 p = tmp;
3570 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3571 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3572 if (type == TYPE_LONGDOUBLE)
3573 # endif
3575 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3577 if (isnanl (arg))
3579 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3581 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3583 else
3585 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3588 else
3590 int sign = 0;
3591 DECL_LONG_DOUBLE_ROUNDING
3593 BEGIN_LONG_DOUBLE_ROUNDING ();
3595 if (signbit (arg)) /* arg < 0.0L or negative zero */
3597 sign = -1;
3598 arg = -arg;
3601 if (sign < 0)
3602 *p++ = '-';
3603 else if (flags & FLAG_SHOWSIGN)
3604 *p++ = '+';
3605 else if (flags & FLAG_SPACE)
3606 *p++ = ' ';
3608 if (arg > 0.0L && arg + arg == arg)
3610 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3612 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3614 else
3616 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3619 else
3621 # if NEED_PRINTF_LONG_DOUBLE
3622 pad_ptr = p;
3624 if (dp->conversion == 'f' || dp->conversion == 'F')
3626 char *digits;
3627 size_t ndigits;
3629 digits =
3630 scale10_round_decimal_long_double (arg, precision);
3631 if (digits == NULL)
3633 END_LONG_DOUBLE_ROUNDING ();
3634 goto out_of_memory;
3636 ndigits = strlen (digits);
3638 if (ndigits > precision)
3641 --ndigits;
3642 *p++ = digits[ndigits];
3644 while (ndigits > precision);
3645 else
3646 *p++ = '0';
3647 /* Here ndigits <= precision. */
3648 if ((flags & FLAG_ALT) || precision > 0)
3650 *p++ = decimal_point_char ();
3651 for (; precision > ndigits; precision--)
3652 *p++ = '0';
3653 while (ndigits > 0)
3655 --ndigits;
3656 *p++ = digits[ndigits];
3660 free (digits);
3662 else if (dp->conversion == 'e' || dp->conversion == 'E')
3664 int exponent;
3666 if (arg == 0.0L)
3668 exponent = 0;
3669 *p++ = '0';
3670 if ((flags & FLAG_ALT) || precision > 0)
3672 *p++ = decimal_point_char ();
3673 for (; precision > 0; precision--)
3674 *p++ = '0';
3677 else
3679 /* arg > 0.0L. */
3680 int adjusted;
3681 char *digits;
3682 size_t ndigits;
3684 exponent = floorlog10l (arg);
3685 adjusted = 0;
3686 for (;;)
3688 digits =
3689 scale10_round_decimal_long_double (arg,
3690 (int)precision - exponent);
3691 if (digits == NULL)
3693 END_LONG_DOUBLE_ROUNDING ();
3694 goto out_of_memory;
3696 ndigits = strlen (digits);
3698 if (ndigits == precision + 1)
3699 break;
3700 if (ndigits < precision
3701 || ndigits > precision + 2)
3702 /* The exponent was not guessed
3703 precisely enough. */
3704 abort ();
3705 if (adjusted)
3706 /* None of two values of exponent is
3707 the right one. Prevent an endless
3708 loop. */
3709 abort ();
3710 free (digits);
3711 if (ndigits == precision)
3712 exponent -= 1;
3713 else
3714 exponent += 1;
3715 adjusted = 1;
3717 /* Here ndigits = precision+1. */
3718 if (is_borderline (digits, precision))
3720 /* Maybe the exponent guess was too high
3721 and a smaller exponent can be reached
3722 by turning a 10...0 into 9...9x. */
3723 char *digits2 =
3724 scale10_round_decimal_long_double (arg,
3725 (int)precision - exponent + 1);
3726 if (digits2 == NULL)
3728 free (digits);
3729 END_LONG_DOUBLE_ROUNDING ();
3730 goto out_of_memory;
3732 if (strlen (digits2) == precision + 1)
3734 free (digits);
3735 digits = digits2;
3736 exponent -= 1;
3738 else
3739 free (digits2);
3741 /* Here ndigits = precision+1. */
3743 *p++ = digits[--ndigits];
3744 if ((flags & FLAG_ALT) || precision > 0)
3746 *p++ = decimal_point_char ();
3747 while (ndigits > 0)
3749 --ndigits;
3750 *p++ = digits[ndigits];
3754 free (digits);
3757 *p++ = dp->conversion; /* 'e' or 'E' */
3758 # if WIDE_CHAR_VERSION
3760 static const wchar_t decimal_format[] =
3761 { '%', '+', '.', '2', 'd', '\0' };
3762 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3764 while (*p != '\0')
3765 p++;
3766 # else
3767 if (sizeof (DCHAR_T) == 1)
3769 sprintf ((char *) p, "%+.2d", exponent);
3770 while (*p != '\0')
3771 p++;
3773 else
3775 char expbuf[6 + 1];
3776 const char *ep;
3777 sprintf (expbuf, "%+.2d", exponent);
3778 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3779 p++;
3781 # endif
3783 else if (dp->conversion == 'g' || dp->conversion == 'G')
3785 if (precision == 0)
3786 precision = 1;
3787 /* precision >= 1. */
3789 if (arg == 0.0L)
3790 /* The exponent is 0, >= -4, < precision.
3791 Use fixed-point notation. */
3793 size_t ndigits = precision;
3794 /* Number of trailing zeroes that have to be
3795 dropped. */
3796 size_t nzeroes =
3797 (flags & FLAG_ALT ? 0 : precision - 1);
3799 --ndigits;
3800 *p++ = '0';
3801 if ((flags & FLAG_ALT) || ndigits > nzeroes)
3803 *p++ = decimal_point_char ();
3804 while (ndigits > nzeroes)
3806 --ndigits;
3807 *p++ = '0';
3811 else
3813 /* arg > 0.0L. */
3814 int exponent;
3815 int adjusted;
3816 char *digits;
3817 size_t ndigits;
3818 size_t nzeroes;
3820 exponent = floorlog10l (arg);
3821 adjusted = 0;
3822 for (;;)
3824 digits =
3825 scale10_round_decimal_long_double (arg,
3826 (int)(precision - 1) - exponent);
3827 if (digits == NULL)
3829 END_LONG_DOUBLE_ROUNDING ();
3830 goto out_of_memory;
3832 ndigits = strlen (digits);
3834 if (ndigits == precision)
3835 break;
3836 if (ndigits < precision - 1
3837 || ndigits > precision + 1)
3838 /* The exponent was not guessed
3839 precisely enough. */
3840 abort ();
3841 if (adjusted)
3842 /* None of two values of exponent is
3843 the right one. Prevent an endless
3844 loop. */
3845 abort ();
3846 free (digits);
3847 if (ndigits < precision)
3848 exponent -= 1;
3849 else
3850 exponent += 1;
3851 adjusted = 1;
3853 /* Here ndigits = precision. */
3854 if (is_borderline (digits, precision - 1))
3856 /* Maybe the exponent guess was too high
3857 and a smaller exponent can be reached
3858 by turning a 10...0 into 9...9x. */
3859 char *digits2 =
3860 scale10_round_decimal_long_double (arg,
3861 (int)(precision - 1) - exponent + 1);
3862 if (digits2 == NULL)
3864 free (digits);
3865 END_LONG_DOUBLE_ROUNDING ();
3866 goto out_of_memory;
3868 if (strlen (digits2) == precision)
3870 free (digits);
3871 digits = digits2;
3872 exponent -= 1;
3874 else
3875 free (digits2);
3877 /* Here ndigits = precision. */
3879 /* Determine the number of trailing zeroes
3880 that have to be dropped. */
3881 nzeroes = 0;
3882 if ((flags & FLAG_ALT) == 0)
3883 while (nzeroes < ndigits
3884 && digits[nzeroes] == '0')
3885 nzeroes++;
3887 /* The exponent is now determined. */
3888 if (exponent >= -4
3889 && exponent < (long)precision)
3891 /* Fixed-point notation:
3892 max(exponent,0)+1 digits, then the
3893 decimal point, then the remaining
3894 digits without trailing zeroes. */
3895 if (exponent >= 0)
3897 size_t ecount = exponent + 1;
3898 /* Note: count <= precision = ndigits. */
3899 for (; ecount > 0; ecount--)
3900 *p++ = digits[--ndigits];
3901 if ((flags & FLAG_ALT) || ndigits > nzeroes)
3903 *p++ = decimal_point_char ();
3904 while (ndigits > nzeroes)
3906 --ndigits;
3907 *p++ = digits[ndigits];
3911 else
3913 size_t ecount = -exponent - 1;
3914 *p++ = '0';
3915 *p++ = decimal_point_char ();
3916 for (; ecount > 0; ecount--)
3917 *p++ = '0';
3918 while (ndigits > nzeroes)
3920 --ndigits;
3921 *p++ = digits[ndigits];
3925 else
3927 /* Exponential notation. */
3928 *p++ = digits[--ndigits];
3929 if ((flags & FLAG_ALT) || ndigits > nzeroes)
3931 *p++ = decimal_point_char ();
3932 while (ndigits > nzeroes)
3934 --ndigits;
3935 *p++ = digits[ndigits];
3938 *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3939 # if WIDE_CHAR_VERSION
3941 static const wchar_t decimal_format[] =
3942 { '%', '+', '.', '2', 'd', '\0' };
3943 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3945 while (*p != '\0')
3946 p++;
3947 # else
3948 if (sizeof (DCHAR_T) == 1)
3950 sprintf ((char *) p, "%+.2d", exponent);
3951 while (*p != '\0')
3952 p++;
3954 else
3956 char expbuf[6 + 1];
3957 const char *ep;
3958 sprintf (expbuf, "%+.2d", exponent);
3959 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3960 p++;
3962 # endif
3965 free (digits);
3968 else
3969 abort ();
3970 # else
3971 /* arg is finite. */
3972 if (!(arg == 0.0L))
3973 abort ();
3975 pad_ptr = p;
3977 if (dp->conversion == 'f' || dp->conversion == 'F')
3979 *p++ = '0';
3980 if ((flags & FLAG_ALT) || precision > 0)
3982 *p++ = decimal_point_char ();
3983 for (; precision > 0; precision--)
3984 *p++ = '0';
3987 else if (dp->conversion == 'e' || dp->conversion == 'E')
3989 *p++ = '0';
3990 if ((flags & FLAG_ALT) || precision > 0)
3992 *p++ = decimal_point_char ();
3993 for (; precision > 0; precision--)
3994 *p++ = '0';
3996 *p++ = dp->conversion; /* 'e' or 'E' */
3997 *p++ = '+';
3998 *p++ = '0';
3999 *p++ = '0';
4001 else if (dp->conversion == 'g' || dp->conversion == 'G')
4003 *p++ = '0';
4004 if (flags & FLAG_ALT)
4006 size_t ndigits =
4007 (precision > 0 ? precision - 1 : 0);
4008 *p++ = decimal_point_char ();
4009 for (; ndigits > 0; --ndigits)
4010 *p++ = '0';
4013 else if (dp->conversion == 'a' || dp->conversion == 'A')
4015 *p++ = '0';
4016 *p++ = dp->conversion - 'A' + 'X';
4017 pad_ptr = p;
4018 *p++ = '0';
4019 if ((flags & FLAG_ALT) || precision > 0)
4021 *p++ = decimal_point_char ();
4022 for (; precision > 0; precision--)
4023 *p++ = '0';
4025 *p++ = dp->conversion - 'A' + 'P';
4026 *p++ = '+';
4027 *p++ = '0';
4029 else
4030 abort ();
4031 # endif
4034 END_LONG_DOUBLE_ROUNDING ();
4037 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4038 else
4039 # endif
4040 # endif
4041 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4043 double arg = a.arg[dp->arg_index].a.a_double;
4045 if (isnand (arg))
4047 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4049 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4051 else
4053 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4056 else
4058 int sign = 0;
4060 if (signbit (arg)) /* arg < 0.0 or negative zero */
4062 sign = -1;
4063 arg = -arg;
4066 if (sign < 0)
4067 *p++ = '-';
4068 else if (flags & FLAG_SHOWSIGN)
4069 *p++ = '+';
4070 else if (flags & FLAG_SPACE)
4071 *p++ = ' ';
4073 if (arg > 0.0 && arg + arg == arg)
4075 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4077 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4079 else
4081 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4084 else
4086 # if NEED_PRINTF_DOUBLE
4087 pad_ptr = p;
4089 if (dp->conversion == 'f' || dp->conversion == 'F')
4091 char *digits;
4092 size_t ndigits;
4094 digits =
4095 scale10_round_decimal_double (arg, precision);
4096 if (digits == NULL)
4097 goto out_of_memory;
4098 ndigits = strlen (digits);
4100 if (ndigits > precision)
4103 --ndigits;
4104 *p++ = digits[ndigits];
4106 while (ndigits > precision);
4107 else
4108 *p++ = '0';
4109 /* Here ndigits <= precision. */
4110 if ((flags & FLAG_ALT) || precision > 0)
4112 *p++ = decimal_point_char ();
4113 for (; precision > ndigits; precision--)
4114 *p++ = '0';
4115 while (ndigits > 0)
4117 --ndigits;
4118 *p++ = digits[ndigits];
4122 free (digits);
4124 else if (dp->conversion == 'e' || dp->conversion == 'E')
4126 int exponent;
4128 if (arg == 0.0)
4130 exponent = 0;
4131 *p++ = '0';
4132 if ((flags & FLAG_ALT) || precision > 0)
4134 *p++ = decimal_point_char ();
4135 for (; precision > 0; precision--)
4136 *p++ = '0';
4139 else
4141 /* arg > 0.0. */
4142 int adjusted;
4143 char *digits;
4144 size_t ndigits;
4146 exponent = floorlog10 (arg);
4147 adjusted = 0;
4148 for (;;)
4150 digits =
4151 scale10_round_decimal_double (arg,
4152 (int)precision - exponent);
4153 if (digits == NULL)
4154 goto out_of_memory;
4155 ndigits = strlen (digits);
4157 if (ndigits == precision + 1)
4158 break;
4159 if (ndigits < precision
4160 || ndigits > precision + 2)
4161 /* The exponent was not guessed
4162 precisely enough. */
4163 abort ();
4164 if (adjusted)
4165 /* None of two values of exponent is
4166 the right one. Prevent an endless
4167 loop. */
4168 abort ();
4169 free (digits);
4170 if (ndigits == precision)
4171 exponent -= 1;
4172 else
4173 exponent += 1;
4174 adjusted = 1;
4176 /* Here ndigits = precision+1. */
4177 if (is_borderline (digits, precision))
4179 /* Maybe the exponent guess was too high
4180 and a smaller exponent can be reached
4181 by turning a 10...0 into 9...9x. */
4182 char *digits2 =
4183 scale10_round_decimal_double (arg,
4184 (int)precision - exponent + 1);
4185 if (digits2 == NULL)
4187 free (digits);
4188 goto out_of_memory;
4190 if (strlen (digits2) == precision + 1)
4192 free (digits);
4193 digits = digits2;
4194 exponent -= 1;
4196 else
4197 free (digits2);
4199 /* Here ndigits = precision+1. */
4201 *p++ = digits[--ndigits];
4202 if ((flags & FLAG_ALT) || precision > 0)
4204 *p++ = decimal_point_char ();
4205 while (ndigits > 0)
4207 --ndigits;
4208 *p++ = digits[ndigits];
4212 free (digits);
4215 *p++ = dp->conversion; /* 'e' or 'E' */
4216 # if WIDE_CHAR_VERSION
4218 static const wchar_t decimal_format[] =
4219 /* Produce the same number of exponent digits
4220 as the native printf implementation. */
4221 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4222 { '%', '+', '.', '3', 'd', '\0' };
4223 # else
4224 { '%', '+', '.', '2', 'd', '\0' };
4225 # endif
4226 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4228 while (*p != '\0')
4229 p++;
4230 # else
4232 static const char decimal_format[] =
4233 /* Produce the same number of exponent digits
4234 as the native printf implementation. */
4235 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4236 "%+.3d";
4237 # else
4238 "%+.2d";
4239 # endif
4240 if (sizeof (DCHAR_T) == 1)
4242 sprintf ((char *) p, decimal_format, exponent);
4243 while (*p != '\0')
4244 p++;
4246 else
4248 char expbuf[6 + 1];
4249 const char *ep;
4250 sprintf (expbuf, decimal_format, exponent);
4251 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4252 p++;
4255 # endif
4257 else if (dp->conversion == 'g' || dp->conversion == 'G')
4259 if (precision == 0)
4260 precision = 1;
4261 /* precision >= 1. */
4263 if (arg == 0.0)
4264 /* The exponent is 0, >= -4, < precision.
4265 Use fixed-point notation. */
4267 size_t ndigits = precision;
4268 /* Number of trailing zeroes that have to be
4269 dropped. */
4270 size_t nzeroes =
4271 (flags & FLAG_ALT ? 0 : precision - 1);
4273 --ndigits;
4274 *p++ = '0';
4275 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4277 *p++ = decimal_point_char ();
4278 while (ndigits > nzeroes)
4280 --ndigits;
4281 *p++ = '0';
4285 else
4287 /* arg > 0.0. */
4288 int exponent;
4289 int adjusted;
4290 char *digits;
4291 size_t ndigits;
4292 size_t nzeroes;
4294 exponent = floorlog10 (arg);
4295 adjusted = 0;
4296 for (;;)
4298 digits =
4299 scale10_round_decimal_double (arg,
4300 (int)(precision - 1) - exponent);
4301 if (digits == NULL)
4302 goto out_of_memory;
4303 ndigits = strlen (digits);
4305 if (ndigits == precision)
4306 break;
4307 if (ndigits < precision - 1
4308 || ndigits > precision + 1)
4309 /* The exponent was not guessed
4310 precisely enough. */
4311 abort ();
4312 if (adjusted)
4313 /* None of two values of exponent is
4314 the right one. Prevent an endless
4315 loop. */
4316 abort ();
4317 free (digits);
4318 if (ndigits < precision)
4319 exponent -= 1;
4320 else
4321 exponent += 1;
4322 adjusted = 1;
4324 /* Here ndigits = precision. */
4325 if (is_borderline (digits, precision - 1))
4327 /* Maybe the exponent guess was too high
4328 and a smaller exponent can be reached
4329 by turning a 10...0 into 9...9x. */
4330 char *digits2 =
4331 scale10_round_decimal_double (arg,
4332 (int)(precision - 1) - exponent + 1);
4333 if (digits2 == NULL)
4335 free (digits);
4336 goto out_of_memory;
4338 if (strlen (digits2) == precision)
4340 free (digits);
4341 digits = digits2;
4342 exponent -= 1;
4344 else
4345 free (digits2);
4347 /* Here ndigits = precision. */
4349 /* Determine the number of trailing zeroes
4350 that have to be dropped. */
4351 nzeroes = 0;
4352 if ((flags & FLAG_ALT) == 0)
4353 while (nzeroes < ndigits
4354 && digits[nzeroes] == '0')
4355 nzeroes++;
4357 /* The exponent is now determined. */
4358 if (exponent >= -4
4359 && exponent < (long)precision)
4361 /* Fixed-point notation:
4362 max(exponent,0)+1 digits, then the
4363 decimal point, then the remaining
4364 digits without trailing zeroes. */
4365 if (exponent >= 0)
4367 size_t ecount = exponent + 1;
4368 /* Note: ecount <= precision = ndigits. */
4369 for (; ecount > 0; ecount--)
4370 *p++ = digits[--ndigits];
4371 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4373 *p++ = decimal_point_char ();
4374 while (ndigits > nzeroes)
4376 --ndigits;
4377 *p++ = digits[ndigits];
4381 else
4383 size_t ecount = -exponent - 1;
4384 *p++ = '0';
4385 *p++ = decimal_point_char ();
4386 for (; ecount > 0; ecount--)
4387 *p++ = '0';
4388 while (ndigits > nzeroes)
4390 --ndigits;
4391 *p++ = digits[ndigits];
4395 else
4397 /* Exponential notation. */
4398 *p++ = digits[--ndigits];
4399 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4401 *p++ = decimal_point_char ();
4402 while (ndigits > nzeroes)
4404 --ndigits;
4405 *p++ = digits[ndigits];
4408 *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4409 # if WIDE_CHAR_VERSION
4411 static const wchar_t decimal_format[] =
4412 /* Produce the same number of exponent digits
4413 as the native printf implementation. */
4414 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4415 { '%', '+', '.', '3', 'd', '\0' };
4416 # else
4417 { '%', '+', '.', '2', 'd', '\0' };
4418 # endif
4419 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4421 while (*p != '\0')
4422 p++;
4423 # else
4425 static const char decimal_format[] =
4426 /* Produce the same number of exponent digits
4427 as the native printf implementation. */
4428 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4429 "%+.3d";
4430 # else
4431 "%+.2d";
4432 # endif
4433 if (sizeof (DCHAR_T) == 1)
4435 sprintf ((char *) p, decimal_format, exponent);
4436 while (*p != '\0')
4437 p++;
4439 else
4441 char expbuf[6 + 1];
4442 const char *ep;
4443 sprintf (expbuf, decimal_format, exponent);
4444 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4445 p++;
4448 # endif
4451 free (digits);
4454 else
4455 abort ();
4456 # else
4457 /* arg is finite. */
4458 if (!(arg == 0.0))
4459 abort ();
4461 pad_ptr = p;
4463 if (dp->conversion == 'f' || dp->conversion == 'F')
4465 *p++ = '0';
4466 if ((flags & FLAG_ALT) || precision > 0)
4468 *p++ = decimal_point_char ();
4469 for (; precision > 0; precision--)
4470 *p++ = '0';
4473 else if (dp->conversion == 'e' || dp->conversion == 'E')
4475 *p++ = '0';
4476 if ((flags & FLAG_ALT) || precision > 0)
4478 *p++ = decimal_point_char ();
4479 for (; precision > 0; precision--)
4480 *p++ = '0';
4482 *p++ = dp->conversion; /* 'e' or 'E' */
4483 *p++ = '+';
4484 /* Produce the same number of exponent digits as
4485 the native printf implementation. */
4486 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4487 *p++ = '0';
4488 # endif
4489 *p++ = '0';
4490 *p++ = '0';
4492 else if (dp->conversion == 'g' || dp->conversion == 'G')
4494 *p++ = '0';
4495 if (flags & FLAG_ALT)
4497 size_t ndigits =
4498 (precision > 0 ? precision - 1 : 0);
4499 *p++ = decimal_point_char ();
4500 for (; ndigits > 0; --ndigits)
4501 *p++ = '0';
4504 else
4505 abort ();
4506 # endif
4510 # endif
4512 /* The generated string now extends from tmp to p, with the
4513 zero padding insertion point being at pad_ptr. */
4514 count = p - tmp;
4516 if (count < width)
4518 size_t pad = width - count;
4519 DCHAR_T *end = p + pad;
4521 if (flags & FLAG_LEFT)
4523 /* Pad with spaces on the right. */
4524 for (; pad > 0; pad--)
4525 *p++ = ' ';
4527 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4529 /* Pad with zeroes. */
4530 DCHAR_T *q = end;
4532 while (p > pad_ptr)
4533 *--q = *--p;
4534 for (; pad > 0; pad--)
4535 *p++ = '0';
4537 else
4539 /* Pad with spaces on the left. */
4540 DCHAR_T *q = end;
4542 while (p > tmp)
4543 *--q = *--p;
4544 for (; pad > 0; pad--)
4545 *p++ = ' ';
4548 p = end;
4551 count = p - tmp;
4553 if (count >= tmp_length)
4554 /* tmp_length was incorrectly calculated - fix the
4555 code above! */
4556 abort ();
4558 /* Make room for the result. */
4559 if (count >= allocated - length)
4561 size_t n = xsum (length, count);
4563 ENSURE_ALLOCATION (n);
4566 /* Append the result. */
4567 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4568 if (tmp != tmpbuf)
4569 free (tmp);
4570 length += count;
4572 #endif
4573 else
4575 arg_type type = a.arg[dp->arg_index].type;
4576 int flags = dp->flags;
4577 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4578 int has_width;
4579 #endif
4580 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4581 size_t width;
4582 #endif
4583 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
4584 int has_precision;
4585 size_t precision;
4586 #endif
4587 #if NEED_PRINTF_UNBOUNDED_PRECISION
4588 int prec_ourselves;
4589 #else
4590 # define prec_ourselves 0
4591 #endif
4592 #if NEED_PRINTF_FLAG_LEFTADJUST
4593 # define pad_ourselves 1
4594 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4595 int pad_ourselves;
4596 #else
4597 # define pad_ourselves 0
4598 #endif
4599 TCHAR_T *fbp;
4600 unsigned int prefix_count;
4601 int prefixes[2] IF_LINT (= { 0 });
4602 int orig_errno;
4603 #if !USE_SNPRINTF
4604 size_t tmp_length;
4605 TCHAR_T tmpbuf[700];
4606 TCHAR_T *tmp;
4607 #endif
4609 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4610 has_width = 0;
4611 #endif
4612 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4613 width = 0;
4614 if (dp->width_start != dp->width_end)
4616 if (dp->width_arg_index != ARG_NONE)
4618 int arg;
4620 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4621 abort ();
4622 arg = a.arg[dp->width_arg_index].a.a_int;
4623 width = arg;
4624 if (arg < 0)
4626 /* "A negative field width is taken as a '-' flag
4627 followed by a positive field width." */
4628 flags |= FLAG_LEFT;
4629 width = -width;
4632 else
4634 const FCHAR_T *digitp = dp->width_start;
4637 width = xsum (xtimes (width, 10), *digitp++ - '0');
4638 while (digitp != dp->width_end);
4640 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4641 has_width = 1;
4642 #endif
4644 #endif
4646 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
4647 has_precision = 0;
4648 precision = 6;
4649 if (dp->precision_start != dp->precision_end)
4651 if (dp->precision_arg_index != ARG_NONE)
4653 int arg;
4655 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4656 abort ();
4657 arg = a.arg[dp->precision_arg_index].a.a_int;
4658 /* "A negative precision is taken as if the precision
4659 were omitted." */
4660 if (arg >= 0)
4662 precision = arg;
4663 has_precision = 1;
4666 else
4668 const FCHAR_T *digitp = dp->precision_start + 1;
4670 precision = 0;
4671 while (digitp != dp->precision_end)
4672 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4673 has_precision = 1;
4676 #endif
4678 /* Decide whether to handle the precision ourselves. */
4679 #if NEED_PRINTF_UNBOUNDED_PRECISION
4680 switch (dp->conversion)
4682 case 'd': case 'i': case 'u':
4683 case 'o':
4684 case 'x': case 'X': case 'p':
4685 prec_ourselves = has_precision && (precision > 0);
4686 break;
4687 default:
4688 prec_ourselves = 0;
4689 break;
4691 #endif
4693 /* Decide whether to perform the padding ourselves. */
4694 #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
4695 switch (dp->conversion)
4697 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4698 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
4699 to perform the padding after this conversion. Functions
4700 with unistdio extensions perform the padding based on
4701 character count rather than element count. */
4702 case 'c': case 's':
4703 # endif
4704 # if NEED_PRINTF_FLAG_ZERO
4705 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
4706 case 'a': case 'A':
4707 # endif
4708 pad_ourselves = 1;
4709 break;
4710 default:
4711 pad_ourselves = prec_ourselves;
4712 break;
4714 #endif
4716 #if !USE_SNPRINTF
4717 /* Allocate a temporary buffer of sufficient size for calling
4718 sprintf. */
4719 tmp_length =
4720 MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
4721 flags, width, has_precision, precision,
4722 pad_ourselves);
4724 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
4725 tmp = tmpbuf;
4726 else
4728 size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
4730 if (size_overflow_p (tmp_memsize))
4731 /* Overflow, would lead to out of memory. */
4732 goto out_of_memory;
4733 tmp = (TCHAR_T *) malloc (tmp_memsize);
4734 if (tmp == NULL)
4735 /* Out of memory. */
4736 goto out_of_memory;
4738 #endif
4740 /* Construct the format string for calling snprintf or
4741 sprintf. */
4742 fbp = buf;
4743 *fbp++ = '%';
4744 #if NEED_PRINTF_FLAG_GROUPING
4745 /* The underlying implementation doesn't support the ' flag.
4746 Produce no grouping characters in this case; this is
4747 acceptable because the grouping is locale dependent. */
4748 #else
4749 if (flags & FLAG_GROUP)
4750 *fbp++ = '\'';
4751 #endif
4752 if (flags & FLAG_LEFT)
4753 *fbp++ = '-';
4754 if (flags & FLAG_SHOWSIGN)
4755 *fbp++ = '+';
4756 if (flags & FLAG_SPACE)
4757 *fbp++ = ' ';
4758 if (flags & FLAG_ALT)
4759 *fbp++ = '#';
4760 #if __GLIBC__ >= 2 && !defined __UCLIBC__
4761 if (flags & FLAG_LOCALIZED)
4762 *fbp++ = 'I';
4763 #endif
4764 if (!pad_ourselves)
4766 if (flags & FLAG_ZERO)
4767 *fbp++ = '0';
4768 if (dp->width_start != dp->width_end)
4770 size_t n = dp->width_end - dp->width_start;
4771 /* The width specification is known to consist only
4772 of standard ASCII characters. */
4773 if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4775 memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
4776 fbp += n;
4778 else
4780 const FCHAR_T *mp = dp->width_start;
4782 *fbp++ = *mp++;
4783 while (--n > 0);
4787 if (!prec_ourselves)
4789 if (dp->precision_start != dp->precision_end)
4791 size_t n = dp->precision_end - dp->precision_start;
4792 /* The precision specification is known to consist only
4793 of standard ASCII characters. */
4794 if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4796 memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
4797 fbp += n;
4799 else
4801 const FCHAR_T *mp = dp->precision_start;
4803 *fbp++ = *mp++;
4804 while (--n > 0);
4809 switch (type)
4811 #if HAVE_LONG_LONG
4812 case TYPE_LONGLONGINT:
4813 case TYPE_ULONGLONGINT:
4814 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4815 *fbp++ = 'I';
4816 *fbp++ = '6';
4817 *fbp++ = '4';
4818 break;
4819 # else
4820 *fbp++ = 'l';
4821 /*FALLTHROUGH*/
4822 # endif
4823 #endif
4824 case TYPE_LONGINT:
4825 case TYPE_ULONGINT:
4826 #if HAVE_WINT_T
4827 case TYPE_WIDE_CHAR:
4828 #endif
4829 #if HAVE_WCHAR_T
4830 case TYPE_WIDE_STRING:
4831 #endif
4832 *fbp++ = 'l';
4833 break;
4834 case TYPE_LONGDOUBLE:
4835 *fbp++ = 'L';
4836 break;
4837 default:
4838 break;
4840 #if NEED_PRINTF_DIRECTIVE_F
4841 if (dp->conversion == 'F')
4842 *fbp = 'f';
4843 else
4844 #endif
4845 *fbp = dp->conversion;
4846 #if USE_SNPRINTF
4847 # if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
4848 fbp[1] = '%';
4849 fbp[2] = 'n';
4850 fbp[3] = '\0';
4851 # else
4852 /* On glibc2 systems from glibc >= 2.3 - probably also older
4853 ones - we know that snprintf's return value conforms to
4854 ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and
4855 gl_SNPRINTF_TRUNCATION_C99 pass.
4856 Therefore we can avoid using %n in this situation.
4857 On glibc2 systems from 2004-10-18 or newer, the use of %n
4858 in format strings in writable memory may crash the program
4859 (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
4860 in this situation. */
4861 /* On native Windows systems (such as mingw), we can avoid using
4862 %n because:
4863 - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
4864 snprintf does not write more than the specified number
4865 of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
4866 '4', '5', '6' into buf, not '4', '5', '\0'.)
4867 - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
4868 allows us to recognize the case of an insufficient
4869 buffer size: it returns -1 in this case.
4870 On native Windows systems (such as mingw) where the OS is
4871 Windows Vista, the use of %n in format strings by default
4872 crashes the program. See
4873 <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
4874 <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
4875 So we should avoid %n in this situation. */
4876 fbp[1] = '\0';
4877 # endif
4878 #else
4879 fbp[1] = '\0';
4880 #endif
4882 /* Construct the arguments for calling snprintf or sprintf. */
4883 prefix_count = 0;
4884 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
4886 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4887 abort ();
4888 prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
4890 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
4892 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4893 abort ();
4894 prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
4897 #if USE_SNPRINTF
4898 /* The SNPRINTF result is appended after result[0..length].
4899 The latter is an array of DCHAR_T; SNPRINTF appends an
4900 array of TCHAR_T to it. This is possible because
4901 sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
4902 alignof (TCHAR_T) <= alignof (DCHAR_T). */
4903 # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
4904 /* Ensure that maxlen below will be >= 2. Needed on BeOS,
4905 where an snprintf() with maxlen==1 acts like sprintf(). */
4906 ENSURE_ALLOCATION (xsum (length,
4907 (2 + TCHARS_PER_DCHAR - 1)
4908 / TCHARS_PER_DCHAR));
4909 /* Prepare checking whether snprintf returns the count
4910 via %n. */
4911 *(TCHAR_T *) (result + length) = '\0';
4912 #endif
4914 orig_errno = errno;
4916 for (;;)
4918 int count = -1;
4920 #if USE_SNPRINTF
4921 int retcount = 0;
4922 size_t maxlen = allocated - length;
4923 /* SNPRINTF can fail if its second argument is
4924 > INT_MAX. */
4925 if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
4926 maxlen = INT_MAX / TCHARS_PER_DCHAR;
4927 maxlen = maxlen * TCHARS_PER_DCHAR;
4928 # define SNPRINTF_BUF(arg) \
4929 switch (prefix_count) \
4931 case 0: \
4932 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4933 maxlen, buf, \
4934 arg, &count); \
4935 break; \
4936 case 1: \
4937 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4938 maxlen, buf, \
4939 prefixes[0], arg, &count); \
4940 break; \
4941 case 2: \
4942 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4943 maxlen, buf, \
4944 prefixes[0], prefixes[1], arg, \
4945 &count); \
4946 break; \
4947 default: \
4948 abort (); \
4950 #else
4951 # define SNPRINTF_BUF(arg) \
4952 switch (prefix_count) \
4954 case 0: \
4955 count = sprintf (tmp, buf, arg); \
4956 break; \
4957 case 1: \
4958 count = sprintf (tmp, buf, prefixes[0], arg); \
4959 break; \
4960 case 2: \
4961 count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
4962 arg); \
4963 break; \
4964 default: \
4965 abort (); \
4967 #endif
4969 errno = 0;
4970 switch (type)
4972 case TYPE_SCHAR:
4974 int arg = a.arg[dp->arg_index].a.a_schar;
4975 SNPRINTF_BUF (arg);
4977 break;
4978 case TYPE_UCHAR:
4980 unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
4981 SNPRINTF_BUF (arg);
4983 break;
4984 case TYPE_SHORT:
4986 int arg = a.arg[dp->arg_index].a.a_short;
4987 SNPRINTF_BUF (arg);
4989 break;
4990 case TYPE_USHORT:
4992 unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
4993 SNPRINTF_BUF (arg);
4995 break;
4996 case TYPE_INT:
4998 int arg = a.arg[dp->arg_index].a.a_int;
4999 SNPRINTF_BUF (arg);
5001 break;
5002 case TYPE_UINT:
5004 unsigned int arg = a.arg[dp->arg_index].a.a_uint;
5005 SNPRINTF_BUF (arg);
5007 break;
5008 case TYPE_LONGINT:
5010 long int arg = a.arg[dp->arg_index].a.a_longint;
5011 SNPRINTF_BUF (arg);
5013 break;
5014 case TYPE_ULONGINT:
5016 unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
5017 SNPRINTF_BUF (arg);
5019 break;
5020 #if HAVE_LONG_LONG
5021 case TYPE_LONGLONGINT:
5023 long long int arg = a.arg[dp->arg_index].a.a_longlongint;
5024 SNPRINTF_BUF (arg);
5026 break;
5027 case TYPE_ULONGLONGINT:
5029 unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
5030 SNPRINTF_BUF (arg);
5032 break;
5033 #endif
5034 case TYPE_DOUBLE:
5036 double arg = a.arg[dp->arg_index].a.a_double;
5037 SNPRINTF_BUF (arg);
5039 break;
5040 case TYPE_LONGDOUBLE:
5042 long double arg = a.arg[dp->arg_index].a.a_longdouble;
5043 SNPRINTF_BUF (arg);
5045 break;
5046 case TYPE_CHAR:
5048 int arg = a.arg[dp->arg_index].a.a_char;
5049 SNPRINTF_BUF (arg);
5051 break;
5052 #if HAVE_WINT_T
5053 case TYPE_WIDE_CHAR:
5055 wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
5056 SNPRINTF_BUF (arg);
5058 break;
5059 #endif
5060 case TYPE_STRING:
5062 const char *arg = a.arg[dp->arg_index].a.a_string;
5063 SNPRINTF_BUF (arg);
5065 break;
5066 #if HAVE_WCHAR_T
5067 case TYPE_WIDE_STRING:
5069 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
5070 SNPRINTF_BUF (arg);
5072 break;
5073 #endif
5074 case TYPE_POINTER:
5076 void *arg = a.arg[dp->arg_index].a.a_pointer;
5077 SNPRINTF_BUF (arg);
5079 break;
5080 default:
5081 abort ();
5084 #if USE_SNPRINTF
5085 /* Portability: Not all implementations of snprintf()
5086 are ISO C 99 compliant. Determine the number of
5087 bytes that snprintf() has produced or would have
5088 produced. */
5089 if (count >= 0)
5091 /* Verify that snprintf() has NUL-terminated its
5092 result. */
5093 if (count < maxlen
5094 && ((TCHAR_T *) (result + length)) [count] != '\0')
5095 abort ();
5096 /* Portability hack. */
5097 if (retcount > count)
5098 count = retcount;
5100 else
5102 /* snprintf() doesn't understand the '%n'
5103 directive. */
5104 if (fbp[1] != '\0')
5106 /* Don't use the '%n' directive; instead, look
5107 at the snprintf() return value. */
5108 fbp[1] = '\0';
5109 continue;
5111 else
5113 /* Look at the snprintf() return value. */
5114 if (retcount < 0)
5116 # if !HAVE_SNPRINTF_RETVAL_C99
5117 /* HP-UX 10.20 snprintf() is doubly deficient:
5118 It doesn't understand the '%n' directive,
5119 *and* it returns -1 (rather than the length
5120 that would have been required) when the
5121 buffer is too small.
5122 But a failure at this point can also come
5123 from other reasons than a too small buffer,
5124 such as an invalid wide string argument to
5125 the %ls directive, or possibly an invalid
5126 floating-point argument. */
5127 size_t tmp_length =
5128 MAX_ROOM_NEEDED (&a, dp->arg_index,
5129 dp->conversion, type, flags,
5130 width,
5131 has_precision,
5132 precision, pad_ourselves);
5134 if (maxlen < tmp_length)
5136 /* Make more room. But try to do through
5137 this reallocation only once. */
5138 size_t bigger_need =
5139 xsum (length,
5140 xsum (tmp_length,
5141 TCHARS_PER_DCHAR - 1)
5142 / TCHARS_PER_DCHAR);
5143 /* And always grow proportionally.
5144 (There may be several arguments, each
5145 needing a little more room than the
5146 previous one.) */
5147 size_t bigger_need2 =
5148 xsum (xtimes (allocated, 2), 12);
5149 if (bigger_need < bigger_need2)
5150 bigger_need = bigger_need2;
5151 ENSURE_ALLOCATION (bigger_need);
5152 continue;
5154 # endif
5156 else
5157 count = retcount;
5160 #endif
5162 /* Attempt to handle failure. */
5163 if (count < 0)
5165 /* SNPRINTF or sprintf failed. Save and use the errno
5166 that it has set, if any. */
5167 int saved_errno = errno;
5168 if (saved_errno == 0)
5170 if (dp->conversion == 'c' || dp->conversion == 's')
5171 saved_errno = EILSEQ;
5172 else
5173 saved_errno = EINVAL;
5176 if (!(result == resultbuf || result == NULL))
5177 free (result);
5178 if (buf_malloced != NULL)
5179 free (buf_malloced);
5180 CLEANUP ();
5182 errno = saved_errno;
5183 return NULL;
5186 #if USE_SNPRINTF
5187 /* Handle overflow of the allocated buffer.
5188 If such an overflow occurs, a C99 compliant snprintf()
5189 returns a count >= maxlen. However, a non-compliant
5190 snprintf() function returns only count = maxlen - 1. To
5191 cover both cases, test whether count >= maxlen - 1. */
5192 if ((unsigned int) count + 1 >= maxlen)
5194 /* If maxlen already has attained its allowed maximum,
5195 allocating more memory will not increase maxlen.
5196 Instead of looping, bail out. */
5197 if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
5198 goto overflow;
5199 else
5201 /* Need at least (count + 1) * sizeof (TCHAR_T)
5202 bytes. (The +1 is for the trailing NUL.)
5203 But ask for (count + 2) * sizeof (TCHAR_T)
5204 bytes, so that in the next round, we likely get
5205 maxlen > (unsigned int) count + 1
5206 and so we don't get here again.
5207 And allocate proportionally, to avoid looping
5208 eternally if snprintf() reports a too small
5209 count. */
5210 size_t n =
5211 xmax (xsum (length,
5212 ((unsigned int) count + 2
5213 + TCHARS_PER_DCHAR - 1)
5214 / TCHARS_PER_DCHAR),
5215 xtimes (allocated, 2));
5217 ENSURE_ALLOCATION (n);
5218 continue;
5221 #endif
5223 #if NEED_PRINTF_UNBOUNDED_PRECISION
5224 if (prec_ourselves)
5226 /* Handle the precision. */
5227 TCHAR_T *prec_ptr =
5228 # if USE_SNPRINTF
5229 (TCHAR_T *) (result + length);
5230 # else
5231 tmp;
5232 # endif
5233 size_t prefix_count;
5234 size_t move;
5236 prefix_count = 0;
5237 /* Put the additional zeroes after the sign. */
5238 if (count >= 1
5239 && (*prec_ptr == '-' || *prec_ptr == '+'
5240 || *prec_ptr == ' '))
5241 prefix_count = 1;
5242 /* Put the additional zeroes after the 0x prefix if
5243 (flags & FLAG_ALT) || (dp->conversion == 'p'). */
5244 else if (count >= 2
5245 && prec_ptr[0] == '0'
5246 && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
5247 prefix_count = 2;
5249 move = count - prefix_count;
5250 if (precision > move)
5252 /* Insert zeroes. */
5253 size_t insert = precision - move;
5254 TCHAR_T *prec_end;
5256 # if USE_SNPRINTF
5257 size_t n =
5258 xsum (length,
5259 (count + insert + TCHARS_PER_DCHAR - 1)
5260 / TCHARS_PER_DCHAR);
5261 length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5262 ENSURE_ALLOCATION (n);
5263 length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5264 prec_ptr = (TCHAR_T *) (result + length);
5265 # endif
5267 prec_end = prec_ptr + count;
5268 prec_ptr += prefix_count;
5270 while (prec_end > prec_ptr)
5272 prec_end--;
5273 prec_end[insert] = prec_end[0];
5276 prec_end += insert;
5278 *--prec_end = '0';
5279 while (prec_end > prec_ptr);
5281 count += insert;
5284 #endif
5286 #if !USE_SNPRINTF
5287 if (count >= tmp_length)
5288 /* tmp_length was incorrectly calculated - fix the
5289 code above! */
5290 abort ();
5291 #endif
5293 #if !DCHAR_IS_TCHAR
5294 /* Convert from TCHAR_T[] to DCHAR_T[]. */
5295 if (dp->conversion == 'c' || dp->conversion == 's')
5297 /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
5298 TYPE_WIDE_STRING.
5299 The result string is not certainly ASCII. */
5300 const TCHAR_T *tmpsrc;
5301 DCHAR_T *tmpdst;
5302 size_t tmpdst_len;
5303 /* This code assumes that TCHAR_T is 'char'. */
5304 verify (sizeof (TCHAR_T) == 1);
5305 # if USE_SNPRINTF
5306 tmpsrc = (TCHAR_T *) (result + length);
5307 # else
5308 tmpsrc = tmp;
5309 # endif
5310 tmpdst =
5311 DCHAR_CONV_FROM_ENCODING (locale_charset (),
5312 iconveh_question_mark,
5313 tmpsrc, count,
5314 NULL,
5315 NULL, &tmpdst_len);
5316 if (tmpdst == NULL)
5318 int saved_errno = errno;
5319 if (!(result == resultbuf || result == NULL))
5320 free (result);
5321 if (buf_malloced != NULL)
5322 free (buf_malloced);
5323 CLEANUP ();
5324 errno = saved_errno;
5325 return NULL;
5327 ENSURE_ALLOCATION (xsum (length, tmpdst_len));
5328 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
5329 free (tmpdst);
5330 count = tmpdst_len;
5332 else
5334 /* The result string is ASCII.
5335 Simple 1:1 conversion. */
5336 # if USE_SNPRINTF
5337 /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
5338 no-op conversion, in-place on the array starting
5339 at (result + length). */
5340 if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
5341 # endif
5343 const TCHAR_T *tmpsrc;
5344 DCHAR_T *tmpdst;
5345 size_t n;
5347 # if USE_SNPRINTF
5348 if (result == resultbuf)
5350 tmpsrc = (TCHAR_T *) (result + length);
5351 /* ENSURE_ALLOCATION will not move tmpsrc
5352 (because it's part of resultbuf). */
5353 ENSURE_ALLOCATION (xsum (length, count));
5355 else
5357 /* ENSURE_ALLOCATION will move the array
5358 (because it uses realloc(). */
5359 ENSURE_ALLOCATION (xsum (length, count));
5360 tmpsrc = (TCHAR_T *) (result + length);
5362 # else
5363 tmpsrc = tmp;
5364 ENSURE_ALLOCATION (xsum (length, count));
5365 # endif
5366 tmpdst = result + length;
5367 /* Copy backwards, because of overlapping. */
5368 tmpsrc += count;
5369 tmpdst += count;
5370 for (n = count; n > 0; n--)
5371 *--tmpdst = *--tmpsrc;
5374 #endif
5376 #if DCHAR_IS_TCHAR && !USE_SNPRINTF
5377 /* Make room for the result. */
5378 if (count > allocated - length)
5380 /* Need at least count elements. But allocate
5381 proportionally. */
5382 size_t n =
5383 xmax (xsum (length, count), xtimes (allocated, 2));
5385 ENSURE_ALLOCATION (n);
5387 #endif
5389 /* Here count <= allocated - length. */
5391 /* Perform padding. */
5392 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5393 if (pad_ourselves && has_width)
5395 size_t w;
5396 # if ENABLE_UNISTDIO
5397 /* Outside POSIX, it's preferable to compare the width
5398 against the number of _characters_ of the converted
5399 value. */
5400 w = DCHAR_MBSNLEN (result + length, count);
5401 # else
5402 /* The width is compared against the number of _bytes_
5403 of the converted value, says POSIX. */
5404 w = count;
5405 # endif
5406 if (w < width)
5408 size_t pad = width - w;
5410 /* Make room for the result. */
5411 if (xsum (count, pad) > allocated - length)
5413 /* Need at least count + pad elements. But
5414 allocate proportionally. */
5415 size_t n =
5416 xmax (xsum3 (length, count, pad),
5417 xtimes (allocated, 2));
5419 # if USE_SNPRINTF
5420 length += count;
5421 ENSURE_ALLOCATION (n);
5422 length -= count;
5423 # else
5424 ENSURE_ALLOCATION (n);
5425 # endif
5427 /* Here count + pad <= allocated - length. */
5430 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
5431 DCHAR_T * const rp = result + length;
5432 # else
5433 DCHAR_T * const rp = tmp;
5434 # endif
5435 DCHAR_T *p = rp + count;
5436 DCHAR_T *end = p + pad;
5437 DCHAR_T *pad_ptr;
5438 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
5439 if (dp->conversion == 'c'
5440 || dp->conversion == 's')
5441 /* No zero-padding for string directives. */
5442 pad_ptr = NULL;
5443 else
5444 # endif
5446 pad_ptr = (*rp == '-' ? rp + 1 : rp);
5447 /* No zero-padding of "inf" and "nan". */
5448 if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
5449 || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
5450 pad_ptr = NULL;
5452 /* The generated string now extends from rp to p,
5453 with the zero padding insertion point being at
5454 pad_ptr. */
5456 count = count + pad; /* = end - rp */
5458 if (flags & FLAG_LEFT)
5460 /* Pad with spaces on the right. */
5461 for (; pad > 0; pad--)
5462 *p++ = ' ';
5464 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
5466 /* Pad with zeroes. */
5467 DCHAR_T *q = end;
5469 while (p > pad_ptr)
5470 *--q = *--p;
5471 for (; pad > 0; pad--)
5472 *p++ = '0';
5474 else
5476 /* Pad with spaces on the left. */
5477 DCHAR_T *q = end;
5479 while (p > rp)
5480 *--q = *--p;
5481 for (; pad > 0; pad--)
5482 *p++ = ' ';
5487 #endif
5489 /* Here still count <= allocated - length. */
5491 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
5492 /* The snprintf() result did fit. */
5493 #else
5494 /* Append the sprintf() result. */
5495 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
5496 #endif
5497 #if !USE_SNPRINTF
5498 if (tmp != tmpbuf)
5499 free (tmp);
5500 #endif
5502 #if NEED_PRINTF_DIRECTIVE_F
5503 if (dp->conversion == 'F')
5505 /* Convert the %f result to upper case for %F. */
5506 DCHAR_T *rp = result + length;
5507 size_t rc;
5508 for (rc = count; rc > 0; rc--, rp++)
5509 if (*rp >= 'a' && *rp <= 'z')
5510 *rp = *rp - 'a' + 'A';
5512 #endif
5514 length += count;
5515 break;
5517 errno = orig_errno;
5518 #undef pad_ourselves
5519 #undef prec_ourselves
5524 /* Add the final NUL. */
5525 ENSURE_ALLOCATION (xsum (length, 1));
5526 result[length] = '\0';
5528 if (result != resultbuf && length + 1 < allocated)
5530 /* Shrink the allocated memory if possible. */
5531 DCHAR_T *memory;
5533 memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
5534 if (memory != NULL)
5535 result = memory;
5538 if (buf_malloced != NULL)
5539 free (buf_malloced);
5540 CLEANUP ();
5541 *lengthp = length;
5542 /* Note that we can produce a big string of a length > INT_MAX. POSIX
5543 says that snprintf() fails with errno = EOVERFLOW in this case, but
5544 that's only because snprintf() returns an 'int'. This function does
5545 not have this limitation. */
5546 return result;
5548 #if USE_SNPRINTF
5549 overflow:
5550 if (!(result == resultbuf || result == NULL))
5551 free (result);
5552 if (buf_malloced != NULL)
5553 free (buf_malloced);
5554 CLEANUP ();
5555 errno = EOVERFLOW;
5556 return NULL;
5557 #endif
5559 out_of_memory:
5560 if (!(result == resultbuf || result == NULL))
5561 free (result);
5562 if (buf_malloced != NULL)
5563 free (buf_malloced);
5564 out_of_memory_1:
5565 CLEANUP ();
5566 errno = ENOMEM;
5567 return NULL;
5571 #undef MAX_ROOM_NEEDED
5572 #undef TCHARS_PER_DCHAR
5573 #undef SNPRINTF
5574 #undef USE_SNPRINTF
5575 #undef DCHAR_SET
5576 #undef DCHAR_CPY
5577 #undef PRINTF_PARSE
5578 #undef DIRECTIVES
5579 #undef DIRECTIVE
5580 #undef DCHAR_IS_TCHAR
5581 #undef TCHAR_T
5582 #undef DCHAR_T
5583 #undef FCHAR_T
5584 #undef VASNPRINTF