Add `gnutls/dtls.h' to the distribution.
[gnutls.git] / gl / vasnprintf.c
blob1e9cd431e650dd81bf9b2d9487b832774d8d540d
1 /* vsprintf with automatic memory allocation.
2 Copyright (C) 1999, 2002-2010 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, 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, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18 /* This file can be parametrized with the following macros:
19 VASNPRINTF The name of the function being defined.
20 FCHAR_T The element type of the format string.
21 DCHAR_T The element type of the destination (result) string.
22 FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
23 in the format string are ASCII. MUST be set if
24 FCHAR_T and DCHAR_T are not the same type.
25 DIRECTIVE Structure denoting a format directive.
26 Depends on FCHAR_T.
27 DIRECTIVES Structure denoting the set of format directives of a
28 format string. Depends on FCHAR_T.
29 PRINTF_PARSE Function that parses a format string.
30 Depends on FCHAR_T.
31 DCHAR_CPY memcpy like function for DCHAR_T[] arrays.
32 DCHAR_SET memset like function for DCHAR_T[] arrays.
33 DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays.
34 SNPRINTF The system's snprintf (or similar) function.
35 This may be either snprintf or swprintf.
36 TCHAR_T The element type of the argument and result string
37 of the said SNPRINTF function. This may be either
38 char or wchar_t. The code exploits that
39 sizeof (TCHAR_T) | sizeof (DCHAR_T) and
40 alignof (TCHAR_T) <= alignof (DCHAR_T).
41 DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type.
42 DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
43 DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t.
44 DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t.
45 DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */
47 /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
48 This must come before <config.h> because <config.h> may include
49 <features.h>, and once <features.h> has been included, it's too late. */
50 #ifndef _GNU_SOURCE
51 # define _GNU_SOURCE 1
52 #endif
54 #ifndef VASNPRINTF
55 # include <config.h>
56 #endif
57 #ifndef IN_LIBINTL
58 # include <alloca.h>
59 #endif
61 /* Specification. */
62 #ifndef VASNPRINTF
63 # if WIDE_CHAR_VERSION
64 # include "vasnwprintf.h"
65 # else
66 # include "vasnprintf.h"
67 # endif
68 #endif
70 #include <locale.h> /* localeconv() */
71 #include <stdio.h> /* snprintf(), sprintf() */
72 #include <stdlib.h> /* abort(), malloc(), realloc(), free() */
73 #include <string.h> /* memcpy(), strlen() */
74 #include <errno.h> /* errno */
75 #include <limits.h> /* CHAR_BIT */
76 #include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
77 #if HAVE_NL_LANGINFO
78 # include <langinfo.h>
79 #endif
80 #ifndef VASNPRINTF
81 # if WIDE_CHAR_VERSION
82 # include "wprintf-parse.h"
83 # else
84 # include "printf-parse.h"
85 # endif
86 #endif
88 /* Checked size_t computations. */
89 #include "xsize.h"
91 #include "verify.h"
93 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
94 # include <math.h>
95 # include "float+.h"
96 #endif
98 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
99 # include <math.h>
100 # include "isnand-nolibm.h"
101 #endif
103 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
104 # include <math.h>
105 # include "isnanl-nolibm.h"
106 # include "fpucw.h"
107 #endif
109 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
110 # include <math.h>
111 # include "isnand-nolibm.h"
112 # include "printf-frexp.h"
113 #endif
115 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
116 # include <math.h>
117 # include "isnanl-nolibm.h"
118 # include "printf-frexpl.h"
119 # include "fpucw.h"
120 #endif
122 /* Default parameters. */
123 #ifndef VASNPRINTF
124 # if WIDE_CHAR_VERSION
125 # define VASNPRINTF vasnwprintf
126 # define FCHAR_T wchar_t
127 # define DCHAR_T wchar_t
128 # define TCHAR_T wchar_t
129 # define DCHAR_IS_TCHAR 1
130 # define DIRECTIVE wchar_t_directive
131 # define DIRECTIVES wchar_t_directives
132 # define PRINTF_PARSE wprintf_parse
133 # define DCHAR_CPY wmemcpy
134 # define DCHAR_SET wmemset
135 # else
136 # define VASNPRINTF vasnprintf
137 # define FCHAR_T char
138 # define DCHAR_T char
139 # define TCHAR_T char
140 # define DCHAR_IS_TCHAR 1
141 # define DIRECTIVE char_directive
142 # define DIRECTIVES char_directives
143 # define PRINTF_PARSE printf_parse
144 # define DCHAR_CPY memcpy
145 # define DCHAR_SET memset
146 # endif
147 #endif
148 #if WIDE_CHAR_VERSION
149 /* TCHAR_T is wchar_t. */
150 # define USE_SNPRINTF 1
151 # if HAVE_DECL__SNWPRINTF
152 /* On Windows, the function swprintf() has a different signature than
153 on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
154 instead. The mingw function snwprintf() has fewer bugs than the
155 MSVCRT function _snwprintf(), so prefer that. */
156 # if defined __MINGW32__
157 # define SNPRINTF snwprintf
158 # else
159 # define SNPRINTF _snwprintf
160 # endif
161 # else
162 /* Unix. */
163 # define SNPRINTF swprintf
164 # endif
165 #else
166 /* TCHAR_T is char. */
167 /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
168 But don't use it on BeOS, since BeOS snprintf produces no output if the
169 size argument is >= 0x3000000.
170 Also don't use it on Linux libc5, since there snprintf with size = 1
171 writes any output without bounds, like sprintf. */
172 # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
173 # define USE_SNPRINTF 1
174 # else
175 # define USE_SNPRINTF 0
176 # endif
177 # if HAVE_DECL__SNPRINTF
178 /* Windows. The mingw function snprintf() has fewer bugs than the MSVCRT
179 function _snprintf(), so prefer that. */
180 # if defined __MINGW32__
181 # define SNPRINTF snprintf
182 /* Here we need to call the native snprintf, not rpl_snprintf. */
183 # undef snprintf
184 # else
185 # define SNPRINTF _snprintf
186 # endif
187 # else
188 /* Unix. */
189 # define SNPRINTF snprintf
190 /* Here we need to call the native snprintf, not rpl_snprintf. */
191 # undef snprintf
192 # endif
193 #endif
194 /* Here we need to call the native sprintf, not rpl_sprintf. */
195 #undef sprintf
197 /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
198 warnings in this file. Use -Dlint to suppress them. */
199 #ifdef lint
200 # define IF_LINT(Code) Code
201 #else
202 # define IF_LINT(Code) /* empty */
203 #endif
205 /* Avoid some warnings from "gcc -Wshadow".
206 This file doesn't use the exp() and remainder() functions. */
207 #undef exp
208 #define exp expo
209 #undef remainder
210 #define remainder rem
212 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION
213 # if (HAVE_STRNLEN && !defined _AIX)
214 # define local_strnlen strnlen
215 # else
216 # ifndef local_strnlen_defined
217 # define local_strnlen_defined 1
218 static size_t
219 local_strnlen (const char *string, size_t maxlen)
221 const char *end = memchr (string, '\0', maxlen);
222 return end ? (size_t) (end - string) : maxlen;
224 # endif
225 # endif
226 #endif
228 #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
229 # if HAVE_WCSLEN
230 # define local_wcslen wcslen
231 # else
232 /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
233 a dependency towards this library, here is a local substitute.
234 Define this substitute only once, even if this file is included
235 twice in the same compilation unit. */
236 # ifndef local_wcslen_defined
237 # define local_wcslen_defined 1
238 static size_t
239 local_wcslen (const wchar_t *s)
241 const wchar_t *ptr;
243 for (ptr = s; *ptr != (wchar_t) 0; ptr++)
245 return ptr - s;
247 # endif
248 # endif
249 #endif
251 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
252 # if HAVE_WCSNLEN
253 # define local_wcsnlen wcsnlen
254 # else
255 # ifndef local_wcsnlen_defined
256 # define local_wcsnlen_defined 1
257 static size_t
258 local_wcsnlen (const wchar_t *s, size_t maxlen)
260 const wchar_t *ptr;
262 for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
264 return ptr - s;
266 # endif
267 # endif
268 #endif
270 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
271 /* Determine the decimal-point character according to the current locale. */
272 # ifndef decimal_point_char_defined
273 # define decimal_point_char_defined 1
274 static char
275 decimal_point_char (void)
277 const char *point;
278 /* Determine it in a multithread-safe way. We know nl_langinfo is
279 multithread-safe on glibc systems and MacOS X systems, but is not required
280 to be multithread-safe by POSIX. sprintf(), however, is multithread-safe.
281 localeconv() is rarely multithread-safe. */
282 # if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__))
283 point = nl_langinfo (RADIXCHAR);
284 # elif 1
285 char pointbuf[5];
286 sprintf (pointbuf, "%#.0f", 1.0);
287 point = &pointbuf[1];
288 # else
289 point = localeconv () -> decimal_point;
290 # endif
291 /* The decimal point is always a single byte: either '.' or ','. */
292 return (point[0] != '\0' ? point[0] : '.');
294 # endif
295 #endif
297 #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
299 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
300 static int
301 is_infinite_or_zero (double x)
303 return isnand (x) || x + x == x;
306 #endif
308 #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
310 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
311 static int
312 is_infinite_or_zerol (long double x)
314 return isnanl (x) || x + x == x;
317 #endif
319 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
321 /* Converting 'long double' to decimal without rare rounding bugs requires
322 real bignums. We use the naming conventions of GNU gmp, but vastly simpler
323 (and slower) algorithms. */
325 typedef unsigned int mp_limb_t;
326 # define GMP_LIMB_BITS 32
327 verify (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS);
329 typedef unsigned long long mp_twolimb_t;
330 # define GMP_TWOLIMB_BITS 64
331 verify (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS);
333 /* Representation of a bignum >= 0. */
334 typedef struct
336 size_t nlimbs;
337 mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */
338 } mpn_t;
340 /* Compute the product of two bignums >= 0.
341 Return the allocated memory in case of success, NULL in case of memory
342 allocation failure. */
343 static void *
344 multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
346 const mp_limb_t *p1;
347 const mp_limb_t *p2;
348 size_t len1;
349 size_t len2;
351 if (src1.nlimbs <= src2.nlimbs)
353 len1 = src1.nlimbs;
354 p1 = src1.limbs;
355 len2 = src2.nlimbs;
356 p2 = src2.limbs;
358 else
360 len1 = src2.nlimbs;
361 p1 = src2.limbs;
362 len2 = src1.nlimbs;
363 p2 = src1.limbs;
365 /* Now 0 <= len1 <= len2. */
366 if (len1 == 0)
368 /* src1 or src2 is zero. */
369 dest->nlimbs = 0;
370 dest->limbs = (mp_limb_t *) malloc (1);
372 else
374 /* Here 1 <= len1 <= len2. */
375 size_t dlen;
376 mp_limb_t *dp;
377 size_t k, i, j;
379 dlen = len1 + len2;
380 dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
381 if (dp == NULL)
382 return NULL;
383 for (k = len2; k > 0; )
384 dp[--k] = 0;
385 for (i = 0; i < len1; i++)
387 mp_limb_t digit1 = p1[i];
388 mp_twolimb_t carry = 0;
389 for (j = 0; j < len2; j++)
391 mp_limb_t digit2 = p2[j];
392 carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
393 carry += dp[i + j];
394 dp[i + j] = (mp_limb_t) carry;
395 carry = carry >> GMP_LIMB_BITS;
397 dp[i + len2] = (mp_limb_t) carry;
399 /* Normalise. */
400 while (dlen > 0 && dp[dlen - 1] == 0)
401 dlen--;
402 dest->nlimbs = dlen;
403 dest->limbs = dp;
405 return dest->limbs;
408 /* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
409 a is written as a = q * b + r with 0 <= r < b. q is the quotient, r
410 the remainder.
411 Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
412 q is incremented.
413 Return the allocated memory in case of success, NULL in case of memory
414 allocation failure. */
415 static void *
416 divide (mpn_t a, mpn_t b, mpn_t *q)
418 /* Algorithm:
419 First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
420 with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
421 If m<n, then q:=0 and r:=a.
422 If m>=n=1, perform a single-precision division:
423 r:=0, j:=m,
424 while j>0 do
425 {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
426 = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
427 j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
428 Normalise [q[m-1],...,q[0]], yields q.
429 If m>=n>1, perform a multiple-precision division:
430 We have a/b < beta^(m-n+1).
431 s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
432 Shift a and b left by s bits, copying them. r:=a.
433 r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
434 For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
435 Compute q* :
436 q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
437 In case of overflow (q* >= beta) set q* := beta-1.
438 Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
439 and c3 := b[n-2] * q*.
440 {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
441 occurred. Furthermore 0 <= c3 < beta^2.
442 If there was overflow and
443 r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
444 the next test can be skipped.}
445 While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
446 Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
447 If q* > 0:
448 Put r := r - b * q* * beta^j. In detail:
449 [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
450 hence: u:=0, for i:=0 to n-1 do
451 u := u + q* * b[i],
452 r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
453 u:=u div beta (+ 1, if carry in subtraction)
454 r[n+j]:=r[n+j]-u.
455 {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
456 < q* + 1 <= beta,
457 the carry u does not overflow.}
458 If a negative carry occurs, put q* := q* - 1
459 and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
460 Set q[j] := q*.
461 Normalise [q[m-n],..,q[0]]; this yields the quotient q.
462 Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
463 rest r.
464 The room for q[j] can be allocated at the memory location of r[n+j].
465 Finally, round-to-even:
466 Shift r left by 1 bit.
467 If r > b or if r = b and q[0] is odd, q := q+1.
469 const mp_limb_t *a_ptr = a.limbs;
470 size_t a_len = a.nlimbs;
471 const mp_limb_t *b_ptr = b.limbs;
472 size_t b_len = b.nlimbs;
473 mp_limb_t *roomptr;
474 mp_limb_t *tmp_roomptr = NULL;
475 mp_limb_t *q_ptr;
476 size_t q_len;
477 mp_limb_t *r_ptr;
478 size_t r_len;
480 /* Allocate room for a_len+2 digits.
481 (Need a_len+1 digits for the real division and 1 more digit for the
482 final rounding of q.) */
483 roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
484 if (roomptr == NULL)
485 return NULL;
487 /* Normalise a. */
488 while (a_len > 0 && a_ptr[a_len - 1] == 0)
489 a_len--;
491 /* Normalise b. */
492 for (;;)
494 if (b_len == 0)
495 /* Division by zero. */
496 abort ();
497 if (b_ptr[b_len - 1] == 0)
498 b_len--;
499 else
500 break;
503 /* Here m = a_len >= 0 and n = b_len > 0. */
505 if (a_len < b_len)
507 /* m<n: trivial case. q=0, r := copy of a. */
508 r_ptr = roomptr;
509 r_len = a_len;
510 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
511 q_ptr = roomptr + a_len;
512 q_len = 0;
514 else if (b_len == 1)
516 /* n=1: single precision division.
517 beta^(m-1) <= a < beta^m ==> beta^(m-2) <= a/b < beta^m */
518 r_ptr = roomptr;
519 q_ptr = roomptr + 1;
521 mp_limb_t den = b_ptr[0];
522 mp_limb_t remainder = 0;
523 const mp_limb_t *sourceptr = a_ptr + a_len;
524 mp_limb_t *destptr = q_ptr + a_len;
525 size_t count;
526 for (count = a_len; count > 0; count--)
528 mp_twolimb_t num =
529 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
530 *--destptr = num / den;
531 remainder = num % den;
533 /* Normalise and store r. */
534 if (remainder > 0)
536 r_ptr[0] = remainder;
537 r_len = 1;
539 else
540 r_len = 0;
541 /* Normalise q. */
542 q_len = a_len;
543 if (q_ptr[q_len - 1] == 0)
544 q_len--;
547 else
549 /* n>1: multiple precision division.
550 beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n ==>
551 beta^(m-n-1) <= a/b < beta^(m-n+1). */
552 /* Determine s. */
553 size_t s;
555 mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
556 s = 31;
557 if (msd >= 0x10000)
559 msd = msd >> 16;
560 s -= 16;
562 if (msd >= 0x100)
564 msd = msd >> 8;
565 s -= 8;
567 if (msd >= 0x10)
569 msd = msd >> 4;
570 s -= 4;
572 if (msd >= 0x4)
574 msd = msd >> 2;
575 s -= 2;
577 if (msd >= 0x2)
579 msd = msd >> 1;
580 s -= 1;
583 /* 0 <= s < GMP_LIMB_BITS.
584 Copy b, shifting it left by s bits. */
585 if (s > 0)
587 tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
588 if (tmp_roomptr == NULL)
590 free (roomptr);
591 return NULL;
594 const mp_limb_t *sourceptr = b_ptr;
595 mp_limb_t *destptr = tmp_roomptr;
596 mp_twolimb_t accu = 0;
597 size_t count;
598 for (count = b_len; count > 0; count--)
600 accu += (mp_twolimb_t) *sourceptr++ << s;
601 *destptr++ = (mp_limb_t) accu;
602 accu = accu >> GMP_LIMB_BITS;
604 /* accu must be zero, since that was how s was determined. */
605 if (accu != 0)
606 abort ();
608 b_ptr = tmp_roomptr;
610 /* Copy a, shifting it left by s bits, yields r.
611 Memory layout:
612 At the beginning: r = roomptr[0..a_len],
613 at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len] */
614 r_ptr = roomptr;
615 if (s == 0)
617 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
618 r_ptr[a_len] = 0;
620 else
622 const mp_limb_t *sourceptr = a_ptr;
623 mp_limb_t *destptr = r_ptr;
624 mp_twolimb_t accu = 0;
625 size_t count;
626 for (count = a_len; count > 0; count--)
628 accu += (mp_twolimb_t) *sourceptr++ << s;
629 *destptr++ = (mp_limb_t) accu;
630 accu = accu >> GMP_LIMB_BITS;
632 *destptr++ = (mp_limb_t) accu;
634 q_ptr = roomptr + b_len;
635 q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
637 size_t j = a_len - b_len; /* m-n */
638 mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
639 mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
640 mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
641 ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
642 /* Division loop, traversed m-n+1 times.
643 j counts down, b is unchanged, beta/2 <= b[n-1] < beta. */
644 for (;;)
646 mp_limb_t q_star;
647 mp_limb_t c1;
648 if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
650 /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow. */
651 mp_twolimb_t num =
652 ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
653 | r_ptr[j + b_len - 1];
654 q_star = num / b_msd;
655 c1 = num % b_msd;
657 else
659 /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1]. */
660 q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
661 /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
662 <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
663 <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
664 {<= beta !}.
665 If yes, jump directly to the subtraction loop.
666 (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
667 <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
668 if (r_ptr[j + b_len] > b_msd
669 || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
670 /* r[j+n] >= b[n-1]+1 or
671 r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
672 carry. */
673 goto subtract;
675 /* q_star = q*,
676 c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta). */
678 mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
679 ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
680 mp_twolimb_t c3 = /* b[n-2] * q* */
681 (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
682 /* While c2 < c3, increase c2 and decrease c3.
683 Consider c3-c2. While it is > 0, decrease it by
684 b[n-1]*beta+b[n-2]. Because of b[n-1]*beta+b[n-2] >= beta^2/2
685 this can happen only twice. */
686 if (c3 > c2)
688 q_star = q_star - 1; /* q* := q* - 1 */
689 if (c3 - c2 > b_msdd)
690 q_star = q_star - 1; /* q* := q* - 1 */
693 if (q_star > 0)
694 subtract:
696 /* Subtract r := r - b * q* * beta^j. */
697 mp_limb_t cr;
699 const mp_limb_t *sourceptr = b_ptr;
700 mp_limb_t *destptr = r_ptr + j;
701 mp_twolimb_t carry = 0;
702 size_t count;
703 for (count = b_len; count > 0; count--)
705 /* Here 0 <= carry <= q*. */
706 carry =
707 carry
708 + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
709 + (mp_limb_t) ~(*destptr);
710 /* Here 0 <= carry <= beta*q* + beta-1. */
711 *destptr++ = ~(mp_limb_t) carry;
712 carry = carry >> GMP_LIMB_BITS; /* <= q* */
714 cr = (mp_limb_t) carry;
716 /* Subtract cr from r_ptr[j + b_len], then forget about
717 r_ptr[j + b_len]. */
718 if (cr > r_ptr[j + b_len])
720 /* Subtraction gave a carry. */
721 q_star = q_star - 1; /* q* := q* - 1 */
722 /* Add b back. */
724 const mp_limb_t *sourceptr = b_ptr;
725 mp_limb_t *destptr = r_ptr + j;
726 mp_limb_t carry = 0;
727 size_t count;
728 for (count = b_len; count > 0; count--)
730 mp_limb_t source1 = *sourceptr++;
731 mp_limb_t source2 = *destptr;
732 *destptr++ = source1 + source2 + carry;
733 carry =
734 (carry
735 ? source1 >= (mp_limb_t) ~source2
736 : source1 > (mp_limb_t) ~source2);
739 /* Forget about the carry and about r[j+n]. */
742 /* q* is determined. Store it as q[j]. */
743 q_ptr[j] = q_star;
744 if (j == 0)
745 break;
746 j--;
749 r_len = b_len;
750 /* Normalise q. */
751 if (q_ptr[q_len - 1] == 0)
752 q_len--;
753 # if 0 /* Not needed here, since we need r only to compare it with b/2, and
754 b is shifted left by s bits. */
755 /* Shift r right by s bits. */
756 if (s > 0)
758 mp_limb_t ptr = r_ptr + r_len;
759 mp_twolimb_t accu = 0;
760 size_t count;
761 for (count = r_len; count > 0; count--)
763 accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
764 accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
765 *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
768 # endif
769 /* Normalise r. */
770 while (r_len > 0 && r_ptr[r_len - 1] == 0)
771 r_len--;
773 /* Compare r << 1 with b. */
774 if (r_len > b_len)
775 goto increment_q;
777 size_t i;
778 for (i = b_len;;)
780 mp_limb_t r_i =
781 (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
782 | (i < r_len ? r_ptr[i] << 1 : 0);
783 mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
784 if (r_i > b_i)
785 goto increment_q;
786 if (r_i < b_i)
787 goto keep_q;
788 if (i == 0)
789 break;
790 i--;
793 if (q_len > 0 && ((q_ptr[0] & 1) != 0))
794 /* q is odd. */
795 increment_q:
797 size_t i;
798 for (i = 0; i < q_len; i++)
799 if (++(q_ptr[i]) != 0)
800 goto keep_q;
801 q_ptr[q_len++] = 1;
803 keep_q:
804 if (tmp_roomptr != NULL)
805 free (tmp_roomptr);
806 q->limbs = q_ptr;
807 q->nlimbs = q_len;
808 return roomptr;
811 /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
812 representation.
813 Destroys the contents of a.
814 Return the allocated memory - containing the decimal digits in low-to-high
815 order, terminated with a NUL character - in case of success, NULL in case
816 of memory allocation failure. */
817 static char *
818 convert_to_decimal (mpn_t a, size_t extra_zeroes)
820 mp_limb_t *a_ptr = a.limbs;
821 size_t a_len = a.nlimbs;
822 /* 0.03345 is slightly larger than log(2)/(9*log(10)). */
823 size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
824 char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes));
825 if (c_ptr != NULL)
827 char *d_ptr = c_ptr;
828 for (; extra_zeroes > 0; extra_zeroes--)
829 *d_ptr++ = '0';
830 while (a_len > 0)
832 /* Divide a by 10^9, in-place. */
833 mp_limb_t remainder = 0;
834 mp_limb_t *ptr = a_ptr + a_len;
835 size_t count;
836 for (count = a_len; count > 0; count--)
838 mp_twolimb_t num =
839 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
840 *ptr = num / 1000000000;
841 remainder = num % 1000000000;
843 /* Store the remainder as 9 decimal digits. */
844 for (count = 9; count > 0; count--)
846 *d_ptr++ = '0' + (remainder % 10);
847 remainder = remainder / 10;
849 /* Normalize a. */
850 if (a_ptr[a_len - 1] == 0)
851 a_len--;
853 /* Remove leading zeroes. */
854 while (d_ptr > c_ptr && d_ptr[-1] == '0')
855 d_ptr--;
856 /* But keep at least one zero. */
857 if (d_ptr == c_ptr)
858 *d_ptr++ = '0';
859 /* Terminate the string. */
860 *d_ptr = '\0';
862 return c_ptr;
865 # if NEED_PRINTF_LONG_DOUBLE
867 /* Assuming x is finite and >= 0:
868 write x as x = 2^e * m, where m is a bignum.
869 Return the allocated memory in case of success, NULL in case of memory
870 allocation failure. */
871 static void *
872 decode_long_double (long double x, int *ep, mpn_t *mp)
874 mpn_t m;
875 int exp;
876 long double y;
877 size_t i;
879 /* Allocate memory for result. */
880 m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
881 m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
882 if (m.limbs == NULL)
883 return NULL;
884 /* Split into exponential part and mantissa. */
885 y = frexpl (x, &exp);
886 if (!(y >= 0.0L && y < 1.0L))
887 abort ();
888 /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * LDBL_MANT_BIT), and the
889 latter is an integer. */
890 /* Convert the mantissa (y * LDBL_MANT_BIT) to a sequence of limbs.
891 I'm not sure whether it's safe to cast a 'long double' value between
892 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
893 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
894 doesn't matter). */
895 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
896 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
898 mp_limb_t hi, lo;
899 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
900 hi = (int) y;
901 y -= hi;
902 if (!(y >= 0.0L && y < 1.0L))
903 abort ();
904 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
905 lo = (int) y;
906 y -= lo;
907 if (!(y >= 0.0L && y < 1.0L))
908 abort ();
909 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
911 # else
913 mp_limb_t d;
914 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
915 d = (int) y;
916 y -= d;
917 if (!(y >= 0.0L && y < 1.0L))
918 abort ();
919 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
921 # endif
922 # endif
923 for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
925 mp_limb_t hi, lo;
926 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
927 hi = (int) y;
928 y -= hi;
929 if (!(y >= 0.0L && y < 1.0L))
930 abort ();
931 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
932 lo = (int) y;
933 y -= lo;
934 if (!(y >= 0.0L && y < 1.0L))
935 abort ();
936 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
938 #if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
939 precision. */
940 if (!(y == 0.0L))
941 abort ();
942 #endif
943 /* Normalise. */
944 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
945 m.nlimbs--;
946 *mp = m;
947 *ep = exp - LDBL_MANT_BIT;
948 return m.limbs;
951 # endif
953 # if NEED_PRINTF_DOUBLE
955 /* Assuming x is finite and >= 0:
956 write x as x = 2^e * m, where m is a bignum.
957 Return the allocated memory in case of success, NULL in case of memory
958 allocation failure. */
959 static void *
960 decode_double (double x, int *ep, mpn_t *mp)
962 mpn_t m;
963 int exp;
964 double y;
965 size_t i;
967 /* Allocate memory for result. */
968 m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
969 m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
970 if (m.limbs == NULL)
971 return NULL;
972 /* Split into exponential part and mantissa. */
973 y = frexp (x, &exp);
974 if (!(y >= 0.0 && y < 1.0))
975 abort ();
976 /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * DBL_MANT_BIT), and the
977 latter is an integer. */
978 /* Convert the mantissa (y * DBL_MANT_BIT) to a sequence of limbs.
979 I'm not sure whether it's safe to cast a 'double' value between
980 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
981 'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
982 doesn't matter). */
983 # if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
984 # if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
986 mp_limb_t hi, lo;
987 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
988 hi = (int) y;
989 y -= hi;
990 if (!(y >= 0.0 && y < 1.0))
991 abort ();
992 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
993 lo = (int) y;
994 y -= lo;
995 if (!(y >= 0.0 && y < 1.0))
996 abort ();
997 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
999 # else
1001 mp_limb_t d;
1002 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
1003 d = (int) y;
1004 y -= d;
1005 if (!(y >= 0.0 && y < 1.0))
1006 abort ();
1007 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
1009 # endif
1010 # endif
1011 for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1013 mp_limb_t hi, lo;
1014 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1015 hi = (int) y;
1016 y -= hi;
1017 if (!(y >= 0.0 && y < 1.0))
1018 abort ();
1019 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1020 lo = (int) y;
1021 y -= lo;
1022 if (!(y >= 0.0 && y < 1.0))
1023 abort ();
1024 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1026 if (!(y == 0.0))
1027 abort ();
1028 /* Normalise. */
1029 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
1030 m.nlimbs--;
1031 *mp = m;
1032 *ep = exp - DBL_MANT_BIT;
1033 return m.limbs;
1036 # endif
1038 /* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
1039 Returns the decimal representation of round (x * 10^n).
1040 Return the allocated memory - containing the decimal digits in low-to-high
1041 order, terminated with a NUL character - in case of success, NULL in case
1042 of memory allocation failure. */
1043 static char *
1044 scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
1046 int s;
1047 size_t extra_zeroes;
1048 unsigned int abs_n;
1049 unsigned int abs_s;
1050 mp_limb_t *pow5_ptr;
1051 size_t pow5_len;
1052 unsigned int s_limbs;
1053 unsigned int s_bits;
1054 mpn_t pow5;
1055 mpn_t z;
1056 void *z_memory;
1057 char *digits;
1059 if (memory == NULL)
1060 return NULL;
1061 /* x = 2^e * m, hence
1062 y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
1063 = round (2^s * 5^n * m). */
1064 s = e + n;
1065 extra_zeroes = 0;
1066 /* Factor out a common power of 10 if possible. */
1067 if (s > 0 && n > 0)
1069 extra_zeroes = (s < n ? s : n);
1070 s -= extra_zeroes;
1071 n -= extra_zeroes;
1073 /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
1074 Before converting to decimal, we need to compute
1075 z = round (2^s * 5^n * m). */
1076 /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
1077 sign. 2.322 is slightly larger than log(5)/log(2). */
1078 abs_n = (n >= 0 ? n : -n);
1079 abs_s = (s >= 0 ? s : -s);
1080 pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
1081 + abs_s / GMP_LIMB_BITS + 1)
1082 * sizeof (mp_limb_t));
1083 if (pow5_ptr == NULL)
1085 free (memory);
1086 return NULL;
1088 /* Initialize with 1. */
1089 pow5_ptr[0] = 1;
1090 pow5_len = 1;
1091 /* Multiply with 5^|n|. */
1092 if (abs_n > 0)
1094 static mp_limb_t const small_pow5[13 + 1] =
1096 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
1097 48828125, 244140625, 1220703125
1099 unsigned int n13;
1100 for (n13 = 0; n13 <= abs_n; n13 += 13)
1102 mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
1103 size_t j;
1104 mp_twolimb_t carry = 0;
1105 for (j = 0; j < pow5_len; j++)
1107 mp_limb_t digit2 = pow5_ptr[j];
1108 carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
1109 pow5_ptr[j] = (mp_limb_t) carry;
1110 carry = carry >> GMP_LIMB_BITS;
1112 if (carry > 0)
1113 pow5_ptr[pow5_len++] = (mp_limb_t) carry;
1116 s_limbs = abs_s / GMP_LIMB_BITS;
1117 s_bits = abs_s % GMP_LIMB_BITS;
1118 if (n >= 0 ? s >= 0 : s <= 0)
1120 /* Multiply with 2^|s|. */
1121 if (s_bits > 0)
1123 mp_limb_t *ptr = pow5_ptr;
1124 mp_twolimb_t accu = 0;
1125 size_t count;
1126 for (count = pow5_len; count > 0; count--)
1128 accu += (mp_twolimb_t) *ptr << s_bits;
1129 *ptr++ = (mp_limb_t) accu;
1130 accu = accu >> GMP_LIMB_BITS;
1132 if (accu > 0)
1134 *ptr = (mp_limb_t) accu;
1135 pow5_len++;
1138 if (s_limbs > 0)
1140 size_t count;
1141 for (count = pow5_len; count > 0;)
1143 count--;
1144 pow5_ptr[s_limbs + count] = pow5_ptr[count];
1146 for (count = s_limbs; count > 0;)
1148 count--;
1149 pow5_ptr[count] = 0;
1151 pow5_len += s_limbs;
1153 pow5.limbs = pow5_ptr;
1154 pow5.nlimbs = pow5_len;
1155 if (n >= 0)
1157 /* Multiply m with pow5. No division needed. */
1158 z_memory = multiply (m, pow5, &z);
1160 else
1162 /* Divide m by pow5 and round. */
1163 z_memory = divide (m, pow5, &z);
1166 else
1168 pow5.limbs = pow5_ptr;
1169 pow5.nlimbs = pow5_len;
1170 if (n >= 0)
1172 /* n >= 0, s < 0.
1173 Multiply m with pow5, then divide by 2^|s|. */
1174 mpn_t numerator;
1175 mpn_t denominator;
1176 void *tmp_memory;
1177 tmp_memory = multiply (m, pow5, &numerator);
1178 if (tmp_memory == NULL)
1180 free (pow5_ptr);
1181 free (memory);
1182 return NULL;
1184 /* Construct 2^|s|. */
1186 mp_limb_t *ptr = pow5_ptr + pow5_len;
1187 size_t i;
1188 for (i = 0; i < s_limbs; i++)
1189 ptr[i] = 0;
1190 ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
1191 denominator.limbs = ptr;
1192 denominator.nlimbs = s_limbs + 1;
1194 z_memory = divide (numerator, denominator, &z);
1195 free (tmp_memory);
1197 else
1199 /* n < 0, s > 0.
1200 Multiply m with 2^s, then divide by pow5. */
1201 mpn_t numerator;
1202 mp_limb_t *num_ptr;
1203 num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
1204 * sizeof (mp_limb_t));
1205 if (num_ptr == NULL)
1207 free (pow5_ptr);
1208 free (memory);
1209 return NULL;
1212 mp_limb_t *destptr = num_ptr;
1214 size_t i;
1215 for (i = 0; i < s_limbs; i++)
1216 *destptr++ = 0;
1218 if (s_bits > 0)
1220 const mp_limb_t *sourceptr = m.limbs;
1221 mp_twolimb_t accu = 0;
1222 size_t count;
1223 for (count = m.nlimbs; count > 0; count--)
1225 accu += (mp_twolimb_t) *sourceptr++ << s_bits;
1226 *destptr++ = (mp_limb_t) accu;
1227 accu = accu >> GMP_LIMB_BITS;
1229 if (accu > 0)
1230 *destptr++ = (mp_limb_t) accu;
1232 else
1234 const mp_limb_t *sourceptr = m.limbs;
1235 size_t count;
1236 for (count = m.nlimbs; count > 0; count--)
1237 *destptr++ = *sourceptr++;
1239 numerator.limbs = num_ptr;
1240 numerator.nlimbs = destptr - num_ptr;
1242 z_memory = divide (numerator, pow5, &z);
1243 free (num_ptr);
1246 free (pow5_ptr);
1247 free (memory);
1249 /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */
1251 if (z_memory == NULL)
1252 return NULL;
1253 digits = convert_to_decimal (z, extra_zeroes);
1254 free (z_memory);
1255 return digits;
1258 # if NEED_PRINTF_LONG_DOUBLE
1260 /* Assuming x is finite and >= 0, and n is an integer:
1261 Returns the decimal representation of round (x * 10^n).
1262 Return the allocated memory - containing the decimal digits in low-to-high
1263 order, terminated with a NUL character - in case of success, NULL in case
1264 of memory allocation failure. */
1265 static char *
1266 scale10_round_decimal_long_double (long double x, int n)
1268 int e IF_LINT(= 0);
1269 mpn_t m;
1270 void *memory = decode_long_double (x, &e, &m);
1271 return scale10_round_decimal_decoded (e, m, memory, n);
1274 # endif
1276 # if NEED_PRINTF_DOUBLE
1278 /* Assuming x is finite and >= 0, and n is an integer:
1279 Returns the decimal representation of round (x * 10^n).
1280 Return the allocated memory - containing the decimal digits in low-to-high
1281 order, terminated with a NUL character - in case of success, NULL in case
1282 of memory allocation failure. */
1283 static char *
1284 scale10_round_decimal_double (double x, int n)
1286 int e IF_LINT(= 0);
1287 mpn_t m;
1288 void *memory = decode_double (x, &e, &m);
1289 return scale10_round_decimal_decoded (e, m, memory, n);
1292 # endif
1294 # if NEED_PRINTF_LONG_DOUBLE
1296 /* Assuming x is finite and > 0:
1297 Return an approximation for n with 10^n <= x < 10^(n+1).
1298 The approximation is usually the right n, but may be off by 1 sometimes. */
1299 static int
1300 floorlog10l (long double x)
1302 int exp;
1303 long double y;
1304 double z;
1305 double l;
1307 /* Split into exponential part and mantissa. */
1308 y = frexpl (x, &exp);
1309 if (!(y >= 0.0L && y < 1.0L))
1310 abort ();
1311 if (y == 0.0L)
1312 return INT_MIN;
1313 if (y < 0.5L)
1315 while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1317 y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1318 exp -= GMP_LIMB_BITS;
1320 if (y < (1.0L / (1 << 16)))
1322 y *= 1.0L * (1 << 16);
1323 exp -= 16;
1325 if (y < (1.0L / (1 << 8)))
1327 y *= 1.0L * (1 << 8);
1328 exp -= 8;
1330 if (y < (1.0L / (1 << 4)))
1332 y *= 1.0L * (1 << 4);
1333 exp -= 4;
1335 if (y < (1.0L / (1 << 2)))
1337 y *= 1.0L * (1 << 2);
1338 exp -= 2;
1340 if (y < (1.0L / (1 << 1)))
1342 y *= 1.0L * (1 << 1);
1343 exp -= 1;
1346 if (!(y >= 0.5L && y < 1.0L))
1347 abort ();
1348 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1349 l = exp;
1350 z = y;
1351 if (z < 0.70710678118654752444)
1353 z *= 1.4142135623730950488;
1354 l -= 0.5;
1356 if (z < 0.8408964152537145431)
1358 z *= 1.1892071150027210667;
1359 l -= 0.25;
1361 if (z < 0.91700404320467123175)
1363 z *= 1.0905077326652576592;
1364 l -= 0.125;
1366 if (z < 0.9576032806985736469)
1368 z *= 1.0442737824274138403;
1369 l -= 0.0625;
1371 /* Now 0.95 <= z <= 1.01. */
1372 z = 1 - z;
1373 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1374 Four terms are enough to get an approximation with error < 10^-7. */
1375 l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1376 /* Finally multiply with log(2)/log(10), yields an approximation for
1377 log10(x). */
1378 l *= 0.30102999566398119523;
1379 /* Round down to the next integer. */
1380 return (int) l + (l < 0 ? -1 : 0);
1383 # endif
1385 # if NEED_PRINTF_DOUBLE
1387 /* Assuming x is finite and > 0:
1388 Return an approximation for n with 10^n <= x < 10^(n+1).
1389 The approximation is usually the right n, but may be off by 1 sometimes. */
1390 static int
1391 floorlog10 (double x)
1393 int exp;
1394 double y;
1395 double z;
1396 double l;
1398 /* Split into exponential part and mantissa. */
1399 y = frexp (x, &exp);
1400 if (!(y >= 0.0 && y < 1.0))
1401 abort ();
1402 if (y == 0.0)
1403 return INT_MIN;
1404 if (y < 0.5)
1406 while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1408 y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1409 exp -= GMP_LIMB_BITS;
1411 if (y < (1.0 / (1 << 16)))
1413 y *= 1.0 * (1 << 16);
1414 exp -= 16;
1416 if (y < (1.0 / (1 << 8)))
1418 y *= 1.0 * (1 << 8);
1419 exp -= 8;
1421 if (y < (1.0 / (1 << 4)))
1423 y *= 1.0 * (1 << 4);
1424 exp -= 4;
1426 if (y < (1.0 / (1 << 2)))
1428 y *= 1.0 * (1 << 2);
1429 exp -= 2;
1431 if (y < (1.0 / (1 << 1)))
1433 y *= 1.0 * (1 << 1);
1434 exp -= 1;
1437 if (!(y >= 0.5 && y < 1.0))
1438 abort ();
1439 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1440 l = exp;
1441 z = y;
1442 if (z < 0.70710678118654752444)
1444 z *= 1.4142135623730950488;
1445 l -= 0.5;
1447 if (z < 0.8408964152537145431)
1449 z *= 1.1892071150027210667;
1450 l -= 0.25;
1452 if (z < 0.91700404320467123175)
1454 z *= 1.0905077326652576592;
1455 l -= 0.125;
1457 if (z < 0.9576032806985736469)
1459 z *= 1.0442737824274138403;
1460 l -= 0.0625;
1462 /* Now 0.95 <= z <= 1.01. */
1463 z = 1 - z;
1464 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1465 Four terms are enough to get an approximation with error < 10^-7. */
1466 l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1467 /* Finally multiply with log(2)/log(10), yields an approximation for
1468 log10(x). */
1469 l *= 0.30102999566398119523;
1470 /* Round down to the next integer. */
1471 return (int) l + (l < 0 ? -1 : 0);
1474 # endif
1476 /* Tests whether a string of digits consists of exactly PRECISION zeroes and
1477 a single '1' digit. */
1478 static int
1479 is_borderline (const char *digits, size_t precision)
1481 for (; precision > 0; precision--, digits++)
1482 if (*digits != '0')
1483 return 0;
1484 if (*digits != '1')
1485 return 0;
1486 digits++;
1487 return *digits == '\0';
1490 #endif
1492 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99
1494 /* Use a different function name, to make it possible that the 'wchar_t'
1495 parametrization and the 'char' parametrization get compiled in the same
1496 translation unit. */
1497 # if WIDE_CHAR_VERSION
1498 # define MAX_ROOM_NEEDED wmax_room_needed
1499 # else
1500 # define MAX_ROOM_NEEDED max_room_needed
1501 # endif
1503 /* Returns the number of TCHAR_T units needed as temporary space for the result
1504 of sprintf or SNPRINTF of a single conversion directive. */
1505 static inline size_t
1506 MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
1507 arg_type type, int flags, size_t width, int has_precision,
1508 size_t precision, int pad_ourselves)
1510 size_t tmp_length;
1512 switch (conversion)
1514 case 'd': case 'i': case 'u':
1515 # if HAVE_LONG_LONG_INT
1516 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1517 tmp_length =
1518 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1519 * 0.30103 /* binary -> decimal */
1521 + 1; /* turn floor into ceil */
1522 else
1523 # endif
1524 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1525 tmp_length =
1526 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1527 * 0.30103 /* binary -> decimal */
1529 + 1; /* turn floor into ceil */
1530 else
1531 tmp_length =
1532 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1533 * 0.30103 /* binary -> decimal */
1535 + 1; /* turn floor into ceil */
1536 if (tmp_length < precision)
1537 tmp_length = precision;
1538 /* Multiply by 2, as an estimate for FLAG_GROUP. */
1539 tmp_length = xsum (tmp_length, tmp_length);
1540 /* Add 1, to account for a leading sign. */
1541 tmp_length = xsum (tmp_length, 1);
1542 break;
1544 case 'o':
1545 # if HAVE_LONG_LONG_INT
1546 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1547 tmp_length =
1548 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1549 * 0.333334 /* binary -> octal */
1551 + 1; /* turn floor into ceil */
1552 else
1553 # endif
1554 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1555 tmp_length =
1556 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1557 * 0.333334 /* binary -> octal */
1559 + 1; /* turn floor into ceil */
1560 else
1561 tmp_length =
1562 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1563 * 0.333334 /* binary -> octal */
1565 + 1; /* turn floor into ceil */
1566 if (tmp_length < precision)
1567 tmp_length = precision;
1568 /* Add 1, to account for a leading sign. */
1569 tmp_length = xsum (tmp_length, 1);
1570 break;
1572 case 'x': case 'X':
1573 # if HAVE_LONG_LONG_INT
1574 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1575 tmp_length =
1576 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1577 * 0.25 /* binary -> hexadecimal */
1579 + 1; /* turn floor into ceil */
1580 else
1581 # endif
1582 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1583 tmp_length =
1584 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1585 * 0.25 /* binary -> hexadecimal */
1587 + 1; /* turn floor into ceil */
1588 else
1589 tmp_length =
1590 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1591 * 0.25 /* binary -> hexadecimal */
1593 + 1; /* turn floor into ceil */
1594 if (tmp_length < precision)
1595 tmp_length = precision;
1596 /* Add 2, to account for a leading sign or alternate form. */
1597 tmp_length = xsum (tmp_length, 2);
1598 break;
1600 case 'f': case 'F':
1601 if (type == TYPE_LONGDOUBLE)
1602 tmp_length =
1603 (unsigned int) (LDBL_MAX_EXP
1604 * 0.30103 /* binary -> decimal */
1605 * 2 /* estimate for FLAG_GROUP */
1607 + 1 /* turn floor into ceil */
1608 + 10; /* sign, decimal point etc. */
1609 else
1610 tmp_length =
1611 (unsigned int) (DBL_MAX_EXP
1612 * 0.30103 /* binary -> decimal */
1613 * 2 /* estimate for FLAG_GROUP */
1615 + 1 /* turn floor into ceil */
1616 + 10; /* sign, decimal point etc. */
1617 tmp_length = xsum (tmp_length, precision);
1618 break;
1620 case 'e': case 'E': case 'g': case 'G':
1621 tmp_length =
1622 12; /* sign, decimal point, exponent etc. */
1623 tmp_length = xsum (tmp_length, precision);
1624 break;
1626 case 'a': case 'A':
1627 if (type == TYPE_LONGDOUBLE)
1628 tmp_length =
1629 (unsigned int) (LDBL_DIG
1630 * 0.831 /* decimal -> hexadecimal */
1632 + 1; /* turn floor into ceil */
1633 else
1634 tmp_length =
1635 (unsigned int) (DBL_DIG
1636 * 0.831 /* decimal -> hexadecimal */
1638 + 1; /* turn floor into ceil */
1639 if (tmp_length < precision)
1640 tmp_length = precision;
1641 /* Account for sign, decimal point etc. */
1642 tmp_length = xsum (tmp_length, 12);
1643 break;
1645 case 'c':
1646 # if HAVE_WINT_T && !WIDE_CHAR_VERSION
1647 if (type == TYPE_WIDE_CHAR)
1648 tmp_length = MB_CUR_MAX;
1649 else
1650 # endif
1651 tmp_length = 1;
1652 break;
1654 case 's':
1655 # if HAVE_WCHAR_T
1656 if (type == TYPE_WIDE_STRING)
1658 # if WIDE_CHAR_VERSION
1659 /* ISO C says about %ls in fwprintf:
1660 "If the precision is not specified or is greater than the size
1661 of the array, the array shall contain a null wide character."
1662 So if there is a precision, we must not use wcslen. */
1663 const wchar_t *arg = ap->arg[arg_index].a.a_wide_string;
1665 if (has_precision)
1666 tmp_length = local_wcsnlen (arg, precision);
1667 else
1668 tmp_length = local_wcslen (arg);
1669 # else
1670 /* ISO C says about %ls in fprintf:
1671 "If a precision is specified, no more than that many bytes are
1672 written (including shift sequences, if any), and the array
1673 shall contain a null wide character if, to equal the multibyte
1674 character sequence length given by the precision, the function
1675 would need to access a wide character one past the end of the
1676 array."
1677 So if there is a precision, we must not use wcslen. */
1678 /* This case has already been handled separately in VASNPRINTF. */
1679 abort ();
1680 # endif
1682 else
1683 # endif
1685 # if WIDE_CHAR_VERSION
1686 /* ISO C says about %s in fwprintf:
1687 "If the precision is not specified or is greater than the size
1688 of the converted array, the converted array shall contain a
1689 null wide character."
1690 So if there is a precision, we must not use strlen. */
1691 /* This case has already been handled separately in VASNPRINTF. */
1692 abort ();
1693 # else
1694 /* ISO C says about %s in fprintf:
1695 "If the precision is not specified or greater than the size of
1696 the array, the array shall contain a null character."
1697 So if there is a precision, we must not use strlen. */
1698 const char *arg = ap->arg[arg_index].a.a_string;
1700 if (has_precision)
1701 tmp_length = local_strnlen (arg, precision);
1702 else
1703 tmp_length = strlen (arg);
1704 # endif
1706 break;
1708 case 'p':
1709 tmp_length =
1710 (unsigned int) (sizeof (void *) * CHAR_BIT
1711 * 0.25 /* binary -> hexadecimal */
1713 + 1 /* turn floor into ceil */
1714 + 2; /* account for leading 0x */
1715 break;
1717 default:
1718 abort ();
1721 if (!pad_ourselves)
1723 # if ENABLE_UNISTDIO
1724 /* Padding considers the number of characters, therefore the number of
1725 elements after padding may be
1726 > max (tmp_length, width)
1727 but is certainly
1728 <= tmp_length + width. */
1729 tmp_length = xsum (tmp_length, width);
1730 # else
1731 /* Padding considers the number of elements, says POSIX. */
1732 if (tmp_length < width)
1733 tmp_length = width;
1734 # endif
1737 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
1739 return tmp_length;
1742 #endif
1744 DCHAR_T *
1745 VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
1746 const FCHAR_T *format, va_list args)
1748 DIRECTIVES d;
1749 arguments a;
1751 if (PRINTF_PARSE (format, &d, &a) < 0)
1752 /* errno is already set. */
1753 return NULL;
1755 #define CLEANUP() \
1756 free (d.dir); \
1757 if (a.arg) \
1758 free (a.arg);
1760 if (PRINTF_FETCHARGS (args, &a) < 0)
1762 CLEANUP ();
1763 errno = EINVAL;
1764 return NULL;
1768 size_t buf_neededlength;
1769 TCHAR_T *buf;
1770 TCHAR_T *buf_malloced;
1771 const FCHAR_T *cp;
1772 size_t i;
1773 DIRECTIVE *dp;
1774 /* Output string accumulator. */
1775 DCHAR_T *result;
1776 size_t allocated;
1777 size_t length;
1779 /* Allocate a small buffer that will hold a directive passed to
1780 sprintf or snprintf. */
1781 buf_neededlength =
1782 xsum4 (7, d.max_width_length, d.max_precision_length, 6);
1783 #if HAVE_ALLOCA
1784 if (buf_neededlength < 4000 / sizeof (TCHAR_T))
1786 buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
1787 buf_malloced = NULL;
1789 else
1790 #endif
1792 size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
1793 if (size_overflow_p (buf_memsize))
1794 goto out_of_memory_1;
1795 buf = (TCHAR_T *) malloc (buf_memsize);
1796 if (buf == NULL)
1797 goto out_of_memory_1;
1798 buf_malloced = buf;
1801 if (resultbuf != NULL)
1803 result = resultbuf;
1804 allocated = *lengthp;
1806 else
1808 result = NULL;
1809 allocated = 0;
1811 length = 0;
1812 /* Invariants:
1813 result is either == resultbuf or == NULL or malloc-allocated.
1814 If length > 0, then result != NULL. */
1816 /* Ensures that allocated >= needed. Aborts through a jump to
1817 out_of_memory if needed is SIZE_MAX or otherwise too big. */
1818 #define ENSURE_ALLOCATION(needed) \
1819 if ((needed) > allocated) \
1821 size_t memory_size; \
1822 DCHAR_T *memory; \
1824 allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \
1825 if ((needed) > allocated) \
1826 allocated = (needed); \
1827 memory_size = xtimes (allocated, sizeof (DCHAR_T)); \
1828 if (size_overflow_p (memory_size)) \
1829 goto out_of_memory; \
1830 if (result == resultbuf || result == NULL) \
1831 memory = (DCHAR_T *) malloc (memory_size); \
1832 else \
1833 memory = (DCHAR_T *) realloc (result, memory_size); \
1834 if (memory == NULL) \
1835 goto out_of_memory; \
1836 if (result == resultbuf && length > 0) \
1837 DCHAR_CPY (memory, result, length); \
1838 result = memory; \
1841 for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
1843 if (cp != dp->dir_start)
1845 size_t n = dp->dir_start - cp;
1846 size_t augmented_length = xsum (length, n);
1848 ENSURE_ALLOCATION (augmented_length);
1849 /* This copies a piece of FCHAR_T[] into a DCHAR_T[]. Here we
1850 need that the format string contains only ASCII characters
1851 if FCHAR_T and DCHAR_T are not the same type. */
1852 if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
1854 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
1855 length = augmented_length;
1857 else
1860 result[length++] = (unsigned char) *cp++;
1861 while (--n > 0);
1864 if (i == d.count)
1865 break;
1867 /* Execute a single directive. */
1868 if (dp->conversion == '%')
1870 size_t augmented_length;
1872 if (!(dp->arg_index == ARG_NONE))
1873 abort ();
1874 augmented_length = xsum (length, 1);
1875 ENSURE_ALLOCATION (augmented_length);
1876 result[length] = '%';
1877 length = augmented_length;
1879 else
1881 if (!(dp->arg_index != ARG_NONE))
1882 abort ();
1884 if (dp->conversion == 'n')
1886 switch (a.arg[dp->arg_index].type)
1888 case TYPE_COUNT_SCHAR_POINTER:
1889 *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
1890 break;
1891 case TYPE_COUNT_SHORT_POINTER:
1892 *a.arg[dp->arg_index].a.a_count_short_pointer = length;
1893 break;
1894 case TYPE_COUNT_INT_POINTER:
1895 *a.arg[dp->arg_index].a.a_count_int_pointer = length;
1896 break;
1897 case TYPE_COUNT_LONGINT_POINTER:
1898 *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
1899 break;
1900 #if HAVE_LONG_LONG_INT
1901 case TYPE_COUNT_LONGLONGINT_POINTER:
1902 *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
1903 break;
1904 #endif
1905 default:
1906 abort ();
1909 #if ENABLE_UNISTDIO
1910 /* The unistdio extensions. */
1911 else if (dp->conversion == 'U')
1913 arg_type type = a.arg[dp->arg_index].type;
1914 int flags = dp->flags;
1915 int has_width;
1916 size_t width;
1917 int has_precision;
1918 size_t precision;
1920 has_width = 0;
1921 width = 0;
1922 if (dp->width_start != dp->width_end)
1924 if (dp->width_arg_index != ARG_NONE)
1926 int arg;
1928 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
1929 abort ();
1930 arg = a.arg[dp->width_arg_index].a.a_int;
1931 if (arg < 0)
1933 /* "A negative field width is taken as a '-' flag
1934 followed by a positive field width." */
1935 flags |= FLAG_LEFT;
1936 width = (unsigned int) (-arg);
1938 else
1939 width = arg;
1941 else
1943 const FCHAR_T *digitp = dp->width_start;
1946 width = xsum (xtimes (width, 10), *digitp++ - '0');
1947 while (digitp != dp->width_end);
1949 has_width = 1;
1952 has_precision = 0;
1953 precision = 0;
1954 if (dp->precision_start != dp->precision_end)
1956 if (dp->precision_arg_index != ARG_NONE)
1958 int arg;
1960 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1961 abort ();
1962 arg = a.arg[dp->precision_arg_index].a.a_int;
1963 /* "A negative precision is taken as if the precision
1964 were omitted." */
1965 if (arg >= 0)
1967 precision = arg;
1968 has_precision = 1;
1971 else
1973 const FCHAR_T *digitp = dp->precision_start + 1;
1975 precision = 0;
1976 while (digitp != dp->precision_end)
1977 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
1978 has_precision = 1;
1982 switch (type)
1984 case TYPE_U8_STRING:
1986 const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
1987 const uint8_t *arg_end;
1988 size_t characters;
1990 if (has_precision)
1992 /* Use only PRECISION characters, from the left. */
1993 arg_end = arg;
1994 characters = 0;
1995 for (; precision > 0; precision--)
1997 int count = u8_strmblen (arg_end);
1998 if (count == 0)
1999 break;
2000 if (count < 0)
2002 if (!(result == resultbuf || result == NULL))
2003 free (result);
2004 if (buf_malloced != NULL)
2005 free (buf_malloced);
2006 CLEANUP ();
2007 errno = EILSEQ;
2008 return NULL;
2010 arg_end += count;
2011 characters++;
2014 else if (has_width)
2016 /* Use the entire string, and count the number of
2017 characters. */
2018 arg_end = arg;
2019 characters = 0;
2020 for (;;)
2022 int count = u8_strmblen (arg_end);
2023 if (count == 0)
2024 break;
2025 if (count < 0)
2027 if (!(result == resultbuf || result == NULL))
2028 free (result);
2029 if (buf_malloced != NULL)
2030 free (buf_malloced);
2031 CLEANUP ();
2032 errno = EILSEQ;
2033 return NULL;
2035 arg_end += count;
2036 characters++;
2039 else
2041 /* Use the entire string. */
2042 arg_end = arg + u8_strlen (arg);
2043 /* The number of characters doesn't matter. */
2044 characters = 0;
2047 if (has_width && width > characters
2048 && !(dp->flags & FLAG_LEFT))
2050 size_t n = width - characters;
2051 ENSURE_ALLOCATION (xsum (length, n));
2052 DCHAR_SET (result + length, ' ', n);
2053 length += n;
2056 # if DCHAR_IS_UINT8_T
2058 size_t n = arg_end - arg;
2059 ENSURE_ALLOCATION (xsum (length, n));
2060 DCHAR_CPY (result + length, arg, n);
2061 length += n;
2063 # else
2064 { /* Convert. */
2065 DCHAR_T *converted = result + length;
2066 size_t converted_len = allocated - length;
2067 # if DCHAR_IS_TCHAR
2068 /* Convert from UTF-8 to locale encoding. */
2069 converted =
2070 u8_conv_to_encoding (locale_charset (),
2071 iconveh_question_mark,
2072 arg, arg_end - arg, NULL,
2073 converted, &converted_len);
2074 # else
2075 /* Convert from UTF-8 to UTF-16/UTF-32. */
2076 converted =
2077 U8_TO_DCHAR (arg, arg_end - arg,
2078 converted, &converted_len);
2079 # endif
2080 if (converted == NULL)
2082 int saved_errno = errno;
2083 if (!(result == resultbuf || result == NULL))
2084 free (result);
2085 if (buf_malloced != NULL)
2086 free (buf_malloced);
2087 CLEANUP ();
2088 errno = saved_errno;
2089 return NULL;
2091 if (converted != result + length)
2093 ENSURE_ALLOCATION (xsum (length, converted_len));
2094 DCHAR_CPY (result + length, converted, converted_len);
2095 free (converted);
2097 length += converted_len;
2099 # endif
2101 if (has_width && width > characters
2102 && (dp->flags & FLAG_LEFT))
2104 size_t n = width - characters;
2105 ENSURE_ALLOCATION (xsum (length, n));
2106 DCHAR_SET (result + length, ' ', n);
2107 length += n;
2110 break;
2112 case TYPE_U16_STRING:
2114 const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
2115 const uint16_t *arg_end;
2116 size_t characters;
2118 if (has_precision)
2120 /* Use only PRECISION characters, from the left. */
2121 arg_end = arg;
2122 characters = 0;
2123 for (; precision > 0; precision--)
2125 int count = u16_strmblen (arg_end);
2126 if (count == 0)
2127 break;
2128 if (count < 0)
2130 if (!(result == resultbuf || result == NULL))
2131 free (result);
2132 if (buf_malloced != NULL)
2133 free (buf_malloced);
2134 CLEANUP ();
2135 errno = EILSEQ;
2136 return NULL;
2138 arg_end += count;
2139 characters++;
2142 else if (has_width)
2144 /* Use the entire string, and count the number of
2145 characters. */
2146 arg_end = arg;
2147 characters = 0;
2148 for (;;)
2150 int count = u16_strmblen (arg_end);
2151 if (count == 0)
2152 break;
2153 if (count < 0)
2155 if (!(result == resultbuf || result == NULL))
2156 free (result);
2157 if (buf_malloced != NULL)
2158 free (buf_malloced);
2159 CLEANUP ();
2160 errno = EILSEQ;
2161 return NULL;
2163 arg_end += count;
2164 characters++;
2167 else
2169 /* Use the entire string. */
2170 arg_end = arg + u16_strlen (arg);
2171 /* The number of characters doesn't matter. */
2172 characters = 0;
2175 if (has_width && width > characters
2176 && !(dp->flags & FLAG_LEFT))
2178 size_t n = width - characters;
2179 ENSURE_ALLOCATION (xsum (length, n));
2180 DCHAR_SET (result + length, ' ', n);
2181 length += n;
2184 # if DCHAR_IS_UINT16_T
2186 size_t n = arg_end - arg;
2187 ENSURE_ALLOCATION (xsum (length, n));
2188 DCHAR_CPY (result + length, arg, n);
2189 length += n;
2191 # else
2192 { /* Convert. */
2193 DCHAR_T *converted = result + length;
2194 size_t converted_len = allocated - length;
2195 # if DCHAR_IS_TCHAR
2196 /* Convert from UTF-16 to locale encoding. */
2197 converted =
2198 u16_conv_to_encoding (locale_charset (),
2199 iconveh_question_mark,
2200 arg, arg_end - arg, NULL,
2201 converted, &converted_len);
2202 # else
2203 /* Convert from UTF-16 to UTF-8/UTF-32. */
2204 converted =
2205 U16_TO_DCHAR (arg, arg_end - arg,
2206 converted, &converted_len);
2207 # endif
2208 if (converted == NULL)
2210 int saved_errno = errno;
2211 if (!(result == resultbuf || result == NULL))
2212 free (result);
2213 if (buf_malloced != NULL)
2214 free (buf_malloced);
2215 CLEANUP ();
2216 errno = saved_errno;
2217 return NULL;
2219 if (converted != result + length)
2221 ENSURE_ALLOCATION (xsum (length, converted_len));
2222 DCHAR_CPY (result + length, converted, converted_len);
2223 free (converted);
2225 length += converted_len;
2227 # endif
2229 if (has_width && width > characters
2230 && (dp->flags & FLAG_LEFT))
2232 size_t n = width - characters;
2233 ENSURE_ALLOCATION (xsum (length, n));
2234 DCHAR_SET (result + length, ' ', n);
2235 length += n;
2238 break;
2240 case TYPE_U32_STRING:
2242 const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
2243 const uint32_t *arg_end;
2244 size_t characters;
2246 if (has_precision)
2248 /* Use only PRECISION characters, from the left. */
2249 arg_end = arg;
2250 characters = 0;
2251 for (; precision > 0; precision--)
2253 int count = u32_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 if (has_width)
2272 /* Use the entire string, and count the number of
2273 characters. */
2274 arg_end = arg;
2275 characters = 0;
2276 for (;;)
2278 int count = u32_strmblen (arg_end);
2279 if (count == 0)
2280 break;
2281 if (count < 0)
2283 if (!(result == resultbuf || result == NULL))
2284 free (result);
2285 if (buf_malloced != NULL)
2286 free (buf_malloced);
2287 CLEANUP ();
2288 errno = EILSEQ;
2289 return NULL;
2291 arg_end += count;
2292 characters++;
2295 else
2297 /* Use the entire string. */
2298 arg_end = arg + u32_strlen (arg);
2299 /* The number of characters doesn't matter. */
2300 characters = 0;
2303 if (has_width && width > characters
2304 && !(dp->flags & FLAG_LEFT))
2306 size_t n = width - characters;
2307 ENSURE_ALLOCATION (xsum (length, n));
2308 DCHAR_SET (result + length, ' ', n);
2309 length += n;
2312 # if DCHAR_IS_UINT32_T
2314 size_t n = arg_end - arg;
2315 ENSURE_ALLOCATION (xsum (length, n));
2316 DCHAR_CPY (result + length, arg, n);
2317 length += n;
2319 # else
2320 { /* Convert. */
2321 DCHAR_T *converted = result + length;
2322 size_t converted_len = allocated - length;
2323 # if DCHAR_IS_TCHAR
2324 /* Convert from UTF-32 to locale encoding. */
2325 converted =
2326 u32_conv_to_encoding (locale_charset (),
2327 iconveh_question_mark,
2328 arg, arg_end - arg, NULL,
2329 converted, &converted_len);
2330 # else
2331 /* Convert from UTF-32 to UTF-8/UTF-16. */
2332 converted =
2333 U32_TO_DCHAR (arg, arg_end - arg,
2334 converted, &converted_len);
2335 # endif
2336 if (converted == NULL)
2338 int saved_errno = errno;
2339 if (!(result == resultbuf || result == NULL))
2340 free (result);
2341 if (buf_malloced != NULL)
2342 free (buf_malloced);
2343 CLEANUP ();
2344 errno = saved_errno;
2345 return NULL;
2347 if (converted != result + length)
2349 ENSURE_ALLOCATION (xsum (length, converted_len));
2350 DCHAR_CPY (result + length, converted, converted_len);
2351 free (converted);
2353 length += converted_len;
2355 # endif
2357 if (has_width && width > characters
2358 && (dp->flags & FLAG_LEFT))
2360 size_t n = width - characters;
2361 ENSURE_ALLOCATION (xsum (length, n));
2362 DCHAR_SET (result + length, ' ', n);
2363 length += n;
2366 break;
2368 default:
2369 abort ();
2372 #endif
2373 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
2374 else if (dp->conversion == 's'
2375 # if WIDE_CHAR_VERSION
2376 && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
2377 # else
2378 && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
2379 # endif
2382 /* The normal handling of the 's' directive below requires
2383 allocating a temporary buffer. The determination of its
2384 length (tmp_length), in the case when a precision is
2385 specified, below requires a conversion between a char[]
2386 string and a wchar_t[] wide string. It could be done, but
2387 we have no guarantee that the implementation of sprintf will
2388 use the exactly same algorithm. Without this guarantee, it
2389 is possible to have buffer overrun bugs. In order to avoid
2390 such bugs, we implement the entire processing of the 's'
2391 directive ourselves. */
2392 int flags = dp->flags;
2393 int has_width;
2394 size_t width;
2395 int has_precision;
2396 size_t precision;
2398 has_width = 0;
2399 width = 0;
2400 if (dp->width_start != dp->width_end)
2402 if (dp->width_arg_index != ARG_NONE)
2404 int arg;
2406 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2407 abort ();
2408 arg = a.arg[dp->width_arg_index].a.a_int;
2409 if (arg < 0)
2411 /* "A negative field width is taken as a '-' flag
2412 followed by a positive field width." */
2413 flags |= FLAG_LEFT;
2414 width = (unsigned int) (-arg);
2416 else
2417 width = arg;
2419 else
2421 const FCHAR_T *digitp = dp->width_start;
2424 width = xsum (xtimes (width, 10), *digitp++ - '0');
2425 while (digitp != dp->width_end);
2427 has_width = 1;
2430 has_precision = 0;
2431 precision = 6;
2432 if (dp->precision_start != dp->precision_end)
2434 if (dp->precision_arg_index != ARG_NONE)
2436 int arg;
2438 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2439 abort ();
2440 arg = a.arg[dp->precision_arg_index].a.a_int;
2441 /* "A negative precision is taken as if the precision
2442 were omitted." */
2443 if (arg >= 0)
2445 precision = arg;
2446 has_precision = 1;
2449 else
2451 const FCHAR_T *digitp = dp->precision_start + 1;
2453 precision = 0;
2454 while (digitp != dp->precision_end)
2455 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2456 has_precision = 1;
2460 # if WIDE_CHAR_VERSION
2461 /* %s in vasnwprintf. See the specification of fwprintf. */
2463 const char *arg = a.arg[dp->arg_index].a.a_string;
2464 const char *arg_end;
2465 size_t characters;
2467 if (has_precision)
2469 /* Use only as many bytes as needed to produce PRECISION
2470 wide characters, from the left. */
2471 # if HAVE_MBRTOWC
2472 mbstate_t state;
2473 memset (&state, '\0', sizeof (mbstate_t));
2474 # endif
2475 arg_end = arg;
2476 characters = 0;
2477 for (; precision > 0; precision--)
2479 int count;
2480 # if HAVE_MBRTOWC
2481 count = mbrlen (arg_end, MB_CUR_MAX, &state);
2482 # else
2483 count = mblen (arg_end, MB_CUR_MAX);
2484 # endif
2485 if (count == 0)
2486 /* Found the terminating NUL. */
2487 break;
2488 if (count < 0)
2490 /* Invalid or incomplete multibyte character. */
2491 if (!(result == resultbuf || result == NULL))
2492 free (result);
2493 if (buf_malloced != NULL)
2494 free (buf_malloced);
2495 CLEANUP ();
2496 errno = EILSEQ;
2497 return NULL;
2499 arg_end += count;
2500 characters++;
2503 else if (has_width)
2505 /* Use the entire string, and count the number of wide
2506 characters. */
2507 # if HAVE_MBRTOWC
2508 mbstate_t state;
2509 memset (&state, '\0', sizeof (mbstate_t));
2510 # endif
2511 arg_end = arg;
2512 characters = 0;
2513 for (;;)
2515 int count;
2516 # if HAVE_MBRTOWC
2517 count = mbrlen (arg_end, MB_CUR_MAX, &state);
2518 # else
2519 count = mblen (arg_end, MB_CUR_MAX);
2520 # endif
2521 if (count == 0)
2522 /* Found the terminating NUL. */
2523 break;
2524 if (count < 0)
2526 /* Invalid or incomplete multibyte character. */
2527 if (!(result == resultbuf || result == NULL))
2528 free (result);
2529 if (buf_malloced != NULL)
2530 free (buf_malloced);
2531 CLEANUP ();
2532 errno = EILSEQ;
2533 return NULL;
2535 arg_end += count;
2536 characters++;
2539 else
2541 /* Use the entire string. */
2542 arg_end = arg + strlen (arg);
2543 /* The number of characters doesn't matter. */
2544 characters = 0;
2547 if (has_width && width > characters
2548 && !(dp->flags & FLAG_LEFT))
2550 size_t n = width - characters;
2551 ENSURE_ALLOCATION (xsum (length, n));
2552 DCHAR_SET (result + length, ' ', n);
2553 length += n;
2556 if (has_precision || has_width)
2558 /* We know the number of wide characters in advance. */
2559 size_t remaining;
2560 # if HAVE_MBRTOWC
2561 mbstate_t state;
2562 memset (&state, '\0', sizeof (mbstate_t));
2563 # endif
2564 ENSURE_ALLOCATION (xsum (length, characters));
2565 for (remaining = characters; remaining > 0; remaining--)
2567 wchar_t wc;
2568 int count;
2569 # if HAVE_MBRTOWC
2570 count = mbrtowc (&wc, arg, arg_end - arg, &state);
2571 # else
2572 count = mbtowc (&wc, arg, arg_end - arg);
2573 # endif
2574 if (count <= 0)
2575 /* mbrtowc not consistent with mbrlen, or mbtowc
2576 not consistent with mblen. */
2577 abort ();
2578 result[length++] = wc;
2579 arg += count;
2581 if (!(arg == arg_end))
2582 abort ();
2584 else
2586 # if HAVE_MBRTOWC
2587 mbstate_t state;
2588 memset (&state, '\0', sizeof (mbstate_t));
2589 # endif
2590 while (arg < arg_end)
2592 wchar_t wc;
2593 int count;
2594 # if HAVE_MBRTOWC
2595 count = mbrtowc (&wc, arg, arg_end - arg, &state);
2596 # else
2597 count = mbtowc (&wc, arg, arg_end - arg);
2598 # endif
2599 if (count <= 0)
2600 /* mbrtowc not consistent with mbrlen, or mbtowc
2601 not consistent with mblen. */
2602 abort ();
2603 ENSURE_ALLOCATION (xsum (length, 1));
2604 result[length++] = wc;
2605 arg += count;
2609 if (has_width && width > characters
2610 && (dp->flags & FLAG_LEFT))
2612 size_t n = width - characters;
2613 ENSURE_ALLOCATION (xsum (length, n));
2614 DCHAR_SET (result + length, ' ', n);
2615 length += n;
2618 # else
2619 /* %ls in vasnprintf. See the specification of fprintf. */
2621 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
2622 const wchar_t *arg_end;
2623 size_t characters;
2624 # if !DCHAR_IS_TCHAR
2625 /* This code assumes that TCHAR_T is 'char'. */
2626 verify (sizeof (TCHAR_T) == 1);
2627 TCHAR_T *tmpsrc;
2628 DCHAR_T *tmpdst;
2629 size_t tmpdst_len;
2630 # endif
2631 size_t w;
2633 if (has_precision)
2635 /* Use only as many wide characters as needed to produce
2636 at most PRECISION bytes, from the left. */
2637 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2638 mbstate_t state;
2639 memset (&state, '\0', sizeof (mbstate_t));
2640 # endif
2641 arg_end = arg;
2642 characters = 0;
2643 while (precision > 0)
2645 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2646 int count;
2648 if (*arg_end == 0)
2649 /* Found the terminating null wide character. */
2650 break;
2651 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2652 count = wcrtomb (cbuf, *arg_end, &state);
2653 # else
2654 count = wctomb (cbuf, *arg_end);
2655 # endif
2656 if (count < 0)
2658 /* Cannot convert. */
2659 if (!(result == resultbuf || result == NULL))
2660 free (result);
2661 if (buf_malloced != NULL)
2662 free (buf_malloced);
2663 CLEANUP ();
2664 errno = EILSEQ;
2665 return NULL;
2667 if (precision < count)
2668 break;
2669 arg_end++;
2670 characters += count;
2671 precision -= count;
2674 # if DCHAR_IS_TCHAR
2675 else if (has_width)
2676 # else
2677 else
2678 # endif
2680 /* Use the entire string, and count the number of
2681 bytes. */
2682 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2683 mbstate_t state;
2684 memset (&state, '\0', sizeof (mbstate_t));
2685 # endif
2686 arg_end = arg;
2687 characters = 0;
2688 for (;;)
2690 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2691 int count;
2693 if (*arg_end == 0)
2694 /* Found the terminating null wide character. */
2695 break;
2696 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2697 count = wcrtomb (cbuf, *arg_end, &state);
2698 # else
2699 count = wctomb (cbuf, *arg_end);
2700 # endif
2701 if (count < 0)
2703 /* Cannot convert. */
2704 if (!(result == resultbuf || result == NULL))
2705 free (result);
2706 if (buf_malloced != NULL)
2707 free (buf_malloced);
2708 CLEANUP ();
2709 errno = EILSEQ;
2710 return NULL;
2712 arg_end++;
2713 characters += count;
2716 # if DCHAR_IS_TCHAR
2717 else
2719 /* Use the entire string. */
2720 arg_end = arg + local_wcslen (arg);
2721 /* The number of bytes doesn't matter. */
2722 characters = 0;
2724 # endif
2726 # if !DCHAR_IS_TCHAR
2727 /* Convert the string into a piece of temporary memory. */
2728 tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
2729 if (tmpsrc == NULL)
2730 goto out_of_memory;
2732 TCHAR_T *tmpptr = tmpsrc;
2733 size_t remaining;
2734 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2735 mbstate_t state;
2736 memset (&state, '\0', sizeof (mbstate_t));
2737 # endif
2738 for (remaining = characters; remaining > 0; )
2740 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2741 int count;
2743 if (*arg == 0)
2744 abort ();
2745 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2746 count = wcrtomb (cbuf, *arg, &state);
2747 # else
2748 count = wctomb (cbuf, *arg);
2749 # endif
2750 if (count <= 0)
2751 /* Inconsistency. */
2752 abort ();
2753 memcpy (tmpptr, cbuf, count);
2754 tmpptr += count;
2755 arg++;
2756 remaining -= count;
2758 if (!(arg == arg_end))
2759 abort ();
2762 /* Convert from TCHAR_T[] to DCHAR_T[]. */
2763 tmpdst =
2764 DCHAR_CONV_FROM_ENCODING (locale_charset (),
2765 iconveh_question_mark,
2766 tmpsrc, characters,
2767 NULL,
2768 NULL, &tmpdst_len);
2769 if (tmpdst == NULL)
2771 int saved_errno = errno;
2772 free (tmpsrc);
2773 if (!(result == resultbuf || result == NULL))
2774 free (result);
2775 if (buf_malloced != NULL)
2776 free (buf_malloced);
2777 CLEANUP ();
2778 errno = saved_errno;
2779 return NULL;
2781 free (tmpsrc);
2782 # endif
2784 if (has_width)
2786 # if ENABLE_UNISTDIO
2787 /* Outside POSIX, it's preferrable to compare the width
2788 against the number of _characters_ of the converted
2789 value. */
2790 w = DCHAR_MBSNLEN (result + length, characters);
2791 # else
2792 /* The width is compared against the number of _bytes_
2793 of the converted value, says POSIX. */
2794 w = characters;
2795 # endif
2797 else
2798 /* w doesn't matter. */
2799 w = 0;
2801 if (has_width && width > w
2802 && !(dp->flags & FLAG_LEFT))
2804 size_t n = width - w;
2805 ENSURE_ALLOCATION (xsum (length, n));
2806 DCHAR_SET (result + length, ' ', n);
2807 length += n;
2810 # if DCHAR_IS_TCHAR
2811 if (has_precision || has_width)
2813 /* We know the number of bytes in advance. */
2814 size_t remaining;
2815 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2816 mbstate_t state;
2817 memset (&state, '\0', sizeof (mbstate_t));
2818 # endif
2819 ENSURE_ALLOCATION (xsum (length, characters));
2820 for (remaining = characters; remaining > 0; )
2822 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2823 int count;
2825 if (*arg == 0)
2826 abort ();
2827 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2828 count = wcrtomb (cbuf, *arg, &state);
2829 # else
2830 count = wctomb (cbuf, *arg);
2831 # endif
2832 if (count <= 0)
2833 /* Inconsistency. */
2834 abort ();
2835 memcpy (result + length, cbuf, count);
2836 length += count;
2837 arg++;
2838 remaining -= count;
2840 if (!(arg == arg_end))
2841 abort ();
2843 else
2845 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2846 mbstate_t state;
2847 memset (&state, '\0', sizeof (mbstate_t));
2848 # endif
2849 while (arg < arg_end)
2851 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2852 int count;
2854 if (*arg == 0)
2855 abort ();
2856 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2857 count = wcrtomb (cbuf, *arg, &state);
2858 # else
2859 count = wctomb (cbuf, *arg);
2860 # endif
2861 if (count <= 0)
2863 /* Cannot convert. */
2864 if (!(result == resultbuf || result == NULL))
2865 free (result);
2866 if (buf_malloced != NULL)
2867 free (buf_malloced);
2868 CLEANUP ();
2869 errno = EILSEQ;
2870 return NULL;
2872 ENSURE_ALLOCATION (xsum (length, count));
2873 memcpy (result + length, cbuf, count);
2874 length += count;
2875 arg++;
2878 # else
2879 ENSURE_ALLOCATION (xsum (length, tmpdst_len));
2880 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
2881 free (tmpdst);
2882 length += tmpdst_len;
2883 # endif
2885 if (has_width && width > w
2886 && (dp->flags & FLAG_LEFT))
2888 size_t n = width - w;
2889 ENSURE_ALLOCATION (xsum (length, n));
2890 DCHAR_SET (result + length, ' ', n);
2891 length += n;
2894 # endif
2896 #endif
2897 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
2898 else if ((dp->conversion == 'a' || dp->conversion == 'A')
2899 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
2900 && (0
2901 # if NEED_PRINTF_DOUBLE
2902 || a.arg[dp->arg_index].type == TYPE_DOUBLE
2903 # endif
2904 # if NEED_PRINTF_LONG_DOUBLE
2905 || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2906 # endif
2908 # endif
2911 arg_type type = a.arg[dp->arg_index].type;
2912 int flags = dp->flags;
2913 int has_width;
2914 size_t width;
2915 int has_precision;
2916 size_t precision;
2917 size_t tmp_length;
2918 DCHAR_T tmpbuf[700];
2919 DCHAR_T *tmp;
2920 DCHAR_T *pad_ptr;
2921 DCHAR_T *p;
2923 has_width = 0;
2924 width = 0;
2925 if (dp->width_start != dp->width_end)
2927 if (dp->width_arg_index != ARG_NONE)
2929 int arg;
2931 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2932 abort ();
2933 arg = a.arg[dp->width_arg_index].a.a_int;
2934 if (arg < 0)
2936 /* "A negative field width is taken as a '-' flag
2937 followed by a positive field width." */
2938 flags |= FLAG_LEFT;
2939 width = (unsigned int) (-arg);
2941 else
2942 width = arg;
2944 else
2946 const FCHAR_T *digitp = dp->width_start;
2949 width = xsum (xtimes (width, 10), *digitp++ - '0');
2950 while (digitp != dp->width_end);
2952 has_width = 1;
2955 has_precision = 0;
2956 precision = 0;
2957 if (dp->precision_start != dp->precision_end)
2959 if (dp->precision_arg_index != ARG_NONE)
2961 int arg;
2963 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2964 abort ();
2965 arg = a.arg[dp->precision_arg_index].a.a_int;
2966 /* "A negative precision is taken as if the precision
2967 were omitted." */
2968 if (arg >= 0)
2970 precision = arg;
2971 has_precision = 1;
2974 else
2976 const FCHAR_T *digitp = dp->precision_start + 1;
2978 precision = 0;
2979 while (digitp != dp->precision_end)
2980 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2981 has_precision = 1;
2985 /* Allocate a temporary buffer of sufficient size. */
2986 if (type == TYPE_LONGDOUBLE)
2987 tmp_length =
2988 (unsigned int) ((LDBL_DIG + 1)
2989 * 0.831 /* decimal -> hexadecimal */
2991 + 1; /* turn floor into ceil */
2992 else
2993 tmp_length =
2994 (unsigned int) ((DBL_DIG + 1)
2995 * 0.831 /* decimal -> hexadecimal */
2997 + 1; /* turn floor into ceil */
2998 if (tmp_length < precision)
2999 tmp_length = precision;
3000 /* Account for sign, decimal point etc. */
3001 tmp_length = xsum (tmp_length, 12);
3003 if (tmp_length < width)
3004 tmp_length = width;
3006 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3008 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3009 tmp = tmpbuf;
3010 else
3012 size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3014 if (size_overflow_p (tmp_memsize))
3015 /* Overflow, would lead to out of memory. */
3016 goto out_of_memory;
3017 tmp = (DCHAR_T *) malloc (tmp_memsize);
3018 if (tmp == NULL)
3019 /* Out of memory. */
3020 goto out_of_memory;
3023 pad_ptr = NULL;
3024 p = tmp;
3025 if (type == TYPE_LONGDOUBLE)
3027 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
3028 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3030 if (isnanl (arg))
3032 if (dp->conversion == 'A')
3034 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3036 else
3038 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3041 else
3043 int sign = 0;
3044 DECL_LONG_DOUBLE_ROUNDING
3046 BEGIN_LONG_DOUBLE_ROUNDING ();
3048 if (signbit (arg)) /* arg < 0.0L or negative zero */
3050 sign = -1;
3051 arg = -arg;
3054 if (sign < 0)
3055 *p++ = '-';
3056 else if (flags & FLAG_SHOWSIGN)
3057 *p++ = '+';
3058 else if (flags & FLAG_SPACE)
3059 *p++ = ' ';
3061 if (arg > 0.0L && arg + arg == arg)
3063 if (dp->conversion == 'A')
3065 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3067 else
3069 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3072 else
3074 int exponent;
3075 long double mantissa;
3077 if (arg > 0.0L)
3078 mantissa = printf_frexpl (arg, &exponent);
3079 else
3081 exponent = 0;
3082 mantissa = 0.0L;
3085 if (has_precision
3086 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
3088 /* Round the mantissa. */
3089 long double tail = mantissa;
3090 size_t q;
3092 for (q = precision; ; q--)
3094 int digit = (int) tail;
3095 tail -= digit;
3096 if (q == 0)
3098 if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
3099 tail = 1 - tail;
3100 else
3101 tail = - tail;
3102 break;
3104 tail *= 16.0L;
3106 if (tail != 0.0L)
3107 for (q = precision; q > 0; q--)
3108 tail *= 0.0625L;
3109 mantissa += tail;
3112 *p++ = '0';
3113 *p++ = dp->conversion - 'A' + 'X';
3114 pad_ptr = p;
3116 int digit;
3118 digit = (int) mantissa;
3119 mantissa -= digit;
3120 *p++ = '0' + digit;
3121 if ((flags & FLAG_ALT)
3122 || mantissa > 0.0L || precision > 0)
3124 *p++ = decimal_point_char ();
3125 /* This loop terminates because we assume
3126 that FLT_RADIX is a power of 2. */
3127 while (mantissa > 0.0L)
3129 mantissa *= 16.0L;
3130 digit = (int) mantissa;
3131 mantissa -= digit;
3132 *p++ = digit
3133 + (digit < 10
3134 ? '0'
3135 : dp->conversion - 10);
3136 if (precision > 0)
3137 precision--;
3139 while (precision > 0)
3141 *p++ = '0';
3142 precision--;
3146 *p++ = dp->conversion - 'A' + 'P';
3147 # if WIDE_CHAR_VERSION
3149 static const wchar_t decimal_format[] =
3150 { '%', '+', 'd', '\0' };
3151 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3153 while (*p != '\0')
3154 p++;
3155 # else
3156 if (sizeof (DCHAR_T) == 1)
3158 sprintf ((char *) p, "%+d", exponent);
3159 while (*p != '\0')
3160 p++;
3162 else
3164 char expbuf[6 + 1];
3165 const char *ep;
3166 sprintf (expbuf, "%+d", exponent);
3167 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3168 p++;
3170 # endif
3173 END_LONG_DOUBLE_ROUNDING ();
3175 # else
3176 abort ();
3177 # endif
3179 else
3181 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
3182 double arg = a.arg[dp->arg_index].a.a_double;
3184 if (isnand (arg))
3186 if (dp->conversion == 'A')
3188 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3190 else
3192 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3195 else
3197 int sign = 0;
3199 if (signbit (arg)) /* arg < 0.0 or negative zero */
3201 sign = -1;
3202 arg = -arg;
3205 if (sign < 0)
3206 *p++ = '-';
3207 else if (flags & FLAG_SHOWSIGN)
3208 *p++ = '+';
3209 else if (flags & FLAG_SPACE)
3210 *p++ = ' ';
3212 if (arg > 0.0 && arg + arg == arg)
3214 if (dp->conversion == 'A')
3216 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3218 else
3220 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3223 else
3225 int exponent;
3226 double mantissa;
3228 if (arg > 0.0)
3229 mantissa = printf_frexp (arg, &exponent);
3230 else
3232 exponent = 0;
3233 mantissa = 0.0;
3236 if (has_precision
3237 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
3239 /* Round the mantissa. */
3240 double tail = mantissa;
3241 size_t q;
3243 for (q = precision; ; q--)
3245 int digit = (int) tail;
3246 tail -= digit;
3247 if (q == 0)
3249 if (digit & 1 ? tail >= 0.5 : tail > 0.5)
3250 tail = 1 - tail;
3251 else
3252 tail = - tail;
3253 break;
3255 tail *= 16.0;
3257 if (tail != 0.0)
3258 for (q = precision; q > 0; q--)
3259 tail *= 0.0625;
3260 mantissa += tail;
3263 *p++ = '0';
3264 *p++ = dp->conversion - 'A' + 'X';
3265 pad_ptr = p;
3267 int digit;
3269 digit = (int) mantissa;
3270 mantissa -= digit;
3271 *p++ = '0' + digit;
3272 if ((flags & FLAG_ALT)
3273 || mantissa > 0.0 || precision > 0)
3275 *p++ = decimal_point_char ();
3276 /* This loop terminates because we assume
3277 that FLT_RADIX is a power of 2. */
3278 while (mantissa > 0.0)
3280 mantissa *= 16.0;
3281 digit = (int) mantissa;
3282 mantissa -= digit;
3283 *p++ = digit
3284 + (digit < 10
3285 ? '0'
3286 : dp->conversion - 10);
3287 if (precision > 0)
3288 precision--;
3290 while (precision > 0)
3292 *p++ = '0';
3293 precision--;
3297 *p++ = dp->conversion - 'A' + 'P';
3298 # if WIDE_CHAR_VERSION
3300 static const wchar_t decimal_format[] =
3301 { '%', '+', 'd', '\0' };
3302 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3304 while (*p != '\0')
3305 p++;
3306 # else
3307 if (sizeof (DCHAR_T) == 1)
3309 sprintf ((char *) p, "%+d", exponent);
3310 while (*p != '\0')
3311 p++;
3313 else
3315 char expbuf[6 + 1];
3316 const char *ep;
3317 sprintf (expbuf, "%+d", exponent);
3318 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3319 p++;
3321 # endif
3324 # else
3325 abort ();
3326 # endif
3328 /* The generated string now extends from tmp to p, with the
3329 zero padding insertion point being at pad_ptr. */
3330 if (has_width && p - tmp < width)
3332 size_t pad = width - (p - tmp);
3333 DCHAR_T *end = p + pad;
3335 if (flags & FLAG_LEFT)
3337 /* Pad with spaces on the right. */
3338 for (; pad > 0; pad--)
3339 *p++ = ' ';
3341 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3343 /* Pad with zeroes. */
3344 DCHAR_T *q = end;
3346 while (p > pad_ptr)
3347 *--q = *--p;
3348 for (; pad > 0; pad--)
3349 *p++ = '0';
3351 else
3353 /* Pad with spaces on the left. */
3354 DCHAR_T *q = end;
3356 while (p > tmp)
3357 *--q = *--p;
3358 for (; pad > 0; pad--)
3359 *p++ = ' ';
3362 p = end;
3366 size_t count = p - tmp;
3368 if (count >= tmp_length)
3369 /* tmp_length was incorrectly calculated - fix the
3370 code above! */
3371 abort ();
3373 /* Make room for the result. */
3374 if (count >= allocated - length)
3376 size_t n = xsum (length, count);
3378 ENSURE_ALLOCATION (n);
3381 /* Append the result. */
3382 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3383 if (tmp != tmpbuf)
3384 free (tmp);
3385 length += count;
3388 #endif
3389 #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
3390 else if ((dp->conversion == 'f' || dp->conversion == 'F'
3391 || dp->conversion == 'e' || dp->conversion == 'E'
3392 || dp->conversion == 'g' || dp->conversion == 'G'
3393 || dp->conversion == 'a' || dp->conversion == 'A')
3394 && (0
3395 # if NEED_PRINTF_DOUBLE
3396 || a.arg[dp->arg_index].type == TYPE_DOUBLE
3397 # elif NEED_PRINTF_INFINITE_DOUBLE
3398 || (a.arg[dp->arg_index].type == TYPE_DOUBLE
3399 /* The systems (mingw) which produce wrong output
3400 for Inf, -Inf, and NaN also do so for -0.0.
3401 Therefore we treat this case here as well. */
3402 && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
3403 # endif
3404 # if NEED_PRINTF_LONG_DOUBLE
3405 || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3406 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
3407 || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3408 /* Some systems produce wrong output for Inf,
3409 -Inf, and NaN. Some systems in this category
3410 (IRIX 5.3) also do so for -0.0. Therefore we
3411 treat this case here as well. */
3412 && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
3413 # endif
3416 # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
3417 arg_type type = a.arg[dp->arg_index].type;
3418 # endif
3419 int flags = dp->flags;
3420 int has_width;
3421 size_t width;
3422 int has_precision;
3423 size_t precision;
3424 size_t tmp_length;
3425 DCHAR_T tmpbuf[700];
3426 DCHAR_T *tmp;
3427 DCHAR_T *pad_ptr;
3428 DCHAR_T *p;
3430 has_width = 0;
3431 width = 0;
3432 if (dp->width_start != dp->width_end)
3434 if (dp->width_arg_index != ARG_NONE)
3436 int arg;
3438 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3439 abort ();
3440 arg = a.arg[dp->width_arg_index].a.a_int;
3441 if (arg < 0)
3443 /* "A negative field width is taken as a '-' flag
3444 followed by a positive field width." */
3445 flags |= FLAG_LEFT;
3446 width = (unsigned int) (-arg);
3448 else
3449 width = arg;
3451 else
3453 const FCHAR_T *digitp = dp->width_start;
3456 width = xsum (xtimes (width, 10), *digitp++ - '0');
3457 while (digitp != dp->width_end);
3459 has_width = 1;
3462 has_precision = 0;
3463 precision = 0;
3464 if (dp->precision_start != dp->precision_end)
3466 if (dp->precision_arg_index != ARG_NONE)
3468 int arg;
3470 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3471 abort ();
3472 arg = a.arg[dp->precision_arg_index].a.a_int;
3473 /* "A negative precision is taken as if the precision
3474 were omitted." */
3475 if (arg >= 0)
3477 precision = arg;
3478 has_precision = 1;
3481 else
3483 const FCHAR_T *digitp = dp->precision_start + 1;
3485 precision = 0;
3486 while (digitp != dp->precision_end)
3487 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3488 has_precision = 1;
3492 /* POSIX specifies the default precision to be 6 for %f, %F,
3493 %e, %E, but not for %g, %G. Implementations appear to use
3494 the same default precision also for %g, %G. But for %a, %A,
3495 the default precision is 0. */
3496 if (!has_precision)
3497 if (!(dp->conversion == 'a' || dp->conversion == 'A'))
3498 precision = 6;
3500 /* Allocate a temporary buffer of sufficient size. */
3501 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3502 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
3503 # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3504 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
3505 # elif NEED_PRINTF_LONG_DOUBLE
3506 tmp_length = LDBL_DIG + 1;
3507 # elif NEED_PRINTF_DOUBLE
3508 tmp_length = DBL_DIG + 1;
3509 # else
3510 tmp_length = 0;
3511 # endif
3512 if (tmp_length < precision)
3513 tmp_length = precision;
3514 # if NEED_PRINTF_LONG_DOUBLE
3515 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3516 if (type == TYPE_LONGDOUBLE)
3517 # endif
3518 if (dp->conversion == 'f' || dp->conversion == 'F')
3520 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3521 if (!(isnanl (arg) || arg + arg == arg))
3523 /* arg is finite and nonzero. */
3524 int exponent = floorlog10l (arg < 0 ? -arg : arg);
3525 if (exponent >= 0 && tmp_length < exponent + precision)
3526 tmp_length = exponent + precision;
3529 # endif
3530 # if NEED_PRINTF_DOUBLE
3531 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3532 if (type == TYPE_DOUBLE)
3533 # endif
3534 if (dp->conversion == 'f' || dp->conversion == 'F')
3536 double arg = a.arg[dp->arg_index].a.a_double;
3537 if (!(isnand (arg) || arg + arg == arg))
3539 /* arg is finite and nonzero. */
3540 int exponent = floorlog10 (arg < 0 ? -arg : arg);
3541 if (exponent >= 0 && tmp_length < exponent + precision)
3542 tmp_length = exponent + precision;
3545 # endif
3546 /* Account for sign, decimal point etc. */
3547 tmp_length = xsum (tmp_length, 12);
3549 if (tmp_length < width)
3550 tmp_length = width;
3552 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3554 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3555 tmp = tmpbuf;
3556 else
3558 size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3560 if (size_overflow_p (tmp_memsize))
3561 /* Overflow, would lead to out of memory. */
3562 goto out_of_memory;
3563 tmp = (DCHAR_T *) malloc (tmp_memsize);
3564 if (tmp == NULL)
3565 /* Out of memory. */
3566 goto out_of_memory;
3569 pad_ptr = NULL;
3570 p = tmp;
3572 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3573 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3574 if (type == TYPE_LONGDOUBLE)
3575 # endif
3577 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3579 if (isnanl (arg))
3581 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3583 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3585 else
3587 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3590 else
3592 int sign = 0;
3593 DECL_LONG_DOUBLE_ROUNDING
3595 BEGIN_LONG_DOUBLE_ROUNDING ();
3597 if (signbit (arg)) /* arg < 0.0L or negative zero */
3599 sign = -1;
3600 arg = -arg;
3603 if (sign < 0)
3604 *p++ = '-';
3605 else if (flags & FLAG_SHOWSIGN)
3606 *p++ = '+';
3607 else if (flags & FLAG_SPACE)
3608 *p++ = ' ';
3610 if (arg > 0.0L && arg + arg == arg)
3612 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3614 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3616 else
3618 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3621 else
3623 # if NEED_PRINTF_LONG_DOUBLE
3624 pad_ptr = p;
3626 if (dp->conversion == 'f' || dp->conversion == 'F')
3628 char *digits;
3629 size_t ndigits;
3631 digits =
3632 scale10_round_decimal_long_double (arg, precision);
3633 if (digits == NULL)
3635 END_LONG_DOUBLE_ROUNDING ();
3636 goto out_of_memory;
3638 ndigits = strlen (digits);
3640 if (ndigits > precision)
3643 --ndigits;
3644 *p++ = digits[ndigits];
3646 while (ndigits > precision);
3647 else
3648 *p++ = '0';
3649 /* Here ndigits <= precision. */
3650 if ((flags & FLAG_ALT) || precision > 0)
3652 *p++ = decimal_point_char ();
3653 for (; precision > ndigits; precision--)
3654 *p++ = '0';
3655 while (ndigits > 0)
3657 --ndigits;
3658 *p++ = digits[ndigits];
3662 free (digits);
3664 else if (dp->conversion == 'e' || dp->conversion == 'E')
3666 int exponent;
3668 if (arg == 0.0L)
3670 exponent = 0;
3671 *p++ = '0';
3672 if ((flags & FLAG_ALT) || precision > 0)
3674 *p++ = decimal_point_char ();
3675 for (; precision > 0; precision--)
3676 *p++ = '0';
3679 else
3681 /* arg > 0.0L. */
3682 int adjusted;
3683 char *digits;
3684 size_t ndigits;
3686 exponent = floorlog10l (arg);
3687 adjusted = 0;
3688 for (;;)
3690 digits =
3691 scale10_round_decimal_long_double (arg,
3692 (int)precision - exponent);
3693 if (digits == NULL)
3695 END_LONG_DOUBLE_ROUNDING ();
3696 goto out_of_memory;
3698 ndigits = strlen (digits);
3700 if (ndigits == precision + 1)
3701 break;
3702 if (ndigits < precision
3703 || ndigits > precision + 2)
3704 /* The exponent was not guessed
3705 precisely enough. */
3706 abort ();
3707 if (adjusted)
3708 /* None of two values of exponent is
3709 the right one. Prevent an endless
3710 loop. */
3711 abort ();
3712 free (digits);
3713 if (ndigits == precision)
3714 exponent -= 1;
3715 else
3716 exponent += 1;
3717 adjusted = 1;
3719 /* Here ndigits = precision+1. */
3720 if (is_borderline (digits, precision))
3722 /* Maybe the exponent guess was too high
3723 and a smaller exponent can be reached
3724 by turning a 10...0 into 9...9x. */
3725 char *digits2 =
3726 scale10_round_decimal_long_double (arg,
3727 (int)precision - exponent + 1);
3728 if (digits2 == NULL)
3730 free (digits);
3731 END_LONG_DOUBLE_ROUNDING ();
3732 goto out_of_memory;
3734 if (strlen (digits2) == precision + 1)
3736 free (digits);
3737 digits = digits2;
3738 exponent -= 1;
3740 else
3741 free (digits2);
3743 /* Here ndigits = precision+1. */
3745 *p++ = digits[--ndigits];
3746 if ((flags & FLAG_ALT) || precision > 0)
3748 *p++ = decimal_point_char ();
3749 while (ndigits > 0)
3751 --ndigits;
3752 *p++ = digits[ndigits];
3756 free (digits);
3759 *p++ = dp->conversion; /* 'e' or 'E' */
3760 # if WIDE_CHAR_VERSION
3762 static const wchar_t decimal_format[] =
3763 { '%', '+', '.', '2', 'd', '\0' };
3764 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3766 while (*p != '\0')
3767 p++;
3768 # else
3769 if (sizeof (DCHAR_T) == 1)
3771 sprintf ((char *) p, "%+.2d", exponent);
3772 while (*p != '\0')
3773 p++;
3775 else
3777 char expbuf[6 + 1];
3778 const char *ep;
3779 sprintf (expbuf, "%+.2d", exponent);
3780 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3781 p++;
3783 # endif
3785 else if (dp->conversion == 'g' || dp->conversion == 'G')
3787 if (precision == 0)
3788 precision = 1;
3789 /* precision >= 1. */
3791 if (arg == 0.0L)
3792 /* The exponent is 0, >= -4, < precision.
3793 Use fixed-point notation. */
3795 size_t ndigits = precision;
3796 /* Number of trailing zeroes that have to be
3797 dropped. */
3798 size_t nzeroes =
3799 (flags & FLAG_ALT ? 0 : precision - 1);
3801 --ndigits;
3802 *p++ = '0';
3803 if ((flags & FLAG_ALT) || ndigits > nzeroes)
3805 *p++ = decimal_point_char ();
3806 while (ndigits > nzeroes)
3808 --ndigits;
3809 *p++ = '0';
3813 else
3815 /* arg > 0.0L. */
3816 int exponent;
3817 int adjusted;
3818 char *digits;
3819 size_t ndigits;
3820 size_t nzeroes;
3822 exponent = floorlog10l (arg);
3823 adjusted = 0;
3824 for (;;)
3826 digits =
3827 scale10_round_decimal_long_double (arg,
3828 (int)(precision - 1) - exponent);
3829 if (digits == NULL)
3831 END_LONG_DOUBLE_ROUNDING ();
3832 goto out_of_memory;
3834 ndigits = strlen (digits);
3836 if (ndigits == precision)
3837 break;
3838 if (ndigits < precision - 1
3839 || ndigits > precision + 1)
3840 /* The exponent was not guessed
3841 precisely enough. */
3842 abort ();
3843 if (adjusted)
3844 /* None of two values of exponent is
3845 the right one. Prevent an endless
3846 loop. */
3847 abort ();
3848 free (digits);
3849 if (ndigits < precision)
3850 exponent -= 1;
3851 else
3852 exponent += 1;
3853 adjusted = 1;
3855 /* Here ndigits = precision. */
3856 if (is_borderline (digits, precision - 1))
3858 /* Maybe the exponent guess was too high
3859 and a smaller exponent can be reached
3860 by turning a 10...0 into 9...9x. */
3861 char *digits2 =
3862 scale10_round_decimal_long_double (arg,
3863 (int)(precision - 1) - exponent + 1);
3864 if (digits2 == NULL)
3866 free (digits);
3867 END_LONG_DOUBLE_ROUNDING ();
3868 goto out_of_memory;
3870 if (strlen (digits2) == precision)
3872 free (digits);
3873 digits = digits2;
3874 exponent -= 1;
3876 else
3877 free (digits2);
3879 /* Here ndigits = precision. */
3881 /* Determine the number of trailing zeroes
3882 that have to be dropped. */
3883 nzeroes = 0;
3884 if ((flags & FLAG_ALT) == 0)
3885 while (nzeroes < ndigits
3886 && digits[nzeroes] == '0')
3887 nzeroes++;
3889 /* The exponent is now determined. */
3890 if (exponent >= -4
3891 && exponent < (long)precision)
3893 /* Fixed-point notation:
3894 max(exponent,0)+1 digits, then the
3895 decimal point, then the remaining
3896 digits without trailing zeroes. */
3897 if (exponent >= 0)
3899 size_t count = exponent + 1;
3900 /* Note: count <= precision = ndigits. */
3901 for (; count > 0; count--)
3902 *p++ = digits[--ndigits];
3903 if ((flags & FLAG_ALT) || ndigits > nzeroes)
3905 *p++ = decimal_point_char ();
3906 while (ndigits > nzeroes)
3908 --ndigits;
3909 *p++ = digits[ndigits];
3913 else
3915 size_t count = -exponent - 1;
3916 *p++ = '0';
3917 *p++ = decimal_point_char ();
3918 for (; count > 0; count--)
3919 *p++ = '0';
3920 while (ndigits > nzeroes)
3922 --ndigits;
3923 *p++ = digits[ndigits];
3927 else
3929 /* Exponential notation. */
3930 *p++ = digits[--ndigits];
3931 if ((flags & FLAG_ALT) || ndigits > nzeroes)
3933 *p++ = decimal_point_char ();
3934 while (ndigits > nzeroes)
3936 --ndigits;
3937 *p++ = digits[ndigits];
3940 *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3941 # if WIDE_CHAR_VERSION
3943 static const wchar_t decimal_format[] =
3944 { '%', '+', '.', '2', 'd', '\0' };
3945 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3947 while (*p != '\0')
3948 p++;
3949 # else
3950 if (sizeof (DCHAR_T) == 1)
3952 sprintf ((char *) p, "%+.2d", exponent);
3953 while (*p != '\0')
3954 p++;
3956 else
3958 char expbuf[6 + 1];
3959 const char *ep;
3960 sprintf (expbuf, "%+.2d", exponent);
3961 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3962 p++;
3964 # endif
3967 free (digits);
3970 else
3971 abort ();
3972 # else
3973 /* arg is finite. */
3974 if (!(arg == 0.0L))
3975 abort ();
3977 pad_ptr = p;
3979 if (dp->conversion == 'f' || dp->conversion == 'F')
3981 *p++ = '0';
3982 if ((flags & FLAG_ALT) || precision > 0)
3984 *p++ = decimal_point_char ();
3985 for (; precision > 0; precision--)
3986 *p++ = '0';
3989 else if (dp->conversion == 'e' || dp->conversion == 'E')
3991 *p++ = '0';
3992 if ((flags & FLAG_ALT) || precision > 0)
3994 *p++ = decimal_point_char ();
3995 for (; precision > 0; precision--)
3996 *p++ = '0';
3998 *p++ = dp->conversion; /* 'e' or 'E' */
3999 *p++ = '+';
4000 *p++ = '0';
4001 *p++ = '0';
4003 else if (dp->conversion == 'g' || dp->conversion == 'G')
4005 *p++ = '0';
4006 if (flags & FLAG_ALT)
4008 size_t ndigits =
4009 (precision > 0 ? precision - 1 : 0);
4010 *p++ = decimal_point_char ();
4011 for (; ndigits > 0; --ndigits)
4012 *p++ = '0';
4015 else if (dp->conversion == 'a' || dp->conversion == 'A')
4017 *p++ = '0';
4018 *p++ = dp->conversion - 'A' + 'X';
4019 pad_ptr = p;
4020 *p++ = '0';
4021 if ((flags & FLAG_ALT) || precision > 0)
4023 *p++ = decimal_point_char ();
4024 for (; precision > 0; precision--)
4025 *p++ = '0';
4027 *p++ = dp->conversion - 'A' + 'P';
4028 *p++ = '+';
4029 *p++ = '0';
4031 else
4032 abort ();
4033 # endif
4036 END_LONG_DOUBLE_ROUNDING ();
4039 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4040 else
4041 # endif
4042 # endif
4043 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4045 double arg = a.arg[dp->arg_index].a.a_double;
4047 if (isnand (arg))
4049 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4051 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4053 else
4055 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4058 else
4060 int sign = 0;
4062 if (signbit (arg)) /* arg < 0.0 or negative zero */
4064 sign = -1;
4065 arg = -arg;
4068 if (sign < 0)
4069 *p++ = '-';
4070 else if (flags & FLAG_SHOWSIGN)
4071 *p++ = '+';
4072 else if (flags & FLAG_SPACE)
4073 *p++ = ' ';
4075 if (arg > 0.0 && arg + arg == arg)
4077 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4079 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4081 else
4083 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4086 else
4088 # if NEED_PRINTF_DOUBLE
4089 pad_ptr = p;
4091 if (dp->conversion == 'f' || dp->conversion == 'F')
4093 char *digits;
4094 size_t ndigits;
4096 digits =
4097 scale10_round_decimal_double (arg, precision);
4098 if (digits == NULL)
4099 goto out_of_memory;
4100 ndigits = strlen (digits);
4102 if (ndigits > precision)
4105 --ndigits;
4106 *p++ = digits[ndigits];
4108 while (ndigits > precision);
4109 else
4110 *p++ = '0';
4111 /* Here ndigits <= precision. */
4112 if ((flags & FLAG_ALT) || precision > 0)
4114 *p++ = decimal_point_char ();
4115 for (; precision > ndigits; precision--)
4116 *p++ = '0';
4117 while (ndigits > 0)
4119 --ndigits;
4120 *p++ = digits[ndigits];
4124 free (digits);
4126 else if (dp->conversion == 'e' || dp->conversion == 'E')
4128 int exponent;
4130 if (arg == 0.0)
4132 exponent = 0;
4133 *p++ = '0';
4134 if ((flags & FLAG_ALT) || precision > 0)
4136 *p++ = decimal_point_char ();
4137 for (; precision > 0; precision--)
4138 *p++ = '0';
4141 else
4143 /* arg > 0.0. */
4144 int adjusted;
4145 char *digits;
4146 size_t ndigits;
4148 exponent = floorlog10 (arg);
4149 adjusted = 0;
4150 for (;;)
4152 digits =
4153 scale10_round_decimal_double (arg,
4154 (int)precision - exponent);
4155 if (digits == NULL)
4156 goto out_of_memory;
4157 ndigits = strlen (digits);
4159 if (ndigits == precision + 1)
4160 break;
4161 if (ndigits < precision
4162 || ndigits > precision + 2)
4163 /* The exponent was not guessed
4164 precisely enough. */
4165 abort ();
4166 if (adjusted)
4167 /* None of two values of exponent is
4168 the right one. Prevent an endless
4169 loop. */
4170 abort ();
4171 free (digits);
4172 if (ndigits == precision)
4173 exponent -= 1;
4174 else
4175 exponent += 1;
4176 adjusted = 1;
4178 /* Here ndigits = precision+1. */
4179 if (is_borderline (digits, precision))
4181 /* Maybe the exponent guess was too high
4182 and a smaller exponent can be reached
4183 by turning a 10...0 into 9...9x. */
4184 char *digits2 =
4185 scale10_round_decimal_double (arg,
4186 (int)precision - exponent + 1);
4187 if (digits2 == NULL)
4189 free (digits);
4190 goto out_of_memory;
4192 if (strlen (digits2) == precision + 1)
4194 free (digits);
4195 digits = digits2;
4196 exponent -= 1;
4198 else
4199 free (digits2);
4201 /* Here ndigits = precision+1. */
4203 *p++ = digits[--ndigits];
4204 if ((flags & FLAG_ALT) || precision > 0)
4206 *p++ = decimal_point_char ();
4207 while (ndigits > 0)
4209 --ndigits;
4210 *p++ = digits[ndigits];
4214 free (digits);
4217 *p++ = dp->conversion; /* 'e' or 'E' */
4218 # if WIDE_CHAR_VERSION
4220 static const wchar_t decimal_format[] =
4221 /* Produce the same number of exponent digits
4222 as the native printf implementation. */
4223 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4224 { '%', '+', '.', '3', 'd', '\0' };
4225 # else
4226 { '%', '+', '.', '2', 'd', '\0' };
4227 # endif
4228 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4230 while (*p != '\0')
4231 p++;
4232 # else
4234 static const char decimal_format[] =
4235 /* Produce the same number of exponent digits
4236 as the native printf implementation. */
4237 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4238 "%+.3d";
4239 # else
4240 "%+.2d";
4241 # endif
4242 if (sizeof (DCHAR_T) == 1)
4244 sprintf ((char *) p, decimal_format, exponent);
4245 while (*p != '\0')
4246 p++;
4248 else
4250 char expbuf[6 + 1];
4251 const char *ep;
4252 sprintf (expbuf, decimal_format, exponent);
4253 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4254 p++;
4257 # endif
4259 else if (dp->conversion == 'g' || dp->conversion == 'G')
4261 if (precision == 0)
4262 precision = 1;
4263 /* precision >= 1. */
4265 if (arg == 0.0)
4266 /* The exponent is 0, >= -4, < precision.
4267 Use fixed-point notation. */
4269 size_t ndigits = precision;
4270 /* Number of trailing zeroes that have to be
4271 dropped. */
4272 size_t nzeroes =
4273 (flags & FLAG_ALT ? 0 : precision - 1);
4275 --ndigits;
4276 *p++ = '0';
4277 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4279 *p++ = decimal_point_char ();
4280 while (ndigits > nzeroes)
4282 --ndigits;
4283 *p++ = '0';
4287 else
4289 /* arg > 0.0. */
4290 int exponent;
4291 int adjusted;
4292 char *digits;
4293 size_t ndigits;
4294 size_t nzeroes;
4296 exponent = floorlog10 (arg);
4297 adjusted = 0;
4298 for (;;)
4300 digits =
4301 scale10_round_decimal_double (arg,
4302 (int)(precision - 1) - exponent);
4303 if (digits == NULL)
4304 goto out_of_memory;
4305 ndigits = strlen (digits);
4307 if (ndigits == precision)
4308 break;
4309 if (ndigits < precision - 1
4310 || ndigits > precision + 1)
4311 /* The exponent was not guessed
4312 precisely enough. */
4313 abort ();
4314 if (adjusted)
4315 /* None of two values of exponent is
4316 the right one. Prevent an endless
4317 loop. */
4318 abort ();
4319 free (digits);
4320 if (ndigits < precision)
4321 exponent -= 1;
4322 else
4323 exponent += 1;
4324 adjusted = 1;
4326 /* Here ndigits = precision. */
4327 if (is_borderline (digits, precision - 1))
4329 /* Maybe the exponent guess was too high
4330 and a smaller exponent can be reached
4331 by turning a 10...0 into 9...9x. */
4332 char *digits2 =
4333 scale10_round_decimal_double (arg,
4334 (int)(precision - 1) - exponent + 1);
4335 if (digits2 == NULL)
4337 free (digits);
4338 goto out_of_memory;
4340 if (strlen (digits2) == precision)
4342 free (digits);
4343 digits = digits2;
4344 exponent -= 1;
4346 else
4347 free (digits2);
4349 /* Here ndigits = precision. */
4351 /* Determine the number of trailing zeroes
4352 that have to be dropped. */
4353 nzeroes = 0;
4354 if ((flags & FLAG_ALT) == 0)
4355 while (nzeroes < ndigits
4356 && digits[nzeroes] == '0')
4357 nzeroes++;
4359 /* The exponent is now determined. */
4360 if (exponent >= -4
4361 && exponent < (long)precision)
4363 /* Fixed-point notation:
4364 max(exponent,0)+1 digits, then the
4365 decimal point, then the remaining
4366 digits without trailing zeroes. */
4367 if (exponent >= 0)
4369 size_t count = exponent + 1;
4370 /* Note: count <= precision = ndigits. */
4371 for (; count > 0; count--)
4372 *p++ = digits[--ndigits];
4373 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4375 *p++ = decimal_point_char ();
4376 while (ndigits > nzeroes)
4378 --ndigits;
4379 *p++ = digits[ndigits];
4383 else
4385 size_t count = -exponent - 1;
4386 *p++ = '0';
4387 *p++ = decimal_point_char ();
4388 for (; count > 0; count--)
4389 *p++ = '0';
4390 while (ndigits > nzeroes)
4392 --ndigits;
4393 *p++ = digits[ndigits];
4397 else
4399 /* Exponential notation. */
4400 *p++ = digits[--ndigits];
4401 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4403 *p++ = decimal_point_char ();
4404 while (ndigits > nzeroes)
4406 --ndigits;
4407 *p++ = digits[ndigits];
4410 *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4411 # if WIDE_CHAR_VERSION
4413 static const wchar_t decimal_format[] =
4414 /* Produce the same number of exponent digits
4415 as the native printf implementation. */
4416 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4417 { '%', '+', '.', '3', 'd', '\0' };
4418 # else
4419 { '%', '+', '.', '2', 'd', '\0' };
4420 # endif
4421 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4423 while (*p != '\0')
4424 p++;
4425 # else
4427 static const char decimal_format[] =
4428 /* Produce the same number of exponent digits
4429 as the native printf implementation. */
4430 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4431 "%+.3d";
4432 # else
4433 "%+.2d";
4434 # endif
4435 if (sizeof (DCHAR_T) == 1)
4437 sprintf ((char *) p, decimal_format, exponent);
4438 while (*p != '\0')
4439 p++;
4441 else
4443 char expbuf[6 + 1];
4444 const char *ep;
4445 sprintf (expbuf, decimal_format, exponent);
4446 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4447 p++;
4450 # endif
4453 free (digits);
4456 else
4457 abort ();
4458 # else
4459 /* arg is finite. */
4460 if (!(arg == 0.0))
4461 abort ();
4463 pad_ptr = p;
4465 if (dp->conversion == 'f' || dp->conversion == 'F')
4467 *p++ = '0';
4468 if ((flags & FLAG_ALT) || precision > 0)
4470 *p++ = decimal_point_char ();
4471 for (; precision > 0; precision--)
4472 *p++ = '0';
4475 else if (dp->conversion == 'e' || dp->conversion == 'E')
4477 *p++ = '0';
4478 if ((flags & FLAG_ALT) || precision > 0)
4480 *p++ = decimal_point_char ();
4481 for (; precision > 0; precision--)
4482 *p++ = '0';
4484 *p++ = dp->conversion; /* 'e' or 'E' */
4485 *p++ = '+';
4486 /* Produce the same number of exponent digits as
4487 the native printf implementation. */
4488 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4489 *p++ = '0';
4490 # endif
4491 *p++ = '0';
4492 *p++ = '0';
4494 else if (dp->conversion == 'g' || dp->conversion == 'G')
4496 *p++ = '0';
4497 if (flags & FLAG_ALT)
4499 size_t ndigits =
4500 (precision > 0 ? precision - 1 : 0);
4501 *p++ = decimal_point_char ();
4502 for (; ndigits > 0; --ndigits)
4503 *p++ = '0';
4506 else
4507 abort ();
4508 # endif
4512 # endif
4514 /* The generated string now extends from tmp to p, with the
4515 zero padding insertion point being at pad_ptr. */
4516 if (has_width && p - tmp < width)
4518 size_t pad = width - (p - tmp);
4519 DCHAR_T *end = p + pad;
4521 if (flags & FLAG_LEFT)
4523 /* Pad with spaces on the right. */
4524 for (; pad > 0; pad--)
4525 *p++ = ' ';
4527 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4529 /* Pad with zeroes. */
4530 DCHAR_T *q = end;
4532 while (p > pad_ptr)
4533 *--q = *--p;
4534 for (; pad > 0; pad--)
4535 *p++ = '0';
4537 else
4539 /* Pad with spaces on the left. */
4540 DCHAR_T *q = end;
4542 while (p > tmp)
4543 *--q = *--p;
4544 for (; pad > 0; pad--)
4545 *p++ = ' ';
4548 p = end;
4552 size_t count = p - tmp;
4554 if (count >= tmp_length)
4555 /* tmp_length was incorrectly calculated - fix the
4556 code above! */
4557 abort ();
4559 /* Make room for the result. */
4560 if (count >= allocated - length)
4562 size_t n = xsum (length, count);
4564 ENSURE_ALLOCATION (n);
4567 /* Append the result. */
4568 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4569 if (tmp != tmpbuf)
4570 free (tmp);
4571 length += count;
4574 #endif
4575 else
4577 arg_type type = a.arg[dp->arg_index].type;
4578 int flags = dp->flags;
4579 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4580 int has_width;
4581 size_t width;
4582 #endif
4583 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
4584 int has_precision;
4585 size_t precision;
4586 #endif
4587 #if NEED_PRINTF_UNBOUNDED_PRECISION
4588 int prec_ourselves;
4589 #else
4590 # define prec_ourselves 0
4591 #endif
4592 #if NEED_PRINTF_FLAG_LEFTADJUST
4593 # define pad_ourselves 1
4594 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4595 int pad_ourselves;
4596 #else
4597 # define pad_ourselves 0
4598 #endif
4599 TCHAR_T *fbp;
4600 unsigned int prefix_count;
4601 int prefixes[2] IF_LINT (= { 0 });
4602 int orig_errno;
4603 #if !USE_SNPRINTF
4604 size_t tmp_length;
4605 TCHAR_T tmpbuf[700];
4606 TCHAR_T *tmp;
4607 #endif
4609 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4610 has_width = 0;
4611 width = 0;
4612 if (dp->width_start != dp->width_end)
4614 if (dp->width_arg_index != ARG_NONE)
4616 int arg;
4618 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4619 abort ();
4620 arg = a.arg[dp->width_arg_index].a.a_int;
4621 if (arg < 0)
4623 /* "A negative field width is taken as a '-' flag
4624 followed by a positive field width." */
4625 flags |= FLAG_LEFT;
4626 width = (unsigned int) (-arg);
4628 else
4629 width = arg;
4631 else
4633 const FCHAR_T *digitp = dp->width_start;
4636 width = xsum (xtimes (width, 10), *digitp++ - '0');
4637 while (digitp != dp->width_end);
4639 has_width = 1;
4641 #endif
4643 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
4644 has_precision = 0;
4645 precision = 6;
4646 if (dp->precision_start != dp->precision_end)
4648 if (dp->precision_arg_index != ARG_NONE)
4650 int arg;
4652 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4653 abort ();
4654 arg = a.arg[dp->precision_arg_index].a.a_int;
4655 /* "A negative precision is taken as if the precision
4656 were omitted." */
4657 if (arg >= 0)
4659 precision = arg;
4660 has_precision = 1;
4663 else
4665 const FCHAR_T *digitp = dp->precision_start + 1;
4667 precision = 0;
4668 while (digitp != dp->precision_end)
4669 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4670 has_precision = 1;
4673 #endif
4675 /* Decide whether to handle the precision ourselves. */
4676 #if NEED_PRINTF_UNBOUNDED_PRECISION
4677 switch (dp->conversion)
4679 case 'd': case 'i': case 'u':
4680 case 'o':
4681 case 'x': case 'X': case 'p':
4682 prec_ourselves = has_precision && (precision > 0);
4683 break;
4684 default:
4685 prec_ourselves = 0;
4686 break;
4688 #endif
4690 /* Decide whether to perform the padding ourselves. */
4691 #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
4692 switch (dp->conversion)
4694 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4695 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
4696 to perform the padding after this conversion. Functions
4697 with unistdio extensions perform the padding based on
4698 character count rather than element count. */
4699 case 'c': case 's':
4700 # endif
4701 # if NEED_PRINTF_FLAG_ZERO
4702 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
4703 case 'a': case 'A':
4704 # endif
4705 pad_ourselves = 1;
4706 break;
4707 default:
4708 pad_ourselves = prec_ourselves;
4709 break;
4711 #endif
4713 #if !USE_SNPRINTF
4714 /* Allocate a temporary buffer of sufficient size for calling
4715 sprintf. */
4716 tmp_length =
4717 MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
4718 flags, width, has_precision, precision,
4719 pad_ourselves);
4721 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
4722 tmp = tmpbuf;
4723 else
4725 size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
4727 if (size_overflow_p (tmp_memsize))
4728 /* Overflow, would lead to out of memory. */
4729 goto out_of_memory;
4730 tmp = (TCHAR_T *) malloc (tmp_memsize);
4731 if (tmp == NULL)
4732 /* Out of memory. */
4733 goto out_of_memory;
4735 #endif
4737 /* Construct the format string for calling snprintf or
4738 sprintf. */
4739 fbp = buf;
4740 *fbp++ = '%';
4741 #if NEED_PRINTF_FLAG_GROUPING
4742 /* The underlying implementation doesn't support the ' flag.
4743 Produce no grouping characters in this case; this is
4744 acceptable because the grouping is locale dependent. */
4745 #else
4746 if (flags & FLAG_GROUP)
4747 *fbp++ = '\'';
4748 #endif
4749 if (flags & FLAG_LEFT)
4750 *fbp++ = '-';
4751 if (flags & FLAG_SHOWSIGN)
4752 *fbp++ = '+';
4753 if (flags & FLAG_SPACE)
4754 *fbp++ = ' ';
4755 if (flags & FLAG_ALT)
4756 *fbp++ = '#';
4757 #if __GLIBC__ >= 2 && !defined __UCLIBC__
4758 if (flags & FLAG_LOCALIZED)
4759 *fbp++ = 'I';
4760 #endif
4761 if (!pad_ourselves)
4763 if (flags & FLAG_ZERO)
4764 *fbp++ = '0';
4765 if (dp->width_start != dp->width_end)
4767 size_t n = dp->width_end - dp->width_start;
4768 /* The width specification is known to consist only
4769 of standard ASCII characters. */
4770 if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4772 memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
4773 fbp += n;
4775 else
4777 const FCHAR_T *mp = dp->width_start;
4779 *fbp++ = (unsigned char) *mp++;
4780 while (--n > 0);
4784 if (!prec_ourselves)
4786 if (dp->precision_start != dp->precision_end)
4788 size_t n = dp->precision_end - dp->precision_start;
4789 /* The precision specification is known to consist only
4790 of standard ASCII characters. */
4791 if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4793 memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
4794 fbp += n;
4796 else
4798 const FCHAR_T *mp = dp->precision_start;
4800 *fbp++ = (unsigned char) *mp++;
4801 while (--n > 0);
4806 switch (type)
4808 #if HAVE_LONG_LONG_INT
4809 case TYPE_LONGLONGINT:
4810 case TYPE_ULONGLONGINT:
4811 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4812 *fbp++ = 'I';
4813 *fbp++ = '6';
4814 *fbp++ = '4';
4815 break;
4816 # else
4817 *fbp++ = 'l';
4818 /*FALLTHROUGH*/
4819 # endif
4820 #endif
4821 case TYPE_LONGINT:
4822 case TYPE_ULONGINT:
4823 #if HAVE_WINT_T
4824 case TYPE_WIDE_CHAR:
4825 #endif
4826 #if HAVE_WCHAR_T
4827 case TYPE_WIDE_STRING:
4828 #endif
4829 *fbp++ = 'l';
4830 break;
4831 case TYPE_LONGDOUBLE:
4832 *fbp++ = 'L';
4833 break;
4834 default:
4835 break;
4837 #if NEED_PRINTF_DIRECTIVE_F
4838 if (dp->conversion == 'F')
4839 *fbp = 'f';
4840 else
4841 #endif
4842 *fbp = dp->conversion;
4843 #if USE_SNPRINTF
4844 # if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
4845 fbp[1] = '%';
4846 fbp[2] = 'n';
4847 fbp[3] = '\0';
4848 # else
4849 /* On glibc2 systems from glibc >= 2.3 - probably also older
4850 ones - we know that snprintf's return value conforms to
4851 ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and
4852 gl_SNPRINTF_TRUNCATION_C99 pass.
4853 Therefore we can avoid using %n in this situation.
4854 On glibc2 systems from 2004-10-18 or newer, the use of %n
4855 in format strings in writable memory may crash the program
4856 (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
4857 in this situation. */
4858 /* On native Win32 systems (such as mingw), we can avoid using
4859 %n because:
4860 - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
4861 snprintf does not write more than the specified number
4862 of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
4863 '4', '5', '6' into buf, not '4', '5', '\0'.)
4864 - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
4865 allows us to recognize the case of an insufficient
4866 buffer size: it returns -1 in this case.
4867 On native Win32 systems (such as mingw) where the OS is
4868 Windows Vista, the use of %n in format strings by default
4869 crashes the program. See
4870 <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
4871 <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
4872 So we should avoid %n in this situation. */
4873 fbp[1] = '\0';
4874 # endif
4875 #else
4876 fbp[1] = '\0';
4877 #endif
4879 /* Construct the arguments for calling snprintf or sprintf. */
4880 prefix_count = 0;
4881 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
4883 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4884 abort ();
4885 prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
4887 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
4889 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4890 abort ();
4891 prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
4894 #if USE_SNPRINTF
4895 /* The SNPRINTF result is appended after result[0..length].
4896 The latter is an array of DCHAR_T; SNPRINTF appends an
4897 array of TCHAR_T to it. This is possible because
4898 sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
4899 alignof (TCHAR_T) <= alignof (DCHAR_T). */
4900 # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
4901 /* Ensure that maxlen below will be >= 2. Needed on BeOS,
4902 where an snprintf() with maxlen==1 acts like sprintf(). */
4903 ENSURE_ALLOCATION (xsum (length,
4904 (2 + TCHARS_PER_DCHAR - 1)
4905 / TCHARS_PER_DCHAR));
4906 /* Prepare checking whether snprintf returns the count
4907 via %n. */
4908 *(TCHAR_T *) (result + length) = '\0';
4909 #endif
4911 orig_errno = errno;
4913 for (;;)
4915 int count = -1;
4917 #if USE_SNPRINTF
4918 int retcount = 0;
4919 size_t maxlen = allocated - length;
4920 /* SNPRINTF can fail if its second argument is
4921 > INT_MAX. */
4922 if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
4923 maxlen = INT_MAX / TCHARS_PER_DCHAR;
4924 maxlen = maxlen * TCHARS_PER_DCHAR;
4925 # define SNPRINTF_BUF(arg) \
4926 switch (prefix_count) \
4928 case 0: \
4929 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4930 maxlen, buf, \
4931 arg, &count); \
4932 break; \
4933 case 1: \
4934 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4935 maxlen, buf, \
4936 prefixes[0], arg, &count); \
4937 break; \
4938 case 2: \
4939 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4940 maxlen, buf, \
4941 prefixes[0], prefixes[1], arg, \
4942 &count); \
4943 break; \
4944 default: \
4945 abort (); \
4947 #else
4948 # define SNPRINTF_BUF(arg) \
4949 switch (prefix_count) \
4951 case 0: \
4952 count = sprintf (tmp, buf, arg); \
4953 break; \
4954 case 1: \
4955 count = sprintf (tmp, buf, prefixes[0], arg); \
4956 break; \
4957 case 2: \
4958 count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
4959 arg); \
4960 break; \
4961 default: \
4962 abort (); \
4964 #endif
4966 errno = 0;
4967 switch (type)
4969 case TYPE_SCHAR:
4971 int arg = a.arg[dp->arg_index].a.a_schar;
4972 SNPRINTF_BUF (arg);
4974 break;
4975 case TYPE_UCHAR:
4977 unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
4978 SNPRINTF_BUF (arg);
4980 break;
4981 case TYPE_SHORT:
4983 int arg = a.arg[dp->arg_index].a.a_short;
4984 SNPRINTF_BUF (arg);
4986 break;
4987 case TYPE_USHORT:
4989 unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
4990 SNPRINTF_BUF (arg);
4992 break;
4993 case TYPE_INT:
4995 int arg = a.arg[dp->arg_index].a.a_int;
4996 SNPRINTF_BUF (arg);
4998 break;
4999 case TYPE_UINT:
5001 unsigned int arg = a.arg[dp->arg_index].a.a_uint;
5002 SNPRINTF_BUF (arg);
5004 break;
5005 case TYPE_LONGINT:
5007 long int arg = a.arg[dp->arg_index].a.a_longint;
5008 SNPRINTF_BUF (arg);
5010 break;
5011 case TYPE_ULONGINT:
5013 unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
5014 SNPRINTF_BUF (arg);
5016 break;
5017 #if HAVE_LONG_LONG_INT
5018 case TYPE_LONGLONGINT:
5020 long long int arg = a.arg[dp->arg_index].a.a_longlongint;
5021 SNPRINTF_BUF (arg);
5023 break;
5024 case TYPE_ULONGLONGINT:
5026 unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
5027 SNPRINTF_BUF (arg);
5029 break;
5030 #endif
5031 case TYPE_DOUBLE:
5033 double arg = a.arg[dp->arg_index].a.a_double;
5034 SNPRINTF_BUF (arg);
5036 break;
5037 case TYPE_LONGDOUBLE:
5039 long double arg = a.arg[dp->arg_index].a.a_longdouble;
5040 SNPRINTF_BUF (arg);
5042 break;
5043 case TYPE_CHAR:
5045 int arg = a.arg[dp->arg_index].a.a_char;
5046 SNPRINTF_BUF (arg);
5048 break;
5049 #if HAVE_WINT_T
5050 case TYPE_WIDE_CHAR:
5052 wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
5053 SNPRINTF_BUF (arg);
5055 break;
5056 #endif
5057 case TYPE_STRING:
5059 const char *arg = a.arg[dp->arg_index].a.a_string;
5060 SNPRINTF_BUF (arg);
5062 break;
5063 #if HAVE_WCHAR_T
5064 case TYPE_WIDE_STRING:
5066 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
5067 SNPRINTF_BUF (arg);
5069 break;
5070 #endif
5071 case TYPE_POINTER:
5073 void *arg = a.arg[dp->arg_index].a.a_pointer;
5074 SNPRINTF_BUF (arg);
5076 break;
5077 default:
5078 abort ();
5081 #if USE_SNPRINTF
5082 /* Portability: Not all implementations of snprintf()
5083 are ISO C 99 compliant. Determine the number of
5084 bytes that snprintf() has produced or would have
5085 produced. */
5086 if (count >= 0)
5088 /* Verify that snprintf() has NUL-terminated its
5089 result. */
5090 if (count < maxlen
5091 && ((TCHAR_T *) (result + length)) [count] != '\0')
5092 abort ();
5093 /* Portability hack. */
5094 if (retcount > count)
5095 count = retcount;
5097 else
5099 /* snprintf() doesn't understand the '%n'
5100 directive. */
5101 if (fbp[1] != '\0')
5103 /* Don't use the '%n' directive; instead, look
5104 at the snprintf() return value. */
5105 fbp[1] = '\0';
5106 continue;
5108 else
5110 /* Look at the snprintf() return value. */
5111 if (retcount < 0)
5113 # if !HAVE_SNPRINTF_RETVAL_C99
5114 /* HP-UX 10.20 snprintf() is doubly deficient:
5115 It doesn't understand the '%n' directive,
5116 *and* it returns -1 (rather than the length
5117 that would have been required) when the
5118 buffer is too small.
5119 But a failure at this point can also come
5120 from other reasons than a too small buffer,
5121 such as an invalid wide string argument to
5122 the %ls directive, or possibly an invalid
5123 floating-point argument. */
5124 size_t tmp_length =
5125 MAX_ROOM_NEEDED (&a, dp->arg_index,
5126 dp->conversion, type, flags,
5127 width, has_precision,
5128 precision, pad_ourselves);
5130 if (maxlen < tmp_length)
5132 /* Make more room. But try to do through
5133 this reallocation only once. */
5134 size_t bigger_need =
5135 xsum (length,
5136 xsum (tmp_length,
5137 TCHARS_PER_DCHAR - 1)
5138 / TCHARS_PER_DCHAR);
5139 /* And always grow proportionally.
5140 (There may be several arguments, each
5141 needing a little more room than the
5142 previous one.) */
5143 size_t bigger_need2 =
5144 xsum (xtimes (allocated, 2), 12);
5145 if (bigger_need < bigger_need2)
5146 bigger_need = bigger_need2;
5147 ENSURE_ALLOCATION (bigger_need);
5148 continue;
5150 # endif
5152 else
5153 count = retcount;
5156 #endif
5158 /* Attempt to handle failure. */
5159 if (count < 0)
5161 /* SNPRINTF or sprintf failed. Save and use the errno
5162 that it has set, if any. */
5163 int saved_errno = errno;
5165 if (!(result == resultbuf || result == NULL))
5166 free (result);
5167 if (buf_malloced != NULL)
5168 free (buf_malloced);
5169 CLEANUP ();
5170 errno =
5171 (saved_errno != 0
5172 ? saved_errno
5173 : (dp->conversion == 'c' || dp->conversion == 's'
5174 ? EILSEQ
5175 : EINVAL));
5176 return NULL;
5179 #if USE_SNPRINTF
5180 /* Handle overflow of the allocated buffer.
5181 If such an overflow occurs, a C99 compliant snprintf()
5182 returns a count >= maxlen. However, a non-compliant
5183 snprintf() function returns only count = maxlen - 1. To
5184 cover both cases, test whether count >= maxlen - 1. */
5185 if ((unsigned int) count + 1 >= maxlen)
5187 /* If maxlen already has attained its allowed maximum,
5188 allocating more memory will not increase maxlen.
5189 Instead of looping, bail out. */
5190 if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
5191 goto overflow;
5192 else
5194 /* Need at least (count + 1) * sizeof (TCHAR_T)
5195 bytes. (The +1 is for the trailing NUL.)
5196 But ask for (count + 2) * sizeof (TCHAR_T)
5197 bytes, so that in the next round, we likely get
5198 maxlen > (unsigned int) count + 1
5199 and so we don't get here again.
5200 And allocate proportionally, to avoid looping
5201 eternally if snprintf() reports a too small
5202 count. */
5203 size_t n =
5204 xmax (xsum (length,
5205 ((unsigned int) count + 2
5206 + TCHARS_PER_DCHAR - 1)
5207 / TCHARS_PER_DCHAR),
5208 xtimes (allocated, 2));
5210 ENSURE_ALLOCATION (n);
5211 continue;
5214 #endif
5216 #if NEED_PRINTF_UNBOUNDED_PRECISION
5217 if (prec_ourselves)
5219 /* Handle the precision. */
5220 TCHAR_T *prec_ptr =
5221 # if USE_SNPRINTF
5222 (TCHAR_T *) (result + length);
5223 # else
5224 tmp;
5225 # endif
5226 size_t prefix_count;
5227 size_t move;
5229 prefix_count = 0;
5230 /* Put the additional zeroes after the sign. */
5231 if (count >= 1
5232 && (*prec_ptr == '-' || *prec_ptr == '+'
5233 || *prec_ptr == ' '))
5234 prefix_count = 1;
5235 /* Put the additional zeroes after the 0x prefix if
5236 (flags & FLAG_ALT) || (dp->conversion == 'p'). */
5237 else if (count >= 2
5238 && prec_ptr[0] == '0'
5239 && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
5240 prefix_count = 2;
5242 move = count - prefix_count;
5243 if (precision > move)
5245 /* Insert zeroes. */
5246 size_t insert = precision - move;
5247 TCHAR_T *prec_end;
5249 # if USE_SNPRINTF
5250 size_t n =
5251 xsum (length,
5252 (count + insert + TCHARS_PER_DCHAR - 1)
5253 / TCHARS_PER_DCHAR);
5254 length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5255 ENSURE_ALLOCATION (n);
5256 length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5257 prec_ptr = (TCHAR_T *) (result + length);
5258 # endif
5260 prec_end = prec_ptr + count;
5261 prec_ptr += prefix_count;
5263 while (prec_end > prec_ptr)
5265 prec_end--;
5266 prec_end[insert] = prec_end[0];
5269 prec_end += insert;
5271 *--prec_end = '0';
5272 while (prec_end > prec_ptr);
5274 count += insert;
5277 #endif
5279 #if !USE_SNPRINTF
5280 if (count >= tmp_length)
5281 /* tmp_length was incorrectly calculated - fix the
5282 code above! */
5283 abort ();
5284 #endif
5286 #if !DCHAR_IS_TCHAR
5287 /* Convert from TCHAR_T[] to DCHAR_T[]. */
5288 if (dp->conversion == 'c' || dp->conversion == 's')
5290 /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
5291 TYPE_WIDE_STRING.
5292 The result string is not certainly ASCII. */
5293 const TCHAR_T *tmpsrc;
5294 DCHAR_T *tmpdst;
5295 size_t tmpdst_len;
5296 /* This code assumes that TCHAR_T is 'char'. */
5297 verify (sizeof (TCHAR_T) == 1);
5298 # if USE_SNPRINTF
5299 tmpsrc = (TCHAR_T *) (result + length);
5300 # else
5301 tmpsrc = tmp;
5302 # endif
5303 tmpdst =
5304 DCHAR_CONV_FROM_ENCODING (locale_charset (),
5305 iconveh_question_mark,
5306 tmpsrc, count,
5307 NULL,
5308 NULL, &tmpdst_len);
5309 if (tmpdst == NULL)
5311 int saved_errno = errno;
5312 if (!(result == resultbuf || result == NULL))
5313 free (result);
5314 if (buf_malloced != NULL)
5315 free (buf_malloced);
5316 CLEANUP ();
5317 errno = saved_errno;
5318 return NULL;
5320 ENSURE_ALLOCATION (xsum (length, tmpdst_len));
5321 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
5322 free (tmpdst);
5323 count = tmpdst_len;
5325 else
5327 /* The result string is ASCII.
5328 Simple 1:1 conversion. */
5329 # if USE_SNPRINTF
5330 /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
5331 no-op conversion, in-place on the array starting
5332 at (result + length). */
5333 if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
5334 # endif
5336 const TCHAR_T *tmpsrc;
5337 DCHAR_T *tmpdst;
5338 size_t n;
5340 # if USE_SNPRINTF
5341 if (result == resultbuf)
5343 tmpsrc = (TCHAR_T *) (result + length);
5344 /* ENSURE_ALLOCATION will not move tmpsrc
5345 (because it's part of resultbuf). */
5346 ENSURE_ALLOCATION (xsum (length, count));
5348 else
5350 /* ENSURE_ALLOCATION will move the array
5351 (because it uses realloc(). */
5352 ENSURE_ALLOCATION (xsum (length, count));
5353 tmpsrc = (TCHAR_T *) (result + length);
5355 # else
5356 tmpsrc = tmp;
5357 ENSURE_ALLOCATION (xsum (length, count));
5358 # endif
5359 tmpdst = result + length;
5360 /* Copy backwards, because of overlapping. */
5361 tmpsrc += count;
5362 tmpdst += count;
5363 for (n = count; n > 0; n--)
5364 *--tmpdst = (unsigned char) *--tmpsrc;
5367 #endif
5369 #if DCHAR_IS_TCHAR && !USE_SNPRINTF
5370 /* Make room for the result. */
5371 if (count > allocated - length)
5373 /* Need at least count elements. But allocate
5374 proportionally. */
5375 size_t n =
5376 xmax (xsum (length, count), xtimes (allocated, 2));
5378 ENSURE_ALLOCATION (n);
5380 #endif
5382 /* Here count <= allocated - length. */
5384 /* Perform padding. */
5385 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5386 if (pad_ourselves && has_width)
5388 size_t w;
5389 # if ENABLE_UNISTDIO
5390 /* Outside POSIX, it's preferrable to compare the width
5391 against the number of _characters_ of the converted
5392 value. */
5393 w = DCHAR_MBSNLEN (result + length, count);
5394 # else
5395 /* The width is compared against the number of _bytes_
5396 of the converted value, says POSIX. */
5397 w = count;
5398 # endif
5399 if (w < width)
5401 size_t pad = width - w;
5403 /* Make room for the result. */
5404 if (xsum (count, pad) > allocated - length)
5406 /* Need at least count + pad elements. But
5407 allocate proportionally. */
5408 size_t n =
5409 xmax (xsum3 (length, count, pad),
5410 xtimes (allocated, 2));
5412 # if USE_SNPRINTF
5413 length += count;
5414 ENSURE_ALLOCATION (n);
5415 length -= count;
5416 # else
5417 ENSURE_ALLOCATION (n);
5418 # endif
5420 /* Here count + pad <= allocated - length. */
5423 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
5424 DCHAR_T * const rp = result + length;
5425 # else
5426 DCHAR_T * const rp = tmp;
5427 # endif
5428 DCHAR_T *p = rp + count;
5429 DCHAR_T *end = p + pad;
5430 DCHAR_T *pad_ptr;
5431 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
5432 if (dp->conversion == 'c'
5433 || dp->conversion == 's')
5434 /* No zero-padding for string directives. */
5435 pad_ptr = NULL;
5436 else
5437 # endif
5439 pad_ptr = (*rp == '-' ? rp + 1 : rp);
5440 /* No zero-padding of "inf" and "nan". */
5441 if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
5442 || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
5443 pad_ptr = NULL;
5445 /* The generated string now extends from rp to p,
5446 with the zero padding insertion point being at
5447 pad_ptr. */
5449 count = count + pad; /* = end - rp */
5451 if (flags & FLAG_LEFT)
5453 /* Pad with spaces on the right. */
5454 for (; pad > 0; pad--)
5455 *p++ = ' ';
5457 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
5459 /* Pad with zeroes. */
5460 DCHAR_T *q = end;
5462 while (p > pad_ptr)
5463 *--q = *--p;
5464 for (; pad > 0; pad--)
5465 *p++ = '0';
5467 else
5469 /* Pad with spaces on the left. */
5470 DCHAR_T *q = end;
5472 while (p > rp)
5473 *--q = *--p;
5474 for (; pad > 0; pad--)
5475 *p++ = ' ';
5480 #endif
5482 /* Here still count <= allocated - length. */
5484 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
5485 /* The snprintf() result did fit. */
5486 #else
5487 /* Append the sprintf() result. */
5488 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
5489 #endif
5490 #if !USE_SNPRINTF
5491 if (tmp != tmpbuf)
5492 free (tmp);
5493 #endif
5495 #if NEED_PRINTF_DIRECTIVE_F
5496 if (dp->conversion == 'F')
5498 /* Convert the %f result to upper case for %F. */
5499 DCHAR_T *rp = result + length;
5500 size_t rc;
5501 for (rc = count; rc > 0; rc--, rp++)
5502 if (*rp >= 'a' && *rp <= 'z')
5503 *rp = *rp - 'a' + 'A';
5505 #endif
5507 length += count;
5508 break;
5510 errno = orig_errno;
5511 #undef pad_ourselves
5512 #undef prec_ourselves
5517 /* Add the final NUL. */
5518 ENSURE_ALLOCATION (xsum (length, 1));
5519 result[length] = '\0';
5521 if (result != resultbuf && length + 1 < allocated)
5523 /* Shrink the allocated memory if possible. */
5524 DCHAR_T *memory;
5526 memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
5527 if (memory != NULL)
5528 result = memory;
5531 if (buf_malloced != NULL)
5532 free (buf_malloced);
5533 CLEANUP ();
5534 *lengthp = length;
5535 /* Note that we can produce a big string of a length > INT_MAX. POSIX
5536 says that snprintf() fails with errno = EOVERFLOW in this case, but
5537 that's only because snprintf() returns an 'int'. This function does
5538 not have this limitation. */
5539 return result;
5541 #if USE_SNPRINTF
5542 overflow:
5543 if (!(result == resultbuf || result == NULL))
5544 free (result);
5545 if (buf_malloced != NULL)
5546 free (buf_malloced);
5547 CLEANUP ();
5548 errno = EOVERFLOW;
5549 return NULL;
5550 #endif
5552 out_of_memory:
5553 if (!(result == resultbuf || result == NULL))
5554 free (result);
5555 if (buf_malloced != NULL)
5556 free (buf_malloced);
5557 out_of_memory_1:
5558 CLEANUP ();
5559 errno = ENOMEM;
5560 return NULL;
5564 #undef MAX_ROOM_NEEDED
5565 #undef TCHARS_PER_DCHAR
5566 #undef SNPRINTF
5567 #undef USE_SNPRINTF
5568 #undef DCHAR_SET
5569 #undef DCHAR_CPY
5570 #undef PRINTF_PARSE
5571 #undef DIRECTIVES
5572 #undef DIRECTIVE
5573 #undef DCHAR_IS_TCHAR
5574 #undef TCHAR_T
5575 #undef DCHAR_T
5576 #undef FCHAR_T
5577 #undef VASNPRINTF