corrected copyright notices
[gnutls.git] / gl / vasnprintf.c
blob0261661d4e45b6e7b960a8833e95e1a159c4940d
1 /* vsprintf with automatic memory allocation.
2 Copyright (C) 1999, 2002-2012 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, see <http://www.gnu.org/licenses/>. */
17 /* This file can be parametrized with the following macros:
18 VASNPRINTF The name of the function being defined.
19 FCHAR_T The element type of the format string.
20 DCHAR_T The element type of the destination (result) string.
21 FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
22 in the format string are ASCII. MUST be set if
23 FCHAR_T and DCHAR_T are not the same type.
24 DIRECTIVE Structure denoting a format directive.
25 Depends on FCHAR_T.
26 DIRECTIVES Structure denoting the set of format directives of a
27 format string. Depends on FCHAR_T.
28 PRINTF_PARSE Function that parses a format string.
29 Depends on FCHAR_T.
30 DCHAR_CPY memcpy like function for DCHAR_T[] arrays.
31 DCHAR_SET memset like function for DCHAR_T[] arrays.
32 DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays.
33 SNPRINTF The system's snprintf (or similar) function.
34 This may be either snprintf or swprintf.
35 TCHAR_T The element type of the argument and result string
36 of the said SNPRINTF function. This may be either
37 char or wchar_t. The code exploits that
38 sizeof (TCHAR_T) | sizeof (DCHAR_T) and
39 alignof (TCHAR_T) <= alignof (DCHAR_T).
40 DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type.
41 DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
42 DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t.
43 DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t.
44 DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */
46 /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
47 This must come before <config.h> because <config.h> may include
48 <features.h>, and once <features.h> has been included, it's too late. */
49 #ifndef _GNU_SOURCE
50 # define _GNU_SOURCE 1
51 #endif
53 #ifndef VASNPRINTF
54 # include <config.h>
55 #endif
56 #ifndef IN_LIBINTL
57 # include <alloca.h>
58 #endif
60 /* Specification. */
61 #ifndef VASNPRINTF
62 # if WIDE_CHAR_VERSION
63 # include "vasnwprintf.h"
64 # else
65 # include "vasnprintf.h"
66 # endif
67 #endif
69 #include <locale.h> /* localeconv() */
70 #include <stdio.h> /* snprintf(), sprintf() */
71 #include <stdlib.h> /* abort(), malloc(), realloc(), free() */
72 #include <string.h> /* memcpy(), strlen() */
73 #include <errno.h> /* errno */
74 #include <limits.h> /* CHAR_BIT */
75 #include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
76 #if HAVE_NL_LANGINFO
77 # include <langinfo.h>
78 #endif
79 #ifndef VASNPRINTF
80 # if WIDE_CHAR_VERSION
81 # include "wprintf-parse.h"
82 # else
83 # include "printf-parse.h"
84 # endif
85 #endif
87 /* Checked size_t computations. */
88 #include "xsize.h"
90 #include "verify.h"
92 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
93 # include <math.h>
94 # include "float+.h"
95 #endif
97 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
98 # include <math.h>
99 # include "isnand-nolibm.h"
100 #endif
102 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
103 # include <math.h>
104 # include "isnanl-nolibm.h"
105 # include "fpucw.h"
106 #endif
108 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
109 # include <math.h>
110 # include "isnand-nolibm.h"
111 # include "printf-frexp.h"
112 #endif
114 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
115 # include <math.h>
116 # include "isnanl-nolibm.h"
117 # include "printf-frexpl.h"
118 # include "fpucw.h"
119 #endif
121 /* Default parameters. */
122 #ifndef VASNPRINTF
123 # if WIDE_CHAR_VERSION
124 # define VASNPRINTF vasnwprintf
125 # define FCHAR_T wchar_t
126 # define DCHAR_T wchar_t
127 # define TCHAR_T wchar_t
128 # define DCHAR_IS_TCHAR 1
129 # define DIRECTIVE wchar_t_directive
130 # define DIRECTIVES wchar_t_directives
131 # define PRINTF_PARSE wprintf_parse
132 # define DCHAR_CPY wmemcpy
133 # define DCHAR_SET wmemset
134 # else
135 # define VASNPRINTF vasnprintf
136 # define FCHAR_T char
137 # define DCHAR_T char
138 # define TCHAR_T char
139 # define DCHAR_IS_TCHAR 1
140 # define DIRECTIVE char_directive
141 # define DIRECTIVES char_directives
142 # define PRINTF_PARSE printf_parse
143 # define DCHAR_CPY memcpy
144 # define DCHAR_SET memset
145 # endif
146 #endif
147 #if WIDE_CHAR_VERSION
148 /* TCHAR_T is wchar_t. */
149 # define USE_SNPRINTF 1
150 # if HAVE_DECL__SNWPRINTF
151 /* On Windows, the function swprintf() has a different signature than
152 on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
153 instead. The mingw function snwprintf() has fewer bugs than the
154 MSVCRT function _snwprintf(), so prefer that. */
155 # if defined __MINGW32__
156 # define SNPRINTF snwprintf
157 # else
158 # define SNPRINTF _snwprintf
159 # endif
160 # else
161 /* Unix. */
162 # define SNPRINTF swprintf
163 # endif
164 #else
165 /* TCHAR_T is char. */
166 /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
167 But don't use it on BeOS, since BeOS snprintf produces no output if the
168 size argument is >= 0x3000000.
169 Also don't use it on Linux libc5, since there snprintf with size = 1
170 writes any output without bounds, like sprintf. */
171 # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
172 # define USE_SNPRINTF 1
173 # else
174 # define USE_SNPRINTF 0
175 # endif
176 # if HAVE_DECL__SNPRINTF
177 /* Windows. The mingw function snprintf() has fewer bugs than the MSVCRT
178 function _snprintf(), so prefer that. */
179 # if defined __MINGW32__
180 # define SNPRINTF snprintf
181 /* Here we need to call the native snprintf, not rpl_snprintf. */
182 # undef snprintf
183 # else
184 # define SNPRINTF _snprintf
185 # endif
186 # else
187 /* Unix. */
188 # define SNPRINTF snprintf
189 /* Here we need to call the native snprintf, not rpl_snprintf. */
190 # undef snprintf
191 # endif
192 #endif
193 /* Here we need to call the native sprintf, not rpl_sprintf. */
194 #undef sprintf
196 /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
197 warnings in this file. Use -Dlint to suppress them. */
198 #ifdef lint
199 # define IF_LINT(Code) Code
200 #else
201 # define IF_LINT(Code) /* empty */
202 #endif
204 /* Avoid some warnings from "gcc -Wshadow".
205 This file doesn't use the exp() and remainder() functions. */
206 #undef exp
207 #define exp expo
208 #undef remainder
209 #define remainder rem
211 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION
212 # if (HAVE_STRNLEN && !defined _AIX)
213 # define local_strnlen strnlen
214 # else
215 # ifndef local_strnlen_defined
216 # define local_strnlen_defined 1
217 static size_t
218 local_strnlen (const char *string, size_t maxlen)
220 const char *end = memchr (string, '\0', maxlen);
221 return end ? (size_t) (end - string) : maxlen;
223 # endif
224 # endif
225 #endif
227 #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
228 # if HAVE_WCSLEN
229 # define local_wcslen wcslen
230 # else
231 /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
232 a dependency towards this library, here is a local substitute.
233 Define this substitute only once, even if this file is included
234 twice in the same compilation unit. */
235 # ifndef local_wcslen_defined
236 # define local_wcslen_defined 1
237 static size_t
238 local_wcslen (const wchar_t *s)
240 const wchar_t *ptr;
242 for (ptr = s; *ptr != (wchar_t) 0; ptr++)
244 return ptr - s;
246 # endif
247 # endif
248 #endif
250 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
251 # if HAVE_WCSNLEN
252 # define local_wcsnlen wcsnlen
253 # else
254 # ifndef local_wcsnlen_defined
255 # define local_wcsnlen_defined 1
256 static size_t
257 local_wcsnlen (const wchar_t *s, size_t maxlen)
259 const wchar_t *ptr;
261 for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
263 return ptr - s;
265 # endif
266 # endif
267 #endif
269 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
270 /* Determine the decimal-point character according to the current locale. */
271 # ifndef decimal_point_char_defined
272 # define decimal_point_char_defined 1
273 static char
274 decimal_point_char (void)
276 const char *point;
277 /* Determine it in a multithread-safe way. We know nl_langinfo is
278 multithread-safe on glibc systems and Mac OS X systems, but is not required
279 to be multithread-safe by POSIX. sprintf(), however, is multithread-safe.
280 localeconv() is rarely multithread-safe. */
281 # if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__))
282 point = nl_langinfo (RADIXCHAR);
283 # elif 1
284 char pointbuf[5];
285 sprintf (pointbuf, "%#.0f", 1.0);
286 point = &pointbuf[1];
287 # else
288 point = localeconv () -> decimal_point;
289 # endif
290 /* The decimal point is always a single byte: either '.' or ','. */
291 return (point[0] != '\0' ? point[0] : '.');
293 # endif
294 #endif
296 #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
298 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
299 static int
300 is_infinite_or_zero (double x)
302 return isnand (x) || x + x == x;
305 #endif
307 #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
309 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
310 static int
311 is_infinite_or_zerol (long double x)
313 return isnanl (x) || x + x == x;
316 #endif
318 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
320 /* Converting 'long double' to decimal without rare rounding bugs requires
321 real bignums. We use the naming conventions of GNU gmp, but vastly simpler
322 (and slower) algorithms. */
324 typedef unsigned int mp_limb_t;
325 # define GMP_LIMB_BITS 32
326 verify (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS);
328 typedef unsigned long long mp_twolimb_t;
329 # define GMP_TWOLIMB_BITS 64
330 verify (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS);
332 /* Representation of a bignum >= 0. */
333 typedef struct
335 size_t nlimbs;
336 mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */
337 } mpn_t;
339 /* Compute the product of two bignums >= 0.
340 Return the allocated memory in case of success, NULL in case of memory
341 allocation failure. */
342 static void *
343 multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
345 const mp_limb_t *p1;
346 const mp_limb_t *p2;
347 size_t len1;
348 size_t len2;
350 if (src1.nlimbs <= src2.nlimbs)
352 len1 = src1.nlimbs;
353 p1 = src1.limbs;
354 len2 = src2.nlimbs;
355 p2 = src2.limbs;
357 else
359 len1 = src2.nlimbs;
360 p1 = src2.limbs;
361 len2 = src1.nlimbs;
362 p2 = src1.limbs;
364 /* Now 0 <= len1 <= len2. */
365 if (len1 == 0)
367 /* src1 or src2 is zero. */
368 dest->nlimbs = 0;
369 dest->limbs = (mp_limb_t *) malloc (1);
371 else
373 /* Here 1 <= len1 <= len2. */
374 size_t dlen;
375 mp_limb_t *dp;
376 size_t k, i, j;
378 dlen = len1 + len2;
379 dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
380 if (dp == NULL)
381 return NULL;
382 for (k = len2; k > 0; )
383 dp[--k] = 0;
384 for (i = 0; i < len1; i++)
386 mp_limb_t digit1 = p1[i];
387 mp_twolimb_t carry = 0;
388 for (j = 0; j < len2; j++)
390 mp_limb_t digit2 = p2[j];
391 carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
392 carry += dp[i + j];
393 dp[i + j] = (mp_limb_t) carry;
394 carry = carry >> GMP_LIMB_BITS;
396 dp[i + len2] = (mp_limb_t) carry;
398 /* Normalise. */
399 while (dlen > 0 && dp[dlen - 1] == 0)
400 dlen--;
401 dest->nlimbs = dlen;
402 dest->limbs = dp;
404 return dest->limbs;
407 /* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
408 a is written as a = q * b + r with 0 <= r < b. q is the quotient, r
409 the remainder.
410 Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
411 q is incremented.
412 Return the allocated memory in case of success, NULL in case of memory
413 allocation failure. */
414 static void *
415 divide (mpn_t a, mpn_t b, mpn_t *q)
417 /* Algorithm:
418 First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
419 with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
420 If m<n, then q:=0 and r:=a.
421 If m>=n=1, perform a single-precision division:
422 r:=0, j:=m,
423 while j>0 do
424 {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
425 = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
426 j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
427 Normalise [q[m-1],...,q[0]], yields q.
428 If m>=n>1, perform a multiple-precision division:
429 We have a/b < beta^(m-n+1).
430 s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
431 Shift a and b left by s bits, copying them. r:=a.
432 r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
433 For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
434 Compute q* :
435 q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
436 In case of overflow (q* >= beta) set q* := beta-1.
437 Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
438 and c3 := b[n-2] * q*.
439 {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
440 occurred. Furthermore 0 <= c3 < beta^2.
441 If there was overflow and
442 r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
443 the next test can be skipped.}
444 While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
445 Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
446 If q* > 0:
447 Put r := r - b * q* * beta^j. In detail:
448 [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
449 hence: u:=0, for i:=0 to n-1 do
450 u := u + q* * b[i],
451 r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
452 u:=u div beta (+ 1, if carry in subtraction)
453 r[n+j]:=r[n+j]-u.
454 {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
455 < q* + 1 <= beta,
456 the carry u does not overflow.}
457 If a negative carry occurs, put q* := q* - 1
458 and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
459 Set q[j] := q*.
460 Normalise [q[m-n],..,q[0]]; this yields the quotient q.
461 Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
462 rest r.
463 The room for q[j] can be allocated at the memory location of r[n+j].
464 Finally, round-to-even:
465 Shift r left by 1 bit.
466 If r > b or if r = b and q[0] is odd, q := q+1.
468 const mp_limb_t *a_ptr = a.limbs;
469 size_t a_len = a.nlimbs;
470 const mp_limb_t *b_ptr = b.limbs;
471 size_t b_len = b.nlimbs;
472 mp_limb_t *roomptr;
473 mp_limb_t *tmp_roomptr = NULL;
474 mp_limb_t *q_ptr;
475 size_t q_len;
476 mp_limb_t *r_ptr;
477 size_t r_len;
479 /* Allocate room for a_len+2 digits.
480 (Need a_len+1 digits for the real division and 1 more digit for the
481 final rounding of q.) */
482 roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
483 if (roomptr == NULL)
484 return NULL;
486 /* Normalise a. */
487 while (a_len > 0 && a_ptr[a_len - 1] == 0)
488 a_len--;
490 /* Normalise b. */
491 for (;;)
493 if (b_len == 0)
494 /* Division by zero. */
495 abort ();
496 if (b_ptr[b_len - 1] == 0)
497 b_len--;
498 else
499 break;
502 /* Here m = a_len >= 0 and n = b_len > 0. */
504 if (a_len < b_len)
506 /* m<n: trivial case. q=0, r := copy of a. */
507 r_ptr = roomptr;
508 r_len = a_len;
509 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
510 q_ptr = roomptr + a_len;
511 q_len = 0;
513 else if (b_len == 1)
515 /* n=1: single precision division.
516 beta^(m-1) <= a < beta^m ==> beta^(m-2) <= a/b < beta^m */
517 r_ptr = roomptr;
518 q_ptr = roomptr + 1;
520 mp_limb_t den = b_ptr[0];
521 mp_limb_t remainder = 0;
522 const mp_limb_t *sourceptr = a_ptr + a_len;
523 mp_limb_t *destptr = q_ptr + a_len;
524 size_t count;
525 for (count = a_len; count > 0; count--)
527 mp_twolimb_t num =
528 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
529 *--destptr = num / den;
530 remainder = num % den;
532 /* Normalise and store r. */
533 if (remainder > 0)
535 r_ptr[0] = remainder;
536 r_len = 1;
538 else
539 r_len = 0;
540 /* Normalise q. */
541 q_len = a_len;
542 if (q_ptr[q_len - 1] == 0)
543 q_len--;
546 else
548 /* n>1: multiple precision division.
549 beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n ==>
550 beta^(m-n-1) <= a/b < beta^(m-n+1). */
551 /* Determine s. */
552 size_t s;
554 mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
555 /* Determine s = GMP_LIMB_BITS - integer_length (msd).
556 Code copied from gnulib's integer_length.c. */
557 # if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
558 s = __builtin_clz (msd);
559 # else
560 # if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
561 if (GMP_LIMB_BITS <= DBL_MANT_BIT)
563 /* Use 'double' operations.
564 Assumes an IEEE 754 'double' implementation. */
565 # define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
566 # define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1)
567 # define NWORDS \
568 ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
569 union { double value; unsigned int word[NWORDS]; } m;
571 /* Use a single integer to floating-point conversion. */
572 m.value = msd;
574 s = GMP_LIMB_BITS
575 - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK)
576 - DBL_EXP_BIAS);
578 else
579 # undef NWORDS
580 # endif
582 s = 31;
583 if (msd >= 0x10000)
585 msd = msd >> 16;
586 s -= 16;
588 if (msd >= 0x100)
590 msd = msd >> 8;
591 s -= 8;
593 if (msd >= 0x10)
595 msd = msd >> 4;
596 s -= 4;
598 if (msd >= 0x4)
600 msd = msd >> 2;
601 s -= 2;
603 if (msd >= 0x2)
605 msd = msd >> 1;
606 s -= 1;
609 # endif
611 /* 0 <= s < GMP_LIMB_BITS.
612 Copy b, shifting it left by s bits. */
613 if (s > 0)
615 tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
616 if (tmp_roomptr == NULL)
618 free (roomptr);
619 return NULL;
622 const mp_limb_t *sourceptr = b_ptr;
623 mp_limb_t *destptr = tmp_roomptr;
624 mp_twolimb_t accu = 0;
625 size_t count;
626 for (count = b_len; count > 0; count--)
628 accu += (mp_twolimb_t) *sourceptr++ << s;
629 *destptr++ = (mp_limb_t) accu;
630 accu = accu >> GMP_LIMB_BITS;
632 /* accu must be zero, since that was how s was determined. */
633 if (accu != 0)
634 abort ();
636 b_ptr = tmp_roomptr;
638 /* Copy a, shifting it left by s bits, yields r.
639 Memory layout:
640 At the beginning: r = roomptr[0..a_len],
641 at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len] */
642 r_ptr = roomptr;
643 if (s == 0)
645 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
646 r_ptr[a_len] = 0;
648 else
650 const mp_limb_t *sourceptr = a_ptr;
651 mp_limb_t *destptr = r_ptr;
652 mp_twolimb_t accu = 0;
653 size_t count;
654 for (count = a_len; count > 0; count--)
656 accu += (mp_twolimb_t) *sourceptr++ << s;
657 *destptr++ = (mp_limb_t) accu;
658 accu = accu >> GMP_LIMB_BITS;
660 *destptr++ = (mp_limb_t) accu;
662 q_ptr = roomptr + b_len;
663 q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
665 size_t j = a_len - b_len; /* m-n */
666 mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
667 mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
668 mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
669 ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
670 /* Division loop, traversed m-n+1 times.
671 j counts down, b is unchanged, beta/2 <= b[n-1] < beta. */
672 for (;;)
674 mp_limb_t q_star;
675 mp_limb_t c1;
676 if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
678 /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow. */
679 mp_twolimb_t num =
680 ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
681 | r_ptr[j + b_len - 1];
682 q_star = num / b_msd;
683 c1 = num % b_msd;
685 else
687 /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1]. */
688 q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
689 /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
690 <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
691 <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
692 {<= beta !}.
693 If yes, jump directly to the subtraction loop.
694 (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
695 <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
696 if (r_ptr[j + b_len] > b_msd
697 || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
698 /* r[j+n] >= b[n-1]+1 or
699 r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
700 carry. */
701 goto subtract;
703 /* q_star = q*,
704 c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta). */
706 mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
707 ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
708 mp_twolimb_t c3 = /* b[n-2] * q* */
709 (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
710 /* While c2 < c3, increase c2 and decrease c3.
711 Consider c3-c2. While it is > 0, decrease it by
712 b[n-1]*beta+b[n-2]. Because of b[n-1]*beta+b[n-2] >= beta^2/2
713 this can happen only twice. */
714 if (c3 > c2)
716 q_star = q_star - 1; /* q* := q* - 1 */
717 if (c3 - c2 > b_msdd)
718 q_star = q_star - 1; /* q* := q* - 1 */
721 if (q_star > 0)
722 subtract:
724 /* Subtract r := r - b * q* * beta^j. */
725 mp_limb_t cr;
727 const mp_limb_t *sourceptr = b_ptr;
728 mp_limb_t *destptr = r_ptr + j;
729 mp_twolimb_t carry = 0;
730 size_t count;
731 for (count = b_len; count > 0; count--)
733 /* Here 0 <= carry <= q*. */
734 carry =
735 carry
736 + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
737 + (mp_limb_t) ~(*destptr);
738 /* Here 0 <= carry <= beta*q* + beta-1. */
739 *destptr++ = ~(mp_limb_t) carry;
740 carry = carry >> GMP_LIMB_BITS; /* <= q* */
742 cr = (mp_limb_t) carry;
744 /* Subtract cr from r_ptr[j + b_len], then forget about
745 r_ptr[j + b_len]. */
746 if (cr > r_ptr[j + b_len])
748 /* Subtraction gave a carry. */
749 q_star = q_star - 1; /* q* := q* - 1 */
750 /* Add b back. */
752 const mp_limb_t *sourceptr = b_ptr;
753 mp_limb_t *destptr = r_ptr + j;
754 mp_limb_t carry = 0;
755 size_t count;
756 for (count = b_len; count > 0; count--)
758 mp_limb_t source1 = *sourceptr++;
759 mp_limb_t source2 = *destptr;
760 *destptr++ = source1 + source2 + carry;
761 carry =
762 (carry
763 ? source1 >= (mp_limb_t) ~source2
764 : source1 > (mp_limb_t) ~source2);
767 /* Forget about the carry and about r[j+n]. */
770 /* q* is determined. Store it as q[j]. */
771 q_ptr[j] = q_star;
772 if (j == 0)
773 break;
774 j--;
777 r_len = b_len;
778 /* Normalise q. */
779 if (q_ptr[q_len - 1] == 0)
780 q_len--;
781 # if 0 /* Not needed here, since we need r only to compare it with b/2, and
782 b is shifted left by s bits. */
783 /* Shift r right by s bits. */
784 if (s > 0)
786 mp_limb_t ptr = r_ptr + r_len;
787 mp_twolimb_t accu = 0;
788 size_t count;
789 for (count = r_len; count > 0; count--)
791 accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
792 accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
793 *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
796 # endif
797 /* Normalise r. */
798 while (r_len > 0 && r_ptr[r_len - 1] == 0)
799 r_len--;
801 /* Compare r << 1 with b. */
802 if (r_len > b_len)
803 goto increment_q;
805 size_t i;
806 for (i = b_len;;)
808 mp_limb_t r_i =
809 (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
810 | (i < r_len ? r_ptr[i] << 1 : 0);
811 mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
812 if (r_i > b_i)
813 goto increment_q;
814 if (r_i < b_i)
815 goto keep_q;
816 if (i == 0)
817 break;
818 i--;
821 if (q_len > 0 && ((q_ptr[0] & 1) != 0))
822 /* q is odd. */
823 increment_q:
825 size_t i;
826 for (i = 0; i < q_len; i++)
827 if (++(q_ptr[i]) != 0)
828 goto keep_q;
829 q_ptr[q_len++] = 1;
831 keep_q:
832 if (tmp_roomptr != NULL)
833 free (tmp_roomptr);
834 q->limbs = q_ptr;
835 q->nlimbs = q_len;
836 return roomptr;
839 /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
840 representation.
841 Destroys the contents of a.
842 Return the allocated memory - containing the decimal digits in low-to-high
843 order, terminated with a NUL character - in case of success, NULL in case
844 of memory allocation failure. */
845 static char *
846 convert_to_decimal (mpn_t a, size_t extra_zeroes)
848 mp_limb_t *a_ptr = a.limbs;
849 size_t a_len = a.nlimbs;
850 /* 0.03345 is slightly larger than log(2)/(9*log(10)). */
851 size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
852 char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes));
853 if (c_ptr != NULL)
855 char *d_ptr = c_ptr;
856 for (; extra_zeroes > 0; extra_zeroes--)
857 *d_ptr++ = '0';
858 while (a_len > 0)
860 /* Divide a by 10^9, in-place. */
861 mp_limb_t remainder = 0;
862 mp_limb_t *ptr = a_ptr + a_len;
863 size_t count;
864 for (count = a_len; count > 0; count--)
866 mp_twolimb_t num =
867 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
868 *ptr = num / 1000000000;
869 remainder = num % 1000000000;
871 /* Store the remainder as 9 decimal digits. */
872 for (count = 9; count > 0; count--)
874 *d_ptr++ = '0' + (remainder % 10);
875 remainder = remainder / 10;
877 /* Normalize a. */
878 if (a_ptr[a_len - 1] == 0)
879 a_len--;
881 /* Remove leading zeroes. */
882 while (d_ptr > c_ptr && d_ptr[-1] == '0')
883 d_ptr--;
884 /* But keep at least one zero. */
885 if (d_ptr == c_ptr)
886 *d_ptr++ = '0';
887 /* Terminate the string. */
888 *d_ptr = '\0';
890 return c_ptr;
893 # if NEED_PRINTF_LONG_DOUBLE
895 /* Assuming x is finite and >= 0:
896 write x as x = 2^e * m, where m is a bignum.
897 Return the allocated memory in case of success, NULL in case of memory
898 allocation failure. */
899 static void *
900 decode_long_double (long double x, int *ep, mpn_t *mp)
902 mpn_t m;
903 int exp;
904 long double y;
905 size_t i;
907 /* Allocate memory for result. */
908 m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
909 m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
910 if (m.limbs == NULL)
911 return NULL;
912 /* Split into exponential part and mantissa. */
913 y = frexpl (x, &exp);
914 if (!(y >= 0.0L && y < 1.0L))
915 abort ();
916 /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the
917 latter is an integer. */
918 /* Convert the mantissa (y * 2^LDBL_MANT_BIT) to a sequence of limbs.
919 I'm not sure whether it's safe to cast a 'long double' value between
920 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
921 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
922 doesn't matter). */
923 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
924 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
926 mp_limb_t hi, lo;
927 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
928 hi = (int) y;
929 y -= hi;
930 if (!(y >= 0.0L && y < 1.0L))
931 abort ();
932 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
933 lo = (int) y;
934 y -= lo;
935 if (!(y >= 0.0L && y < 1.0L))
936 abort ();
937 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
939 # else
941 mp_limb_t d;
942 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
943 d = (int) y;
944 y -= d;
945 if (!(y >= 0.0L && y < 1.0L))
946 abort ();
947 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
949 # endif
950 # endif
951 for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
953 mp_limb_t hi, lo;
954 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
955 hi = (int) y;
956 y -= hi;
957 if (!(y >= 0.0L && y < 1.0L))
958 abort ();
959 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
960 lo = (int) y;
961 y -= lo;
962 if (!(y >= 0.0L && y < 1.0L))
963 abort ();
964 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
966 # if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
967 precision. */
968 if (!(y == 0.0L))
969 abort ();
970 # endif
971 /* Normalise. */
972 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
973 m.nlimbs--;
974 *mp = m;
975 *ep = exp - LDBL_MANT_BIT;
976 return m.limbs;
979 # endif
981 # if NEED_PRINTF_DOUBLE
983 /* Assuming x is finite and >= 0:
984 write x as x = 2^e * m, where m is a bignum.
985 Return the allocated memory in case of success, NULL in case of memory
986 allocation failure. */
987 static void *
988 decode_double (double x, int *ep, mpn_t *mp)
990 mpn_t m;
991 int exp;
992 double y;
993 size_t i;
995 /* Allocate memory for result. */
996 m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
997 m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
998 if (m.limbs == NULL)
999 return NULL;
1000 /* Split into exponential part and mantissa. */
1001 y = frexp (x, &exp);
1002 if (!(y >= 0.0 && y < 1.0))
1003 abort ();
1004 /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * 2^DBL_MANT_BIT), and the
1005 latter is an integer. */
1006 /* Convert the mantissa (y * 2^DBL_MANT_BIT) to a sequence of limbs.
1007 I'm not sure whether it's safe to cast a 'double' value between
1008 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
1009 'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
1010 doesn't matter). */
1011 # if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
1012 # if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
1014 mp_limb_t hi, lo;
1015 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
1016 hi = (int) y;
1017 y -= hi;
1018 if (!(y >= 0.0 && y < 1.0))
1019 abort ();
1020 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1021 lo = (int) y;
1022 y -= lo;
1023 if (!(y >= 0.0 && y < 1.0))
1024 abort ();
1025 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1027 # else
1029 mp_limb_t d;
1030 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
1031 d = (int) y;
1032 y -= d;
1033 if (!(y >= 0.0 && y < 1.0))
1034 abort ();
1035 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
1037 # endif
1038 # endif
1039 for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1041 mp_limb_t hi, lo;
1042 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1043 hi = (int) y;
1044 y -= hi;
1045 if (!(y >= 0.0 && y < 1.0))
1046 abort ();
1047 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1048 lo = (int) y;
1049 y -= lo;
1050 if (!(y >= 0.0 && y < 1.0))
1051 abort ();
1052 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1054 if (!(y == 0.0))
1055 abort ();
1056 /* Normalise. */
1057 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
1058 m.nlimbs--;
1059 *mp = m;
1060 *ep = exp - DBL_MANT_BIT;
1061 return m.limbs;
1064 # endif
1066 /* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
1067 Returns the decimal representation of round (x * 10^n).
1068 Return the allocated memory - containing the decimal digits in low-to-high
1069 order, terminated with a NUL character - in case of success, NULL in case
1070 of memory allocation failure. */
1071 static char *
1072 scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
1074 int s;
1075 size_t extra_zeroes;
1076 unsigned int abs_n;
1077 unsigned int abs_s;
1078 mp_limb_t *pow5_ptr;
1079 size_t pow5_len;
1080 unsigned int s_limbs;
1081 unsigned int s_bits;
1082 mpn_t pow5;
1083 mpn_t z;
1084 void *z_memory;
1085 char *digits;
1087 if (memory == NULL)
1088 return NULL;
1089 /* x = 2^e * m, hence
1090 y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
1091 = round (2^s * 5^n * m). */
1092 s = e + n;
1093 extra_zeroes = 0;
1094 /* Factor out a common power of 10 if possible. */
1095 if (s > 0 && n > 0)
1097 extra_zeroes = (s < n ? s : n);
1098 s -= extra_zeroes;
1099 n -= extra_zeroes;
1101 /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
1102 Before converting to decimal, we need to compute
1103 z = round (2^s * 5^n * m). */
1104 /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
1105 sign. 2.322 is slightly larger than log(5)/log(2). */
1106 abs_n = (n >= 0 ? n : -n);
1107 abs_s = (s >= 0 ? s : -s);
1108 pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
1109 + abs_s / GMP_LIMB_BITS + 1)
1110 * sizeof (mp_limb_t));
1111 if (pow5_ptr == NULL)
1113 free (memory);
1114 return NULL;
1116 /* Initialize with 1. */
1117 pow5_ptr[0] = 1;
1118 pow5_len = 1;
1119 /* Multiply with 5^|n|. */
1120 if (abs_n > 0)
1122 static mp_limb_t const small_pow5[13 + 1] =
1124 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
1125 48828125, 244140625, 1220703125
1127 unsigned int n13;
1128 for (n13 = 0; n13 <= abs_n; n13 += 13)
1130 mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
1131 size_t j;
1132 mp_twolimb_t carry = 0;
1133 for (j = 0; j < pow5_len; j++)
1135 mp_limb_t digit2 = pow5_ptr[j];
1136 carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
1137 pow5_ptr[j] = (mp_limb_t) carry;
1138 carry = carry >> GMP_LIMB_BITS;
1140 if (carry > 0)
1141 pow5_ptr[pow5_len++] = (mp_limb_t) carry;
1144 s_limbs = abs_s / GMP_LIMB_BITS;
1145 s_bits = abs_s % GMP_LIMB_BITS;
1146 if (n >= 0 ? s >= 0 : s <= 0)
1148 /* Multiply with 2^|s|. */
1149 if (s_bits > 0)
1151 mp_limb_t *ptr = pow5_ptr;
1152 mp_twolimb_t accu = 0;
1153 size_t count;
1154 for (count = pow5_len; count > 0; count--)
1156 accu += (mp_twolimb_t) *ptr << s_bits;
1157 *ptr++ = (mp_limb_t) accu;
1158 accu = accu >> GMP_LIMB_BITS;
1160 if (accu > 0)
1162 *ptr = (mp_limb_t) accu;
1163 pow5_len++;
1166 if (s_limbs > 0)
1168 size_t count;
1169 for (count = pow5_len; count > 0;)
1171 count--;
1172 pow5_ptr[s_limbs + count] = pow5_ptr[count];
1174 for (count = s_limbs; count > 0;)
1176 count--;
1177 pow5_ptr[count] = 0;
1179 pow5_len += s_limbs;
1181 pow5.limbs = pow5_ptr;
1182 pow5.nlimbs = pow5_len;
1183 if (n >= 0)
1185 /* Multiply m with pow5. No division needed. */
1186 z_memory = multiply (m, pow5, &z);
1188 else
1190 /* Divide m by pow5 and round. */
1191 z_memory = divide (m, pow5, &z);
1194 else
1196 pow5.limbs = pow5_ptr;
1197 pow5.nlimbs = pow5_len;
1198 if (n >= 0)
1200 /* n >= 0, s < 0.
1201 Multiply m with pow5, then divide by 2^|s|. */
1202 mpn_t numerator;
1203 mpn_t denominator;
1204 void *tmp_memory;
1205 tmp_memory = multiply (m, pow5, &numerator);
1206 if (tmp_memory == NULL)
1208 free (pow5_ptr);
1209 free (memory);
1210 return NULL;
1212 /* Construct 2^|s|. */
1214 mp_limb_t *ptr = pow5_ptr + pow5_len;
1215 size_t i;
1216 for (i = 0; i < s_limbs; i++)
1217 ptr[i] = 0;
1218 ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
1219 denominator.limbs = ptr;
1220 denominator.nlimbs = s_limbs + 1;
1222 z_memory = divide (numerator, denominator, &z);
1223 free (tmp_memory);
1225 else
1227 /* n < 0, s > 0.
1228 Multiply m with 2^s, then divide by pow5. */
1229 mpn_t numerator;
1230 mp_limb_t *num_ptr;
1231 num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
1232 * sizeof (mp_limb_t));
1233 if (num_ptr == NULL)
1235 free (pow5_ptr);
1236 free (memory);
1237 return NULL;
1240 mp_limb_t *destptr = num_ptr;
1242 size_t i;
1243 for (i = 0; i < s_limbs; i++)
1244 *destptr++ = 0;
1246 if (s_bits > 0)
1248 const mp_limb_t *sourceptr = m.limbs;
1249 mp_twolimb_t accu = 0;
1250 size_t count;
1251 for (count = m.nlimbs; count > 0; count--)
1253 accu += (mp_twolimb_t) *sourceptr++ << s_bits;
1254 *destptr++ = (mp_limb_t) accu;
1255 accu = accu >> GMP_LIMB_BITS;
1257 if (accu > 0)
1258 *destptr++ = (mp_limb_t) accu;
1260 else
1262 const mp_limb_t *sourceptr = m.limbs;
1263 size_t count;
1264 for (count = m.nlimbs; count > 0; count--)
1265 *destptr++ = *sourceptr++;
1267 numerator.limbs = num_ptr;
1268 numerator.nlimbs = destptr - num_ptr;
1270 z_memory = divide (numerator, pow5, &z);
1271 free (num_ptr);
1274 free (pow5_ptr);
1275 free (memory);
1277 /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */
1279 if (z_memory == NULL)
1280 return NULL;
1281 digits = convert_to_decimal (z, extra_zeroes);
1282 free (z_memory);
1283 return digits;
1286 # if NEED_PRINTF_LONG_DOUBLE
1288 /* Assuming x is finite and >= 0, and n is an integer:
1289 Returns the decimal representation of round (x * 10^n).
1290 Return the allocated memory - containing the decimal digits in low-to-high
1291 order, terminated with a NUL character - in case of success, NULL in case
1292 of memory allocation failure. */
1293 static char *
1294 scale10_round_decimal_long_double (long double x, int n)
1296 int e IF_LINT(= 0);
1297 mpn_t m;
1298 void *memory = decode_long_double (x, &e, &m);
1299 return scale10_round_decimal_decoded (e, m, memory, n);
1302 # endif
1304 # if NEED_PRINTF_DOUBLE
1306 /* Assuming x is finite and >= 0, and n is an integer:
1307 Returns the decimal representation of round (x * 10^n).
1308 Return the allocated memory - containing the decimal digits in low-to-high
1309 order, terminated with a NUL character - in case of success, NULL in case
1310 of memory allocation failure. */
1311 static char *
1312 scale10_round_decimal_double (double x, int n)
1314 int e IF_LINT(= 0);
1315 mpn_t m;
1316 void *memory = decode_double (x, &e, &m);
1317 return scale10_round_decimal_decoded (e, m, memory, n);
1320 # endif
1322 # if NEED_PRINTF_LONG_DOUBLE
1324 /* Assuming x is finite and > 0:
1325 Return an approximation for n with 10^n <= x < 10^(n+1).
1326 The approximation is usually the right n, but may be off by 1 sometimes. */
1327 static int
1328 floorlog10l (long double x)
1330 int exp;
1331 long double y;
1332 double z;
1333 double l;
1335 /* Split into exponential part and mantissa. */
1336 y = frexpl (x, &exp);
1337 if (!(y >= 0.0L && y < 1.0L))
1338 abort ();
1339 if (y == 0.0L)
1340 return INT_MIN;
1341 if (y < 0.5L)
1343 while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1345 y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1346 exp -= GMP_LIMB_BITS;
1348 if (y < (1.0L / (1 << 16)))
1350 y *= 1.0L * (1 << 16);
1351 exp -= 16;
1353 if (y < (1.0L / (1 << 8)))
1355 y *= 1.0L * (1 << 8);
1356 exp -= 8;
1358 if (y < (1.0L / (1 << 4)))
1360 y *= 1.0L * (1 << 4);
1361 exp -= 4;
1363 if (y < (1.0L / (1 << 2)))
1365 y *= 1.0L * (1 << 2);
1366 exp -= 2;
1368 if (y < (1.0L / (1 << 1)))
1370 y *= 1.0L * (1 << 1);
1371 exp -= 1;
1374 if (!(y >= 0.5L && y < 1.0L))
1375 abort ();
1376 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1377 l = exp;
1378 z = y;
1379 if (z < 0.70710678118654752444)
1381 z *= 1.4142135623730950488;
1382 l -= 0.5;
1384 if (z < 0.8408964152537145431)
1386 z *= 1.1892071150027210667;
1387 l -= 0.25;
1389 if (z < 0.91700404320467123175)
1391 z *= 1.0905077326652576592;
1392 l -= 0.125;
1394 if (z < 0.9576032806985736469)
1396 z *= 1.0442737824274138403;
1397 l -= 0.0625;
1399 /* Now 0.95 <= z <= 1.01. */
1400 z = 1 - z;
1401 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1402 Four terms are enough to get an approximation with error < 10^-7. */
1403 l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1404 /* Finally multiply with log(2)/log(10), yields an approximation for
1405 log10(x). */
1406 l *= 0.30102999566398119523;
1407 /* Round down to the next integer. */
1408 return (int) l + (l < 0 ? -1 : 0);
1411 # endif
1413 # if NEED_PRINTF_DOUBLE
1415 /* Assuming x is finite and > 0:
1416 Return an approximation for n with 10^n <= x < 10^(n+1).
1417 The approximation is usually the right n, but may be off by 1 sometimes. */
1418 static int
1419 floorlog10 (double x)
1421 int exp;
1422 double y;
1423 double z;
1424 double l;
1426 /* Split into exponential part and mantissa. */
1427 y = frexp (x, &exp);
1428 if (!(y >= 0.0 && y < 1.0))
1429 abort ();
1430 if (y == 0.0)
1431 return INT_MIN;
1432 if (y < 0.5)
1434 while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1436 y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1437 exp -= GMP_LIMB_BITS;
1439 if (y < (1.0 / (1 << 16)))
1441 y *= 1.0 * (1 << 16);
1442 exp -= 16;
1444 if (y < (1.0 / (1 << 8)))
1446 y *= 1.0 * (1 << 8);
1447 exp -= 8;
1449 if (y < (1.0 / (1 << 4)))
1451 y *= 1.0 * (1 << 4);
1452 exp -= 4;
1454 if (y < (1.0 / (1 << 2)))
1456 y *= 1.0 * (1 << 2);
1457 exp -= 2;
1459 if (y < (1.0 / (1 << 1)))
1461 y *= 1.0 * (1 << 1);
1462 exp -= 1;
1465 if (!(y >= 0.5 && y < 1.0))
1466 abort ();
1467 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1468 l = exp;
1469 z = y;
1470 if (z < 0.70710678118654752444)
1472 z *= 1.4142135623730950488;
1473 l -= 0.5;
1475 if (z < 0.8408964152537145431)
1477 z *= 1.1892071150027210667;
1478 l -= 0.25;
1480 if (z < 0.91700404320467123175)
1482 z *= 1.0905077326652576592;
1483 l -= 0.125;
1485 if (z < 0.9576032806985736469)
1487 z *= 1.0442737824274138403;
1488 l -= 0.0625;
1490 /* Now 0.95 <= z <= 1.01. */
1491 z = 1 - z;
1492 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1493 Four terms are enough to get an approximation with error < 10^-7. */
1494 l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1495 /* Finally multiply with log(2)/log(10), yields an approximation for
1496 log10(x). */
1497 l *= 0.30102999566398119523;
1498 /* Round down to the next integer. */
1499 return (int) l + (l < 0 ? -1 : 0);
1502 # endif
1504 /* Tests whether a string of digits consists of exactly PRECISION zeroes and
1505 a single '1' digit. */
1506 static int
1507 is_borderline (const char *digits, size_t precision)
1509 for (; precision > 0; precision--, digits++)
1510 if (*digits != '0')
1511 return 0;
1512 if (*digits != '1')
1513 return 0;
1514 digits++;
1515 return *digits == '\0';
1518 #endif
1520 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99
1522 /* Use a different function name, to make it possible that the 'wchar_t'
1523 parametrization and the 'char' parametrization get compiled in the same
1524 translation unit. */
1525 # if WIDE_CHAR_VERSION
1526 # define MAX_ROOM_NEEDED wmax_room_needed
1527 # else
1528 # define MAX_ROOM_NEEDED max_room_needed
1529 # endif
1531 /* Returns the number of TCHAR_T units needed as temporary space for the result
1532 of sprintf or SNPRINTF of a single conversion directive. */
1533 static inline size_t
1534 MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
1535 arg_type type, int flags, size_t width, int has_precision,
1536 size_t precision, int pad_ourselves)
1538 size_t tmp_length;
1540 switch (conversion)
1542 case 'd': case 'i': case 'u':
1543 # if HAVE_LONG_LONG_INT
1544 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1545 tmp_length =
1546 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1547 * 0.30103 /* binary -> decimal */
1549 + 1; /* turn floor into ceil */
1550 else
1551 # endif
1552 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1553 tmp_length =
1554 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1555 * 0.30103 /* binary -> decimal */
1557 + 1; /* turn floor into ceil */
1558 else
1559 tmp_length =
1560 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1561 * 0.30103 /* binary -> decimal */
1563 + 1; /* turn floor into ceil */
1564 if (tmp_length < precision)
1565 tmp_length = precision;
1566 /* Multiply by 2, as an estimate for FLAG_GROUP. */
1567 tmp_length = xsum (tmp_length, tmp_length);
1568 /* Add 1, to account for a leading sign. */
1569 tmp_length = xsum (tmp_length, 1);
1570 break;
1572 case 'o':
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.333334 /* binary -> octal */
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.333334 /* binary -> octal */
1587 + 1; /* turn floor into ceil */
1588 else
1589 tmp_length =
1590 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1591 * 0.333334 /* binary -> octal */
1593 + 1; /* turn floor into ceil */
1594 if (tmp_length < precision)
1595 tmp_length = precision;
1596 /* Add 1, to account for a leading sign. */
1597 tmp_length = xsum (tmp_length, 1);
1598 break;
1600 case 'x': case 'X':
1601 # if HAVE_LONG_LONG_INT
1602 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1603 tmp_length =
1604 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1605 * 0.25 /* binary -> hexadecimal */
1607 + 1; /* turn floor into ceil */
1608 else
1609 # endif
1610 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1611 tmp_length =
1612 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1613 * 0.25 /* binary -> hexadecimal */
1615 + 1; /* turn floor into ceil */
1616 else
1617 tmp_length =
1618 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1619 * 0.25 /* binary -> hexadecimal */
1621 + 1; /* turn floor into ceil */
1622 if (tmp_length < precision)
1623 tmp_length = precision;
1624 /* Add 2, to account for a leading sign or alternate form. */
1625 tmp_length = xsum (tmp_length, 2);
1626 break;
1628 case 'f': case 'F':
1629 if (type == TYPE_LONGDOUBLE)
1630 tmp_length =
1631 (unsigned int) (LDBL_MAX_EXP
1632 * 0.30103 /* binary -> decimal */
1633 * 2 /* estimate for FLAG_GROUP */
1635 + 1 /* turn floor into ceil */
1636 + 10; /* sign, decimal point etc. */
1637 else
1638 tmp_length =
1639 (unsigned int) (DBL_MAX_EXP
1640 * 0.30103 /* binary -> decimal */
1641 * 2 /* estimate for FLAG_GROUP */
1643 + 1 /* turn floor into ceil */
1644 + 10; /* sign, decimal point etc. */
1645 tmp_length = xsum (tmp_length, precision);
1646 break;
1648 case 'e': case 'E': case 'g': case 'G':
1649 tmp_length =
1650 12; /* sign, decimal point, exponent etc. */
1651 tmp_length = xsum (tmp_length, precision);
1652 break;
1654 case 'a': case 'A':
1655 if (type == TYPE_LONGDOUBLE)
1656 tmp_length =
1657 (unsigned int) (LDBL_DIG
1658 * 0.831 /* decimal -> hexadecimal */
1660 + 1; /* turn floor into ceil */
1661 else
1662 tmp_length =
1663 (unsigned int) (DBL_DIG
1664 * 0.831 /* decimal -> hexadecimal */
1666 + 1; /* turn floor into ceil */
1667 if (tmp_length < precision)
1668 tmp_length = precision;
1669 /* Account for sign, decimal point etc. */
1670 tmp_length = xsum (tmp_length, 12);
1671 break;
1673 case 'c':
1674 # if HAVE_WINT_T && !WIDE_CHAR_VERSION
1675 if (type == TYPE_WIDE_CHAR)
1676 tmp_length = MB_CUR_MAX;
1677 else
1678 # endif
1679 tmp_length = 1;
1680 break;
1682 case 's':
1683 # if HAVE_WCHAR_T
1684 if (type == TYPE_WIDE_STRING)
1686 # if WIDE_CHAR_VERSION
1687 /* ISO C says about %ls in fwprintf:
1688 "If the precision is not specified or is greater than the size
1689 of the array, the array shall contain a null wide character."
1690 So if there is a precision, we must not use wcslen. */
1691 const wchar_t *arg = ap->arg[arg_index].a.a_wide_string;
1693 if (has_precision)
1694 tmp_length = local_wcsnlen (arg, precision);
1695 else
1696 tmp_length = local_wcslen (arg);
1697 # else
1698 /* ISO C says about %ls in fprintf:
1699 "If a precision is specified, no more than that many bytes are
1700 written (including shift sequences, if any), and the array
1701 shall contain a null wide character if, to equal the multibyte
1702 character sequence length given by the precision, the function
1703 would need to access a wide character one past the end of the
1704 array."
1705 So if there is a precision, we must not use wcslen. */
1706 /* This case has already been handled separately in VASNPRINTF. */
1707 abort ();
1708 # endif
1710 else
1711 # endif
1713 # if WIDE_CHAR_VERSION
1714 /* ISO C says about %s in fwprintf:
1715 "If the precision is not specified or is greater than the size
1716 of the converted array, the converted array shall contain a
1717 null wide character."
1718 So if there is a precision, we must not use strlen. */
1719 /* This case has already been handled separately in VASNPRINTF. */
1720 abort ();
1721 # else
1722 /* ISO C says about %s in fprintf:
1723 "If the precision is not specified or greater than the size of
1724 the array, the array shall contain a null character."
1725 So if there is a precision, we must not use strlen. */
1726 const char *arg = ap->arg[arg_index].a.a_string;
1728 if (has_precision)
1729 tmp_length = local_strnlen (arg, precision);
1730 else
1731 tmp_length = strlen (arg);
1732 # endif
1734 break;
1736 case 'p':
1737 tmp_length =
1738 (unsigned int) (sizeof (void *) * CHAR_BIT
1739 * 0.25 /* binary -> hexadecimal */
1741 + 1 /* turn floor into ceil */
1742 + 2; /* account for leading 0x */
1743 break;
1745 default:
1746 abort ();
1749 if (!pad_ourselves)
1751 # if ENABLE_UNISTDIO
1752 /* Padding considers the number of characters, therefore the number of
1753 elements after padding may be
1754 > max (tmp_length, width)
1755 but is certainly
1756 <= tmp_length + width. */
1757 tmp_length = xsum (tmp_length, width);
1758 # else
1759 /* Padding considers the number of elements, says POSIX. */
1760 if (tmp_length < width)
1761 tmp_length = width;
1762 # endif
1765 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
1767 return tmp_length;
1770 #endif
1772 DCHAR_T *
1773 VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
1774 const FCHAR_T *format, va_list args)
1776 DIRECTIVES d;
1777 arguments a;
1779 if (PRINTF_PARSE (format, &d, &a) < 0)
1780 /* errno is already set. */
1781 return NULL;
1783 #define CLEANUP() \
1784 if (d.dir != d.direct_alloc_dir) \
1785 free (d.dir); \
1786 if (a.arg != a.direct_alloc_arg) \
1787 free (a.arg);
1789 if (PRINTF_FETCHARGS (args, &a) < 0)
1791 CLEANUP ();
1792 errno = EINVAL;
1793 return NULL;
1797 size_t buf_neededlength;
1798 TCHAR_T *buf;
1799 TCHAR_T *buf_malloced;
1800 const FCHAR_T *cp;
1801 size_t i;
1802 DIRECTIVE *dp;
1803 /* Output string accumulator. */
1804 DCHAR_T *result;
1805 size_t allocated;
1806 size_t length;
1808 /* Allocate a small buffer that will hold a directive passed to
1809 sprintf or snprintf. */
1810 buf_neededlength =
1811 xsum4 (7, d.max_width_length, d.max_precision_length, 6);
1812 #if HAVE_ALLOCA
1813 if (buf_neededlength < 4000 / sizeof (TCHAR_T))
1815 buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
1816 buf_malloced = NULL;
1818 else
1819 #endif
1821 size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
1822 if (size_overflow_p (buf_memsize))
1823 goto out_of_memory_1;
1824 buf = (TCHAR_T *) malloc (buf_memsize);
1825 if (buf == NULL)
1826 goto out_of_memory_1;
1827 buf_malloced = buf;
1830 if (resultbuf != NULL)
1832 result = resultbuf;
1833 allocated = *lengthp;
1835 else
1837 result = NULL;
1838 allocated = 0;
1840 length = 0;
1841 /* Invariants:
1842 result is either == resultbuf or == NULL or malloc-allocated.
1843 If length > 0, then result != NULL. */
1845 /* Ensures that allocated >= needed. Aborts through a jump to
1846 out_of_memory if needed is SIZE_MAX or otherwise too big. */
1847 #define ENSURE_ALLOCATION(needed) \
1848 if ((needed) > allocated) \
1850 size_t memory_size; \
1851 DCHAR_T *memory; \
1853 allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \
1854 if ((needed) > allocated) \
1855 allocated = (needed); \
1856 memory_size = xtimes (allocated, sizeof (DCHAR_T)); \
1857 if (size_overflow_p (memory_size)) \
1858 goto out_of_memory; \
1859 if (result == resultbuf || result == NULL) \
1860 memory = (DCHAR_T *) malloc (memory_size); \
1861 else \
1862 memory = (DCHAR_T *) realloc (result, memory_size); \
1863 if (memory == NULL) \
1864 goto out_of_memory; \
1865 if (result == resultbuf && length > 0) \
1866 DCHAR_CPY (memory, result, length); \
1867 result = memory; \
1870 for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
1872 if (cp != dp->dir_start)
1874 size_t n = dp->dir_start - cp;
1875 size_t augmented_length = xsum (length, n);
1877 ENSURE_ALLOCATION (augmented_length);
1878 /* This copies a piece of FCHAR_T[] into a DCHAR_T[]. Here we
1879 need that the format string contains only ASCII characters
1880 if FCHAR_T and DCHAR_T are not the same type. */
1881 if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
1883 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
1884 length = augmented_length;
1886 else
1889 result[length++] = (unsigned char) *cp++;
1890 while (--n > 0);
1893 if (i == d.count)
1894 break;
1896 /* Execute a single directive. */
1897 if (dp->conversion == '%')
1899 size_t augmented_length;
1901 if (!(dp->arg_index == ARG_NONE))
1902 abort ();
1903 augmented_length = xsum (length, 1);
1904 ENSURE_ALLOCATION (augmented_length);
1905 result[length] = '%';
1906 length = augmented_length;
1908 else
1910 if (!(dp->arg_index != ARG_NONE))
1911 abort ();
1913 if (dp->conversion == 'n')
1915 switch (a.arg[dp->arg_index].type)
1917 case TYPE_COUNT_SCHAR_POINTER:
1918 *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
1919 break;
1920 case TYPE_COUNT_SHORT_POINTER:
1921 *a.arg[dp->arg_index].a.a_count_short_pointer = length;
1922 break;
1923 case TYPE_COUNT_INT_POINTER:
1924 *a.arg[dp->arg_index].a.a_count_int_pointer = length;
1925 break;
1926 case TYPE_COUNT_LONGINT_POINTER:
1927 *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
1928 break;
1929 #if HAVE_LONG_LONG_INT
1930 case TYPE_COUNT_LONGLONGINT_POINTER:
1931 *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
1932 break;
1933 #endif
1934 default:
1935 abort ();
1938 #if ENABLE_UNISTDIO
1939 /* The unistdio extensions. */
1940 else if (dp->conversion == 'U')
1942 arg_type type = a.arg[dp->arg_index].type;
1943 int flags = dp->flags;
1944 int has_width;
1945 size_t width;
1946 int has_precision;
1947 size_t precision;
1949 has_width = 0;
1950 width = 0;
1951 if (dp->width_start != dp->width_end)
1953 if (dp->width_arg_index != ARG_NONE)
1955 int arg;
1957 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
1958 abort ();
1959 arg = a.arg[dp->width_arg_index].a.a_int;
1960 if (arg < 0)
1962 /* "A negative field width is taken as a '-' flag
1963 followed by a positive field width." */
1964 flags |= FLAG_LEFT;
1965 width = (unsigned int) (-arg);
1967 else
1968 width = arg;
1970 else
1972 const FCHAR_T *digitp = dp->width_start;
1975 width = xsum (xtimes (width, 10), *digitp++ - '0');
1976 while (digitp != dp->width_end);
1978 has_width = 1;
1981 has_precision = 0;
1982 precision = 0;
1983 if (dp->precision_start != dp->precision_end)
1985 if (dp->precision_arg_index != ARG_NONE)
1987 int arg;
1989 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1990 abort ();
1991 arg = a.arg[dp->precision_arg_index].a.a_int;
1992 /* "A negative precision is taken as if the precision
1993 were omitted." */
1994 if (arg >= 0)
1996 precision = arg;
1997 has_precision = 1;
2000 else
2002 const FCHAR_T *digitp = dp->precision_start + 1;
2004 precision = 0;
2005 while (digitp != dp->precision_end)
2006 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2007 has_precision = 1;
2011 switch (type)
2013 case TYPE_U8_STRING:
2015 const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
2016 const uint8_t *arg_end;
2017 size_t characters;
2019 if (has_precision)
2021 /* Use only PRECISION characters, from the left. */
2022 arg_end = arg;
2023 characters = 0;
2024 for (; precision > 0; precision--)
2026 int count = u8_strmblen (arg_end);
2027 if (count == 0)
2028 break;
2029 if (count < 0)
2031 if (!(result == resultbuf || result == NULL))
2032 free (result);
2033 if (buf_malloced != NULL)
2034 free (buf_malloced);
2035 CLEANUP ();
2036 errno = EILSEQ;
2037 return NULL;
2039 arg_end += count;
2040 characters++;
2043 else if (has_width)
2045 /* Use the entire string, and count the number of
2046 characters. */
2047 arg_end = arg;
2048 characters = 0;
2049 for (;;)
2051 int count = u8_strmblen (arg_end);
2052 if (count == 0)
2053 break;
2054 if (count < 0)
2056 if (!(result == resultbuf || result == NULL))
2057 free (result);
2058 if (buf_malloced != NULL)
2059 free (buf_malloced);
2060 CLEANUP ();
2061 errno = EILSEQ;
2062 return NULL;
2064 arg_end += count;
2065 characters++;
2068 else
2070 /* Use the entire string. */
2071 arg_end = arg + u8_strlen (arg);
2072 /* The number of characters doesn't matter. */
2073 characters = 0;
2076 if (has_width && width > characters
2077 && !(dp->flags & FLAG_LEFT))
2079 size_t n = width - characters;
2080 ENSURE_ALLOCATION (xsum (length, n));
2081 DCHAR_SET (result + length, ' ', n);
2082 length += n;
2085 # if DCHAR_IS_UINT8_T
2087 size_t n = arg_end - arg;
2088 ENSURE_ALLOCATION (xsum (length, n));
2089 DCHAR_CPY (result + length, arg, n);
2090 length += n;
2092 # else
2093 { /* Convert. */
2094 DCHAR_T *converted = result + length;
2095 size_t converted_len = allocated - length;
2096 # if DCHAR_IS_TCHAR
2097 /* Convert from UTF-8 to locale encoding. */
2098 converted =
2099 u8_conv_to_encoding (locale_charset (),
2100 iconveh_question_mark,
2101 arg, arg_end - arg, NULL,
2102 converted, &converted_len);
2103 # else
2104 /* Convert from UTF-8 to UTF-16/UTF-32. */
2105 converted =
2106 U8_TO_DCHAR (arg, arg_end - arg,
2107 converted, &converted_len);
2108 # endif
2109 if (converted == NULL)
2111 int saved_errno = errno;
2112 if (!(result == resultbuf || result == NULL))
2113 free (result);
2114 if (buf_malloced != NULL)
2115 free (buf_malloced);
2116 CLEANUP ();
2117 errno = saved_errno;
2118 return NULL;
2120 if (converted != result + length)
2122 ENSURE_ALLOCATION (xsum (length, converted_len));
2123 DCHAR_CPY (result + length, converted, converted_len);
2124 free (converted);
2126 length += converted_len;
2128 # endif
2130 if (has_width && width > characters
2131 && (dp->flags & FLAG_LEFT))
2133 size_t n = width - characters;
2134 ENSURE_ALLOCATION (xsum (length, n));
2135 DCHAR_SET (result + length, ' ', n);
2136 length += n;
2139 break;
2141 case TYPE_U16_STRING:
2143 const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
2144 const uint16_t *arg_end;
2145 size_t characters;
2147 if (has_precision)
2149 /* Use only PRECISION characters, from the left. */
2150 arg_end = arg;
2151 characters = 0;
2152 for (; precision > 0; precision--)
2154 int count = u16_strmblen (arg_end);
2155 if (count == 0)
2156 break;
2157 if (count < 0)
2159 if (!(result == resultbuf || result == NULL))
2160 free (result);
2161 if (buf_malloced != NULL)
2162 free (buf_malloced);
2163 CLEANUP ();
2164 errno = EILSEQ;
2165 return NULL;
2167 arg_end += count;
2168 characters++;
2171 else if (has_width)
2173 /* Use the entire string, and count the number of
2174 characters. */
2175 arg_end = arg;
2176 characters = 0;
2177 for (;;)
2179 int count = u16_strmblen (arg_end);
2180 if (count == 0)
2181 break;
2182 if (count < 0)
2184 if (!(result == resultbuf || result == NULL))
2185 free (result);
2186 if (buf_malloced != NULL)
2187 free (buf_malloced);
2188 CLEANUP ();
2189 errno = EILSEQ;
2190 return NULL;
2192 arg_end += count;
2193 characters++;
2196 else
2198 /* Use the entire string. */
2199 arg_end = arg + u16_strlen (arg);
2200 /* The number of characters doesn't matter. */
2201 characters = 0;
2204 if (has_width && width > characters
2205 && !(dp->flags & FLAG_LEFT))
2207 size_t n = width - characters;
2208 ENSURE_ALLOCATION (xsum (length, n));
2209 DCHAR_SET (result + length, ' ', n);
2210 length += n;
2213 # if DCHAR_IS_UINT16_T
2215 size_t n = arg_end - arg;
2216 ENSURE_ALLOCATION (xsum (length, n));
2217 DCHAR_CPY (result + length, arg, n);
2218 length += n;
2220 # else
2221 { /* Convert. */
2222 DCHAR_T *converted = result + length;
2223 size_t converted_len = allocated - length;
2224 # if DCHAR_IS_TCHAR
2225 /* Convert from UTF-16 to locale encoding. */
2226 converted =
2227 u16_conv_to_encoding (locale_charset (),
2228 iconveh_question_mark,
2229 arg, arg_end - arg, NULL,
2230 converted, &converted_len);
2231 # else
2232 /* Convert from UTF-16 to UTF-8/UTF-32. */
2233 converted =
2234 U16_TO_DCHAR (arg, arg_end - arg,
2235 converted, &converted_len);
2236 # endif
2237 if (converted == NULL)
2239 int saved_errno = errno;
2240 if (!(result == resultbuf || result == NULL))
2241 free (result);
2242 if (buf_malloced != NULL)
2243 free (buf_malloced);
2244 CLEANUP ();
2245 errno = saved_errno;
2246 return NULL;
2248 if (converted != result + length)
2250 ENSURE_ALLOCATION (xsum (length, converted_len));
2251 DCHAR_CPY (result + length, converted, converted_len);
2252 free (converted);
2254 length += converted_len;
2256 # endif
2258 if (has_width && width > characters
2259 && (dp->flags & FLAG_LEFT))
2261 size_t n = width - characters;
2262 ENSURE_ALLOCATION (xsum (length, n));
2263 DCHAR_SET (result + length, ' ', n);
2264 length += n;
2267 break;
2269 case TYPE_U32_STRING:
2271 const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
2272 const uint32_t *arg_end;
2273 size_t characters;
2275 if (has_precision)
2277 /* Use only PRECISION characters, from the left. */
2278 arg_end = arg;
2279 characters = 0;
2280 for (; precision > 0; precision--)
2282 int count = u32_strmblen (arg_end);
2283 if (count == 0)
2284 break;
2285 if (count < 0)
2287 if (!(result == resultbuf || result == NULL))
2288 free (result);
2289 if (buf_malloced != NULL)
2290 free (buf_malloced);
2291 CLEANUP ();
2292 errno = EILSEQ;
2293 return NULL;
2295 arg_end += count;
2296 characters++;
2299 else if (has_width)
2301 /* Use the entire string, and count the number of
2302 characters. */
2303 arg_end = arg;
2304 characters = 0;
2305 for (;;)
2307 int count = u32_strmblen (arg_end);
2308 if (count == 0)
2309 break;
2310 if (count < 0)
2312 if (!(result == resultbuf || result == NULL))
2313 free (result);
2314 if (buf_malloced != NULL)
2315 free (buf_malloced);
2316 CLEANUP ();
2317 errno = EILSEQ;
2318 return NULL;
2320 arg_end += count;
2321 characters++;
2324 else
2326 /* Use the entire string. */
2327 arg_end = arg + u32_strlen (arg);
2328 /* The number of characters doesn't matter. */
2329 characters = 0;
2332 if (has_width && width > characters
2333 && !(dp->flags & FLAG_LEFT))
2335 size_t n = width - characters;
2336 ENSURE_ALLOCATION (xsum (length, n));
2337 DCHAR_SET (result + length, ' ', n);
2338 length += n;
2341 # if DCHAR_IS_UINT32_T
2343 size_t n = arg_end - arg;
2344 ENSURE_ALLOCATION (xsum (length, n));
2345 DCHAR_CPY (result + length, arg, n);
2346 length += n;
2348 # else
2349 { /* Convert. */
2350 DCHAR_T *converted = result + length;
2351 size_t converted_len = allocated - length;
2352 # if DCHAR_IS_TCHAR
2353 /* Convert from UTF-32 to locale encoding. */
2354 converted =
2355 u32_conv_to_encoding (locale_charset (),
2356 iconveh_question_mark,
2357 arg, arg_end - arg, NULL,
2358 converted, &converted_len);
2359 # else
2360 /* Convert from UTF-32 to UTF-8/UTF-16. */
2361 converted =
2362 U32_TO_DCHAR (arg, arg_end - arg,
2363 converted, &converted_len);
2364 # endif
2365 if (converted == NULL)
2367 int saved_errno = errno;
2368 if (!(result == resultbuf || result == NULL))
2369 free (result);
2370 if (buf_malloced != NULL)
2371 free (buf_malloced);
2372 CLEANUP ();
2373 errno = saved_errno;
2374 return NULL;
2376 if (converted != result + length)
2378 ENSURE_ALLOCATION (xsum (length, converted_len));
2379 DCHAR_CPY (result + length, converted, converted_len);
2380 free (converted);
2382 length += converted_len;
2384 # endif
2386 if (has_width && width > characters
2387 && (dp->flags & FLAG_LEFT))
2389 size_t n = width - characters;
2390 ENSURE_ALLOCATION (xsum (length, n));
2391 DCHAR_SET (result + length, ' ', n);
2392 length += n;
2395 break;
2397 default:
2398 abort ();
2401 #endif
2402 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
2403 else if (dp->conversion == 's'
2404 # if WIDE_CHAR_VERSION
2405 && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
2406 # else
2407 && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
2408 # endif
2411 /* The normal handling of the 's' directive below requires
2412 allocating a temporary buffer. The determination of its
2413 length (tmp_length), in the case when a precision is
2414 specified, below requires a conversion between a char[]
2415 string and a wchar_t[] wide string. It could be done, but
2416 we have no guarantee that the implementation of sprintf will
2417 use the exactly same algorithm. Without this guarantee, it
2418 is possible to have buffer overrun bugs. In order to avoid
2419 such bugs, we implement the entire processing of the 's'
2420 directive ourselves. */
2421 int flags = dp->flags;
2422 int has_width;
2423 size_t width;
2424 int has_precision;
2425 size_t precision;
2427 has_width = 0;
2428 width = 0;
2429 if (dp->width_start != dp->width_end)
2431 if (dp->width_arg_index != ARG_NONE)
2433 int arg;
2435 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2436 abort ();
2437 arg = a.arg[dp->width_arg_index].a.a_int;
2438 if (arg < 0)
2440 /* "A negative field width is taken as a '-' flag
2441 followed by a positive field width." */
2442 flags |= FLAG_LEFT;
2443 width = (unsigned int) (-arg);
2445 else
2446 width = arg;
2448 else
2450 const FCHAR_T *digitp = dp->width_start;
2453 width = xsum (xtimes (width, 10), *digitp++ - '0');
2454 while (digitp != dp->width_end);
2456 has_width = 1;
2459 has_precision = 0;
2460 precision = 6;
2461 if (dp->precision_start != dp->precision_end)
2463 if (dp->precision_arg_index != ARG_NONE)
2465 int arg;
2467 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2468 abort ();
2469 arg = a.arg[dp->precision_arg_index].a.a_int;
2470 /* "A negative precision is taken as if the precision
2471 were omitted." */
2472 if (arg >= 0)
2474 precision = arg;
2475 has_precision = 1;
2478 else
2480 const FCHAR_T *digitp = dp->precision_start + 1;
2482 precision = 0;
2483 while (digitp != dp->precision_end)
2484 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2485 has_precision = 1;
2489 # if WIDE_CHAR_VERSION
2490 /* %s in vasnwprintf. See the specification of fwprintf. */
2492 const char *arg = a.arg[dp->arg_index].a.a_string;
2493 const char *arg_end;
2494 size_t characters;
2496 if (has_precision)
2498 /* Use only as many bytes as needed to produce PRECISION
2499 wide characters, from the left. */
2500 # if HAVE_MBRTOWC
2501 mbstate_t state;
2502 memset (&state, '\0', sizeof (mbstate_t));
2503 # endif
2504 arg_end = arg;
2505 characters = 0;
2506 for (; precision > 0; precision--)
2508 int count;
2509 # if HAVE_MBRTOWC
2510 count = mbrlen (arg_end, MB_CUR_MAX, &state);
2511 # else
2512 count = mblen (arg_end, MB_CUR_MAX);
2513 # endif
2514 if (count == 0)
2515 /* Found the terminating NUL. */
2516 break;
2517 if (count < 0)
2519 /* Invalid or incomplete multibyte character. */
2520 if (!(result == resultbuf || result == NULL))
2521 free (result);
2522 if (buf_malloced != NULL)
2523 free (buf_malloced);
2524 CLEANUP ();
2525 errno = EILSEQ;
2526 return NULL;
2528 arg_end += count;
2529 characters++;
2532 else if (has_width)
2534 /* Use the entire string, and count the number of wide
2535 characters. */
2536 # if HAVE_MBRTOWC
2537 mbstate_t state;
2538 memset (&state, '\0', sizeof (mbstate_t));
2539 # endif
2540 arg_end = arg;
2541 characters = 0;
2542 for (;;)
2544 int count;
2545 # if HAVE_MBRTOWC
2546 count = mbrlen (arg_end, MB_CUR_MAX, &state);
2547 # else
2548 count = mblen (arg_end, MB_CUR_MAX);
2549 # endif
2550 if (count == 0)
2551 /* Found the terminating NUL. */
2552 break;
2553 if (count < 0)
2555 /* Invalid or incomplete multibyte character. */
2556 if (!(result == resultbuf || result == NULL))
2557 free (result);
2558 if (buf_malloced != NULL)
2559 free (buf_malloced);
2560 CLEANUP ();
2561 errno = EILSEQ;
2562 return NULL;
2564 arg_end += count;
2565 characters++;
2568 else
2570 /* Use the entire string. */
2571 arg_end = arg + strlen (arg);
2572 /* The number of characters doesn't matter. */
2573 characters = 0;
2576 if (has_width && width > characters
2577 && !(dp->flags & FLAG_LEFT))
2579 size_t n = width - characters;
2580 ENSURE_ALLOCATION (xsum (length, n));
2581 DCHAR_SET (result + length, ' ', n);
2582 length += n;
2585 if (has_precision || has_width)
2587 /* We know the number of wide characters in advance. */
2588 size_t remaining;
2589 # if HAVE_MBRTOWC
2590 mbstate_t state;
2591 memset (&state, '\0', sizeof (mbstate_t));
2592 # endif
2593 ENSURE_ALLOCATION (xsum (length, characters));
2594 for (remaining = characters; remaining > 0; remaining--)
2596 wchar_t wc;
2597 int count;
2598 # if HAVE_MBRTOWC
2599 count = mbrtowc (&wc, arg, arg_end - arg, &state);
2600 # else
2601 count = mbtowc (&wc, arg, arg_end - arg);
2602 # endif
2603 if (count <= 0)
2604 /* mbrtowc not consistent with mbrlen, or mbtowc
2605 not consistent with mblen. */
2606 abort ();
2607 result[length++] = wc;
2608 arg += count;
2610 if (!(arg == arg_end))
2611 abort ();
2613 else
2615 # if HAVE_MBRTOWC
2616 mbstate_t state;
2617 memset (&state, '\0', sizeof (mbstate_t));
2618 # endif
2619 while (arg < arg_end)
2621 wchar_t wc;
2622 int count;
2623 # if HAVE_MBRTOWC
2624 count = mbrtowc (&wc, arg, arg_end - arg, &state);
2625 # else
2626 count = mbtowc (&wc, arg, arg_end - arg);
2627 # endif
2628 if (count <= 0)
2629 /* mbrtowc not consistent with mbrlen, or mbtowc
2630 not consistent with mblen. */
2631 abort ();
2632 ENSURE_ALLOCATION (xsum (length, 1));
2633 result[length++] = wc;
2634 arg += count;
2638 if (has_width && width > characters
2639 && (dp->flags & FLAG_LEFT))
2641 size_t n = width - characters;
2642 ENSURE_ALLOCATION (xsum (length, n));
2643 DCHAR_SET (result + length, ' ', n);
2644 length += n;
2647 # else
2648 /* %ls in vasnprintf. See the specification of fprintf. */
2650 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
2651 const wchar_t *arg_end;
2652 size_t characters;
2653 # if !DCHAR_IS_TCHAR
2654 /* This code assumes that TCHAR_T is 'char'. */
2655 verify (sizeof (TCHAR_T) == 1);
2656 TCHAR_T *tmpsrc;
2657 DCHAR_T *tmpdst;
2658 size_t tmpdst_len;
2659 # endif
2660 size_t w;
2662 if (has_precision)
2664 /* Use only as many wide characters as needed to produce
2665 at most PRECISION bytes, from the left. */
2666 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2667 mbstate_t state;
2668 memset (&state, '\0', sizeof (mbstate_t));
2669 # endif
2670 arg_end = arg;
2671 characters = 0;
2672 while (precision > 0)
2674 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2675 int count;
2677 if (*arg_end == 0)
2678 /* Found the terminating null wide character. */
2679 break;
2680 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2681 count = wcrtomb (cbuf, *arg_end, &state);
2682 # else
2683 count = wctomb (cbuf, *arg_end);
2684 # endif
2685 if (count < 0)
2687 /* Cannot convert. */
2688 if (!(result == resultbuf || result == NULL))
2689 free (result);
2690 if (buf_malloced != NULL)
2691 free (buf_malloced);
2692 CLEANUP ();
2693 errno = EILSEQ;
2694 return NULL;
2696 if (precision < count)
2697 break;
2698 arg_end++;
2699 characters += count;
2700 precision -= count;
2703 # if DCHAR_IS_TCHAR
2704 else if (has_width)
2705 # else
2706 else
2707 # endif
2709 /* Use the entire string, and count the number of
2710 bytes. */
2711 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2712 mbstate_t state;
2713 memset (&state, '\0', sizeof (mbstate_t));
2714 # endif
2715 arg_end = arg;
2716 characters = 0;
2717 for (;;)
2719 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2720 int count;
2722 if (*arg_end == 0)
2723 /* Found the terminating null wide character. */
2724 break;
2725 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2726 count = wcrtomb (cbuf, *arg_end, &state);
2727 # else
2728 count = wctomb (cbuf, *arg_end);
2729 # endif
2730 if (count < 0)
2732 /* Cannot convert. */
2733 if (!(result == resultbuf || result == NULL))
2734 free (result);
2735 if (buf_malloced != NULL)
2736 free (buf_malloced);
2737 CLEANUP ();
2738 errno = EILSEQ;
2739 return NULL;
2741 arg_end++;
2742 characters += count;
2745 # if DCHAR_IS_TCHAR
2746 else
2748 /* Use the entire string. */
2749 arg_end = arg + local_wcslen (arg);
2750 /* The number of bytes doesn't matter. */
2751 characters = 0;
2753 # endif
2755 # if !DCHAR_IS_TCHAR
2756 /* Convert the string into a piece of temporary memory. */
2757 tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
2758 if (tmpsrc == NULL)
2759 goto out_of_memory;
2761 TCHAR_T *tmpptr = tmpsrc;
2762 size_t remaining;
2763 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2764 mbstate_t state;
2765 memset (&state, '\0', sizeof (mbstate_t));
2766 # endif
2767 for (remaining = characters; remaining > 0; )
2769 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2770 int count;
2772 if (*arg == 0)
2773 abort ();
2774 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2775 count = wcrtomb (cbuf, *arg, &state);
2776 # else
2777 count = wctomb (cbuf, *arg);
2778 # endif
2779 if (count <= 0)
2780 /* Inconsistency. */
2781 abort ();
2782 memcpy (tmpptr, cbuf, count);
2783 tmpptr += count;
2784 arg++;
2785 remaining -= count;
2787 if (!(arg == arg_end))
2788 abort ();
2791 /* Convert from TCHAR_T[] to DCHAR_T[]. */
2792 tmpdst =
2793 DCHAR_CONV_FROM_ENCODING (locale_charset (),
2794 iconveh_question_mark,
2795 tmpsrc, characters,
2796 NULL,
2797 NULL, &tmpdst_len);
2798 if (tmpdst == NULL)
2800 int saved_errno = errno;
2801 free (tmpsrc);
2802 if (!(result == resultbuf || result == NULL))
2803 free (result);
2804 if (buf_malloced != NULL)
2805 free (buf_malloced);
2806 CLEANUP ();
2807 errno = saved_errno;
2808 return NULL;
2810 free (tmpsrc);
2811 # endif
2813 if (has_width)
2815 # if ENABLE_UNISTDIO
2816 /* Outside POSIX, it's preferable to compare the width
2817 against the number of _characters_ of the converted
2818 value. */
2819 w = DCHAR_MBSNLEN (result + length, characters);
2820 # else
2821 /* The width is compared against the number of _bytes_
2822 of the converted value, says POSIX. */
2823 w = characters;
2824 # endif
2826 else
2827 /* w doesn't matter. */
2828 w = 0;
2830 if (has_width && width > w
2831 && !(dp->flags & FLAG_LEFT))
2833 size_t n = width - w;
2834 ENSURE_ALLOCATION (xsum (length, n));
2835 DCHAR_SET (result + length, ' ', n);
2836 length += n;
2839 # if DCHAR_IS_TCHAR
2840 if (has_precision || has_width)
2842 /* We know the number of bytes in advance. */
2843 size_t remaining;
2844 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2845 mbstate_t state;
2846 memset (&state, '\0', sizeof (mbstate_t));
2847 # endif
2848 ENSURE_ALLOCATION (xsum (length, characters));
2849 for (remaining = characters; remaining > 0; )
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)
2862 /* Inconsistency. */
2863 abort ();
2864 memcpy (result + length, cbuf, count);
2865 length += count;
2866 arg++;
2867 remaining -= count;
2869 if (!(arg == arg_end))
2870 abort ();
2872 else
2874 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2875 mbstate_t state;
2876 memset (&state, '\0', sizeof (mbstate_t));
2877 # endif
2878 while (arg < arg_end)
2880 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2881 int count;
2883 if (*arg == 0)
2884 abort ();
2885 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2886 count = wcrtomb (cbuf, *arg, &state);
2887 # else
2888 count = wctomb (cbuf, *arg);
2889 # endif
2890 if (count <= 0)
2892 /* Cannot convert. */
2893 if (!(result == resultbuf || result == NULL))
2894 free (result);
2895 if (buf_malloced != NULL)
2896 free (buf_malloced);
2897 CLEANUP ();
2898 errno = EILSEQ;
2899 return NULL;
2901 ENSURE_ALLOCATION (xsum (length, count));
2902 memcpy (result + length, cbuf, count);
2903 length += count;
2904 arg++;
2907 # else
2908 ENSURE_ALLOCATION (xsum (length, tmpdst_len));
2909 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
2910 free (tmpdst);
2911 length += tmpdst_len;
2912 # endif
2914 if (has_width && width > w
2915 && (dp->flags & FLAG_LEFT))
2917 size_t n = width - w;
2918 ENSURE_ALLOCATION (xsum (length, n));
2919 DCHAR_SET (result + length, ' ', n);
2920 length += n;
2923 # endif
2925 #endif
2926 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
2927 else if ((dp->conversion == 'a' || dp->conversion == 'A')
2928 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
2929 && (0
2930 # if NEED_PRINTF_DOUBLE
2931 || a.arg[dp->arg_index].type == TYPE_DOUBLE
2932 # endif
2933 # if NEED_PRINTF_LONG_DOUBLE
2934 || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2935 # endif
2937 # endif
2940 arg_type type = a.arg[dp->arg_index].type;
2941 int flags = dp->flags;
2942 int has_width;
2943 size_t width;
2944 int has_precision;
2945 size_t precision;
2946 size_t tmp_length;
2947 DCHAR_T tmpbuf[700];
2948 DCHAR_T *tmp;
2949 DCHAR_T *pad_ptr;
2950 DCHAR_T *p;
2952 has_width = 0;
2953 width = 0;
2954 if (dp->width_start != dp->width_end)
2956 if (dp->width_arg_index != ARG_NONE)
2958 int arg;
2960 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2961 abort ();
2962 arg = a.arg[dp->width_arg_index].a.a_int;
2963 if (arg < 0)
2965 /* "A negative field width is taken as a '-' flag
2966 followed by a positive field width." */
2967 flags |= FLAG_LEFT;
2968 width = (unsigned int) (-arg);
2970 else
2971 width = arg;
2973 else
2975 const FCHAR_T *digitp = dp->width_start;
2978 width = xsum (xtimes (width, 10), *digitp++ - '0');
2979 while (digitp != dp->width_end);
2981 has_width = 1;
2984 has_precision = 0;
2985 precision = 0;
2986 if (dp->precision_start != dp->precision_end)
2988 if (dp->precision_arg_index != ARG_NONE)
2990 int arg;
2992 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2993 abort ();
2994 arg = a.arg[dp->precision_arg_index].a.a_int;
2995 /* "A negative precision is taken as if the precision
2996 were omitted." */
2997 if (arg >= 0)
2999 precision = arg;
3000 has_precision = 1;
3003 else
3005 const FCHAR_T *digitp = dp->precision_start + 1;
3007 precision = 0;
3008 while (digitp != dp->precision_end)
3009 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3010 has_precision = 1;
3014 /* Allocate a temporary buffer of sufficient size. */
3015 if (type == TYPE_LONGDOUBLE)
3016 tmp_length =
3017 (unsigned int) ((LDBL_DIG + 1)
3018 * 0.831 /* decimal -> hexadecimal */
3020 + 1; /* turn floor into ceil */
3021 else
3022 tmp_length =
3023 (unsigned int) ((DBL_DIG + 1)
3024 * 0.831 /* decimal -> hexadecimal */
3026 + 1; /* turn floor into ceil */
3027 if (tmp_length < precision)
3028 tmp_length = precision;
3029 /* Account for sign, decimal point etc. */
3030 tmp_length = xsum (tmp_length, 12);
3032 if (tmp_length < width)
3033 tmp_length = width;
3035 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3037 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3038 tmp = tmpbuf;
3039 else
3041 size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3043 if (size_overflow_p (tmp_memsize))
3044 /* Overflow, would lead to out of memory. */
3045 goto out_of_memory;
3046 tmp = (DCHAR_T *) malloc (tmp_memsize);
3047 if (tmp == NULL)
3048 /* Out of memory. */
3049 goto out_of_memory;
3052 pad_ptr = NULL;
3053 p = tmp;
3054 if (type == TYPE_LONGDOUBLE)
3056 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
3057 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3059 if (isnanl (arg))
3061 if (dp->conversion == 'A')
3063 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3065 else
3067 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3070 else
3072 int sign = 0;
3073 DECL_LONG_DOUBLE_ROUNDING
3075 BEGIN_LONG_DOUBLE_ROUNDING ();
3077 if (signbit (arg)) /* arg < 0.0L or negative zero */
3079 sign = -1;
3080 arg = -arg;
3083 if (sign < 0)
3084 *p++ = '-';
3085 else if (flags & FLAG_SHOWSIGN)
3086 *p++ = '+';
3087 else if (flags & FLAG_SPACE)
3088 *p++ = ' ';
3090 if (arg > 0.0L && arg + arg == arg)
3092 if (dp->conversion == 'A')
3094 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3096 else
3098 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3101 else
3103 int exponent;
3104 long double mantissa;
3106 if (arg > 0.0L)
3107 mantissa = printf_frexpl (arg, &exponent);
3108 else
3110 exponent = 0;
3111 mantissa = 0.0L;
3114 if (has_precision
3115 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
3117 /* Round the mantissa. */
3118 long double tail = mantissa;
3119 size_t q;
3121 for (q = precision; ; q--)
3123 int digit = (int) tail;
3124 tail -= digit;
3125 if (q == 0)
3127 if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
3128 tail = 1 - tail;
3129 else
3130 tail = - tail;
3131 break;
3133 tail *= 16.0L;
3135 if (tail != 0.0L)
3136 for (q = precision; q > 0; q--)
3137 tail *= 0.0625L;
3138 mantissa += tail;
3141 *p++ = '0';
3142 *p++ = dp->conversion - 'A' + 'X';
3143 pad_ptr = p;
3145 int digit;
3147 digit = (int) mantissa;
3148 mantissa -= digit;
3149 *p++ = '0' + digit;
3150 if ((flags & FLAG_ALT)
3151 || mantissa > 0.0L || precision > 0)
3153 *p++ = decimal_point_char ();
3154 /* This loop terminates because we assume
3155 that FLT_RADIX is a power of 2. */
3156 while (mantissa > 0.0L)
3158 mantissa *= 16.0L;
3159 digit = (int) mantissa;
3160 mantissa -= digit;
3161 *p++ = digit
3162 + (digit < 10
3163 ? '0'
3164 : dp->conversion - 10);
3165 if (precision > 0)
3166 precision--;
3168 while (precision > 0)
3170 *p++ = '0';
3171 precision--;
3175 *p++ = dp->conversion - 'A' + 'P';
3176 # if WIDE_CHAR_VERSION
3178 static const wchar_t decimal_format[] =
3179 { '%', '+', 'd', '\0' };
3180 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3182 while (*p != '\0')
3183 p++;
3184 # else
3185 if (sizeof (DCHAR_T) == 1)
3187 sprintf ((char *) p, "%+d", exponent);
3188 while (*p != '\0')
3189 p++;
3191 else
3193 char expbuf[6 + 1];
3194 const char *ep;
3195 sprintf (expbuf, "%+d", exponent);
3196 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3197 p++;
3199 # endif
3202 END_LONG_DOUBLE_ROUNDING ();
3204 # else
3205 abort ();
3206 # endif
3208 else
3210 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
3211 double arg = a.arg[dp->arg_index].a.a_double;
3213 if (isnand (arg))
3215 if (dp->conversion == 'A')
3217 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3219 else
3221 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3224 else
3226 int sign = 0;
3228 if (signbit (arg)) /* arg < 0.0 or negative zero */
3230 sign = -1;
3231 arg = -arg;
3234 if (sign < 0)
3235 *p++ = '-';
3236 else if (flags & FLAG_SHOWSIGN)
3237 *p++ = '+';
3238 else if (flags & FLAG_SPACE)
3239 *p++ = ' ';
3241 if (arg > 0.0 && arg + arg == arg)
3243 if (dp->conversion == 'A')
3245 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3247 else
3249 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3252 else
3254 int exponent;
3255 double mantissa;
3257 if (arg > 0.0)
3258 mantissa = printf_frexp (arg, &exponent);
3259 else
3261 exponent = 0;
3262 mantissa = 0.0;
3265 if (has_precision
3266 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
3268 /* Round the mantissa. */
3269 double tail = mantissa;
3270 size_t q;
3272 for (q = precision; ; q--)
3274 int digit = (int) tail;
3275 tail -= digit;
3276 if (q == 0)
3278 if (digit & 1 ? tail >= 0.5 : tail > 0.5)
3279 tail = 1 - tail;
3280 else
3281 tail = - tail;
3282 break;
3284 tail *= 16.0;
3286 if (tail != 0.0)
3287 for (q = precision; q > 0; q--)
3288 tail *= 0.0625;
3289 mantissa += tail;
3292 *p++ = '0';
3293 *p++ = dp->conversion - 'A' + 'X';
3294 pad_ptr = p;
3296 int digit;
3298 digit = (int) mantissa;
3299 mantissa -= digit;
3300 *p++ = '0' + digit;
3301 if ((flags & FLAG_ALT)
3302 || mantissa > 0.0 || precision > 0)
3304 *p++ = decimal_point_char ();
3305 /* This loop terminates because we assume
3306 that FLT_RADIX is a power of 2. */
3307 while (mantissa > 0.0)
3309 mantissa *= 16.0;
3310 digit = (int) mantissa;
3311 mantissa -= digit;
3312 *p++ = digit
3313 + (digit < 10
3314 ? '0'
3315 : dp->conversion - 10);
3316 if (precision > 0)
3317 precision--;
3319 while (precision > 0)
3321 *p++ = '0';
3322 precision--;
3326 *p++ = dp->conversion - 'A' + 'P';
3327 # if WIDE_CHAR_VERSION
3329 static const wchar_t decimal_format[] =
3330 { '%', '+', 'd', '\0' };
3331 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3333 while (*p != '\0')
3334 p++;
3335 # else
3336 if (sizeof (DCHAR_T) == 1)
3338 sprintf ((char *) p, "%+d", exponent);
3339 while (*p != '\0')
3340 p++;
3342 else
3344 char expbuf[6 + 1];
3345 const char *ep;
3346 sprintf (expbuf, "%+d", exponent);
3347 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3348 p++;
3350 # endif
3353 # else
3354 abort ();
3355 # endif
3357 /* The generated string now extends from tmp to p, with the
3358 zero padding insertion point being at pad_ptr. */
3359 if (has_width && p - tmp < width)
3361 size_t pad = width - (p - tmp);
3362 DCHAR_T *end = p + pad;
3364 if (flags & FLAG_LEFT)
3366 /* Pad with spaces on the right. */
3367 for (; pad > 0; pad--)
3368 *p++ = ' ';
3370 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3372 /* Pad with zeroes. */
3373 DCHAR_T *q = end;
3375 while (p > pad_ptr)
3376 *--q = *--p;
3377 for (; pad > 0; pad--)
3378 *p++ = '0';
3380 else
3382 /* Pad with spaces on the left. */
3383 DCHAR_T *q = end;
3385 while (p > tmp)
3386 *--q = *--p;
3387 for (; pad > 0; pad--)
3388 *p++ = ' ';
3391 p = end;
3395 size_t count = p - tmp;
3397 if (count >= tmp_length)
3398 /* tmp_length was incorrectly calculated - fix the
3399 code above! */
3400 abort ();
3402 /* Make room for the result. */
3403 if (count >= allocated - length)
3405 size_t n = xsum (length, count);
3407 ENSURE_ALLOCATION (n);
3410 /* Append the result. */
3411 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3412 if (tmp != tmpbuf)
3413 free (tmp);
3414 length += count;
3417 #endif
3418 #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
3419 else if ((dp->conversion == 'f' || dp->conversion == 'F'
3420 || dp->conversion == 'e' || dp->conversion == 'E'
3421 || dp->conversion == 'g' || dp->conversion == 'G'
3422 || dp->conversion == 'a' || dp->conversion == 'A')
3423 && (0
3424 # if NEED_PRINTF_DOUBLE
3425 || a.arg[dp->arg_index].type == TYPE_DOUBLE
3426 # elif NEED_PRINTF_INFINITE_DOUBLE
3427 || (a.arg[dp->arg_index].type == TYPE_DOUBLE
3428 /* The systems (mingw) which produce wrong output
3429 for Inf, -Inf, and NaN also do so for -0.0.
3430 Therefore we treat this case here as well. */
3431 && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
3432 # endif
3433 # if NEED_PRINTF_LONG_DOUBLE
3434 || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3435 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
3436 || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3437 /* Some systems produce wrong output for Inf,
3438 -Inf, and NaN. Some systems in this category
3439 (IRIX 5.3) also do so for -0.0. Therefore we
3440 treat this case here as well. */
3441 && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
3442 # endif
3445 # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
3446 arg_type type = a.arg[dp->arg_index].type;
3447 # endif
3448 int flags = dp->flags;
3449 int has_width;
3450 size_t width;
3451 int has_precision;
3452 size_t precision;
3453 size_t tmp_length;
3454 DCHAR_T tmpbuf[700];
3455 DCHAR_T *tmp;
3456 DCHAR_T *pad_ptr;
3457 DCHAR_T *p;
3459 has_width = 0;
3460 width = 0;
3461 if (dp->width_start != dp->width_end)
3463 if (dp->width_arg_index != ARG_NONE)
3465 int arg;
3467 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3468 abort ();
3469 arg = a.arg[dp->width_arg_index].a.a_int;
3470 if (arg < 0)
3472 /* "A negative field width is taken as a '-' flag
3473 followed by a positive field width." */
3474 flags |= FLAG_LEFT;
3475 width = (unsigned int) (-arg);
3477 else
3478 width = arg;
3480 else
3482 const FCHAR_T *digitp = dp->width_start;
3485 width = xsum (xtimes (width, 10), *digitp++ - '0');
3486 while (digitp != dp->width_end);
3488 has_width = 1;
3491 has_precision = 0;
3492 precision = 0;
3493 if (dp->precision_start != dp->precision_end)
3495 if (dp->precision_arg_index != ARG_NONE)
3497 int arg;
3499 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3500 abort ();
3501 arg = a.arg[dp->precision_arg_index].a.a_int;
3502 /* "A negative precision is taken as if the precision
3503 were omitted." */
3504 if (arg >= 0)
3506 precision = arg;
3507 has_precision = 1;
3510 else
3512 const FCHAR_T *digitp = dp->precision_start + 1;
3514 precision = 0;
3515 while (digitp != dp->precision_end)
3516 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3517 has_precision = 1;
3521 /* POSIX specifies the default precision to be 6 for %f, %F,
3522 %e, %E, but not for %g, %G. Implementations appear to use
3523 the same default precision also for %g, %G. But for %a, %A,
3524 the default precision is 0. */
3525 if (!has_precision)
3526 if (!(dp->conversion == 'a' || dp->conversion == 'A'))
3527 precision = 6;
3529 /* Allocate a temporary buffer of sufficient size. */
3530 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3531 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
3532 # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3533 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
3534 # elif NEED_PRINTF_LONG_DOUBLE
3535 tmp_length = LDBL_DIG + 1;
3536 # elif NEED_PRINTF_DOUBLE
3537 tmp_length = DBL_DIG + 1;
3538 # else
3539 tmp_length = 0;
3540 # endif
3541 if (tmp_length < precision)
3542 tmp_length = precision;
3543 # if NEED_PRINTF_LONG_DOUBLE
3544 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3545 if (type == TYPE_LONGDOUBLE)
3546 # endif
3547 if (dp->conversion == 'f' || dp->conversion == 'F')
3549 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3550 if (!(isnanl (arg) || arg + arg == arg))
3552 /* arg is finite and nonzero. */
3553 int exponent = floorlog10l (arg < 0 ? -arg : arg);
3554 if (exponent >= 0 && tmp_length < exponent + precision)
3555 tmp_length = exponent + precision;
3558 # endif
3559 # if NEED_PRINTF_DOUBLE
3560 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3561 if (type == TYPE_DOUBLE)
3562 # endif
3563 if (dp->conversion == 'f' || dp->conversion == 'F')
3565 double arg = a.arg[dp->arg_index].a.a_double;
3566 if (!(isnand (arg) || arg + arg == arg))
3568 /* arg is finite and nonzero. */
3569 int exponent = floorlog10 (arg < 0 ? -arg : arg);
3570 if (exponent >= 0 && tmp_length < exponent + precision)
3571 tmp_length = exponent + precision;
3574 # endif
3575 /* Account for sign, decimal point etc. */
3576 tmp_length = xsum (tmp_length, 12);
3578 if (tmp_length < width)
3579 tmp_length = width;
3581 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3583 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3584 tmp = tmpbuf;
3585 else
3587 size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3589 if (size_overflow_p (tmp_memsize))
3590 /* Overflow, would lead to out of memory. */
3591 goto out_of_memory;
3592 tmp = (DCHAR_T *) malloc (tmp_memsize);
3593 if (tmp == NULL)
3594 /* Out of memory. */
3595 goto out_of_memory;
3598 pad_ptr = NULL;
3599 p = tmp;
3601 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3602 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3603 if (type == TYPE_LONGDOUBLE)
3604 # endif
3606 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3608 if (isnanl (arg))
3610 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3612 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3614 else
3616 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3619 else
3621 int sign = 0;
3622 DECL_LONG_DOUBLE_ROUNDING
3624 BEGIN_LONG_DOUBLE_ROUNDING ();
3626 if (signbit (arg)) /* arg < 0.0L or negative zero */
3628 sign = -1;
3629 arg = -arg;
3632 if (sign < 0)
3633 *p++ = '-';
3634 else if (flags & FLAG_SHOWSIGN)
3635 *p++ = '+';
3636 else if (flags & FLAG_SPACE)
3637 *p++ = ' ';
3639 if (arg > 0.0L && arg + arg == arg)
3641 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3643 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3645 else
3647 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3650 else
3652 # if NEED_PRINTF_LONG_DOUBLE
3653 pad_ptr = p;
3655 if (dp->conversion == 'f' || dp->conversion == 'F')
3657 char *digits;
3658 size_t ndigits;
3660 digits =
3661 scale10_round_decimal_long_double (arg, precision);
3662 if (digits == NULL)
3664 END_LONG_DOUBLE_ROUNDING ();
3665 goto out_of_memory;
3667 ndigits = strlen (digits);
3669 if (ndigits > precision)
3672 --ndigits;
3673 *p++ = digits[ndigits];
3675 while (ndigits > precision);
3676 else
3677 *p++ = '0';
3678 /* Here ndigits <= precision. */
3679 if ((flags & FLAG_ALT) || precision > 0)
3681 *p++ = decimal_point_char ();
3682 for (; precision > ndigits; precision--)
3683 *p++ = '0';
3684 while (ndigits > 0)
3686 --ndigits;
3687 *p++ = digits[ndigits];
3691 free (digits);
3693 else if (dp->conversion == 'e' || dp->conversion == 'E')
3695 int exponent;
3697 if (arg == 0.0L)
3699 exponent = 0;
3700 *p++ = '0';
3701 if ((flags & FLAG_ALT) || precision > 0)
3703 *p++ = decimal_point_char ();
3704 for (; precision > 0; precision--)
3705 *p++ = '0';
3708 else
3710 /* arg > 0.0L. */
3711 int adjusted;
3712 char *digits;
3713 size_t ndigits;
3715 exponent = floorlog10l (arg);
3716 adjusted = 0;
3717 for (;;)
3719 digits =
3720 scale10_round_decimal_long_double (arg,
3721 (int)precision - exponent);
3722 if (digits == NULL)
3724 END_LONG_DOUBLE_ROUNDING ();
3725 goto out_of_memory;
3727 ndigits = strlen (digits);
3729 if (ndigits == precision + 1)
3730 break;
3731 if (ndigits < precision
3732 || ndigits > precision + 2)
3733 /* The exponent was not guessed
3734 precisely enough. */
3735 abort ();
3736 if (adjusted)
3737 /* None of two values of exponent is
3738 the right one. Prevent an endless
3739 loop. */
3740 abort ();
3741 free (digits);
3742 if (ndigits == precision)
3743 exponent -= 1;
3744 else
3745 exponent += 1;
3746 adjusted = 1;
3748 /* Here ndigits = precision+1. */
3749 if (is_borderline (digits, precision))
3751 /* Maybe the exponent guess was too high
3752 and a smaller exponent can be reached
3753 by turning a 10...0 into 9...9x. */
3754 char *digits2 =
3755 scale10_round_decimal_long_double (arg,
3756 (int)precision - exponent + 1);
3757 if (digits2 == NULL)
3759 free (digits);
3760 END_LONG_DOUBLE_ROUNDING ();
3761 goto out_of_memory;
3763 if (strlen (digits2) == precision + 1)
3765 free (digits);
3766 digits = digits2;
3767 exponent -= 1;
3769 else
3770 free (digits2);
3772 /* Here ndigits = precision+1. */
3774 *p++ = digits[--ndigits];
3775 if ((flags & FLAG_ALT) || precision > 0)
3777 *p++ = decimal_point_char ();
3778 while (ndigits > 0)
3780 --ndigits;
3781 *p++ = digits[ndigits];
3785 free (digits);
3788 *p++ = dp->conversion; /* 'e' or 'E' */
3789 # if WIDE_CHAR_VERSION
3791 static const wchar_t decimal_format[] =
3792 { '%', '+', '.', '2', 'd', '\0' };
3793 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3795 while (*p != '\0')
3796 p++;
3797 # else
3798 if (sizeof (DCHAR_T) == 1)
3800 sprintf ((char *) p, "%+.2d", exponent);
3801 while (*p != '\0')
3802 p++;
3804 else
3806 char expbuf[6 + 1];
3807 const char *ep;
3808 sprintf (expbuf, "%+.2d", exponent);
3809 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3810 p++;
3812 # endif
3814 else if (dp->conversion == 'g' || dp->conversion == 'G')
3816 if (precision == 0)
3817 precision = 1;
3818 /* precision >= 1. */
3820 if (arg == 0.0L)
3821 /* The exponent is 0, >= -4, < precision.
3822 Use fixed-point notation. */
3824 size_t ndigits = precision;
3825 /* Number of trailing zeroes that have to be
3826 dropped. */
3827 size_t nzeroes =
3828 (flags & FLAG_ALT ? 0 : precision - 1);
3830 --ndigits;
3831 *p++ = '0';
3832 if ((flags & FLAG_ALT) || ndigits > nzeroes)
3834 *p++ = decimal_point_char ();
3835 while (ndigits > nzeroes)
3837 --ndigits;
3838 *p++ = '0';
3842 else
3844 /* arg > 0.0L. */
3845 int exponent;
3846 int adjusted;
3847 char *digits;
3848 size_t ndigits;
3849 size_t nzeroes;
3851 exponent = floorlog10l (arg);
3852 adjusted = 0;
3853 for (;;)
3855 digits =
3856 scale10_round_decimal_long_double (arg,
3857 (int)(precision - 1) - exponent);
3858 if (digits == NULL)
3860 END_LONG_DOUBLE_ROUNDING ();
3861 goto out_of_memory;
3863 ndigits = strlen (digits);
3865 if (ndigits == precision)
3866 break;
3867 if (ndigits < precision - 1
3868 || ndigits > precision + 1)
3869 /* The exponent was not guessed
3870 precisely enough. */
3871 abort ();
3872 if (adjusted)
3873 /* None of two values of exponent is
3874 the right one. Prevent an endless
3875 loop. */
3876 abort ();
3877 free (digits);
3878 if (ndigits < precision)
3879 exponent -= 1;
3880 else
3881 exponent += 1;
3882 adjusted = 1;
3884 /* Here ndigits = precision. */
3885 if (is_borderline (digits, precision - 1))
3887 /* Maybe the exponent guess was too high
3888 and a smaller exponent can be reached
3889 by turning a 10...0 into 9...9x. */
3890 char *digits2 =
3891 scale10_round_decimal_long_double (arg,
3892 (int)(precision - 1) - exponent + 1);
3893 if (digits2 == NULL)
3895 free (digits);
3896 END_LONG_DOUBLE_ROUNDING ();
3897 goto out_of_memory;
3899 if (strlen (digits2) == precision)
3901 free (digits);
3902 digits = digits2;
3903 exponent -= 1;
3905 else
3906 free (digits2);
3908 /* Here ndigits = precision. */
3910 /* Determine the number of trailing zeroes
3911 that have to be dropped. */
3912 nzeroes = 0;
3913 if ((flags & FLAG_ALT) == 0)
3914 while (nzeroes < ndigits
3915 && digits[nzeroes] == '0')
3916 nzeroes++;
3918 /* The exponent is now determined. */
3919 if (exponent >= -4
3920 && exponent < (long)precision)
3922 /* Fixed-point notation:
3923 max(exponent,0)+1 digits, then the
3924 decimal point, then the remaining
3925 digits without trailing zeroes. */
3926 if (exponent >= 0)
3928 size_t count = exponent + 1;
3929 /* Note: count <= precision = ndigits. */
3930 for (; count > 0; count--)
3931 *p++ = digits[--ndigits];
3932 if ((flags & FLAG_ALT) || ndigits > nzeroes)
3934 *p++ = decimal_point_char ();
3935 while (ndigits > nzeroes)
3937 --ndigits;
3938 *p++ = digits[ndigits];
3942 else
3944 size_t count = -exponent - 1;
3945 *p++ = '0';
3946 *p++ = decimal_point_char ();
3947 for (; count > 0; count--)
3948 *p++ = '0';
3949 while (ndigits > nzeroes)
3951 --ndigits;
3952 *p++ = digits[ndigits];
3956 else
3958 /* Exponential notation. */
3959 *p++ = digits[--ndigits];
3960 if ((flags & FLAG_ALT) || ndigits > nzeroes)
3962 *p++ = decimal_point_char ();
3963 while (ndigits > nzeroes)
3965 --ndigits;
3966 *p++ = digits[ndigits];
3969 *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3970 # if WIDE_CHAR_VERSION
3972 static const wchar_t decimal_format[] =
3973 { '%', '+', '.', '2', 'd', '\0' };
3974 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3976 while (*p != '\0')
3977 p++;
3978 # else
3979 if (sizeof (DCHAR_T) == 1)
3981 sprintf ((char *) p, "%+.2d", exponent);
3982 while (*p != '\0')
3983 p++;
3985 else
3987 char expbuf[6 + 1];
3988 const char *ep;
3989 sprintf (expbuf, "%+.2d", exponent);
3990 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3991 p++;
3993 # endif
3996 free (digits);
3999 else
4000 abort ();
4001 # else
4002 /* arg is finite. */
4003 if (!(arg == 0.0L))
4004 abort ();
4006 pad_ptr = p;
4008 if (dp->conversion == 'f' || dp->conversion == 'F')
4010 *p++ = '0';
4011 if ((flags & FLAG_ALT) || precision > 0)
4013 *p++ = decimal_point_char ();
4014 for (; precision > 0; precision--)
4015 *p++ = '0';
4018 else if (dp->conversion == 'e' || dp->conversion == 'E')
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; /* 'e' or 'E' */
4028 *p++ = '+';
4029 *p++ = '0';
4030 *p++ = '0';
4032 else if (dp->conversion == 'g' || dp->conversion == 'G')
4034 *p++ = '0';
4035 if (flags & FLAG_ALT)
4037 size_t ndigits =
4038 (precision > 0 ? precision - 1 : 0);
4039 *p++ = decimal_point_char ();
4040 for (; ndigits > 0; --ndigits)
4041 *p++ = '0';
4044 else if (dp->conversion == 'a' || dp->conversion == 'A')
4046 *p++ = '0';
4047 *p++ = dp->conversion - 'A' + 'X';
4048 pad_ptr = p;
4049 *p++ = '0';
4050 if ((flags & FLAG_ALT) || precision > 0)
4052 *p++ = decimal_point_char ();
4053 for (; precision > 0; precision--)
4054 *p++ = '0';
4056 *p++ = dp->conversion - 'A' + 'P';
4057 *p++ = '+';
4058 *p++ = '0';
4060 else
4061 abort ();
4062 # endif
4065 END_LONG_DOUBLE_ROUNDING ();
4068 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4069 else
4070 # endif
4071 # endif
4072 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4074 double arg = a.arg[dp->arg_index].a.a_double;
4076 if (isnand (arg))
4078 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4080 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4082 else
4084 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4087 else
4089 int sign = 0;
4091 if (signbit (arg)) /* arg < 0.0 or negative zero */
4093 sign = -1;
4094 arg = -arg;
4097 if (sign < 0)
4098 *p++ = '-';
4099 else if (flags & FLAG_SHOWSIGN)
4100 *p++ = '+';
4101 else if (flags & FLAG_SPACE)
4102 *p++ = ' ';
4104 if (arg > 0.0 && arg + arg == arg)
4106 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4108 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4110 else
4112 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4115 else
4117 # if NEED_PRINTF_DOUBLE
4118 pad_ptr = p;
4120 if (dp->conversion == 'f' || dp->conversion == 'F')
4122 char *digits;
4123 size_t ndigits;
4125 digits =
4126 scale10_round_decimal_double (arg, precision);
4127 if (digits == NULL)
4128 goto out_of_memory;
4129 ndigits = strlen (digits);
4131 if (ndigits > precision)
4134 --ndigits;
4135 *p++ = digits[ndigits];
4137 while (ndigits > precision);
4138 else
4139 *p++ = '0';
4140 /* Here ndigits <= precision. */
4141 if ((flags & FLAG_ALT) || precision > 0)
4143 *p++ = decimal_point_char ();
4144 for (; precision > ndigits; precision--)
4145 *p++ = '0';
4146 while (ndigits > 0)
4148 --ndigits;
4149 *p++ = digits[ndigits];
4153 free (digits);
4155 else if (dp->conversion == 'e' || dp->conversion == 'E')
4157 int exponent;
4159 if (arg == 0.0)
4161 exponent = 0;
4162 *p++ = '0';
4163 if ((flags & FLAG_ALT) || precision > 0)
4165 *p++ = decimal_point_char ();
4166 for (; precision > 0; precision--)
4167 *p++ = '0';
4170 else
4172 /* arg > 0.0. */
4173 int adjusted;
4174 char *digits;
4175 size_t ndigits;
4177 exponent = floorlog10 (arg);
4178 adjusted = 0;
4179 for (;;)
4181 digits =
4182 scale10_round_decimal_double (arg,
4183 (int)precision - exponent);
4184 if (digits == NULL)
4185 goto out_of_memory;
4186 ndigits = strlen (digits);
4188 if (ndigits == precision + 1)
4189 break;
4190 if (ndigits < precision
4191 || ndigits > precision + 2)
4192 /* The exponent was not guessed
4193 precisely enough. */
4194 abort ();
4195 if (adjusted)
4196 /* None of two values of exponent is
4197 the right one. Prevent an endless
4198 loop. */
4199 abort ();
4200 free (digits);
4201 if (ndigits == precision)
4202 exponent -= 1;
4203 else
4204 exponent += 1;
4205 adjusted = 1;
4207 /* Here ndigits = precision+1. */
4208 if (is_borderline (digits, precision))
4210 /* Maybe the exponent guess was too high
4211 and a smaller exponent can be reached
4212 by turning a 10...0 into 9...9x. */
4213 char *digits2 =
4214 scale10_round_decimal_double (arg,
4215 (int)precision - exponent + 1);
4216 if (digits2 == NULL)
4218 free (digits);
4219 goto out_of_memory;
4221 if (strlen (digits2) == precision + 1)
4223 free (digits);
4224 digits = digits2;
4225 exponent -= 1;
4227 else
4228 free (digits2);
4230 /* Here ndigits = precision+1. */
4232 *p++ = digits[--ndigits];
4233 if ((flags & FLAG_ALT) || precision > 0)
4235 *p++ = decimal_point_char ();
4236 while (ndigits > 0)
4238 --ndigits;
4239 *p++ = digits[ndigits];
4243 free (digits);
4246 *p++ = dp->conversion; /* 'e' or 'E' */
4247 # if WIDE_CHAR_VERSION
4249 static const wchar_t decimal_format[] =
4250 /* Produce the same number of exponent digits
4251 as the native printf implementation. */
4252 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4253 { '%', '+', '.', '3', 'd', '\0' };
4254 # else
4255 { '%', '+', '.', '2', 'd', '\0' };
4256 # endif
4257 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4259 while (*p != '\0')
4260 p++;
4261 # else
4263 static const char decimal_format[] =
4264 /* Produce the same number of exponent digits
4265 as the native printf implementation. */
4266 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4267 "%+.3d";
4268 # else
4269 "%+.2d";
4270 # endif
4271 if (sizeof (DCHAR_T) == 1)
4273 sprintf ((char *) p, decimal_format, exponent);
4274 while (*p != '\0')
4275 p++;
4277 else
4279 char expbuf[6 + 1];
4280 const char *ep;
4281 sprintf (expbuf, decimal_format, exponent);
4282 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4283 p++;
4286 # endif
4288 else if (dp->conversion == 'g' || dp->conversion == 'G')
4290 if (precision == 0)
4291 precision = 1;
4292 /* precision >= 1. */
4294 if (arg == 0.0)
4295 /* The exponent is 0, >= -4, < precision.
4296 Use fixed-point notation. */
4298 size_t ndigits = precision;
4299 /* Number of trailing zeroes that have to be
4300 dropped. */
4301 size_t nzeroes =
4302 (flags & FLAG_ALT ? 0 : precision - 1);
4304 --ndigits;
4305 *p++ = '0';
4306 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4308 *p++ = decimal_point_char ();
4309 while (ndigits > nzeroes)
4311 --ndigits;
4312 *p++ = '0';
4316 else
4318 /* arg > 0.0. */
4319 int exponent;
4320 int adjusted;
4321 char *digits;
4322 size_t ndigits;
4323 size_t nzeroes;
4325 exponent = floorlog10 (arg);
4326 adjusted = 0;
4327 for (;;)
4329 digits =
4330 scale10_round_decimal_double (arg,
4331 (int)(precision - 1) - exponent);
4332 if (digits == NULL)
4333 goto out_of_memory;
4334 ndigits = strlen (digits);
4336 if (ndigits == precision)
4337 break;
4338 if (ndigits < precision - 1
4339 || ndigits > precision + 1)
4340 /* The exponent was not guessed
4341 precisely enough. */
4342 abort ();
4343 if (adjusted)
4344 /* None of two values of exponent is
4345 the right one. Prevent an endless
4346 loop. */
4347 abort ();
4348 free (digits);
4349 if (ndigits < precision)
4350 exponent -= 1;
4351 else
4352 exponent += 1;
4353 adjusted = 1;
4355 /* Here ndigits = precision. */
4356 if (is_borderline (digits, precision - 1))
4358 /* Maybe the exponent guess was too high
4359 and a smaller exponent can be reached
4360 by turning a 10...0 into 9...9x. */
4361 char *digits2 =
4362 scale10_round_decimal_double (arg,
4363 (int)(precision - 1) - exponent + 1);
4364 if (digits2 == NULL)
4366 free (digits);
4367 goto out_of_memory;
4369 if (strlen (digits2) == precision)
4371 free (digits);
4372 digits = digits2;
4373 exponent -= 1;
4375 else
4376 free (digits2);
4378 /* Here ndigits = precision. */
4380 /* Determine the number of trailing zeroes
4381 that have to be dropped. */
4382 nzeroes = 0;
4383 if ((flags & FLAG_ALT) == 0)
4384 while (nzeroes < ndigits
4385 && digits[nzeroes] == '0')
4386 nzeroes++;
4388 /* The exponent is now determined. */
4389 if (exponent >= -4
4390 && exponent < (long)precision)
4392 /* Fixed-point notation:
4393 max(exponent,0)+1 digits, then the
4394 decimal point, then the remaining
4395 digits without trailing zeroes. */
4396 if (exponent >= 0)
4398 size_t count = exponent + 1;
4399 /* Note: count <= precision = ndigits. */
4400 for (; count > 0; count--)
4401 *p++ = digits[--ndigits];
4402 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4404 *p++ = decimal_point_char ();
4405 while (ndigits > nzeroes)
4407 --ndigits;
4408 *p++ = digits[ndigits];
4412 else
4414 size_t count = -exponent - 1;
4415 *p++ = '0';
4416 *p++ = decimal_point_char ();
4417 for (; count > 0; count--)
4418 *p++ = '0';
4419 while (ndigits > nzeroes)
4421 --ndigits;
4422 *p++ = digits[ndigits];
4426 else
4428 /* Exponential notation. */
4429 *p++ = digits[--ndigits];
4430 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4432 *p++ = decimal_point_char ();
4433 while (ndigits > nzeroes)
4435 --ndigits;
4436 *p++ = digits[ndigits];
4439 *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4440 # if WIDE_CHAR_VERSION
4442 static const wchar_t decimal_format[] =
4443 /* Produce the same number of exponent digits
4444 as the native printf implementation. */
4445 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4446 { '%', '+', '.', '3', 'd', '\0' };
4447 # else
4448 { '%', '+', '.', '2', 'd', '\0' };
4449 # endif
4450 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4452 while (*p != '\0')
4453 p++;
4454 # else
4456 static const char decimal_format[] =
4457 /* Produce the same number of exponent digits
4458 as the native printf implementation. */
4459 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4460 "%+.3d";
4461 # else
4462 "%+.2d";
4463 # endif
4464 if (sizeof (DCHAR_T) == 1)
4466 sprintf ((char *) p, decimal_format, exponent);
4467 while (*p != '\0')
4468 p++;
4470 else
4472 char expbuf[6 + 1];
4473 const char *ep;
4474 sprintf (expbuf, decimal_format, exponent);
4475 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4476 p++;
4479 # endif
4482 free (digits);
4485 else
4486 abort ();
4487 # else
4488 /* arg is finite. */
4489 if (!(arg == 0.0))
4490 abort ();
4492 pad_ptr = p;
4494 if (dp->conversion == 'f' || dp->conversion == 'F')
4496 *p++ = '0';
4497 if ((flags & FLAG_ALT) || precision > 0)
4499 *p++ = decimal_point_char ();
4500 for (; precision > 0; precision--)
4501 *p++ = '0';
4504 else if (dp->conversion == 'e' || dp->conversion == 'E')
4506 *p++ = '0';
4507 if ((flags & FLAG_ALT) || precision > 0)
4509 *p++ = decimal_point_char ();
4510 for (; precision > 0; precision--)
4511 *p++ = '0';
4513 *p++ = dp->conversion; /* 'e' or 'E' */
4514 *p++ = '+';
4515 /* Produce the same number of exponent digits as
4516 the native printf implementation. */
4517 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4518 *p++ = '0';
4519 # endif
4520 *p++ = '0';
4521 *p++ = '0';
4523 else if (dp->conversion == 'g' || dp->conversion == 'G')
4525 *p++ = '0';
4526 if (flags & FLAG_ALT)
4528 size_t ndigits =
4529 (precision > 0 ? precision - 1 : 0);
4530 *p++ = decimal_point_char ();
4531 for (; ndigits > 0; --ndigits)
4532 *p++ = '0';
4535 else
4536 abort ();
4537 # endif
4541 # endif
4543 /* The generated string now extends from tmp to p, with the
4544 zero padding insertion point being at pad_ptr. */
4545 if (has_width && p - tmp < width)
4547 size_t pad = width - (p - tmp);
4548 DCHAR_T *end = p + pad;
4550 if (flags & FLAG_LEFT)
4552 /* Pad with spaces on the right. */
4553 for (; pad > 0; pad--)
4554 *p++ = ' ';
4556 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4558 /* Pad with zeroes. */
4559 DCHAR_T *q = end;
4561 while (p > pad_ptr)
4562 *--q = *--p;
4563 for (; pad > 0; pad--)
4564 *p++ = '0';
4566 else
4568 /* Pad with spaces on the left. */
4569 DCHAR_T *q = end;
4571 while (p > tmp)
4572 *--q = *--p;
4573 for (; pad > 0; pad--)
4574 *p++ = ' ';
4577 p = end;
4581 size_t count = p - tmp;
4583 if (count >= tmp_length)
4584 /* tmp_length was incorrectly calculated - fix the
4585 code above! */
4586 abort ();
4588 /* Make room for the result. */
4589 if (count >= allocated - length)
4591 size_t n = xsum (length, count);
4593 ENSURE_ALLOCATION (n);
4596 /* Append the result. */
4597 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4598 if (tmp != tmpbuf)
4599 free (tmp);
4600 length += count;
4603 #endif
4604 else
4606 arg_type type = a.arg[dp->arg_index].type;
4607 int flags = dp->flags;
4608 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4609 int has_width;
4610 size_t width;
4611 #endif
4612 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
4613 int has_precision;
4614 size_t precision;
4615 #endif
4616 #if NEED_PRINTF_UNBOUNDED_PRECISION
4617 int prec_ourselves;
4618 #else
4619 # define prec_ourselves 0
4620 #endif
4621 #if NEED_PRINTF_FLAG_LEFTADJUST
4622 # define pad_ourselves 1
4623 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4624 int pad_ourselves;
4625 #else
4626 # define pad_ourselves 0
4627 #endif
4628 TCHAR_T *fbp;
4629 unsigned int prefix_count;
4630 int prefixes[2] IF_LINT (= { 0 });
4631 int orig_errno;
4632 #if !USE_SNPRINTF
4633 size_t tmp_length;
4634 TCHAR_T tmpbuf[700];
4635 TCHAR_T *tmp;
4636 #endif
4638 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4639 has_width = 0;
4640 width = 0;
4641 if (dp->width_start != dp->width_end)
4643 if (dp->width_arg_index != ARG_NONE)
4645 int arg;
4647 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4648 abort ();
4649 arg = a.arg[dp->width_arg_index].a.a_int;
4650 if (arg < 0)
4652 /* "A negative field width is taken as a '-' flag
4653 followed by a positive field width." */
4654 flags |= FLAG_LEFT;
4655 width = (unsigned int) (-arg);
4657 else
4658 width = arg;
4660 else
4662 const FCHAR_T *digitp = dp->width_start;
4665 width = xsum (xtimes (width, 10), *digitp++ - '0');
4666 while (digitp != dp->width_end);
4668 has_width = 1;
4670 #endif
4672 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
4673 has_precision = 0;
4674 precision = 6;
4675 if (dp->precision_start != dp->precision_end)
4677 if (dp->precision_arg_index != ARG_NONE)
4679 int arg;
4681 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4682 abort ();
4683 arg = a.arg[dp->precision_arg_index].a.a_int;
4684 /* "A negative precision is taken as if the precision
4685 were omitted." */
4686 if (arg >= 0)
4688 precision = arg;
4689 has_precision = 1;
4692 else
4694 const FCHAR_T *digitp = dp->precision_start + 1;
4696 precision = 0;
4697 while (digitp != dp->precision_end)
4698 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4699 has_precision = 1;
4702 #endif
4704 /* Decide whether to handle the precision ourselves. */
4705 #if NEED_PRINTF_UNBOUNDED_PRECISION
4706 switch (dp->conversion)
4708 case 'd': case 'i': case 'u':
4709 case 'o':
4710 case 'x': case 'X': case 'p':
4711 prec_ourselves = has_precision && (precision > 0);
4712 break;
4713 default:
4714 prec_ourselves = 0;
4715 break;
4717 #endif
4719 /* Decide whether to perform the padding ourselves. */
4720 #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
4721 switch (dp->conversion)
4723 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4724 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
4725 to perform the padding after this conversion. Functions
4726 with unistdio extensions perform the padding based on
4727 character count rather than element count. */
4728 case 'c': case 's':
4729 # endif
4730 # if NEED_PRINTF_FLAG_ZERO
4731 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
4732 case 'a': case 'A':
4733 # endif
4734 pad_ourselves = 1;
4735 break;
4736 default:
4737 pad_ourselves = prec_ourselves;
4738 break;
4740 #endif
4742 #if !USE_SNPRINTF
4743 /* Allocate a temporary buffer of sufficient size for calling
4744 sprintf. */
4745 tmp_length =
4746 MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
4747 flags, width, has_precision, precision,
4748 pad_ourselves);
4750 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
4751 tmp = tmpbuf;
4752 else
4754 size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
4756 if (size_overflow_p (tmp_memsize))
4757 /* Overflow, would lead to out of memory. */
4758 goto out_of_memory;
4759 tmp = (TCHAR_T *) malloc (tmp_memsize);
4760 if (tmp == NULL)
4761 /* Out of memory. */
4762 goto out_of_memory;
4764 #endif
4766 /* Construct the format string for calling snprintf or
4767 sprintf. */
4768 fbp = buf;
4769 *fbp++ = '%';
4770 #if NEED_PRINTF_FLAG_GROUPING
4771 /* The underlying implementation doesn't support the ' flag.
4772 Produce no grouping characters in this case; this is
4773 acceptable because the grouping is locale dependent. */
4774 #else
4775 if (flags & FLAG_GROUP)
4776 *fbp++ = '\'';
4777 #endif
4778 if (flags & FLAG_LEFT)
4779 *fbp++ = '-';
4780 if (flags & FLAG_SHOWSIGN)
4781 *fbp++ = '+';
4782 if (flags & FLAG_SPACE)
4783 *fbp++ = ' ';
4784 if (flags & FLAG_ALT)
4785 *fbp++ = '#';
4786 #if __GLIBC__ >= 2 && !defined __UCLIBC__
4787 if (flags & FLAG_LOCALIZED)
4788 *fbp++ = 'I';
4789 #endif
4790 if (!pad_ourselves)
4792 if (flags & FLAG_ZERO)
4793 *fbp++ = '0';
4794 if (dp->width_start != dp->width_end)
4796 size_t n = dp->width_end - dp->width_start;
4797 /* The width specification is known to consist only
4798 of standard ASCII characters. */
4799 if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4801 memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
4802 fbp += n;
4804 else
4806 const FCHAR_T *mp = dp->width_start;
4808 *fbp++ = (unsigned char) *mp++;
4809 while (--n > 0);
4813 if (!prec_ourselves)
4815 if (dp->precision_start != dp->precision_end)
4817 size_t n = dp->precision_end - dp->precision_start;
4818 /* The precision specification is known to consist only
4819 of standard ASCII characters. */
4820 if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4822 memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
4823 fbp += n;
4825 else
4827 const FCHAR_T *mp = dp->precision_start;
4829 *fbp++ = (unsigned char) *mp++;
4830 while (--n > 0);
4835 switch (type)
4837 #if HAVE_LONG_LONG_INT
4838 case TYPE_LONGLONGINT:
4839 case TYPE_ULONGLONGINT:
4840 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4841 *fbp++ = 'I';
4842 *fbp++ = '6';
4843 *fbp++ = '4';
4844 break;
4845 # else
4846 *fbp++ = 'l';
4847 /*FALLTHROUGH*/
4848 # endif
4849 #endif
4850 case TYPE_LONGINT:
4851 case TYPE_ULONGINT:
4852 #if HAVE_WINT_T
4853 case TYPE_WIDE_CHAR:
4854 #endif
4855 #if HAVE_WCHAR_T
4856 case TYPE_WIDE_STRING:
4857 #endif
4858 *fbp++ = 'l';
4859 break;
4860 case TYPE_LONGDOUBLE:
4861 *fbp++ = 'L';
4862 break;
4863 default:
4864 break;
4866 #if NEED_PRINTF_DIRECTIVE_F
4867 if (dp->conversion == 'F')
4868 *fbp = 'f';
4869 else
4870 #endif
4871 *fbp = dp->conversion;
4872 #if USE_SNPRINTF
4873 # if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
4874 fbp[1] = '%';
4875 fbp[2] = 'n';
4876 fbp[3] = '\0';
4877 # else
4878 /* On glibc2 systems from glibc >= 2.3 - probably also older
4879 ones - we know that snprintf's return value conforms to
4880 ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and
4881 gl_SNPRINTF_TRUNCATION_C99 pass.
4882 Therefore we can avoid using %n in this situation.
4883 On glibc2 systems from 2004-10-18 or newer, the use of %n
4884 in format strings in writable memory may crash the program
4885 (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
4886 in this situation. */
4887 /* On native Windows systems (such as mingw), we can avoid using
4888 %n because:
4889 - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
4890 snprintf does not write more than the specified number
4891 of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
4892 '4', '5', '6' into buf, not '4', '5', '\0'.)
4893 - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
4894 allows us to recognize the case of an insufficient
4895 buffer size: it returns -1 in this case.
4896 On native Windows systems (such as mingw) where the OS is
4897 Windows Vista, the use of %n in format strings by default
4898 crashes the program. See
4899 <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
4900 <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
4901 So we should avoid %n in this situation. */
4902 fbp[1] = '\0';
4903 # endif
4904 #else
4905 fbp[1] = '\0';
4906 #endif
4908 /* Construct the arguments for calling snprintf or sprintf. */
4909 prefix_count = 0;
4910 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
4912 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4913 abort ();
4914 prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
4916 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
4918 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4919 abort ();
4920 prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
4923 #if USE_SNPRINTF
4924 /* The SNPRINTF result is appended after result[0..length].
4925 The latter is an array of DCHAR_T; SNPRINTF appends an
4926 array of TCHAR_T to it. This is possible because
4927 sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
4928 alignof (TCHAR_T) <= alignof (DCHAR_T). */
4929 # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
4930 /* Ensure that maxlen below will be >= 2. Needed on BeOS,
4931 where an snprintf() with maxlen==1 acts like sprintf(). */
4932 ENSURE_ALLOCATION (xsum (length,
4933 (2 + TCHARS_PER_DCHAR - 1)
4934 / TCHARS_PER_DCHAR));
4935 /* Prepare checking whether snprintf returns the count
4936 via %n. */
4937 *(TCHAR_T *) (result + length) = '\0';
4938 #endif
4940 orig_errno = errno;
4942 for (;;)
4944 int count = -1;
4946 #if USE_SNPRINTF
4947 int retcount = 0;
4948 size_t maxlen = allocated - length;
4949 /* SNPRINTF can fail if its second argument is
4950 > INT_MAX. */
4951 if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
4952 maxlen = INT_MAX / TCHARS_PER_DCHAR;
4953 maxlen = maxlen * TCHARS_PER_DCHAR;
4954 # define SNPRINTF_BUF(arg) \
4955 switch (prefix_count) \
4957 case 0: \
4958 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4959 maxlen, buf, \
4960 arg, &count); \
4961 break; \
4962 case 1: \
4963 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4964 maxlen, buf, \
4965 prefixes[0], arg, &count); \
4966 break; \
4967 case 2: \
4968 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4969 maxlen, buf, \
4970 prefixes[0], prefixes[1], arg, \
4971 &count); \
4972 break; \
4973 default: \
4974 abort (); \
4976 #else
4977 # define SNPRINTF_BUF(arg) \
4978 switch (prefix_count) \
4980 case 0: \
4981 count = sprintf (tmp, buf, arg); \
4982 break; \
4983 case 1: \
4984 count = sprintf (tmp, buf, prefixes[0], arg); \
4985 break; \
4986 case 2: \
4987 count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
4988 arg); \
4989 break; \
4990 default: \
4991 abort (); \
4993 #endif
4995 errno = 0;
4996 switch (type)
4998 case TYPE_SCHAR:
5000 int arg = a.arg[dp->arg_index].a.a_schar;
5001 SNPRINTF_BUF (arg);
5003 break;
5004 case TYPE_UCHAR:
5006 unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
5007 SNPRINTF_BUF (arg);
5009 break;
5010 case TYPE_SHORT:
5012 int arg = a.arg[dp->arg_index].a.a_short;
5013 SNPRINTF_BUF (arg);
5015 break;
5016 case TYPE_USHORT:
5018 unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
5019 SNPRINTF_BUF (arg);
5021 break;
5022 case TYPE_INT:
5024 int arg = a.arg[dp->arg_index].a.a_int;
5025 SNPRINTF_BUF (arg);
5027 break;
5028 case TYPE_UINT:
5030 unsigned int arg = a.arg[dp->arg_index].a.a_uint;
5031 SNPRINTF_BUF (arg);
5033 break;
5034 case TYPE_LONGINT:
5036 long int arg = a.arg[dp->arg_index].a.a_longint;
5037 SNPRINTF_BUF (arg);
5039 break;
5040 case TYPE_ULONGINT:
5042 unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
5043 SNPRINTF_BUF (arg);
5045 break;
5046 #if HAVE_LONG_LONG_INT
5047 case TYPE_LONGLONGINT:
5049 long long int arg = a.arg[dp->arg_index].a.a_longlongint;
5050 SNPRINTF_BUF (arg);
5052 break;
5053 case TYPE_ULONGLONGINT:
5055 unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
5056 SNPRINTF_BUF (arg);
5058 break;
5059 #endif
5060 case TYPE_DOUBLE:
5062 double arg = a.arg[dp->arg_index].a.a_double;
5063 SNPRINTF_BUF (arg);
5065 break;
5066 case TYPE_LONGDOUBLE:
5068 long double arg = a.arg[dp->arg_index].a.a_longdouble;
5069 SNPRINTF_BUF (arg);
5071 break;
5072 case TYPE_CHAR:
5074 int arg = a.arg[dp->arg_index].a.a_char;
5075 SNPRINTF_BUF (arg);
5077 break;
5078 #if HAVE_WINT_T
5079 case TYPE_WIDE_CHAR:
5081 wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
5082 SNPRINTF_BUF (arg);
5084 break;
5085 #endif
5086 case TYPE_STRING:
5088 const char *arg = a.arg[dp->arg_index].a.a_string;
5089 SNPRINTF_BUF (arg);
5091 break;
5092 #if HAVE_WCHAR_T
5093 case TYPE_WIDE_STRING:
5095 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
5096 SNPRINTF_BUF (arg);
5098 break;
5099 #endif
5100 case TYPE_POINTER:
5102 void *arg = a.arg[dp->arg_index].a.a_pointer;
5103 SNPRINTF_BUF (arg);
5105 break;
5106 default:
5107 abort ();
5110 #if USE_SNPRINTF
5111 /* Portability: Not all implementations of snprintf()
5112 are ISO C 99 compliant. Determine the number of
5113 bytes that snprintf() has produced or would have
5114 produced. */
5115 if (count >= 0)
5117 /* Verify that snprintf() has NUL-terminated its
5118 result. */
5119 if (count < maxlen
5120 && ((TCHAR_T *) (result + length)) [count] != '\0')
5121 abort ();
5122 /* Portability hack. */
5123 if (retcount > count)
5124 count = retcount;
5126 else
5128 /* snprintf() doesn't understand the '%n'
5129 directive. */
5130 if (fbp[1] != '\0')
5132 /* Don't use the '%n' directive; instead, look
5133 at the snprintf() return value. */
5134 fbp[1] = '\0';
5135 continue;
5137 else
5139 /* Look at the snprintf() return value. */
5140 if (retcount < 0)
5142 # if !HAVE_SNPRINTF_RETVAL_C99
5143 /* HP-UX 10.20 snprintf() is doubly deficient:
5144 It doesn't understand the '%n' directive,
5145 *and* it returns -1 (rather than the length
5146 that would have been required) when the
5147 buffer is too small.
5148 But a failure at this point can also come
5149 from other reasons than a too small buffer,
5150 such as an invalid wide string argument to
5151 the %ls directive, or possibly an invalid
5152 floating-point argument. */
5153 size_t tmp_length =
5154 MAX_ROOM_NEEDED (&a, dp->arg_index,
5155 dp->conversion, type, flags,
5156 width, has_precision,
5157 precision, pad_ourselves);
5159 if (maxlen < tmp_length)
5161 /* Make more room. But try to do through
5162 this reallocation only once. */
5163 size_t bigger_need =
5164 xsum (length,
5165 xsum (tmp_length,
5166 TCHARS_PER_DCHAR - 1)
5167 / TCHARS_PER_DCHAR);
5168 /* And always grow proportionally.
5169 (There may be several arguments, each
5170 needing a little more room than the
5171 previous one.) */
5172 size_t bigger_need2 =
5173 xsum (xtimes (allocated, 2), 12);
5174 if (bigger_need < bigger_need2)
5175 bigger_need = bigger_need2;
5176 ENSURE_ALLOCATION (bigger_need);
5177 continue;
5179 # endif
5181 else
5182 count = retcount;
5185 #endif
5187 /* Attempt to handle failure. */
5188 if (count < 0)
5190 /* SNPRINTF or sprintf failed. Save and use the errno
5191 that it has set, if any. */
5192 int saved_errno = errno;
5194 if (!(result == resultbuf || result == NULL))
5195 free (result);
5196 if (buf_malloced != NULL)
5197 free (buf_malloced);
5198 CLEANUP ();
5199 errno =
5200 (saved_errno != 0
5201 ? saved_errno
5202 : (dp->conversion == 'c' || dp->conversion == 's'
5203 ? EILSEQ
5204 : EINVAL));
5205 return NULL;
5208 #if USE_SNPRINTF
5209 /* Handle overflow of the allocated buffer.
5210 If such an overflow occurs, a C99 compliant snprintf()
5211 returns a count >= maxlen. However, a non-compliant
5212 snprintf() function returns only count = maxlen - 1. To
5213 cover both cases, test whether count >= maxlen - 1. */
5214 if ((unsigned int) count + 1 >= maxlen)
5216 /* If maxlen already has attained its allowed maximum,
5217 allocating more memory will not increase maxlen.
5218 Instead of looping, bail out. */
5219 if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
5220 goto overflow;
5221 else
5223 /* Need at least (count + 1) * sizeof (TCHAR_T)
5224 bytes. (The +1 is for the trailing NUL.)
5225 But ask for (count + 2) * sizeof (TCHAR_T)
5226 bytes, so that in the next round, we likely get
5227 maxlen > (unsigned int) count + 1
5228 and so we don't get here again.
5229 And allocate proportionally, to avoid looping
5230 eternally if snprintf() reports a too small
5231 count. */
5232 size_t n =
5233 xmax (xsum (length,
5234 ((unsigned int) count + 2
5235 + TCHARS_PER_DCHAR - 1)
5236 / TCHARS_PER_DCHAR),
5237 xtimes (allocated, 2));
5239 ENSURE_ALLOCATION (n);
5240 continue;
5243 #endif
5245 #if NEED_PRINTF_UNBOUNDED_PRECISION
5246 if (prec_ourselves)
5248 /* Handle the precision. */
5249 TCHAR_T *prec_ptr =
5250 # if USE_SNPRINTF
5251 (TCHAR_T *) (result + length);
5252 # else
5253 tmp;
5254 # endif
5255 size_t prefix_count;
5256 size_t move;
5258 prefix_count = 0;
5259 /* Put the additional zeroes after the sign. */
5260 if (count >= 1
5261 && (*prec_ptr == '-' || *prec_ptr == '+'
5262 || *prec_ptr == ' '))
5263 prefix_count = 1;
5264 /* Put the additional zeroes after the 0x prefix if
5265 (flags & FLAG_ALT) || (dp->conversion == 'p'). */
5266 else if (count >= 2
5267 && prec_ptr[0] == '0'
5268 && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
5269 prefix_count = 2;
5271 move = count - prefix_count;
5272 if (precision > move)
5274 /* Insert zeroes. */
5275 size_t insert = precision - move;
5276 TCHAR_T *prec_end;
5278 # if USE_SNPRINTF
5279 size_t n =
5280 xsum (length,
5281 (count + insert + TCHARS_PER_DCHAR - 1)
5282 / TCHARS_PER_DCHAR);
5283 length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5284 ENSURE_ALLOCATION (n);
5285 length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5286 prec_ptr = (TCHAR_T *) (result + length);
5287 # endif
5289 prec_end = prec_ptr + count;
5290 prec_ptr += prefix_count;
5292 while (prec_end > prec_ptr)
5294 prec_end--;
5295 prec_end[insert] = prec_end[0];
5298 prec_end += insert;
5300 *--prec_end = '0';
5301 while (prec_end > prec_ptr);
5303 count += insert;
5306 #endif
5308 #if !USE_SNPRINTF
5309 if (count >= tmp_length)
5310 /* tmp_length was incorrectly calculated - fix the
5311 code above! */
5312 abort ();
5313 #endif
5315 #if !DCHAR_IS_TCHAR
5316 /* Convert from TCHAR_T[] to DCHAR_T[]. */
5317 if (dp->conversion == 'c' || dp->conversion == 's')
5319 /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
5320 TYPE_WIDE_STRING.
5321 The result string is not certainly ASCII. */
5322 const TCHAR_T *tmpsrc;
5323 DCHAR_T *tmpdst;
5324 size_t tmpdst_len;
5325 /* This code assumes that TCHAR_T is 'char'. */
5326 verify (sizeof (TCHAR_T) == 1);
5327 # if USE_SNPRINTF
5328 tmpsrc = (TCHAR_T *) (result + length);
5329 # else
5330 tmpsrc = tmp;
5331 # endif
5332 tmpdst =
5333 DCHAR_CONV_FROM_ENCODING (locale_charset (),
5334 iconveh_question_mark,
5335 tmpsrc, count,
5336 NULL,
5337 NULL, &tmpdst_len);
5338 if (tmpdst == NULL)
5340 int saved_errno = errno;
5341 if (!(result == resultbuf || result == NULL))
5342 free (result);
5343 if (buf_malloced != NULL)
5344 free (buf_malloced);
5345 CLEANUP ();
5346 errno = saved_errno;
5347 return NULL;
5349 ENSURE_ALLOCATION (xsum (length, tmpdst_len));
5350 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
5351 free (tmpdst);
5352 count = tmpdst_len;
5354 else
5356 /* The result string is ASCII.
5357 Simple 1:1 conversion. */
5358 # if USE_SNPRINTF
5359 /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
5360 no-op conversion, in-place on the array starting
5361 at (result + length). */
5362 if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
5363 # endif
5365 const TCHAR_T *tmpsrc;
5366 DCHAR_T *tmpdst;
5367 size_t n;
5369 # if USE_SNPRINTF
5370 if (result == resultbuf)
5372 tmpsrc = (TCHAR_T *) (result + length);
5373 /* ENSURE_ALLOCATION will not move tmpsrc
5374 (because it's part of resultbuf). */
5375 ENSURE_ALLOCATION (xsum (length, count));
5377 else
5379 /* ENSURE_ALLOCATION will move the array
5380 (because it uses realloc(). */
5381 ENSURE_ALLOCATION (xsum (length, count));
5382 tmpsrc = (TCHAR_T *) (result + length);
5384 # else
5385 tmpsrc = tmp;
5386 ENSURE_ALLOCATION (xsum (length, count));
5387 # endif
5388 tmpdst = result + length;
5389 /* Copy backwards, because of overlapping. */
5390 tmpsrc += count;
5391 tmpdst += count;
5392 for (n = count; n > 0; n--)
5393 *--tmpdst = (unsigned char) *--tmpsrc;
5396 #endif
5398 #if DCHAR_IS_TCHAR && !USE_SNPRINTF
5399 /* Make room for the result. */
5400 if (count > allocated - length)
5402 /* Need at least count elements. But allocate
5403 proportionally. */
5404 size_t n =
5405 xmax (xsum (length, count), xtimes (allocated, 2));
5407 ENSURE_ALLOCATION (n);
5409 #endif
5411 /* Here count <= allocated - length. */
5413 /* Perform padding. */
5414 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5415 if (pad_ourselves && has_width)
5417 size_t w;
5418 # if ENABLE_UNISTDIO
5419 /* Outside POSIX, it's preferable to compare the width
5420 against the number of _characters_ of the converted
5421 value. */
5422 w = DCHAR_MBSNLEN (result + length, count);
5423 # else
5424 /* The width is compared against the number of _bytes_
5425 of the converted value, says POSIX. */
5426 w = count;
5427 # endif
5428 if (w < width)
5430 size_t pad = width - w;
5432 /* Make room for the result. */
5433 if (xsum (count, pad) > allocated - length)
5435 /* Need at least count + pad elements. But
5436 allocate proportionally. */
5437 size_t n =
5438 xmax (xsum3 (length, count, pad),
5439 xtimes (allocated, 2));
5441 # if USE_SNPRINTF
5442 length += count;
5443 ENSURE_ALLOCATION (n);
5444 length -= count;
5445 # else
5446 ENSURE_ALLOCATION (n);
5447 # endif
5449 /* Here count + pad <= allocated - length. */
5452 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
5453 DCHAR_T * const rp = result + length;
5454 # else
5455 DCHAR_T * const rp = tmp;
5456 # endif
5457 DCHAR_T *p = rp + count;
5458 DCHAR_T *end = p + pad;
5459 DCHAR_T *pad_ptr;
5460 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
5461 if (dp->conversion == 'c'
5462 || dp->conversion == 's')
5463 /* No zero-padding for string directives. */
5464 pad_ptr = NULL;
5465 else
5466 # endif
5468 pad_ptr = (*rp == '-' ? rp + 1 : rp);
5469 /* No zero-padding of "inf" and "nan". */
5470 if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
5471 || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
5472 pad_ptr = NULL;
5474 /* The generated string now extends from rp to p,
5475 with the zero padding insertion point being at
5476 pad_ptr. */
5478 count = count + pad; /* = end - rp */
5480 if (flags & FLAG_LEFT)
5482 /* Pad with spaces on the right. */
5483 for (; pad > 0; pad--)
5484 *p++ = ' ';
5486 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
5488 /* Pad with zeroes. */
5489 DCHAR_T *q = end;
5491 while (p > pad_ptr)
5492 *--q = *--p;
5493 for (; pad > 0; pad--)
5494 *p++ = '0';
5496 else
5498 /* Pad with spaces on the left. */
5499 DCHAR_T *q = end;
5501 while (p > rp)
5502 *--q = *--p;
5503 for (; pad > 0; pad--)
5504 *p++ = ' ';
5509 #endif
5511 /* Here still count <= allocated - length. */
5513 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
5514 /* The snprintf() result did fit. */
5515 #else
5516 /* Append the sprintf() result. */
5517 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
5518 #endif
5519 #if !USE_SNPRINTF
5520 if (tmp != tmpbuf)
5521 free (tmp);
5522 #endif
5524 #if NEED_PRINTF_DIRECTIVE_F
5525 if (dp->conversion == 'F')
5527 /* Convert the %f result to upper case for %F. */
5528 DCHAR_T *rp = result + length;
5529 size_t rc;
5530 for (rc = count; rc > 0; rc--, rp++)
5531 if (*rp >= 'a' && *rp <= 'z')
5532 *rp = *rp - 'a' + 'A';
5534 #endif
5536 length += count;
5537 break;
5539 errno = orig_errno;
5540 #undef pad_ourselves
5541 #undef prec_ourselves
5546 /* Add the final NUL. */
5547 ENSURE_ALLOCATION (xsum (length, 1));
5548 result[length] = '\0';
5550 if (result != resultbuf && length + 1 < allocated)
5552 /* Shrink the allocated memory if possible. */
5553 DCHAR_T *memory;
5555 memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
5556 if (memory != NULL)
5557 result = memory;
5560 if (buf_malloced != NULL)
5561 free (buf_malloced);
5562 CLEANUP ();
5563 *lengthp = length;
5564 /* Note that we can produce a big string of a length > INT_MAX. POSIX
5565 says that snprintf() fails with errno = EOVERFLOW in this case, but
5566 that's only because snprintf() returns an 'int'. This function does
5567 not have this limitation. */
5568 return result;
5570 #if USE_SNPRINTF
5571 overflow:
5572 if (!(result == resultbuf || result == NULL))
5573 free (result);
5574 if (buf_malloced != NULL)
5575 free (buf_malloced);
5576 CLEANUP ();
5577 errno = EOVERFLOW;
5578 return NULL;
5579 #endif
5581 out_of_memory:
5582 if (!(result == resultbuf || result == NULL))
5583 free (result);
5584 if (buf_malloced != NULL)
5585 free (buf_malloced);
5586 out_of_memory_1:
5587 CLEANUP ();
5588 errno = ENOMEM;
5589 return NULL;
5593 #undef MAX_ROOM_NEEDED
5594 #undef TCHARS_PER_DCHAR
5595 #undef SNPRINTF
5596 #undef USE_SNPRINTF
5597 #undef DCHAR_SET
5598 #undef DCHAR_CPY
5599 #undef PRINTF_PARSE
5600 #undef DIRECTIVES
5601 #undef DIRECTIVE
5602 #undef DCHAR_IS_TCHAR
5603 #undef TCHAR_T
5604 #undef DCHAR_T
5605 #undef FCHAR_T
5606 #undef VASNPRINTF