unistr/u{8,16,32}-uctomb: Avoid possible trouble with huge strings.
[gnulib.git] / lib / vasnprintf.c
blob7f75139560778244a5a33075bb4840ddf5de86c1
1 /* vsprintf with automatic memory allocation.
2 Copyright (C) 1999, 2002-2020 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, see <https://www.gnu.org/licenses/>. */
17 /* This file can be parametrized with the following macros:
18 VASNPRINTF The name of the function being defined.
19 FCHAR_T The element type of the format string.
20 DCHAR_T The element type of the destination (result) string.
21 FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
22 in the format string are ASCII. MUST be set if
23 FCHAR_T and DCHAR_T are not the same type.
24 DIRECTIVE Structure denoting a format directive.
25 Depends on FCHAR_T.
26 DIRECTIVES Structure denoting the set of format directives of a
27 format string. Depends on FCHAR_T.
28 PRINTF_PARSE Function that parses a format string.
29 Depends on FCHAR_T.
30 DCHAR_CPY memcpy like function for DCHAR_T[] arrays.
31 DCHAR_SET memset like function for DCHAR_T[] arrays.
32 DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays.
33 SNPRINTF The system's snprintf (or similar) function.
34 This may be either snprintf or swprintf.
35 TCHAR_T The element type of the argument and result string
36 of the said SNPRINTF function. This may be either
37 char or wchar_t. The code exploits that
38 sizeof (TCHAR_T) | sizeof (DCHAR_T) and
39 alignof (TCHAR_T) <= alignof (DCHAR_T).
40 DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type.
41 DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
42 DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t.
43 DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t.
44 DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t.
45 ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions.
46 ENABLE_WCHAR_FALLBACK Set to 1 to avoid EILSEQ during conversion of wide
47 characters (wchar_t) and wide character strings
48 (wchar_t[]) to multibyte sequences. The fallback is the
49 hexadecimal escape syntax (\unnnn or \Unnnnnnnn) or,
50 if wchar_t is not Unicode encoded, \wnnnn or \Wnnnnnnnn.
53 /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
54 This must come before <config.h> because <config.h> may include
55 <features.h>, and once <features.h> has been included, it's too late. */
56 #ifndef _GNU_SOURCE
57 # define _GNU_SOURCE 1
58 #endif
60 #ifndef VASNPRINTF
61 # include <config.h>
62 #endif
63 #ifndef IN_LIBINTL
64 # include <alloca.h>
65 #endif
67 /* Specification. */
68 #ifndef VASNPRINTF
69 # if WIDE_CHAR_VERSION
70 # include "vasnwprintf.h"
71 # else
72 # include "vasnprintf.h"
73 # endif
74 #endif
76 #include <locale.h> /* localeconv() */
77 #include <stdio.h> /* snprintf(), sprintf() */
78 #include <stdlib.h> /* abort(), malloc(), realloc(), free() */
79 #include <string.h> /* memcpy(), strlen() */
80 #include <errno.h> /* errno */
81 #include <limits.h> /* CHAR_BIT */
82 #include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
83 #if HAVE_NL_LANGINFO
84 # include <langinfo.h>
85 #endif
86 #ifndef VASNPRINTF
87 # if WIDE_CHAR_VERSION
88 # include "wprintf-parse.h"
89 # else
90 # include "printf-parse.h"
91 # endif
92 #endif
94 /* Checked size_t computations. */
95 #include "xsize.h"
97 #include "attribute.h"
98 #include "verify.h"
100 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
101 # include <math.h>
102 # include "float+.h"
103 #endif
105 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
106 # include <math.h>
107 # include "isnand-nolibm.h"
108 #endif
110 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
111 # include <math.h>
112 # include "isnanl-nolibm.h"
113 # include "fpucw.h"
114 #endif
116 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
117 # include <math.h>
118 # include "isnand-nolibm.h"
119 # include "printf-frexp.h"
120 #endif
122 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
123 # include <math.h>
124 # include "isnanl-nolibm.h"
125 # include "printf-frexpl.h"
126 # include "fpucw.h"
127 #endif
129 /* Default parameters. */
130 #ifndef VASNPRINTF
131 # if WIDE_CHAR_VERSION
132 # define VASNPRINTF vasnwprintf
133 # define FCHAR_T wchar_t
134 # define DCHAR_T wchar_t
135 # define TCHAR_T wchar_t
136 # define DCHAR_IS_TCHAR 1
137 # define DIRECTIVE wchar_t_directive
138 # define DIRECTIVES wchar_t_directives
139 # define PRINTF_PARSE wprintf_parse
140 # define DCHAR_CPY wmemcpy
141 # define DCHAR_SET wmemset
142 # else
143 # define VASNPRINTF vasnprintf
144 # define FCHAR_T char
145 # define DCHAR_T char
146 # define TCHAR_T char
147 # define DCHAR_IS_TCHAR 1
148 # define DIRECTIVE char_directive
149 # define DIRECTIVES char_directives
150 # define PRINTF_PARSE printf_parse
151 # define DCHAR_CPY memcpy
152 # define DCHAR_SET memset
153 # endif
154 #endif
155 #if WIDE_CHAR_VERSION
156 /* TCHAR_T is wchar_t. */
157 # define USE_SNPRINTF 1
158 # if HAVE_DECL__SNWPRINTF
159 /* On Windows, the function swprintf() has a different signature than
160 on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
161 instead. The mingw function snwprintf() has fewer bugs than the
162 MSVCRT function _snwprintf(), so prefer that. */
163 # if defined __MINGW32__
164 # define SNPRINTF snwprintf
165 # else
166 # define SNPRINTF _snwprintf
167 # define USE_MSVC__SNPRINTF 1
168 # endif
169 # else
170 /* Unix. */
171 # define SNPRINTF swprintf
172 # endif
173 #else
174 /* TCHAR_T is char. */
175 /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
176 But don't use it on BeOS, since BeOS snprintf produces no output if the
177 size argument is >= 0x3000000.
178 Also don't use it on Linux libc5, since there snprintf with size = 1
179 writes any output without bounds, like sprintf. */
180 # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
181 # define USE_SNPRINTF 1
182 # else
183 # define USE_SNPRINTF 0
184 # endif
185 # if HAVE_DECL__SNPRINTF
186 /* Windows. The mingw function snprintf() has fewer bugs than the MSVCRT
187 function _snprintf(), so prefer that. */
188 # if defined __MINGW32__
189 # define SNPRINTF snprintf
190 /* Here we need to call the native snprintf, not rpl_snprintf. */
191 # undef snprintf
192 # else
193 /* MSVC versions < 14 did not have snprintf, only _snprintf. */
194 # define SNPRINTF _snprintf
195 # define USE_MSVC__SNPRINTF 1
196 # endif
197 # else
198 /* Unix. */
199 # define SNPRINTF snprintf
200 /* Here we need to call the native snprintf, not rpl_snprintf. */
201 # undef snprintf
202 # endif
203 #endif
204 /* Here we need to call the native sprintf, not rpl_sprintf. */
205 #undef sprintf
207 /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
208 warnings in this file. Use -Dlint to suppress them. */
209 #if defined GCC_LINT || defined lint
210 # define IF_LINT(Code) Code
211 #else
212 # define IF_LINT(Code) /* empty */
213 #endif
215 /* Avoid some warnings from "gcc -Wshadow".
216 This file doesn't use the exp() and remainder() functions. */
217 #undef exp
218 #define exp expo
219 #undef remainder
220 #define remainder rem
222 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && !WIDE_CHAR_VERSION
223 # if (HAVE_STRNLEN && !defined _AIX)
224 # define local_strnlen strnlen
225 # else
226 # ifndef local_strnlen_defined
227 # define local_strnlen_defined 1
228 static size_t
229 local_strnlen (const char *string, size_t maxlen)
231 const char *end = memchr (string, '\0', maxlen);
232 return end ? (size_t) (end - string) : maxlen;
234 # endif
235 # endif
236 #endif
238 #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
239 # if HAVE_WCSLEN
240 # define local_wcslen wcslen
241 # else
242 /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
243 a dependency towards this library, here is a local substitute.
244 Define this substitute only once, even if this file is included
245 twice in the same compilation unit. */
246 # ifndef local_wcslen_defined
247 # define local_wcslen_defined 1
248 static size_t
249 local_wcslen (const wchar_t *s)
251 const wchar_t *ptr;
253 for (ptr = s; *ptr != (wchar_t) 0; ptr++)
255 return ptr - s;
257 # endif
258 # endif
259 #endif
261 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
262 # if HAVE_WCSNLEN
263 # define local_wcsnlen wcsnlen
264 # else
265 # ifndef local_wcsnlen_defined
266 # define local_wcsnlen_defined 1
267 static size_t
268 local_wcsnlen (const wchar_t *s, size_t maxlen)
270 const wchar_t *ptr;
272 for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
274 return ptr - s;
276 # endif
277 # endif
278 #endif
280 #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T) || (ENABLE_WCHAR_FALLBACK && HAVE_WINT_T)) && !WIDE_CHAR_VERSION
281 # if ENABLE_WCHAR_FALLBACK
282 static size_t
283 wctomb_fallback (char *s, wchar_t wc)
285 static char hex[16] = "0123456789ABCDEF";
287 s[0] = '\\';
288 if (sizeof (wchar_t) > 2 && wc > 0xffff)
290 # if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
291 s[1] = 'U';
292 # else
293 s[1] = 'W';
294 # endif
295 s[2] = hex[(wc & 0xf0000000U) >> 28];
296 s[3] = hex[(wc & 0xf000000U) >> 24];
297 s[4] = hex[(wc & 0xf00000U) >> 20];
298 s[5] = hex[(wc & 0xf0000U) >> 16];
299 s[6] = hex[(wc & 0xf000U) >> 12];
300 s[7] = hex[(wc & 0xf00U) >> 8];
301 s[8] = hex[(wc & 0xf0U) >> 4];
302 s[9] = hex[wc & 0xfU];
303 return 10;
305 else
307 # if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
308 s[1] = 'u';
309 # else
310 s[1] = 'w';
311 # endif
312 s[2] = hex[(wc & 0xf000U) >> 12];
313 s[3] = hex[(wc & 0xf00U) >> 8];
314 s[4] = hex[(wc & 0xf0U) >> 4];
315 s[5] = hex[wc & 0xfU];
316 return 6;
319 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
320 static size_t
321 local_wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
323 size_t count = wcrtomb (s, wc, ps);
324 if (count == (size_t)(-1))
325 count = wctomb_fallback (s, wc);
326 return count;
328 # else
329 static int
330 local_wctomb (char *s, wchar_t wc)
332 int count = wctomb (s, wc);
333 if (count < 0)
334 count = wctomb_fallback (s, wc);
335 return count;
337 # define local_wcrtomb(S, WC, PS) local_wctomb ((S), (WC))
338 # endif
339 # else
340 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
341 # define local_wcrtomb(S, WC, PS) wcrtomb ((S), (WC), (PS))
342 # else
343 # define local_wcrtomb(S, WC, PS) wctomb ((S), (WC))
344 # endif
345 # endif
346 #endif
348 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
349 /* Determine the decimal-point character according to the current locale. */
350 # ifndef decimal_point_char_defined
351 # define decimal_point_char_defined 1
352 static char
353 decimal_point_char (void)
355 const char *point;
356 /* Determine it in a multithread-safe way. We know nl_langinfo is
357 multithread-safe on glibc systems and Mac OS X systems, but is not required
358 to be multithread-safe by POSIX. sprintf(), however, is multithread-safe.
359 localeconv() is rarely multithread-safe. */
360 # if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__))
361 point = nl_langinfo (RADIXCHAR);
362 # elif 1
363 char pointbuf[5];
364 sprintf (pointbuf, "%#.0f", 1.0);
365 point = &pointbuf[1];
366 # else
367 point = localeconv () -> decimal_point;
368 # endif
369 /* The decimal point is always a single byte: either '.' or ','. */
370 return (point[0] != '\0' ? point[0] : '.');
372 # endif
373 #endif
375 #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
377 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
378 static int
379 is_infinite_or_zero (double x)
381 return isnand (x) || x + x == x;
384 #endif
386 #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
388 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
389 static int
390 is_infinite_or_zerol (long double x)
392 return isnanl (x) || x + x == x;
395 #endif
397 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
399 /* Converting 'long double' to decimal without rare rounding bugs requires
400 real bignums. We use the naming conventions of GNU gmp, but vastly simpler
401 (and slower) algorithms. */
403 typedef unsigned int mp_limb_t;
404 # define GMP_LIMB_BITS 32
405 verify (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS);
407 typedef unsigned long long mp_twolimb_t;
408 # define GMP_TWOLIMB_BITS 64
409 verify (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS);
411 /* Representation of a bignum >= 0. */
412 typedef struct
414 size_t nlimbs;
415 mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */
416 } mpn_t;
418 /* Compute the product of two bignums >= 0.
419 Return the allocated memory in case of success, NULL in case of memory
420 allocation failure. */
421 static void *
422 multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
424 const mp_limb_t *p1;
425 const mp_limb_t *p2;
426 size_t len1;
427 size_t len2;
429 if (src1.nlimbs <= src2.nlimbs)
431 len1 = src1.nlimbs;
432 p1 = src1.limbs;
433 len2 = src2.nlimbs;
434 p2 = src2.limbs;
436 else
438 len1 = src2.nlimbs;
439 p1 = src2.limbs;
440 len2 = src1.nlimbs;
441 p2 = src1.limbs;
443 /* Now 0 <= len1 <= len2. */
444 if (len1 == 0)
446 /* src1 or src2 is zero. */
447 dest->nlimbs = 0;
448 dest->limbs = (mp_limb_t *) malloc (1);
450 else
452 /* Here 1 <= len1 <= len2. */
453 size_t dlen;
454 mp_limb_t *dp;
455 size_t k, i, j;
457 dlen = len1 + len2;
458 dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
459 if (dp == NULL)
460 return NULL;
461 for (k = len2; k > 0; )
462 dp[--k] = 0;
463 for (i = 0; i < len1; i++)
465 mp_limb_t digit1 = p1[i];
466 mp_twolimb_t carry = 0;
467 for (j = 0; j < len2; j++)
469 mp_limb_t digit2 = p2[j];
470 carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
471 carry += dp[i + j];
472 dp[i + j] = (mp_limb_t) carry;
473 carry = carry >> GMP_LIMB_BITS;
475 dp[i + len2] = (mp_limb_t) carry;
477 /* Normalise. */
478 while (dlen > 0 && dp[dlen - 1] == 0)
479 dlen--;
480 dest->nlimbs = dlen;
481 dest->limbs = dp;
483 return dest->limbs;
486 /* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
487 a is written as a = q * b + r with 0 <= r < b. q is the quotient, r
488 the remainder.
489 Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
490 q is incremented.
491 Return the allocated memory in case of success, NULL in case of memory
492 allocation failure. */
493 static void *
494 divide (mpn_t a, mpn_t b, mpn_t *q)
496 /* Algorithm:
497 First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
498 with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
499 If m<n, then q:=0 and r:=a.
500 If m>=n=1, perform a single-precision division:
501 r:=0, j:=m,
502 while j>0 do
503 {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
504 = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
505 j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
506 Normalise [q[m-1],...,q[0]], yields q.
507 If m>=n>1, perform a multiple-precision division:
508 We have a/b < beta^(m-n+1).
509 s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
510 Shift a and b left by s bits, copying them. r:=a.
511 r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
512 For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
513 Compute q* :
514 q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
515 In case of overflow (q* >= beta) set q* := beta-1.
516 Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
517 and c3 := b[n-2] * q*.
518 {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
519 occurred. Furthermore 0 <= c3 < beta^2.
520 If there was overflow and
521 r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
522 the next test can be skipped.}
523 While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
524 Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
525 If q* > 0:
526 Put r := r - b * q* * beta^j. In detail:
527 [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
528 hence: u:=0, for i:=0 to n-1 do
529 u := u + q* * b[i],
530 r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
531 u:=u div beta (+ 1, if carry in subtraction)
532 r[n+j]:=r[n+j]-u.
533 {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
534 < q* + 1 <= beta,
535 the carry u does not overflow.}
536 If a negative carry occurs, put q* := q* - 1
537 and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
538 Set q[j] := q*.
539 Normalise [q[m-n],..,q[0]]; this yields the quotient q.
540 Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
541 rest r.
542 The room for q[j] can be allocated at the memory location of r[n+j].
543 Finally, round-to-even:
544 Shift r left by 1 bit.
545 If r > b or if r = b and q[0] is odd, q := q+1.
547 const mp_limb_t *a_ptr = a.limbs;
548 size_t a_len = a.nlimbs;
549 const mp_limb_t *b_ptr = b.limbs;
550 size_t b_len = b.nlimbs;
551 mp_limb_t *roomptr;
552 mp_limb_t *tmp_roomptr = NULL;
553 mp_limb_t *q_ptr;
554 size_t q_len;
555 mp_limb_t *r_ptr;
556 size_t r_len;
558 /* Allocate room for a_len+2 digits.
559 (Need a_len+1 digits for the real division and 1 more digit for the
560 final rounding of q.) */
561 roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
562 if (roomptr == NULL)
563 return NULL;
565 /* Normalise a. */
566 while (a_len > 0 && a_ptr[a_len - 1] == 0)
567 a_len--;
569 /* Normalise b. */
570 for (;;)
572 if (b_len == 0)
573 /* Division by zero. */
574 abort ();
575 if (b_ptr[b_len - 1] == 0)
576 b_len--;
577 else
578 break;
581 /* Here m = a_len >= 0 and n = b_len > 0. */
583 if (a_len < b_len)
585 /* m<n: trivial case. q=0, r := copy of a. */
586 r_ptr = roomptr;
587 r_len = a_len;
588 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
589 q_ptr = roomptr + a_len;
590 q_len = 0;
592 else if (b_len == 1)
594 /* n=1: single precision division.
595 beta^(m-1) <= a < beta^m ==> beta^(m-2) <= a/b < beta^m */
596 r_ptr = roomptr;
597 q_ptr = roomptr + 1;
599 mp_limb_t den = b_ptr[0];
600 mp_limb_t remainder = 0;
601 const mp_limb_t *sourceptr = a_ptr + a_len;
602 mp_limb_t *destptr = q_ptr + a_len;
603 size_t count;
604 for (count = a_len; count > 0; count--)
606 mp_twolimb_t num =
607 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
608 *--destptr = num / den;
609 remainder = num % den;
611 /* Normalise and store r. */
612 if (remainder > 0)
614 r_ptr[0] = remainder;
615 r_len = 1;
617 else
618 r_len = 0;
619 /* Normalise q. */
620 q_len = a_len;
621 if (q_ptr[q_len - 1] == 0)
622 q_len--;
625 else
627 /* n>1: multiple precision division.
628 beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n ==>
629 beta^(m-n-1) <= a/b < beta^(m-n+1). */
630 /* Determine s. */
631 size_t s;
633 mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
634 /* Determine s = GMP_LIMB_BITS - integer_length (msd).
635 Code copied from gnulib's integer_length.c. */
636 # if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) \
637 || (__clang_major__ >= 4)
638 s = __builtin_clz (msd);
639 # else
640 # if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
641 if (GMP_LIMB_BITS <= DBL_MANT_BIT)
643 /* Use 'double' operations.
644 Assumes an IEEE 754 'double' implementation. */
645 # define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
646 # define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1)
647 # define NWORDS \
648 ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
649 union { double value; unsigned int word[NWORDS]; } m;
651 /* Use a single integer to floating-point conversion. */
652 m.value = msd;
654 s = GMP_LIMB_BITS
655 - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK)
656 - DBL_EXP_BIAS);
658 else
659 # undef NWORDS
660 # endif
662 s = 31;
663 if (msd >= 0x10000)
665 msd = msd >> 16;
666 s -= 16;
668 if (msd >= 0x100)
670 msd = msd >> 8;
671 s -= 8;
673 if (msd >= 0x10)
675 msd = msd >> 4;
676 s -= 4;
678 if (msd >= 0x4)
680 msd = msd >> 2;
681 s -= 2;
683 if (msd >= 0x2)
685 msd = msd >> 1;
686 s -= 1;
689 # endif
691 /* 0 <= s < GMP_LIMB_BITS.
692 Copy b, shifting it left by s bits. */
693 if (s > 0)
695 tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
696 if (tmp_roomptr == NULL)
698 free (roomptr);
699 return NULL;
702 const mp_limb_t *sourceptr = b_ptr;
703 mp_limb_t *destptr = tmp_roomptr;
704 mp_twolimb_t accu = 0;
705 size_t count;
706 for (count = b_len; count > 0; count--)
708 accu += (mp_twolimb_t) *sourceptr++ << s;
709 *destptr++ = (mp_limb_t) accu;
710 accu = accu >> GMP_LIMB_BITS;
712 /* accu must be zero, since that was how s was determined. */
713 if (accu != 0)
714 abort ();
716 b_ptr = tmp_roomptr;
718 /* Copy a, shifting it left by s bits, yields r.
719 Memory layout:
720 At the beginning: r = roomptr[0..a_len],
721 at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len] */
722 r_ptr = roomptr;
723 if (s == 0)
725 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
726 r_ptr[a_len] = 0;
728 else
730 const mp_limb_t *sourceptr = a_ptr;
731 mp_limb_t *destptr = r_ptr;
732 mp_twolimb_t accu = 0;
733 size_t count;
734 for (count = a_len; count > 0; count--)
736 accu += (mp_twolimb_t) *sourceptr++ << s;
737 *destptr++ = (mp_limb_t) accu;
738 accu = accu >> GMP_LIMB_BITS;
740 *destptr++ = (mp_limb_t) accu;
742 q_ptr = roomptr + b_len;
743 q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
745 size_t j = a_len - b_len; /* m-n */
746 mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
747 mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
748 mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
749 ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
750 /* Division loop, traversed m-n+1 times.
751 j counts down, b is unchanged, beta/2 <= b[n-1] < beta. */
752 for (;;)
754 mp_limb_t q_star;
755 mp_limb_t c1;
756 if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
758 /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow. */
759 mp_twolimb_t num =
760 ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
761 | r_ptr[j + b_len - 1];
762 q_star = num / b_msd;
763 c1 = num % b_msd;
765 else
767 /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1]. */
768 q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
769 /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
770 <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
771 <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
772 {<= beta !}.
773 If yes, jump directly to the subtraction loop.
774 (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
775 <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
776 if (r_ptr[j + b_len] > b_msd
777 || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
778 /* r[j+n] >= b[n-1]+1 or
779 r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
780 carry. */
781 goto subtract;
783 /* q_star = q*,
784 c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta). */
786 mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
787 ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
788 mp_twolimb_t c3 = /* b[n-2] * q* */
789 (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
790 /* While c2 < c3, increase c2 and decrease c3.
791 Consider c3-c2. While it is > 0, decrease it by
792 b[n-1]*beta+b[n-2]. Because of b[n-1]*beta+b[n-2] >= beta^2/2
793 this can happen only twice. */
794 if (c3 > c2)
796 q_star = q_star - 1; /* q* := q* - 1 */
797 if (c3 - c2 > b_msdd)
798 q_star = q_star - 1; /* q* := q* - 1 */
801 if (q_star > 0)
802 subtract:
804 /* Subtract r := r - b * q* * beta^j. */
805 mp_limb_t cr;
807 const mp_limb_t *sourceptr = b_ptr;
808 mp_limb_t *destptr = r_ptr + j;
809 mp_twolimb_t carry = 0;
810 size_t count;
811 for (count = b_len; count > 0; count--)
813 /* Here 0 <= carry <= q*. */
814 carry =
815 carry
816 + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
817 + (mp_limb_t) ~(*destptr);
818 /* Here 0 <= carry <= beta*q* + beta-1. */
819 *destptr++ = ~(mp_limb_t) carry;
820 carry = carry >> GMP_LIMB_BITS; /* <= q* */
822 cr = (mp_limb_t) carry;
824 /* Subtract cr from r_ptr[j + b_len], then forget about
825 r_ptr[j + b_len]. */
826 if (cr > r_ptr[j + b_len])
828 /* Subtraction gave a carry. */
829 q_star = q_star - 1; /* q* := q* - 1 */
830 /* Add b back. */
832 const mp_limb_t *sourceptr = b_ptr;
833 mp_limb_t *destptr = r_ptr + j;
834 mp_limb_t carry = 0;
835 size_t count;
836 for (count = b_len; count > 0; count--)
838 mp_limb_t source1 = *sourceptr++;
839 mp_limb_t source2 = *destptr;
840 *destptr++ = source1 + source2 + carry;
841 carry =
842 (carry
843 ? source1 >= (mp_limb_t) ~source2
844 : source1 > (mp_limb_t) ~source2);
847 /* Forget about the carry and about r[j+n]. */
850 /* q* is determined. Store it as q[j]. */
851 q_ptr[j] = q_star;
852 if (j == 0)
853 break;
854 j--;
857 r_len = b_len;
858 /* Normalise q. */
859 if (q_ptr[q_len - 1] == 0)
860 q_len--;
861 # if 0 /* Not needed here, since we need r only to compare it with b/2, and
862 b is shifted left by s bits. */
863 /* Shift r right by s bits. */
864 if (s > 0)
866 mp_limb_t ptr = r_ptr + r_len;
867 mp_twolimb_t accu = 0;
868 size_t count;
869 for (count = r_len; count > 0; count--)
871 accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
872 accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
873 *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
876 # endif
877 /* Normalise r. */
878 while (r_len > 0 && r_ptr[r_len - 1] == 0)
879 r_len--;
881 /* Compare r << 1 with b. */
882 if (r_len > b_len)
883 goto increment_q;
885 size_t i;
886 for (i = b_len;;)
888 mp_limb_t r_i =
889 (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
890 | (i < r_len ? r_ptr[i] << 1 : 0);
891 mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
892 if (r_i > b_i)
893 goto increment_q;
894 if (r_i < b_i)
895 goto keep_q;
896 if (i == 0)
897 break;
898 i--;
901 if (q_len > 0 && ((q_ptr[0] & 1) != 0))
902 /* q is odd. */
903 increment_q:
905 size_t i;
906 for (i = 0; i < q_len; i++)
907 if (++(q_ptr[i]) != 0)
908 goto keep_q;
909 q_ptr[q_len++] = 1;
911 keep_q:
912 if (tmp_roomptr != NULL)
913 free (tmp_roomptr);
914 q->limbs = q_ptr;
915 q->nlimbs = q_len;
916 return roomptr;
919 /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
920 representation.
921 Destroys the contents of a.
922 Return the allocated memory - containing the decimal digits in low-to-high
923 order, terminated with a NUL character - in case of success, NULL in case
924 of memory allocation failure. */
925 static char *
926 convert_to_decimal (mpn_t a, size_t extra_zeroes)
928 mp_limb_t *a_ptr = a.limbs;
929 size_t a_len = a.nlimbs;
930 /* 0.03345 is slightly larger than log(2)/(9*log(10)). */
931 size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
932 /* We need extra_zeroes bytes for zeroes, followed by c_len bytes for the
933 digits of a, followed by 1 byte for the terminating NUL. */
934 char *c_ptr = (char *) malloc (xsum (xsum (extra_zeroes, c_len), 1));
935 if (c_ptr != NULL)
937 char *d_ptr = c_ptr;
938 for (; extra_zeroes > 0; extra_zeroes--)
939 *d_ptr++ = '0';
940 while (a_len > 0)
942 /* Divide a by 10^9, in-place. */
943 mp_limb_t remainder = 0;
944 mp_limb_t *ptr = a_ptr + a_len;
945 size_t count;
946 for (count = a_len; count > 0; count--)
948 mp_twolimb_t num =
949 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
950 *ptr = num / 1000000000;
951 remainder = num % 1000000000;
953 /* Store the remainder as 9 decimal digits. */
954 for (count = 9; count > 0; count--)
956 *d_ptr++ = '0' + (remainder % 10);
957 remainder = remainder / 10;
959 /* Normalize a. */
960 if (a_ptr[a_len - 1] == 0)
961 a_len--;
963 /* Remove leading zeroes. */
964 while (d_ptr > c_ptr && d_ptr[-1] == '0')
965 d_ptr--;
966 /* But keep at least one zero. */
967 if (d_ptr == c_ptr)
968 *d_ptr++ = '0';
969 /* Terminate the string. */
970 *d_ptr = '\0';
972 return c_ptr;
975 # if NEED_PRINTF_LONG_DOUBLE
977 /* Assuming x is finite and >= 0:
978 write x as x = 2^e * m, where m is a bignum.
979 Return the allocated memory in case of success, NULL in case of memory
980 allocation failure. */
981 static void *
982 decode_long_double (long double x, int *ep, mpn_t *mp)
984 mpn_t m;
985 int exp;
986 long double y;
987 size_t i;
989 /* Allocate memory for result. */
990 m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
991 m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
992 if (m.limbs == NULL)
993 return NULL;
994 /* Split into exponential part and mantissa. */
995 y = frexpl (x, &exp);
996 if (!(y >= 0.0L && y < 1.0L))
997 abort ();
998 /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the
999 latter is an integer. */
1000 /* Convert the mantissa (y * 2^LDBL_MANT_BIT) to a sequence of limbs.
1001 I'm not sure whether it's safe to cast a 'long double' value between
1002 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
1003 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
1004 doesn't matter). */
1005 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
1006 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
1008 mp_limb_t hi, lo;
1009 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
1010 hi = (int) y;
1011 y -= hi;
1012 if (!(y >= 0.0L && y < 1.0L))
1013 abort ();
1014 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1015 lo = (int) y;
1016 y -= lo;
1017 if (!(y >= 0.0L && y < 1.0L))
1018 abort ();
1019 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1021 # else
1023 mp_limb_t d;
1024 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
1025 d = (int) y;
1026 y -= d;
1027 if (!(y >= 0.0L && y < 1.0L))
1028 abort ();
1029 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
1031 # endif
1032 # endif
1033 for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1035 mp_limb_t hi, lo;
1036 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1037 hi = (int) y;
1038 y -= hi;
1039 if (!(y >= 0.0L && y < 1.0L))
1040 abort ();
1041 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1042 lo = (int) y;
1043 y -= lo;
1044 if (!(y >= 0.0L && y < 1.0L))
1045 abort ();
1046 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1048 # if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
1049 precision. */
1050 if (!(y == 0.0L))
1051 abort ();
1052 # endif
1053 /* Normalise. */
1054 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
1055 m.nlimbs--;
1056 *mp = m;
1057 *ep = exp - LDBL_MANT_BIT;
1058 return m.limbs;
1061 # endif
1063 # if NEED_PRINTF_DOUBLE
1065 /* Assuming x is finite and >= 0:
1066 write x as x = 2^e * m, where m is a bignum.
1067 Return the allocated memory in case of success, NULL in case of memory
1068 allocation failure. */
1069 static void *
1070 decode_double (double x, int *ep, mpn_t *mp)
1072 mpn_t m;
1073 int exp;
1074 double y;
1075 size_t i;
1077 /* Allocate memory for result. */
1078 m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
1079 m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
1080 if (m.limbs == NULL)
1081 return NULL;
1082 /* Split into exponential part and mantissa. */
1083 y = frexp (x, &exp);
1084 if (!(y >= 0.0 && y < 1.0))
1085 abort ();
1086 /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * 2^DBL_MANT_BIT), and the
1087 latter is an integer. */
1088 /* Convert the mantissa (y * 2^DBL_MANT_BIT) to a sequence of limbs.
1089 I'm not sure whether it's safe to cast a 'double' value between
1090 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
1091 'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
1092 doesn't matter). */
1093 # if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
1094 # if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
1096 mp_limb_t hi, lo;
1097 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
1098 hi = (int) y;
1099 y -= hi;
1100 if (!(y >= 0.0 && y < 1.0))
1101 abort ();
1102 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1103 lo = (int) y;
1104 y -= lo;
1105 if (!(y >= 0.0 && y < 1.0))
1106 abort ();
1107 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1109 # else
1111 mp_limb_t d;
1112 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
1113 d = (int) y;
1114 y -= d;
1115 if (!(y >= 0.0 && y < 1.0))
1116 abort ();
1117 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
1119 # endif
1120 # endif
1121 for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1123 mp_limb_t hi, lo;
1124 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1125 hi = (int) y;
1126 y -= hi;
1127 if (!(y >= 0.0 && y < 1.0))
1128 abort ();
1129 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1130 lo = (int) y;
1131 y -= lo;
1132 if (!(y >= 0.0 && y < 1.0))
1133 abort ();
1134 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1136 if (!(y == 0.0))
1137 abort ();
1138 /* Normalise. */
1139 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
1140 m.nlimbs--;
1141 *mp = m;
1142 *ep = exp - DBL_MANT_BIT;
1143 return m.limbs;
1146 # endif
1148 /* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
1149 Returns the decimal representation of round (x * 10^n).
1150 Return the allocated memory - containing the decimal digits in low-to-high
1151 order, terminated with a NUL character - in case of success, NULL in case
1152 of memory allocation failure. */
1153 static char *
1154 scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
1156 int s;
1157 size_t extra_zeroes;
1158 unsigned int abs_n;
1159 unsigned int abs_s;
1160 mp_limb_t *pow5_ptr;
1161 size_t pow5_len;
1162 unsigned int s_limbs;
1163 unsigned int s_bits;
1164 mpn_t pow5;
1165 mpn_t z;
1166 void *z_memory;
1167 char *digits;
1169 if (memory == NULL)
1170 return NULL;
1171 /* x = 2^e * m, hence
1172 y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
1173 = round (2^s * 5^n * m). */
1174 s = e + n;
1175 extra_zeroes = 0;
1176 /* Factor out a common power of 10 if possible. */
1177 if (s > 0 && n > 0)
1179 extra_zeroes = (s < n ? s : n);
1180 s -= extra_zeroes;
1181 n -= extra_zeroes;
1183 /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
1184 Before converting to decimal, we need to compute
1185 z = round (2^s * 5^n * m). */
1186 /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
1187 sign. 2.322 is slightly larger than log(5)/log(2). */
1188 abs_n = (n >= 0 ? n : -n);
1189 abs_s = (s >= 0 ? s : -s);
1190 pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
1191 + abs_s / GMP_LIMB_BITS + 1)
1192 * sizeof (mp_limb_t));
1193 if (pow5_ptr == NULL)
1195 free (memory);
1196 return NULL;
1198 /* Initialize with 1. */
1199 pow5_ptr[0] = 1;
1200 pow5_len = 1;
1201 /* Multiply with 5^|n|. */
1202 if (abs_n > 0)
1204 static mp_limb_t const small_pow5[13 + 1] =
1206 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
1207 48828125, 244140625, 1220703125
1209 unsigned int n13;
1210 for (n13 = 0; n13 <= abs_n; n13 += 13)
1212 mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
1213 size_t j;
1214 mp_twolimb_t carry = 0;
1215 for (j = 0; j < pow5_len; j++)
1217 mp_limb_t digit2 = pow5_ptr[j];
1218 carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
1219 pow5_ptr[j] = (mp_limb_t) carry;
1220 carry = carry >> GMP_LIMB_BITS;
1222 if (carry > 0)
1223 pow5_ptr[pow5_len++] = (mp_limb_t) carry;
1226 s_limbs = abs_s / GMP_LIMB_BITS;
1227 s_bits = abs_s % GMP_LIMB_BITS;
1228 if (n >= 0 ? s >= 0 : s <= 0)
1230 /* Multiply with 2^|s|. */
1231 if (s_bits > 0)
1233 mp_limb_t *ptr = pow5_ptr;
1234 mp_twolimb_t accu = 0;
1235 size_t count;
1236 for (count = pow5_len; count > 0; count--)
1238 accu += (mp_twolimb_t) *ptr << s_bits;
1239 *ptr++ = (mp_limb_t) accu;
1240 accu = accu >> GMP_LIMB_BITS;
1242 if (accu > 0)
1244 *ptr = (mp_limb_t) accu;
1245 pow5_len++;
1248 if (s_limbs > 0)
1250 size_t count;
1251 for (count = pow5_len; count > 0;)
1253 count--;
1254 pow5_ptr[s_limbs + count] = pow5_ptr[count];
1256 for (count = s_limbs; count > 0;)
1258 count--;
1259 pow5_ptr[count] = 0;
1261 pow5_len += s_limbs;
1263 pow5.limbs = pow5_ptr;
1264 pow5.nlimbs = pow5_len;
1265 if (n >= 0)
1267 /* Multiply m with pow5. No division needed. */
1268 z_memory = multiply (m, pow5, &z);
1270 else
1272 /* Divide m by pow5 and round. */
1273 z_memory = divide (m, pow5, &z);
1276 else
1278 pow5.limbs = pow5_ptr;
1279 pow5.nlimbs = pow5_len;
1280 if (n >= 0)
1282 /* n >= 0, s < 0.
1283 Multiply m with pow5, then divide by 2^|s|. */
1284 mpn_t numerator;
1285 mpn_t denominator;
1286 void *tmp_memory;
1287 tmp_memory = multiply (m, pow5, &numerator);
1288 if (tmp_memory == NULL)
1290 free (pow5_ptr);
1291 free (memory);
1292 return NULL;
1294 /* Construct 2^|s|. */
1296 mp_limb_t *ptr = pow5_ptr + pow5_len;
1297 size_t i;
1298 for (i = 0; i < s_limbs; i++)
1299 ptr[i] = 0;
1300 ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
1301 denominator.limbs = ptr;
1302 denominator.nlimbs = s_limbs + 1;
1304 z_memory = divide (numerator, denominator, &z);
1305 free (tmp_memory);
1307 else
1309 /* n < 0, s > 0.
1310 Multiply m with 2^s, then divide by pow5. */
1311 mpn_t numerator;
1312 mp_limb_t *num_ptr;
1313 num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
1314 * sizeof (mp_limb_t));
1315 if (num_ptr == NULL)
1317 free (pow5_ptr);
1318 free (memory);
1319 return NULL;
1322 mp_limb_t *destptr = num_ptr;
1324 size_t i;
1325 for (i = 0; i < s_limbs; i++)
1326 *destptr++ = 0;
1328 if (s_bits > 0)
1330 const mp_limb_t *sourceptr = m.limbs;
1331 mp_twolimb_t accu = 0;
1332 size_t count;
1333 for (count = m.nlimbs; count > 0; count--)
1335 accu += (mp_twolimb_t) *sourceptr++ << s_bits;
1336 *destptr++ = (mp_limb_t) accu;
1337 accu = accu >> GMP_LIMB_BITS;
1339 if (accu > 0)
1340 *destptr++ = (mp_limb_t) accu;
1342 else
1344 const mp_limb_t *sourceptr = m.limbs;
1345 size_t count;
1346 for (count = m.nlimbs; count > 0; count--)
1347 *destptr++ = *sourceptr++;
1349 numerator.limbs = num_ptr;
1350 numerator.nlimbs = destptr - num_ptr;
1352 z_memory = divide (numerator, pow5, &z);
1353 free (num_ptr);
1356 free (pow5_ptr);
1357 free (memory);
1359 /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */
1361 if (z_memory == NULL)
1362 return NULL;
1363 digits = convert_to_decimal (z, extra_zeroes);
1364 free (z_memory);
1365 return digits;
1368 # if NEED_PRINTF_LONG_DOUBLE
1370 /* Assuming x is finite and >= 0, and n is an integer:
1371 Returns the decimal representation of round (x * 10^n).
1372 Return the allocated memory - containing the decimal digits in low-to-high
1373 order, terminated with a NUL character - in case of success, NULL in case
1374 of memory allocation failure. */
1375 static char *
1376 scale10_round_decimal_long_double (long double x, int n)
1378 int e IF_LINT(= 0);
1379 mpn_t m;
1380 void *memory = decode_long_double (x, &e, &m);
1381 return scale10_round_decimal_decoded (e, m, memory, n);
1384 # endif
1386 # if NEED_PRINTF_DOUBLE
1388 /* Assuming x is finite and >= 0, and n is an integer:
1389 Returns the decimal representation of round (x * 10^n).
1390 Return the allocated memory - containing the decimal digits in low-to-high
1391 order, terminated with a NUL character - in case of success, NULL in case
1392 of memory allocation failure. */
1393 static char *
1394 scale10_round_decimal_double (double x, int n)
1396 int e IF_LINT(= 0);
1397 mpn_t m;
1398 void *memory = decode_double (x, &e, &m);
1399 return scale10_round_decimal_decoded (e, m, memory, n);
1402 # endif
1404 # if NEED_PRINTF_LONG_DOUBLE
1406 /* Assuming x is finite and > 0:
1407 Return an approximation for n with 10^n <= x < 10^(n+1).
1408 The approximation is usually the right n, but may be off by 1 sometimes. */
1409 static int
1410 floorlog10l (long double x)
1412 int exp;
1413 long double y;
1414 double z;
1415 double l;
1417 /* Split into exponential part and mantissa. */
1418 y = frexpl (x, &exp);
1419 if (!(y >= 0.0L && y < 1.0L))
1420 abort ();
1421 if (y == 0.0L)
1422 return INT_MIN;
1423 if (y < 0.5L)
1425 while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1427 y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1428 exp -= GMP_LIMB_BITS;
1430 if (y < (1.0L / (1 << 16)))
1432 y *= 1.0L * (1 << 16);
1433 exp -= 16;
1435 if (y < (1.0L / (1 << 8)))
1437 y *= 1.0L * (1 << 8);
1438 exp -= 8;
1440 if (y < (1.0L / (1 << 4)))
1442 y *= 1.0L * (1 << 4);
1443 exp -= 4;
1445 if (y < (1.0L / (1 << 2)))
1447 y *= 1.0L * (1 << 2);
1448 exp -= 2;
1450 if (y < (1.0L / (1 << 1)))
1452 y *= 1.0L * (1 << 1);
1453 exp -= 1;
1456 if (!(y >= 0.5L && y < 1.0L))
1457 abort ();
1458 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1459 l = exp;
1460 z = y;
1461 if (z < 0.70710678118654752444)
1463 z *= 1.4142135623730950488;
1464 l -= 0.5;
1466 if (z < 0.8408964152537145431)
1468 z *= 1.1892071150027210667;
1469 l -= 0.25;
1471 if (z < 0.91700404320467123175)
1473 z *= 1.0905077326652576592;
1474 l -= 0.125;
1476 if (z < 0.9576032806985736469)
1478 z *= 1.0442737824274138403;
1479 l -= 0.0625;
1481 /* Now 0.95 <= z <= 1.01. */
1482 z = 1 - z;
1483 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1484 Four terms are enough to get an approximation with error < 10^-7. */
1485 l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1486 /* Finally multiply with log(2)/log(10), yields an approximation for
1487 log10(x). */
1488 l *= 0.30102999566398119523;
1489 /* Round down to the next integer. */
1490 return (int) l + (l < 0 ? -1 : 0);
1493 # endif
1495 # if NEED_PRINTF_DOUBLE
1497 /* Assuming x is finite and > 0:
1498 Return an approximation for n with 10^n <= x < 10^(n+1).
1499 The approximation is usually the right n, but may be off by 1 sometimes. */
1500 static int
1501 floorlog10 (double x)
1503 int exp;
1504 double y;
1505 double z;
1506 double l;
1508 /* Split into exponential part and mantissa. */
1509 y = frexp (x, &exp);
1510 if (!(y >= 0.0 && y < 1.0))
1511 abort ();
1512 if (y == 0.0)
1513 return INT_MIN;
1514 if (y < 0.5)
1516 while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1518 y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1519 exp -= GMP_LIMB_BITS;
1521 if (y < (1.0 / (1 << 16)))
1523 y *= 1.0 * (1 << 16);
1524 exp -= 16;
1526 if (y < (1.0 / (1 << 8)))
1528 y *= 1.0 * (1 << 8);
1529 exp -= 8;
1531 if (y < (1.0 / (1 << 4)))
1533 y *= 1.0 * (1 << 4);
1534 exp -= 4;
1536 if (y < (1.0 / (1 << 2)))
1538 y *= 1.0 * (1 << 2);
1539 exp -= 2;
1541 if (y < (1.0 / (1 << 1)))
1543 y *= 1.0 * (1 << 1);
1544 exp -= 1;
1547 if (!(y >= 0.5 && y < 1.0))
1548 abort ();
1549 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1550 l = exp;
1551 z = y;
1552 if (z < 0.70710678118654752444)
1554 z *= 1.4142135623730950488;
1555 l -= 0.5;
1557 if (z < 0.8408964152537145431)
1559 z *= 1.1892071150027210667;
1560 l -= 0.25;
1562 if (z < 0.91700404320467123175)
1564 z *= 1.0905077326652576592;
1565 l -= 0.125;
1567 if (z < 0.9576032806985736469)
1569 z *= 1.0442737824274138403;
1570 l -= 0.0625;
1572 /* Now 0.95 <= z <= 1.01. */
1573 z = 1 - z;
1574 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1575 Four terms are enough to get an approximation with error < 10^-7. */
1576 l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1577 /* Finally multiply with log(2)/log(10), yields an approximation for
1578 log10(x). */
1579 l *= 0.30102999566398119523;
1580 /* Round down to the next integer. */
1581 return (int) l + (l < 0 ? -1 : 0);
1584 # endif
1586 /* Tests whether a string of digits consists of exactly PRECISION zeroes and
1587 a single '1' digit. */
1588 static int
1589 is_borderline (const char *digits, size_t precision)
1591 for (; precision > 0; precision--, digits++)
1592 if (*digits != '0')
1593 return 0;
1594 if (*digits != '1')
1595 return 0;
1596 digits++;
1597 return *digits == '\0';
1600 #endif
1602 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
1604 /* Use a different function name, to make it possible that the 'wchar_t'
1605 parametrization and the 'char' parametrization get compiled in the same
1606 translation unit. */
1607 # if WIDE_CHAR_VERSION
1608 # define MAX_ROOM_NEEDED wmax_room_needed
1609 # else
1610 # define MAX_ROOM_NEEDED max_room_needed
1611 # endif
1613 /* Returns the number of TCHAR_T units needed as temporary space for the result
1614 of sprintf or SNPRINTF of a single conversion directive. */
1615 static size_t
1616 MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
1617 arg_type type, int flags, size_t width, int has_precision,
1618 size_t precision, int pad_ourselves)
1620 size_t tmp_length;
1622 switch (conversion)
1624 case 'd': case 'i': case 'u':
1625 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1626 tmp_length =
1627 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1628 * 0.30103 /* binary -> decimal */
1630 + 1; /* turn floor into ceil */
1631 else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1632 tmp_length =
1633 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1634 * 0.30103 /* binary -> decimal */
1636 + 1; /* turn floor into ceil */
1637 else
1638 tmp_length =
1639 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1640 * 0.30103 /* binary -> decimal */
1642 + 1; /* turn floor into ceil */
1643 if (tmp_length < precision)
1644 tmp_length = precision;
1645 /* Multiply by 2, as an estimate for FLAG_GROUP. */
1646 tmp_length = xsum (tmp_length, tmp_length);
1647 /* Add 1, to account for a leading sign. */
1648 tmp_length = xsum (tmp_length, 1);
1649 break;
1651 case 'o':
1652 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1653 tmp_length =
1654 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1655 * 0.333334 /* binary -> octal */
1657 + 1; /* turn floor into ceil */
1658 else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1659 tmp_length =
1660 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1661 * 0.333334 /* binary -> octal */
1663 + 1; /* turn floor into ceil */
1664 else
1665 tmp_length =
1666 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1667 * 0.333334 /* binary -> octal */
1669 + 1; /* turn floor into ceil */
1670 if (tmp_length < precision)
1671 tmp_length = precision;
1672 /* Add 1, to account for a leading sign. */
1673 tmp_length = xsum (tmp_length, 1);
1674 break;
1676 case 'x': case 'X':
1677 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1678 tmp_length =
1679 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1680 * 0.25 /* binary -> hexadecimal */
1682 + 1; /* turn floor into ceil */
1683 else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1684 tmp_length =
1685 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1686 * 0.25 /* binary -> hexadecimal */
1688 + 1; /* turn floor into ceil */
1689 else
1690 tmp_length =
1691 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1692 * 0.25 /* binary -> hexadecimal */
1694 + 1; /* turn floor into ceil */
1695 if (tmp_length < precision)
1696 tmp_length = precision;
1697 /* Add 2, to account for a leading sign or alternate form. */
1698 tmp_length = xsum (tmp_length, 2);
1699 break;
1701 case 'f': case 'F':
1702 if (type == TYPE_LONGDOUBLE)
1703 tmp_length =
1704 (unsigned int) (LDBL_MAX_EXP
1705 * 0.30103 /* binary -> decimal */
1706 * 2 /* estimate for FLAG_GROUP */
1708 + 1 /* turn floor into ceil */
1709 + 10; /* sign, decimal point etc. */
1710 else
1711 tmp_length =
1712 (unsigned int) (DBL_MAX_EXP
1713 * 0.30103 /* binary -> decimal */
1714 * 2 /* estimate for FLAG_GROUP */
1716 + 1 /* turn floor into ceil */
1717 + 10; /* sign, decimal point etc. */
1718 tmp_length = xsum (tmp_length, precision);
1719 break;
1721 case 'e': case 'E': case 'g': case 'G':
1722 tmp_length =
1723 12; /* sign, decimal point, exponent etc. */
1724 tmp_length = xsum (tmp_length, precision);
1725 break;
1727 case 'a': case 'A':
1728 if (type == TYPE_LONGDOUBLE)
1729 tmp_length =
1730 (unsigned int) (LDBL_DIG
1731 * 0.831 /* decimal -> hexadecimal */
1733 + 1; /* turn floor into ceil */
1734 else
1735 tmp_length =
1736 (unsigned int) (DBL_DIG
1737 * 0.831 /* decimal -> hexadecimal */
1739 + 1; /* turn floor into ceil */
1740 if (tmp_length < precision)
1741 tmp_length = precision;
1742 /* Account for sign, decimal point etc. */
1743 tmp_length = xsum (tmp_length, 12);
1744 break;
1746 case 'c':
1747 # if HAVE_WINT_T && !WIDE_CHAR_VERSION
1748 if (type == TYPE_WIDE_CHAR)
1750 tmp_length = MB_CUR_MAX;
1751 # if ENABLE_WCHAR_FALLBACK
1752 if (tmp_length < (sizeof (wchar_t) > 2 ? 10 : 6))
1753 tmp_length = (sizeof (wchar_t) > 2 ? 10 : 6);
1754 # endif
1756 else
1757 # endif
1758 tmp_length = 1;
1759 break;
1761 case 's':
1762 # if HAVE_WCHAR_T
1763 if (type == TYPE_WIDE_STRING)
1765 # if WIDE_CHAR_VERSION
1766 /* ISO C says about %ls in fwprintf:
1767 "If the precision is not specified or is greater than the size
1768 of the array, the array shall contain a null wide character."
1769 So if there is a precision, we must not use wcslen. */
1770 const wchar_t *arg = ap->arg[arg_index].a.a_wide_string;
1772 if (has_precision)
1773 tmp_length = local_wcsnlen (arg, precision);
1774 else
1775 tmp_length = local_wcslen (arg);
1776 # else
1777 /* ISO C says about %ls in fprintf:
1778 "If a precision is specified, no more than that many bytes are
1779 written (including shift sequences, if any), and the array
1780 shall contain a null wide character if, to equal the multibyte
1781 character sequence length given by the precision, the function
1782 would need to access a wide character one past the end of the
1783 array."
1784 So if there is a precision, we must not use wcslen. */
1785 /* This case has already been handled separately in VASNPRINTF. */
1786 abort ();
1787 # endif
1789 else
1790 # endif
1792 # if WIDE_CHAR_VERSION
1793 /* ISO C says about %s in fwprintf:
1794 "If the precision is not specified or is greater than the size
1795 of the converted array, the converted array shall contain a
1796 null wide character."
1797 So if there is a precision, we must not use strlen. */
1798 /* This case has already been handled separately in VASNPRINTF. */
1799 abort ();
1800 # else
1801 /* ISO C says about %s in fprintf:
1802 "If the precision is not specified or greater than the size of
1803 the array, the array shall contain a null character."
1804 So if there is a precision, we must not use strlen. */
1805 const char *arg = ap->arg[arg_index].a.a_string;
1807 if (has_precision)
1808 tmp_length = local_strnlen (arg, precision);
1809 else
1810 tmp_length = strlen (arg);
1811 # endif
1813 break;
1815 case 'p':
1816 tmp_length =
1817 (unsigned int) (sizeof (void *) * CHAR_BIT
1818 * 0.25 /* binary -> hexadecimal */
1820 + 1 /* turn floor into ceil */
1821 + 2; /* account for leading 0x */
1822 break;
1824 default:
1825 abort ();
1828 if (!pad_ourselves)
1830 # if ENABLE_UNISTDIO
1831 /* Padding considers the number of characters, therefore the number of
1832 elements after padding may be
1833 > max (tmp_length, width)
1834 but is certainly
1835 <= tmp_length + width. */
1836 tmp_length = xsum (tmp_length, width);
1837 # else
1838 /* Padding considers the number of elements, says POSIX. */
1839 if (tmp_length < width)
1840 tmp_length = width;
1841 # endif
1844 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
1846 return tmp_length;
1849 #endif
1851 DCHAR_T *
1852 VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
1853 const FCHAR_T *format, va_list args)
1855 DIRECTIVES d;
1856 arguments a;
1858 if (PRINTF_PARSE (format, &d, &a) < 0)
1859 /* errno is already set. */
1860 return NULL;
1862 #define CLEANUP() \
1863 if (d.dir != d.direct_alloc_dir) \
1864 free (d.dir); \
1865 if (a.arg != a.direct_alloc_arg) \
1866 free (a.arg);
1868 if (PRINTF_FETCHARGS (args, &a) < 0)
1870 CLEANUP ();
1871 errno = EINVAL;
1872 return NULL;
1876 size_t buf_neededlength;
1877 TCHAR_T *buf;
1878 TCHAR_T *buf_malloced;
1879 const FCHAR_T *cp;
1880 size_t i;
1881 DIRECTIVE *dp;
1882 /* Output string accumulator. */
1883 DCHAR_T *result;
1884 size_t allocated;
1885 size_t length;
1887 /* Allocate a small buffer that will hold a directive passed to
1888 sprintf or snprintf. */
1889 buf_neededlength =
1890 xsum4 (7, d.max_width_length, d.max_precision_length, 6);
1891 #if HAVE_ALLOCA
1892 if (buf_neededlength < 4000 / sizeof (TCHAR_T))
1894 buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
1895 buf_malloced = NULL;
1897 else
1898 #endif
1900 size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
1901 if (size_overflow_p (buf_memsize))
1902 goto out_of_memory_1;
1903 buf = (TCHAR_T *) malloc (buf_memsize);
1904 if (buf == NULL)
1905 goto out_of_memory_1;
1906 buf_malloced = buf;
1909 if (resultbuf != NULL)
1911 result = resultbuf;
1912 allocated = *lengthp;
1914 else
1916 result = NULL;
1917 allocated = 0;
1919 length = 0;
1920 /* Invariants:
1921 result is either == resultbuf or == NULL or malloc-allocated.
1922 If length > 0, then result != NULL. */
1924 /* Ensures that allocated >= needed. Aborts through a jump to
1925 out_of_memory if needed is SIZE_MAX or otherwise too big. */
1926 #define ENSURE_ALLOCATION(needed) \
1927 if ((needed) > allocated) \
1929 size_t memory_size; \
1930 DCHAR_T *memory; \
1932 allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \
1933 if ((needed) > allocated) \
1934 allocated = (needed); \
1935 memory_size = xtimes (allocated, sizeof (DCHAR_T)); \
1936 if (size_overflow_p (memory_size)) \
1937 goto out_of_memory; \
1938 if (result == resultbuf || result == NULL) \
1939 memory = (DCHAR_T *) malloc (memory_size); \
1940 else \
1941 memory = (DCHAR_T *) realloc (result, memory_size); \
1942 if (memory == NULL) \
1943 goto out_of_memory; \
1944 if (result == resultbuf && length > 0) \
1945 DCHAR_CPY (memory, result, length); \
1946 result = memory; \
1949 for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
1951 if (cp != dp->dir_start)
1953 size_t n = dp->dir_start - cp;
1954 size_t augmented_length = xsum (length, n);
1956 ENSURE_ALLOCATION (augmented_length);
1957 /* This copies a piece of FCHAR_T[] into a DCHAR_T[]. Here we
1958 need that the format string contains only ASCII characters
1959 if FCHAR_T and DCHAR_T are not the same type. */
1960 if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
1962 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
1963 length = augmented_length;
1965 else
1968 result[length++] = *cp++;
1969 while (--n > 0);
1972 if (i == d.count)
1973 break;
1975 /* Execute a single directive. */
1976 if (dp->conversion == '%')
1978 size_t augmented_length;
1980 if (!(dp->arg_index == ARG_NONE))
1981 abort ();
1982 augmented_length = xsum (length, 1);
1983 ENSURE_ALLOCATION (augmented_length);
1984 result[length] = '%';
1985 length = augmented_length;
1987 else
1989 if (!(dp->arg_index != ARG_NONE))
1990 abort ();
1992 if (dp->conversion == 'n')
1994 switch (a.arg[dp->arg_index].type)
1996 case TYPE_COUNT_SCHAR_POINTER:
1997 *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
1998 break;
1999 case TYPE_COUNT_SHORT_POINTER:
2000 *a.arg[dp->arg_index].a.a_count_short_pointer = length;
2001 break;
2002 case TYPE_COUNT_INT_POINTER:
2003 *a.arg[dp->arg_index].a.a_count_int_pointer = length;
2004 break;
2005 case TYPE_COUNT_LONGINT_POINTER:
2006 *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
2007 break;
2008 case TYPE_COUNT_LONGLONGINT_POINTER:
2009 *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
2010 break;
2011 default:
2012 abort ();
2015 #if ENABLE_UNISTDIO
2016 /* The unistdio extensions. */
2017 else if (dp->conversion == 'U')
2019 arg_type type = a.arg[dp->arg_index].type;
2020 int flags = dp->flags;
2021 int has_width;
2022 size_t width;
2023 int has_precision;
2024 size_t precision;
2026 has_width = 0;
2027 width = 0;
2028 if (dp->width_start != dp->width_end)
2030 if (dp->width_arg_index != ARG_NONE)
2032 int arg;
2034 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2035 abort ();
2036 arg = a.arg[dp->width_arg_index].a.a_int;
2037 width = arg;
2038 if (arg < 0)
2040 /* "A negative field width is taken as a '-' flag
2041 followed by a positive field width." */
2042 flags |= FLAG_LEFT;
2043 width = -width;
2046 else
2048 const FCHAR_T *digitp = dp->width_start;
2051 width = xsum (xtimes (width, 10), *digitp++ - '0');
2052 while (digitp != dp->width_end);
2054 has_width = 1;
2057 has_precision = 0;
2058 precision = 0;
2059 if (dp->precision_start != dp->precision_end)
2061 if (dp->precision_arg_index != ARG_NONE)
2063 int arg;
2065 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2066 abort ();
2067 arg = a.arg[dp->precision_arg_index].a.a_int;
2068 /* "A negative precision is taken as if the precision
2069 were omitted." */
2070 if (arg >= 0)
2072 precision = arg;
2073 has_precision = 1;
2076 else
2078 const FCHAR_T *digitp = dp->precision_start + 1;
2080 precision = 0;
2081 while (digitp != dp->precision_end)
2082 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2083 has_precision = 1;
2087 switch (type)
2089 case TYPE_U8_STRING:
2091 const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
2092 const uint8_t *arg_end;
2093 size_t characters;
2095 if (has_precision)
2097 /* Use only PRECISION characters, from the left. */
2098 arg_end = arg;
2099 characters = 0;
2100 for (; precision > 0; precision--)
2102 int count = u8_strmblen (arg_end);
2103 if (count == 0)
2104 break;
2105 if (count < 0)
2107 if (!(result == resultbuf || result == NULL))
2108 free (result);
2109 if (buf_malloced != NULL)
2110 free (buf_malloced);
2111 CLEANUP ();
2112 errno = EILSEQ;
2113 return NULL;
2115 arg_end += count;
2116 characters++;
2119 else if (has_width)
2121 /* Use the entire string, and count the number of
2122 characters. */
2123 arg_end = arg;
2124 characters = 0;
2125 for (;;)
2127 int count = u8_strmblen (arg_end);
2128 if (count == 0)
2129 break;
2130 if (count < 0)
2132 if (!(result == resultbuf || result == NULL))
2133 free (result);
2134 if (buf_malloced != NULL)
2135 free (buf_malloced);
2136 CLEANUP ();
2137 errno = EILSEQ;
2138 return NULL;
2140 arg_end += count;
2141 characters++;
2144 else
2146 /* Use the entire string. */
2147 arg_end = arg + u8_strlen (arg);
2148 /* The number of characters doesn't matter. */
2149 characters = 0;
2152 if (characters < width && !(dp->flags & FLAG_LEFT))
2154 size_t n = width - characters;
2155 ENSURE_ALLOCATION (xsum (length, n));
2156 DCHAR_SET (result + length, ' ', n);
2157 length += n;
2160 # if DCHAR_IS_UINT8_T
2162 size_t n = arg_end - arg;
2163 ENSURE_ALLOCATION (xsum (length, n));
2164 DCHAR_CPY (result + length, arg, n);
2165 length += n;
2167 # else
2168 { /* Convert. */
2169 DCHAR_T *converted = result + length;
2170 size_t converted_len = allocated - length;
2171 # if DCHAR_IS_TCHAR
2172 /* Convert from UTF-8 to locale encoding. */
2173 converted =
2174 u8_conv_to_encoding (locale_charset (),
2175 iconveh_question_mark,
2176 arg, arg_end - arg, NULL,
2177 converted, &converted_len);
2178 # else
2179 /* Convert from UTF-8 to UTF-16/UTF-32. */
2180 converted =
2181 U8_TO_DCHAR (arg, arg_end - arg,
2182 converted, &converted_len);
2183 # endif
2184 if (converted == NULL)
2186 int saved_errno = errno;
2187 if (!(result == resultbuf || result == NULL))
2188 free (result);
2189 if (buf_malloced != NULL)
2190 free (buf_malloced);
2191 CLEANUP ();
2192 errno = saved_errno;
2193 return NULL;
2195 if (converted != result + length)
2197 ENSURE_ALLOCATION (xsum (length, converted_len));
2198 DCHAR_CPY (result + length, converted, converted_len);
2199 free (converted);
2201 length += converted_len;
2203 # endif
2205 if (characters < width && (dp->flags & FLAG_LEFT))
2207 size_t n = width - characters;
2208 ENSURE_ALLOCATION (xsum (length, n));
2209 DCHAR_SET (result + length, ' ', n);
2210 length += n;
2213 break;
2215 case TYPE_U16_STRING:
2217 const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
2218 const uint16_t *arg_end;
2219 size_t characters;
2221 if (has_precision)
2223 /* Use only PRECISION characters, from the left. */
2224 arg_end = arg;
2225 characters = 0;
2226 for (; precision > 0; precision--)
2228 int count = u16_strmblen (arg_end);
2229 if (count == 0)
2230 break;
2231 if (count < 0)
2233 if (!(result == resultbuf || result == NULL))
2234 free (result);
2235 if (buf_malloced != NULL)
2236 free (buf_malloced);
2237 CLEANUP ();
2238 errno = EILSEQ;
2239 return NULL;
2241 arg_end += count;
2242 characters++;
2245 else if (has_width)
2247 /* Use the entire string, and count the number of
2248 characters. */
2249 arg_end = arg;
2250 characters = 0;
2251 for (;;)
2253 int count = u16_strmblen (arg_end);
2254 if (count == 0)
2255 break;
2256 if (count < 0)
2258 if (!(result == resultbuf || result == NULL))
2259 free (result);
2260 if (buf_malloced != NULL)
2261 free (buf_malloced);
2262 CLEANUP ();
2263 errno = EILSEQ;
2264 return NULL;
2266 arg_end += count;
2267 characters++;
2270 else
2272 /* Use the entire string. */
2273 arg_end = arg + u16_strlen (arg);
2274 /* The number of characters doesn't matter. */
2275 characters = 0;
2278 if (characters < width && !(dp->flags & FLAG_LEFT))
2280 size_t n = width - characters;
2281 ENSURE_ALLOCATION (xsum (length, n));
2282 DCHAR_SET (result + length, ' ', n);
2283 length += n;
2286 # if DCHAR_IS_UINT16_T
2288 size_t n = arg_end - arg;
2289 ENSURE_ALLOCATION (xsum (length, n));
2290 DCHAR_CPY (result + length, arg, n);
2291 length += n;
2293 # else
2294 { /* Convert. */
2295 DCHAR_T *converted = result + length;
2296 size_t converted_len = allocated - length;
2297 # if DCHAR_IS_TCHAR
2298 /* Convert from UTF-16 to locale encoding. */
2299 converted =
2300 u16_conv_to_encoding (locale_charset (),
2301 iconveh_question_mark,
2302 arg, arg_end - arg, NULL,
2303 converted, &converted_len);
2304 # else
2305 /* Convert from UTF-16 to UTF-8/UTF-32. */
2306 converted =
2307 U16_TO_DCHAR (arg, arg_end - arg,
2308 converted, &converted_len);
2309 # endif
2310 if (converted == NULL)
2312 int saved_errno = errno;
2313 if (!(result == resultbuf || result == NULL))
2314 free (result);
2315 if (buf_malloced != NULL)
2316 free (buf_malloced);
2317 CLEANUP ();
2318 errno = saved_errno;
2319 return NULL;
2321 if (converted != result + length)
2323 ENSURE_ALLOCATION (xsum (length, converted_len));
2324 DCHAR_CPY (result + length, converted, converted_len);
2325 free (converted);
2327 length += converted_len;
2329 # endif
2331 if (characters < width && (dp->flags & FLAG_LEFT))
2333 size_t n = width - characters;
2334 ENSURE_ALLOCATION (xsum (length, n));
2335 DCHAR_SET (result + length, ' ', n);
2336 length += n;
2339 break;
2341 case TYPE_U32_STRING:
2343 const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
2344 const uint32_t *arg_end;
2345 size_t characters;
2347 if (has_precision)
2349 /* Use only PRECISION characters, from the left. */
2350 arg_end = arg;
2351 characters = 0;
2352 for (; precision > 0; precision--)
2354 int count = u32_strmblen (arg_end);
2355 if (count == 0)
2356 break;
2357 if (count < 0)
2359 if (!(result == resultbuf || result == NULL))
2360 free (result);
2361 if (buf_malloced != NULL)
2362 free (buf_malloced);
2363 CLEANUP ();
2364 errno = EILSEQ;
2365 return NULL;
2367 arg_end += count;
2368 characters++;
2371 else if (has_width)
2373 /* Use the entire string, and count the number of
2374 characters. */
2375 arg_end = arg;
2376 characters = 0;
2377 for (;;)
2379 int count = u32_strmblen (arg_end);
2380 if (count == 0)
2381 break;
2382 if (count < 0)
2384 if (!(result == resultbuf || result == NULL))
2385 free (result);
2386 if (buf_malloced != NULL)
2387 free (buf_malloced);
2388 CLEANUP ();
2389 errno = EILSEQ;
2390 return NULL;
2392 arg_end += count;
2393 characters++;
2396 else
2398 /* Use the entire string. */
2399 arg_end = arg + u32_strlen (arg);
2400 /* The number of characters doesn't matter. */
2401 characters = 0;
2404 if (characters < width && !(dp->flags & FLAG_LEFT))
2406 size_t n = width - characters;
2407 ENSURE_ALLOCATION (xsum (length, n));
2408 DCHAR_SET (result + length, ' ', n);
2409 length += n;
2412 # if DCHAR_IS_UINT32_T
2414 size_t n = arg_end - arg;
2415 ENSURE_ALLOCATION (xsum (length, n));
2416 DCHAR_CPY (result + length, arg, n);
2417 length += n;
2419 # else
2420 { /* Convert. */
2421 DCHAR_T *converted = result + length;
2422 size_t converted_len = allocated - length;
2423 # if DCHAR_IS_TCHAR
2424 /* Convert from UTF-32 to locale encoding. */
2425 converted =
2426 u32_conv_to_encoding (locale_charset (),
2427 iconveh_question_mark,
2428 arg, arg_end - arg, NULL,
2429 converted, &converted_len);
2430 # else
2431 /* Convert from UTF-32 to UTF-8/UTF-16. */
2432 converted =
2433 U32_TO_DCHAR (arg, arg_end - arg,
2434 converted, &converted_len);
2435 # endif
2436 if (converted == NULL)
2438 int saved_errno = errno;
2439 if (!(result == resultbuf || result == NULL))
2440 free (result);
2441 if (buf_malloced != NULL)
2442 free (buf_malloced);
2443 CLEANUP ();
2444 errno = saved_errno;
2445 return NULL;
2447 if (converted != result + length)
2449 ENSURE_ALLOCATION (xsum (length, converted_len));
2450 DCHAR_CPY (result + length, converted, converted_len);
2451 free (converted);
2453 length += converted_len;
2455 # endif
2457 if (characters < width && (dp->flags & FLAG_LEFT))
2459 size_t n = width - characters;
2460 ENSURE_ALLOCATION (xsum (length, n));
2461 DCHAR_SET (result + length, ' ', n);
2462 length += n;
2465 break;
2467 default:
2468 abort ();
2471 #endif
2472 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T
2473 else if (dp->conversion == 's'
2474 # if WIDE_CHAR_VERSION
2475 && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
2476 # else
2477 && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
2478 # endif
2481 /* The normal handling of the 's' directive below requires
2482 allocating a temporary buffer. The determination of its
2483 length (tmp_length), in the case when a precision is
2484 specified, below requires a conversion between a char[]
2485 string and a wchar_t[] wide string. It could be done, but
2486 we have no guarantee that the implementation of sprintf will
2487 use the exactly same algorithm. Without this guarantee, it
2488 is possible to have buffer overrun bugs. In order to avoid
2489 such bugs, we implement the entire processing of the 's'
2490 directive ourselves. */
2491 int flags = dp->flags;
2492 int has_width;
2493 size_t width;
2494 int has_precision;
2495 size_t precision;
2497 has_width = 0;
2498 width = 0;
2499 if (dp->width_start != dp->width_end)
2501 if (dp->width_arg_index != ARG_NONE)
2503 int arg;
2505 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2506 abort ();
2507 arg = a.arg[dp->width_arg_index].a.a_int;
2508 width = arg;
2509 if (arg < 0)
2511 /* "A negative field width is taken as a '-' flag
2512 followed by a positive field width." */
2513 flags |= FLAG_LEFT;
2514 width = -width;
2517 else
2519 const FCHAR_T *digitp = dp->width_start;
2522 width = xsum (xtimes (width, 10), *digitp++ - '0');
2523 while (digitp != dp->width_end);
2525 has_width = 1;
2528 has_precision = 0;
2529 precision = 6;
2530 if (dp->precision_start != dp->precision_end)
2532 if (dp->precision_arg_index != ARG_NONE)
2534 int arg;
2536 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2537 abort ();
2538 arg = a.arg[dp->precision_arg_index].a.a_int;
2539 /* "A negative precision is taken as if the precision
2540 were omitted." */
2541 if (arg >= 0)
2543 precision = arg;
2544 has_precision = 1;
2547 else
2549 const FCHAR_T *digitp = dp->precision_start + 1;
2551 precision = 0;
2552 while (digitp != dp->precision_end)
2553 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2554 has_precision = 1;
2558 # if WIDE_CHAR_VERSION
2559 /* %s in vasnwprintf. See the specification of fwprintf. */
2561 const char *arg = a.arg[dp->arg_index].a.a_string;
2562 const char *arg_end;
2563 size_t characters;
2565 if (has_precision)
2567 /* Use only as many bytes as needed to produce PRECISION
2568 wide characters, from the left. */
2569 # if HAVE_MBRTOWC
2570 mbstate_t state;
2571 memset (&state, '\0', sizeof (mbstate_t));
2572 # endif
2573 arg_end = arg;
2574 characters = 0;
2575 for (; precision > 0; precision--)
2577 int count;
2578 # if HAVE_MBRTOWC
2579 count = mbrlen (arg_end, MB_CUR_MAX, &state);
2580 # else
2581 count = mblen (arg_end, MB_CUR_MAX);
2582 # endif
2583 if (count == 0)
2584 /* Found the terminating NUL. */
2585 break;
2586 if (count < 0)
2588 /* Invalid or incomplete multibyte character. */
2589 if (!(result == resultbuf || result == NULL))
2590 free (result);
2591 if (buf_malloced != NULL)
2592 free (buf_malloced);
2593 CLEANUP ();
2594 errno = EILSEQ;
2595 return NULL;
2597 arg_end += count;
2598 characters++;
2601 else if (has_width)
2603 /* Use the entire string, and count the number of wide
2604 characters. */
2605 # if HAVE_MBRTOWC
2606 mbstate_t state;
2607 memset (&state, '\0', sizeof (mbstate_t));
2608 # endif
2609 arg_end = arg;
2610 characters = 0;
2611 for (;;)
2613 int count;
2614 # if HAVE_MBRTOWC
2615 count = mbrlen (arg_end, MB_CUR_MAX, &state);
2616 # else
2617 count = mblen (arg_end, MB_CUR_MAX);
2618 # endif
2619 if (count == 0)
2620 /* Found the terminating NUL. */
2621 break;
2622 if (count < 0)
2624 /* Invalid or incomplete multibyte character. */
2625 if (!(result == resultbuf || result == NULL))
2626 free (result);
2627 if (buf_malloced != NULL)
2628 free (buf_malloced);
2629 CLEANUP ();
2630 errno = EILSEQ;
2631 return NULL;
2633 arg_end += count;
2634 characters++;
2637 else
2639 /* Use the entire string. */
2640 arg_end = arg + strlen (arg);
2641 /* The number of characters doesn't matter. */
2642 characters = 0;
2645 if (characters < width && !(dp->flags & FLAG_LEFT))
2647 size_t n = width - characters;
2648 ENSURE_ALLOCATION (xsum (length, n));
2649 DCHAR_SET (result + length, ' ', n);
2650 length += n;
2653 if (has_precision || has_width)
2655 /* We know the number of wide characters in advance. */
2656 size_t remaining;
2657 # if HAVE_MBRTOWC
2658 mbstate_t state;
2659 memset (&state, '\0', sizeof (mbstate_t));
2660 # endif
2661 ENSURE_ALLOCATION (xsum (length, characters));
2662 for (remaining = characters; remaining > 0; remaining--)
2664 wchar_t wc;
2665 int count;
2666 # if HAVE_MBRTOWC
2667 count = mbrtowc (&wc, arg, arg_end - arg, &state);
2668 # else
2669 count = mbtowc (&wc, arg, arg_end - arg);
2670 # endif
2671 if (count <= 0)
2672 /* mbrtowc not consistent with mbrlen, or mbtowc
2673 not consistent with mblen. */
2674 abort ();
2675 result[length++] = wc;
2676 arg += count;
2678 if (!(arg == arg_end))
2679 abort ();
2681 else
2683 # if HAVE_MBRTOWC
2684 mbstate_t state;
2685 memset (&state, '\0', sizeof (mbstate_t));
2686 # endif
2687 while (arg < arg_end)
2689 wchar_t wc;
2690 int count;
2691 # if HAVE_MBRTOWC
2692 count = mbrtowc (&wc, arg, arg_end - arg, &state);
2693 # else
2694 count = mbtowc (&wc, arg, arg_end - arg);
2695 # endif
2696 if (count <= 0)
2697 /* mbrtowc not consistent with mbrlen, or mbtowc
2698 not consistent with mblen. */
2699 abort ();
2700 ENSURE_ALLOCATION (xsum (length, 1));
2701 result[length++] = wc;
2702 arg += count;
2706 if (characters < width && (dp->flags & FLAG_LEFT))
2708 size_t n = width - characters;
2709 ENSURE_ALLOCATION (xsum (length, n));
2710 DCHAR_SET (result + length, ' ', n);
2711 length += n;
2714 # else
2715 /* %ls in vasnprintf. See the specification of fprintf. */
2717 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
2718 const wchar_t *arg_end;
2719 size_t characters;
2720 # if !DCHAR_IS_TCHAR
2721 /* This code assumes that TCHAR_T is 'char'. */
2722 verify (sizeof (TCHAR_T) == 1);
2723 TCHAR_T *tmpsrc;
2724 DCHAR_T *tmpdst;
2725 size_t tmpdst_len;
2726 # endif
2727 size_t w;
2729 if (has_precision)
2731 /* Use only as many wide characters as needed to produce
2732 at most PRECISION bytes, from the left. */
2733 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2734 mbstate_t state;
2735 memset (&state, '\0', sizeof (mbstate_t));
2736 # endif
2737 arg_end = arg;
2738 characters = 0;
2739 while (precision > 0)
2741 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2742 int count;
2744 if (*arg_end == 0)
2745 /* Found the terminating null wide character. */
2746 break;
2747 count = local_wcrtomb (cbuf, *arg_end, &state);
2748 if (count < 0)
2750 /* Cannot convert. */
2751 if (!(result == resultbuf || result == NULL))
2752 free (result);
2753 if (buf_malloced != NULL)
2754 free (buf_malloced);
2755 CLEANUP ();
2756 errno = EILSEQ;
2757 return NULL;
2759 if (precision < (unsigned int) count)
2760 break;
2761 arg_end++;
2762 characters += count;
2763 precision -= count;
2766 # if DCHAR_IS_TCHAR
2767 else if (has_width)
2768 # else
2769 else
2770 # endif
2772 /* Use the entire string, and count the number of
2773 bytes. */
2774 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2775 mbstate_t state;
2776 memset (&state, '\0', sizeof (mbstate_t));
2777 # endif
2778 arg_end = arg;
2779 characters = 0;
2780 for (;;)
2782 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2783 int count;
2785 if (*arg_end == 0)
2786 /* Found the terminating null wide character. */
2787 break;
2788 count = local_wcrtomb (cbuf, *arg_end, &state);
2789 if (count < 0)
2791 /* Cannot convert. */
2792 if (!(result == resultbuf || result == NULL))
2793 free (result);
2794 if (buf_malloced != NULL)
2795 free (buf_malloced);
2796 CLEANUP ();
2797 errno = EILSEQ;
2798 return NULL;
2800 arg_end++;
2801 characters += count;
2804 # if DCHAR_IS_TCHAR
2805 else
2807 /* Use the entire string. */
2808 arg_end = arg + local_wcslen (arg);
2809 /* The number of bytes doesn't matter. */
2810 characters = 0;
2812 # endif
2814 # if !DCHAR_IS_TCHAR
2815 /* Convert the string into a piece of temporary memory. */
2816 tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
2817 if (tmpsrc == NULL)
2818 goto out_of_memory;
2820 TCHAR_T *tmpptr = tmpsrc;
2821 size_t remaining;
2822 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2823 mbstate_t state;
2824 memset (&state, '\0', sizeof (mbstate_t));
2825 # endif
2826 for (remaining = characters; remaining > 0; )
2828 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2829 int count;
2831 if (*arg == 0)
2832 abort ();
2833 count = local_wcrtomb (cbuf, *arg, &state);
2834 if (count <= 0)
2835 /* Inconsistency. */
2836 abort ();
2837 memcpy (tmpptr, cbuf, count);
2838 tmpptr += count;
2839 arg++;
2840 remaining -= count;
2842 if (!(arg == arg_end))
2843 abort ();
2846 /* Convert from TCHAR_T[] to DCHAR_T[]. */
2847 tmpdst =
2848 DCHAR_CONV_FROM_ENCODING (locale_charset (),
2849 iconveh_question_mark,
2850 tmpsrc, characters,
2851 NULL,
2852 NULL, &tmpdst_len);
2853 if (tmpdst == NULL)
2855 int saved_errno = errno;
2856 free (tmpsrc);
2857 if (!(result == resultbuf || result == NULL))
2858 free (result);
2859 if (buf_malloced != NULL)
2860 free (buf_malloced);
2861 CLEANUP ();
2862 errno = saved_errno;
2863 return NULL;
2865 free (tmpsrc);
2866 # endif
2868 if (has_width)
2870 # if ENABLE_UNISTDIO
2871 /* Outside POSIX, it's preferable to compare the width
2872 against the number of _characters_ of the converted
2873 value. */
2874 w = DCHAR_MBSNLEN (result + length, characters);
2875 # else
2876 /* The width is compared against the number of _bytes_
2877 of the converted value, says POSIX. */
2878 w = characters;
2879 # endif
2881 else
2882 /* w doesn't matter. */
2883 w = 0;
2885 if (w < width && !(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 # if DCHAR_IS_TCHAR
2894 if (has_precision || has_width)
2896 /* We know the number of bytes in advance. */
2897 size_t remaining;
2898 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2899 mbstate_t state;
2900 memset (&state, '\0', sizeof (mbstate_t));
2901 # endif
2902 ENSURE_ALLOCATION (xsum (length, characters));
2903 for (remaining = characters; remaining > 0; )
2905 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2906 int count;
2908 if (*arg == 0)
2909 abort ();
2910 count = local_wcrtomb (cbuf, *arg, &state);
2911 if (count <= 0)
2912 /* Inconsistency. */
2913 abort ();
2914 memcpy (result + length, cbuf, count);
2915 length += count;
2916 arg++;
2917 remaining -= count;
2919 if (!(arg == arg_end))
2920 abort ();
2922 else
2924 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2925 mbstate_t state;
2926 memset (&state, '\0', sizeof (mbstate_t));
2927 # endif
2928 while (arg < arg_end)
2930 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2931 int count;
2933 if (*arg == 0)
2934 abort ();
2935 count = local_wcrtomb (cbuf, *arg, &state);
2936 if (count <= 0)
2938 /* Cannot convert. */
2939 if (!(result == resultbuf || result == NULL))
2940 free (result);
2941 if (buf_malloced != NULL)
2942 free (buf_malloced);
2943 CLEANUP ();
2944 errno = EILSEQ;
2945 return NULL;
2947 ENSURE_ALLOCATION (xsum (length, count));
2948 memcpy (result + length, cbuf, count);
2949 length += count;
2950 arg++;
2953 # else
2954 ENSURE_ALLOCATION (xsum (length, tmpdst_len));
2955 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
2956 free (tmpdst);
2957 length += tmpdst_len;
2958 # endif
2960 if (w < width && (dp->flags & FLAG_LEFT))
2962 size_t n = width - w;
2963 ENSURE_ALLOCATION (xsum (length, n));
2964 DCHAR_SET (result + length, ' ', n);
2965 length += n;
2968 # endif
2970 #endif
2971 #if ENABLE_WCHAR_FALLBACK && HAVE_WINT_T && !WIDE_CHAR_VERSION
2972 else if (dp->conversion == 'c'
2973 && a.arg[dp->arg_index].type == TYPE_WIDE_CHAR)
2975 /* Implement the 'lc' directive ourselves, in order to provide
2976 the fallback that avoids EILSEQ. */
2977 int flags = dp->flags;
2978 int has_width;
2979 size_t width;
2981 has_width = 0;
2982 width = 0;
2983 if (dp->width_start != dp->width_end)
2985 if (dp->width_arg_index != ARG_NONE)
2987 int arg;
2989 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2990 abort ();
2991 arg = a.arg[dp->width_arg_index].a.a_int;
2992 width = arg;
2993 if (arg < 0)
2995 /* "A negative field width is taken as a '-' flag
2996 followed by a positive field width." */
2997 flags |= FLAG_LEFT;
2998 width = -width;
3001 else
3003 const FCHAR_T *digitp = dp->width_start;
3006 width = xsum (xtimes (width, 10), *digitp++ - '0');
3007 while (digitp != dp->width_end);
3009 has_width = 1;
3012 /* %lc in vasnprintf. See the specification of fprintf. */
3014 wchar_t arg = (wchar_t) a.arg[dp->arg_index].a.a_wide_char;
3015 size_t characters;
3016 # if !DCHAR_IS_TCHAR
3017 /* This code assumes that TCHAR_T is 'char'. */
3018 verify (sizeof (TCHAR_T) == 1);
3019 TCHAR_T tmpsrc[64]; /* Assume MB_CUR_MAX <= 64. */
3020 DCHAR_T *tmpdst;
3021 size_t tmpdst_len;
3022 # endif
3023 size_t w;
3025 # if DCHAR_IS_TCHAR
3026 if (has_width)
3027 # endif
3029 /* Count the number of bytes. */
3030 characters = 0;
3031 if (arg != 0)
3033 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3034 int count;
3035 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3036 mbstate_t state;
3037 memset (&state, '\0', sizeof (mbstate_t));
3038 # endif
3040 count = local_wcrtomb (cbuf, arg, &state);
3041 if (count < 0)
3042 /* Inconsistency. */
3043 abort ();
3044 characters = count;
3047 # if DCHAR_IS_TCHAR
3048 else
3050 /* The number of bytes doesn't matter. */
3051 characters = 0;
3053 # endif
3055 # if !DCHAR_IS_TCHAR
3056 /* Convert the string into a piece of temporary memory. */
3057 if (characters > 0) /* implies arg != 0 */
3059 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3060 int count;
3061 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3062 mbstate_t state;
3063 memset (&state, '\0', sizeof (mbstate_t));
3064 # endif
3066 count = local_wcrtomb (cbuf, arg, &state);
3067 if (count <= 0)
3068 /* Inconsistency. */
3069 abort ();
3070 memcpy (tmpsrc, cbuf, count);
3073 /* Convert from TCHAR_T[] to DCHAR_T[]. */
3074 tmpdst =
3075 DCHAR_CONV_FROM_ENCODING (locale_charset (),
3076 iconveh_question_mark,
3077 tmpsrc, characters,
3078 NULL,
3079 NULL, &tmpdst_len);
3080 if (tmpdst == NULL)
3082 int saved_errno = errno;
3083 if (!(result == resultbuf || result == NULL))
3084 free (result);
3085 if (buf_malloced != NULL)
3086 free (buf_malloced);
3087 CLEANUP ();
3088 errno = saved_errno;
3089 return NULL;
3091 # endif
3093 if (has_width)
3095 # if ENABLE_UNISTDIO
3096 /* Outside POSIX, it's preferable to compare the width
3097 against the number of _characters_ of the converted
3098 value. */
3099 w = DCHAR_MBSNLEN (result + length, characters);
3100 # else
3101 /* The width is compared against the number of _bytes_
3102 of the converted value, says POSIX. */
3103 w = characters;
3104 # endif
3106 else
3107 /* w doesn't matter. */
3108 w = 0;
3110 if (w < width && !(dp->flags & FLAG_LEFT))
3112 size_t n = width - w;
3113 ENSURE_ALLOCATION (xsum (length, n));
3114 DCHAR_SET (result + length, ' ', n);
3115 length += n;
3118 # if DCHAR_IS_TCHAR
3119 if (has_width)
3121 /* We know the number of bytes in advance. */
3122 ENSURE_ALLOCATION (xsum (length, characters));
3123 if (characters > 0) /* implies arg != 0 */
3125 int count;
3126 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3127 mbstate_t state;
3128 memset (&state, '\0', sizeof (mbstate_t));
3129 # endif
3131 count = local_wcrtomb (result + length, arg, &state);
3132 if (count <= 0)
3133 /* Inconsistency. */
3134 abort ();
3135 length += count;
3138 else
3140 if (arg != 0)
3142 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3143 int count;
3144 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3145 mbstate_t state;
3146 memset (&state, '\0', sizeof (mbstate_t));
3147 # endif
3149 count = local_wcrtomb (cbuf, arg, &state);
3150 if (count <= 0)
3151 /* Inconsistency. */
3152 abort ();
3153 ENSURE_ALLOCATION (xsum (length, count));
3154 memcpy (result + length, cbuf, count);
3155 length += count;
3158 # else
3159 ENSURE_ALLOCATION (xsum (length, tmpdst_len));
3160 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
3161 free (tmpdst);
3162 length += tmpdst_len;
3163 # endif
3165 if (w < width && (dp->flags & FLAG_LEFT))
3167 size_t n = width - w;
3168 ENSURE_ALLOCATION (xsum (length, n));
3169 DCHAR_SET (result + length, ' ', n);
3170 length += n;
3174 #endif
3175 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
3176 else if ((dp->conversion == 'a' || dp->conversion == 'A')
3177 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
3178 && (0
3179 # if NEED_PRINTF_DOUBLE
3180 || a.arg[dp->arg_index].type == TYPE_DOUBLE
3181 # endif
3182 # if NEED_PRINTF_LONG_DOUBLE
3183 || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3184 # endif
3186 # endif
3189 arg_type type = a.arg[dp->arg_index].type;
3190 int flags = dp->flags;
3191 size_t width;
3192 int has_precision;
3193 size_t precision;
3194 size_t tmp_length;
3195 size_t count;
3196 DCHAR_T tmpbuf[700];
3197 DCHAR_T *tmp;
3198 DCHAR_T *pad_ptr;
3199 DCHAR_T *p;
3201 width = 0;
3202 if (dp->width_start != dp->width_end)
3204 if (dp->width_arg_index != ARG_NONE)
3206 int arg;
3208 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3209 abort ();
3210 arg = a.arg[dp->width_arg_index].a.a_int;
3211 width = arg;
3212 if (arg < 0)
3214 /* "A negative field width is taken as a '-' flag
3215 followed by a positive field width." */
3216 flags |= FLAG_LEFT;
3217 width = -width;
3220 else
3222 const FCHAR_T *digitp = dp->width_start;
3225 width = xsum (xtimes (width, 10), *digitp++ - '0');
3226 while (digitp != dp->width_end);
3230 has_precision = 0;
3231 precision = 0;
3232 if (dp->precision_start != dp->precision_end)
3234 if (dp->precision_arg_index != ARG_NONE)
3236 int arg;
3238 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3239 abort ();
3240 arg = a.arg[dp->precision_arg_index].a.a_int;
3241 /* "A negative precision is taken as if the precision
3242 were omitted." */
3243 if (arg >= 0)
3245 precision = arg;
3246 has_precision = 1;
3249 else
3251 const FCHAR_T *digitp = dp->precision_start + 1;
3253 precision = 0;
3254 while (digitp != dp->precision_end)
3255 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3256 has_precision = 1;
3260 /* Allocate a temporary buffer of sufficient size. */
3261 if (type == TYPE_LONGDOUBLE)
3262 tmp_length =
3263 (unsigned int) ((LDBL_DIG + 1)
3264 * 0.831 /* decimal -> hexadecimal */
3266 + 1; /* turn floor into ceil */
3267 else
3268 tmp_length =
3269 (unsigned int) ((DBL_DIG + 1)
3270 * 0.831 /* decimal -> hexadecimal */
3272 + 1; /* turn floor into ceil */
3273 if (tmp_length < precision)
3274 tmp_length = precision;
3275 /* Account for sign, decimal point etc. */
3276 tmp_length = xsum (tmp_length, 12);
3278 if (tmp_length < width)
3279 tmp_length = width;
3281 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3283 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3284 tmp = tmpbuf;
3285 else
3287 size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3289 if (size_overflow_p (tmp_memsize))
3290 /* Overflow, would lead to out of memory. */
3291 goto out_of_memory;
3292 tmp = (DCHAR_T *) malloc (tmp_memsize);
3293 if (tmp == NULL)
3294 /* Out of memory. */
3295 goto out_of_memory;
3298 pad_ptr = NULL;
3299 p = tmp;
3300 if (type == TYPE_LONGDOUBLE)
3302 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
3303 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3305 if (isnanl (arg))
3307 if (dp->conversion == 'A')
3309 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3311 else
3313 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3316 else
3318 int sign = 0;
3319 DECL_LONG_DOUBLE_ROUNDING
3321 BEGIN_LONG_DOUBLE_ROUNDING ();
3323 if (signbit (arg)) /* arg < 0.0L or negative zero */
3325 sign = -1;
3326 arg = -arg;
3329 if (sign < 0)
3330 *p++ = '-';
3331 else if (flags & FLAG_SHOWSIGN)
3332 *p++ = '+';
3333 else if (flags & FLAG_SPACE)
3334 *p++ = ' ';
3336 if (arg > 0.0L && arg + arg == arg)
3338 if (dp->conversion == 'A')
3340 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3342 else
3344 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3347 else
3349 int exponent;
3350 long double mantissa;
3352 if (arg > 0.0L)
3353 mantissa = printf_frexpl (arg, &exponent);
3354 else
3356 exponent = 0;
3357 mantissa = 0.0L;
3360 if (has_precision
3361 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
3363 /* Round the mantissa. */
3364 long double tail = mantissa;
3365 size_t q;
3367 for (q = precision; ; q--)
3369 int digit = (int) tail;
3370 tail -= digit;
3371 if (q == 0)
3373 if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
3374 tail = 1 - tail;
3375 else
3376 tail = - tail;
3377 break;
3379 tail *= 16.0L;
3381 if (tail != 0.0L)
3382 for (q = precision; q > 0; q--)
3383 tail *= 0.0625L;
3384 mantissa += tail;
3387 *p++ = '0';
3388 *p++ = dp->conversion - 'A' + 'X';
3389 pad_ptr = p;
3391 int digit;
3393 digit = (int) mantissa;
3394 mantissa -= digit;
3395 *p++ = '0' + digit;
3396 if ((flags & FLAG_ALT)
3397 || mantissa > 0.0L || precision > 0)
3399 *p++ = decimal_point_char ();
3400 /* This loop terminates because we assume
3401 that FLT_RADIX is a power of 2. */
3402 while (mantissa > 0.0L)
3404 mantissa *= 16.0L;
3405 digit = (int) mantissa;
3406 mantissa -= digit;
3407 *p++ = digit
3408 + (digit < 10
3409 ? '0'
3410 : dp->conversion - 10);
3411 if (precision > 0)
3412 precision--;
3414 while (precision > 0)
3416 *p++ = '0';
3417 precision--;
3421 *p++ = dp->conversion - 'A' + 'P';
3422 # if WIDE_CHAR_VERSION
3424 static const wchar_t decimal_format[] =
3425 { '%', '+', 'd', '\0' };
3426 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3428 while (*p != '\0')
3429 p++;
3430 # else
3431 if (sizeof (DCHAR_T) == 1)
3433 sprintf ((char *) p, "%+d", exponent);
3434 while (*p != '\0')
3435 p++;
3437 else
3439 char expbuf[6 + 1];
3440 const char *ep;
3441 sprintf (expbuf, "%+d", exponent);
3442 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3443 p++;
3445 # endif
3448 END_LONG_DOUBLE_ROUNDING ();
3450 # else
3451 abort ();
3452 # endif
3454 else
3456 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
3457 double arg = a.arg[dp->arg_index].a.a_double;
3459 if (isnand (arg))
3461 if (dp->conversion == 'A')
3463 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3465 else
3467 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3470 else
3472 int sign = 0;
3474 if (signbit (arg)) /* arg < 0.0 or negative zero */
3476 sign = -1;
3477 arg = -arg;
3480 if (sign < 0)
3481 *p++ = '-';
3482 else if (flags & FLAG_SHOWSIGN)
3483 *p++ = '+';
3484 else if (flags & FLAG_SPACE)
3485 *p++ = ' ';
3487 if (arg > 0.0 && arg + arg == arg)
3489 if (dp->conversion == 'A')
3491 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3493 else
3495 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3498 else
3500 int exponent;
3501 double mantissa;
3503 if (arg > 0.0)
3504 mantissa = printf_frexp (arg, &exponent);
3505 else
3507 exponent = 0;
3508 mantissa = 0.0;
3511 if (has_precision
3512 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
3514 /* Round the mantissa. */
3515 double tail = mantissa;
3516 size_t q;
3518 for (q = precision; ; q--)
3520 int digit = (int) tail;
3521 tail -= digit;
3522 if (q == 0)
3524 if (digit & 1 ? tail >= 0.5 : tail > 0.5)
3525 tail = 1 - tail;
3526 else
3527 tail = - tail;
3528 break;
3530 tail *= 16.0;
3532 if (tail != 0.0)
3533 for (q = precision; q > 0; q--)
3534 tail *= 0.0625;
3535 mantissa += tail;
3538 *p++ = '0';
3539 *p++ = dp->conversion - 'A' + 'X';
3540 pad_ptr = p;
3542 int digit;
3544 digit = (int) mantissa;
3545 mantissa -= digit;
3546 *p++ = '0' + digit;
3547 if ((flags & FLAG_ALT)
3548 || mantissa > 0.0 || precision > 0)
3550 *p++ = decimal_point_char ();
3551 /* This loop terminates because we assume
3552 that FLT_RADIX is a power of 2. */
3553 while (mantissa > 0.0)
3555 mantissa *= 16.0;
3556 digit = (int) mantissa;
3557 mantissa -= digit;
3558 *p++ = digit
3559 + (digit < 10
3560 ? '0'
3561 : dp->conversion - 10);
3562 if (precision > 0)
3563 precision--;
3565 while (precision > 0)
3567 *p++ = '0';
3568 precision--;
3572 *p++ = dp->conversion - 'A' + 'P';
3573 # if WIDE_CHAR_VERSION
3575 static const wchar_t decimal_format[] =
3576 { '%', '+', 'd', '\0' };
3577 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3579 while (*p != '\0')
3580 p++;
3581 # else
3582 if (sizeof (DCHAR_T) == 1)
3584 sprintf ((char *) p, "%+d", exponent);
3585 while (*p != '\0')
3586 p++;
3588 else
3590 char expbuf[6 + 1];
3591 const char *ep;
3592 sprintf (expbuf, "%+d", exponent);
3593 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3594 p++;
3596 # endif
3599 # else
3600 abort ();
3601 # endif
3604 /* The generated string now extends from tmp to p, with the
3605 zero padding insertion point being at pad_ptr. */
3606 count = p - tmp;
3608 if (count < width)
3610 size_t pad = width - count;
3611 DCHAR_T *end = p + pad;
3613 if (flags & FLAG_LEFT)
3615 /* Pad with spaces on the right. */
3616 for (; pad > 0; pad--)
3617 *p++ = ' ';
3619 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3621 /* Pad with zeroes. */
3622 DCHAR_T *q = end;
3624 while (p > pad_ptr)
3625 *--q = *--p;
3626 for (; pad > 0; pad--)
3627 *p++ = '0';
3629 else
3631 /* Pad with spaces on the left. */
3632 DCHAR_T *q = end;
3634 while (p > tmp)
3635 *--q = *--p;
3636 for (; pad > 0; pad--)
3637 *p++ = ' ';
3640 p = end;
3643 count = p - tmp;
3645 if (count >= tmp_length)
3646 /* tmp_length was incorrectly calculated - fix the
3647 code above! */
3648 abort ();
3650 /* Make room for the result. */
3651 if (count >= allocated - length)
3653 size_t n = xsum (length, count);
3655 ENSURE_ALLOCATION (n);
3658 /* Append the result. */
3659 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3660 if (tmp != tmpbuf)
3661 free (tmp);
3662 length += count;
3664 #endif
3665 #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
3666 else if ((dp->conversion == 'f' || dp->conversion == 'F'
3667 || dp->conversion == 'e' || dp->conversion == 'E'
3668 || dp->conversion == 'g' || dp->conversion == 'G'
3669 || dp->conversion == 'a' || dp->conversion == 'A')
3670 && (0
3671 # if NEED_PRINTF_DOUBLE
3672 || a.arg[dp->arg_index].type == TYPE_DOUBLE
3673 # elif NEED_PRINTF_INFINITE_DOUBLE
3674 || (a.arg[dp->arg_index].type == TYPE_DOUBLE
3675 /* The systems (mingw) which produce wrong output
3676 for Inf, -Inf, and NaN also do so for -0.0.
3677 Therefore we treat this case here as well. */
3678 && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
3679 # endif
3680 # if NEED_PRINTF_LONG_DOUBLE
3681 || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3682 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
3683 || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3684 /* Some systems produce wrong output for Inf,
3685 -Inf, and NaN. Some systems in this category
3686 (IRIX 5.3) also do so for -0.0. Therefore we
3687 treat this case here as well. */
3688 && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
3689 # endif
3692 # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
3693 arg_type type = a.arg[dp->arg_index].type;
3694 # endif
3695 int flags = dp->flags;
3696 size_t width;
3697 size_t count;
3698 int has_precision;
3699 size_t precision;
3700 size_t tmp_length;
3701 DCHAR_T tmpbuf[700];
3702 DCHAR_T *tmp;
3703 DCHAR_T *pad_ptr;
3704 DCHAR_T *p;
3706 width = 0;
3707 if (dp->width_start != dp->width_end)
3709 if (dp->width_arg_index != ARG_NONE)
3711 int arg;
3713 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3714 abort ();
3715 arg = a.arg[dp->width_arg_index].a.a_int;
3716 width = arg;
3717 if (arg < 0)
3719 /* "A negative field width is taken as a '-' flag
3720 followed by a positive field width." */
3721 flags |= FLAG_LEFT;
3722 width = -width;
3725 else
3727 const FCHAR_T *digitp = dp->width_start;
3730 width = xsum (xtimes (width, 10), *digitp++ - '0');
3731 while (digitp != dp->width_end);
3735 has_precision = 0;
3736 precision = 0;
3737 if (dp->precision_start != dp->precision_end)
3739 if (dp->precision_arg_index != ARG_NONE)
3741 int arg;
3743 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3744 abort ();
3745 arg = a.arg[dp->precision_arg_index].a.a_int;
3746 /* "A negative precision is taken as if the precision
3747 were omitted." */
3748 if (arg >= 0)
3750 precision = arg;
3751 has_precision = 1;
3754 else
3756 const FCHAR_T *digitp = dp->precision_start + 1;
3758 precision = 0;
3759 while (digitp != dp->precision_end)
3760 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3761 has_precision = 1;
3765 /* POSIX specifies the default precision to be 6 for %f, %F,
3766 %e, %E, but not for %g, %G. Implementations appear to use
3767 the same default precision also for %g, %G. But for %a, %A,
3768 the default precision is 0. */
3769 if (!has_precision)
3770 if (!(dp->conversion == 'a' || dp->conversion == 'A'))
3771 precision = 6;
3773 /* Allocate a temporary buffer of sufficient size. */
3774 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3775 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
3776 # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3777 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
3778 # elif NEED_PRINTF_LONG_DOUBLE
3779 tmp_length = LDBL_DIG + 1;
3780 # elif NEED_PRINTF_DOUBLE
3781 tmp_length = DBL_DIG + 1;
3782 # else
3783 tmp_length = 0;
3784 # endif
3785 if (tmp_length < precision)
3786 tmp_length = precision;
3787 # if NEED_PRINTF_LONG_DOUBLE
3788 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3789 if (type == TYPE_LONGDOUBLE)
3790 # endif
3791 if (dp->conversion == 'f' || dp->conversion == 'F')
3793 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3794 if (!(isnanl (arg) || arg + arg == arg))
3796 /* arg is finite and nonzero. */
3797 int exponent = floorlog10l (arg < 0 ? -arg : arg);
3798 if (exponent >= 0 && tmp_length < exponent + precision)
3799 tmp_length = exponent + precision;
3802 # endif
3803 # if NEED_PRINTF_DOUBLE
3804 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3805 if (type == TYPE_DOUBLE)
3806 # endif
3807 if (dp->conversion == 'f' || dp->conversion == 'F')
3809 double arg = a.arg[dp->arg_index].a.a_double;
3810 if (!(isnand (arg) || arg + arg == arg))
3812 /* arg is finite and nonzero. */
3813 int exponent = floorlog10 (arg < 0 ? -arg : arg);
3814 if (exponent >= 0 && tmp_length < exponent + precision)
3815 tmp_length = exponent + precision;
3818 # endif
3819 /* Account for sign, decimal point etc. */
3820 tmp_length = xsum (tmp_length, 12);
3822 if (tmp_length < width)
3823 tmp_length = width;
3825 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3827 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3828 tmp = tmpbuf;
3829 else
3831 size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3833 if (size_overflow_p (tmp_memsize))
3834 /* Overflow, would lead to out of memory. */
3835 goto out_of_memory;
3836 tmp = (DCHAR_T *) malloc (tmp_memsize);
3837 if (tmp == NULL)
3838 /* Out of memory. */
3839 goto out_of_memory;
3842 pad_ptr = NULL;
3843 p = tmp;
3845 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3846 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3847 if (type == TYPE_LONGDOUBLE)
3848 # endif
3850 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3852 if (isnanl (arg))
3854 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3856 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3858 else
3860 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3863 else
3865 int sign = 0;
3866 DECL_LONG_DOUBLE_ROUNDING
3868 BEGIN_LONG_DOUBLE_ROUNDING ();
3870 if (signbit (arg)) /* arg < 0.0L or negative zero */
3872 sign = -1;
3873 arg = -arg;
3876 if (sign < 0)
3877 *p++ = '-';
3878 else if (flags & FLAG_SHOWSIGN)
3879 *p++ = '+';
3880 else if (flags & FLAG_SPACE)
3881 *p++ = ' ';
3883 if (arg > 0.0L && arg + arg == arg)
3885 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3887 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3889 else
3891 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3894 else
3896 # if NEED_PRINTF_LONG_DOUBLE
3897 pad_ptr = p;
3899 if (dp->conversion == 'f' || dp->conversion == 'F')
3901 char *digits;
3902 size_t ndigits;
3904 digits =
3905 scale10_round_decimal_long_double (arg, precision);
3906 if (digits == NULL)
3908 END_LONG_DOUBLE_ROUNDING ();
3909 goto out_of_memory;
3911 ndigits = strlen (digits);
3913 if (ndigits > precision)
3916 --ndigits;
3917 *p++ = digits[ndigits];
3919 while (ndigits > precision);
3920 else
3921 *p++ = '0';
3922 /* Here ndigits <= precision. */
3923 if ((flags & FLAG_ALT) || precision > 0)
3925 *p++ = decimal_point_char ();
3926 for (; precision > ndigits; precision--)
3927 *p++ = '0';
3928 while (ndigits > 0)
3930 --ndigits;
3931 *p++ = digits[ndigits];
3935 free (digits);
3937 else if (dp->conversion == 'e' || dp->conversion == 'E')
3939 int exponent;
3941 if (arg == 0.0L)
3943 exponent = 0;
3944 *p++ = '0';
3945 if ((flags & FLAG_ALT) || precision > 0)
3947 *p++ = decimal_point_char ();
3948 for (; precision > 0; precision--)
3949 *p++ = '0';
3952 else
3954 /* arg > 0.0L. */
3955 int adjusted;
3956 char *digits;
3957 size_t ndigits;
3959 exponent = floorlog10l (arg);
3960 adjusted = 0;
3961 for (;;)
3963 digits =
3964 scale10_round_decimal_long_double (arg,
3965 (int)precision - exponent);
3966 if (digits == NULL)
3968 END_LONG_DOUBLE_ROUNDING ();
3969 goto out_of_memory;
3971 ndigits = strlen (digits);
3973 if (ndigits == precision + 1)
3974 break;
3975 if (ndigits < precision
3976 || ndigits > precision + 2)
3977 /* The exponent was not guessed
3978 precisely enough. */
3979 abort ();
3980 if (adjusted)
3981 /* None of two values of exponent is
3982 the right one. Prevent an endless
3983 loop. */
3984 abort ();
3985 free (digits);
3986 if (ndigits == precision)
3987 exponent -= 1;
3988 else
3989 exponent += 1;
3990 adjusted = 1;
3992 /* Here ndigits = precision+1. */
3993 if (is_borderline (digits, precision))
3995 /* Maybe the exponent guess was too high
3996 and a smaller exponent can be reached
3997 by turning a 10...0 into 9...9x. */
3998 char *digits2 =
3999 scale10_round_decimal_long_double (arg,
4000 (int)precision - exponent + 1);
4001 if (digits2 == NULL)
4003 free (digits);
4004 END_LONG_DOUBLE_ROUNDING ();
4005 goto out_of_memory;
4007 if (strlen (digits2) == precision + 1)
4009 free (digits);
4010 digits = digits2;
4011 exponent -= 1;
4013 else
4014 free (digits2);
4016 /* Here ndigits = precision+1. */
4018 *p++ = digits[--ndigits];
4019 if ((flags & FLAG_ALT) || precision > 0)
4021 *p++ = decimal_point_char ();
4022 while (ndigits > 0)
4024 --ndigits;
4025 *p++ = digits[ndigits];
4029 free (digits);
4032 *p++ = dp->conversion; /* 'e' or 'E' */
4033 # if WIDE_CHAR_VERSION
4035 static const wchar_t decimal_format[] =
4036 { '%', '+', '.', '2', 'd', '\0' };
4037 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4039 while (*p != '\0')
4040 p++;
4041 # else
4042 if (sizeof (DCHAR_T) == 1)
4044 sprintf ((char *) p, "%+.2d", exponent);
4045 while (*p != '\0')
4046 p++;
4048 else
4050 char expbuf[6 + 1];
4051 const char *ep;
4052 sprintf (expbuf, "%+.2d", exponent);
4053 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4054 p++;
4056 # endif
4058 else if (dp->conversion == 'g' || dp->conversion == 'G')
4060 if (precision == 0)
4061 precision = 1;
4062 /* precision >= 1. */
4064 if (arg == 0.0L)
4065 /* The exponent is 0, >= -4, < precision.
4066 Use fixed-point notation. */
4068 size_t ndigits = precision;
4069 /* Number of trailing zeroes that have to be
4070 dropped. */
4071 size_t nzeroes =
4072 (flags & FLAG_ALT ? 0 : precision - 1);
4074 --ndigits;
4075 *p++ = '0';
4076 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4078 *p++ = decimal_point_char ();
4079 while (ndigits > nzeroes)
4081 --ndigits;
4082 *p++ = '0';
4086 else
4088 /* arg > 0.0L. */
4089 int exponent;
4090 int adjusted;
4091 char *digits;
4092 size_t ndigits;
4093 size_t nzeroes;
4095 exponent = floorlog10l (arg);
4096 adjusted = 0;
4097 for (;;)
4099 digits =
4100 scale10_round_decimal_long_double (arg,
4101 (int)(precision - 1) - exponent);
4102 if (digits == NULL)
4104 END_LONG_DOUBLE_ROUNDING ();
4105 goto out_of_memory;
4107 ndigits = strlen (digits);
4109 if (ndigits == precision)
4110 break;
4111 if (ndigits < precision - 1
4112 || ndigits > precision + 1)
4113 /* The exponent was not guessed
4114 precisely enough. */
4115 abort ();
4116 if (adjusted)
4117 /* None of two values of exponent is
4118 the right one. Prevent an endless
4119 loop. */
4120 abort ();
4121 free (digits);
4122 if (ndigits < precision)
4123 exponent -= 1;
4124 else
4125 exponent += 1;
4126 adjusted = 1;
4128 /* Here ndigits = precision. */
4129 if (is_borderline (digits, precision - 1))
4131 /* Maybe the exponent guess was too high
4132 and a smaller exponent can be reached
4133 by turning a 10...0 into 9...9x. */
4134 char *digits2 =
4135 scale10_round_decimal_long_double (arg,
4136 (int)(precision - 1) - exponent + 1);
4137 if (digits2 == NULL)
4139 free (digits);
4140 END_LONG_DOUBLE_ROUNDING ();
4141 goto out_of_memory;
4143 if (strlen (digits2) == precision)
4145 free (digits);
4146 digits = digits2;
4147 exponent -= 1;
4149 else
4150 free (digits2);
4152 /* Here ndigits = precision. */
4154 /* Determine the number of trailing zeroes
4155 that have to be dropped. */
4156 nzeroes = 0;
4157 if ((flags & FLAG_ALT) == 0)
4158 while (nzeroes < ndigits
4159 && digits[nzeroes] == '0')
4160 nzeroes++;
4162 /* The exponent is now determined. */
4163 if (exponent >= -4
4164 && exponent < (long)precision)
4166 /* Fixed-point notation:
4167 max(exponent,0)+1 digits, then the
4168 decimal point, then the remaining
4169 digits without trailing zeroes. */
4170 if (exponent >= 0)
4172 size_t ecount = exponent + 1;
4173 /* Note: count <= precision = ndigits. */
4174 for (; ecount > 0; ecount--)
4175 *p++ = digits[--ndigits];
4176 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4178 *p++ = decimal_point_char ();
4179 while (ndigits > nzeroes)
4181 --ndigits;
4182 *p++ = digits[ndigits];
4186 else
4188 size_t ecount = -exponent - 1;
4189 *p++ = '0';
4190 *p++ = decimal_point_char ();
4191 for (; ecount > 0; ecount--)
4192 *p++ = '0';
4193 while (ndigits > nzeroes)
4195 --ndigits;
4196 *p++ = digits[ndigits];
4200 else
4202 /* Exponential notation. */
4203 *p++ = digits[--ndigits];
4204 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4206 *p++ = decimal_point_char ();
4207 while (ndigits > nzeroes)
4209 --ndigits;
4210 *p++ = digits[ndigits];
4213 *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4214 # if WIDE_CHAR_VERSION
4216 static const wchar_t decimal_format[] =
4217 { '%', '+', '.', '2', 'd', '\0' };
4218 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4220 while (*p != '\0')
4221 p++;
4222 # else
4223 if (sizeof (DCHAR_T) == 1)
4225 sprintf ((char *) p, "%+.2d", exponent);
4226 while (*p != '\0')
4227 p++;
4229 else
4231 char expbuf[6 + 1];
4232 const char *ep;
4233 sprintf (expbuf, "%+.2d", exponent);
4234 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4235 p++;
4237 # endif
4240 free (digits);
4243 else
4244 abort ();
4245 # else
4246 /* arg is finite. */
4247 if (!(arg == 0.0L))
4248 abort ();
4250 pad_ptr = p;
4252 if (dp->conversion == 'f' || dp->conversion == 'F')
4254 *p++ = '0';
4255 if ((flags & FLAG_ALT) || precision > 0)
4257 *p++ = decimal_point_char ();
4258 for (; precision > 0; precision--)
4259 *p++ = '0';
4262 else if (dp->conversion == 'e' || dp->conversion == 'E')
4264 *p++ = '0';
4265 if ((flags & FLAG_ALT) || precision > 0)
4267 *p++ = decimal_point_char ();
4268 for (; precision > 0; precision--)
4269 *p++ = '0';
4271 *p++ = dp->conversion; /* 'e' or 'E' */
4272 *p++ = '+';
4273 *p++ = '0';
4274 *p++ = '0';
4276 else if (dp->conversion == 'g' || dp->conversion == 'G')
4278 *p++ = '0';
4279 if (flags & FLAG_ALT)
4281 size_t ndigits =
4282 (precision > 0 ? precision - 1 : 0);
4283 *p++ = decimal_point_char ();
4284 for (; ndigits > 0; --ndigits)
4285 *p++ = '0';
4288 else if (dp->conversion == 'a' || dp->conversion == 'A')
4290 *p++ = '0';
4291 *p++ = dp->conversion - 'A' + 'X';
4292 pad_ptr = p;
4293 *p++ = '0';
4294 if ((flags & FLAG_ALT) || precision > 0)
4296 *p++ = decimal_point_char ();
4297 for (; precision > 0; precision--)
4298 *p++ = '0';
4300 *p++ = dp->conversion - 'A' + 'P';
4301 *p++ = '+';
4302 *p++ = '0';
4304 else
4305 abort ();
4306 # endif
4309 END_LONG_DOUBLE_ROUNDING ();
4312 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4313 else
4314 # endif
4315 # endif
4316 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4318 double arg = a.arg[dp->arg_index].a.a_double;
4320 if (isnand (arg))
4322 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4324 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4326 else
4328 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4331 else
4333 int sign = 0;
4335 if (signbit (arg)) /* arg < 0.0 or negative zero */
4337 sign = -1;
4338 arg = -arg;
4341 if (sign < 0)
4342 *p++ = '-';
4343 else if (flags & FLAG_SHOWSIGN)
4344 *p++ = '+';
4345 else if (flags & FLAG_SPACE)
4346 *p++ = ' ';
4348 if (arg > 0.0 && arg + arg == arg)
4350 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4352 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4354 else
4356 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4359 else
4361 # if NEED_PRINTF_DOUBLE
4362 pad_ptr = p;
4364 if (dp->conversion == 'f' || dp->conversion == 'F')
4366 char *digits;
4367 size_t ndigits;
4369 digits =
4370 scale10_round_decimal_double (arg, precision);
4371 if (digits == NULL)
4372 goto out_of_memory;
4373 ndigits = strlen (digits);
4375 if (ndigits > precision)
4378 --ndigits;
4379 *p++ = digits[ndigits];
4381 while (ndigits > precision);
4382 else
4383 *p++ = '0';
4384 /* Here ndigits <= precision. */
4385 if ((flags & FLAG_ALT) || precision > 0)
4387 *p++ = decimal_point_char ();
4388 for (; precision > ndigits; precision--)
4389 *p++ = '0';
4390 while (ndigits > 0)
4392 --ndigits;
4393 *p++ = digits[ndigits];
4397 free (digits);
4399 else if (dp->conversion == 'e' || dp->conversion == 'E')
4401 int exponent;
4403 if (arg == 0.0)
4405 exponent = 0;
4406 *p++ = '0';
4407 if ((flags & FLAG_ALT) || precision > 0)
4409 *p++ = decimal_point_char ();
4410 for (; precision > 0; precision--)
4411 *p++ = '0';
4414 else
4416 /* arg > 0.0. */
4417 int adjusted;
4418 char *digits;
4419 size_t ndigits;
4421 exponent = floorlog10 (arg);
4422 adjusted = 0;
4423 for (;;)
4425 digits =
4426 scale10_round_decimal_double (arg,
4427 (int)precision - exponent);
4428 if (digits == NULL)
4429 goto out_of_memory;
4430 ndigits = strlen (digits);
4432 if (ndigits == precision + 1)
4433 break;
4434 if (ndigits < precision
4435 || ndigits > precision + 2)
4436 /* The exponent was not guessed
4437 precisely enough. */
4438 abort ();
4439 if (adjusted)
4440 /* None of two values of exponent is
4441 the right one. Prevent an endless
4442 loop. */
4443 abort ();
4444 free (digits);
4445 if (ndigits == precision)
4446 exponent -= 1;
4447 else
4448 exponent += 1;
4449 adjusted = 1;
4451 /* Here ndigits = precision+1. */
4452 if (is_borderline (digits, precision))
4454 /* Maybe the exponent guess was too high
4455 and a smaller exponent can be reached
4456 by turning a 10...0 into 9...9x. */
4457 char *digits2 =
4458 scale10_round_decimal_double (arg,
4459 (int)precision - exponent + 1);
4460 if (digits2 == NULL)
4462 free (digits);
4463 goto out_of_memory;
4465 if (strlen (digits2) == precision + 1)
4467 free (digits);
4468 digits = digits2;
4469 exponent -= 1;
4471 else
4472 free (digits2);
4474 /* Here ndigits = precision+1. */
4476 *p++ = digits[--ndigits];
4477 if ((flags & FLAG_ALT) || precision > 0)
4479 *p++ = decimal_point_char ();
4480 while (ndigits > 0)
4482 --ndigits;
4483 *p++ = digits[ndigits];
4487 free (digits);
4490 *p++ = dp->conversion; /* 'e' or 'E' */
4491 # if WIDE_CHAR_VERSION
4493 static const wchar_t decimal_format[] =
4494 /* Produce the same number of exponent digits
4495 as the native printf implementation. */
4496 # if defined _WIN32 && ! defined __CYGWIN__
4497 { '%', '+', '.', '3', 'd', '\0' };
4498 # else
4499 { '%', '+', '.', '2', 'd', '\0' };
4500 # endif
4501 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4503 while (*p != '\0')
4504 p++;
4505 # else
4507 static const char decimal_format[] =
4508 /* Produce the same number of exponent digits
4509 as the native printf implementation. */
4510 # if defined _WIN32 && ! defined __CYGWIN__
4511 "%+.3d";
4512 # else
4513 "%+.2d";
4514 # endif
4515 if (sizeof (DCHAR_T) == 1)
4517 sprintf ((char *) p, decimal_format, exponent);
4518 while (*p != '\0')
4519 p++;
4521 else
4523 char expbuf[6 + 1];
4524 const char *ep;
4525 sprintf (expbuf, decimal_format, exponent);
4526 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4527 p++;
4530 # endif
4532 else if (dp->conversion == 'g' || dp->conversion == 'G')
4534 if (precision == 0)
4535 precision = 1;
4536 /* precision >= 1. */
4538 if (arg == 0.0)
4539 /* The exponent is 0, >= -4, < precision.
4540 Use fixed-point notation. */
4542 size_t ndigits = precision;
4543 /* Number of trailing zeroes that have to be
4544 dropped. */
4545 size_t nzeroes =
4546 (flags & FLAG_ALT ? 0 : precision - 1);
4548 --ndigits;
4549 *p++ = '0';
4550 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4552 *p++ = decimal_point_char ();
4553 while (ndigits > nzeroes)
4555 --ndigits;
4556 *p++ = '0';
4560 else
4562 /* arg > 0.0. */
4563 int exponent;
4564 int adjusted;
4565 char *digits;
4566 size_t ndigits;
4567 size_t nzeroes;
4569 exponent = floorlog10 (arg);
4570 adjusted = 0;
4571 for (;;)
4573 digits =
4574 scale10_round_decimal_double (arg,
4575 (int)(precision - 1) - exponent);
4576 if (digits == NULL)
4577 goto out_of_memory;
4578 ndigits = strlen (digits);
4580 if (ndigits == precision)
4581 break;
4582 if (ndigits < precision - 1
4583 || ndigits > precision + 1)
4584 /* The exponent was not guessed
4585 precisely enough. */
4586 abort ();
4587 if (adjusted)
4588 /* None of two values of exponent is
4589 the right one. Prevent an endless
4590 loop. */
4591 abort ();
4592 free (digits);
4593 if (ndigits < precision)
4594 exponent -= 1;
4595 else
4596 exponent += 1;
4597 adjusted = 1;
4599 /* Here ndigits = precision. */
4600 if (is_borderline (digits, precision - 1))
4602 /* Maybe the exponent guess was too high
4603 and a smaller exponent can be reached
4604 by turning a 10...0 into 9...9x. */
4605 char *digits2 =
4606 scale10_round_decimal_double (arg,
4607 (int)(precision - 1) - exponent + 1);
4608 if (digits2 == NULL)
4610 free (digits);
4611 goto out_of_memory;
4613 if (strlen (digits2) == precision)
4615 free (digits);
4616 digits = digits2;
4617 exponent -= 1;
4619 else
4620 free (digits2);
4622 /* Here ndigits = precision. */
4624 /* Determine the number of trailing zeroes
4625 that have to be dropped. */
4626 nzeroes = 0;
4627 if ((flags & FLAG_ALT) == 0)
4628 while (nzeroes < ndigits
4629 && digits[nzeroes] == '0')
4630 nzeroes++;
4632 /* The exponent is now determined. */
4633 if (exponent >= -4
4634 && exponent < (long)precision)
4636 /* Fixed-point notation:
4637 max(exponent,0)+1 digits, then the
4638 decimal point, then the remaining
4639 digits without trailing zeroes. */
4640 if (exponent >= 0)
4642 size_t ecount = exponent + 1;
4643 /* Note: ecount <= precision = ndigits. */
4644 for (; ecount > 0; ecount--)
4645 *p++ = digits[--ndigits];
4646 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4648 *p++ = decimal_point_char ();
4649 while (ndigits > nzeroes)
4651 --ndigits;
4652 *p++ = digits[ndigits];
4656 else
4658 size_t ecount = -exponent - 1;
4659 *p++ = '0';
4660 *p++ = decimal_point_char ();
4661 for (; ecount > 0; ecount--)
4662 *p++ = '0';
4663 while (ndigits > nzeroes)
4665 --ndigits;
4666 *p++ = digits[ndigits];
4670 else
4672 /* Exponential notation. */
4673 *p++ = digits[--ndigits];
4674 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4676 *p++ = decimal_point_char ();
4677 while (ndigits > nzeroes)
4679 --ndigits;
4680 *p++ = digits[ndigits];
4683 *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4684 # if WIDE_CHAR_VERSION
4686 static const wchar_t decimal_format[] =
4687 /* Produce the same number of exponent digits
4688 as the native printf implementation. */
4689 # if defined _WIN32 && ! defined __CYGWIN__
4690 { '%', '+', '.', '3', 'd', '\0' };
4691 # else
4692 { '%', '+', '.', '2', 'd', '\0' };
4693 # endif
4694 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4696 while (*p != '\0')
4697 p++;
4698 # else
4700 static const char decimal_format[] =
4701 /* Produce the same number of exponent digits
4702 as the native printf implementation. */
4703 # if defined _WIN32 && ! defined __CYGWIN__
4704 "%+.3d";
4705 # else
4706 "%+.2d";
4707 # endif
4708 if (sizeof (DCHAR_T) == 1)
4710 sprintf ((char *) p, decimal_format, exponent);
4711 while (*p != '\0')
4712 p++;
4714 else
4716 char expbuf[6 + 1];
4717 const char *ep;
4718 sprintf (expbuf, decimal_format, exponent);
4719 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4720 p++;
4723 # endif
4726 free (digits);
4729 else
4730 abort ();
4731 # else
4732 /* arg is finite. */
4733 if (!(arg == 0.0))
4734 abort ();
4736 pad_ptr = p;
4738 if (dp->conversion == 'f' || dp->conversion == 'F')
4740 *p++ = '0';
4741 if ((flags & FLAG_ALT) || precision > 0)
4743 *p++ = decimal_point_char ();
4744 for (; precision > 0; precision--)
4745 *p++ = '0';
4748 else if (dp->conversion == 'e' || dp->conversion == 'E')
4750 *p++ = '0';
4751 if ((flags & FLAG_ALT) || precision > 0)
4753 *p++ = decimal_point_char ();
4754 for (; precision > 0; precision--)
4755 *p++ = '0';
4757 *p++ = dp->conversion; /* 'e' or 'E' */
4758 *p++ = '+';
4759 /* Produce the same number of exponent digits as
4760 the native printf implementation. */
4761 # if defined _WIN32 && ! defined __CYGWIN__
4762 *p++ = '0';
4763 # endif
4764 *p++ = '0';
4765 *p++ = '0';
4767 else if (dp->conversion == 'g' || dp->conversion == 'G')
4769 *p++ = '0';
4770 if (flags & FLAG_ALT)
4772 size_t ndigits =
4773 (precision > 0 ? precision - 1 : 0);
4774 *p++ = decimal_point_char ();
4775 for (; ndigits > 0; --ndigits)
4776 *p++ = '0';
4779 else
4780 abort ();
4781 # endif
4785 # endif
4787 /* The generated string now extends from tmp to p, with the
4788 zero padding insertion point being at pad_ptr. */
4789 count = p - tmp;
4791 if (count < width)
4793 size_t pad = width - count;
4794 DCHAR_T *end = p + pad;
4796 if (flags & FLAG_LEFT)
4798 /* Pad with spaces on the right. */
4799 for (; pad > 0; pad--)
4800 *p++ = ' ';
4802 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4804 /* Pad with zeroes. */
4805 DCHAR_T *q = end;
4807 while (p > pad_ptr)
4808 *--q = *--p;
4809 for (; pad > 0; pad--)
4810 *p++ = '0';
4812 else
4814 /* Pad with spaces on the left. */
4815 DCHAR_T *q = end;
4817 while (p > tmp)
4818 *--q = *--p;
4819 for (; pad > 0; pad--)
4820 *p++ = ' ';
4823 p = end;
4826 count = p - tmp;
4828 if (count >= tmp_length)
4829 /* tmp_length was incorrectly calculated - fix the
4830 code above! */
4831 abort ();
4833 /* Make room for the result. */
4834 if (count >= allocated - length)
4836 size_t n = xsum (length, count);
4838 ENSURE_ALLOCATION (n);
4841 /* Append the result. */
4842 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4843 if (tmp != tmpbuf)
4844 free (tmp);
4845 length += count;
4847 #endif
4848 else
4850 arg_type type = a.arg[dp->arg_index].type;
4851 int flags = dp->flags;
4852 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4853 int has_width;
4854 #endif
4855 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4856 size_t width;
4857 #endif
4858 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
4859 int has_precision;
4860 size_t precision;
4861 #endif
4862 #if NEED_PRINTF_UNBOUNDED_PRECISION
4863 int prec_ourselves;
4864 #else
4865 # define prec_ourselves 0
4866 #endif
4867 #if NEED_PRINTF_FLAG_LEFTADJUST
4868 # define pad_ourselves 1
4869 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4870 int pad_ourselves;
4871 #else
4872 # define pad_ourselves 0
4873 #endif
4874 TCHAR_T *fbp;
4875 unsigned int prefix_count;
4876 int prefixes[2] IF_LINT (= { 0 });
4877 int orig_errno;
4878 #if !USE_SNPRINTF
4879 size_t tmp_length;
4880 TCHAR_T tmpbuf[700];
4881 TCHAR_T *tmp;
4882 #endif
4884 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4885 has_width = 0;
4886 #endif
4887 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4888 width = 0;
4889 if (dp->width_start != dp->width_end)
4891 if (dp->width_arg_index != ARG_NONE)
4893 int arg;
4895 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4896 abort ();
4897 arg = a.arg[dp->width_arg_index].a.a_int;
4898 width = arg;
4899 if (arg < 0)
4901 /* "A negative field width is taken as a '-' flag
4902 followed by a positive field width." */
4903 flags |= FLAG_LEFT;
4904 width = -width;
4907 else
4909 const FCHAR_T *digitp = dp->width_start;
4912 width = xsum (xtimes (width, 10), *digitp++ - '0');
4913 while (digitp != dp->width_end);
4915 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4916 has_width = 1;
4917 #endif
4919 #endif
4921 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
4922 has_precision = 0;
4923 precision = 6;
4924 if (dp->precision_start != dp->precision_end)
4926 if (dp->precision_arg_index != ARG_NONE)
4928 int arg;
4930 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4931 abort ();
4932 arg = a.arg[dp->precision_arg_index].a.a_int;
4933 /* "A negative precision is taken as if the precision
4934 were omitted." */
4935 if (arg >= 0)
4937 precision = arg;
4938 has_precision = 1;
4941 else
4943 const FCHAR_T *digitp = dp->precision_start + 1;
4945 precision = 0;
4946 while (digitp != dp->precision_end)
4947 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4948 has_precision = 1;
4951 #endif
4953 /* Decide whether to handle the precision ourselves. */
4954 #if NEED_PRINTF_UNBOUNDED_PRECISION
4955 switch (dp->conversion)
4957 case 'd': case 'i': case 'u':
4958 case 'o':
4959 case 'x': case 'X': case 'p':
4960 prec_ourselves = has_precision && (precision > 0);
4961 break;
4962 default:
4963 prec_ourselves = 0;
4964 break;
4966 #endif
4968 /* Decide whether to perform the padding ourselves. */
4969 #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
4970 switch (dp->conversion)
4972 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4973 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
4974 to perform the padding after this conversion. Functions
4975 with unistdio extensions perform the padding based on
4976 character count rather than element count. */
4977 case 'c': case 's':
4978 # endif
4979 # if NEED_PRINTF_FLAG_ZERO
4980 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
4981 case 'a': case 'A':
4982 # endif
4983 pad_ourselves = 1;
4984 break;
4985 default:
4986 pad_ourselves = prec_ourselves;
4987 break;
4989 #endif
4991 #if !USE_SNPRINTF
4992 /* Allocate a temporary buffer of sufficient size for calling
4993 sprintf. */
4994 tmp_length =
4995 MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
4996 flags, width, has_precision, precision,
4997 pad_ourselves);
4999 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
5000 tmp = tmpbuf;
5001 else
5003 size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
5005 if (size_overflow_p (tmp_memsize))
5006 /* Overflow, would lead to out of memory. */
5007 goto out_of_memory;
5008 tmp = (TCHAR_T *) malloc (tmp_memsize);
5009 if (tmp == NULL)
5010 /* Out of memory. */
5011 goto out_of_memory;
5013 #endif
5015 /* Construct the format string for calling snprintf or
5016 sprintf. */
5017 fbp = buf;
5018 *fbp++ = '%';
5019 #if NEED_PRINTF_FLAG_GROUPING
5020 /* The underlying implementation doesn't support the ' flag.
5021 Produce no grouping characters in this case; this is
5022 acceptable because the grouping is locale dependent. */
5023 #else
5024 if (flags & FLAG_GROUP)
5025 *fbp++ = '\'';
5026 #endif
5027 if (flags & FLAG_LEFT)
5028 *fbp++ = '-';
5029 if (flags & FLAG_SHOWSIGN)
5030 *fbp++ = '+';
5031 if (flags & FLAG_SPACE)
5032 *fbp++ = ' ';
5033 if (flags & FLAG_ALT)
5034 *fbp++ = '#';
5035 #if __GLIBC__ >= 2 && !defined __UCLIBC__
5036 if (flags & FLAG_LOCALIZED)
5037 *fbp++ = 'I';
5038 #endif
5039 if (!pad_ourselves)
5041 if (flags & FLAG_ZERO)
5042 *fbp++ = '0';
5043 if (dp->width_start != dp->width_end)
5045 size_t n = dp->width_end - dp->width_start;
5046 /* The width specification is known to consist only
5047 of standard ASCII characters. */
5048 if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
5050 memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
5051 fbp += n;
5053 else
5055 const FCHAR_T *mp = dp->width_start;
5057 *fbp++ = *mp++;
5058 while (--n > 0);
5062 if (!prec_ourselves)
5064 if (dp->precision_start != dp->precision_end)
5066 size_t n = dp->precision_end - dp->precision_start;
5067 /* The precision specification is known to consist only
5068 of standard ASCII characters. */
5069 if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
5071 memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
5072 fbp += n;
5074 else
5076 const FCHAR_T *mp = dp->precision_start;
5078 *fbp++ = *mp++;
5079 while (--n > 0);
5084 switch (type)
5086 case TYPE_LONGLONGINT:
5087 case TYPE_ULONGLONGINT:
5088 #if defined _WIN32 && ! defined __CYGWIN__
5089 *fbp++ = 'I';
5090 *fbp++ = '6';
5091 *fbp++ = '4';
5092 break;
5093 #else
5094 *fbp++ = 'l';
5095 #endif
5096 FALLTHROUGH;
5097 case TYPE_LONGINT:
5098 case TYPE_ULONGINT:
5099 #if HAVE_WINT_T
5100 case TYPE_WIDE_CHAR:
5101 #endif
5102 #if HAVE_WCHAR_T
5103 case TYPE_WIDE_STRING:
5104 #endif
5105 *fbp++ = 'l';
5106 break;
5107 case TYPE_LONGDOUBLE:
5108 *fbp++ = 'L';
5109 break;
5110 default:
5111 break;
5113 #if NEED_PRINTF_DIRECTIVE_F
5114 if (dp->conversion == 'F')
5115 *fbp = 'f';
5116 else
5117 #endif
5118 *fbp = dp->conversion;
5119 #if USE_SNPRINTF
5120 # if ! (((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) \
5121 && !defined __UCLIBC__) \
5122 || (defined __APPLE__ && defined __MACH__) \
5123 || defined __ANDROID__ \
5124 || (defined _WIN32 && ! defined __CYGWIN__))
5125 fbp[1] = '%';
5126 fbp[2] = 'n';
5127 fbp[3] = '\0';
5128 # else
5129 /* On glibc2 systems from glibc >= 2.3 - probably also older
5130 ones - we know that snprintf's return value conforms to
5131 ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and
5132 gl_SNPRINTF_TRUNCATION_C99 pass.
5133 Therefore we can avoid using %n in this situation.
5134 On glibc2 systems from 2004-10-18 or newer, the use of %n
5135 in format strings in writable memory may crash the program
5136 (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
5137 in this situation. */
5138 /* On Mac OS X 10.3 or newer, we know that snprintf's return
5139 value conforms to ISO C 99: the tests gl_SNPRINTF_RETVAL_C99
5140 and gl_SNPRINTF_TRUNCATION_C99 pass.
5141 Therefore we can avoid using %n in this situation.
5142 On Mac OS X 10.13 or newer, the use of %n in format strings
5143 in writable memory by default crashes the program, so we
5144 should avoid it in this situation. */
5145 /* On Android, we know that snprintf's return value conforms to
5146 ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and
5147 gl_SNPRINTF_TRUNCATION_C99 pass.
5148 Therefore we can avoid using %n in this situation.
5149 Starting on 2018-03-07, the use of %n in format strings
5150 produces a fatal error (see
5151 <https://android.googlesource.com/platform/bionic/+/41398d03b7e8e0dfb951660ae713e682e9fc0336>),
5152 so we should avoid it. */
5153 /* On native Windows systems (such as mingw), we can avoid using
5154 %n because:
5155 - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
5156 snprintf does not write more than the specified number
5157 of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
5158 '4', '5', '6' into buf, not '4', '5', '\0'.)
5159 - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
5160 allows us to recognize the case of an insufficient
5161 buffer size: it returns -1 in this case.
5162 On native Windows systems (such as mingw) where the OS is
5163 Windows Vista, the use of %n in format strings by default
5164 crashes the program. See
5165 <https://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
5166 <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-printf-count-output>
5167 So we should avoid %n in this situation. */
5168 fbp[1] = '\0';
5169 # endif
5170 #else
5171 fbp[1] = '\0';
5172 #endif
5174 /* Construct the arguments for calling snprintf or sprintf. */
5175 prefix_count = 0;
5176 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
5178 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
5179 abort ();
5180 prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
5182 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
5184 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
5185 abort ();
5186 prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
5189 #if USE_SNPRINTF
5190 /* The SNPRINTF result is appended after result[0..length].
5191 The latter is an array of DCHAR_T; SNPRINTF appends an
5192 array of TCHAR_T to it. This is possible because
5193 sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
5194 alignof (TCHAR_T) <= alignof (DCHAR_T). */
5195 # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
5196 /* Ensure that maxlen below will be >= 2. Needed on BeOS,
5197 where an snprintf() with maxlen==1 acts like sprintf(). */
5198 ENSURE_ALLOCATION (xsum (length,
5199 (2 + TCHARS_PER_DCHAR - 1)
5200 / TCHARS_PER_DCHAR));
5201 /* Prepare checking whether snprintf returns the count
5202 via %n. */
5203 *(TCHAR_T *) (result + length) = '\0';
5204 #endif
5206 orig_errno = errno;
5208 for (;;)
5210 int count = -1;
5212 #if USE_SNPRINTF
5213 int retcount = 0;
5214 size_t maxlen = allocated - length;
5215 /* SNPRINTF can fail if its second argument is
5216 > INT_MAX. */
5217 if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
5218 maxlen = INT_MAX / TCHARS_PER_DCHAR;
5219 maxlen = maxlen * TCHARS_PER_DCHAR;
5220 # define SNPRINTF_BUF(arg) \
5221 switch (prefix_count) \
5223 case 0: \
5224 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
5225 maxlen, buf, \
5226 arg, &count); \
5227 break; \
5228 case 1: \
5229 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
5230 maxlen, buf, \
5231 prefixes[0], arg, &count); \
5232 break; \
5233 case 2: \
5234 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
5235 maxlen, buf, \
5236 prefixes[0], prefixes[1], arg, \
5237 &count); \
5238 break; \
5239 default: \
5240 abort (); \
5242 #else
5243 # define SNPRINTF_BUF(arg) \
5244 switch (prefix_count) \
5246 case 0: \
5247 count = sprintf (tmp, buf, arg); \
5248 break; \
5249 case 1: \
5250 count = sprintf (tmp, buf, prefixes[0], arg); \
5251 break; \
5252 case 2: \
5253 count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
5254 arg); \
5255 break; \
5256 default: \
5257 abort (); \
5259 #endif
5261 errno = 0;
5262 switch (type)
5264 case TYPE_SCHAR:
5266 int arg = a.arg[dp->arg_index].a.a_schar;
5267 SNPRINTF_BUF (arg);
5269 break;
5270 case TYPE_UCHAR:
5272 unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
5273 SNPRINTF_BUF (arg);
5275 break;
5276 case TYPE_SHORT:
5278 int arg = a.arg[dp->arg_index].a.a_short;
5279 SNPRINTF_BUF (arg);
5281 break;
5282 case TYPE_USHORT:
5284 unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
5285 SNPRINTF_BUF (arg);
5287 break;
5288 case TYPE_INT:
5290 int arg = a.arg[dp->arg_index].a.a_int;
5291 SNPRINTF_BUF (arg);
5293 break;
5294 case TYPE_UINT:
5296 unsigned int arg = a.arg[dp->arg_index].a.a_uint;
5297 SNPRINTF_BUF (arg);
5299 break;
5300 case TYPE_LONGINT:
5302 long int arg = a.arg[dp->arg_index].a.a_longint;
5303 SNPRINTF_BUF (arg);
5305 break;
5306 case TYPE_ULONGINT:
5308 unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
5309 SNPRINTF_BUF (arg);
5311 break;
5312 case TYPE_LONGLONGINT:
5314 long long int arg = a.arg[dp->arg_index].a.a_longlongint;
5315 SNPRINTF_BUF (arg);
5317 break;
5318 case TYPE_ULONGLONGINT:
5320 unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
5321 SNPRINTF_BUF (arg);
5323 break;
5324 case TYPE_DOUBLE:
5326 double arg = a.arg[dp->arg_index].a.a_double;
5327 SNPRINTF_BUF (arg);
5329 break;
5330 case TYPE_LONGDOUBLE:
5332 long double arg = a.arg[dp->arg_index].a.a_longdouble;
5333 SNPRINTF_BUF (arg);
5335 break;
5336 case TYPE_CHAR:
5338 int arg = a.arg[dp->arg_index].a.a_char;
5339 SNPRINTF_BUF (arg);
5341 break;
5342 #if HAVE_WINT_T
5343 case TYPE_WIDE_CHAR:
5345 wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
5346 SNPRINTF_BUF (arg);
5348 break;
5349 #endif
5350 case TYPE_STRING:
5352 const char *arg = a.arg[dp->arg_index].a.a_string;
5353 SNPRINTF_BUF (arg);
5355 break;
5356 #if HAVE_WCHAR_T
5357 case TYPE_WIDE_STRING:
5359 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
5360 SNPRINTF_BUF (arg);
5362 break;
5363 #endif
5364 case TYPE_POINTER:
5366 void *arg = a.arg[dp->arg_index].a.a_pointer;
5367 SNPRINTF_BUF (arg);
5369 break;
5370 default:
5371 abort ();
5374 #if USE_SNPRINTF
5375 /* Portability: Not all implementations of snprintf()
5376 are ISO C 99 compliant. Determine the number of
5377 bytes that snprintf() has produced or would have
5378 produced. */
5379 if (count >= 0)
5381 /* Verify that snprintf() has NUL-terminated its
5382 result. */
5383 if ((unsigned int) count < maxlen
5384 && ((TCHAR_T *) (result + length)) [count] != '\0')
5385 abort ();
5386 /* Portability hack. */
5387 if (retcount > count)
5388 count = retcount;
5390 else
5392 /* snprintf() doesn't understand the '%n'
5393 directive. */
5394 if (fbp[1] != '\0')
5396 /* Don't use the '%n' directive; instead, look
5397 at the snprintf() return value. */
5398 fbp[1] = '\0';
5399 continue;
5401 else
5403 /* Look at the snprintf() return value. */
5404 if (retcount < 0)
5406 # if !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
5407 /* HP-UX 10.20 snprintf() is doubly deficient:
5408 It doesn't understand the '%n' directive,
5409 *and* it returns -1 (rather than the length
5410 that would have been required) when the
5411 buffer is too small.
5412 But a failure at this point can also come
5413 from other reasons than a too small buffer,
5414 such as an invalid wide string argument to
5415 the %ls directive, or possibly an invalid
5416 floating-point argument. */
5417 size_t tmp_length =
5418 MAX_ROOM_NEEDED (&a, dp->arg_index,
5419 dp->conversion, type, flags,
5420 width,
5421 has_precision,
5422 precision, pad_ourselves);
5424 if (maxlen < tmp_length)
5426 /* Make more room. But try to do through
5427 this reallocation only once. */
5428 size_t bigger_need =
5429 xsum (length,
5430 xsum (tmp_length,
5431 TCHARS_PER_DCHAR - 1)
5432 / TCHARS_PER_DCHAR);
5433 /* And always grow proportionally.
5434 (There may be several arguments, each
5435 needing a little more room than the
5436 previous one.) */
5437 size_t bigger_need2 =
5438 xsum (xtimes (allocated, 2), 12);
5439 if (bigger_need < bigger_need2)
5440 bigger_need = bigger_need2;
5441 ENSURE_ALLOCATION (bigger_need);
5442 continue;
5444 # endif
5446 else
5447 count = retcount;
5450 #endif
5452 /* Attempt to handle failure. */
5453 if (count < 0)
5455 /* SNPRINTF or sprintf failed. Save and use the errno
5456 that it has set, if any. */
5457 int saved_errno = errno;
5458 if (saved_errno == 0)
5460 if (dp->conversion == 'c' || dp->conversion == 's')
5461 saved_errno = EILSEQ;
5462 else
5463 saved_errno = EINVAL;
5466 if (!(result == resultbuf || result == NULL))
5467 free (result);
5468 if (buf_malloced != NULL)
5469 free (buf_malloced);
5470 CLEANUP ();
5472 errno = saved_errno;
5473 return NULL;
5476 #if USE_SNPRINTF
5477 /* Handle overflow of the allocated buffer.
5478 If such an overflow occurs, a C99 compliant snprintf()
5479 returns a count >= maxlen. However, a non-compliant
5480 snprintf() function returns only count = maxlen - 1. To
5481 cover both cases, test whether count >= maxlen - 1. */
5482 if ((unsigned int) count + 1 >= maxlen)
5484 /* If maxlen already has attained its allowed maximum,
5485 allocating more memory will not increase maxlen.
5486 Instead of looping, bail out. */
5487 if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
5488 goto overflow;
5489 else
5491 /* Need at least (count + 1) * sizeof (TCHAR_T)
5492 bytes. (The +1 is for the trailing NUL.)
5493 But ask for (count + 2) * sizeof (TCHAR_T)
5494 bytes, so that in the next round, we likely get
5495 maxlen > (unsigned int) count + 1
5496 and so we don't get here again.
5497 And allocate proportionally, to avoid looping
5498 eternally if snprintf() reports a too small
5499 count. */
5500 size_t n =
5501 xmax (xsum (length,
5502 ((unsigned int) count + 2
5503 + TCHARS_PER_DCHAR - 1)
5504 / TCHARS_PER_DCHAR),
5505 xtimes (allocated, 2));
5507 ENSURE_ALLOCATION (n);
5508 continue;
5511 #endif
5513 #if NEED_PRINTF_UNBOUNDED_PRECISION
5514 if (prec_ourselves)
5516 /* Handle the precision. */
5517 TCHAR_T *prec_ptr =
5518 # if USE_SNPRINTF
5519 (TCHAR_T *) (result + length);
5520 # else
5521 tmp;
5522 # endif
5523 size_t prefix_count;
5524 size_t move;
5526 prefix_count = 0;
5527 /* Put the additional zeroes after the sign. */
5528 if (count >= 1
5529 && (*prec_ptr == '-' || *prec_ptr == '+'
5530 || *prec_ptr == ' '))
5531 prefix_count = 1;
5532 /* Put the additional zeroes after the 0x prefix if
5533 (flags & FLAG_ALT) || (dp->conversion == 'p'). */
5534 else if (count >= 2
5535 && prec_ptr[0] == '0'
5536 && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
5537 prefix_count = 2;
5539 move = count - prefix_count;
5540 if (precision > move)
5542 /* Insert zeroes. */
5543 size_t insert = precision - move;
5544 TCHAR_T *prec_end;
5546 # if USE_SNPRINTF
5547 size_t n =
5548 xsum (length,
5549 (count + insert + TCHARS_PER_DCHAR - 1)
5550 / TCHARS_PER_DCHAR);
5551 length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5552 ENSURE_ALLOCATION (n);
5553 length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5554 prec_ptr = (TCHAR_T *) (result + length);
5555 # endif
5557 prec_end = prec_ptr + count;
5558 prec_ptr += prefix_count;
5560 while (prec_end > prec_ptr)
5562 prec_end--;
5563 prec_end[insert] = prec_end[0];
5566 prec_end += insert;
5568 *--prec_end = '0';
5569 while (prec_end > prec_ptr);
5571 count += insert;
5574 #endif
5576 #if !USE_SNPRINTF
5577 if (count >= tmp_length)
5578 /* tmp_length was incorrectly calculated - fix the
5579 code above! */
5580 abort ();
5581 #endif
5583 #if !DCHAR_IS_TCHAR
5584 /* Convert from TCHAR_T[] to DCHAR_T[]. */
5585 if (dp->conversion == 'c' || dp->conversion == 's')
5587 /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
5588 TYPE_WIDE_STRING.
5589 The result string is not certainly ASCII. */
5590 const TCHAR_T *tmpsrc;
5591 DCHAR_T *tmpdst;
5592 size_t tmpdst_len;
5593 /* This code assumes that TCHAR_T is 'char'. */
5594 verify (sizeof (TCHAR_T) == 1);
5595 # if USE_SNPRINTF
5596 tmpsrc = (TCHAR_T *) (result + length);
5597 # else
5598 tmpsrc = tmp;
5599 # endif
5600 tmpdst =
5601 DCHAR_CONV_FROM_ENCODING (locale_charset (),
5602 iconveh_question_mark,
5603 tmpsrc, count,
5604 NULL,
5605 NULL, &tmpdst_len);
5606 if (tmpdst == NULL)
5608 int saved_errno = errno;
5609 if (!(result == resultbuf || result == NULL))
5610 free (result);
5611 if (buf_malloced != NULL)
5612 free (buf_malloced);
5613 CLEANUP ();
5614 errno = saved_errno;
5615 return NULL;
5617 ENSURE_ALLOCATION (xsum (length, tmpdst_len));
5618 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
5619 free (tmpdst);
5620 count = tmpdst_len;
5622 else
5624 /* The result string is ASCII.
5625 Simple 1:1 conversion. */
5626 # if USE_SNPRINTF
5627 /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
5628 no-op conversion, in-place on the array starting
5629 at (result + length). */
5630 if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
5631 # endif
5633 const TCHAR_T *tmpsrc;
5634 DCHAR_T *tmpdst;
5635 size_t n;
5637 # if USE_SNPRINTF
5638 if (result == resultbuf)
5640 tmpsrc = (TCHAR_T *) (result + length);
5641 /* ENSURE_ALLOCATION will not move tmpsrc
5642 (because it's part of resultbuf). */
5643 ENSURE_ALLOCATION (xsum (length, count));
5645 else
5647 /* ENSURE_ALLOCATION will move the array
5648 (because it uses realloc(). */
5649 ENSURE_ALLOCATION (xsum (length, count));
5650 tmpsrc = (TCHAR_T *) (result + length);
5652 # else
5653 tmpsrc = tmp;
5654 ENSURE_ALLOCATION (xsum (length, count));
5655 # endif
5656 tmpdst = result + length;
5657 /* Copy backwards, because of overlapping. */
5658 tmpsrc += count;
5659 tmpdst += count;
5660 for (n = count; n > 0; n--)
5661 *--tmpdst = *--tmpsrc;
5664 #endif
5666 #if DCHAR_IS_TCHAR && !USE_SNPRINTF
5667 /* Make room for the result. */
5668 if (count > allocated - length)
5670 /* Need at least count elements. But allocate
5671 proportionally. */
5672 size_t n =
5673 xmax (xsum (length, count), xtimes (allocated, 2));
5675 ENSURE_ALLOCATION (n);
5677 #endif
5679 /* Here count <= allocated - length. */
5681 /* Perform padding. */
5682 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5683 if (pad_ourselves && has_width)
5685 size_t w;
5686 # if ENABLE_UNISTDIO
5687 /* Outside POSIX, it's preferable to compare the width
5688 against the number of _characters_ of the converted
5689 value. */
5690 w = DCHAR_MBSNLEN (result + length, count);
5691 # else
5692 /* The width is compared against the number of _bytes_
5693 of the converted value, says POSIX. */
5694 w = count;
5695 # endif
5696 if (w < width)
5698 size_t pad = width - w;
5700 /* Make room for the result. */
5701 if (xsum (count, pad) > allocated - length)
5703 /* Need at least count + pad elements. But
5704 allocate proportionally. */
5705 size_t n =
5706 xmax (xsum3 (length, count, pad),
5707 xtimes (allocated, 2));
5709 # if USE_SNPRINTF
5710 length += count;
5711 ENSURE_ALLOCATION (n);
5712 length -= count;
5713 # else
5714 ENSURE_ALLOCATION (n);
5715 # endif
5717 /* Here count + pad <= allocated - length. */
5720 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
5721 DCHAR_T * const rp = result + length;
5722 # else
5723 DCHAR_T * const rp = tmp;
5724 # endif
5725 DCHAR_T *p = rp + count;
5726 DCHAR_T *end = p + pad;
5727 DCHAR_T *pad_ptr;
5728 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
5729 if (dp->conversion == 'c'
5730 || dp->conversion == 's')
5731 /* No zero-padding for string directives. */
5732 pad_ptr = NULL;
5733 else
5734 # endif
5736 pad_ptr = (*rp == '-' ? rp + 1 : rp);
5737 /* No zero-padding of "inf" and "nan". */
5738 if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
5739 || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
5740 pad_ptr = NULL;
5742 /* The generated string now extends from rp to p,
5743 with the zero padding insertion point being at
5744 pad_ptr. */
5746 count = count + pad; /* = end - rp */
5748 if (flags & FLAG_LEFT)
5750 /* Pad with spaces on the right. */
5751 for (; pad > 0; pad--)
5752 *p++ = ' ';
5754 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
5756 /* Pad with zeroes. */
5757 DCHAR_T *q = end;
5759 while (p > pad_ptr)
5760 *--q = *--p;
5761 for (; pad > 0; pad--)
5762 *p++ = '0';
5764 else
5766 /* Pad with spaces on the left. */
5767 DCHAR_T *q = end;
5769 while (p > rp)
5770 *--q = *--p;
5771 for (; pad > 0; pad--)
5772 *p++ = ' ';
5777 #endif
5779 /* Here still count <= allocated - length. */
5781 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
5782 /* The snprintf() result did fit. */
5783 #else
5784 /* Append the sprintf() result. */
5785 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
5786 #endif
5787 #if !USE_SNPRINTF
5788 if (tmp != tmpbuf)
5789 free (tmp);
5790 #endif
5792 #if NEED_PRINTF_DIRECTIVE_F
5793 if (dp->conversion == 'F')
5795 /* Convert the %f result to upper case for %F. */
5796 DCHAR_T *rp = result + length;
5797 size_t rc;
5798 for (rc = count; rc > 0; rc--, rp++)
5799 if (*rp >= 'a' && *rp <= 'z')
5800 *rp = *rp - 'a' + 'A';
5802 #endif
5804 length += count;
5805 break;
5807 errno = orig_errno;
5808 #undef pad_ourselves
5809 #undef prec_ourselves
5814 /* Add the final NUL. */
5815 ENSURE_ALLOCATION (xsum (length, 1));
5816 result[length] = '\0';
5818 if (result != resultbuf && length + 1 < allocated)
5820 /* Shrink the allocated memory if possible. */
5821 DCHAR_T *memory;
5823 memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
5824 if (memory != NULL)
5825 result = memory;
5828 if (buf_malloced != NULL)
5829 free (buf_malloced);
5830 CLEANUP ();
5831 *lengthp = length;
5832 /* Note that we can produce a big string of a length > INT_MAX. POSIX
5833 says that snprintf() fails with errno = EOVERFLOW in this case, but
5834 that's only because snprintf() returns an 'int'. This function does
5835 not have this limitation. */
5836 return result;
5838 #if USE_SNPRINTF
5839 overflow:
5840 if (!(result == resultbuf || result == NULL))
5841 free (result);
5842 if (buf_malloced != NULL)
5843 free (buf_malloced);
5844 CLEANUP ();
5845 errno = EOVERFLOW;
5846 return NULL;
5847 #endif
5849 out_of_memory:
5850 if (!(result == resultbuf || result == NULL))
5851 free (result);
5852 if (buf_malloced != NULL)
5853 free (buf_malloced);
5854 out_of_memory_1:
5855 CLEANUP ();
5856 errno = ENOMEM;
5857 return NULL;
5861 #undef MAX_ROOM_NEEDED
5862 #undef TCHARS_PER_DCHAR
5863 #undef SNPRINTF
5864 #undef USE_SNPRINTF
5865 #undef DCHAR_SET
5866 #undef DCHAR_CPY
5867 #undef PRINTF_PARSE
5868 #undef DIRECTIVES
5869 #undef DIRECTIVE
5870 #undef DCHAR_IS_TCHAR
5871 #undef TCHAR_T
5872 #undef DCHAR_T
5873 #undef FCHAR_T
5874 #undef VASNPRINTF