Install gettext-0.18.1.1.tar.gz
[msysgit.git] / mingw / share / gettext / intl / vasnprintf.c
blob8a07ca6e72da1331e3bf1a741aaa6efbf80085ac
1 /* vsprintf with automatic memory allocation.
2 Copyright (C) 1999, 2002-2010 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published
6 by 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 GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
17 USA. */
19 /* This file can be parametrized with the following macros:
20 VASNPRINTF The name of the function being defined.
21 FCHAR_T The element type of the format string.
22 DCHAR_T The element type of the destination (result) string.
23 FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
24 in the format string are ASCII. MUST be set if
25 FCHAR_T and DCHAR_T are not the same type.
26 DIRECTIVE Structure denoting a format directive.
27 Depends on FCHAR_T.
28 DIRECTIVES Structure denoting the set of format directives of a
29 format string. Depends on FCHAR_T.
30 PRINTF_PARSE Function that parses a format string.
31 Depends on FCHAR_T.
32 DCHAR_CPY memcpy like function for DCHAR_T[] arrays.
33 DCHAR_SET memset like function for DCHAR_T[] arrays.
34 DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays.
35 SNPRINTF The system's snprintf (or similar) function.
36 This may be either snprintf or swprintf.
37 TCHAR_T The element type of the argument and result string
38 of the said SNPRINTF function. This may be either
39 char or wchar_t. The code exploits that
40 sizeof (TCHAR_T) | sizeof (DCHAR_T) and
41 alignof (TCHAR_T) <= alignof (DCHAR_T).
42 DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type.
43 DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
44 DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t.
45 DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t.
46 DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */
48 /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
49 This must come before <config.h> because <config.h> may include
50 <features.h>, and once <features.h> has been included, it's too late. */
51 #ifndef _GNU_SOURCE
52 # define _GNU_SOURCE 1
53 #endif
55 #ifndef VASNPRINTF
56 # include <config.h>
57 #endif
58 #ifndef IN_LIBINTL
59 # include <alloca.h>
60 #endif
62 /* Specification. */
63 #ifndef VASNPRINTF
64 # if WIDE_CHAR_VERSION
65 # include "vasnwprintf.h"
66 # else
67 # include "vasnprintf.h"
68 # endif
69 #endif
71 #include <locale.h> /* localeconv() */
72 #include <stdio.h> /* snprintf(), sprintf() */
73 #include <stdlib.h> /* abort(), malloc(), realloc(), free() */
74 #include <string.h> /* memcpy(), strlen() */
75 #include <errno.h> /* errno */
76 #include <limits.h> /* CHAR_BIT */
77 #include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
78 #if HAVE_NL_LANGINFO
79 # include <langinfo.h>
80 #endif
81 #ifndef VASNPRINTF
82 # if WIDE_CHAR_VERSION
83 # include "wprintf-parse.h"
84 # else
85 # include "printf-parse.h"
86 # endif
87 #endif
89 /* Checked size_t computations. */
90 #include "xsize.h"
92 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
93 # include <math.h>
94 # include "float+.h"
95 #endif
97 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
98 # include <math.h>
99 # include "isnand-nolibm.h"
100 #endif
102 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
103 # include <math.h>
104 # include "isnanl-nolibm.h"
105 # include "fpucw.h"
106 #endif
108 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
109 # include <math.h>
110 # include "isnand-nolibm.h"
111 # include "printf-frexp.h"
112 #endif
114 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
115 # include <math.h>
116 # include "isnanl-nolibm.h"
117 # include "printf-frexpl.h"
118 # include "fpucw.h"
119 #endif
121 /* Default parameters. */
122 #ifndef VASNPRINTF
123 # if WIDE_CHAR_VERSION
124 # define VASNPRINTF vasnwprintf
125 # define FCHAR_T wchar_t
126 # define DCHAR_T wchar_t
127 # define TCHAR_T wchar_t
128 # define DCHAR_IS_TCHAR 1
129 # define DIRECTIVE wchar_t_directive
130 # define DIRECTIVES wchar_t_directives
131 # define PRINTF_PARSE wprintf_parse
132 # define DCHAR_CPY wmemcpy
133 # define DCHAR_SET wmemset
134 # else
135 # define VASNPRINTF vasnprintf
136 # define FCHAR_T char
137 # define DCHAR_T char
138 # define TCHAR_T char
139 # define DCHAR_IS_TCHAR 1
140 # define DIRECTIVE char_directive
141 # define DIRECTIVES char_directives
142 # define PRINTF_PARSE printf_parse
143 # define DCHAR_CPY memcpy
144 # define DCHAR_SET memset
145 # endif
146 #endif
147 #if WIDE_CHAR_VERSION
148 /* TCHAR_T is wchar_t. */
149 # define USE_SNPRINTF 1
150 # if HAVE_DECL__SNWPRINTF
151 /* On Windows, the function swprintf() has a different signature than
152 on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
153 instead. The mingw function snwprintf() has fewer bugs than the
154 MSVCRT function _snwprintf(), so prefer that. */
155 # if defined __MINGW32__
156 # define SNPRINTF snwprintf
157 # else
158 # define SNPRINTF _snwprintf
159 # endif
160 # else
161 /* Unix. */
162 # define SNPRINTF swprintf
163 # endif
164 #else
165 /* TCHAR_T is char. */
166 /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
167 But don't use it on BeOS, since BeOS snprintf produces no output if the
168 size argument is >= 0x3000000.
169 Also don't use it on Linux libc5, since there snprintf with size = 1
170 writes any output without bounds, like sprintf. */
171 # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
172 # define USE_SNPRINTF 1
173 # else
174 # define USE_SNPRINTF 0
175 # endif
176 # if HAVE_DECL__SNPRINTF
177 /* Windows. The mingw function snprintf() has fewer bugs than the MSVCRT
178 function _snprintf(), so prefer that. */
179 # if defined __MINGW32__
180 # define SNPRINTF snprintf
181 /* Here we need to call the native snprintf, not rpl_snprintf. */
182 # undef snprintf
183 # else
184 # define SNPRINTF _snprintf
185 # endif
186 # else
187 /* Unix. */
188 # define SNPRINTF snprintf
189 /* Here we need to call the native snprintf, not rpl_snprintf. */
190 # undef snprintf
191 # endif
192 #endif
193 /* Here we need to call the native sprintf, not rpl_sprintf. */
194 #undef sprintf
196 /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
197 warnings in this file. Use -Dlint to suppress them. */
198 #ifdef lint
199 # define IF_LINT(Code) Code
200 #else
201 # define IF_LINT(Code) /* empty */
202 #endif
204 /* Avoid some warnings from "gcc -Wshadow".
205 This file doesn't use the exp() and remainder() functions. */
206 #undef exp
207 #define exp expo
208 #undef remainder
209 #define remainder rem
211 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION
212 # if (HAVE_STRNLEN && !defined _AIX)
213 # define local_strnlen strnlen
214 # else
215 # ifndef local_strnlen_defined
216 # define local_strnlen_defined 1
217 static size_t
218 local_strnlen (const char *string, size_t maxlen)
220 const char *end = memchr (string, '\0', maxlen);
221 return end ? (size_t) (end - string) : maxlen;
223 # endif
224 # endif
225 #endif
227 #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
228 # if HAVE_WCSLEN
229 # define local_wcslen wcslen
230 # else
231 /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
232 a dependency towards this library, here is a local substitute.
233 Define this substitute only once, even if this file is included
234 twice in the same compilation unit. */
235 # ifndef local_wcslen_defined
236 # define local_wcslen_defined 1
237 static size_t
238 local_wcslen (const wchar_t *s)
240 const wchar_t *ptr;
242 for (ptr = s; *ptr != (wchar_t) 0; ptr++)
244 return ptr - s;
246 # endif
247 # endif
248 #endif
250 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
251 # if HAVE_WCSNLEN
252 # define local_wcsnlen wcsnlen
253 # else
254 # ifndef local_wcsnlen_defined
255 # define local_wcsnlen_defined 1
256 static size_t
257 local_wcsnlen (const wchar_t *s, size_t maxlen)
259 const wchar_t *ptr;
261 for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
263 return ptr - s;
265 # endif
266 # endif
267 #endif
269 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
270 /* Determine the decimal-point character according to the current locale. */
271 # ifndef decimal_point_char_defined
272 # define decimal_point_char_defined 1
273 static char
274 decimal_point_char (void)
276 const char *point;
277 /* Determine it in a multithread-safe way. We know nl_langinfo is
278 multithread-safe on glibc systems and MacOS X systems, but is not required
279 to be multithread-safe by POSIX. sprintf(), however, is multithread-safe.
280 localeconv() is rarely multithread-safe. */
281 # if HAVE_NL_LANGINFO && (__GLIBC__ || (defined __APPLE__ && defined __MACH__))
282 point = nl_langinfo (RADIXCHAR);
283 # elif 1
284 char pointbuf[5];
285 sprintf (pointbuf, "%#.0f", 1.0);
286 point = &pointbuf[1];
287 # else
288 point = localeconv () -> decimal_point;
289 # endif
290 /* The decimal point is always a single byte: either '.' or ','. */
291 return (point[0] != '\0' ? point[0] : '.');
293 # endif
294 #endif
296 #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
298 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
299 static int
300 is_infinite_or_zero (double x)
302 return isnand (x) || x + x == x;
305 #endif
307 #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
309 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
310 static int
311 is_infinite_or_zerol (long double x)
313 return isnanl (x) || x + x == x;
316 #endif
318 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
320 /* Converting 'long double' to decimal without rare rounding bugs requires
321 real bignums. We use the naming conventions of GNU gmp, but vastly simpler
322 (and slower) algorithms. */
324 typedef unsigned int mp_limb_t;
325 # define GMP_LIMB_BITS 32
326 typedef int mp_limb_verify[2 * (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS) - 1];
328 typedef unsigned long long mp_twolimb_t;
329 # define GMP_TWOLIMB_BITS 64
330 typedef int mp_twolimb_verify[2 * (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS) - 1];
332 /* Representation of a bignum >= 0. */
333 typedef struct
335 size_t nlimbs;
336 mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */
337 } mpn_t;
339 /* Compute the product of two bignums >= 0.
340 Return the allocated memory in case of success, NULL in case of memory
341 allocation failure. */
342 static void *
343 multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
345 const mp_limb_t *p1;
346 const mp_limb_t *p2;
347 size_t len1;
348 size_t len2;
350 if (src1.nlimbs <= src2.nlimbs)
352 len1 = src1.nlimbs;
353 p1 = src1.limbs;
354 len2 = src2.nlimbs;
355 p2 = src2.limbs;
357 else
359 len1 = src2.nlimbs;
360 p1 = src2.limbs;
361 len2 = src1.nlimbs;
362 p2 = src1.limbs;
364 /* Now 0 <= len1 <= len2. */
365 if (len1 == 0)
367 /* src1 or src2 is zero. */
368 dest->nlimbs = 0;
369 dest->limbs = (mp_limb_t *) malloc (1);
371 else
373 /* Here 1 <= len1 <= len2. */
374 size_t dlen;
375 mp_limb_t *dp;
376 size_t k, i, j;
378 dlen = len1 + len2;
379 dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
380 if (dp == NULL)
381 return NULL;
382 for (k = len2; k > 0; )
383 dp[--k] = 0;
384 for (i = 0; i < len1; i++)
386 mp_limb_t digit1 = p1[i];
387 mp_twolimb_t carry = 0;
388 for (j = 0; j < len2; j++)
390 mp_limb_t digit2 = p2[j];
391 carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
392 carry += dp[i + j];
393 dp[i + j] = (mp_limb_t) carry;
394 carry = carry >> GMP_LIMB_BITS;
396 dp[i + len2] = (mp_limb_t) carry;
398 /* Normalise. */
399 while (dlen > 0 && dp[dlen - 1] == 0)
400 dlen--;
401 dest->nlimbs = dlen;
402 dest->limbs = dp;
404 return dest->limbs;
407 /* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
408 a is written as a = q * b + r with 0 <= r < b. q is the quotient, r
409 the remainder.
410 Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
411 q is incremented.
412 Return the allocated memory in case of success, NULL in case of memory
413 allocation failure. */
414 static void *
415 divide (mpn_t a, mpn_t b, mpn_t *q)
417 /* Algorithm:
418 First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
419 with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
420 If m<n, then q:=0 and r:=a.
421 If m>=n=1, perform a single-precision division:
422 r:=0, j:=m,
423 while j>0 do
424 {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
425 = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
426 j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
427 Normalise [q[m-1],...,q[0]], yields q.
428 If m>=n>1, perform a multiple-precision division:
429 We have a/b < beta^(m-n+1).
430 s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
431 Shift a and b left by s bits, copying them. r:=a.
432 r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
433 For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
434 Compute q* :
435 q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
436 In case of overflow (q* >= beta) set q* := beta-1.
437 Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
438 and c3 := b[n-2] * q*.
439 {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
440 occurred. Furthermore 0 <= c3 < beta^2.
441 If there was overflow and
442 r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
443 the next test can be skipped.}
444 While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
445 Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
446 If q* > 0:
447 Put r := r - b * q* * beta^j. In detail:
448 [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
449 hence: u:=0, for i:=0 to n-1 do
450 u := u + q* * b[i],
451 r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
452 u:=u div beta (+ 1, if carry in subtraction)
453 r[n+j]:=r[n+j]-u.
454 {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
455 < q* + 1 <= beta,
456 the carry u does not overflow.}
457 If a negative carry occurs, put q* := q* - 1
458 and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
459 Set q[j] := q*.
460 Normalise [q[m-n],..,q[0]]; this yields the quotient q.
461 Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
462 rest r.
463 The room for q[j] can be allocated at the memory location of r[n+j].
464 Finally, round-to-even:
465 Shift r left by 1 bit.
466 If r > b or if r = b and q[0] is odd, q := q+1.
468 const mp_limb_t *a_ptr = a.limbs;
469 size_t a_len = a.nlimbs;
470 const mp_limb_t *b_ptr = b.limbs;
471 size_t b_len = b.nlimbs;
472 mp_limb_t *roomptr;
473 mp_limb_t *tmp_roomptr = NULL;
474 mp_limb_t *q_ptr;
475 size_t q_len;
476 mp_limb_t *r_ptr;
477 size_t r_len;
479 /* Allocate room for a_len+2 digits.
480 (Need a_len+1 digits for the real division and 1 more digit for the
481 final rounding of q.) */
482 roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
483 if (roomptr == NULL)
484 return NULL;
486 /* Normalise a. */
487 while (a_len > 0 && a_ptr[a_len - 1] == 0)
488 a_len--;
490 /* Normalise b. */
491 for (;;)
493 if (b_len == 0)
494 /* Division by zero. */
495 abort ();
496 if (b_ptr[b_len - 1] == 0)
497 b_len--;
498 else
499 break;
502 /* Here m = a_len >= 0 and n = b_len > 0. */
504 if (a_len < b_len)
506 /* m<n: trivial case. q=0, r := copy of a. */
507 r_ptr = roomptr;
508 r_len = a_len;
509 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
510 q_ptr = roomptr + a_len;
511 q_len = 0;
513 else if (b_len == 1)
515 /* n=1: single precision division.
516 beta^(m-1) <= a < beta^m ==> beta^(m-2) <= a/b < beta^m */
517 r_ptr = roomptr;
518 q_ptr = roomptr + 1;
520 mp_limb_t den = b_ptr[0];
521 mp_limb_t remainder = 0;
522 const mp_limb_t *sourceptr = a_ptr + a_len;
523 mp_limb_t *destptr = q_ptr + a_len;
524 size_t count;
525 for (count = a_len; count > 0; count--)
527 mp_twolimb_t num =
528 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
529 *--destptr = num / den;
530 remainder = num % den;
532 /* Normalise and store r. */
533 if (remainder > 0)
535 r_ptr[0] = remainder;
536 r_len = 1;
538 else
539 r_len = 0;
540 /* Normalise q. */
541 q_len = a_len;
542 if (q_ptr[q_len - 1] == 0)
543 q_len--;
546 else
548 /* n>1: multiple precision division.
549 beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n ==>
550 beta^(m-n-1) <= a/b < beta^(m-n+1). */
551 /* Determine s. */
552 size_t s;
554 mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
555 s = 31;
556 if (msd >= 0x10000)
558 msd = msd >> 16;
559 s -= 16;
561 if (msd >= 0x100)
563 msd = msd >> 8;
564 s -= 8;
566 if (msd >= 0x10)
568 msd = msd >> 4;
569 s -= 4;
571 if (msd >= 0x4)
573 msd = msd >> 2;
574 s -= 2;
576 if (msd >= 0x2)
578 msd = msd >> 1;
579 s -= 1;
582 /* 0 <= s < GMP_LIMB_BITS.
583 Copy b, shifting it left by s bits. */
584 if (s > 0)
586 tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
587 if (tmp_roomptr == NULL)
589 free (roomptr);
590 return NULL;
593 const mp_limb_t *sourceptr = b_ptr;
594 mp_limb_t *destptr = tmp_roomptr;
595 mp_twolimb_t accu = 0;
596 size_t count;
597 for (count = b_len; count > 0; count--)
599 accu += (mp_twolimb_t) *sourceptr++ << s;
600 *destptr++ = (mp_limb_t) accu;
601 accu = accu >> GMP_LIMB_BITS;
603 /* accu must be zero, since that was how s was determined. */
604 if (accu != 0)
605 abort ();
607 b_ptr = tmp_roomptr;
609 /* Copy a, shifting it left by s bits, yields r.
610 Memory layout:
611 At the beginning: r = roomptr[0..a_len],
612 at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len] */
613 r_ptr = roomptr;
614 if (s == 0)
616 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
617 r_ptr[a_len] = 0;
619 else
621 const mp_limb_t *sourceptr = a_ptr;
622 mp_limb_t *destptr = r_ptr;
623 mp_twolimb_t accu = 0;
624 size_t count;
625 for (count = a_len; count > 0; count--)
627 accu += (mp_twolimb_t) *sourceptr++ << s;
628 *destptr++ = (mp_limb_t) accu;
629 accu = accu >> GMP_LIMB_BITS;
631 *destptr++ = (mp_limb_t) accu;
633 q_ptr = roomptr + b_len;
634 q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
636 size_t j = a_len - b_len; /* m-n */
637 mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
638 mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
639 mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
640 ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
641 /* Division loop, traversed m-n+1 times.
642 j counts down, b is unchanged, beta/2 <= b[n-1] < beta. */
643 for (;;)
645 mp_limb_t q_star;
646 mp_limb_t c1;
647 if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
649 /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow. */
650 mp_twolimb_t num =
651 ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
652 | r_ptr[j + b_len - 1];
653 q_star = num / b_msd;
654 c1 = num % b_msd;
656 else
658 /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1]. */
659 q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
660 /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
661 <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
662 <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
663 {<= beta !}.
664 If yes, jump directly to the subtraction loop.
665 (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
666 <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
667 if (r_ptr[j + b_len] > b_msd
668 || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
669 /* r[j+n] >= b[n-1]+1 or
670 r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
671 carry. */
672 goto subtract;
674 /* q_star = q*,
675 c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta). */
677 mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
678 ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
679 mp_twolimb_t c3 = /* b[n-2] * q* */
680 (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
681 /* While c2 < c3, increase c2 and decrease c3.
682 Consider c3-c2. While it is > 0, decrease it by
683 b[n-1]*beta+b[n-2]. Because of b[n-1]*beta+b[n-2] >= beta^2/2
684 this can happen only twice. */
685 if (c3 > c2)
687 q_star = q_star - 1; /* q* := q* - 1 */
688 if (c3 - c2 > b_msdd)
689 q_star = q_star - 1; /* q* := q* - 1 */
692 if (q_star > 0)
693 subtract:
695 /* Subtract r := r - b * q* * beta^j. */
696 mp_limb_t cr;
698 const mp_limb_t *sourceptr = b_ptr;
699 mp_limb_t *destptr = r_ptr + j;
700 mp_twolimb_t carry = 0;
701 size_t count;
702 for (count = b_len; count > 0; count--)
704 /* Here 0 <= carry <= q*. */
705 carry =
706 carry
707 + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
708 + (mp_limb_t) ~(*destptr);
709 /* Here 0 <= carry <= beta*q* + beta-1. */
710 *destptr++ = ~(mp_limb_t) carry;
711 carry = carry >> GMP_LIMB_BITS; /* <= q* */
713 cr = (mp_limb_t) carry;
715 /* Subtract cr from r_ptr[j + b_len], then forget about
716 r_ptr[j + b_len]. */
717 if (cr > r_ptr[j + b_len])
719 /* Subtraction gave a carry. */
720 q_star = q_star - 1; /* q* := q* - 1 */
721 /* Add b back. */
723 const mp_limb_t *sourceptr = b_ptr;
724 mp_limb_t *destptr = r_ptr + j;
725 mp_limb_t carry = 0;
726 size_t count;
727 for (count = b_len; count > 0; count--)
729 mp_limb_t source1 = *sourceptr++;
730 mp_limb_t source2 = *destptr;
731 *destptr++ = source1 + source2 + carry;
732 carry =
733 (carry
734 ? source1 >= (mp_limb_t) ~source2
735 : source1 > (mp_limb_t) ~source2);
738 /* Forget about the carry and about r[j+n]. */
741 /* q* is determined. Store it as q[j]. */
742 q_ptr[j] = q_star;
743 if (j == 0)
744 break;
745 j--;
748 r_len = b_len;
749 /* Normalise q. */
750 if (q_ptr[q_len - 1] == 0)
751 q_len--;
752 # if 0 /* Not needed here, since we need r only to compare it with b/2, and
753 b is shifted left by s bits. */
754 /* Shift r right by s bits. */
755 if (s > 0)
757 mp_limb_t ptr = r_ptr + r_len;
758 mp_twolimb_t accu = 0;
759 size_t count;
760 for (count = r_len; count > 0; count--)
762 accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
763 accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
764 *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
767 # endif
768 /* Normalise r. */
769 while (r_len > 0 && r_ptr[r_len - 1] == 0)
770 r_len--;
772 /* Compare r << 1 with b. */
773 if (r_len > b_len)
774 goto increment_q;
776 size_t i;
777 for (i = b_len;;)
779 mp_limb_t r_i =
780 (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
781 | (i < r_len ? r_ptr[i] << 1 : 0);
782 mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
783 if (r_i > b_i)
784 goto increment_q;
785 if (r_i < b_i)
786 goto keep_q;
787 if (i == 0)
788 break;
789 i--;
792 if (q_len > 0 && ((q_ptr[0] & 1) != 0))
793 /* q is odd. */
794 increment_q:
796 size_t i;
797 for (i = 0; i < q_len; i++)
798 if (++(q_ptr[i]) != 0)
799 goto keep_q;
800 q_ptr[q_len++] = 1;
802 keep_q:
803 if (tmp_roomptr != NULL)
804 free (tmp_roomptr);
805 q->limbs = q_ptr;
806 q->nlimbs = q_len;
807 return roomptr;
810 /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
811 representation.
812 Destroys the contents of a.
813 Return the allocated memory - containing the decimal digits in low-to-high
814 order, terminated with a NUL character - in case of success, NULL in case
815 of memory allocation failure. */
816 static char *
817 convert_to_decimal (mpn_t a, size_t extra_zeroes)
819 mp_limb_t *a_ptr = a.limbs;
820 size_t a_len = a.nlimbs;
821 /* 0.03345 is slightly larger than log(2)/(9*log(10)). */
822 size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
823 char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes));
824 if (c_ptr != NULL)
826 char *d_ptr = c_ptr;
827 for (; extra_zeroes > 0; extra_zeroes--)
828 *d_ptr++ = '0';
829 while (a_len > 0)
831 /* Divide a by 10^9, in-place. */
832 mp_limb_t remainder = 0;
833 mp_limb_t *ptr = a_ptr + a_len;
834 size_t count;
835 for (count = a_len; count > 0; count--)
837 mp_twolimb_t num =
838 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
839 *ptr = num / 1000000000;
840 remainder = num % 1000000000;
842 /* Store the remainder as 9 decimal digits. */
843 for (count = 9; count > 0; count--)
845 *d_ptr++ = '0' + (remainder % 10);
846 remainder = remainder / 10;
848 /* Normalize a. */
849 if (a_ptr[a_len - 1] == 0)
850 a_len--;
852 /* Remove leading zeroes. */
853 while (d_ptr > c_ptr && d_ptr[-1] == '0')
854 d_ptr--;
855 /* But keep at least one zero. */
856 if (d_ptr == c_ptr)
857 *d_ptr++ = '0';
858 /* Terminate the string. */
859 *d_ptr = '\0';
861 return c_ptr;
864 # if NEED_PRINTF_LONG_DOUBLE
866 /* Assuming x is finite and >= 0:
867 write x as x = 2^e * m, where m is a bignum.
868 Return the allocated memory in case of success, NULL in case of memory
869 allocation failure. */
870 static void *
871 decode_long_double (long double x, int *ep, mpn_t *mp)
873 mpn_t m;
874 int exp;
875 long double y;
876 size_t i;
878 /* Allocate memory for result. */
879 m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
880 m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
881 if (m.limbs == NULL)
882 return NULL;
883 /* Split into exponential part and mantissa. */
884 y = frexpl (x, &exp);
885 if (!(y >= 0.0L && y < 1.0L))
886 abort ();
887 /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * LDBL_MANT_BIT), and the
888 latter is an integer. */
889 /* Convert the mantissa (y * LDBL_MANT_BIT) to a sequence of limbs.
890 I'm not sure whether it's safe to cast a 'long double' value between
891 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
892 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
893 doesn't matter). */
894 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
895 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
897 mp_limb_t hi, lo;
898 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
899 hi = (int) y;
900 y -= hi;
901 if (!(y >= 0.0L && y < 1.0L))
902 abort ();
903 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
904 lo = (int) y;
905 y -= lo;
906 if (!(y >= 0.0L && y < 1.0L))
907 abort ();
908 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
910 # else
912 mp_limb_t d;
913 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
914 d = (int) y;
915 y -= d;
916 if (!(y >= 0.0L && y < 1.0L))
917 abort ();
918 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
920 # endif
921 # endif
922 for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
924 mp_limb_t hi, lo;
925 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
926 hi = (int) y;
927 y -= hi;
928 if (!(y >= 0.0L && y < 1.0L))
929 abort ();
930 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
931 lo = (int) y;
932 y -= lo;
933 if (!(y >= 0.0L && y < 1.0L))
934 abort ();
935 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
937 #if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
938 precision. */
939 if (!(y == 0.0L))
940 abort ();
941 #endif
942 /* Normalise. */
943 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
944 m.nlimbs--;
945 *mp = m;
946 *ep = exp - LDBL_MANT_BIT;
947 return m.limbs;
950 # endif
952 # if NEED_PRINTF_DOUBLE
954 /* Assuming x is finite and >= 0:
955 write x as x = 2^e * m, where m is a bignum.
956 Return the allocated memory in case of success, NULL in case of memory
957 allocation failure. */
958 static void *
959 decode_double (double x, int *ep, mpn_t *mp)
961 mpn_t m;
962 int exp;
963 double y;
964 size_t i;
966 /* Allocate memory for result. */
967 m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
968 m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
969 if (m.limbs == NULL)
970 return NULL;
971 /* Split into exponential part and mantissa. */
972 y = frexp (x, &exp);
973 if (!(y >= 0.0 && y < 1.0))
974 abort ();
975 /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * DBL_MANT_BIT), and the
976 latter is an integer. */
977 /* Convert the mantissa (y * DBL_MANT_BIT) to a sequence of limbs.
978 I'm not sure whether it's safe to cast a 'double' value between
979 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
980 'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
981 doesn't matter). */
982 # if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
983 # if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
985 mp_limb_t hi, lo;
986 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
987 hi = (int) y;
988 y -= hi;
989 if (!(y >= 0.0 && y < 1.0))
990 abort ();
991 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
992 lo = (int) y;
993 y -= lo;
994 if (!(y >= 0.0 && y < 1.0))
995 abort ();
996 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
998 # else
1000 mp_limb_t d;
1001 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
1002 d = (int) y;
1003 y -= d;
1004 if (!(y >= 0.0 && y < 1.0))
1005 abort ();
1006 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
1008 # endif
1009 # endif
1010 for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1012 mp_limb_t hi, lo;
1013 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1014 hi = (int) y;
1015 y -= hi;
1016 if (!(y >= 0.0 && y < 1.0))
1017 abort ();
1018 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1019 lo = (int) y;
1020 y -= lo;
1021 if (!(y >= 0.0 && y < 1.0))
1022 abort ();
1023 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1025 if (!(y == 0.0))
1026 abort ();
1027 /* Normalise. */
1028 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
1029 m.nlimbs--;
1030 *mp = m;
1031 *ep = exp - DBL_MANT_BIT;
1032 return m.limbs;
1035 # endif
1037 /* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
1038 Returns the decimal representation of round (x * 10^n).
1039 Return the allocated memory - containing the decimal digits in low-to-high
1040 order, terminated with a NUL character - in case of success, NULL in case
1041 of memory allocation failure. */
1042 static char *
1043 scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
1045 int s;
1046 size_t extra_zeroes;
1047 unsigned int abs_n;
1048 unsigned int abs_s;
1049 mp_limb_t *pow5_ptr;
1050 size_t pow5_len;
1051 unsigned int s_limbs;
1052 unsigned int s_bits;
1053 mpn_t pow5;
1054 mpn_t z;
1055 void *z_memory;
1056 char *digits;
1058 if (memory == NULL)
1059 return NULL;
1060 /* x = 2^e * m, hence
1061 y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
1062 = round (2^s * 5^n * m). */
1063 s = e + n;
1064 extra_zeroes = 0;
1065 /* Factor out a common power of 10 if possible. */
1066 if (s > 0 && n > 0)
1068 extra_zeroes = (s < n ? s : n);
1069 s -= extra_zeroes;
1070 n -= extra_zeroes;
1072 /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
1073 Before converting to decimal, we need to compute
1074 z = round (2^s * 5^n * m). */
1075 /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
1076 sign. 2.322 is slightly larger than log(5)/log(2). */
1077 abs_n = (n >= 0 ? n : -n);
1078 abs_s = (s >= 0 ? s : -s);
1079 pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
1080 + abs_s / GMP_LIMB_BITS + 1)
1081 * sizeof (mp_limb_t));
1082 if (pow5_ptr == NULL)
1084 free (memory);
1085 return NULL;
1087 /* Initialize with 1. */
1088 pow5_ptr[0] = 1;
1089 pow5_len = 1;
1090 /* Multiply with 5^|n|. */
1091 if (abs_n > 0)
1093 static mp_limb_t const small_pow5[13 + 1] =
1095 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
1096 48828125, 244140625, 1220703125
1098 unsigned int n13;
1099 for (n13 = 0; n13 <= abs_n; n13 += 13)
1101 mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
1102 size_t j;
1103 mp_twolimb_t carry = 0;
1104 for (j = 0; j < pow5_len; j++)
1106 mp_limb_t digit2 = pow5_ptr[j];
1107 carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
1108 pow5_ptr[j] = (mp_limb_t) carry;
1109 carry = carry >> GMP_LIMB_BITS;
1111 if (carry > 0)
1112 pow5_ptr[pow5_len++] = (mp_limb_t) carry;
1115 s_limbs = abs_s / GMP_LIMB_BITS;
1116 s_bits = abs_s % GMP_LIMB_BITS;
1117 if (n >= 0 ? s >= 0 : s <= 0)
1119 /* Multiply with 2^|s|. */
1120 if (s_bits > 0)
1122 mp_limb_t *ptr = pow5_ptr;
1123 mp_twolimb_t accu = 0;
1124 size_t count;
1125 for (count = pow5_len; count > 0; count--)
1127 accu += (mp_twolimb_t) *ptr << s_bits;
1128 *ptr++ = (mp_limb_t) accu;
1129 accu = accu >> GMP_LIMB_BITS;
1131 if (accu > 0)
1133 *ptr = (mp_limb_t) accu;
1134 pow5_len++;
1137 if (s_limbs > 0)
1139 size_t count;
1140 for (count = pow5_len; count > 0;)
1142 count--;
1143 pow5_ptr[s_limbs + count] = pow5_ptr[count];
1145 for (count = s_limbs; count > 0;)
1147 count--;
1148 pow5_ptr[count] = 0;
1150 pow5_len += s_limbs;
1152 pow5.limbs = pow5_ptr;
1153 pow5.nlimbs = pow5_len;
1154 if (n >= 0)
1156 /* Multiply m with pow5. No division needed. */
1157 z_memory = multiply (m, pow5, &z);
1159 else
1161 /* Divide m by pow5 and round. */
1162 z_memory = divide (m, pow5, &z);
1165 else
1167 pow5.limbs = pow5_ptr;
1168 pow5.nlimbs = pow5_len;
1169 if (n >= 0)
1171 /* n >= 0, s < 0.
1172 Multiply m with pow5, then divide by 2^|s|. */
1173 mpn_t numerator;
1174 mpn_t denominator;
1175 void *tmp_memory;
1176 tmp_memory = multiply (m, pow5, &numerator);
1177 if (tmp_memory == NULL)
1179 free (pow5_ptr);
1180 free (memory);
1181 return NULL;
1183 /* Construct 2^|s|. */
1185 mp_limb_t *ptr = pow5_ptr + pow5_len;
1186 size_t i;
1187 for (i = 0; i < s_limbs; i++)
1188 ptr[i] = 0;
1189 ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
1190 denominator.limbs = ptr;
1191 denominator.nlimbs = s_limbs + 1;
1193 z_memory = divide (numerator, denominator, &z);
1194 free (tmp_memory);
1196 else
1198 /* n < 0, s > 0.
1199 Multiply m with 2^s, then divide by pow5. */
1200 mpn_t numerator;
1201 mp_limb_t *num_ptr;
1202 num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
1203 * sizeof (mp_limb_t));
1204 if (num_ptr == NULL)
1206 free (pow5_ptr);
1207 free (memory);
1208 return NULL;
1211 mp_limb_t *destptr = num_ptr;
1213 size_t i;
1214 for (i = 0; i < s_limbs; i++)
1215 *destptr++ = 0;
1217 if (s_bits > 0)
1219 const mp_limb_t *sourceptr = m.limbs;
1220 mp_twolimb_t accu = 0;
1221 size_t count;
1222 for (count = m.nlimbs; count > 0; count--)
1224 accu += (mp_twolimb_t) *sourceptr++ << s_bits;
1225 *destptr++ = (mp_limb_t) accu;
1226 accu = accu >> GMP_LIMB_BITS;
1228 if (accu > 0)
1229 *destptr++ = (mp_limb_t) accu;
1231 else
1233 const mp_limb_t *sourceptr = m.limbs;
1234 size_t count;
1235 for (count = m.nlimbs; count > 0; count--)
1236 *destptr++ = *sourceptr++;
1238 numerator.limbs = num_ptr;
1239 numerator.nlimbs = destptr - num_ptr;
1241 z_memory = divide (numerator, pow5, &z);
1242 free (num_ptr);
1245 free (pow5_ptr);
1246 free (memory);
1248 /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */
1250 if (z_memory == NULL)
1251 return NULL;
1252 digits = convert_to_decimal (z, extra_zeroes);
1253 free (z_memory);
1254 return digits;
1257 # if NEED_PRINTF_LONG_DOUBLE
1259 /* Assuming x is finite and >= 0, and n is an integer:
1260 Returns the decimal representation of round (x * 10^n).
1261 Return the allocated memory - containing the decimal digits in low-to-high
1262 order, terminated with a NUL character - in case of success, NULL in case
1263 of memory allocation failure. */
1264 static char *
1265 scale10_round_decimal_long_double (long double x, int n)
1267 int e IF_LINT(= 0);
1268 mpn_t m;
1269 void *memory = decode_long_double (x, &e, &m);
1270 return scale10_round_decimal_decoded (e, m, memory, n);
1273 # endif
1275 # if NEED_PRINTF_DOUBLE
1277 /* Assuming x is finite and >= 0, and n is an integer:
1278 Returns the decimal representation of round (x * 10^n).
1279 Return the allocated memory - containing the decimal digits in low-to-high
1280 order, terminated with a NUL character - in case of success, NULL in case
1281 of memory allocation failure. */
1282 static char *
1283 scale10_round_decimal_double (double x, int n)
1285 int e IF_LINT(= 0);
1286 mpn_t m;
1287 void *memory = decode_double (x, &e, &m);
1288 return scale10_round_decimal_decoded (e, m, memory, n);
1291 # endif
1293 # if NEED_PRINTF_LONG_DOUBLE
1295 /* Assuming x is finite and > 0:
1296 Return an approximation for n with 10^n <= x < 10^(n+1).
1297 The approximation is usually the right n, but may be off by 1 sometimes. */
1298 static int
1299 floorlog10l (long double x)
1301 int exp;
1302 long double y;
1303 double z;
1304 double l;
1306 /* Split into exponential part and mantissa. */
1307 y = frexpl (x, &exp);
1308 if (!(y >= 0.0L && y < 1.0L))
1309 abort ();
1310 if (y == 0.0L)
1311 return INT_MIN;
1312 if (y < 0.5L)
1314 while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1316 y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1317 exp -= GMP_LIMB_BITS;
1319 if (y < (1.0L / (1 << 16)))
1321 y *= 1.0L * (1 << 16);
1322 exp -= 16;
1324 if (y < (1.0L / (1 << 8)))
1326 y *= 1.0L * (1 << 8);
1327 exp -= 8;
1329 if (y < (1.0L / (1 << 4)))
1331 y *= 1.0L * (1 << 4);
1332 exp -= 4;
1334 if (y < (1.0L / (1 << 2)))
1336 y *= 1.0L * (1 << 2);
1337 exp -= 2;
1339 if (y < (1.0L / (1 << 1)))
1341 y *= 1.0L * (1 << 1);
1342 exp -= 1;
1345 if (!(y >= 0.5L && y < 1.0L))
1346 abort ();
1347 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1348 l = exp;
1349 z = y;
1350 if (z < 0.70710678118654752444)
1352 z *= 1.4142135623730950488;
1353 l -= 0.5;
1355 if (z < 0.8408964152537145431)
1357 z *= 1.1892071150027210667;
1358 l -= 0.25;
1360 if (z < 0.91700404320467123175)
1362 z *= 1.0905077326652576592;
1363 l -= 0.125;
1365 if (z < 0.9576032806985736469)
1367 z *= 1.0442737824274138403;
1368 l -= 0.0625;
1370 /* Now 0.95 <= z <= 1.01. */
1371 z = 1 - z;
1372 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1373 Four terms are enough to get an approximation with error < 10^-7. */
1374 l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1375 /* Finally multiply with log(2)/log(10), yields an approximation for
1376 log10(x). */
1377 l *= 0.30102999566398119523;
1378 /* Round down to the next integer. */
1379 return (int) l + (l < 0 ? -1 : 0);
1382 # endif
1384 # if NEED_PRINTF_DOUBLE
1386 /* Assuming x is finite and > 0:
1387 Return an approximation for n with 10^n <= x < 10^(n+1).
1388 The approximation is usually the right n, but may be off by 1 sometimes. */
1389 static int
1390 floorlog10 (double x)
1392 int exp;
1393 double y;
1394 double z;
1395 double l;
1397 /* Split into exponential part and mantissa. */
1398 y = frexp (x, &exp);
1399 if (!(y >= 0.0 && y < 1.0))
1400 abort ();
1401 if (y == 0.0)
1402 return INT_MIN;
1403 if (y < 0.5)
1405 while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1407 y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1408 exp -= GMP_LIMB_BITS;
1410 if (y < (1.0 / (1 << 16)))
1412 y *= 1.0 * (1 << 16);
1413 exp -= 16;
1415 if (y < (1.0 / (1 << 8)))
1417 y *= 1.0 * (1 << 8);
1418 exp -= 8;
1420 if (y < (1.0 / (1 << 4)))
1422 y *= 1.0 * (1 << 4);
1423 exp -= 4;
1425 if (y < (1.0 / (1 << 2)))
1427 y *= 1.0 * (1 << 2);
1428 exp -= 2;
1430 if (y < (1.0 / (1 << 1)))
1432 y *= 1.0 * (1 << 1);
1433 exp -= 1;
1436 if (!(y >= 0.5 && y < 1.0))
1437 abort ();
1438 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1439 l = exp;
1440 z = y;
1441 if (z < 0.70710678118654752444)
1443 z *= 1.4142135623730950488;
1444 l -= 0.5;
1446 if (z < 0.8408964152537145431)
1448 z *= 1.1892071150027210667;
1449 l -= 0.25;
1451 if (z < 0.91700404320467123175)
1453 z *= 1.0905077326652576592;
1454 l -= 0.125;
1456 if (z < 0.9576032806985736469)
1458 z *= 1.0442737824274138403;
1459 l -= 0.0625;
1461 /* Now 0.95 <= z <= 1.01. */
1462 z = 1 - z;
1463 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1464 Four terms are enough to get an approximation with error < 10^-7. */
1465 l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1466 /* Finally multiply with log(2)/log(10), yields an approximation for
1467 log10(x). */
1468 l *= 0.30102999566398119523;
1469 /* Round down to the next integer. */
1470 return (int) l + (l < 0 ? -1 : 0);
1473 # endif
1475 /* Tests whether a string of digits consists of exactly PRECISION zeroes and
1476 a single '1' digit. */
1477 static int
1478 is_borderline (const char *digits, size_t precision)
1480 for (; precision > 0; precision--, digits++)
1481 if (*digits != '0')
1482 return 0;
1483 if (*digits != '1')
1484 return 0;
1485 digits++;
1486 return *digits == '\0';
1489 #endif
1491 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99
1493 /* Use a different function name, to make it possible that the 'wchar_t'
1494 parametrization and the 'char' parametrization get compiled in the same
1495 translation unit. */
1496 # if WIDE_CHAR_VERSION
1497 # define MAX_ROOM_NEEDED wmax_room_needed
1498 # else
1499 # define MAX_ROOM_NEEDED max_room_needed
1500 # endif
1502 /* Returns the number of TCHAR_T units needed as temporary space for the result
1503 of sprintf or SNPRINTF of a single conversion directive. */
1504 static inline size_t
1505 MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
1506 arg_type type, int flags, size_t width, int has_precision,
1507 size_t precision, int pad_ourselves)
1509 size_t tmp_length;
1511 switch (conversion)
1513 case 'd': case 'i': case 'u':
1514 # if HAVE_LONG_LONG_INT
1515 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1516 tmp_length =
1517 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1518 * 0.30103 /* binary -> decimal */
1520 + 1; /* turn floor into ceil */
1521 else
1522 # endif
1523 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1524 tmp_length =
1525 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1526 * 0.30103 /* binary -> decimal */
1528 + 1; /* turn floor into ceil */
1529 else
1530 tmp_length =
1531 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1532 * 0.30103 /* binary -> decimal */
1534 + 1; /* turn floor into ceil */
1535 if (tmp_length < precision)
1536 tmp_length = precision;
1537 /* Multiply by 2, as an estimate for FLAG_GROUP. */
1538 tmp_length = xsum (tmp_length, tmp_length);
1539 /* Add 1, to account for a leading sign. */
1540 tmp_length = xsum (tmp_length, 1);
1541 break;
1543 case 'o':
1544 # if HAVE_LONG_LONG_INT
1545 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1546 tmp_length =
1547 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1548 * 0.333334 /* binary -> octal */
1550 + 1; /* turn floor into ceil */
1551 else
1552 # endif
1553 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1554 tmp_length =
1555 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1556 * 0.333334 /* binary -> octal */
1558 + 1; /* turn floor into ceil */
1559 else
1560 tmp_length =
1561 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1562 * 0.333334 /* binary -> octal */
1564 + 1; /* turn floor into ceil */
1565 if (tmp_length < precision)
1566 tmp_length = precision;
1567 /* Add 1, to account for a leading sign. */
1568 tmp_length = xsum (tmp_length, 1);
1569 break;
1571 case 'x': case 'X':
1572 # if HAVE_LONG_LONG_INT
1573 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1574 tmp_length =
1575 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1576 * 0.25 /* binary -> hexadecimal */
1578 + 1; /* turn floor into ceil */
1579 else
1580 # endif
1581 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1582 tmp_length =
1583 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1584 * 0.25 /* binary -> hexadecimal */
1586 + 1; /* turn floor into ceil */
1587 else
1588 tmp_length =
1589 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1590 * 0.25 /* binary -> hexadecimal */
1592 + 1; /* turn floor into ceil */
1593 if (tmp_length < precision)
1594 tmp_length = precision;
1595 /* Add 2, to account for a leading sign or alternate form. */
1596 tmp_length = xsum (tmp_length, 2);
1597 break;
1599 case 'f': case 'F':
1600 if (type == TYPE_LONGDOUBLE)
1601 tmp_length =
1602 (unsigned int) (LDBL_MAX_EXP
1603 * 0.30103 /* binary -> decimal */
1604 * 2 /* estimate for FLAG_GROUP */
1606 + 1 /* turn floor into ceil */
1607 + 10; /* sign, decimal point etc. */
1608 else
1609 tmp_length =
1610 (unsigned int) (DBL_MAX_EXP
1611 * 0.30103 /* binary -> decimal */
1612 * 2 /* estimate for FLAG_GROUP */
1614 + 1 /* turn floor into ceil */
1615 + 10; /* sign, decimal point etc. */
1616 tmp_length = xsum (tmp_length, precision);
1617 break;
1619 case 'e': case 'E': case 'g': case 'G':
1620 tmp_length =
1621 12; /* sign, decimal point, exponent etc. */
1622 tmp_length = xsum (tmp_length, precision);
1623 break;
1625 case 'a': case 'A':
1626 if (type == TYPE_LONGDOUBLE)
1627 tmp_length =
1628 (unsigned int) (LDBL_DIG
1629 * 0.831 /* decimal -> hexadecimal */
1631 + 1; /* turn floor into ceil */
1632 else
1633 tmp_length =
1634 (unsigned int) (DBL_DIG
1635 * 0.831 /* decimal -> hexadecimal */
1637 + 1; /* turn floor into ceil */
1638 if (tmp_length < precision)
1639 tmp_length = precision;
1640 /* Account for sign, decimal point etc. */
1641 tmp_length = xsum (tmp_length, 12);
1642 break;
1644 case 'c':
1645 # if HAVE_WINT_T && !WIDE_CHAR_VERSION
1646 if (type == TYPE_WIDE_CHAR)
1647 tmp_length = MB_CUR_MAX;
1648 else
1649 # endif
1650 tmp_length = 1;
1651 break;
1653 case 's':
1654 # if HAVE_WCHAR_T
1655 if (type == TYPE_WIDE_STRING)
1657 # if WIDE_CHAR_VERSION
1658 /* ISO C says about %ls in fwprintf:
1659 "If the precision is not specified or is greater than the size
1660 of the array, the array shall contain a null wide character."
1661 So if there is a precision, we must not use wcslen. */
1662 const wchar_t *arg = ap->arg[arg_index].a.a_wide_string;
1664 if (has_precision)
1665 tmp_length = local_wcsnlen (arg, precision);
1666 else
1667 tmp_length = local_wcslen (arg);
1668 # else
1669 /* ISO C says about %ls in fprintf:
1670 "If a precision is specified, no more than that many bytes are
1671 written (including shift sequences, if any), and the array
1672 shall contain a null wide character if, to equal the multibyte
1673 character sequence length given by the precision, the function
1674 would need to access a wide character one past the end of the
1675 array."
1676 So if there is a precision, we must not use wcslen. */
1677 /* This case has already been handled separately in VASNPRINTF. */
1678 abort ();
1679 # endif
1681 else
1682 # endif
1684 # if WIDE_CHAR_VERSION
1685 /* ISO C says about %s in fwprintf:
1686 "If the precision is not specified or is greater than the size
1687 of the converted array, the converted array shall contain a
1688 null wide character."
1689 So if there is a precision, we must not use strlen. */
1690 /* This case has already been handled separately in VASNPRINTF. */
1691 abort ();
1692 # else
1693 /* ISO C says about %s in fprintf:
1694 "If the precision is not specified or greater than the size of
1695 the array, the array shall contain a null character."
1696 So if there is a precision, we must not use strlen. */
1697 const char *arg = ap->arg[arg_index].a.a_string;
1699 if (has_precision)
1700 tmp_length = local_strnlen (arg, precision);
1701 else
1702 tmp_length = strlen (arg);
1703 # endif
1705 break;
1707 case 'p':
1708 tmp_length =
1709 (unsigned int) (sizeof (void *) * CHAR_BIT
1710 * 0.25 /* binary -> hexadecimal */
1712 + 1 /* turn floor into ceil */
1713 + 2; /* account for leading 0x */
1714 break;
1716 default:
1717 abort ();
1720 if (!pad_ourselves)
1722 # if ENABLE_UNISTDIO
1723 /* Padding considers the number of characters, therefore the number of
1724 elements after padding may be
1725 > max (tmp_length, width)
1726 but is certainly
1727 <= tmp_length + width. */
1728 tmp_length = xsum (tmp_length, width);
1729 # else
1730 /* Padding considers the number of elements, says POSIX. */
1731 if (tmp_length < width)
1732 tmp_length = width;
1733 # endif
1736 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
1738 return tmp_length;
1741 #endif
1743 DCHAR_T *
1744 VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
1745 const FCHAR_T *format, va_list args)
1747 DIRECTIVES d;
1748 arguments a;
1750 if (PRINTF_PARSE (format, &d, &a) < 0)
1751 /* errno is already set. */
1752 return NULL;
1754 #define CLEANUP() \
1755 free (d.dir); \
1756 if (a.arg) \
1757 free (a.arg);
1759 if (PRINTF_FETCHARGS (args, &a) < 0)
1761 CLEANUP ();
1762 errno = EINVAL;
1763 return NULL;
1767 size_t buf_neededlength;
1768 TCHAR_T *buf;
1769 TCHAR_T *buf_malloced;
1770 const FCHAR_T *cp;
1771 size_t i;
1772 DIRECTIVE *dp;
1773 /* Output string accumulator. */
1774 DCHAR_T *result;
1775 size_t allocated;
1776 size_t length;
1778 /* Allocate a small buffer that will hold a directive passed to
1779 sprintf or snprintf. */
1780 buf_neededlength =
1781 xsum4 (7, d.max_width_length, d.max_precision_length, 6);
1782 #if HAVE_ALLOCA
1783 if (buf_neededlength < 4000 / sizeof (TCHAR_T))
1785 buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
1786 buf_malloced = NULL;
1788 else
1789 #endif
1791 size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
1792 if (size_overflow_p (buf_memsize))
1793 goto out_of_memory_1;
1794 buf = (TCHAR_T *) malloc (buf_memsize);
1795 if (buf == NULL)
1796 goto out_of_memory_1;
1797 buf_malloced = buf;
1800 if (resultbuf != NULL)
1802 result = resultbuf;
1803 allocated = *lengthp;
1805 else
1807 result = NULL;
1808 allocated = 0;
1810 length = 0;
1811 /* Invariants:
1812 result is either == resultbuf or == NULL or malloc-allocated.
1813 If length > 0, then result != NULL. */
1815 /* Ensures that allocated >= needed. Aborts through a jump to
1816 out_of_memory if needed is SIZE_MAX or otherwise too big. */
1817 #define ENSURE_ALLOCATION(needed) \
1818 if ((needed) > allocated) \
1820 size_t memory_size; \
1821 DCHAR_T *memory; \
1823 allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \
1824 if ((needed) > allocated) \
1825 allocated = (needed); \
1826 memory_size = xtimes (allocated, sizeof (DCHAR_T)); \
1827 if (size_overflow_p (memory_size)) \
1828 goto out_of_memory; \
1829 if (result == resultbuf || result == NULL) \
1830 memory = (DCHAR_T *) malloc (memory_size); \
1831 else \
1832 memory = (DCHAR_T *) realloc (result, memory_size); \
1833 if (memory == NULL) \
1834 goto out_of_memory; \
1835 if (result == resultbuf && length > 0) \
1836 DCHAR_CPY (memory, result, length); \
1837 result = memory; \
1840 for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
1842 if (cp != dp->dir_start)
1844 size_t n = dp->dir_start - cp;
1845 size_t augmented_length = xsum (length, n);
1847 ENSURE_ALLOCATION (augmented_length);
1848 /* This copies a piece of FCHAR_T[] into a DCHAR_T[]. Here we
1849 need that the format string contains only ASCII characters
1850 if FCHAR_T and DCHAR_T are not the same type. */
1851 if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
1853 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
1854 length = augmented_length;
1856 else
1859 result[length++] = (unsigned char) *cp++;
1860 while (--n > 0);
1863 if (i == d.count)
1864 break;
1866 /* Execute a single directive. */
1867 if (dp->conversion == '%')
1869 size_t augmented_length;
1871 if (!(dp->arg_index == ARG_NONE))
1872 abort ();
1873 augmented_length = xsum (length, 1);
1874 ENSURE_ALLOCATION (augmented_length);
1875 result[length] = '%';
1876 length = augmented_length;
1878 else
1880 if (!(dp->arg_index != ARG_NONE))
1881 abort ();
1883 if (dp->conversion == 'n')
1885 switch (a.arg[dp->arg_index].type)
1887 case TYPE_COUNT_SCHAR_POINTER:
1888 *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
1889 break;
1890 case TYPE_COUNT_SHORT_POINTER:
1891 *a.arg[dp->arg_index].a.a_count_short_pointer = length;
1892 break;
1893 case TYPE_COUNT_INT_POINTER:
1894 *a.arg[dp->arg_index].a.a_count_int_pointer = length;
1895 break;
1896 case TYPE_COUNT_LONGINT_POINTER:
1897 *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
1898 break;
1899 #if HAVE_LONG_LONG_INT
1900 case TYPE_COUNT_LONGLONGINT_POINTER:
1901 *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
1902 break;
1903 #endif
1904 default:
1905 abort ();
1908 #if ENABLE_UNISTDIO
1909 /* The unistdio extensions. */
1910 else if (dp->conversion == 'U')
1912 arg_type type = a.arg[dp->arg_index].type;
1913 int flags = dp->flags;
1914 int has_width;
1915 size_t width;
1916 int has_precision;
1917 size_t precision;
1919 has_width = 0;
1920 width = 0;
1921 if (dp->width_start != dp->width_end)
1923 if (dp->width_arg_index != ARG_NONE)
1925 int arg;
1927 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
1928 abort ();
1929 arg = a.arg[dp->width_arg_index].a.a_int;
1930 if (arg < 0)
1932 /* "A negative field width is taken as a '-' flag
1933 followed by a positive field width." */
1934 flags |= FLAG_LEFT;
1935 width = (unsigned int) (-arg);
1937 else
1938 width = arg;
1940 else
1942 const FCHAR_T *digitp = dp->width_start;
1945 width = xsum (xtimes (width, 10), *digitp++ - '0');
1946 while (digitp != dp->width_end);
1948 has_width = 1;
1951 has_precision = 0;
1952 precision = 0;
1953 if (dp->precision_start != dp->precision_end)
1955 if (dp->precision_arg_index != ARG_NONE)
1957 int arg;
1959 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1960 abort ();
1961 arg = a.arg[dp->precision_arg_index].a.a_int;
1962 /* "A negative precision is taken as if the precision
1963 were omitted." */
1964 if (arg >= 0)
1966 precision = arg;
1967 has_precision = 1;
1970 else
1972 const FCHAR_T *digitp = dp->precision_start + 1;
1974 precision = 0;
1975 while (digitp != dp->precision_end)
1976 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
1977 has_precision = 1;
1981 switch (type)
1983 case TYPE_U8_STRING:
1985 const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
1986 const uint8_t *arg_end;
1987 size_t characters;
1989 if (has_precision)
1991 /* Use only PRECISION characters, from the left. */
1992 arg_end = arg;
1993 characters = 0;
1994 for (; precision > 0; precision--)
1996 int count = u8_strmblen (arg_end);
1997 if (count == 0)
1998 break;
1999 if (count < 0)
2001 if (!(result == resultbuf || result == NULL))
2002 free (result);
2003 if (buf_malloced != NULL)
2004 free (buf_malloced);
2005 CLEANUP ();
2006 errno = EILSEQ;
2007 return NULL;
2009 arg_end += count;
2010 characters++;
2013 else if (has_width)
2015 /* Use the entire string, and count the number of
2016 characters. */
2017 arg_end = arg;
2018 characters = 0;
2019 for (;;)
2021 int count = u8_strmblen (arg_end);
2022 if (count == 0)
2023 break;
2024 if (count < 0)
2026 if (!(result == resultbuf || result == NULL))
2027 free (result);
2028 if (buf_malloced != NULL)
2029 free (buf_malloced);
2030 CLEANUP ();
2031 errno = EILSEQ;
2032 return NULL;
2034 arg_end += count;
2035 characters++;
2038 else
2040 /* Use the entire string. */
2041 arg_end = arg + u8_strlen (arg);
2042 /* The number of characters doesn't matter. */
2043 characters = 0;
2046 if (has_width && width > characters
2047 && !(dp->flags & FLAG_LEFT))
2049 size_t n = width - characters;
2050 ENSURE_ALLOCATION (xsum (length, n));
2051 DCHAR_SET (result + length, ' ', n);
2052 length += n;
2055 # if DCHAR_IS_UINT8_T
2057 size_t n = arg_end - arg;
2058 ENSURE_ALLOCATION (xsum (length, n));
2059 DCHAR_CPY (result + length, arg, n);
2060 length += n;
2062 # else
2063 { /* Convert. */
2064 DCHAR_T *converted = result + length;
2065 size_t converted_len = allocated - length;
2066 # if DCHAR_IS_TCHAR
2067 /* Convert from UTF-8 to locale encoding. */
2068 converted =
2069 u8_conv_to_encoding (locale_charset (),
2070 iconveh_question_mark,
2071 arg, arg_end - arg, NULL,
2072 converted, &converted_len);
2073 # else
2074 /* Convert from UTF-8 to UTF-16/UTF-32. */
2075 converted =
2076 U8_TO_DCHAR (arg, arg_end - arg,
2077 converted, &converted_len);
2078 # endif
2079 if (converted == NULL)
2081 int saved_errno = errno;
2082 if (!(result == resultbuf || result == NULL))
2083 free (result);
2084 if (buf_malloced != NULL)
2085 free (buf_malloced);
2086 CLEANUP ();
2087 errno = saved_errno;
2088 return NULL;
2090 if (converted != result + length)
2092 ENSURE_ALLOCATION (xsum (length, converted_len));
2093 DCHAR_CPY (result + length, converted, converted_len);
2094 free (converted);
2096 length += converted_len;
2098 # endif
2100 if (has_width && width > characters
2101 && (dp->flags & FLAG_LEFT))
2103 size_t n = width - characters;
2104 ENSURE_ALLOCATION (xsum (length, n));
2105 DCHAR_SET (result + length, ' ', n);
2106 length += n;
2109 break;
2111 case TYPE_U16_STRING:
2113 const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
2114 const uint16_t *arg_end;
2115 size_t characters;
2117 if (has_precision)
2119 /* Use only PRECISION characters, from the left. */
2120 arg_end = arg;
2121 characters = 0;
2122 for (; precision > 0; precision--)
2124 int count = u16_strmblen (arg_end);
2125 if (count == 0)
2126 break;
2127 if (count < 0)
2129 if (!(result == resultbuf || result == NULL))
2130 free (result);
2131 if (buf_malloced != NULL)
2132 free (buf_malloced);
2133 CLEANUP ();
2134 errno = EILSEQ;
2135 return NULL;
2137 arg_end += count;
2138 characters++;
2141 else if (has_width)
2143 /* Use the entire string, and count the number of
2144 characters. */
2145 arg_end = arg;
2146 characters = 0;
2147 for (;;)
2149 int count = u16_strmblen (arg_end);
2150 if (count == 0)
2151 break;
2152 if (count < 0)
2154 if (!(result == resultbuf || result == NULL))
2155 free (result);
2156 if (buf_malloced != NULL)
2157 free (buf_malloced);
2158 CLEANUP ();
2159 errno = EILSEQ;
2160 return NULL;
2162 arg_end += count;
2163 characters++;
2166 else
2168 /* Use the entire string. */
2169 arg_end = arg + u16_strlen (arg);
2170 /* The number of characters doesn't matter. */
2171 characters = 0;
2174 if (has_width && width > characters
2175 && !(dp->flags & FLAG_LEFT))
2177 size_t n = width - characters;
2178 ENSURE_ALLOCATION (xsum (length, n));
2179 DCHAR_SET (result + length, ' ', n);
2180 length += n;
2183 # if DCHAR_IS_UINT16_T
2185 size_t n = arg_end - arg;
2186 ENSURE_ALLOCATION (xsum (length, n));
2187 DCHAR_CPY (result + length, arg, n);
2188 length += n;
2190 # else
2191 { /* Convert. */
2192 DCHAR_T *converted = result + length;
2193 size_t converted_len = allocated - length;
2194 # if DCHAR_IS_TCHAR
2195 /* Convert from UTF-16 to locale encoding. */
2196 converted =
2197 u16_conv_to_encoding (locale_charset (),
2198 iconveh_question_mark,
2199 arg, arg_end - arg, NULL,
2200 converted, &converted_len);
2201 # else
2202 /* Convert from UTF-16 to UTF-8/UTF-32. */
2203 converted =
2204 U16_TO_DCHAR (arg, arg_end - arg,
2205 converted, &converted_len);
2206 # endif
2207 if (converted == NULL)
2209 int saved_errno = errno;
2210 if (!(result == resultbuf || result == NULL))
2211 free (result);
2212 if (buf_malloced != NULL)
2213 free (buf_malloced);
2214 CLEANUP ();
2215 errno = saved_errno;
2216 return NULL;
2218 if (converted != result + length)
2220 ENSURE_ALLOCATION (xsum (length, converted_len));
2221 DCHAR_CPY (result + length, converted, converted_len);
2222 free (converted);
2224 length += converted_len;
2226 # endif
2228 if (has_width && width > characters
2229 && (dp->flags & FLAG_LEFT))
2231 size_t n = width - characters;
2232 ENSURE_ALLOCATION (xsum (length, n));
2233 DCHAR_SET (result + length, ' ', n);
2234 length += n;
2237 break;
2239 case TYPE_U32_STRING:
2241 const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
2242 const uint32_t *arg_end;
2243 size_t characters;
2245 if (has_precision)
2247 /* Use only PRECISION characters, from the left. */
2248 arg_end = arg;
2249 characters = 0;
2250 for (; precision > 0; precision--)
2252 int count = u32_strmblen (arg_end);
2253 if (count == 0)
2254 break;
2255 if (count < 0)
2257 if (!(result == resultbuf || result == NULL))
2258 free (result);
2259 if (buf_malloced != NULL)
2260 free (buf_malloced);
2261 CLEANUP ();
2262 errno = EILSEQ;
2263 return NULL;
2265 arg_end += count;
2266 characters++;
2269 else if (has_width)
2271 /* Use the entire string, and count the number of
2272 characters. */
2273 arg_end = arg;
2274 characters = 0;
2275 for (;;)
2277 int count = u32_strmblen (arg_end);
2278 if (count == 0)
2279 break;
2280 if (count < 0)
2282 if (!(result == resultbuf || result == NULL))
2283 free (result);
2284 if (buf_malloced != NULL)
2285 free (buf_malloced);
2286 CLEANUP ();
2287 errno = EILSEQ;
2288 return NULL;
2290 arg_end += count;
2291 characters++;
2294 else
2296 /* Use the entire string. */
2297 arg_end = arg + u32_strlen (arg);
2298 /* The number of characters doesn't matter. */
2299 characters = 0;
2302 if (has_width && width > characters
2303 && !(dp->flags & FLAG_LEFT))
2305 size_t n = width - characters;
2306 ENSURE_ALLOCATION (xsum (length, n));
2307 DCHAR_SET (result + length, ' ', n);
2308 length += n;
2311 # if DCHAR_IS_UINT32_T
2313 size_t n = arg_end - arg;
2314 ENSURE_ALLOCATION (xsum (length, n));
2315 DCHAR_CPY (result + length, arg, n);
2316 length += n;
2318 # else
2319 { /* Convert. */
2320 DCHAR_T *converted = result + length;
2321 size_t converted_len = allocated - length;
2322 # if DCHAR_IS_TCHAR
2323 /* Convert from UTF-32 to locale encoding. */
2324 converted =
2325 u32_conv_to_encoding (locale_charset (),
2326 iconveh_question_mark,
2327 arg, arg_end - arg, NULL,
2328 converted, &converted_len);
2329 # else
2330 /* Convert from UTF-32 to UTF-8/UTF-16. */
2331 converted =
2332 U32_TO_DCHAR (arg, arg_end - arg,
2333 converted, &converted_len);
2334 # endif
2335 if (converted == NULL)
2337 int saved_errno = errno;
2338 if (!(result == resultbuf || result == NULL))
2339 free (result);
2340 if (buf_malloced != NULL)
2341 free (buf_malloced);
2342 CLEANUP ();
2343 errno = saved_errno;
2344 return NULL;
2346 if (converted != result + length)
2348 ENSURE_ALLOCATION (xsum (length, converted_len));
2349 DCHAR_CPY (result + length, converted, converted_len);
2350 free (converted);
2352 length += converted_len;
2354 # endif
2356 if (has_width && width > characters
2357 && (dp->flags & FLAG_LEFT))
2359 size_t n = width - characters;
2360 ENSURE_ALLOCATION (xsum (length, n));
2361 DCHAR_SET (result + length, ' ', n);
2362 length += n;
2365 break;
2367 default:
2368 abort ();
2371 #endif
2372 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
2373 else if (dp->conversion == 's'
2374 # if WIDE_CHAR_VERSION
2375 && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
2376 # else
2377 && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
2378 # endif
2381 /* The normal handling of the 's' directive below requires
2382 allocating a temporary buffer. The determination of its
2383 length (tmp_length), in the case when a precision is
2384 specified, below requires a conversion between a char[]
2385 string and a wchar_t[] wide string. It could be done, but
2386 we have no guarantee that the implementation of sprintf will
2387 use the exactly same algorithm. Without this guarantee, it
2388 is possible to have buffer overrun bugs. In order to avoid
2389 such bugs, we implement the entire processing of the 's'
2390 directive ourselves. */
2391 int flags = dp->flags;
2392 int has_width;
2393 size_t width;
2394 int has_precision;
2395 size_t precision;
2397 has_width = 0;
2398 width = 0;
2399 if (dp->width_start != dp->width_end)
2401 if (dp->width_arg_index != ARG_NONE)
2403 int arg;
2405 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2406 abort ();
2407 arg = a.arg[dp->width_arg_index].a.a_int;
2408 if (arg < 0)
2410 /* "A negative field width is taken as a '-' flag
2411 followed by a positive field width." */
2412 flags |= FLAG_LEFT;
2413 width = (unsigned int) (-arg);
2415 else
2416 width = arg;
2418 else
2420 const FCHAR_T *digitp = dp->width_start;
2423 width = xsum (xtimes (width, 10), *digitp++ - '0');
2424 while (digitp != dp->width_end);
2426 has_width = 1;
2429 has_precision = 0;
2430 precision = 6;
2431 if (dp->precision_start != dp->precision_end)
2433 if (dp->precision_arg_index != ARG_NONE)
2435 int arg;
2437 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2438 abort ();
2439 arg = a.arg[dp->precision_arg_index].a.a_int;
2440 /* "A negative precision is taken as if the precision
2441 were omitted." */
2442 if (arg >= 0)
2444 precision = arg;
2445 has_precision = 1;
2448 else
2450 const FCHAR_T *digitp = dp->precision_start + 1;
2452 precision = 0;
2453 while (digitp != dp->precision_end)
2454 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2455 has_precision = 1;
2459 # if WIDE_CHAR_VERSION
2460 /* %s in vasnwprintf. See the specification of fwprintf. */
2462 const char *arg = a.arg[dp->arg_index].a.a_string;
2463 const char *arg_end;
2464 size_t characters;
2466 if (has_precision)
2468 /* Use only as many bytes as needed to produce PRECISION
2469 wide characters, from the left. */
2470 # if HAVE_MBRTOWC
2471 mbstate_t state;
2472 memset (&state, '\0', sizeof (mbstate_t));
2473 # endif
2474 arg_end = arg;
2475 characters = 0;
2476 for (; precision > 0; precision--)
2478 int count;
2479 # if HAVE_MBRTOWC
2480 count = mbrlen (arg_end, MB_CUR_MAX, &state);
2481 # else
2482 count = mblen (arg_end, MB_CUR_MAX);
2483 # endif
2484 if (count == 0)
2485 /* Found the terminating NUL. */
2486 break;
2487 if (count < 0)
2489 /* Invalid or incomplete multibyte character. */
2490 if (!(result == resultbuf || result == NULL))
2491 free (result);
2492 if (buf_malloced != NULL)
2493 free (buf_malloced);
2494 CLEANUP ();
2495 errno = EILSEQ;
2496 return NULL;
2498 arg_end += count;
2499 characters++;
2502 else if (has_width)
2504 /* Use the entire string, and count the number of wide
2505 characters. */
2506 # if HAVE_MBRTOWC
2507 mbstate_t state;
2508 memset (&state, '\0', sizeof (mbstate_t));
2509 # endif
2510 arg_end = arg;
2511 characters = 0;
2512 for (;;)
2514 int count;
2515 # if HAVE_MBRTOWC
2516 count = mbrlen (arg_end, MB_CUR_MAX, &state);
2517 # else
2518 count = mblen (arg_end, MB_CUR_MAX);
2519 # endif
2520 if (count == 0)
2521 /* Found the terminating NUL. */
2522 break;
2523 if (count < 0)
2525 /* Invalid or incomplete multibyte character. */
2526 if (!(result == resultbuf || result == NULL))
2527 free (result);
2528 if (buf_malloced != NULL)
2529 free (buf_malloced);
2530 CLEANUP ();
2531 errno = EILSEQ;
2532 return NULL;
2534 arg_end += count;
2535 characters++;
2538 else
2540 /* Use the entire string. */
2541 arg_end = arg + strlen (arg);
2542 /* The number of characters doesn't matter. */
2543 characters = 0;
2546 if (has_width && width > characters
2547 && !(dp->flags & FLAG_LEFT))
2549 size_t n = width - characters;
2550 ENSURE_ALLOCATION (xsum (length, n));
2551 DCHAR_SET (result + length, ' ', n);
2552 length += n;
2555 if (has_precision || has_width)
2557 /* We know the number of wide characters in advance. */
2558 size_t remaining;
2559 # if HAVE_MBRTOWC
2560 mbstate_t state;
2561 memset (&state, '\0', sizeof (mbstate_t));
2562 # endif
2563 ENSURE_ALLOCATION (xsum (length, characters));
2564 for (remaining = characters; remaining > 0; remaining--)
2566 wchar_t wc;
2567 int count;
2568 # if HAVE_MBRTOWC
2569 count = mbrtowc (&wc, arg, arg_end - arg, &state);
2570 # else
2571 count = mbtowc (&wc, arg, arg_end - arg);
2572 # endif
2573 if (count <= 0)
2574 /* mbrtowc not consistent with mbrlen, or mbtowc
2575 not consistent with mblen. */
2576 abort ();
2577 result[length++] = wc;
2578 arg += count;
2580 if (!(arg == arg_end))
2581 abort ();
2583 else
2585 # if HAVE_MBRTOWC
2586 mbstate_t state;
2587 memset (&state, '\0', sizeof (mbstate_t));
2588 # endif
2589 while (arg < arg_end)
2591 wchar_t wc;
2592 int count;
2593 # if HAVE_MBRTOWC
2594 count = mbrtowc (&wc, arg, arg_end - arg, &state);
2595 # else
2596 count = mbtowc (&wc, arg, arg_end - arg);
2597 # endif
2598 if (count <= 0)
2599 /* mbrtowc not consistent with mbrlen, or mbtowc
2600 not consistent with mblen. */
2601 abort ();
2602 ENSURE_ALLOCATION (xsum (length, 1));
2603 result[length++] = wc;
2604 arg += count;
2608 if (has_width && width > characters
2609 && (dp->flags & FLAG_LEFT))
2611 size_t n = width - characters;
2612 ENSURE_ALLOCATION (xsum (length, n));
2613 DCHAR_SET (result + length, ' ', n);
2614 length += n;
2617 # else
2618 /* %ls in vasnprintf. See the specification of fprintf. */
2620 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
2621 const wchar_t *arg_end;
2622 size_t characters;
2623 # if !DCHAR_IS_TCHAR
2624 /* This code assumes that TCHAR_T is 'char'. */
2625 typedef int TCHAR_T_verify[2 * (sizeof (TCHAR_T) == 1) - 1];
2626 TCHAR_T *tmpsrc;
2627 DCHAR_T *tmpdst;
2628 size_t tmpdst_len;
2629 # endif
2630 size_t w;
2632 if (has_precision)
2634 /* Use only as many wide characters as needed to produce
2635 at most PRECISION bytes, from the left. */
2636 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2637 mbstate_t state;
2638 memset (&state, '\0', sizeof (mbstate_t));
2639 # endif
2640 arg_end = arg;
2641 characters = 0;
2642 while (precision > 0)
2644 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2645 int count;
2647 if (*arg_end == 0)
2648 /* Found the terminating null wide character. */
2649 break;
2650 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2651 count = wcrtomb (cbuf, *arg_end, &state);
2652 # else
2653 count = wctomb (cbuf, *arg_end);
2654 # endif
2655 if (count < 0)
2657 /* Cannot convert. */
2658 if (!(result == resultbuf || result == NULL))
2659 free (result);
2660 if (buf_malloced != NULL)
2661 free (buf_malloced);
2662 CLEANUP ();
2663 errno = EILSEQ;
2664 return NULL;
2666 if (precision < count)
2667 break;
2668 arg_end++;
2669 characters += count;
2670 precision -= count;
2673 # if DCHAR_IS_TCHAR
2674 else if (has_width)
2675 # else
2676 else
2677 # endif
2679 /* Use the entire string, and count the number of
2680 bytes. */
2681 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2682 mbstate_t state;
2683 memset (&state, '\0', sizeof (mbstate_t));
2684 # endif
2685 arg_end = arg;
2686 characters = 0;
2687 for (;;)
2689 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2690 int count;
2692 if (*arg_end == 0)
2693 /* Found the terminating null wide character. */
2694 break;
2695 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2696 count = wcrtomb (cbuf, *arg_end, &state);
2697 # else
2698 count = wctomb (cbuf, *arg_end);
2699 # endif
2700 if (count < 0)
2702 /* Cannot convert. */
2703 if (!(result == resultbuf || result == NULL))
2704 free (result);
2705 if (buf_malloced != NULL)
2706 free (buf_malloced);
2707 CLEANUP ();
2708 errno = EILSEQ;
2709 return NULL;
2711 arg_end++;
2712 characters += count;
2715 # if DCHAR_IS_TCHAR
2716 else
2718 /* Use the entire string. */
2719 arg_end = arg + local_wcslen (arg);
2720 /* The number of bytes doesn't matter. */
2721 characters = 0;
2723 # endif
2725 # if !DCHAR_IS_TCHAR
2726 /* Convert the string into a piece of temporary memory. */
2727 tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
2728 if (tmpsrc == NULL)
2729 goto out_of_memory;
2731 TCHAR_T *tmpptr = tmpsrc;
2732 size_t remaining;
2733 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2734 mbstate_t state;
2735 memset (&state, '\0', sizeof (mbstate_t));
2736 # endif
2737 for (remaining = characters; remaining > 0; )
2739 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2740 int count;
2742 if (*arg == 0)
2743 abort ();
2744 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2745 count = wcrtomb (cbuf, *arg, &state);
2746 # else
2747 count = wctomb (cbuf, *arg);
2748 # endif
2749 if (count <= 0)
2750 /* Inconsistency. */
2751 abort ();
2752 memcpy (tmpptr, cbuf, count);
2753 tmpptr += count;
2754 arg++;
2755 remaining -= count;
2757 if (!(arg == arg_end))
2758 abort ();
2761 /* Convert from TCHAR_T[] to DCHAR_T[]. */
2762 tmpdst =
2763 DCHAR_CONV_FROM_ENCODING (locale_charset (),
2764 iconveh_question_mark,
2765 tmpsrc, characters,
2766 NULL,
2767 NULL, &tmpdst_len);
2768 if (tmpdst == NULL)
2770 int saved_errno = errno;
2771 free (tmpsrc);
2772 if (!(result == resultbuf || result == NULL))
2773 free (result);
2774 if (buf_malloced != NULL)
2775 free (buf_malloced);
2776 CLEANUP ();
2777 errno = saved_errno;
2778 return NULL;
2780 free (tmpsrc);
2781 # endif
2783 if (has_width)
2785 # if ENABLE_UNISTDIO
2786 /* Outside POSIX, it's preferrable to compare the width
2787 against the number of _characters_ of the converted
2788 value. */
2789 w = DCHAR_MBSNLEN (result + length, characters);
2790 # else
2791 /* The width is compared against the number of _bytes_
2792 of the converted value, says POSIX. */
2793 w = characters;
2794 # endif
2796 else
2797 /* w doesn't matter. */
2798 w = 0;
2800 if (has_width && width > w
2801 && !(dp->flags & FLAG_LEFT))
2803 size_t n = width - w;
2804 ENSURE_ALLOCATION (xsum (length, n));
2805 DCHAR_SET (result + length, ' ', n);
2806 length += n;
2809 # if DCHAR_IS_TCHAR
2810 if (has_precision || has_width)
2812 /* We know the number of bytes in advance. */
2813 size_t remaining;
2814 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2815 mbstate_t state;
2816 memset (&state, '\0', sizeof (mbstate_t));
2817 # endif
2818 ENSURE_ALLOCATION (xsum (length, characters));
2819 for (remaining = characters; remaining > 0; )
2821 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2822 int count;
2824 if (*arg == 0)
2825 abort ();
2826 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2827 count = wcrtomb (cbuf, *arg, &state);
2828 # else
2829 count = wctomb (cbuf, *arg);
2830 # endif
2831 if (count <= 0)
2832 /* Inconsistency. */
2833 abort ();
2834 memcpy (result + length, cbuf, count);
2835 length += count;
2836 arg++;
2837 remaining -= count;
2839 if (!(arg == arg_end))
2840 abort ();
2842 else
2844 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2845 mbstate_t state;
2846 memset (&state, '\0', sizeof (mbstate_t));
2847 # endif
2848 while (arg < arg_end)
2850 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2851 int count;
2853 if (*arg == 0)
2854 abort ();
2855 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2856 count = wcrtomb (cbuf, *arg, &state);
2857 # else
2858 count = wctomb (cbuf, *arg);
2859 # endif
2860 if (count <= 0)
2862 /* Cannot convert. */
2863 if (!(result == resultbuf || result == NULL))
2864 free (result);
2865 if (buf_malloced != NULL)
2866 free (buf_malloced);
2867 CLEANUP ();
2868 errno = EILSEQ;
2869 return NULL;
2871 ENSURE_ALLOCATION (xsum (length, count));
2872 memcpy (result + length, cbuf, count);
2873 length += count;
2874 arg++;
2877 # else
2878 ENSURE_ALLOCATION (xsum (length, tmpdst_len));
2879 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
2880 free (tmpdst);
2881 length += tmpdst_len;
2882 # endif
2884 if (has_width && width > w
2885 && (dp->flags & FLAG_LEFT))
2887 size_t n = width - w;
2888 ENSURE_ALLOCATION (xsum (length, n));
2889 DCHAR_SET (result + length, ' ', n);
2890 length += n;
2893 # endif
2895 #endif
2896 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
2897 else if ((dp->conversion == 'a' || dp->conversion == 'A')
2898 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
2899 && (0
2900 # if NEED_PRINTF_DOUBLE
2901 || a.arg[dp->arg_index].type == TYPE_DOUBLE
2902 # endif
2903 # if NEED_PRINTF_LONG_DOUBLE
2904 || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2905 # endif
2907 # endif
2910 arg_type type = a.arg[dp->arg_index].type;
2911 int flags = dp->flags;
2912 int has_width;
2913 size_t width;
2914 int has_precision;
2915 size_t precision;
2916 size_t tmp_length;
2917 DCHAR_T tmpbuf[700];
2918 DCHAR_T *tmp;
2919 DCHAR_T *pad_ptr;
2920 DCHAR_T *p;
2922 has_width = 0;
2923 width = 0;
2924 if (dp->width_start != dp->width_end)
2926 if (dp->width_arg_index != ARG_NONE)
2928 int arg;
2930 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2931 abort ();
2932 arg = a.arg[dp->width_arg_index].a.a_int;
2933 if (arg < 0)
2935 /* "A negative field width is taken as a '-' flag
2936 followed by a positive field width." */
2937 flags |= FLAG_LEFT;
2938 width = (unsigned int) (-arg);
2940 else
2941 width = arg;
2943 else
2945 const FCHAR_T *digitp = dp->width_start;
2948 width = xsum (xtimes (width, 10), *digitp++ - '0');
2949 while (digitp != dp->width_end);
2951 has_width = 1;
2954 has_precision = 0;
2955 precision = 0;
2956 if (dp->precision_start != dp->precision_end)
2958 if (dp->precision_arg_index != ARG_NONE)
2960 int arg;
2962 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2963 abort ();
2964 arg = a.arg[dp->precision_arg_index].a.a_int;
2965 /* "A negative precision is taken as if the precision
2966 were omitted." */
2967 if (arg >= 0)
2969 precision = arg;
2970 has_precision = 1;
2973 else
2975 const FCHAR_T *digitp = dp->precision_start + 1;
2977 precision = 0;
2978 while (digitp != dp->precision_end)
2979 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2980 has_precision = 1;
2984 /* Allocate a temporary buffer of sufficient size. */
2985 if (type == TYPE_LONGDOUBLE)
2986 tmp_length =
2987 (unsigned int) ((LDBL_DIG + 1)
2988 * 0.831 /* decimal -> hexadecimal */
2990 + 1; /* turn floor into ceil */
2991 else
2992 tmp_length =
2993 (unsigned int) ((DBL_DIG + 1)
2994 * 0.831 /* decimal -> hexadecimal */
2996 + 1; /* turn floor into ceil */
2997 if (tmp_length < precision)
2998 tmp_length = precision;
2999 /* Account for sign, decimal point etc. */
3000 tmp_length = xsum (tmp_length, 12);
3002 if (tmp_length < width)
3003 tmp_length = width;
3005 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3007 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3008 tmp = tmpbuf;
3009 else
3011 size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3013 if (size_overflow_p (tmp_memsize))
3014 /* Overflow, would lead to out of memory. */
3015 goto out_of_memory;
3016 tmp = (DCHAR_T *) malloc (tmp_memsize);
3017 if (tmp == NULL)
3018 /* Out of memory. */
3019 goto out_of_memory;
3022 pad_ptr = NULL;
3023 p = tmp;
3024 if (type == TYPE_LONGDOUBLE)
3026 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
3027 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3029 if (isnanl (arg))
3031 if (dp->conversion == 'A')
3033 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3035 else
3037 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3040 else
3042 int sign = 0;
3043 DECL_LONG_DOUBLE_ROUNDING
3045 BEGIN_LONG_DOUBLE_ROUNDING ();
3047 if (signbit (arg)) /* arg < 0.0L or negative zero */
3049 sign = -1;
3050 arg = -arg;
3053 if (sign < 0)
3054 *p++ = '-';
3055 else if (flags & FLAG_SHOWSIGN)
3056 *p++ = '+';
3057 else if (flags & FLAG_SPACE)
3058 *p++ = ' ';
3060 if (arg > 0.0L && arg + arg == arg)
3062 if (dp->conversion == 'A')
3064 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3066 else
3068 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3071 else
3073 int exponent;
3074 long double mantissa;
3076 if (arg > 0.0L)
3077 mantissa = printf_frexpl (arg, &exponent);
3078 else
3080 exponent = 0;
3081 mantissa = 0.0L;
3084 if (has_precision
3085 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
3087 /* Round the mantissa. */
3088 long double tail = mantissa;
3089 size_t q;
3091 for (q = precision; ; q--)
3093 int digit = (int) tail;
3094 tail -= digit;
3095 if (q == 0)
3097 if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
3098 tail = 1 - tail;
3099 else
3100 tail = - tail;
3101 break;
3103 tail *= 16.0L;
3105 if (tail != 0.0L)
3106 for (q = precision; q > 0; q--)
3107 tail *= 0.0625L;
3108 mantissa += tail;
3111 *p++ = '0';
3112 *p++ = dp->conversion - 'A' + 'X';
3113 pad_ptr = p;
3115 int digit;
3117 digit = (int) mantissa;
3118 mantissa -= digit;
3119 *p++ = '0' + digit;
3120 if ((flags & FLAG_ALT)
3121 || mantissa > 0.0L || precision > 0)
3123 *p++ = decimal_point_char ();
3124 /* This loop terminates because we assume
3125 that FLT_RADIX is a power of 2. */
3126 while (mantissa > 0.0L)
3128 mantissa *= 16.0L;
3129 digit = (int) mantissa;
3130 mantissa -= digit;
3131 *p++ = digit
3132 + (digit < 10
3133 ? '0'
3134 : dp->conversion - 10);
3135 if (precision > 0)
3136 precision--;
3138 while (precision > 0)
3140 *p++ = '0';
3141 precision--;
3145 *p++ = dp->conversion - 'A' + 'P';
3146 # if WIDE_CHAR_VERSION
3148 static const wchar_t decimal_format[] =
3149 { '%', '+', 'd', '\0' };
3150 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3152 while (*p != '\0')
3153 p++;
3154 # else
3155 if (sizeof (DCHAR_T) == 1)
3157 sprintf ((char *) p, "%+d", exponent);
3158 while (*p != '\0')
3159 p++;
3161 else
3163 char expbuf[6 + 1];
3164 const char *ep;
3165 sprintf (expbuf, "%+d", exponent);
3166 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3167 p++;
3169 # endif
3172 END_LONG_DOUBLE_ROUNDING ();
3174 # else
3175 abort ();
3176 # endif
3178 else
3180 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
3181 double arg = a.arg[dp->arg_index].a.a_double;
3183 if (isnand (arg))
3185 if (dp->conversion == 'A')
3187 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3189 else
3191 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3194 else
3196 int sign = 0;
3198 if (signbit (arg)) /* arg < 0.0 or negative zero */
3200 sign = -1;
3201 arg = -arg;
3204 if (sign < 0)
3205 *p++ = '-';
3206 else if (flags & FLAG_SHOWSIGN)
3207 *p++ = '+';
3208 else if (flags & FLAG_SPACE)
3209 *p++ = ' ';
3211 if (arg > 0.0 && arg + arg == arg)
3213 if (dp->conversion == 'A')
3215 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3217 else
3219 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3222 else
3224 int exponent;
3225 double mantissa;
3227 if (arg > 0.0)
3228 mantissa = printf_frexp (arg, &exponent);
3229 else
3231 exponent = 0;
3232 mantissa = 0.0;
3235 if (has_precision
3236 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
3238 /* Round the mantissa. */
3239 double tail = mantissa;
3240 size_t q;
3242 for (q = precision; ; q--)
3244 int digit = (int) tail;
3245 tail -= digit;
3246 if (q == 0)
3248 if (digit & 1 ? tail >= 0.5 : tail > 0.5)
3249 tail = 1 - tail;
3250 else
3251 tail = - tail;
3252 break;
3254 tail *= 16.0;
3256 if (tail != 0.0)
3257 for (q = precision; q > 0; q--)
3258 tail *= 0.0625;
3259 mantissa += tail;
3262 *p++ = '0';
3263 *p++ = dp->conversion - 'A' + 'X';
3264 pad_ptr = p;
3266 int digit;
3268 digit = (int) mantissa;
3269 mantissa -= digit;
3270 *p++ = '0' + digit;
3271 if ((flags & FLAG_ALT)
3272 || mantissa > 0.0 || precision > 0)
3274 *p++ = decimal_point_char ();
3275 /* This loop terminates because we assume
3276 that FLT_RADIX is a power of 2. */
3277 while (mantissa > 0.0)
3279 mantissa *= 16.0;
3280 digit = (int) mantissa;
3281 mantissa -= digit;
3282 *p++ = digit
3283 + (digit < 10
3284 ? '0'
3285 : dp->conversion - 10);
3286 if (precision > 0)
3287 precision--;
3289 while (precision > 0)
3291 *p++ = '0';
3292 precision--;
3296 *p++ = dp->conversion - 'A' + 'P';
3297 # if WIDE_CHAR_VERSION
3299 static const wchar_t decimal_format[] =
3300 { '%', '+', 'd', '\0' };
3301 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3303 while (*p != '\0')
3304 p++;
3305 # else
3306 if (sizeof (DCHAR_T) == 1)
3308 sprintf ((char *) p, "%+d", exponent);
3309 while (*p != '\0')
3310 p++;
3312 else
3314 char expbuf[6 + 1];
3315 const char *ep;
3316 sprintf (expbuf, "%+d", exponent);
3317 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3318 p++;
3320 # endif
3323 # else
3324 abort ();
3325 # endif
3327 /* The generated string now extends from tmp to p, with the
3328 zero padding insertion point being at pad_ptr. */
3329 if (has_width && p - tmp < width)
3331 size_t pad = width - (p - tmp);
3332 DCHAR_T *end = p + pad;
3334 if (flags & FLAG_LEFT)
3336 /* Pad with spaces on the right. */
3337 for (; pad > 0; pad--)
3338 *p++ = ' ';
3340 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3342 /* Pad with zeroes. */
3343 DCHAR_T *q = end;
3345 while (p > pad_ptr)
3346 *--q = *--p;
3347 for (; pad > 0; pad--)
3348 *p++ = '0';
3350 else
3352 /* Pad with spaces on the left. */
3353 DCHAR_T *q = end;
3355 while (p > tmp)
3356 *--q = *--p;
3357 for (; pad > 0; pad--)
3358 *p++ = ' ';
3361 p = end;
3365 size_t count = p - tmp;
3367 if (count >= tmp_length)
3368 /* tmp_length was incorrectly calculated - fix the
3369 code above! */
3370 abort ();
3372 /* Make room for the result. */
3373 if (count >= allocated - length)
3375 size_t n = xsum (length, count);
3377 ENSURE_ALLOCATION (n);
3380 /* Append the result. */
3381 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3382 if (tmp != tmpbuf)
3383 free (tmp);
3384 length += count;
3387 #endif
3388 #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
3389 else if ((dp->conversion == 'f' || dp->conversion == 'F'
3390 || dp->conversion == 'e' || dp->conversion == 'E'
3391 || dp->conversion == 'g' || dp->conversion == 'G'
3392 || dp->conversion == 'a' || dp->conversion == 'A')
3393 && (0
3394 # if NEED_PRINTF_DOUBLE
3395 || a.arg[dp->arg_index].type == TYPE_DOUBLE
3396 # elif NEED_PRINTF_INFINITE_DOUBLE
3397 || (a.arg[dp->arg_index].type == TYPE_DOUBLE
3398 /* The systems (mingw) which produce wrong output
3399 for Inf, -Inf, and NaN also do so for -0.0.
3400 Therefore we treat this case here as well. */
3401 && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
3402 # endif
3403 # if NEED_PRINTF_LONG_DOUBLE
3404 || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3405 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
3406 || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3407 /* Some systems produce wrong output for Inf,
3408 -Inf, and NaN. Some systems in this category
3409 (IRIX 5.3) also do so for -0.0. Therefore we
3410 treat this case here as well. */
3411 && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
3412 # endif
3415 # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
3416 arg_type type = a.arg[dp->arg_index].type;
3417 # endif
3418 int flags = dp->flags;
3419 int has_width;
3420 size_t width;
3421 int has_precision;
3422 size_t precision;
3423 size_t tmp_length;
3424 DCHAR_T tmpbuf[700];
3425 DCHAR_T *tmp;
3426 DCHAR_T *pad_ptr;
3427 DCHAR_T *p;
3429 has_width = 0;
3430 width = 0;
3431 if (dp->width_start != dp->width_end)
3433 if (dp->width_arg_index != ARG_NONE)
3435 int arg;
3437 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3438 abort ();
3439 arg = a.arg[dp->width_arg_index].a.a_int;
3440 if (arg < 0)
3442 /* "A negative field width is taken as a '-' flag
3443 followed by a positive field width." */
3444 flags |= FLAG_LEFT;
3445 width = (unsigned int) (-arg);
3447 else
3448 width = arg;
3450 else
3452 const FCHAR_T *digitp = dp->width_start;
3455 width = xsum (xtimes (width, 10), *digitp++ - '0');
3456 while (digitp != dp->width_end);
3458 has_width = 1;
3461 has_precision = 0;
3462 precision = 0;
3463 if (dp->precision_start != dp->precision_end)
3465 if (dp->precision_arg_index != ARG_NONE)
3467 int arg;
3469 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3470 abort ();
3471 arg = a.arg[dp->precision_arg_index].a.a_int;
3472 /* "A negative precision is taken as if the precision
3473 were omitted." */
3474 if (arg >= 0)
3476 precision = arg;
3477 has_precision = 1;
3480 else
3482 const FCHAR_T *digitp = dp->precision_start + 1;
3484 precision = 0;
3485 while (digitp != dp->precision_end)
3486 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3487 has_precision = 1;
3491 /* POSIX specifies the default precision to be 6 for %f, %F,
3492 %e, %E, but not for %g, %G. Implementations appear to use
3493 the same default precision also for %g, %G. But for %a, %A,
3494 the default precision is 0. */
3495 if (!has_precision)
3496 if (!(dp->conversion == 'a' || dp->conversion == 'A'))
3497 precision = 6;
3499 /* Allocate a temporary buffer of sufficient size. */
3500 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3501 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
3502 # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3503 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
3504 # elif NEED_PRINTF_LONG_DOUBLE
3505 tmp_length = LDBL_DIG + 1;
3506 # elif NEED_PRINTF_DOUBLE
3507 tmp_length = DBL_DIG + 1;
3508 # else
3509 tmp_length = 0;
3510 # endif
3511 if (tmp_length < precision)
3512 tmp_length = precision;
3513 # if NEED_PRINTF_LONG_DOUBLE
3514 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3515 if (type == TYPE_LONGDOUBLE)
3516 # endif
3517 if (dp->conversion == 'f' || dp->conversion == 'F')
3519 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3520 if (!(isnanl (arg) || arg + arg == arg))
3522 /* arg is finite and nonzero. */
3523 int exponent = floorlog10l (arg < 0 ? -arg : arg);
3524 if (exponent >= 0 && tmp_length < exponent + precision)
3525 tmp_length = exponent + precision;
3528 # endif
3529 # if NEED_PRINTF_DOUBLE
3530 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3531 if (type == TYPE_DOUBLE)
3532 # endif
3533 if (dp->conversion == 'f' || dp->conversion == 'F')
3535 double arg = a.arg[dp->arg_index].a.a_double;
3536 if (!(isnand (arg) || arg + arg == arg))
3538 /* arg is finite and nonzero. */
3539 int exponent = floorlog10 (arg < 0 ? -arg : arg);
3540 if (exponent >= 0 && tmp_length < exponent + precision)
3541 tmp_length = exponent + precision;
3544 # endif
3545 /* Account for sign, decimal point etc. */
3546 tmp_length = xsum (tmp_length, 12);
3548 if (tmp_length < width)
3549 tmp_length = width;
3551 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3553 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3554 tmp = tmpbuf;
3555 else
3557 size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3559 if (size_overflow_p (tmp_memsize))
3560 /* Overflow, would lead to out of memory. */
3561 goto out_of_memory;
3562 tmp = (DCHAR_T *) malloc (tmp_memsize);
3563 if (tmp == NULL)
3564 /* Out of memory. */
3565 goto out_of_memory;
3568 pad_ptr = NULL;
3569 p = tmp;
3571 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3572 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3573 if (type == TYPE_LONGDOUBLE)
3574 # endif
3576 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3578 if (isnanl (arg))
3580 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3582 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3584 else
3586 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3589 else
3591 int sign = 0;
3592 DECL_LONG_DOUBLE_ROUNDING
3594 BEGIN_LONG_DOUBLE_ROUNDING ();
3596 if (signbit (arg)) /* arg < 0.0L or negative zero */
3598 sign = -1;
3599 arg = -arg;
3602 if (sign < 0)
3603 *p++ = '-';
3604 else if (flags & FLAG_SHOWSIGN)
3605 *p++ = '+';
3606 else if (flags & FLAG_SPACE)
3607 *p++ = ' ';
3609 if (arg > 0.0L && arg + arg == arg)
3611 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3613 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3615 else
3617 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3620 else
3622 # if NEED_PRINTF_LONG_DOUBLE
3623 pad_ptr = p;
3625 if (dp->conversion == 'f' || dp->conversion == 'F')
3627 char *digits;
3628 size_t ndigits;
3630 digits =
3631 scale10_round_decimal_long_double (arg, precision);
3632 if (digits == NULL)
3634 END_LONG_DOUBLE_ROUNDING ();
3635 goto out_of_memory;
3637 ndigits = strlen (digits);
3639 if (ndigits > precision)
3642 --ndigits;
3643 *p++ = digits[ndigits];
3645 while (ndigits > precision);
3646 else
3647 *p++ = '0';
3648 /* Here ndigits <= precision. */
3649 if ((flags & FLAG_ALT) || precision > 0)
3651 *p++ = decimal_point_char ();
3652 for (; precision > ndigits; precision--)
3653 *p++ = '0';
3654 while (ndigits > 0)
3656 --ndigits;
3657 *p++ = digits[ndigits];
3661 free (digits);
3663 else if (dp->conversion == 'e' || dp->conversion == 'E')
3665 int exponent;
3667 if (arg == 0.0L)
3669 exponent = 0;
3670 *p++ = '0';
3671 if ((flags & FLAG_ALT) || precision > 0)
3673 *p++ = decimal_point_char ();
3674 for (; precision > 0; precision--)
3675 *p++ = '0';
3678 else
3680 /* arg > 0.0L. */
3681 int adjusted;
3682 char *digits;
3683 size_t ndigits;
3685 exponent = floorlog10l (arg);
3686 adjusted = 0;
3687 for (;;)
3689 digits =
3690 scale10_round_decimal_long_double (arg,
3691 (int)precision - exponent);
3692 if (digits == NULL)
3694 END_LONG_DOUBLE_ROUNDING ();
3695 goto out_of_memory;
3697 ndigits = strlen (digits);
3699 if (ndigits == precision + 1)
3700 break;
3701 if (ndigits < precision
3702 || ndigits > precision + 2)
3703 /* The exponent was not guessed
3704 precisely enough. */
3705 abort ();
3706 if (adjusted)
3707 /* None of two values of exponent is
3708 the right one. Prevent an endless
3709 loop. */
3710 abort ();
3711 free (digits);
3712 if (ndigits == precision)
3713 exponent -= 1;
3714 else
3715 exponent += 1;
3716 adjusted = 1;
3718 /* Here ndigits = precision+1. */
3719 if (is_borderline (digits, precision))
3721 /* Maybe the exponent guess was too high
3722 and a smaller exponent can be reached
3723 by turning a 10...0 into 9...9x. */
3724 char *digits2 =
3725 scale10_round_decimal_long_double (arg,
3726 (int)precision - exponent + 1);
3727 if (digits2 == NULL)
3729 free (digits);
3730 END_LONG_DOUBLE_ROUNDING ();
3731 goto out_of_memory;
3733 if (strlen (digits2) == precision + 1)
3735 free (digits);
3736 digits = digits2;
3737 exponent -= 1;
3739 else
3740 free (digits2);
3742 /* Here ndigits = precision+1. */
3744 *p++ = digits[--ndigits];
3745 if ((flags & FLAG_ALT) || precision > 0)
3747 *p++ = decimal_point_char ();
3748 while (ndigits > 0)
3750 --ndigits;
3751 *p++ = digits[ndigits];
3755 free (digits);
3758 *p++ = dp->conversion; /* 'e' or 'E' */
3759 # if WIDE_CHAR_VERSION
3761 static const wchar_t decimal_format[] =
3762 { '%', '+', '.', '2', 'd', '\0' };
3763 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3765 while (*p != '\0')
3766 p++;
3767 # else
3768 if (sizeof (DCHAR_T) == 1)
3770 sprintf ((char *) p, "%+.2d", exponent);
3771 while (*p != '\0')
3772 p++;
3774 else
3776 char expbuf[6 + 1];
3777 const char *ep;
3778 sprintf (expbuf, "%+.2d", exponent);
3779 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3780 p++;
3782 # endif
3784 else if (dp->conversion == 'g' || dp->conversion == 'G')
3786 if (precision == 0)
3787 precision = 1;
3788 /* precision >= 1. */
3790 if (arg == 0.0L)
3791 /* The exponent is 0, >= -4, < precision.
3792 Use fixed-point notation. */
3794 size_t ndigits = precision;
3795 /* Number of trailing zeroes that have to be
3796 dropped. */
3797 size_t nzeroes =
3798 (flags & FLAG_ALT ? 0 : precision - 1);
3800 --ndigits;
3801 *p++ = '0';
3802 if ((flags & FLAG_ALT) || ndigits > nzeroes)
3804 *p++ = decimal_point_char ();
3805 while (ndigits > nzeroes)
3807 --ndigits;
3808 *p++ = '0';
3812 else
3814 /* arg > 0.0L. */
3815 int exponent;
3816 int adjusted;
3817 char *digits;
3818 size_t ndigits;
3819 size_t nzeroes;
3821 exponent = floorlog10l (arg);
3822 adjusted = 0;
3823 for (;;)
3825 digits =
3826 scale10_round_decimal_long_double (arg,
3827 (int)(precision - 1) - exponent);
3828 if (digits == NULL)
3830 END_LONG_DOUBLE_ROUNDING ();
3831 goto out_of_memory;
3833 ndigits = strlen (digits);
3835 if (ndigits == precision)
3836 break;
3837 if (ndigits < precision - 1
3838 || ndigits > precision + 1)
3839 /* The exponent was not guessed
3840 precisely enough. */
3841 abort ();
3842 if (adjusted)
3843 /* None of two values of exponent is
3844 the right one. Prevent an endless
3845 loop. */
3846 abort ();
3847 free (digits);
3848 if (ndigits < precision)
3849 exponent -= 1;
3850 else
3851 exponent += 1;
3852 adjusted = 1;
3854 /* Here ndigits = precision. */
3855 if (is_borderline (digits, precision - 1))
3857 /* Maybe the exponent guess was too high
3858 and a smaller exponent can be reached
3859 by turning a 10...0 into 9...9x. */
3860 char *digits2 =
3861 scale10_round_decimal_long_double (arg,
3862 (int)(precision - 1) - exponent + 1);
3863 if (digits2 == NULL)
3865 free (digits);
3866 END_LONG_DOUBLE_ROUNDING ();
3867 goto out_of_memory;
3869 if (strlen (digits2) == precision)
3871 free (digits);
3872 digits = digits2;
3873 exponent -= 1;
3875 else
3876 free (digits2);
3878 /* Here ndigits = precision. */
3880 /* Determine the number of trailing zeroes
3881 that have to be dropped. */
3882 nzeroes = 0;
3883 if ((flags & FLAG_ALT) == 0)
3884 while (nzeroes < ndigits
3885 && digits[nzeroes] == '0')
3886 nzeroes++;
3888 /* The exponent is now determined. */
3889 if (exponent >= -4
3890 && exponent < (long)precision)
3892 /* Fixed-point notation:
3893 max(exponent,0)+1 digits, then the
3894 decimal point, then the remaining
3895 digits without trailing zeroes. */
3896 if (exponent >= 0)
3898 size_t count = exponent + 1;
3899 /* Note: count <= precision = ndigits. */
3900 for (; count > 0; count--)
3901 *p++ = digits[--ndigits];
3902 if ((flags & FLAG_ALT) || ndigits > nzeroes)
3904 *p++ = decimal_point_char ();
3905 while (ndigits > nzeroes)
3907 --ndigits;
3908 *p++ = digits[ndigits];
3912 else
3914 size_t count = -exponent - 1;
3915 *p++ = '0';
3916 *p++ = decimal_point_char ();
3917 for (; count > 0; count--)
3918 *p++ = '0';
3919 while (ndigits > nzeroes)
3921 --ndigits;
3922 *p++ = digits[ndigits];
3926 else
3928 /* Exponential notation. */
3929 *p++ = digits[--ndigits];
3930 if ((flags & FLAG_ALT) || ndigits > nzeroes)
3932 *p++ = decimal_point_char ();
3933 while (ndigits > nzeroes)
3935 --ndigits;
3936 *p++ = digits[ndigits];
3939 *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3940 # if WIDE_CHAR_VERSION
3942 static const wchar_t decimal_format[] =
3943 { '%', '+', '.', '2', 'd', '\0' };
3944 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3946 while (*p != '\0')
3947 p++;
3948 # else
3949 if (sizeof (DCHAR_T) == 1)
3951 sprintf ((char *) p, "%+.2d", exponent);
3952 while (*p != '\0')
3953 p++;
3955 else
3957 char expbuf[6 + 1];
3958 const char *ep;
3959 sprintf (expbuf, "%+.2d", exponent);
3960 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3961 p++;
3963 # endif
3966 free (digits);
3969 else
3970 abort ();
3971 # else
3972 /* arg is finite. */
3973 if (!(arg == 0.0L))
3974 abort ();
3976 pad_ptr = p;
3978 if (dp->conversion == 'f' || dp->conversion == 'F')
3980 *p++ = '0';
3981 if ((flags & FLAG_ALT) || precision > 0)
3983 *p++ = decimal_point_char ();
3984 for (; precision > 0; precision--)
3985 *p++ = '0';
3988 else if (dp->conversion == 'e' || dp->conversion == 'E')
3990 *p++ = '0';
3991 if ((flags & FLAG_ALT) || precision > 0)
3993 *p++ = decimal_point_char ();
3994 for (; precision > 0; precision--)
3995 *p++ = '0';
3997 *p++ = dp->conversion; /* 'e' or 'E' */
3998 *p++ = '+';
3999 *p++ = '0';
4000 *p++ = '0';
4002 else if (dp->conversion == 'g' || dp->conversion == 'G')
4004 *p++ = '0';
4005 if (flags & FLAG_ALT)
4007 size_t ndigits =
4008 (precision > 0 ? precision - 1 : 0);
4009 *p++ = decimal_point_char ();
4010 for (; ndigits > 0; --ndigits)
4011 *p++ = '0';
4014 else if (dp->conversion == 'a' || dp->conversion == 'A')
4016 *p++ = '0';
4017 *p++ = dp->conversion - 'A' + 'X';
4018 pad_ptr = p;
4019 *p++ = '0';
4020 if ((flags & FLAG_ALT) || precision > 0)
4022 *p++ = decimal_point_char ();
4023 for (; precision > 0; precision--)
4024 *p++ = '0';
4026 *p++ = dp->conversion - 'A' + 'P';
4027 *p++ = '+';
4028 *p++ = '0';
4030 else
4031 abort ();
4032 # endif
4035 END_LONG_DOUBLE_ROUNDING ();
4038 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4039 else
4040 # endif
4041 # endif
4042 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4044 double arg = a.arg[dp->arg_index].a.a_double;
4046 if (isnand (arg))
4048 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4050 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4052 else
4054 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4057 else
4059 int sign = 0;
4061 if (signbit (arg)) /* arg < 0.0 or negative zero */
4063 sign = -1;
4064 arg = -arg;
4067 if (sign < 0)
4068 *p++ = '-';
4069 else if (flags & FLAG_SHOWSIGN)
4070 *p++ = '+';
4071 else if (flags & FLAG_SPACE)
4072 *p++ = ' ';
4074 if (arg > 0.0 && arg + arg == arg)
4076 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4078 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4080 else
4082 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4085 else
4087 # if NEED_PRINTF_DOUBLE
4088 pad_ptr = p;
4090 if (dp->conversion == 'f' || dp->conversion == 'F')
4092 char *digits;
4093 size_t ndigits;
4095 digits =
4096 scale10_round_decimal_double (arg, precision);
4097 if (digits == NULL)
4098 goto out_of_memory;
4099 ndigits = strlen (digits);
4101 if (ndigits > precision)
4104 --ndigits;
4105 *p++ = digits[ndigits];
4107 while (ndigits > precision);
4108 else
4109 *p++ = '0';
4110 /* Here ndigits <= precision. */
4111 if ((flags & FLAG_ALT) || precision > 0)
4113 *p++ = decimal_point_char ();
4114 for (; precision > ndigits; precision--)
4115 *p++ = '0';
4116 while (ndigits > 0)
4118 --ndigits;
4119 *p++ = digits[ndigits];
4123 free (digits);
4125 else if (dp->conversion == 'e' || dp->conversion == 'E')
4127 int exponent;
4129 if (arg == 0.0)
4131 exponent = 0;
4132 *p++ = '0';
4133 if ((flags & FLAG_ALT) || precision > 0)
4135 *p++ = decimal_point_char ();
4136 for (; precision > 0; precision--)
4137 *p++ = '0';
4140 else
4142 /* arg > 0.0. */
4143 int adjusted;
4144 char *digits;
4145 size_t ndigits;
4147 exponent = floorlog10 (arg);
4148 adjusted = 0;
4149 for (;;)
4151 digits =
4152 scale10_round_decimal_double (arg,
4153 (int)precision - exponent);
4154 if (digits == NULL)
4155 goto out_of_memory;
4156 ndigits = strlen (digits);
4158 if (ndigits == precision + 1)
4159 break;
4160 if (ndigits < precision
4161 || ndigits > precision + 2)
4162 /* The exponent was not guessed
4163 precisely enough. */
4164 abort ();
4165 if (adjusted)
4166 /* None of two values of exponent is
4167 the right one. Prevent an endless
4168 loop. */
4169 abort ();
4170 free (digits);
4171 if (ndigits == precision)
4172 exponent -= 1;
4173 else
4174 exponent += 1;
4175 adjusted = 1;
4177 /* Here ndigits = precision+1. */
4178 if (is_borderline (digits, precision))
4180 /* Maybe the exponent guess was too high
4181 and a smaller exponent can be reached
4182 by turning a 10...0 into 9...9x. */
4183 char *digits2 =
4184 scale10_round_decimal_double (arg,
4185 (int)precision - exponent + 1);
4186 if (digits2 == NULL)
4188 free (digits);
4189 goto out_of_memory;
4191 if (strlen (digits2) == precision + 1)
4193 free (digits);
4194 digits = digits2;
4195 exponent -= 1;
4197 else
4198 free (digits2);
4200 /* Here ndigits = precision+1. */
4202 *p++ = digits[--ndigits];
4203 if ((flags & FLAG_ALT) || precision > 0)
4205 *p++ = decimal_point_char ();
4206 while (ndigits > 0)
4208 --ndigits;
4209 *p++ = digits[ndigits];
4213 free (digits);
4216 *p++ = dp->conversion; /* 'e' or 'E' */
4217 # if WIDE_CHAR_VERSION
4219 static const wchar_t decimal_format[] =
4220 /* Produce the same number of exponent digits
4221 as the native printf implementation. */
4222 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4223 { '%', '+', '.', '3', 'd', '\0' };
4224 # else
4225 { '%', '+', '.', '2', 'd', '\0' };
4226 # endif
4227 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4229 while (*p != '\0')
4230 p++;
4231 # else
4233 static const char decimal_format[] =
4234 /* Produce the same number of exponent digits
4235 as the native printf implementation. */
4236 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4237 "%+.3d";
4238 # else
4239 "%+.2d";
4240 # endif
4241 if (sizeof (DCHAR_T) == 1)
4243 sprintf ((char *) p, decimal_format, exponent);
4244 while (*p != '\0')
4245 p++;
4247 else
4249 char expbuf[6 + 1];
4250 const char *ep;
4251 sprintf (expbuf, decimal_format, exponent);
4252 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4253 p++;
4256 # endif
4258 else if (dp->conversion == 'g' || dp->conversion == 'G')
4260 if (precision == 0)
4261 precision = 1;
4262 /* precision >= 1. */
4264 if (arg == 0.0)
4265 /* The exponent is 0, >= -4, < precision.
4266 Use fixed-point notation. */
4268 size_t ndigits = precision;
4269 /* Number of trailing zeroes that have to be
4270 dropped. */
4271 size_t nzeroes =
4272 (flags & FLAG_ALT ? 0 : precision - 1);
4274 --ndigits;
4275 *p++ = '0';
4276 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4278 *p++ = decimal_point_char ();
4279 while (ndigits > nzeroes)
4281 --ndigits;
4282 *p++ = '0';
4286 else
4288 /* arg > 0.0. */
4289 int exponent;
4290 int adjusted;
4291 char *digits;
4292 size_t ndigits;
4293 size_t nzeroes;
4295 exponent = floorlog10 (arg);
4296 adjusted = 0;
4297 for (;;)
4299 digits =
4300 scale10_round_decimal_double (arg,
4301 (int)(precision - 1) - exponent);
4302 if (digits == NULL)
4303 goto out_of_memory;
4304 ndigits = strlen (digits);
4306 if (ndigits == precision)
4307 break;
4308 if (ndigits < precision - 1
4309 || ndigits > precision + 1)
4310 /* The exponent was not guessed
4311 precisely enough. */
4312 abort ();
4313 if (adjusted)
4314 /* None of two values of exponent is
4315 the right one. Prevent an endless
4316 loop. */
4317 abort ();
4318 free (digits);
4319 if (ndigits < precision)
4320 exponent -= 1;
4321 else
4322 exponent += 1;
4323 adjusted = 1;
4325 /* Here ndigits = precision. */
4326 if (is_borderline (digits, precision - 1))
4328 /* Maybe the exponent guess was too high
4329 and a smaller exponent can be reached
4330 by turning a 10...0 into 9...9x. */
4331 char *digits2 =
4332 scale10_round_decimal_double (arg,
4333 (int)(precision - 1) - exponent + 1);
4334 if (digits2 == NULL)
4336 free (digits);
4337 goto out_of_memory;
4339 if (strlen (digits2) == precision)
4341 free (digits);
4342 digits = digits2;
4343 exponent -= 1;
4345 else
4346 free (digits2);
4348 /* Here ndigits = precision. */
4350 /* Determine the number of trailing zeroes
4351 that have to be dropped. */
4352 nzeroes = 0;
4353 if ((flags & FLAG_ALT) == 0)
4354 while (nzeroes < ndigits
4355 && digits[nzeroes] == '0')
4356 nzeroes++;
4358 /* The exponent is now determined. */
4359 if (exponent >= -4
4360 && exponent < (long)precision)
4362 /* Fixed-point notation:
4363 max(exponent,0)+1 digits, then the
4364 decimal point, then the remaining
4365 digits without trailing zeroes. */
4366 if (exponent >= 0)
4368 size_t count = exponent + 1;
4369 /* Note: count <= precision = ndigits. */
4370 for (; count > 0; count--)
4371 *p++ = digits[--ndigits];
4372 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4374 *p++ = decimal_point_char ();
4375 while (ndigits > nzeroes)
4377 --ndigits;
4378 *p++ = digits[ndigits];
4382 else
4384 size_t count = -exponent - 1;
4385 *p++ = '0';
4386 *p++ = decimal_point_char ();
4387 for (; count > 0; count--)
4388 *p++ = '0';
4389 while (ndigits > nzeroes)
4391 --ndigits;
4392 *p++ = digits[ndigits];
4396 else
4398 /* Exponential notation. */
4399 *p++ = digits[--ndigits];
4400 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4402 *p++ = decimal_point_char ();
4403 while (ndigits > nzeroes)
4405 --ndigits;
4406 *p++ = digits[ndigits];
4409 *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4410 # if WIDE_CHAR_VERSION
4412 static const wchar_t decimal_format[] =
4413 /* Produce the same number of exponent digits
4414 as the native printf implementation. */
4415 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4416 { '%', '+', '.', '3', 'd', '\0' };
4417 # else
4418 { '%', '+', '.', '2', 'd', '\0' };
4419 # endif
4420 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4422 while (*p != '\0')
4423 p++;
4424 # else
4426 static const char decimal_format[] =
4427 /* Produce the same number of exponent digits
4428 as the native printf implementation. */
4429 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4430 "%+.3d";
4431 # else
4432 "%+.2d";
4433 # endif
4434 if (sizeof (DCHAR_T) == 1)
4436 sprintf ((char *) p, decimal_format, exponent);
4437 while (*p != '\0')
4438 p++;
4440 else
4442 char expbuf[6 + 1];
4443 const char *ep;
4444 sprintf (expbuf, decimal_format, exponent);
4445 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4446 p++;
4449 # endif
4452 free (digits);
4455 else
4456 abort ();
4457 # else
4458 /* arg is finite. */
4459 if (!(arg == 0.0))
4460 abort ();
4462 pad_ptr = p;
4464 if (dp->conversion == 'f' || dp->conversion == 'F')
4466 *p++ = '0';
4467 if ((flags & FLAG_ALT) || precision > 0)
4469 *p++ = decimal_point_char ();
4470 for (; precision > 0; precision--)
4471 *p++ = '0';
4474 else if (dp->conversion == 'e' || dp->conversion == 'E')
4476 *p++ = '0';
4477 if ((flags & FLAG_ALT) || precision > 0)
4479 *p++ = decimal_point_char ();
4480 for (; precision > 0; precision--)
4481 *p++ = '0';
4483 *p++ = dp->conversion; /* 'e' or 'E' */
4484 *p++ = '+';
4485 /* Produce the same number of exponent digits as
4486 the native printf implementation. */
4487 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4488 *p++ = '0';
4489 # endif
4490 *p++ = '0';
4491 *p++ = '0';
4493 else if (dp->conversion == 'g' || dp->conversion == 'G')
4495 *p++ = '0';
4496 if (flags & FLAG_ALT)
4498 size_t ndigits =
4499 (precision > 0 ? precision - 1 : 0);
4500 *p++ = decimal_point_char ();
4501 for (; ndigits > 0; --ndigits)
4502 *p++ = '0';
4505 else
4506 abort ();
4507 # endif
4511 # endif
4513 /* The generated string now extends from tmp to p, with the
4514 zero padding insertion point being at pad_ptr. */
4515 if (has_width && p - tmp < width)
4517 size_t pad = width - (p - tmp);
4518 DCHAR_T *end = p + pad;
4520 if (flags & FLAG_LEFT)
4522 /* Pad with spaces on the right. */
4523 for (; pad > 0; pad--)
4524 *p++ = ' ';
4526 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4528 /* Pad with zeroes. */
4529 DCHAR_T *q = end;
4531 while (p > pad_ptr)
4532 *--q = *--p;
4533 for (; pad > 0; pad--)
4534 *p++ = '0';
4536 else
4538 /* Pad with spaces on the left. */
4539 DCHAR_T *q = end;
4541 while (p > tmp)
4542 *--q = *--p;
4543 for (; pad > 0; pad--)
4544 *p++ = ' ';
4547 p = end;
4551 size_t 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;
4573 #endif
4574 else
4576 arg_type type = a.arg[dp->arg_index].type;
4577 int flags = dp->flags;
4578 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4579 int has_width;
4580 size_t width;
4581 #endif
4582 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
4583 int has_precision;
4584 size_t precision;
4585 #endif
4586 #if NEED_PRINTF_UNBOUNDED_PRECISION
4587 int prec_ourselves;
4588 #else
4589 # define prec_ourselves 0
4590 #endif
4591 #if NEED_PRINTF_FLAG_LEFTADJUST
4592 # define pad_ourselves 1
4593 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4594 int pad_ourselves;
4595 #else
4596 # define pad_ourselves 0
4597 #endif
4598 TCHAR_T *fbp;
4599 unsigned int prefix_count;
4600 int prefixes[2] IF_LINT (= { 0 });
4601 #if !USE_SNPRINTF
4602 size_t tmp_length;
4603 TCHAR_T tmpbuf[700];
4604 TCHAR_T *tmp;
4605 #endif
4607 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4608 has_width = 0;
4609 width = 0;
4610 if (dp->width_start != dp->width_end)
4612 if (dp->width_arg_index != ARG_NONE)
4614 int arg;
4616 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4617 abort ();
4618 arg = a.arg[dp->width_arg_index].a.a_int;
4619 if (arg < 0)
4621 /* "A negative field width is taken as a '-' flag
4622 followed by a positive field width." */
4623 flags |= FLAG_LEFT;
4624 width = (unsigned int) (-arg);
4626 else
4627 width = arg;
4629 else
4631 const FCHAR_T *digitp = dp->width_start;
4634 width = xsum (xtimes (width, 10), *digitp++ - '0');
4635 while (digitp != dp->width_end);
4637 has_width = 1;
4639 #endif
4641 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
4642 has_precision = 0;
4643 precision = 6;
4644 if (dp->precision_start != dp->precision_end)
4646 if (dp->precision_arg_index != ARG_NONE)
4648 int arg;
4650 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4651 abort ();
4652 arg = a.arg[dp->precision_arg_index].a.a_int;
4653 /* "A negative precision is taken as if the precision
4654 were omitted." */
4655 if (arg >= 0)
4657 precision = arg;
4658 has_precision = 1;
4661 else
4663 const FCHAR_T *digitp = dp->precision_start + 1;
4665 precision = 0;
4666 while (digitp != dp->precision_end)
4667 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4668 has_precision = 1;
4671 #endif
4673 /* Decide whether to handle the precision ourselves. */
4674 #if NEED_PRINTF_UNBOUNDED_PRECISION
4675 switch (dp->conversion)
4677 case 'd': case 'i': case 'u':
4678 case 'o':
4679 case 'x': case 'X': case 'p':
4680 prec_ourselves = has_precision && (precision > 0);
4681 break;
4682 default:
4683 prec_ourselves = 0;
4684 break;
4686 #endif
4688 /* Decide whether to perform the padding ourselves. */
4689 #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
4690 switch (dp->conversion)
4692 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4693 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
4694 to perform the padding after this conversion. Functions
4695 with unistdio extensions perform the padding based on
4696 character count rather than element count. */
4697 case 'c': case 's':
4698 # endif
4699 # if NEED_PRINTF_FLAG_ZERO
4700 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
4701 case 'a': case 'A':
4702 # endif
4703 pad_ourselves = 1;
4704 break;
4705 default:
4706 pad_ourselves = prec_ourselves;
4707 break;
4709 #endif
4711 #if !USE_SNPRINTF
4712 /* Allocate a temporary buffer of sufficient size for calling
4713 sprintf. */
4714 tmp_length =
4715 MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
4716 flags, width, has_precision, precision,
4717 pad_ourselves);
4719 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
4720 tmp = tmpbuf;
4721 else
4723 size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
4725 if (size_overflow_p (tmp_memsize))
4726 /* Overflow, would lead to out of memory. */
4727 goto out_of_memory;
4728 tmp = (TCHAR_T *) malloc (tmp_memsize);
4729 if (tmp == NULL)
4730 /* Out of memory. */
4731 goto out_of_memory;
4733 #endif
4735 /* Construct the format string for calling snprintf or
4736 sprintf. */
4737 fbp = buf;
4738 *fbp++ = '%';
4739 #if NEED_PRINTF_FLAG_GROUPING
4740 /* The underlying implementation doesn't support the ' flag.
4741 Produce no grouping characters in this case; this is
4742 acceptable because the grouping is locale dependent. */
4743 #else
4744 if (flags & FLAG_GROUP)
4745 *fbp++ = '\'';
4746 #endif
4747 if (flags & FLAG_LEFT)
4748 *fbp++ = '-';
4749 if (flags & FLAG_SHOWSIGN)
4750 *fbp++ = '+';
4751 if (flags & FLAG_SPACE)
4752 *fbp++ = ' ';
4753 if (flags & FLAG_ALT)
4754 *fbp++ = '#';
4755 if (!pad_ourselves)
4757 if (flags & FLAG_ZERO)
4758 *fbp++ = '0';
4759 if (dp->width_start != dp->width_end)
4761 size_t n = dp->width_end - dp->width_start;
4762 /* The width specification is known to consist only
4763 of standard ASCII characters. */
4764 if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4766 memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
4767 fbp += n;
4769 else
4771 const FCHAR_T *mp = dp->width_start;
4773 *fbp++ = (unsigned char) *mp++;
4774 while (--n > 0);
4778 if (!prec_ourselves)
4780 if (dp->precision_start != dp->precision_end)
4782 size_t n = dp->precision_end - dp->precision_start;
4783 /* The precision specification is known to consist only
4784 of standard ASCII characters. */
4785 if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4787 memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
4788 fbp += n;
4790 else
4792 const FCHAR_T *mp = dp->precision_start;
4794 *fbp++ = (unsigned char) *mp++;
4795 while (--n > 0);
4800 switch (type)
4802 #if HAVE_LONG_LONG_INT
4803 case TYPE_LONGLONGINT:
4804 case TYPE_ULONGLONGINT:
4805 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4806 *fbp++ = 'I';
4807 *fbp++ = '6';
4808 *fbp++ = '4';
4809 break;
4810 # else
4811 *fbp++ = 'l';
4812 /*FALLTHROUGH*/
4813 # endif
4814 #endif
4815 case TYPE_LONGINT:
4816 case TYPE_ULONGINT:
4817 #if HAVE_WINT_T
4818 case TYPE_WIDE_CHAR:
4819 #endif
4820 #if HAVE_WCHAR_T
4821 case TYPE_WIDE_STRING:
4822 #endif
4823 *fbp++ = 'l';
4824 break;
4825 case TYPE_LONGDOUBLE:
4826 *fbp++ = 'L';
4827 break;
4828 default:
4829 break;
4831 #if NEED_PRINTF_DIRECTIVE_F
4832 if (dp->conversion == 'F')
4833 *fbp = 'f';
4834 else
4835 #endif
4836 *fbp = dp->conversion;
4837 #if USE_SNPRINTF
4838 # if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
4839 fbp[1] = '%';
4840 fbp[2] = 'n';
4841 fbp[3] = '\0';
4842 # else
4843 /* On glibc2 systems from glibc >= 2.3 - probably also older
4844 ones - we know that snprintf's returns value conforms to
4845 ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes.
4846 Therefore we can avoid using %n in this situation.
4847 On glibc2 systems from 2004-10-18 or newer, the use of %n
4848 in format strings in writable memory may crash the program
4849 (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
4850 in this situation. */
4851 /* On native Win32 systems (such as mingw), we can avoid using
4852 %n because:
4853 - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
4854 snprintf does not write more than the specified number
4855 of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
4856 '4', '5', '6' into buf, not '4', '5', '\0'.)
4857 - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
4858 allows us to recognize the case of an insufficient
4859 buffer size: it returns -1 in this case.
4860 On native Win32 systems (such as mingw) where the OS is
4861 Windows Vista, the use of %n in format strings by default
4862 crashes the program. See
4863 <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
4864 <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
4865 So we should avoid %n in this situation. */
4866 fbp[1] = '\0';
4867 # endif
4868 #else
4869 fbp[1] = '\0';
4870 #endif
4872 /* Construct the arguments for calling snprintf or sprintf. */
4873 prefix_count = 0;
4874 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
4876 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4877 abort ();
4878 prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
4880 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
4882 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4883 abort ();
4884 prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
4887 #if USE_SNPRINTF
4888 /* The SNPRINTF result is appended after result[0..length].
4889 The latter is an array of DCHAR_T; SNPRINTF appends an
4890 array of TCHAR_T to it. This is possible because
4891 sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
4892 alignof (TCHAR_T) <= alignof (DCHAR_T). */
4893 # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
4894 /* Ensure that maxlen below will be >= 2. Needed on BeOS,
4895 where an snprintf() with maxlen==1 acts like sprintf(). */
4896 ENSURE_ALLOCATION (xsum (length,
4897 (2 + TCHARS_PER_DCHAR - 1)
4898 / TCHARS_PER_DCHAR));
4899 /* Prepare checking whether snprintf returns the count
4900 via %n. */
4901 *(TCHAR_T *) (result + length) = '\0';
4902 #endif
4904 for (;;)
4906 int count = -1;
4908 #if USE_SNPRINTF
4909 int retcount = 0;
4910 size_t maxlen = allocated - length;
4911 /* SNPRINTF can fail if its second argument is
4912 > INT_MAX. */
4913 if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
4914 maxlen = INT_MAX / TCHARS_PER_DCHAR;
4915 maxlen = maxlen * TCHARS_PER_DCHAR;
4916 # define SNPRINTF_BUF(arg) \
4917 switch (prefix_count) \
4919 case 0: \
4920 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4921 maxlen, buf, \
4922 arg, &count); \
4923 break; \
4924 case 1: \
4925 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4926 maxlen, buf, \
4927 prefixes[0], arg, &count); \
4928 break; \
4929 case 2: \
4930 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4931 maxlen, buf, \
4932 prefixes[0], prefixes[1], arg, \
4933 &count); \
4934 break; \
4935 default: \
4936 abort (); \
4938 #else
4939 # define SNPRINTF_BUF(arg) \
4940 switch (prefix_count) \
4942 case 0: \
4943 count = sprintf (tmp, buf, arg); \
4944 break; \
4945 case 1: \
4946 count = sprintf (tmp, buf, prefixes[0], arg); \
4947 break; \
4948 case 2: \
4949 count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
4950 arg); \
4951 break; \
4952 default: \
4953 abort (); \
4955 #endif
4957 errno = 0;
4958 switch (type)
4960 case TYPE_SCHAR:
4962 int arg = a.arg[dp->arg_index].a.a_schar;
4963 SNPRINTF_BUF (arg);
4965 break;
4966 case TYPE_UCHAR:
4968 unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
4969 SNPRINTF_BUF (arg);
4971 break;
4972 case TYPE_SHORT:
4974 int arg = a.arg[dp->arg_index].a.a_short;
4975 SNPRINTF_BUF (arg);
4977 break;
4978 case TYPE_USHORT:
4980 unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
4981 SNPRINTF_BUF (arg);
4983 break;
4984 case TYPE_INT:
4986 int arg = a.arg[dp->arg_index].a.a_int;
4987 SNPRINTF_BUF (arg);
4989 break;
4990 case TYPE_UINT:
4992 unsigned int arg = a.arg[dp->arg_index].a.a_uint;
4993 SNPRINTF_BUF (arg);
4995 break;
4996 case TYPE_LONGINT:
4998 long int arg = a.arg[dp->arg_index].a.a_longint;
4999 SNPRINTF_BUF (arg);
5001 break;
5002 case TYPE_ULONGINT:
5004 unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
5005 SNPRINTF_BUF (arg);
5007 break;
5008 #if HAVE_LONG_LONG_INT
5009 case TYPE_LONGLONGINT:
5011 long long int arg = a.arg[dp->arg_index].a.a_longlongint;
5012 SNPRINTF_BUF (arg);
5014 break;
5015 case TYPE_ULONGLONGINT:
5017 unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
5018 SNPRINTF_BUF (arg);
5020 break;
5021 #endif
5022 case TYPE_DOUBLE:
5024 double arg = a.arg[dp->arg_index].a.a_double;
5025 SNPRINTF_BUF (arg);
5027 break;
5028 case TYPE_LONGDOUBLE:
5030 long double arg = a.arg[dp->arg_index].a.a_longdouble;
5031 SNPRINTF_BUF (arg);
5033 break;
5034 case TYPE_CHAR:
5036 int arg = a.arg[dp->arg_index].a.a_char;
5037 SNPRINTF_BUF (arg);
5039 break;
5040 #if HAVE_WINT_T
5041 case TYPE_WIDE_CHAR:
5043 wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
5044 SNPRINTF_BUF (arg);
5046 break;
5047 #endif
5048 case TYPE_STRING:
5050 const char *arg = a.arg[dp->arg_index].a.a_string;
5051 SNPRINTF_BUF (arg);
5053 break;
5054 #if HAVE_WCHAR_T
5055 case TYPE_WIDE_STRING:
5057 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
5058 SNPRINTF_BUF (arg);
5060 break;
5061 #endif
5062 case TYPE_POINTER:
5064 void *arg = a.arg[dp->arg_index].a.a_pointer;
5065 SNPRINTF_BUF (arg);
5067 break;
5068 default:
5069 abort ();
5072 #if USE_SNPRINTF
5073 /* Portability: Not all implementations of snprintf()
5074 are ISO C 99 compliant. Determine the number of
5075 bytes that snprintf() has produced or would have
5076 produced. */
5077 if (count >= 0)
5079 /* Verify that snprintf() has NUL-terminated its
5080 result. */
5081 if (count < maxlen
5082 && ((TCHAR_T *) (result + length)) [count] != '\0')
5083 abort ();
5084 /* Portability hack. */
5085 if (retcount > count)
5086 count = retcount;
5088 else
5090 /* snprintf() doesn't understand the '%n'
5091 directive. */
5092 if (fbp[1] != '\0')
5094 /* Don't use the '%n' directive; instead, look
5095 at the snprintf() return value. */
5096 fbp[1] = '\0';
5097 continue;
5099 else
5101 /* Look at the snprintf() return value. */
5102 if (retcount < 0)
5104 # if !HAVE_SNPRINTF_RETVAL_C99
5105 /* HP-UX 10.20 snprintf() is doubly deficient:
5106 It doesn't understand the '%n' directive,
5107 *and* it returns -1 (rather than the length
5108 that would have been required) when the
5109 buffer is too small.
5110 But a failure at this point can also come
5111 from other reasons than a too small buffer,
5112 such as an invalid wide string argument to
5113 the %ls directive, or possibly an invalid
5114 floating-point argument. */
5115 size_t tmp_length =
5116 MAX_ROOM_NEEDED (&a, dp->arg_index,
5117 dp->conversion, type, flags,
5118 width, has_precision,
5119 precision, pad_ourselves);
5121 if (maxlen < tmp_length)
5123 /* Make more room. But try to do through
5124 this reallocation only once. */
5125 size_t bigger_need =
5126 xsum (length,
5127 xsum (tmp_length,
5128 TCHARS_PER_DCHAR - 1)
5129 / TCHARS_PER_DCHAR);
5130 /* And always grow proportionally.
5131 (There may be several arguments, each
5132 needing a little more room than the
5133 previous one.) */
5134 size_t bigger_need2 =
5135 xsum (xtimes (allocated, 2), 12);
5136 if (bigger_need < bigger_need2)
5137 bigger_need = bigger_need2;
5138 ENSURE_ALLOCATION (bigger_need);
5139 continue;
5141 # endif
5143 else
5144 count = retcount;
5147 #endif
5149 /* Attempt to handle failure. */
5150 if (count < 0)
5152 /* SNPRINTF or sprintf failed. Save and use the errno
5153 that it has set, if any. */
5154 int saved_errno = errno;
5156 if (!(result == resultbuf || result == NULL))
5157 free (result);
5158 if (buf_malloced != NULL)
5159 free (buf_malloced);
5160 CLEANUP ();
5161 errno =
5162 (saved_errno != 0
5163 ? saved_errno
5164 : (dp->conversion == 'c' || dp->conversion == 's'
5165 ? EILSEQ
5166 : EINVAL));
5167 return NULL;
5170 #if USE_SNPRINTF
5171 /* Handle overflow of the allocated buffer.
5172 If such an overflow occurs, a C99 compliant snprintf()
5173 returns a count >= maxlen. However, a non-compliant
5174 snprintf() function returns only count = maxlen - 1. To
5175 cover both cases, test whether count >= maxlen - 1. */
5176 if ((unsigned int) count + 1 >= maxlen)
5178 /* If maxlen already has attained its allowed maximum,
5179 allocating more memory will not increase maxlen.
5180 Instead of looping, bail out. */
5181 if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
5182 goto overflow;
5183 else
5185 /* Need at least (count + 1) * sizeof (TCHAR_T)
5186 bytes. (The +1 is for the trailing NUL.)
5187 But ask for (count + 2) * sizeof (TCHAR_T)
5188 bytes, so that in the next round, we likely get
5189 maxlen > (unsigned int) count + 1
5190 and so we don't get here again.
5191 And allocate proportionally, to avoid looping
5192 eternally if snprintf() reports a too small
5193 count. */
5194 size_t n =
5195 xmax (xsum (length,
5196 ((unsigned int) count + 2
5197 + TCHARS_PER_DCHAR - 1)
5198 / TCHARS_PER_DCHAR),
5199 xtimes (allocated, 2));
5201 ENSURE_ALLOCATION (n);
5202 continue;
5205 #endif
5207 #if NEED_PRINTF_UNBOUNDED_PRECISION
5208 if (prec_ourselves)
5210 /* Handle the precision. */
5211 TCHAR_T *prec_ptr =
5212 # if USE_SNPRINTF
5213 (TCHAR_T *) (result + length);
5214 # else
5215 tmp;
5216 # endif
5217 size_t prefix_count;
5218 size_t move;
5220 prefix_count = 0;
5221 /* Put the additional zeroes after the sign. */
5222 if (count >= 1
5223 && (*prec_ptr == '-' || *prec_ptr == '+'
5224 || *prec_ptr == ' '))
5225 prefix_count = 1;
5226 /* Put the additional zeroes after the 0x prefix if
5227 (flags & FLAG_ALT) || (dp->conversion == 'p'). */
5228 else if (count >= 2
5229 && prec_ptr[0] == '0'
5230 && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
5231 prefix_count = 2;
5233 move = count - prefix_count;
5234 if (precision > move)
5236 /* Insert zeroes. */
5237 size_t insert = precision - move;
5238 TCHAR_T *prec_end;
5240 # if USE_SNPRINTF
5241 size_t n =
5242 xsum (length,
5243 (count + insert + TCHARS_PER_DCHAR - 1)
5244 / TCHARS_PER_DCHAR);
5245 length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5246 ENSURE_ALLOCATION (n);
5247 length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5248 prec_ptr = (TCHAR_T *) (result + length);
5249 # endif
5251 prec_end = prec_ptr + count;
5252 prec_ptr += prefix_count;
5254 while (prec_end > prec_ptr)
5256 prec_end--;
5257 prec_end[insert] = prec_end[0];
5260 prec_end += insert;
5262 *--prec_end = '0';
5263 while (prec_end > prec_ptr);
5265 count += insert;
5268 #endif
5270 #if !USE_SNPRINTF
5271 if (count >= tmp_length)
5272 /* tmp_length was incorrectly calculated - fix the
5273 code above! */
5274 abort ();
5275 #endif
5277 #if !DCHAR_IS_TCHAR
5278 /* Convert from TCHAR_T[] to DCHAR_T[]. */
5279 if (dp->conversion == 'c' || dp->conversion == 's')
5281 /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
5282 TYPE_WIDE_STRING.
5283 The result string is not certainly ASCII. */
5284 const TCHAR_T *tmpsrc;
5285 DCHAR_T *tmpdst;
5286 size_t tmpdst_len;
5287 /* This code assumes that TCHAR_T is 'char'. */
5288 typedef int TCHAR_T_verify
5289 [2 * (sizeof (TCHAR_T) == 1) - 1];
5290 # if USE_SNPRINTF
5291 tmpsrc = (TCHAR_T *) (result + length);
5292 # else
5293 tmpsrc = tmp;
5294 # endif
5295 tmpdst =
5296 DCHAR_CONV_FROM_ENCODING (locale_charset (),
5297 iconveh_question_mark,
5298 tmpsrc, count,
5299 NULL,
5300 NULL, &tmpdst_len);
5301 if (tmpdst == NULL)
5303 int saved_errno = errno;
5304 if (!(result == resultbuf || result == NULL))
5305 free (result);
5306 if (buf_malloced != NULL)
5307 free (buf_malloced);
5308 CLEANUP ();
5309 errno = saved_errno;
5310 return NULL;
5312 ENSURE_ALLOCATION (xsum (length, tmpdst_len));
5313 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
5314 free (tmpdst);
5315 count = tmpdst_len;
5317 else
5319 /* The result string is ASCII.
5320 Simple 1:1 conversion. */
5321 # if USE_SNPRINTF
5322 /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
5323 no-op conversion, in-place on the array starting
5324 at (result + length). */
5325 if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
5326 # endif
5328 const TCHAR_T *tmpsrc;
5329 DCHAR_T *tmpdst;
5330 size_t n;
5332 # if USE_SNPRINTF
5333 if (result == resultbuf)
5335 tmpsrc = (TCHAR_T *) (result + length);
5336 /* ENSURE_ALLOCATION will not move tmpsrc
5337 (because it's part of resultbuf). */
5338 ENSURE_ALLOCATION (xsum (length, count));
5340 else
5342 /* ENSURE_ALLOCATION will move the array
5343 (because it uses realloc(). */
5344 ENSURE_ALLOCATION (xsum (length, count));
5345 tmpsrc = (TCHAR_T *) (result + length);
5347 # else
5348 tmpsrc = tmp;
5349 ENSURE_ALLOCATION (xsum (length, count));
5350 # endif
5351 tmpdst = result + length;
5352 /* Copy backwards, because of overlapping. */
5353 tmpsrc += count;
5354 tmpdst += count;
5355 for (n = count; n > 0; n--)
5356 *--tmpdst = (unsigned char) *--tmpsrc;
5359 #endif
5361 #if DCHAR_IS_TCHAR && !USE_SNPRINTF
5362 /* Make room for the result. */
5363 if (count > allocated - length)
5365 /* Need at least count elements. But allocate
5366 proportionally. */
5367 size_t n =
5368 xmax (xsum (length, count), xtimes (allocated, 2));
5370 ENSURE_ALLOCATION (n);
5372 #endif
5374 /* Here count <= allocated - length. */
5376 /* Perform padding. */
5377 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5378 if (pad_ourselves && has_width)
5380 size_t w;
5381 # if ENABLE_UNISTDIO
5382 /* Outside POSIX, it's preferrable to compare the width
5383 against the number of _characters_ of the converted
5384 value. */
5385 w = DCHAR_MBSNLEN (result + length, count);
5386 # else
5387 /* The width is compared against the number of _bytes_
5388 of the converted value, says POSIX. */
5389 w = count;
5390 # endif
5391 if (w < width)
5393 size_t pad = width - w;
5395 /* Make room for the result. */
5396 if (xsum (count, pad) > allocated - length)
5398 /* Need at least count + pad elements. But
5399 allocate proportionally. */
5400 size_t n =
5401 xmax (xsum3 (length, count, pad),
5402 xtimes (allocated, 2));
5404 # if USE_SNPRINTF
5405 length += count;
5406 ENSURE_ALLOCATION (n);
5407 length -= count;
5408 # else
5409 ENSURE_ALLOCATION (n);
5410 # endif
5412 /* Here count + pad <= allocated - length. */
5415 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
5416 DCHAR_T * const rp = result + length;
5417 # else
5418 DCHAR_T * const rp = tmp;
5419 # endif
5420 DCHAR_T *p = rp + count;
5421 DCHAR_T *end = p + pad;
5422 DCHAR_T *pad_ptr;
5423 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
5424 if (dp->conversion == 'c'
5425 || dp->conversion == 's')
5426 /* No zero-padding for string directives. */
5427 pad_ptr = NULL;
5428 else
5429 # endif
5431 pad_ptr = (*rp == '-' ? rp + 1 : rp);
5432 /* No zero-padding of "inf" and "nan". */
5433 if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
5434 || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
5435 pad_ptr = NULL;
5437 /* The generated string now extends from rp to p,
5438 with the zero padding insertion point being at
5439 pad_ptr. */
5441 count = count + pad; /* = end - rp */
5443 if (flags & FLAG_LEFT)
5445 /* Pad with spaces on the right. */
5446 for (; pad > 0; pad--)
5447 *p++ = ' ';
5449 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
5451 /* Pad with zeroes. */
5452 DCHAR_T *q = end;
5454 while (p > pad_ptr)
5455 *--q = *--p;
5456 for (; pad > 0; pad--)
5457 *p++ = '0';
5459 else
5461 /* Pad with spaces on the left. */
5462 DCHAR_T *q = end;
5464 while (p > rp)
5465 *--q = *--p;
5466 for (; pad > 0; pad--)
5467 *p++ = ' ';
5472 #endif
5474 /* Here still count <= allocated - length. */
5476 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
5477 /* The snprintf() result did fit. */
5478 #else
5479 /* Append the sprintf() result. */
5480 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
5481 #endif
5482 #if !USE_SNPRINTF
5483 if (tmp != tmpbuf)
5484 free (tmp);
5485 #endif
5487 #if NEED_PRINTF_DIRECTIVE_F
5488 if (dp->conversion == 'F')
5490 /* Convert the %f result to upper case for %F. */
5491 DCHAR_T *rp = result + length;
5492 size_t rc;
5493 for (rc = count; rc > 0; rc--, rp++)
5494 if (*rp >= 'a' && *rp <= 'z')
5495 *rp = *rp - 'a' + 'A';
5497 #endif
5499 length += count;
5500 break;
5502 #undef pad_ourselves
5503 #undef prec_ourselves
5508 /* Add the final NUL. */
5509 ENSURE_ALLOCATION (xsum (length, 1));
5510 result[length] = '\0';
5512 if (result != resultbuf && length + 1 < allocated)
5514 /* Shrink the allocated memory if possible. */
5515 DCHAR_T *memory;
5517 memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
5518 if (memory != NULL)
5519 result = memory;
5522 if (buf_malloced != NULL)
5523 free (buf_malloced);
5524 CLEANUP ();
5525 *lengthp = length;
5526 /* Note that we can produce a big string of a length > INT_MAX. POSIX
5527 says that snprintf() fails with errno = EOVERFLOW in this case, but
5528 that's only because snprintf() returns an 'int'. This function does
5529 not have this limitation. */
5530 return result;
5532 #if USE_SNPRINTF
5533 overflow:
5534 if (!(result == resultbuf || result == NULL))
5535 free (result);
5536 if (buf_malloced != NULL)
5537 free (buf_malloced);
5538 CLEANUP ();
5539 errno = EOVERFLOW;
5540 return NULL;
5541 #endif
5543 out_of_memory:
5544 if (!(result == resultbuf || result == NULL))
5545 free (result);
5546 if (buf_malloced != NULL)
5547 free (buf_malloced);
5548 out_of_memory_1:
5549 CLEANUP ();
5550 errno = ENOMEM;
5551 return NULL;
5555 #undef MAX_ROOM_NEEDED
5556 #undef TCHARS_PER_DCHAR
5557 #undef SNPRINTF
5558 #undef USE_SNPRINTF
5559 #undef DCHAR_SET
5560 #undef DCHAR_CPY
5561 #undef PRINTF_PARSE
5562 #undef DIRECTIVES
5563 #undef DIRECTIVE
5564 #undef DCHAR_IS_TCHAR
5565 #undef TCHAR_T
5566 #undef DCHAR_T
5567 #undef FCHAR_T
5568 #undef VASNPRINTF