Line data Source code
1 : /* vsprintf with automatic memory allocation.
2 : Copyright (C) 1999, 2002-2016 Free Software Foundation, Inc.
3 :
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.
8 :
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.
13 :
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/>. */
16 :
17 : /* This file can be parametrized with the following macros:
18 : VASNPRINTF The name of the function being defined.
19 : FCHAR_T The element type of the format string.
20 : DCHAR_T The element type of the destination (result) string.
21 : FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
22 : in the format string are ASCII. MUST be set if
23 : FCHAR_T and DCHAR_T are not the same type.
24 : DIRECTIVE Structure denoting a format directive.
25 : Depends on FCHAR_T.
26 : DIRECTIVES Structure denoting the set of format directives of a
27 : format string. Depends on FCHAR_T.
28 : PRINTF_PARSE Function that parses a format string.
29 : Depends on FCHAR_T.
30 : DCHAR_CPY memcpy like function for DCHAR_T[] arrays.
31 : DCHAR_SET memset like function for DCHAR_T[] arrays.
32 : DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays.
33 : SNPRINTF The system's snprintf (or similar) function.
34 : This may be either snprintf or swprintf.
35 : TCHAR_T The element type of the argument and result string
36 : of the said SNPRINTF function. This may be either
37 : char or wchar_t. The code exploits that
38 : sizeof (TCHAR_T) | sizeof (DCHAR_T) and
39 : alignof (TCHAR_T) <= alignof (DCHAR_T).
40 : DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type.
41 : DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
42 : DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t.
43 : DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t.
44 : DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */
45 :
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
52 :
53 : #ifndef VASNPRINTF
54 : # include <config.h>
55 : #endif
56 : #ifndef IN_LIBINTL
57 : # include <alloca.h>
58 : #endif
59 :
60 : /* Specification. */
61 : #ifndef VASNPRINTF
62 : # if WIDE_CHAR_VERSION
63 : # include "vasnwprintf.h"
64 : # else
65 : # include "vasnprintf.h"
66 : # endif
67 : #endif
68 :
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
86 :
87 : /* Checked size_t computations. */
88 : #include "xsize.h"
89 :
90 : #include "verify.h"
91 :
92 : #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
93 : # include <math.h>
94 : # include "float+.h"
95 : #endif
96 :
97 : #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
98 : # include <math.h>
99 : # include "isnand-nolibm.h"
100 : #endif
101 :
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
107 :
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
113 :
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
120 :
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
195 :
196 : /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
197 : warnings in this file. Use -Dlint to suppress them. */
198 : #if defined GCC_LINT || defined lint
199 : # define IF_LINT(Code) Code
200 : #else
201 : # define IF_LINT(Code) /* empty */
202 : #endif
203 :
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
210 :
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)
219 : {
220 : const char *end = memchr (string, '\0', maxlen);
221 : return end ? (size_t) (end - string) : maxlen;
222 : }
223 : # endif
224 : # endif
225 : #endif
226 :
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)
239 : {
240 : const wchar_t *ptr;
241 :
242 : for (ptr = s; *ptr != (wchar_t) 0; ptr++)
243 : ;
244 : return ptr - s;
245 : }
246 : # endif
247 : # endif
248 : #endif
249 :
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)
258 : {
259 : const wchar_t *ptr;
260 :
261 : for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
262 : ;
263 : return ptr - s;
264 : }
265 : # endif
266 : # endif
267 : #endif
268 :
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)
275 : {
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] : '.');
292 : }
293 : # endif
294 : #endif
295 :
296 : #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
297 :
298 : /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
299 : static int
300 : is_infinite_or_zero (double x)
301 : {
302 : return isnand (x) || x + x == x;
303 : }
304 :
305 : #endif
306 :
307 : #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
308 :
309 : /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
310 : static int
311 : is_infinite_or_zerol (long double x)
312 : {
313 : return isnanl (x) || x + x == x;
314 : }
315 :
316 : #endif
317 :
318 : #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
319 :
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. */
323 :
324 : typedef unsigned int mp_limb_t;
325 : # define GMP_LIMB_BITS 32
326 : verify (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS);
327 :
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);
331 :
332 : /* Representation of a bignum >= 0. */
333 : typedef struct
334 : {
335 : size_t nlimbs;
336 : mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */
337 : } mpn_t;
338 :
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)
344 : {
345 : const mp_limb_t *p1;
346 : const mp_limb_t *p2;
347 : size_t len1;
348 : size_t len2;
349 :
350 : if (src1.nlimbs <= src2.nlimbs)
351 : {
352 : len1 = src1.nlimbs;
353 : p1 = src1.limbs;
354 : len2 = src2.nlimbs;
355 : p2 = src2.limbs;
356 : }
357 : else
358 : {
359 : len1 = src2.nlimbs;
360 : p1 = src2.limbs;
361 : len2 = src1.nlimbs;
362 : p2 = src1.limbs;
363 : }
364 : /* Now 0 <= len1 <= len2. */
365 : if (len1 == 0)
366 : {
367 : /* src1 or src2 is zero. */
368 : dest->nlimbs = 0;
369 : dest->limbs = (mp_limb_t *) malloc (1);
370 : }
371 : else
372 : {
373 : /* Here 1 <= len1 <= len2. */
374 : size_t dlen;
375 : mp_limb_t *dp;
376 : size_t k, i, j;
377 :
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++)
385 : {
386 : mp_limb_t digit1 = p1[i];
387 : mp_twolimb_t carry = 0;
388 : for (j = 0; j < len2; j++)
389 : {
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;
395 : }
396 : dp[i + len2] = (mp_limb_t) carry;
397 : }
398 : /* Normalise. */
399 : while (dlen > 0 && dp[dlen - 1] == 0)
400 : dlen--;
401 : dest->nlimbs = dlen;
402 : dest->limbs = dp;
403 : }
404 : return dest->limbs;
405 : }
406 :
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)
416 : {
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.
467 : */
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;
478 :
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;
485 :
486 : /* Normalise a. */
487 : while (a_len > 0 && a_ptr[a_len - 1] == 0)
488 : a_len--;
489 :
490 : /* Normalise b. */
491 : for (;;)
492 : {
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;
500 : }
501 :
502 : /* Here m = a_len >= 0 and n = b_len > 0. */
503 :
504 : if (a_len < b_len)
505 : {
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;
512 : }
513 : else if (b_len == 1)
514 : {
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;
519 : {
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--)
526 : {
527 : mp_twolimb_t num =
528 : ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
529 : *--destptr = num / den;
530 : remainder = num % den;
531 : }
532 : /* Normalise and store r. */
533 : if (remainder > 0)
534 : {
535 : r_ptr[0] = remainder;
536 : r_len = 1;
537 : }
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--;
544 : }
545 : }
546 : else
547 : {
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;
553 : {
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)
562 : {
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;
570 :
571 : /* Use a single integer to floating-point conversion. */
572 : m.value = msd;
573 :
574 : s = GMP_LIMB_BITS
575 : - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK)
576 : - DBL_EXP_BIAS);
577 : }
578 : else
579 : # undef NWORDS
580 : # endif
581 : {
582 : s = 31;
583 : if (msd >= 0x10000)
584 : {
585 : msd = msd >> 16;
586 : s -= 16;
587 : }
588 : if (msd >= 0x100)
589 : {
590 : msd = msd >> 8;
591 : s -= 8;
592 : }
593 : if (msd >= 0x10)
594 : {
595 : msd = msd >> 4;
596 : s -= 4;
597 : }
598 : if (msd >= 0x4)
599 : {
600 : msd = msd >> 2;
601 : s -= 2;
602 : }
603 : if (msd >= 0x2)
604 : {
605 : msd = msd >> 1;
606 : s -= 1;
607 : }
608 : }
609 : # endif
610 : }
611 : /* 0 <= s < GMP_LIMB_BITS.
612 : Copy b, shifting it left by s bits. */
613 : if (s > 0)
614 : {
615 : tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
616 : if (tmp_roomptr == NULL)
617 : {
618 : free (roomptr);
619 : return NULL;
620 : }
621 : {
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--)
627 : {
628 : accu += (mp_twolimb_t) *sourceptr++ << s;
629 : *destptr++ = (mp_limb_t) accu;
630 : accu = accu >> GMP_LIMB_BITS;
631 : }
632 : /* accu must be zero, since that was how s was determined. */
633 : if (accu != 0)
634 : abort ();
635 : }
636 : b_ptr = tmp_roomptr;
637 : }
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)
644 : {
645 : memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
646 : r_ptr[a_len] = 0;
647 : }
648 : else
649 : {
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--)
655 : {
656 : accu += (mp_twolimb_t) *sourceptr++ << s;
657 : *destptr++ = (mp_limb_t) accu;
658 : accu = accu >> GMP_LIMB_BITS;
659 : }
660 : *destptr++ = (mp_limb_t) accu;
661 : }
662 : q_ptr = roomptr + b_len;
663 : q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
664 : {
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 (;;)
673 : {
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] ? */
677 : {
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;
684 : }
685 : else
686 : {
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;
702 : }
703 : /* q_star = q*,
704 : c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta). */
705 : {
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)
715 : {
716 : q_star = q_star - 1; /* q* := q* - 1 */
717 : if (c3 - c2 > b_msdd)
718 : q_star = q_star - 1; /* q* := q* - 1 */
719 : }
720 : }
721 : if (q_star > 0)
722 : subtract:
723 : {
724 : /* Subtract r := r - b * q* * beta^j. */
725 : mp_limb_t cr;
726 : {
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--)
732 : {
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* */
741 : }
742 : cr = (mp_limb_t) carry;
743 : }
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])
747 : {
748 : /* Subtraction gave a carry. */
749 : q_star = q_star - 1; /* q* := q* - 1 */
750 : /* Add b back. */
751 : {
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--)
757 : {
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);
765 : }
766 : }
767 : /* Forget about the carry and about r[j+n]. */
768 : }
769 : }
770 : /* q* is determined. Store it as q[j]. */
771 : q_ptr[j] = q_star;
772 : if (j == 0)
773 : break;
774 : j--;
775 : }
776 : }
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)
785 : {
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--)
790 : {
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);
794 : }
795 : }
796 : # endif
797 : /* Normalise r. */
798 : while (r_len > 0 && r_ptr[r_len - 1] == 0)
799 : r_len--;
800 : }
801 : /* Compare r << 1 with b. */
802 : if (r_len > b_len)
803 : goto increment_q;
804 : {
805 : size_t i;
806 : for (i = b_len;;)
807 : {
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--;
819 : }
820 : }
821 : if (q_len > 0 && ((q_ptr[0] & 1) != 0))
822 : /* q is odd. */
823 : increment_q:
824 : {
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;
830 : }
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;
837 : }
838 :
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)
847 : {
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)
854 : {
855 : char *d_ptr = c_ptr;
856 : for (; extra_zeroes > 0; extra_zeroes--)
857 : *d_ptr++ = '0';
858 : while (a_len > 0)
859 : {
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--)
865 : {
866 : mp_twolimb_t num =
867 : ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
868 : *ptr = num / 1000000000;
869 : remainder = num % 1000000000;
870 : }
871 : /* Store the remainder as 9 decimal digits. */
872 : for (count = 9; count > 0; count--)
873 : {
874 : *d_ptr++ = '0' + (remainder % 10);
875 : remainder = remainder / 10;
876 : }
877 : /* Normalize a. */
878 : if (a_ptr[a_len - 1] == 0)
879 : a_len--;
880 : }
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';
889 : }
890 : return c_ptr;
891 : }
892 :
893 : # if NEED_PRINTF_LONG_DOUBLE
894 :
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)
901 : {
902 : mpn_t m;
903 : int exp;
904 : long double y;
905 : size_t i;
906 :
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
925 : {
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;
938 : }
939 : # else
940 : {
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;
948 : }
949 : # endif
950 : # endif
951 : for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
952 : {
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;
965 : }
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;
977 : }
978 :
979 : # endif
980 :
981 : # if NEED_PRINTF_DOUBLE
982 :
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)
989 : {
990 : mpn_t m;
991 : int exp;
992 : double y;
993 : size_t i;
994 :
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
1013 : {
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;
1026 : }
1027 : # else
1028 : {
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;
1036 : }
1037 : # endif
1038 : # endif
1039 : for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1040 : {
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;
1053 : }
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;
1062 : }
1063 :
1064 : # endif
1065 :
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)
1073 : {
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;
1086 :
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)
1096 : {
1097 : extra_zeroes = (s < n ? s : n);
1098 : s -= extra_zeroes;
1099 : n -= extra_zeroes;
1100 : }
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)
1112 : {
1113 : free (memory);
1114 : return NULL;
1115 : }
1116 : /* Initialize with 1. */
1117 : pow5_ptr[0] = 1;
1118 : pow5_len = 1;
1119 : /* Multiply with 5^|n|. */
1120 : if (abs_n > 0)
1121 : {
1122 : static mp_limb_t const small_pow5[13 + 1] =
1123 : {
1124 : 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
1125 : 48828125, 244140625, 1220703125
1126 : };
1127 : unsigned int n13;
1128 : for (n13 = 0; n13 <= abs_n; n13 += 13)
1129 : {
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++)
1134 : {
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;
1139 : }
1140 : if (carry > 0)
1141 : pow5_ptr[pow5_len++] = (mp_limb_t) carry;
1142 : }
1143 : }
1144 : s_limbs = abs_s / GMP_LIMB_BITS;
1145 : s_bits = abs_s % GMP_LIMB_BITS;
1146 : if (n >= 0 ? s >= 0 : s <= 0)
1147 : {
1148 : /* Multiply with 2^|s|. */
1149 : if (s_bits > 0)
1150 : {
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--)
1155 : {
1156 : accu += (mp_twolimb_t) *ptr << s_bits;
1157 : *ptr++ = (mp_limb_t) accu;
1158 : accu = accu >> GMP_LIMB_BITS;
1159 : }
1160 : if (accu > 0)
1161 : {
1162 : *ptr = (mp_limb_t) accu;
1163 : pow5_len++;
1164 : }
1165 : }
1166 : if (s_limbs > 0)
1167 : {
1168 : size_t count;
1169 : for (count = pow5_len; count > 0;)
1170 : {
1171 : count--;
1172 : pow5_ptr[s_limbs + count] = pow5_ptr[count];
1173 : }
1174 : for (count = s_limbs; count > 0;)
1175 : {
1176 : count--;
1177 : pow5_ptr[count] = 0;
1178 : }
1179 : pow5_len += s_limbs;
1180 : }
1181 : pow5.limbs = pow5_ptr;
1182 : pow5.nlimbs = pow5_len;
1183 : if (n >= 0)
1184 : {
1185 : /* Multiply m with pow5. No division needed. */
1186 : z_memory = multiply (m, pow5, &z);
1187 : }
1188 : else
1189 : {
1190 : /* Divide m by pow5 and round. */
1191 : z_memory = divide (m, pow5, &z);
1192 : }
1193 : }
1194 : else
1195 : {
1196 : pow5.limbs = pow5_ptr;
1197 : pow5.nlimbs = pow5_len;
1198 : if (n >= 0)
1199 : {
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)
1207 : {
1208 : free (pow5_ptr);
1209 : free (memory);
1210 : return NULL;
1211 : }
1212 : /* Construct 2^|s|. */
1213 : {
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;
1221 : }
1222 : z_memory = divide (numerator, denominator, &z);
1223 : free (tmp_memory);
1224 : }
1225 : else
1226 : {
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)
1234 : {
1235 : free (pow5_ptr);
1236 : free (memory);
1237 : return NULL;
1238 : }
1239 : {
1240 : mp_limb_t *destptr = num_ptr;
1241 : {
1242 : size_t i;
1243 : for (i = 0; i < s_limbs; i++)
1244 : *destptr++ = 0;
1245 : }
1246 : if (s_bits > 0)
1247 : {
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--)
1252 : {
1253 : accu += (mp_twolimb_t) *sourceptr++ << s_bits;
1254 : *destptr++ = (mp_limb_t) accu;
1255 : accu = accu >> GMP_LIMB_BITS;
1256 : }
1257 : if (accu > 0)
1258 : *destptr++ = (mp_limb_t) accu;
1259 : }
1260 : else
1261 : {
1262 : const mp_limb_t *sourceptr = m.limbs;
1263 : size_t count;
1264 : for (count = m.nlimbs; count > 0; count--)
1265 : *destptr++ = *sourceptr++;
1266 : }
1267 : numerator.limbs = num_ptr;
1268 : numerator.nlimbs = destptr - num_ptr;
1269 : }
1270 : z_memory = divide (numerator, pow5, &z);
1271 : free (num_ptr);
1272 : }
1273 : }
1274 : free (pow5_ptr);
1275 : free (memory);
1276 :
1277 : /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */
1278 :
1279 : if (z_memory == NULL)
1280 : return NULL;
1281 : digits = convert_to_decimal (z, extra_zeroes);
1282 : free (z_memory);
1283 : return digits;
1284 : }
1285 :
1286 : # if NEED_PRINTF_LONG_DOUBLE
1287 :
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)
1295 : {
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);
1300 : }
1301 :
1302 : # endif
1303 :
1304 : # if NEED_PRINTF_DOUBLE
1305 :
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)
1313 : {
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);
1318 : }
1319 :
1320 : # endif
1321 :
1322 : # if NEED_PRINTF_LONG_DOUBLE
1323 :
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)
1329 : {
1330 : int exp;
1331 : long double y;
1332 : double z;
1333 : double l;
1334 :
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)
1342 : {
1343 : while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1344 : {
1345 : y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1346 : exp -= GMP_LIMB_BITS;
1347 : }
1348 : if (y < (1.0L / (1 << 16)))
1349 : {
1350 : y *= 1.0L * (1 << 16);
1351 : exp -= 16;
1352 : }
1353 : if (y < (1.0L / (1 << 8)))
1354 : {
1355 : y *= 1.0L * (1 << 8);
1356 : exp -= 8;
1357 : }
1358 : if (y < (1.0L / (1 << 4)))
1359 : {
1360 : y *= 1.0L * (1 << 4);
1361 : exp -= 4;
1362 : }
1363 : if (y < (1.0L / (1 << 2)))
1364 : {
1365 : y *= 1.0L * (1 << 2);
1366 : exp -= 2;
1367 : }
1368 : if (y < (1.0L / (1 << 1)))
1369 : {
1370 : y *= 1.0L * (1 << 1);
1371 : exp -= 1;
1372 : }
1373 : }
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)
1380 : {
1381 : z *= 1.4142135623730950488;
1382 : l -= 0.5;
1383 : }
1384 : if (z < 0.8408964152537145431)
1385 : {
1386 : z *= 1.1892071150027210667;
1387 : l -= 0.25;
1388 : }
1389 : if (z < 0.91700404320467123175)
1390 : {
1391 : z *= 1.0905077326652576592;
1392 : l -= 0.125;
1393 : }
1394 : if (z < 0.9576032806985736469)
1395 : {
1396 : z *= 1.0442737824274138403;
1397 : l -= 0.0625;
1398 : }
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);
1409 : }
1410 :
1411 : # endif
1412 :
1413 : # if NEED_PRINTF_DOUBLE
1414 :
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)
1420 : {
1421 : int exp;
1422 : double y;
1423 : double z;
1424 : double l;
1425 :
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)
1433 : {
1434 : while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1435 : {
1436 : y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1437 : exp -= GMP_LIMB_BITS;
1438 : }
1439 : if (y < (1.0 / (1 << 16)))
1440 : {
1441 : y *= 1.0 * (1 << 16);
1442 : exp -= 16;
1443 : }
1444 : if (y < (1.0 / (1 << 8)))
1445 : {
1446 : y *= 1.0 * (1 << 8);
1447 : exp -= 8;
1448 : }
1449 : if (y < (1.0 / (1 << 4)))
1450 : {
1451 : y *= 1.0 * (1 << 4);
1452 : exp -= 4;
1453 : }
1454 : if (y < (1.0 / (1 << 2)))
1455 : {
1456 : y *= 1.0 * (1 << 2);
1457 : exp -= 2;
1458 : }
1459 : if (y < (1.0 / (1 << 1)))
1460 : {
1461 : y *= 1.0 * (1 << 1);
1462 : exp -= 1;
1463 : }
1464 : }
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)
1471 : {
1472 : z *= 1.4142135623730950488;
1473 : l -= 0.5;
1474 : }
1475 : if (z < 0.8408964152537145431)
1476 : {
1477 : z *= 1.1892071150027210667;
1478 : l -= 0.25;
1479 : }
1480 : if (z < 0.91700404320467123175)
1481 : {
1482 : z *= 1.0905077326652576592;
1483 : l -= 0.125;
1484 : }
1485 : if (z < 0.9576032806985736469)
1486 : {
1487 : z *= 1.0442737824274138403;
1488 : l -= 0.0625;
1489 : }
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);
1500 : }
1501 :
1502 : # endif
1503 :
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)
1508 : {
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';
1516 : }
1517 :
1518 : #endif
1519 :
1520 : #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99
1521 :
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
1530 :
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 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)
1537 : {
1538 : size_t tmp_length;
1539 :
1540 : switch (conversion)
1541 : {
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 */
1548 : )
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 */
1556 : )
1557 : + 1; /* turn floor into ceil */
1558 : else
1559 : tmp_length =
1560 : (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1561 : * 0.30103 /* binary -> decimal */
1562 : )
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;
1571 :
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 */
1578 : )
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 */
1586 : )
1587 : + 1; /* turn floor into ceil */
1588 : else
1589 : tmp_length =
1590 : (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1591 : * 0.333334 /* binary -> octal */
1592 : )
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;
1599 :
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 */
1606 : )
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 */
1614 : )
1615 : + 1; /* turn floor into ceil */
1616 : else
1617 : tmp_length =
1618 : (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1619 : * 0.25 /* binary -> hexadecimal */
1620 : )
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;
1627 :
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 */
1634 : )
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 */
1642 : )
1643 : + 1 /* turn floor into ceil */
1644 : + 10; /* sign, decimal point etc. */
1645 : tmp_length = xsum (tmp_length, precision);
1646 : break;
1647 :
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;
1653 :
1654 : case 'a': case 'A':
1655 : if (type == TYPE_LONGDOUBLE)
1656 : tmp_length =
1657 : (unsigned int) (LDBL_DIG
1658 : * 0.831 /* decimal -> hexadecimal */
1659 : )
1660 : + 1; /* turn floor into ceil */
1661 : else
1662 : tmp_length =
1663 : (unsigned int) (DBL_DIG
1664 : * 0.831 /* decimal -> hexadecimal */
1665 : )
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;
1672 :
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;
1681 :
1682 : case 's':
1683 : # if HAVE_WCHAR_T
1684 : if (type == TYPE_WIDE_STRING)
1685 : {
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;
1692 :
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
1709 : }
1710 : else
1711 : # endif
1712 : {
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;
1727 :
1728 : if (has_precision)
1729 : tmp_length = local_strnlen (arg, precision);
1730 : else
1731 : tmp_length = strlen (arg);
1732 : # endif
1733 : }
1734 : break;
1735 :
1736 : case 'p':
1737 : tmp_length =
1738 : (unsigned int) (sizeof (void *) * CHAR_BIT
1739 : * 0.25 /* binary -> hexadecimal */
1740 : )
1741 : + 1 /* turn floor into ceil */
1742 : + 2; /* account for leading 0x */
1743 : break;
1744 :
1745 : default:
1746 : abort ();
1747 : }
1748 :
1749 : if (!pad_ourselves)
1750 : {
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
1763 : }
1764 :
1765 : tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
1766 :
1767 : return tmp_length;
1768 : }
1769 :
1770 : #endif
1771 :
1772 : DCHAR_T *
1773 0 : VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
1774 : const FCHAR_T *format, va_list args)
1775 : {
1776 : DIRECTIVES d;
1777 : arguments a;
1778 :
1779 0 : if (PRINTF_PARSE (format, &d, &a) < 0)
1780 : /* errno is already set. */
1781 0 : return NULL;
1782 :
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);
1788 :
1789 0 : if (PRINTF_FETCHARGS (args, &a) < 0)
1790 : {
1791 0 : CLEANUP ();
1792 0 : errno = EINVAL;
1793 0 : return NULL;
1794 : }
1795 :
1796 : {
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;
1807 :
1808 : /* Allocate a small buffer that will hold a directive passed to
1809 : sprintf or snprintf. */
1810 0 : buf_neededlength =
1811 0 : xsum4 (7, d.max_width_length, d.max_precision_length, 6);
1812 : #if HAVE_ALLOCA
1813 0 : if (buf_neededlength < 4000 / sizeof (TCHAR_T))
1814 : {
1815 0 : buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
1816 0 : buf_malloced = NULL;
1817 : }
1818 : else
1819 : #endif
1820 : {
1821 0 : size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
1822 0 : if (size_overflow_p (buf_memsize))
1823 0 : goto out_of_memory_1;
1824 0 : buf = (TCHAR_T *) malloc (buf_memsize);
1825 0 : if (buf == NULL)
1826 0 : goto out_of_memory_1;
1827 0 : buf_malloced = buf;
1828 : }
1829 :
1830 0 : if (resultbuf != NULL)
1831 : {
1832 0 : result = resultbuf;
1833 0 : allocated = *lengthp;
1834 : }
1835 : else
1836 : {
1837 0 : result = NULL;
1838 0 : allocated = 0;
1839 : }
1840 0 : length = 0;
1841 : /* Invariants:
1842 : result is either == resultbuf or == NULL or malloc-allocated.
1843 : If length > 0, then result != NULL. */
1844 :
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) \
1849 : { \
1850 : size_t memory_size; \
1851 : DCHAR_T *memory; \
1852 : \
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; \
1868 : }
1869 :
1870 0 : for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
1871 : {
1872 0 : if (cp != dp->dir_start)
1873 : {
1874 0 : size_t n = dp->dir_start - cp;
1875 0 : size_t augmented_length = xsum (length, n);
1876 :
1877 0 : 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))
1882 : {
1883 0 : DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
1884 0 : length = augmented_length;
1885 : }
1886 : else
1887 : {
1888 : do
1889 : result[length++] = *cp++;
1890 : while (--n > 0);
1891 : }
1892 : }
1893 0 : if (i == d.count)
1894 0 : break;
1895 :
1896 : /* Execute a single directive. */
1897 0 : if (dp->conversion == '%')
1898 : {
1899 : size_t augmented_length;
1900 :
1901 0 : if (!(dp->arg_index == ARG_NONE))
1902 0 : abort ();
1903 0 : augmented_length = xsum (length, 1);
1904 0 : ENSURE_ALLOCATION (augmented_length);
1905 0 : result[length] = '%';
1906 0 : length = augmented_length;
1907 : }
1908 : else
1909 : {
1910 0 : if (!(dp->arg_index != ARG_NONE))
1911 0 : abort ();
1912 :
1913 0 : if (dp->conversion == 'n')
1914 : {
1915 0 : switch (a.arg[dp->arg_index].type)
1916 : {
1917 : case TYPE_COUNT_SCHAR_POINTER:
1918 0 : *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
1919 0 : break;
1920 : case TYPE_COUNT_SHORT_POINTER:
1921 0 : *a.arg[dp->arg_index].a.a_count_short_pointer = length;
1922 0 : break;
1923 : case TYPE_COUNT_INT_POINTER:
1924 0 : *a.arg[dp->arg_index].a.a_count_int_pointer = length;
1925 0 : break;
1926 : case TYPE_COUNT_LONGINT_POINTER:
1927 0 : *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
1928 0 : break;
1929 : #if HAVE_LONG_LONG_INT
1930 : case TYPE_COUNT_LONGLONGINT_POINTER:
1931 0 : *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
1932 0 : break;
1933 : #endif
1934 : default:
1935 0 : abort ();
1936 : }
1937 : }
1938 : #if ENABLE_UNISTDIO
1939 : /* The unistdio extensions. */
1940 : else if (dp->conversion == 'U')
1941 : {
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;
1948 :
1949 : has_width = 0;
1950 : width = 0;
1951 : if (dp->width_start != dp->width_end)
1952 : {
1953 : if (dp->width_arg_index != ARG_NONE)
1954 : {
1955 : int arg;
1956 :
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 : width = arg;
1961 : if (arg < 0)
1962 : {
1963 : /* "A negative field width is taken as a '-' flag
1964 : followed by a positive field width." */
1965 : flags |= FLAG_LEFT;
1966 : width = -width;
1967 : }
1968 : }
1969 : else
1970 : {
1971 : const FCHAR_T *digitp = dp->width_start;
1972 :
1973 : do
1974 : width = xsum (xtimes (width, 10), *digitp++ - '0');
1975 : while (digitp != dp->width_end);
1976 : }
1977 : has_width = 1;
1978 : }
1979 :
1980 : has_precision = 0;
1981 : precision = 0;
1982 : if (dp->precision_start != dp->precision_end)
1983 : {
1984 : if (dp->precision_arg_index != ARG_NONE)
1985 : {
1986 : int arg;
1987 :
1988 : if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1989 : abort ();
1990 : arg = a.arg[dp->precision_arg_index].a.a_int;
1991 : /* "A negative precision is taken as if the precision
1992 : were omitted." */
1993 : if (arg >= 0)
1994 : {
1995 : precision = arg;
1996 : has_precision = 1;
1997 : }
1998 : }
1999 : else
2000 : {
2001 : const FCHAR_T *digitp = dp->precision_start + 1;
2002 :
2003 : precision = 0;
2004 : while (digitp != dp->precision_end)
2005 : precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2006 : has_precision = 1;
2007 : }
2008 : }
2009 :
2010 : switch (type)
2011 : {
2012 : case TYPE_U8_STRING:
2013 : {
2014 : const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
2015 : const uint8_t *arg_end;
2016 : size_t characters;
2017 :
2018 : if (has_precision)
2019 : {
2020 : /* Use only PRECISION characters, from the left. */
2021 : arg_end = arg;
2022 : characters = 0;
2023 : for (; precision > 0; precision--)
2024 : {
2025 : int count = u8_strmblen (arg_end);
2026 : if (count == 0)
2027 : break;
2028 : if (count < 0)
2029 : {
2030 : if (!(result == resultbuf || result == NULL))
2031 : free (result);
2032 : if (buf_malloced != NULL)
2033 : free (buf_malloced);
2034 : CLEANUP ();
2035 : errno = EILSEQ;
2036 : return NULL;
2037 : }
2038 : arg_end += count;
2039 : characters++;
2040 : }
2041 : }
2042 : else if (has_width)
2043 : {
2044 : /* Use the entire string, and count the number of
2045 : characters. */
2046 : arg_end = arg;
2047 : characters = 0;
2048 : for (;;)
2049 : {
2050 : int count = u8_strmblen (arg_end);
2051 : if (count == 0)
2052 : break;
2053 : if (count < 0)
2054 : {
2055 : if (!(result == resultbuf || result == NULL))
2056 : free (result);
2057 : if (buf_malloced != NULL)
2058 : free (buf_malloced);
2059 : CLEANUP ();
2060 : errno = EILSEQ;
2061 : return NULL;
2062 : }
2063 : arg_end += count;
2064 : characters++;
2065 : }
2066 : }
2067 : else
2068 : {
2069 : /* Use the entire string. */
2070 : arg_end = arg + u8_strlen (arg);
2071 : /* The number of characters doesn't matter. */
2072 : characters = 0;
2073 : }
2074 :
2075 : if (characters < width && !(dp->flags & FLAG_LEFT))
2076 : {
2077 : size_t n = width - characters;
2078 : ENSURE_ALLOCATION (xsum (length, n));
2079 : DCHAR_SET (result + length, ' ', n);
2080 : length += n;
2081 : }
2082 :
2083 : # if DCHAR_IS_UINT8_T
2084 : {
2085 : size_t n = arg_end - arg;
2086 : ENSURE_ALLOCATION (xsum (length, n));
2087 : DCHAR_CPY (result + length, arg, n);
2088 : length += n;
2089 : }
2090 : # else
2091 : { /* Convert. */
2092 : DCHAR_T *converted = result + length;
2093 : size_t converted_len = allocated - length;
2094 : # if DCHAR_IS_TCHAR
2095 : /* Convert from UTF-8 to locale encoding. */
2096 : converted =
2097 : u8_conv_to_encoding (locale_charset (),
2098 : iconveh_question_mark,
2099 : arg, arg_end - arg, NULL,
2100 : converted, &converted_len);
2101 : # else
2102 : /* Convert from UTF-8 to UTF-16/UTF-32. */
2103 : converted =
2104 : U8_TO_DCHAR (arg, arg_end - arg,
2105 : converted, &converted_len);
2106 : # endif
2107 : if (converted == NULL)
2108 : {
2109 : int saved_errno = errno;
2110 : if (!(result == resultbuf || result == NULL))
2111 : free (result);
2112 : if (buf_malloced != NULL)
2113 : free (buf_malloced);
2114 : CLEANUP ();
2115 : errno = saved_errno;
2116 : return NULL;
2117 : }
2118 : if (converted != result + length)
2119 : {
2120 : ENSURE_ALLOCATION (xsum (length, converted_len));
2121 : DCHAR_CPY (result + length, converted, converted_len);
2122 : free (converted);
2123 : }
2124 : length += converted_len;
2125 : }
2126 : # endif
2127 :
2128 : if (characters < width && (dp->flags & FLAG_LEFT))
2129 : {
2130 : size_t n = width - characters;
2131 : ENSURE_ALLOCATION (xsum (length, n));
2132 : DCHAR_SET (result + length, ' ', n);
2133 : length += n;
2134 : }
2135 : }
2136 : break;
2137 :
2138 : case TYPE_U16_STRING:
2139 : {
2140 : const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
2141 : const uint16_t *arg_end;
2142 : size_t characters;
2143 :
2144 : if (has_precision)
2145 : {
2146 : /* Use only PRECISION characters, from the left. */
2147 : arg_end = arg;
2148 : characters = 0;
2149 : for (; precision > 0; precision--)
2150 : {
2151 : int count = u16_strmblen (arg_end);
2152 : if (count == 0)
2153 : break;
2154 : if (count < 0)
2155 : {
2156 : if (!(result == resultbuf || result == NULL))
2157 : free (result);
2158 : if (buf_malloced != NULL)
2159 : free (buf_malloced);
2160 : CLEANUP ();
2161 : errno = EILSEQ;
2162 : return NULL;
2163 : }
2164 : arg_end += count;
2165 : characters++;
2166 : }
2167 : }
2168 : else if (has_width)
2169 : {
2170 : /* Use the entire string, and count the number of
2171 : characters. */
2172 : arg_end = arg;
2173 : characters = 0;
2174 : for (;;)
2175 : {
2176 : int count = u16_strmblen (arg_end);
2177 : if (count == 0)
2178 : break;
2179 : if (count < 0)
2180 : {
2181 : if (!(result == resultbuf || result == NULL))
2182 : free (result);
2183 : if (buf_malloced != NULL)
2184 : free (buf_malloced);
2185 : CLEANUP ();
2186 : errno = EILSEQ;
2187 : return NULL;
2188 : }
2189 : arg_end += count;
2190 : characters++;
2191 : }
2192 : }
2193 : else
2194 : {
2195 : /* Use the entire string. */
2196 : arg_end = arg + u16_strlen (arg);
2197 : /* The number of characters doesn't matter. */
2198 : characters = 0;
2199 : }
2200 :
2201 : if (characters < width && !(dp->flags & FLAG_LEFT))
2202 : {
2203 : size_t n = width - characters;
2204 : ENSURE_ALLOCATION (xsum (length, n));
2205 : DCHAR_SET (result + length, ' ', n);
2206 : length += n;
2207 : }
2208 :
2209 : # if DCHAR_IS_UINT16_T
2210 : {
2211 : size_t n = arg_end - arg;
2212 : ENSURE_ALLOCATION (xsum (length, n));
2213 : DCHAR_CPY (result + length, arg, n);
2214 : length += n;
2215 : }
2216 : # else
2217 : { /* Convert. */
2218 : DCHAR_T *converted = result + length;
2219 : size_t converted_len = allocated - length;
2220 : # if DCHAR_IS_TCHAR
2221 : /* Convert from UTF-16 to locale encoding. */
2222 : converted =
2223 : u16_conv_to_encoding (locale_charset (),
2224 : iconveh_question_mark,
2225 : arg, arg_end - arg, NULL,
2226 : converted, &converted_len);
2227 : # else
2228 : /* Convert from UTF-16 to UTF-8/UTF-32. */
2229 : converted =
2230 : U16_TO_DCHAR (arg, arg_end - arg,
2231 : converted, &converted_len);
2232 : # endif
2233 : if (converted == NULL)
2234 : {
2235 : int saved_errno = errno;
2236 : if (!(result == resultbuf || result == NULL))
2237 : free (result);
2238 : if (buf_malloced != NULL)
2239 : free (buf_malloced);
2240 : CLEANUP ();
2241 : errno = saved_errno;
2242 : return NULL;
2243 : }
2244 : if (converted != result + length)
2245 : {
2246 : ENSURE_ALLOCATION (xsum (length, converted_len));
2247 : DCHAR_CPY (result + length, converted, converted_len);
2248 : free (converted);
2249 : }
2250 : length += converted_len;
2251 : }
2252 : # endif
2253 :
2254 : if (characters < width && (dp->flags & FLAG_LEFT))
2255 : {
2256 : size_t n = width - characters;
2257 : ENSURE_ALLOCATION (xsum (length, n));
2258 : DCHAR_SET (result + length, ' ', n);
2259 : length += n;
2260 : }
2261 : }
2262 : break;
2263 :
2264 : case TYPE_U32_STRING:
2265 : {
2266 : const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
2267 : const uint32_t *arg_end;
2268 : size_t characters;
2269 :
2270 : if (has_precision)
2271 : {
2272 : /* Use only PRECISION characters, from the left. */
2273 : arg_end = arg;
2274 : characters = 0;
2275 : for (; precision > 0; precision--)
2276 : {
2277 : int count = u32_strmblen (arg_end);
2278 : if (count == 0)
2279 : break;
2280 : if (count < 0)
2281 : {
2282 : if (!(result == resultbuf || result == NULL))
2283 : free (result);
2284 : if (buf_malloced != NULL)
2285 : free (buf_malloced);
2286 : CLEANUP ();
2287 : errno = EILSEQ;
2288 : return NULL;
2289 : }
2290 : arg_end += count;
2291 : characters++;
2292 : }
2293 : }
2294 : else if (has_width)
2295 : {
2296 : /* Use the entire string, and count the number of
2297 : characters. */
2298 : arg_end = arg;
2299 : characters = 0;
2300 : for (;;)
2301 : {
2302 : int count = u32_strmblen (arg_end);
2303 : if (count == 0)
2304 : break;
2305 : if (count < 0)
2306 : {
2307 : if (!(result == resultbuf || result == NULL))
2308 : free (result);
2309 : if (buf_malloced != NULL)
2310 : free (buf_malloced);
2311 : CLEANUP ();
2312 : errno = EILSEQ;
2313 : return NULL;
2314 : }
2315 : arg_end += count;
2316 : characters++;
2317 : }
2318 : }
2319 : else
2320 : {
2321 : /* Use the entire string. */
2322 : arg_end = arg + u32_strlen (arg);
2323 : /* The number of characters doesn't matter. */
2324 : characters = 0;
2325 : }
2326 :
2327 : if (characters < width && !(dp->flags & FLAG_LEFT))
2328 : {
2329 : size_t n = width - characters;
2330 : ENSURE_ALLOCATION (xsum (length, n));
2331 : DCHAR_SET (result + length, ' ', n);
2332 : length += n;
2333 : }
2334 :
2335 : # if DCHAR_IS_UINT32_T
2336 : {
2337 : size_t n = arg_end - arg;
2338 : ENSURE_ALLOCATION (xsum (length, n));
2339 : DCHAR_CPY (result + length, arg, n);
2340 : length += n;
2341 : }
2342 : # else
2343 : { /* Convert. */
2344 : DCHAR_T *converted = result + length;
2345 : size_t converted_len = allocated - length;
2346 : # if DCHAR_IS_TCHAR
2347 : /* Convert from UTF-32 to locale encoding. */
2348 : converted =
2349 : u32_conv_to_encoding (locale_charset (),
2350 : iconveh_question_mark,
2351 : arg, arg_end - arg, NULL,
2352 : converted, &converted_len);
2353 : # else
2354 : /* Convert from UTF-32 to UTF-8/UTF-16. */
2355 : converted =
2356 : U32_TO_DCHAR (arg, arg_end - arg,
2357 : converted, &converted_len);
2358 : # endif
2359 : if (converted == NULL)
2360 : {
2361 : int saved_errno = errno;
2362 : if (!(result == resultbuf || result == NULL))
2363 : free (result);
2364 : if (buf_malloced != NULL)
2365 : free (buf_malloced);
2366 : CLEANUP ();
2367 : errno = saved_errno;
2368 : return NULL;
2369 : }
2370 : if (converted != result + length)
2371 : {
2372 : ENSURE_ALLOCATION (xsum (length, converted_len));
2373 : DCHAR_CPY (result + length, converted, converted_len);
2374 : free (converted);
2375 : }
2376 : length += converted_len;
2377 : }
2378 : # endif
2379 :
2380 : if (characters < width && (dp->flags & FLAG_LEFT))
2381 : {
2382 : size_t n = width - characters;
2383 : ENSURE_ALLOCATION (xsum (length, n));
2384 : DCHAR_SET (result + length, ' ', n);
2385 : length += n;
2386 : }
2387 : }
2388 : break;
2389 :
2390 : default:
2391 : abort ();
2392 : }
2393 : }
2394 : #endif
2395 : #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
2396 : else if (dp->conversion == 's'
2397 : # if WIDE_CHAR_VERSION
2398 : && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
2399 : # else
2400 : && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
2401 : # endif
2402 : )
2403 : {
2404 : /* The normal handling of the 's' directive below requires
2405 : allocating a temporary buffer. The determination of its
2406 : length (tmp_length), in the case when a precision is
2407 : specified, below requires a conversion between a char[]
2408 : string and a wchar_t[] wide string. It could be done, but
2409 : we have no guarantee that the implementation of sprintf will
2410 : use the exactly same algorithm. Without this guarantee, it
2411 : is possible to have buffer overrun bugs. In order to avoid
2412 : such bugs, we implement the entire processing of the 's'
2413 : directive ourselves. */
2414 : int flags = dp->flags;
2415 : int has_width;
2416 : size_t width;
2417 : int has_precision;
2418 : size_t precision;
2419 :
2420 : has_width = 0;
2421 : width = 0;
2422 : if (dp->width_start != dp->width_end)
2423 : {
2424 : if (dp->width_arg_index != ARG_NONE)
2425 : {
2426 : int arg;
2427 :
2428 : if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2429 : abort ();
2430 : arg = a.arg[dp->width_arg_index].a.a_int;
2431 : width = arg;
2432 : if (arg < 0)
2433 : {
2434 : /* "A negative field width is taken as a '-' flag
2435 : followed by a positive field width." */
2436 : flags |= FLAG_LEFT;
2437 : width = -width;
2438 : }
2439 : }
2440 : else
2441 : {
2442 : const FCHAR_T *digitp = dp->width_start;
2443 :
2444 : do
2445 : width = xsum (xtimes (width, 10), *digitp++ - '0');
2446 : while (digitp != dp->width_end);
2447 : }
2448 : has_width = 1;
2449 : }
2450 :
2451 : has_precision = 0;
2452 : precision = 6;
2453 : if (dp->precision_start != dp->precision_end)
2454 : {
2455 : if (dp->precision_arg_index != ARG_NONE)
2456 : {
2457 : int arg;
2458 :
2459 : if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2460 : abort ();
2461 : arg = a.arg[dp->precision_arg_index].a.a_int;
2462 : /* "A negative precision is taken as if the precision
2463 : were omitted." */
2464 : if (arg >= 0)
2465 : {
2466 : precision = arg;
2467 : has_precision = 1;
2468 : }
2469 : }
2470 : else
2471 : {
2472 : const FCHAR_T *digitp = dp->precision_start + 1;
2473 :
2474 : precision = 0;
2475 : while (digitp != dp->precision_end)
2476 : precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2477 : has_precision = 1;
2478 : }
2479 : }
2480 :
2481 : # if WIDE_CHAR_VERSION
2482 : /* %s in vasnwprintf. See the specification of fwprintf. */
2483 : {
2484 : const char *arg = a.arg[dp->arg_index].a.a_string;
2485 : const char *arg_end;
2486 : size_t characters;
2487 :
2488 : if (has_precision)
2489 : {
2490 : /* Use only as many bytes as needed to produce PRECISION
2491 : wide characters, from the left. */
2492 : # if HAVE_MBRTOWC
2493 : mbstate_t state;
2494 : memset (&state, '\0', sizeof (mbstate_t));
2495 : # endif
2496 : arg_end = arg;
2497 : characters = 0;
2498 : for (; precision > 0; precision--)
2499 : {
2500 : int count;
2501 : # if HAVE_MBRTOWC
2502 : count = mbrlen (arg_end, MB_CUR_MAX, &state);
2503 : # else
2504 : count = mblen (arg_end, MB_CUR_MAX);
2505 : # endif
2506 : if (count == 0)
2507 : /* Found the terminating NUL. */
2508 : break;
2509 : if (count < 0)
2510 : {
2511 : /* Invalid or incomplete multibyte character. */
2512 : if (!(result == resultbuf || result == NULL))
2513 : free (result);
2514 : if (buf_malloced != NULL)
2515 : free (buf_malloced);
2516 : CLEANUP ();
2517 : errno = EILSEQ;
2518 : return NULL;
2519 : }
2520 : arg_end += count;
2521 : characters++;
2522 : }
2523 : }
2524 : else if (has_width)
2525 : {
2526 : /* Use the entire string, and count the number of wide
2527 : characters. */
2528 : # if HAVE_MBRTOWC
2529 : mbstate_t state;
2530 : memset (&state, '\0', sizeof (mbstate_t));
2531 : # endif
2532 : arg_end = arg;
2533 : characters = 0;
2534 : for (;;)
2535 : {
2536 : int count;
2537 : # if HAVE_MBRTOWC
2538 : count = mbrlen (arg_end, MB_CUR_MAX, &state);
2539 : # else
2540 : count = mblen (arg_end, MB_CUR_MAX);
2541 : # endif
2542 : if (count == 0)
2543 : /* Found the terminating NUL. */
2544 : break;
2545 : if (count < 0)
2546 : {
2547 : /* Invalid or incomplete multibyte character. */
2548 : if (!(result == resultbuf || result == NULL))
2549 : free (result);
2550 : if (buf_malloced != NULL)
2551 : free (buf_malloced);
2552 : CLEANUP ();
2553 : errno = EILSEQ;
2554 : return NULL;
2555 : }
2556 : arg_end += count;
2557 : characters++;
2558 : }
2559 : }
2560 : else
2561 : {
2562 : /* Use the entire string. */
2563 : arg_end = arg + strlen (arg);
2564 : /* The number of characters doesn't matter. */
2565 : characters = 0;
2566 : }
2567 :
2568 : if (characters < width && !(dp->flags & FLAG_LEFT))
2569 : {
2570 : size_t n = width - characters;
2571 : ENSURE_ALLOCATION (xsum (length, n));
2572 : DCHAR_SET (result + length, ' ', n);
2573 : length += n;
2574 : }
2575 :
2576 : if (has_precision || has_width)
2577 : {
2578 : /* We know the number of wide characters in advance. */
2579 : size_t remaining;
2580 : # if HAVE_MBRTOWC
2581 : mbstate_t state;
2582 : memset (&state, '\0', sizeof (mbstate_t));
2583 : # endif
2584 : ENSURE_ALLOCATION (xsum (length, characters));
2585 : for (remaining = characters; remaining > 0; remaining--)
2586 : {
2587 : wchar_t wc;
2588 : int count;
2589 : # if HAVE_MBRTOWC
2590 : count = mbrtowc (&wc, arg, arg_end - arg, &state);
2591 : # else
2592 : count = mbtowc (&wc, arg, arg_end - arg);
2593 : # endif
2594 : if (count <= 0)
2595 : /* mbrtowc not consistent with mbrlen, or mbtowc
2596 : not consistent with mblen. */
2597 : abort ();
2598 : result[length++] = wc;
2599 : arg += count;
2600 : }
2601 : if (!(arg == arg_end))
2602 : abort ();
2603 : }
2604 : else
2605 : {
2606 : # if HAVE_MBRTOWC
2607 : mbstate_t state;
2608 : memset (&state, '\0', sizeof (mbstate_t));
2609 : # endif
2610 : while (arg < arg_end)
2611 : {
2612 : wchar_t wc;
2613 : int count;
2614 : # if HAVE_MBRTOWC
2615 : count = mbrtowc (&wc, arg, arg_end - arg, &state);
2616 : # else
2617 : count = mbtowc (&wc, arg, arg_end - arg);
2618 : # endif
2619 : if (count <= 0)
2620 : /* mbrtowc not consistent with mbrlen, or mbtowc
2621 : not consistent with mblen. */
2622 : abort ();
2623 : ENSURE_ALLOCATION (xsum (length, 1));
2624 : result[length++] = wc;
2625 : arg += count;
2626 : }
2627 : }
2628 :
2629 : if (characters < width && (dp->flags & FLAG_LEFT))
2630 : {
2631 : size_t n = width - characters;
2632 : ENSURE_ALLOCATION (xsum (length, n));
2633 : DCHAR_SET (result + length, ' ', n);
2634 : length += n;
2635 : }
2636 : }
2637 : # else
2638 : /* %ls in vasnprintf. See the specification of fprintf. */
2639 : {
2640 : const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
2641 : const wchar_t *arg_end;
2642 : size_t characters;
2643 : # if !DCHAR_IS_TCHAR
2644 : /* This code assumes that TCHAR_T is 'char'. */
2645 : verify (sizeof (TCHAR_T) == 1);
2646 : TCHAR_T *tmpsrc;
2647 : DCHAR_T *tmpdst;
2648 : size_t tmpdst_len;
2649 : # endif
2650 : size_t w;
2651 :
2652 : if (has_precision)
2653 : {
2654 : /* Use only as many wide characters as needed to produce
2655 : at most PRECISION bytes, from the left. */
2656 : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2657 : mbstate_t state;
2658 : memset (&state, '\0', sizeof (mbstate_t));
2659 : # endif
2660 : arg_end = arg;
2661 : characters = 0;
2662 : while (precision > 0)
2663 : {
2664 : char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2665 : int count;
2666 :
2667 : if (*arg_end == 0)
2668 : /* Found the terminating null wide character. */
2669 : break;
2670 : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2671 : count = wcrtomb (cbuf, *arg_end, &state);
2672 : # else
2673 : count = wctomb (cbuf, *arg_end);
2674 : # endif
2675 : if (count < 0)
2676 : {
2677 : /* Cannot convert. */
2678 : if (!(result == resultbuf || result == NULL))
2679 : free (result);
2680 : if (buf_malloced != NULL)
2681 : free (buf_malloced);
2682 : CLEANUP ();
2683 : errno = EILSEQ;
2684 : return NULL;
2685 : }
2686 : if (precision < count)
2687 : break;
2688 : arg_end++;
2689 : characters += count;
2690 : precision -= count;
2691 : }
2692 : }
2693 : # if DCHAR_IS_TCHAR
2694 : else if (has_width)
2695 : # else
2696 : else
2697 : # endif
2698 : {
2699 : /* Use the entire string, and count the number of
2700 : bytes. */
2701 : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2702 : mbstate_t state;
2703 : memset (&state, '\0', sizeof (mbstate_t));
2704 : # endif
2705 : arg_end = arg;
2706 : characters = 0;
2707 : for (;;)
2708 : {
2709 : char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2710 : int count;
2711 :
2712 : if (*arg_end == 0)
2713 : /* Found the terminating null wide character. */
2714 : break;
2715 : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2716 : count = wcrtomb (cbuf, *arg_end, &state);
2717 : # else
2718 : count = wctomb (cbuf, *arg_end);
2719 : # endif
2720 : if (count < 0)
2721 : {
2722 : /* Cannot convert. */
2723 : if (!(result == resultbuf || result == NULL))
2724 : free (result);
2725 : if (buf_malloced != NULL)
2726 : free (buf_malloced);
2727 : CLEANUP ();
2728 : errno = EILSEQ;
2729 : return NULL;
2730 : }
2731 : arg_end++;
2732 : characters += count;
2733 : }
2734 : }
2735 : # if DCHAR_IS_TCHAR
2736 : else
2737 : {
2738 : /* Use the entire string. */
2739 : arg_end = arg + local_wcslen (arg);
2740 : /* The number of bytes doesn't matter. */
2741 : characters = 0;
2742 : }
2743 : # endif
2744 :
2745 : # if !DCHAR_IS_TCHAR
2746 : /* Convert the string into a piece of temporary memory. */
2747 : tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
2748 : if (tmpsrc == NULL)
2749 : goto out_of_memory;
2750 : {
2751 : TCHAR_T *tmpptr = tmpsrc;
2752 : size_t remaining;
2753 : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2754 : mbstate_t state;
2755 : memset (&state, '\0', sizeof (mbstate_t));
2756 : # endif
2757 : for (remaining = characters; remaining > 0; )
2758 : {
2759 : char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2760 : int count;
2761 :
2762 : if (*arg == 0)
2763 : abort ();
2764 : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2765 : count = wcrtomb (cbuf, *arg, &state);
2766 : # else
2767 : count = wctomb (cbuf, *arg);
2768 : # endif
2769 : if (count <= 0)
2770 : /* Inconsistency. */
2771 : abort ();
2772 : memcpy (tmpptr, cbuf, count);
2773 : tmpptr += count;
2774 : arg++;
2775 : remaining -= count;
2776 : }
2777 : if (!(arg == arg_end))
2778 : abort ();
2779 : }
2780 :
2781 : /* Convert from TCHAR_T[] to DCHAR_T[]. */
2782 : tmpdst =
2783 : DCHAR_CONV_FROM_ENCODING (locale_charset (),
2784 : iconveh_question_mark,
2785 : tmpsrc, characters,
2786 : NULL,
2787 : NULL, &tmpdst_len);
2788 : if (tmpdst == NULL)
2789 : {
2790 : int saved_errno = errno;
2791 : free (tmpsrc);
2792 : if (!(result == resultbuf || result == NULL))
2793 : free (result);
2794 : if (buf_malloced != NULL)
2795 : free (buf_malloced);
2796 : CLEANUP ();
2797 : errno = saved_errno;
2798 : return NULL;
2799 : }
2800 : free (tmpsrc);
2801 : # endif
2802 :
2803 : if (has_width)
2804 : {
2805 : # if ENABLE_UNISTDIO
2806 : /* Outside POSIX, it's preferable to compare the width
2807 : against the number of _characters_ of the converted
2808 : value. */
2809 : w = DCHAR_MBSNLEN (result + length, characters);
2810 : # else
2811 : /* The width is compared against the number of _bytes_
2812 : of the converted value, says POSIX. */
2813 : w = characters;
2814 : # endif
2815 : }
2816 : else
2817 : /* w doesn't matter. */
2818 : w = 0;
2819 :
2820 : if (w < width && !(dp->flags & FLAG_LEFT))
2821 : {
2822 : size_t n = width - w;
2823 : ENSURE_ALLOCATION (xsum (length, n));
2824 : DCHAR_SET (result + length, ' ', n);
2825 : length += n;
2826 : }
2827 :
2828 : # if DCHAR_IS_TCHAR
2829 : if (has_precision || has_width)
2830 : {
2831 : /* We know the number of bytes in advance. */
2832 : size_t remaining;
2833 : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2834 : mbstate_t state;
2835 : memset (&state, '\0', sizeof (mbstate_t));
2836 : # endif
2837 : ENSURE_ALLOCATION (xsum (length, characters));
2838 : for (remaining = characters; remaining > 0; )
2839 : {
2840 : char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2841 : int count;
2842 :
2843 : if (*arg == 0)
2844 : abort ();
2845 : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2846 : count = wcrtomb (cbuf, *arg, &state);
2847 : # else
2848 : count = wctomb (cbuf, *arg);
2849 : # endif
2850 : if (count <= 0)
2851 : /* Inconsistency. */
2852 : abort ();
2853 : memcpy (result + length, cbuf, count);
2854 : length += count;
2855 : arg++;
2856 : remaining -= count;
2857 : }
2858 : if (!(arg == arg_end))
2859 : abort ();
2860 : }
2861 : else
2862 : {
2863 : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2864 : mbstate_t state;
2865 : memset (&state, '\0', sizeof (mbstate_t));
2866 : # endif
2867 : while (arg < arg_end)
2868 : {
2869 : char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2870 : int count;
2871 :
2872 : if (*arg == 0)
2873 : abort ();
2874 : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2875 : count = wcrtomb (cbuf, *arg, &state);
2876 : # else
2877 : count = wctomb (cbuf, *arg);
2878 : # endif
2879 : if (count <= 0)
2880 : {
2881 : /* Cannot convert. */
2882 : if (!(result == resultbuf || result == NULL))
2883 : free (result);
2884 : if (buf_malloced != NULL)
2885 : free (buf_malloced);
2886 : CLEANUP ();
2887 : errno = EILSEQ;
2888 : return NULL;
2889 : }
2890 : ENSURE_ALLOCATION (xsum (length, count));
2891 : memcpy (result + length, cbuf, count);
2892 : length += count;
2893 : arg++;
2894 : }
2895 : }
2896 : # else
2897 : ENSURE_ALLOCATION (xsum (length, tmpdst_len));
2898 : DCHAR_CPY (result + length, tmpdst, tmpdst_len);
2899 : free (tmpdst);
2900 : length += tmpdst_len;
2901 : # endif
2902 :
2903 : if (w < width && (dp->flags & FLAG_LEFT))
2904 : {
2905 : size_t n = width - w;
2906 : ENSURE_ALLOCATION (xsum (length, n));
2907 : DCHAR_SET (result + length, ' ', n);
2908 : length += n;
2909 : }
2910 : }
2911 : # endif
2912 : }
2913 : #endif
2914 : #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
2915 : else if ((dp->conversion == 'a' || dp->conversion == 'A')
2916 : # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
2917 : && (0
2918 : # if NEED_PRINTF_DOUBLE
2919 : || a.arg[dp->arg_index].type == TYPE_DOUBLE
2920 : # endif
2921 : # if NEED_PRINTF_LONG_DOUBLE
2922 : || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2923 : # endif
2924 : )
2925 : # endif
2926 : )
2927 : {
2928 : arg_type type = a.arg[dp->arg_index].type;
2929 : int flags = dp->flags;
2930 : size_t width;
2931 : int has_precision;
2932 : size_t precision;
2933 : size_t tmp_length;
2934 : size_t count;
2935 : DCHAR_T tmpbuf[700];
2936 : DCHAR_T *tmp;
2937 : DCHAR_T *pad_ptr;
2938 : DCHAR_T *p;
2939 :
2940 : width = 0;
2941 : if (dp->width_start != dp->width_end)
2942 : {
2943 : if (dp->width_arg_index != ARG_NONE)
2944 : {
2945 : int arg;
2946 :
2947 : if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2948 : abort ();
2949 : arg = a.arg[dp->width_arg_index].a.a_int;
2950 : width = arg;
2951 : if (arg < 0)
2952 : {
2953 : /* "A negative field width is taken as a '-' flag
2954 : followed by a positive field width." */
2955 : flags |= FLAG_LEFT;
2956 : width = -width;
2957 : }
2958 : }
2959 : else
2960 : {
2961 : const FCHAR_T *digitp = dp->width_start;
2962 :
2963 : do
2964 : width = xsum (xtimes (width, 10), *digitp++ - '0');
2965 : while (digitp != dp->width_end);
2966 : }
2967 : }
2968 :
2969 : has_precision = 0;
2970 : precision = 0;
2971 : if (dp->precision_start != dp->precision_end)
2972 : {
2973 : if (dp->precision_arg_index != ARG_NONE)
2974 : {
2975 : int arg;
2976 :
2977 : if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2978 : abort ();
2979 : arg = a.arg[dp->precision_arg_index].a.a_int;
2980 : /* "A negative precision is taken as if the precision
2981 : were omitted." */
2982 : if (arg >= 0)
2983 : {
2984 : precision = arg;
2985 : has_precision = 1;
2986 : }
2987 : }
2988 : else
2989 : {
2990 : const FCHAR_T *digitp = dp->precision_start + 1;
2991 :
2992 : precision = 0;
2993 : while (digitp != dp->precision_end)
2994 : precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2995 : has_precision = 1;
2996 : }
2997 : }
2998 :
2999 : /* Allocate a temporary buffer of sufficient size. */
3000 : if (type == TYPE_LONGDOUBLE)
3001 : tmp_length =
3002 : (unsigned int) ((LDBL_DIG + 1)
3003 : * 0.831 /* decimal -> hexadecimal */
3004 : )
3005 : + 1; /* turn floor into ceil */
3006 : else
3007 : tmp_length =
3008 : (unsigned int) ((DBL_DIG + 1)
3009 : * 0.831 /* decimal -> hexadecimal */
3010 : )
3011 : + 1; /* turn floor into ceil */
3012 : if (tmp_length < precision)
3013 : tmp_length = precision;
3014 : /* Account for sign, decimal point etc. */
3015 : tmp_length = xsum (tmp_length, 12);
3016 :
3017 : if (tmp_length < width)
3018 : tmp_length = width;
3019 :
3020 : tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3021 :
3022 : if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3023 : tmp = tmpbuf;
3024 : else
3025 : {
3026 : size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3027 :
3028 : if (size_overflow_p (tmp_memsize))
3029 : /* Overflow, would lead to out of memory. */
3030 : goto out_of_memory;
3031 : tmp = (DCHAR_T *) malloc (tmp_memsize);
3032 : if (tmp == NULL)
3033 : /* Out of memory. */
3034 : goto out_of_memory;
3035 : }
3036 :
3037 : pad_ptr = NULL;
3038 : p = tmp;
3039 : if (type == TYPE_LONGDOUBLE)
3040 : {
3041 : # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
3042 : long double arg = a.arg[dp->arg_index].a.a_longdouble;
3043 :
3044 : if (isnanl (arg))
3045 : {
3046 : if (dp->conversion == 'A')
3047 : {
3048 : *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3049 : }
3050 : else
3051 : {
3052 : *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3053 : }
3054 : }
3055 : else
3056 : {
3057 : int sign = 0;
3058 : DECL_LONG_DOUBLE_ROUNDING
3059 :
3060 : BEGIN_LONG_DOUBLE_ROUNDING ();
3061 :
3062 : if (signbit (arg)) /* arg < 0.0L or negative zero */
3063 : {
3064 : sign = -1;
3065 : arg = -arg;
3066 : }
3067 :
3068 : if (sign < 0)
3069 : *p++ = '-';
3070 : else if (flags & FLAG_SHOWSIGN)
3071 : *p++ = '+';
3072 : else if (flags & FLAG_SPACE)
3073 : *p++ = ' ';
3074 :
3075 : if (arg > 0.0L && arg + arg == arg)
3076 : {
3077 : if (dp->conversion == 'A')
3078 : {
3079 : *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3080 : }
3081 : else
3082 : {
3083 : *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3084 : }
3085 : }
3086 : else
3087 : {
3088 : int exponent;
3089 : long double mantissa;
3090 :
3091 : if (arg > 0.0L)
3092 : mantissa = printf_frexpl (arg, &exponent);
3093 : else
3094 : {
3095 : exponent = 0;
3096 : mantissa = 0.0L;
3097 : }
3098 :
3099 : if (has_precision
3100 : && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
3101 : {
3102 : /* Round the mantissa. */
3103 : long double tail = mantissa;
3104 : size_t q;
3105 :
3106 : for (q = precision; ; q--)
3107 : {
3108 : int digit = (int) tail;
3109 : tail -= digit;
3110 : if (q == 0)
3111 : {
3112 : if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
3113 : tail = 1 - tail;
3114 : else
3115 : tail = - tail;
3116 : break;
3117 : }
3118 : tail *= 16.0L;
3119 : }
3120 : if (tail != 0.0L)
3121 : for (q = precision; q > 0; q--)
3122 : tail *= 0.0625L;
3123 : mantissa += tail;
3124 : }
3125 :
3126 : *p++ = '0';
3127 : *p++ = dp->conversion - 'A' + 'X';
3128 : pad_ptr = p;
3129 : {
3130 : int digit;
3131 :
3132 : digit = (int) mantissa;
3133 : mantissa -= digit;
3134 : *p++ = '0' + digit;
3135 : if ((flags & FLAG_ALT)
3136 : || mantissa > 0.0L || precision > 0)
3137 : {
3138 : *p++ = decimal_point_char ();
3139 : /* This loop terminates because we assume
3140 : that FLT_RADIX is a power of 2. */
3141 : while (mantissa > 0.0L)
3142 : {
3143 : mantissa *= 16.0L;
3144 : digit = (int) mantissa;
3145 : mantissa -= digit;
3146 : *p++ = digit
3147 : + (digit < 10
3148 : ? '0'
3149 : : dp->conversion - 10);
3150 : if (precision > 0)
3151 : precision--;
3152 : }
3153 : while (precision > 0)
3154 : {
3155 : *p++ = '0';
3156 : precision--;
3157 : }
3158 : }
3159 : }
3160 : *p++ = dp->conversion - 'A' + 'P';
3161 : # if WIDE_CHAR_VERSION
3162 : {
3163 : static const wchar_t decimal_format[] =
3164 : { '%', '+', 'd', '\0' };
3165 : SNPRINTF (p, 6 + 1, decimal_format, exponent);
3166 : }
3167 : while (*p != '\0')
3168 : p++;
3169 : # else
3170 : if (sizeof (DCHAR_T) == 1)
3171 : {
3172 : sprintf ((char *) p, "%+d", exponent);
3173 : while (*p != '\0')
3174 : p++;
3175 : }
3176 : else
3177 : {
3178 : char expbuf[6 + 1];
3179 : const char *ep;
3180 : sprintf (expbuf, "%+d", exponent);
3181 : for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3182 : p++;
3183 : }
3184 : # endif
3185 : }
3186 :
3187 : END_LONG_DOUBLE_ROUNDING ();
3188 : }
3189 : # else
3190 : abort ();
3191 : # endif
3192 : }
3193 : else
3194 : {
3195 : # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
3196 : double arg = a.arg[dp->arg_index].a.a_double;
3197 :
3198 : if (isnand (arg))
3199 : {
3200 : if (dp->conversion == 'A')
3201 : {
3202 : *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3203 : }
3204 : else
3205 : {
3206 : *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3207 : }
3208 : }
3209 : else
3210 : {
3211 : int sign = 0;
3212 :
3213 : if (signbit (arg)) /* arg < 0.0 or negative zero */
3214 : {
3215 : sign = -1;
3216 : arg = -arg;
3217 : }
3218 :
3219 : if (sign < 0)
3220 : *p++ = '-';
3221 : else if (flags & FLAG_SHOWSIGN)
3222 : *p++ = '+';
3223 : else if (flags & FLAG_SPACE)
3224 : *p++ = ' ';
3225 :
3226 : if (arg > 0.0 && arg + arg == arg)
3227 : {
3228 : if (dp->conversion == 'A')
3229 : {
3230 : *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3231 : }
3232 : else
3233 : {
3234 : *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3235 : }
3236 : }
3237 : else
3238 : {
3239 : int exponent;
3240 : double mantissa;
3241 :
3242 : if (arg > 0.0)
3243 : mantissa = printf_frexp (arg, &exponent);
3244 : else
3245 : {
3246 : exponent = 0;
3247 : mantissa = 0.0;
3248 : }
3249 :
3250 : if (has_precision
3251 : && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
3252 : {
3253 : /* Round the mantissa. */
3254 : double tail = mantissa;
3255 : size_t q;
3256 :
3257 : for (q = precision; ; q--)
3258 : {
3259 : int digit = (int) tail;
3260 : tail -= digit;
3261 : if (q == 0)
3262 : {
3263 : if (digit & 1 ? tail >= 0.5 : tail > 0.5)
3264 : tail = 1 - tail;
3265 : else
3266 : tail = - tail;
3267 : break;
3268 : }
3269 : tail *= 16.0;
3270 : }
3271 : if (tail != 0.0)
3272 : for (q = precision; q > 0; q--)
3273 : tail *= 0.0625;
3274 : mantissa += tail;
3275 : }
3276 :
3277 : *p++ = '0';
3278 : *p++ = dp->conversion - 'A' + 'X';
3279 : pad_ptr = p;
3280 : {
3281 : int digit;
3282 :
3283 : digit = (int) mantissa;
3284 : mantissa -= digit;
3285 : *p++ = '0' + digit;
3286 : if ((flags & FLAG_ALT)
3287 : || mantissa > 0.0 || precision > 0)
3288 : {
3289 : *p++ = decimal_point_char ();
3290 : /* This loop terminates because we assume
3291 : that FLT_RADIX is a power of 2. */
3292 : while (mantissa > 0.0)
3293 : {
3294 : mantissa *= 16.0;
3295 : digit = (int) mantissa;
3296 : mantissa -= digit;
3297 : *p++ = digit
3298 : + (digit < 10
3299 : ? '0'
3300 : : dp->conversion - 10);
3301 : if (precision > 0)
3302 : precision--;
3303 : }
3304 : while (precision > 0)
3305 : {
3306 : *p++ = '0';
3307 : precision--;
3308 : }
3309 : }
3310 : }
3311 : *p++ = dp->conversion - 'A' + 'P';
3312 : # if WIDE_CHAR_VERSION
3313 : {
3314 : static const wchar_t decimal_format[] =
3315 : { '%', '+', 'd', '\0' };
3316 : SNPRINTF (p, 6 + 1, decimal_format, exponent);
3317 : }
3318 : while (*p != '\0')
3319 : p++;
3320 : # else
3321 : if (sizeof (DCHAR_T) == 1)
3322 : {
3323 : sprintf ((char *) p, "%+d", exponent);
3324 : while (*p != '\0')
3325 : p++;
3326 : }
3327 : else
3328 : {
3329 : char expbuf[6 + 1];
3330 : const char *ep;
3331 : sprintf (expbuf, "%+d", exponent);
3332 : for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3333 : p++;
3334 : }
3335 : # endif
3336 : }
3337 : }
3338 : # else
3339 : abort ();
3340 : # endif
3341 : }
3342 :
3343 : /* The generated string now extends from tmp to p, with the
3344 : zero padding insertion point being at pad_ptr. */
3345 : count = p - tmp;
3346 :
3347 : if (count < width)
3348 : {
3349 : size_t pad = width - count;
3350 : DCHAR_T *end = p + pad;
3351 :
3352 : if (flags & FLAG_LEFT)
3353 : {
3354 : /* Pad with spaces on the right. */
3355 : for (; pad > 0; pad--)
3356 : *p++ = ' ';
3357 : }
3358 : else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3359 : {
3360 : /* Pad with zeroes. */
3361 : DCHAR_T *q = end;
3362 :
3363 : while (p > pad_ptr)
3364 : *--q = *--p;
3365 : for (; pad > 0; pad--)
3366 : *p++ = '0';
3367 : }
3368 : else
3369 : {
3370 : /* Pad with spaces on the left. */
3371 : DCHAR_T *q = end;
3372 :
3373 : while (p > tmp)
3374 : *--q = *--p;
3375 : for (; pad > 0; pad--)
3376 : *p++ = ' ';
3377 : }
3378 :
3379 : p = end;
3380 : }
3381 :
3382 : count = p - tmp;
3383 :
3384 : if (count >= tmp_length)
3385 : /* tmp_length was incorrectly calculated - fix the
3386 : code above! */
3387 : abort ();
3388 :
3389 : /* Make room for the result. */
3390 : if (count >= allocated - length)
3391 : {
3392 : size_t n = xsum (length, count);
3393 :
3394 : ENSURE_ALLOCATION (n);
3395 : }
3396 :
3397 : /* Append the result. */
3398 : memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3399 : if (tmp != tmpbuf)
3400 : free (tmp);
3401 : length += count;
3402 : }
3403 : #endif
3404 : #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
3405 : else if ((dp->conversion == 'f' || dp->conversion == 'F'
3406 : || dp->conversion == 'e' || dp->conversion == 'E'
3407 : || dp->conversion == 'g' || dp->conversion == 'G'
3408 : || dp->conversion == 'a' || dp->conversion == 'A')
3409 : && (0
3410 : # if NEED_PRINTF_DOUBLE
3411 : || a.arg[dp->arg_index].type == TYPE_DOUBLE
3412 : # elif NEED_PRINTF_INFINITE_DOUBLE
3413 : || (a.arg[dp->arg_index].type == TYPE_DOUBLE
3414 : /* The systems (mingw) which produce wrong output
3415 : for Inf, -Inf, and NaN also do so for -0.0.
3416 : Therefore we treat this case here as well. */
3417 : && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
3418 : # endif
3419 : # if NEED_PRINTF_LONG_DOUBLE
3420 : || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3421 : # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
3422 : || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3423 : /* Some systems produce wrong output for Inf,
3424 : -Inf, and NaN. Some systems in this category
3425 : (IRIX 5.3) also do so for -0.0. Therefore we
3426 : treat this case here as well. */
3427 : && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
3428 : # endif
3429 : ))
3430 : {
3431 : # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
3432 : arg_type type = a.arg[dp->arg_index].type;
3433 : # endif
3434 : int flags = dp->flags;
3435 : size_t width;
3436 : size_t count;
3437 : int has_precision;
3438 : size_t precision;
3439 : size_t tmp_length;
3440 : DCHAR_T tmpbuf[700];
3441 : DCHAR_T *tmp;
3442 : DCHAR_T *pad_ptr;
3443 : DCHAR_T *p;
3444 :
3445 : width = 0;
3446 : if (dp->width_start != dp->width_end)
3447 : {
3448 : if (dp->width_arg_index != ARG_NONE)
3449 : {
3450 : int arg;
3451 :
3452 : if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3453 : abort ();
3454 : arg = a.arg[dp->width_arg_index].a.a_int;
3455 : width = arg;
3456 : if (arg < 0)
3457 : {
3458 : /* "A negative field width is taken as a '-' flag
3459 : followed by a positive field width." */
3460 : flags |= FLAG_LEFT;
3461 : width = -width;
3462 : }
3463 : }
3464 : else
3465 : {
3466 : const FCHAR_T *digitp = dp->width_start;
3467 :
3468 : do
3469 : width = xsum (xtimes (width, 10), *digitp++ - '0');
3470 : while (digitp != dp->width_end);
3471 : }
3472 : }
3473 :
3474 : has_precision = 0;
3475 : precision = 0;
3476 : if (dp->precision_start != dp->precision_end)
3477 : {
3478 : if (dp->precision_arg_index != ARG_NONE)
3479 : {
3480 : int arg;
3481 :
3482 : if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3483 : abort ();
3484 : arg = a.arg[dp->precision_arg_index].a.a_int;
3485 : /* "A negative precision is taken as if the precision
3486 : were omitted." */
3487 : if (arg >= 0)
3488 : {
3489 : precision = arg;
3490 : has_precision = 1;
3491 : }
3492 : }
3493 : else
3494 : {
3495 : const FCHAR_T *digitp = dp->precision_start + 1;
3496 :
3497 : precision = 0;
3498 : while (digitp != dp->precision_end)
3499 : precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3500 : has_precision = 1;
3501 : }
3502 : }
3503 :
3504 : /* POSIX specifies the default precision to be 6 for %f, %F,
3505 : %e, %E, but not for %g, %G. Implementations appear to use
3506 : the same default precision also for %g, %G. But for %a, %A,
3507 : the default precision is 0. */
3508 : if (!has_precision)
3509 : if (!(dp->conversion == 'a' || dp->conversion == 'A'))
3510 : precision = 6;
3511 :
3512 : /* Allocate a temporary buffer of sufficient size. */
3513 : # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3514 : tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
3515 : # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3516 : tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
3517 : # elif NEED_PRINTF_LONG_DOUBLE
3518 : tmp_length = LDBL_DIG + 1;
3519 : # elif NEED_PRINTF_DOUBLE
3520 : tmp_length = DBL_DIG + 1;
3521 : # else
3522 : tmp_length = 0;
3523 : # endif
3524 : if (tmp_length < precision)
3525 : tmp_length = precision;
3526 : # if NEED_PRINTF_LONG_DOUBLE
3527 : # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3528 : if (type == TYPE_LONGDOUBLE)
3529 : # endif
3530 : if (dp->conversion == 'f' || dp->conversion == 'F')
3531 : {
3532 : long double arg = a.arg[dp->arg_index].a.a_longdouble;
3533 : if (!(isnanl (arg) || arg + arg == arg))
3534 : {
3535 : /* arg is finite and nonzero. */
3536 : int exponent = floorlog10l (arg < 0 ? -arg : arg);
3537 : if (exponent >= 0 && tmp_length < exponent + precision)
3538 : tmp_length = exponent + precision;
3539 : }
3540 : }
3541 : # endif
3542 : # if NEED_PRINTF_DOUBLE
3543 : # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3544 : if (type == TYPE_DOUBLE)
3545 : # endif
3546 : if (dp->conversion == 'f' || dp->conversion == 'F')
3547 : {
3548 : double arg = a.arg[dp->arg_index].a.a_double;
3549 : if (!(isnand (arg) || arg + arg == arg))
3550 : {
3551 : /* arg is finite and nonzero. */
3552 : int exponent = floorlog10 (arg < 0 ? -arg : arg);
3553 : if (exponent >= 0 && tmp_length < exponent + precision)
3554 : tmp_length = exponent + precision;
3555 : }
3556 : }
3557 : # endif
3558 : /* Account for sign, decimal point etc. */
3559 : tmp_length = xsum (tmp_length, 12);
3560 :
3561 : if (tmp_length < width)
3562 : tmp_length = width;
3563 :
3564 : tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3565 :
3566 : if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3567 : tmp = tmpbuf;
3568 : else
3569 : {
3570 : size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3571 :
3572 : if (size_overflow_p (tmp_memsize))
3573 : /* Overflow, would lead to out of memory. */
3574 : goto out_of_memory;
3575 : tmp = (DCHAR_T *) malloc (tmp_memsize);
3576 : if (tmp == NULL)
3577 : /* Out of memory. */
3578 : goto out_of_memory;
3579 : }
3580 :
3581 : pad_ptr = NULL;
3582 : p = tmp;
3583 :
3584 : # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3585 : # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3586 : if (type == TYPE_LONGDOUBLE)
3587 : # endif
3588 : {
3589 : long double arg = a.arg[dp->arg_index].a.a_longdouble;
3590 :
3591 : if (isnanl (arg))
3592 : {
3593 : if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3594 : {
3595 : *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3596 : }
3597 : else
3598 : {
3599 : *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3600 : }
3601 : }
3602 : else
3603 : {
3604 : int sign = 0;
3605 : DECL_LONG_DOUBLE_ROUNDING
3606 :
3607 : BEGIN_LONG_DOUBLE_ROUNDING ();
3608 :
3609 : if (signbit (arg)) /* arg < 0.0L or negative zero */
3610 : {
3611 : sign = -1;
3612 : arg = -arg;
3613 : }
3614 :
3615 : if (sign < 0)
3616 : *p++ = '-';
3617 : else if (flags & FLAG_SHOWSIGN)
3618 : *p++ = '+';
3619 : else if (flags & FLAG_SPACE)
3620 : *p++ = ' ';
3621 :
3622 : if (arg > 0.0L && arg + arg == arg)
3623 : {
3624 : if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3625 : {
3626 : *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3627 : }
3628 : else
3629 : {
3630 : *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3631 : }
3632 : }
3633 : else
3634 : {
3635 : # if NEED_PRINTF_LONG_DOUBLE
3636 : pad_ptr = p;
3637 :
3638 : if (dp->conversion == 'f' || dp->conversion == 'F')
3639 : {
3640 : char *digits;
3641 : size_t ndigits;
3642 :
3643 : digits =
3644 : scale10_round_decimal_long_double (arg, precision);
3645 : if (digits == NULL)
3646 : {
3647 : END_LONG_DOUBLE_ROUNDING ();
3648 : goto out_of_memory;
3649 : }
3650 : ndigits = strlen (digits);
3651 :
3652 : if (ndigits > precision)
3653 : do
3654 : {
3655 : --ndigits;
3656 : *p++ = digits[ndigits];
3657 : }
3658 : while (ndigits > precision);
3659 : else
3660 : *p++ = '0';
3661 : /* Here ndigits <= precision. */
3662 : if ((flags & FLAG_ALT) || precision > 0)
3663 : {
3664 : *p++ = decimal_point_char ();
3665 : for (; precision > ndigits; precision--)
3666 : *p++ = '0';
3667 : while (ndigits > 0)
3668 : {
3669 : --ndigits;
3670 : *p++ = digits[ndigits];
3671 : }
3672 : }
3673 :
3674 : free (digits);
3675 : }
3676 : else if (dp->conversion == 'e' || dp->conversion == 'E')
3677 : {
3678 : int exponent;
3679 :
3680 : if (arg == 0.0L)
3681 : {
3682 : exponent = 0;
3683 : *p++ = '0';
3684 : if ((flags & FLAG_ALT) || precision > 0)
3685 : {
3686 : *p++ = decimal_point_char ();
3687 : for (; precision > 0; precision--)
3688 : *p++ = '0';
3689 : }
3690 : }
3691 : else
3692 : {
3693 : /* arg > 0.0L. */
3694 : int adjusted;
3695 : char *digits;
3696 : size_t ndigits;
3697 :
3698 : exponent = floorlog10l (arg);
3699 : adjusted = 0;
3700 : for (;;)
3701 : {
3702 : digits =
3703 : scale10_round_decimal_long_double (arg,
3704 : (int)precision - exponent);
3705 : if (digits == NULL)
3706 : {
3707 : END_LONG_DOUBLE_ROUNDING ();
3708 : goto out_of_memory;
3709 : }
3710 : ndigits = strlen (digits);
3711 :
3712 : if (ndigits == precision + 1)
3713 : break;
3714 : if (ndigits < precision
3715 : || ndigits > precision + 2)
3716 : /* The exponent was not guessed
3717 : precisely enough. */
3718 : abort ();
3719 : if (adjusted)
3720 : /* None of two values of exponent is
3721 : the right one. Prevent an endless
3722 : loop. */
3723 : abort ();
3724 : free (digits);
3725 : if (ndigits == precision)
3726 : exponent -= 1;
3727 : else
3728 : exponent += 1;
3729 : adjusted = 1;
3730 : }
3731 : /* Here ndigits = precision+1. */
3732 : if (is_borderline (digits, precision))
3733 : {
3734 : /* Maybe the exponent guess was too high
3735 : and a smaller exponent can be reached
3736 : by turning a 10...0 into 9...9x. */
3737 : char *digits2 =
3738 : scale10_round_decimal_long_double (arg,
3739 : (int)precision - exponent + 1);
3740 : if (digits2 == NULL)
3741 : {
3742 : free (digits);
3743 : END_LONG_DOUBLE_ROUNDING ();
3744 : goto out_of_memory;
3745 : }
3746 : if (strlen (digits2) == precision + 1)
3747 : {
3748 : free (digits);
3749 : digits = digits2;
3750 : exponent -= 1;
3751 : }
3752 : else
3753 : free (digits2);
3754 : }
3755 : /* Here ndigits = precision+1. */
3756 :
3757 : *p++ = digits[--ndigits];
3758 : if ((flags & FLAG_ALT) || precision > 0)
3759 : {
3760 : *p++ = decimal_point_char ();
3761 : while (ndigits > 0)
3762 : {
3763 : --ndigits;
3764 : *p++ = digits[ndigits];
3765 : }
3766 : }
3767 :
3768 : free (digits);
3769 : }
3770 :
3771 : *p++ = dp->conversion; /* 'e' or 'E' */
3772 : # if WIDE_CHAR_VERSION
3773 : {
3774 : static const wchar_t decimal_format[] =
3775 : { '%', '+', '.', '2', 'd', '\0' };
3776 : SNPRINTF (p, 6 + 1, decimal_format, exponent);
3777 : }
3778 : while (*p != '\0')
3779 : p++;
3780 : # else
3781 : if (sizeof (DCHAR_T) == 1)
3782 : {
3783 : sprintf ((char *) p, "%+.2d", exponent);
3784 : while (*p != '\0')
3785 : p++;
3786 : }
3787 : else
3788 : {
3789 : char expbuf[6 + 1];
3790 : const char *ep;
3791 : sprintf (expbuf, "%+.2d", exponent);
3792 : for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3793 : p++;
3794 : }
3795 : # endif
3796 : }
3797 : else if (dp->conversion == 'g' || dp->conversion == 'G')
3798 : {
3799 : if (precision == 0)
3800 : precision = 1;
3801 : /* precision >= 1. */
3802 :
3803 : if (arg == 0.0L)
3804 : /* The exponent is 0, >= -4, < precision.
3805 : Use fixed-point notation. */
3806 : {
3807 : size_t ndigits = precision;
3808 : /* Number of trailing zeroes that have to be
3809 : dropped. */
3810 : size_t nzeroes =
3811 : (flags & FLAG_ALT ? 0 : precision - 1);
3812 :
3813 : --ndigits;
3814 : *p++ = '0';
3815 : if ((flags & FLAG_ALT) || ndigits > nzeroes)
3816 : {
3817 : *p++ = decimal_point_char ();
3818 : while (ndigits > nzeroes)
3819 : {
3820 : --ndigits;
3821 : *p++ = '0';
3822 : }
3823 : }
3824 : }
3825 : else
3826 : {
3827 : /* arg > 0.0L. */
3828 : int exponent;
3829 : int adjusted;
3830 : char *digits;
3831 : size_t ndigits;
3832 : size_t nzeroes;
3833 :
3834 : exponent = floorlog10l (arg);
3835 : adjusted = 0;
3836 : for (;;)
3837 : {
3838 : digits =
3839 : scale10_round_decimal_long_double (arg,
3840 : (int)(precision - 1) - exponent);
3841 : if (digits == NULL)
3842 : {
3843 : END_LONG_DOUBLE_ROUNDING ();
3844 : goto out_of_memory;
3845 : }
3846 : ndigits = strlen (digits);
3847 :
3848 : if (ndigits == precision)
3849 : break;
3850 : if (ndigits < precision - 1
3851 : || ndigits > precision + 1)
3852 : /* The exponent was not guessed
3853 : precisely enough. */
3854 : abort ();
3855 : if (adjusted)
3856 : /* None of two values of exponent is
3857 : the right one. Prevent an endless
3858 : loop. */
3859 : abort ();
3860 : free (digits);
3861 : if (ndigits < precision)
3862 : exponent -= 1;
3863 : else
3864 : exponent += 1;
3865 : adjusted = 1;
3866 : }
3867 : /* Here ndigits = precision. */
3868 : if (is_borderline (digits, precision - 1))
3869 : {
3870 : /* Maybe the exponent guess was too high
3871 : and a smaller exponent can be reached
3872 : by turning a 10...0 into 9...9x. */
3873 : char *digits2 =
3874 : scale10_round_decimal_long_double (arg,
3875 : (int)(precision - 1) - exponent + 1);
3876 : if (digits2 == NULL)
3877 : {
3878 : free (digits);
3879 : END_LONG_DOUBLE_ROUNDING ();
3880 : goto out_of_memory;
3881 : }
3882 : if (strlen (digits2) == precision)
3883 : {
3884 : free (digits);
3885 : digits = digits2;
3886 : exponent -= 1;
3887 : }
3888 : else
3889 : free (digits2);
3890 : }
3891 : /* Here ndigits = precision. */
3892 :
3893 : /* Determine the number of trailing zeroes
3894 : that have to be dropped. */
3895 : nzeroes = 0;
3896 : if ((flags & FLAG_ALT) == 0)
3897 : while (nzeroes < ndigits
3898 : && digits[nzeroes] == '0')
3899 : nzeroes++;
3900 :
3901 : /* The exponent is now determined. */
3902 : if (exponent >= -4
3903 : && exponent < (long)precision)
3904 : {
3905 : /* Fixed-point notation:
3906 : max(exponent,0)+1 digits, then the
3907 : decimal point, then the remaining
3908 : digits without trailing zeroes. */
3909 : if (exponent >= 0)
3910 : {
3911 : size_t ecount = exponent + 1;
3912 : /* Note: count <= precision = ndigits. */
3913 : for (; ecount > 0; ecount--)
3914 : *p++ = digits[--ndigits];
3915 : if ((flags & FLAG_ALT) || ndigits > nzeroes)
3916 : {
3917 : *p++ = decimal_point_char ();
3918 : while (ndigits > nzeroes)
3919 : {
3920 : --ndigits;
3921 : *p++ = digits[ndigits];
3922 : }
3923 : }
3924 : }
3925 : else
3926 : {
3927 : size_t ecount = -exponent - 1;
3928 : *p++ = '0';
3929 : *p++ = decimal_point_char ();
3930 : for (; ecount > 0; ecount--)
3931 : *p++ = '0';
3932 : while (ndigits > nzeroes)
3933 : {
3934 : --ndigits;
3935 : *p++ = digits[ndigits];
3936 : }
3937 : }
3938 : }
3939 : else
3940 : {
3941 : /* Exponential notation. */
3942 : *p++ = digits[--ndigits];
3943 : if ((flags & FLAG_ALT) || ndigits > nzeroes)
3944 : {
3945 : *p++ = decimal_point_char ();
3946 : while (ndigits > nzeroes)
3947 : {
3948 : --ndigits;
3949 : *p++ = digits[ndigits];
3950 : }
3951 : }
3952 : *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3953 : # if WIDE_CHAR_VERSION
3954 : {
3955 : static const wchar_t decimal_format[] =
3956 : { '%', '+', '.', '2', 'd', '\0' };
3957 : SNPRINTF (p, 6 + 1, decimal_format, exponent);
3958 : }
3959 : while (*p != '\0')
3960 : p++;
3961 : # else
3962 : if (sizeof (DCHAR_T) == 1)
3963 : {
3964 : sprintf ((char *) p, "%+.2d", exponent);
3965 : while (*p != '\0')
3966 : p++;
3967 : }
3968 : else
3969 : {
3970 : char expbuf[6 + 1];
3971 : const char *ep;
3972 : sprintf (expbuf, "%+.2d", exponent);
3973 : for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3974 : p++;
3975 : }
3976 : # endif
3977 : }
3978 :
3979 : free (digits);
3980 : }
3981 : }
3982 : else
3983 : abort ();
3984 : # else
3985 : /* arg is finite. */
3986 : if (!(arg == 0.0L))
3987 : abort ();
3988 :
3989 : pad_ptr = p;
3990 :
3991 : if (dp->conversion == 'f' || dp->conversion == 'F')
3992 : {
3993 : *p++ = '0';
3994 : if ((flags & FLAG_ALT) || precision > 0)
3995 : {
3996 : *p++ = decimal_point_char ();
3997 : for (; precision > 0; precision--)
3998 : *p++ = '0';
3999 : }
4000 : }
4001 : else if (dp->conversion == 'e' || dp->conversion == 'E')
4002 : {
4003 : *p++ = '0';
4004 : if ((flags & FLAG_ALT) || precision > 0)
4005 : {
4006 : *p++ = decimal_point_char ();
4007 : for (; precision > 0; precision--)
4008 : *p++ = '0';
4009 : }
4010 : *p++ = dp->conversion; /* 'e' or 'E' */
4011 : *p++ = '+';
4012 : *p++ = '0';
4013 : *p++ = '0';
4014 : }
4015 : else if (dp->conversion == 'g' || dp->conversion == 'G')
4016 : {
4017 : *p++ = '0';
4018 : if (flags & FLAG_ALT)
4019 : {
4020 : size_t ndigits =
4021 : (precision > 0 ? precision - 1 : 0);
4022 : *p++ = decimal_point_char ();
4023 : for (; ndigits > 0; --ndigits)
4024 : *p++ = '0';
4025 : }
4026 : }
4027 : else if (dp->conversion == 'a' || dp->conversion == 'A')
4028 : {
4029 : *p++ = '0';
4030 : *p++ = dp->conversion - 'A' + 'X';
4031 : pad_ptr = p;
4032 : *p++ = '0';
4033 : if ((flags & FLAG_ALT) || precision > 0)
4034 : {
4035 : *p++ = decimal_point_char ();
4036 : for (; precision > 0; precision--)
4037 : *p++ = '0';
4038 : }
4039 : *p++ = dp->conversion - 'A' + 'P';
4040 : *p++ = '+';
4041 : *p++ = '0';
4042 : }
4043 : else
4044 : abort ();
4045 : # endif
4046 : }
4047 :
4048 : END_LONG_DOUBLE_ROUNDING ();
4049 : }
4050 : }
4051 : # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4052 : else
4053 : # endif
4054 : # endif
4055 : # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4056 : {
4057 : double arg = a.arg[dp->arg_index].a.a_double;
4058 :
4059 : if (isnand (arg))
4060 : {
4061 : if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4062 : {
4063 : *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4064 : }
4065 : else
4066 : {
4067 : *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4068 : }
4069 : }
4070 : else
4071 : {
4072 : int sign = 0;
4073 :
4074 : if (signbit (arg)) /* arg < 0.0 or negative zero */
4075 : {
4076 : sign = -1;
4077 : arg = -arg;
4078 : }
4079 :
4080 : if (sign < 0)
4081 : *p++ = '-';
4082 : else if (flags & FLAG_SHOWSIGN)
4083 : *p++ = '+';
4084 : else if (flags & FLAG_SPACE)
4085 : *p++ = ' ';
4086 :
4087 : if (arg > 0.0 && arg + arg == arg)
4088 : {
4089 : if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4090 : {
4091 : *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4092 : }
4093 : else
4094 : {
4095 : *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4096 : }
4097 : }
4098 : else
4099 : {
4100 : # if NEED_PRINTF_DOUBLE
4101 : pad_ptr = p;
4102 :
4103 : if (dp->conversion == 'f' || dp->conversion == 'F')
4104 : {
4105 : char *digits;
4106 : size_t ndigits;
4107 :
4108 : digits =
4109 : scale10_round_decimal_double (arg, precision);
4110 : if (digits == NULL)
4111 : goto out_of_memory;
4112 : ndigits = strlen (digits);
4113 :
4114 : if (ndigits > precision)
4115 : do
4116 : {
4117 : --ndigits;
4118 : *p++ = digits[ndigits];
4119 : }
4120 : while (ndigits > precision);
4121 : else
4122 : *p++ = '0';
4123 : /* Here ndigits <= precision. */
4124 : if ((flags & FLAG_ALT) || precision > 0)
4125 : {
4126 : *p++ = decimal_point_char ();
4127 : for (; precision > ndigits; precision--)
4128 : *p++ = '0';
4129 : while (ndigits > 0)
4130 : {
4131 : --ndigits;
4132 : *p++ = digits[ndigits];
4133 : }
4134 : }
4135 :
4136 : free (digits);
4137 : }
4138 : else if (dp->conversion == 'e' || dp->conversion == 'E')
4139 : {
4140 : int exponent;
4141 :
4142 : if (arg == 0.0)
4143 : {
4144 : exponent = 0;
4145 : *p++ = '0';
4146 : if ((flags & FLAG_ALT) || precision > 0)
4147 : {
4148 : *p++ = decimal_point_char ();
4149 : for (; precision > 0; precision--)
4150 : *p++ = '0';
4151 : }
4152 : }
4153 : else
4154 : {
4155 : /* arg > 0.0. */
4156 : int adjusted;
4157 : char *digits;
4158 : size_t ndigits;
4159 :
4160 : exponent = floorlog10 (arg);
4161 : adjusted = 0;
4162 : for (;;)
4163 : {
4164 : digits =
4165 : scale10_round_decimal_double (arg,
4166 : (int)precision - exponent);
4167 : if (digits == NULL)
4168 : goto out_of_memory;
4169 : ndigits = strlen (digits);
4170 :
4171 : if (ndigits == precision + 1)
4172 : break;
4173 : if (ndigits < precision
4174 : || ndigits > precision + 2)
4175 : /* The exponent was not guessed
4176 : precisely enough. */
4177 : abort ();
4178 : if (adjusted)
4179 : /* None of two values of exponent is
4180 : the right one. Prevent an endless
4181 : loop. */
4182 : abort ();
4183 : free (digits);
4184 : if (ndigits == precision)
4185 : exponent -= 1;
4186 : else
4187 : exponent += 1;
4188 : adjusted = 1;
4189 : }
4190 : /* Here ndigits = precision+1. */
4191 : if (is_borderline (digits, precision))
4192 : {
4193 : /* Maybe the exponent guess was too high
4194 : and a smaller exponent can be reached
4195 : by turning a 10...0 into 9...9x. */
4196 : char *digits2 =
4197 : scale10_round_decimal_double (arg,
4198 : (int)precision - exponent + 1);
4199 : if (digits2 == NULL)
4200 : {
4201 : free (digits);
4202 : goto out_of_memory;
4203 : }
4204 : if (strlen (digits2) == precision + 1)
4205 : {
4206 : free (digits);
4207 : digits = digits2;
4208 : exponent -= 1;
4209 : }
4210 : else
4211 : free (digits2);
4212 : }
4213 : /* Here ndigits = precision+1. */
4214 :
4215 : *p++ = digits[--ndigits];
4216 : if ((flags & FLAG_ALT) || precision > 0)
4217 : {
4218 : *p++ = decimal_point_char ();
4219 : while (ndigits > 0)
4220 : {
4221 : --ndigits;
4222 : *p++ = digits[ndigits];
4223 : }
4224 : }
4225 :
4226 : free (digits);
4227 : }
4228 :
4229 : *p++ = dp->conversion; /* 'e' or 'E' */
4230 : # if WIDE_CHAR_VERSION
4231 : {
4232 : static const wchar_t decimal_format[] =
4233 : /* Produce the same number of exponent digits
4234 : as the native printf implementation. */
4235 : # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4236 : { '%', '+', '.', '3', 'd', '\0' };
4237 : # else
4238 : { '%', '+', '.', '2', 'd', '\0' };
4239 : # endif
4240 : SNPRINTF (p, 6 + 1, decimal_format, exponent);
4241 : }
4242 : while (*p != '\0')
4243 : p++;
4244 : # else
4245 : {
4246 : static const char decimal_format[] =
4247 : /* Produce the same number of exponent digits
4248 : as the native printf implementation. */
4249 : # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4250 : "%+.3d";
4251 : # else
4252 : "%+.2d";
4253 : # endif
4254 : if (sizeof (DCHAR_T) == 1)
4255 : {
4256 : sprintf ((char *) p, decimal_format, exponent);
4257 : while (*p != '\0')
4258 : p++;
4259 : }
4260 : else
4261 : {
4262 : char expbuf[6 + 1];
4263 : const char *ep;
4264 : sprintf (expbuf, decimal_format, exponent);
4265 : for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4266 : p++;
4267 : }
4268 : }
4269 : # endif
4270 : }
4271 : else if (dp->conversion == 'g' || dp->conversion == 'G')
4272 : {
4273 : if (precision == 0)
4274 : precision = 1;
4275 : /* precision >= 1. */
4276 :
4277 : if (arg == 0.0)
4278 : /* The exponent is 0, >= -4, < precision.
4279 : Use fixed-point notation. */
4280 : {
4281 : size_t ndigits = precision;
4282 : /* Number of trailing zeroes that have to be
4283 : dropped. */
4284 : size_t nzeroes =
4285 : (flags & FLAG_ALT ? 0 : precision - 1);
4286 :
4287 : --ndigits;
4288 : *p++ = '0';
4289 : if ((flags & FLAG_ALT) || ndigits > nzeroes)
4290 : {
4291 : *p++ = decimal_point_char ();
4292 : while (ndigits > nzeroes)
4293 : {
4294 : --ndigits;
4295 : *p++ = '0';
4296 : }
4297 : }
4298 : }
4299 : else
4300 : {
4301 : /* arg > 0.0. */
4302 : int exponent;
4303 : int adjusted;
4304 : char *digits;
4305 : size_t ndigits;
4306 : size_t nzeroes;
4307 :
4308 : exponent = floorlog10 (arg);
4309 : adjusted = 0;
4310 : for (;;)
4311 : {
4312 : digits =
4313 : scale10_round_decimal_double (arg,
4314 : (int)(precision - 1) - exponent);
4315 : if (digits == NULL)
4316 : goto out_of_memory;
4317 : ndigits = strlen (digits);
4318 :
4319 : if (ndigits == precision)
4320 : break;
4321 : if (ndigits < precision - 1
4322 : || ndigits > precision + 1)
4323 : /* The exponent was not guessed
4324 : precisely enough. */
4325 : abort ();
4326 : if (adjusted)
4327 : /* None of two values of exponent is
4328 : the right one. Prevent an endless
4329 : loop. */
4330 : abort ();
4331 : free (digits);
4332 : if (ndigits < precision)
4333 : exponent -= 1;
4334 : else
4335 : exponent += 1;
4336 : adjusted = 1;
4337 : }
4338 : /* Here ndigits = precision. */
4339 : if (is_borderline (digits, precision - 1))
4340 : {
4341 : /* Maybe the exponent guess was too high
4342 : and a smaller exponent can be reached
4343 : by turning a 10...0 into 9...9x. */
4344 : char *digits2 =
4345 : scale10_round_decimal_double (arg,
4346 : (int)(precision - 1) - exponent + 1);
4347 : if (digits2 == NULL)
4348 : {
4349 : free (digits);
4350 : goto out_of_memory;
4351 : }
4352 : if (strlen (digits2) == precision)
4353 : {
4354 : free (digits);
4355 : digits = digits2;
4356 : exponent -= 1;
4357 : }
4358 : else
4359 : free (digits2);
4360 : }
4361 : /* Here ndigits = precision. */
4362 :
4363 : /* Determine the number of trailing zeroes
4364 : that have to be dropped. */
4365 : nzeroes = 0;
4366 : if ((flags & FLAG_ALT) == 0)
4367 : while (nzeroes < ndigits
4368 : && digits[nzeroes] == '0')
4369 : nzeroes++;
4370 :
4371 : /* The exponent is now determined. */
4372 : if (exponent >= -4
4373 : && exponent < (long)precision)
4374 : {
4375 : /* Fixed-point notation:
4376 : max(exponent,0)+1 digits, then the
4377 : decimal point, then the remaining
4378 : digits without trailing zeroes. */
4379 : if (exponent >= 0)
4380 : {
4381 : size_t ecount = exponent + 1;
4382 : /* Note: ecount <= precision = ndigits. */
4383 : for (; ecount > 0; ecount--)
4384 : *p++ = digits[--ndigits];
4385 : if ((flags & FLAG_ALT) || ndigits > nzeroes)
4386 : {
4387 : *p++ = decimal_point_char ();
4388 : while (ndigits > nzeroes)
4389 : {
4390 : --ndigits;
4391 : *p++ = digits[ndigits];
4392 : }
4393 : }
4394 : }
4395 : else
4396 : {
4397 : size_t ecount = -exponent - 1;
4398 : *p++ = '0';
4399 : *p++ = decimal_point_char ();
4400 : for (; ecount > 0; ecount--)
4401 : *p++ = '0';
4402 : while (ndigits > nzeroes)
4403 : {
4404 : --ndigits;
4405 : *p++ = digits[ndigits];
4406 : }
4407 : }
4408 : }
4409 : else
4410 : {
4411 : /* Exponential notation. */
4412 : *p++ = digits[--ndigits];
4413 : if ((flags & FLAG_ALT) || ndigits > nzeroes)
4414 : {
4415 : *p++ = decimal_point_char ();
4416 : while (ndigits > nzeroes)
4417 : {
4418 : --ndigits;
4419 : *p++ = digits[ndigits];
4420 : }
4421 : }
4422 : *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4423 : # if WIDE_CHAR_VERSION
4424 : {
4425 : static const wchar_t decimal_format[] =
4426 : /* Produce the same number of exponent digits
4427 : as the native printf implementation. */
4428 : # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4429 : { '%', '+', '.', '3', 'd', '\0' };
4430 : # else
4431 : { '%', '+', '.', '2', 'd', '\0' };
4432 : # endif
4433 : SNPRINTF (p, 6 + 1, decimal_format, exponent);
4434 : }
4435 : while (*p != '\0')
4436 : p++;
4437 : # else
4438 : {
4439 : static const char decimal_format[] =
4440 : /* Produce the same number of exponent digits
4441 : as the native printf implementation. */
4442 : # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4443 : "%+.3d";
4444 : # else
4445 : "%+.2d";
4446 : # endif
4447 : if (sizeof (DCHAR_T) == 1)
4448 : {
4449 : sprintf ((char *) p, decimal_format, exponent);
4450 : while (*p != '\0')
4451 : p++;
4452 : }
4453 : else
4454 : {
4455 : char expbuf[6 + 1];
4456 : const char *ep;
4457 : sprintf (expbuf, decimal_format, exponent);
4458 : for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4459 : p++;
4460 : }
4461 : }
4462 : # endif
4463 : }
4464 :
4465 : free (digits);
4466 : }
4467 : }
4468 : else
4469 : abort ();
4470 : # else
4471 : /* arg is finite. */
4472 : if (!(arg == 0.0))
4473 : abort ();
4474 :
4475 : pad_ptr = p;
4476 :
4477 : if (dp->conversion == 'f' || dp->conversion == 'F')
4478 : {
4479 : *p++ = '0';
4480 : if ((flags & FLAG_ALT) || precision > 0)
4481 : {
4482 : *p++ = decimal_point_char ();
4483 : for (; precision > 0; precision--)
4484 : *p++ = '0';
4485 : }
4486 : }
4487 : else if (dp->conversion == 'e' || dp->conversion == 'E')
4488 : {
4489 : *p++ = '0';
4490 : if ((flags & FLAG_ALT) || precision > 0)
4491 : {
4492 : *p++ = decimal_point_char ();
4493 : for (; precision > 0; precision--)
4494 : *p++ = '0';
4495 : }
4496 : *p++ = dp->conversion; /* 'e' or 'E' */
4497 : *p++ = '+';
4498 : /* Produce the same number of exponent digits as
4499 : the native printf implementation. */
4500 : # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4501 : *p++ = '0';
4502 : # endif
4503 : *p++ = '0';
4504 : *p++ = '0';
4505 : }
4506 : else if (dp->conversion == 'g' || dp->conversion == 'G')
4507 : {
4508 : *p++ = '0';
4509 : if (flags & FLAG_ALT)
4510 : {
4511 : size_t ndigits =
4512 : (precision > 0 ? precision - 1 : 0);
4513 : *p++ = decimal_point_char ();
4514 : for (; ndigits > 0; --ndigits)
4515 : *p++ = '0';
4516 : }
4517 : }
4518 : else
4519 : abort ();
4520 : # endif
4521 : }
4522 : }
4523 : }
4524 : # endif
4525 :
4526 : /* The generated string now extends from tmp to p, with the
4527 : zero padding insertion point being at pad_ptr. */
4528 : count = p - tmp;
4529 :
4530 : if (count < width)
4531 : {
4532 : size_t pad = width - count;
4533 : DCHAR_T *end = p + pad;
4534 :
4535 : if (flags & FLAG_LEFT)
4536 : {
4537 : /* Pad with spaces on the right. */
4538 : for (; pad > 0; pad--)
4539 : *p++ = ' ';
4540 : }
4541 : else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4542 : {
4543 : /* Pad with zeroes. */
4544 : DCHAR_T *q = end;
4545 :
4546 : while (p > pad_ptr)
4547 : *--q = *--p;
4548 : for (; pad > 0; pad--)
4549 : *p++ = '0';
4550 : }
4551 : else
4552 : {
4553 : /* Pad with spaces on the left. */
4554 : DCHAR_T *q = end;
4555 :
4556 : while (p > tmp)
4557 : *--q = *--p;
4558 : for (; pad > 0; pad--)
4559 : *p++ = ' ';
4560 : }
4561 :
4562 : p = end;
4563 : }
4564 :
4565 : count = p - tmp;
4566 :
4567 : if (count >= tmp_length)
4568 : /* tmp_length was incorrectly calculated - fix the
4569 : code above! */
4570 : abort ();
4571 :
4572 : /* Make room for the result. */
4573 : if (count >= allocated - length)
4574 : {
4575 : size_t n = xsum (length, count);
4576 :
4577 : ENSURE_ALLOCATION (n);
4578 : }
4579 :
4580 : /* Append the result. */
4581 : memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4582 : if (tmp != tmpbuf)
4583 : free (tmp);
4584 : length += count;
4585 : }
4586 : #endif
4587 : else
4588 : {
4589 0 : arg_type type = a.arg[dp->arg_index].type;
4590 0 : int flags = dp->flags;
4591 : #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4592 : int has_width;
4593 : #endif
4594 : #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4595 : size_t width;
4596 : #endif
4597 : #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
4598 : int has_precision;
4599 : size_t precision;
4600 : #endif
4601 : #if NEED_PRINTF_UNBOUNDED_PRECISION
4602 : int prec_ourselves;
4603 : #else
4604 : # define prec_ourselves 0
4605 : #endif
4606 : #if NEED_PRINTF_FLAG_LEFTADJUST
4607 : # define pad_ourselves 1
4608 : #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4609 : int pad_ourselves;
4610 : #else
4611 : # define pad_ourselves 0
4612 : #endif
4613 : TCHAR_T *fbp;
4614 : unsigned int prefix_count;
4615 : int prefixes[2] IF_LINT (= { 0 });
4616 : int orig_errno;
4617 : #if !USE_SNPRINTF
4618 : size_t tmp_length;
4619 : TCHAR_T tmpbuf[700];
4620 : TCHAR_T *tmp;
4621 : #endif
4622 :
4623 : #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4624 : has_width = 0;
4625 : #endif
4626 : #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4627 : width = 0;
4628 : if (dp->width_start != dp->width_end)
4629 : {
4630 : if (dp->width_arg_index != ARG_NONE)
4631 : {
4632 : int arg;
4633 :
4634 : if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4635 : abort ();
4636 : arg = a.arg[dp->width_arg_index].a.a_int;
4637 : width = arg;
4638 : if (arg < 0)
4639 : {
4640 : /* "A negative field width is taken as a '-' flag
4641 : followed by a positive field width." */
4642 : flags |= FLAG_LEFT;
4643 : width = -width;
4644 : }
4645 : }
4646 : else
4647 : {
4648 : const FCHAR_T *digitp = dp->width_start;
4649 :
4650 : do
4651 : width = xsum (xtimes (width, 10), *digitp++ - '0');
4652 : while (digitp != dp->width_end);
4653 : }
4654 : #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4655 : has_width = 1;
4656 : #endif
4657 : }
4658 : #endif
4659 :
4660 : #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
4661 : has_precision = 0;
4662 : precision = 6;
4663 : if (dp->precision_start != dp->precision_end)
4664 : {
4665 : if (dp->precision_arg_index != ARG_NONE)
4666 : {
4667 : int arg;
4668 :
4669 : if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4670 : abort ();
4671 : arg = a.arg[dp->precision_arg_index].a.a_int;
4672 : /* "A negative precision is taken as if the precision
4673 : were omitted." */
4674 : if (arg >= 0)
4675 : {
4676 : precision = arg;
4677 : has_precision = 1;
4678 : }
4679 : }
4680 : else
4681 : {
4682 : const FCHAR_T *digitp = dp->precision_start + 1;
4683 :
4684 : precision = 0;
4685 : while (digitp != dp->precision_end)
4686 : precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4687 : has_precision = 1;
4688 : }
4689 : }
4690 : #endif
4691 :
4692 : /* Decide whether to handle the precision ourselves. */
4693 : #if NEED_PRINTF_UNBOUNDED_PRECISION
4694 : switch (dp->conversion)
4695 : {
4696 : case 'd': case 'i': case 'u':
4697 : case 'o':
4698 : case 'x': case 'X': case 'p':
4699 : prec_ourselves = has_precision && (precision > 0);
4700 : break;
4701 : default:
4702 : prec_ourselves = 0;
4703 : break;
4704 : }
4705 : #endif
4706 :
4707 : /* Decide whether to perform the padding ourselves. */
4708 : #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
4709 : switch (dp->conversion)
4710 : {
4711 : # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4712 : /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
4713 : to perform the padding after this conversion. Functions
4714 : with unistdio extensions perform the padding based on
4715 : character count rather than element count. */
4716 : case 'c': case 's':
4717 : # endif
4718 : # if NEED_PRINTF_FLAG_ZERO
4719 : case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
4720 : case 'a': case 'A':
4721 : # endif
4722 : pad_ourselves = 1;
4723 : break;
4724 : default:
4725 : pad_ourselves = prec_ourselves;
4726 : break;
4727 : }
4728 : #endif
4729 :
4730 : #if !USE_SNPRINTF
4731 : /* Allocate a temporary buffer of sufficient size for calling
4732 : sprintf. */
4733 : tmp_length =
4734 : MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
4735 : flags, width, has_precision, precision,
4736 : pad_ourselves);
4737 :
4738 : if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
4739 : tmp = tmpbuf;
4740 : else
4741 : {
4742 : size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
4743 :
4744 : if (size_overflow_p (tmp_memsize))
4745 : /* Overflow, would lead to out of memory. */
4746 : goto out_of_memory;
4747 : tmp = (TCHAR_T *) malloc (tmp_memsize);
4748 : if (tmp == NULL)
4749 : /* Out of memory. */
4750 : goto out_of_memory;
4751 : }
4752 : #endif
4753 :
4754 : /* Construct the format string for calling snprintf or
4755 : sprintf. */
4756 0 : fbp = buf;
4757 0 : *fbp++ = '%';
4758 : #if NEED_PRINTF_FLAG_GROUPING
4759 : /* The underlying implementation doesn't support the ' flag.
4760 : Produce no grouping characters in this case; this is
4761 : acceptable because the grouping is locale dependent. */
4762 : #else
4763 0 : if (flags & FLAG_GROUP)
4764 0 : *fbp++ = '\'';
4765 : #endif
4766 0 : if (flags & FLAG_LEFT)
4767 0 : *fbp++ = '-';
4768 0 : if (flags & FLAG_SHOWSIGN)
4769 0 : *fbp++ = '+';
4770 0 : if (flags & FLAG_SPACE)
4771 0 : *fbp++ = ' ';
4772 0 : if (flags & FLAG_ALT)
4773 0 : *fbp++ = '#';
4774 : #if __GLIBC__ >= 2 && !defined __UCLIBC__
4775 0 : if (flags & FLAG_LOCALIZED)
4776 0 : *fbp++ = 'I';
4777 : #endif
4778 : if (!pad_ourselves)
4779 : {
4780 0 : if (flags & FLAG_ZERO)
4781 0 : *fbp++ = '0';
4782 0 : if (dp->width_start != dp->width_end)
4783 : {
4784 0 : size_t n = dp->width_end - dp->width_start;
4785 : /* The width specification is known to consist only
4786 : of standard ASCII characters. */
4787 : if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4788 : {
4789 0 : memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
4790 0 : fbp += n;
4791 : }
4792 : else
4793 : {
4794 : const FCHAR_T *mp = dp->width_start;
4795 : do
4796 : *fbp++ = *mp++;
4797 : while (--n > 0);
4798 : }
4799 : }
4800 : }
4801 : if (!prec_ourselves)
4802 : {
4803 0 : if (dp->precision_start != dp->precision_end)
4804 : {
4805 0 : size_t n = dp->precision_end - dp->precision_start;
4806 : /* The precision specification is known to consist only
4807 : of standard ASCII characters. */
4808 : if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4809 : {
4810 0 : memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
4811 0 : fbp += n;
4812 : }
4813 : else
4814 : {
4815 : const FCHAR_T *mp = dp->precision_start;
4816 : do
4817 : *fbp++ = *mp++;
4818 : while (--n > 0);
4819 : }
4820 : }
4821 : }
4822 :
4823 0 : switch (type)
4824 : {
4825 : #if HAVE_LONG_LONG_INT
4826 : case TYPE_LONGLONGINT:
4827 : case TYPE_ULONGLONGINT:
4828 : # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4829 : *fbp++ = 'I';
4830 : *fbp++ = '6';
4831 : *fbp++ = '4';
4832 : break;
4833 : # else
4834 0 : *fbp++ = 'l';
4835 : /*FALLTHROUGH*/
4836 : # endif
4837 : #endif
4838 : case TYPE_LONGINT:
4839 : case TYPE_ULONGINT:
4840 : #if HAVE_WINT_T
4841 : case TYPE_WIDE_CHAR:
4842 : #endif
4843 : #if HAVE_WCHAR_T
4844 : case TYPE_WIDE_STRING:
4845 : #endif
4846 0 : *fbp++ = 'l';
4847 0 : break;
4848 : case TYPE_LONGDOUBLE:
4849 0 : *fbp++ = 'L';
4850 0 : break;
4851 : default:
4852 0 : break;
4853 : }
4854 : #if NEED_PRINTF_DIRECTIVE_F
4855 : if (dp->conversion == 'F')
4856 : *fbp = 'f';
4857 : else
4858 : #endif
4859 0 : *fbp = dp->conversion;
4860 : #if USE_SNPRINTF
4861 : # if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
4862 : fbp[1] = '%';
4863 : fbp[2] = 'n';
4864 : fbp[3] = '\0';
4865 : # else
4866 : /* On glibc2 systems from glibc >= 2.3 - probably also older
4867 : ones - we know that snprintf's return value conforms to
4868 : ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and
4869 : gl_SNPRINTF_TRUNCATION_C99 pass.
4870 : Therefore we can avoid using %n in this situation.
4871 : On glibc2 systems from 2004-10-18 or newer, the use of %n
4872 : in format strings in writable memory may crash the program
4873 : (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
4874 : in this situation. */
4875 : /* On native Windows systems (such as mingw), we can avoid using
4876 : %n because:
4877 : - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
4878 : snprintf does not write more than the specified number
4879 : of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
4880 : '4', '5', '6' into buf, not '4', '5', '\0'.)
4881 : - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
4882 : allows us to recognize the case of an insufficient
4883 : buffer size: it returns -1 in this case.
4884 : On native Windows systems (such as mingw) where the OS is
4885 : Windows Vista, the use of %n in format strings by default
4886 : crashes the program. See
4887 : <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
4888 : <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
4889 : So we should avoid %n in this situation. */
4890 0 : fbp[1] = '\0';
4891 : # endif
4892 : #else
4893 : fbp[1] = '\0';
4894 : #endif
4895 :
4896 : /* Construct the arguments for calling snprintf or sprintf. */
4897 0 : prefix_count = 0;
4898 0 : if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
4899 : {
4900 0 : if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4901 0 : abort ();
4902 0 : prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
4903 : }
4904 0 : if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
4905 : {
4906 0 : if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4907 0 : abort ();
4908 0 : prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
4909 : }
4910 :
4911 : #if USE_SNPRINTF
4912 : /* The SNPRINTF result is appended after result[0..length].
4913 : The latter is an array of DCHAR_T; SNPRINTF appends an
4914 : array of TCHAR_T to it. This is possible because
4915 : sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
4916 : alignof (TCHAR_T) <= alignof (DCHAR_T). */
4917 : # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
4918 : /* Ensure that maxlen below will be >= 2. Needed on BeOS,
4919 : where an snprintf() with maxlen==1 acts like sprintf(). */
4920 0 : ENSURE_ALLOCATION (xsum (length,
4921 : (2 + TCHARS_PER_DCHAR - 1)
4922 : / TCHARS_PER_DCHAR));
4923 : /* Prepare checking whether snprintf returns the count
4924 : via %n. */
4925 0 : *(TCHAR_T *) (result + length) = '\0';
4926 : #endif
4927 :
4928 0 : orig_errno = errno;
4929 :
4930 : for (;;)
4931 : {
4932 0 : int count = -1;
4933 :
4934 : #if USE_SNPRINTF
4935 0 : int retcount = 0;
4936 0 : size_t maxlen = allocated - length;
4937 : /* SNPRINTF can fail if its second argument is
4938 : > INT_MAX. */
4939 0 : if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
4940 0 : maxlen = INT_MAX / TCHARS_PER_DCHAR;
4941 0 : maxlen = maxlen * TCHARS_PER_DCHAR;
4942 : # define SNPRINTF_BUF(arg) \
4943 : switch (prefix_count) \
4944 : { \
4945 : case 0: \
4946 : retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4947 : maxlen, buf, \
4948 : arg, &count); \
4949 : break; \
4950 : case 1: \
4951 : retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4952 : maxlen, buf, \
4953 : prefixes[0], arg, &count); \
4954 : break; \
4955 : case 2: \
4956 : retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4957 : maxlen, buf, \
4958 : prefixes[0], prefixes[1], arg, \
4959 : &count); \
4960 : break; \
4961 : default: \
4962 : abort (); \
4963 : }
4964 : #else
4965 : # define SNPRINTF_BUF(arg) \
4966 : switch (prefix_count) \
4967 : { \
4968 : case 0: \
4969 : count = sprintf (tmp, buf, arg); \
4970 : break; \
4971 : case 1: \
4972 : count = sprintf (tmp, buf, prefixes[0], arg); \
4973 : break; \
4974 : case 2: \
4975 : count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
4976 : arg); \
4977 : break; \
4978 : default: \
4979 : abort (); \
4980 : }
4981 : #endif
4982 :
4983 0 : errno = 0;
4984 0 : switch (type)
4985 : {
4986 : case TYPE_SCHAR:
4987 : {
4988 0 : int arg = a.arg[dp->arg_index].a.a_schar;
4989 0 : SNPRINTF_BUF (arg);
4990 : }
4991 0 : break;
4992 : case TYPE_UCHAR:
4993 : {
4994 0 : unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
4995 0 : SNPRINTF_BUF (arg);
4996 : }
4997 0 : break;
4998 : case TYPE_SHORT:
4999 : {
5000 0 : int arg = a.arg[dp->arg_index].a.a_short;
5001 0 : SNPRINTF_BUF (arg);
5002 : }
5003 0 : break;
5004 : case TYPE_USHORT:
5005 : {
5006 0 : unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
5007 0 : SNPRINTF_BUF (arg);
5008 : }
5009 0 : break;
5010 : case TYPE_INT:
5011 : {
5012 0 : int arg = a.arg[dp->arg_index].a.a_int;
5013 0 : SNPRINTF_BUF (arg);
5014 : }
5015 0 : break;
5016 : case TYPE_UINT:
5017 : {
5018 0 : unsigned int arg = a.arg[dp->arg_index].a.a_uint;
5019 0 : SNPRINTF_BUF (arg);
5020 : }
5021 0 : break;
5022 : case TYPE_LONGINT:
5023 : {
5024 0 : long int arg = a.arg[dp->arg_index].a.a_longint;
5025 0 : SNPRINTF_BUF (arg);
5026 : }
5027 0 : break;
5028 : case TYPE_ULONGINT:
5029 : {
5030 0 : unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
5031 0 : SNPRINTF_BUF (arg);
5032 : }
5033 0 : break;
5034 : #if HAVE_LONG_LONG_INT
5035 : case TYPE_LONGLONGINT:
5036 : {
5037 0 : long long int arg = a.arg[dp->arg_index].a.a_longlongint;
5038 0 : SNPRINTF_BUF (arg);
5039 : }
5040 0 : break;
5041 : case TYPE_ULONGLONGINT:
5042 : {
5043 0 : unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
5044 0 : SNPRINTF_BUF (arg);
5045 : }
5046 0 : break;
5047 : #endif
5048 : case TYPE_DOUBLE:
5049 : {
5050 0 : double arg = a.arg[dp->arg_index].a.a_double;
5051 0 : SNPRINTF_BUF (arg);
5052 : }
5053 0 : break;
5054 : case TYPE_LONGDOUBLE:
5055 : {
5056 0 : long double arg = a.arg[dp->arg_index].a.a_longdouble;
5057 0 : SNPRINTF_BUF (arg);
5058 : }
5059 0 : break;
5060 : case TYPE_CHAR:
5061 : {
5062 0 : int arg = a.arg[dp->arg_index].a.a_char;
5063 0 : SNPRINTF_BUF (arg);
5064 : }
5065 0 : break;
5066 : #if HAVE_WINT_T
5067 : case TYPE_WIDE_CHAR:
5068 : {
5069 0 : wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
5070 0 : SNPRINTF_BUF (arg);
5071 : }
5072 0 : break;
5073 : #endif
5074 : case TYPE_STRING:
5075 : {
5076 0 : const char *arg = a.arg[dp->arg_index].a.a_string;
5077 0 : SNPRINTF_BUF (arg);
5078 : }
5079 0 : break;
5080 : #if HAVE_WCHAR_T
5081 : case TYPE_WIDE_STRING:
5082 : {
5083 0 : const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
5084 0 : SNPRINTF_BUF (arg);
5085 : }
5086 0 : break;
5087 : #endif
5088 : case TYPE_POINTER:
5089 : {
5090 0 : void *arg = a.arg[dp->arg_index].a.a_pointer;
5091 0 : SNPRINTF_BUF (arg);
5092 : }
5093 0 : break;
5094 : default:
5095 0 : abort ();
5096 : }
5097 :
5098 : #if USE_SNPRINTF
5099 : /* Portability: Not all implementations of snprintf()
5100 : are ISO C 99 compliant. Determine the number of
5101 : bytes that snprintf() has produced or would have
5102 : produced. */
5103 0 : if (count >= 0)
5104 : {
5105 : /* Verify that snprintf() has NUL-terminated its
5106 : result. */
5107 0 : if (count < maxlen
5108 0 : && ((TCHAR_T *) (result + length)) [count] != '\0')
5109 0 : abort ();
5110 : /* Portability hack. */
5111 0 : if (retcount > count)
5112 0 : count = retcount;
5113 : }
5114 : else
5115 : {
5116 : /* snprintf() doesn't understand the '%n'
5117 : directive. */
5118 0 : if (fbp[1] != '\0')
5119 : {
5120 : /* Don't use the '%n' directive; instead, look
5121 : at the snprintf() return value. */
5122 0 : fbp[1] = '\0';
5123 0 : continue;
5124 : }
5125 : else
5126 : {
5127 : /* Look at the snprintf() return value. */
5128 0 : if (retcount < 0)
5129 : {
5130 : # if !HAVE_SNPRINTF_RETVAL_C99
5131 : /* HP-UX 10.20 snprintf() is doubly deficient:
5132 : It doesn't understand the '%n' directive,
5133 : *and* it returns -1 (rather than the length
5134 : that would have been required) when the
5135 : buffer is too small.
5136 : But a failure at this point can also come
5137 : from other reasons than a too small buffer,
5138 : such as an invalid wide string argument to
5139 : the %ls directive, or possibly an invalid
5140 : floating-point argument. */
5141 : size_t tmp_length =
5142 : MAX_ROOM_NEEDED (&a, dp->arg_index,
5143 : dp->conversion, type, flags,
5144 : width,
5145 : has_precision,
5146 : precision, pad_ourselves);
5147 :
5148 : if (maxlen < tmp_length)
5149 : {
5150 : /* Make more room. But try to do through
5151 : this reallocation only once. */
5152 : size_t bigger_need =
5153 : xsum (length,
5154 : xsum (tmp_length,
5155 : TCHARS_PER_DCHAR - 1)
5156 : / TCHARS_PER_DCHAR);
5157 : /* And always grow proportionally.
5158 : (There may be several arguments, each
5159 : needing a little more room than the
5160 : previous one.) */
5161 : size_t bigger_need2 =
5162 : xsum (xtimes (allocated, 2), 12);
5163 : if (bigger_need < bigger_need2)
5164 : bigger_need = bigger_need2;
5165 : ENSURE_ALLOCATION (bigger_need);
5166 : continue;
5167 : }
5168 : # endif
5169 : }
5170 : else
5171 0 : count = retcount;
5172 : }
5173 : }
5174 : #endif
5175 :
5176 : /* Attempt to handle failure. */
5177 0 : if (count < 0)
5178 : {
5179 : /* SNPRINTF or sprintf failed. Save and use the errno
5180 : that it has set, if any. */
5181 0 : int saved_errno = errno;
5182 0 : if (saved_errno == 0)
5183 : {
5184 0 : if (dp->conversion == 'c' || dp->conversion == 's')
5185 0 : saved_errno = EILSEQ;
5186 : else
5187 0 : saved_errno = EINVAL;
5188 : }
5189 :
5190 0 : if (!(result == resultbuf || result == NULL))
5191 0 : free (result);
5192 0 : if (buf_malloced != NULL)
5193 0 : free (buf_malloced);
5194 0 : CLEANUP ();
5195 :
5196 0 : errno = saved_errno;
5197 0 : return NULL;
5198 : }
5199 :
5200 : #if USE_SNPRINTF
5201 : /* Handle overflow of the allocated buffer.
5202 : If such an overflow occurs, a C99 compliant snprintf()
5203 : returns a count >= maxlen. However, a non-compliant
5204 : snprintf() function returns only count = maxlen - 1. To
5205 : cover both cases, test whether count >= maxlen - 1. */
5206 0 : if ((unsigned int) count + 1 >= maxlen)
5207 : {
5208 : /* If maxlen already has attained its allowed maximum,
5209 : allocating more memory will not increase maxlen.
5210 : Instead of looping, bail out. */
5211 0 : if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
5212 0 : goto overflow;
5213 : else
5214 : {
5215 : /* Need at least (count + 1) * sizeof (TCHAR_T)
5216 : bytes. (The +1 is for the trailing NUL.)
5217 : But ask for (count + 2) * sizeof (TCHAR_T)
5218 : bytes, so that in the next round, we likely get
5219 : maxlen > (unsigned int) count + 1
5220 : and so we don't get here again.
5221 : And allocate proportionally, to avoid looping
5222 : eternally if snprintf() reports a too small
5223 : count. */
5224 0 : size_t n =
5225 0 : xmax (xsum (length,
5226 0 : ((unsigned int) count + 2
5227 : + TCHARS_PER_DCHAR - 1)
5228 : / TCHARS_PER_DCHAR),
5229 0 : xtimes (allocated, 2));
5230 :
5231 0 : ENSURE_ALLOCATION (n);
5232 0 : continue;
5233 : }
5234 : }
5235 : #endif
5236 :
5237 : #if NEED_PRINTF_UNBOUNDED_PRECISION
5238 : if (prec_ourselves)
5239 : {
5240 : /* Handle the precision. */
5241 : TCHAR_T *prec_ptr =
5242 : # if USE_SNPRINTF
5243 : (TCHAR_T *) (result + length);
5244 : # else
5245 : tmp;
5246 : # endif
5247 : size_t prefix_count;
5248 : size_t move;
5249 :
5250 : prefix_count = 0;
5251 : /* Put the additional zeroes after the sign. */
5252 : if (count >= 1
5253 : && (*prec_ptr == '-' || *prec_ptr == '+'
5254 : || *prec_ptr == ' '))
5255 : prefix_count = 1;
5256 : /* Put the additional zeroes after the 0x prefix if
5257 : (flags & FLAG_ALT) || (dp->conversion == 'p'). */
5258 : else if (count >= 2
5259 : && prec_ptr[0] == '0'
5260 : && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
5261 : prefix_count = 2;
5262 :
5263 : move = count - prefix_count;
5264 : if (precision > move)
5265 : {
5266 : /* Insert zeroes. */
5267 : size_t insert = precision - move;
5268 : TCHAR_T *prec_end;
5269 :
5270 : # if USE_SNPRINTF
5271 : size_t n =
5272 : xsum (length,
5273 : (count + insert + TCHARS_PER_DCHAR - 1)
5274 : / TCHARS_PER_DCHAR);
5275 : length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5276 : ENSURE_ALLOCATION (n);
5277 : length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5278 : prec_ptr = (TCHAR_T *) (result + length);
5279 : # endif
5280 :
5281 : prec_end = prec_ptr + count;
5282 : prec_ptr += prefix_count;
5283 :
5284 : while (prec_end > prec_ptr)
5285 : {
5286 : prec_end--;
5287 : prec_end[insert] = prec_end[0];
5288 : }
5289 :
5290 : prec_end += insert;
5291 : do
5292 : *--prec_end = '0';
5293 : while (prec_end > prec_ptr);
5294 :
5295 : count += insert;
5296 : }
5297 : }
5298 : #endif
5299 :
5300 : #if !USE_SNPRINTF
5301 : if (count >= tmp_length)
5302 : /* tmp_length was incorrectly calculated - fix the
5303 : code above! */
5304 : abort ();
5305 : #endif
5306 :
5307 : #if !DCHAR_IS_TCHAR
5308 : /* Convert from TCHAR_T[] to DCHAR_T[]. */
5309 : if (dp->conversion == 'c' || dp->conversion == 's')
5310 : {
5311 : /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
5312 : TYPE_WIDE_STRING.
5313 : The result string is not certainly ASCII. */
5314 : const TCHAR_T *tmpsrc;
5315 : DCHAR_T *tmpdst;
5316 : size_t tmpdst_len;
5317 : /* This code assumes that TCHAR_T is 'char'. */
5318 : verify (sizeof (TCHAR_T) == 1);
5319 : # if USE_SNPRINTF
5320 : tmpsrc = (TCHAR_T *) (result + length);
5321 : # else
5322 : tmpsrc = tmp;
5323 : # endif
5324 : tmpdst =
5325 : DCHAR_CONV_FROM_ENCODING (locale_charset (),
5326 : iconveh_question_mark,
5327 : tmpsrc, count,
5328 : NULL,
5329 : NULL, &tmpdst_len);
5330 : if (tmpdst == NULL)
5331 : {
5332 : int saved_errno = errno;
5333 : if (!(result == resultbuf || result == NULL))
5334 : free (result);
5335 : if (buf_malloced != NULL)
5336 : free (buf_malloced);
5337 : CLEANUP ();
5338 : errno = saved_errno;
5339 : return NULL;
5340 : }
5341 : ENSURE_ALLOCATION (xsum (length, tmpdst_len));
5342 : DCHAR_CPY (result + length, tmpdst, tmpdst_len);
5343 : free (tmpdst);
5344 : count = tmpdst_len;
5345 : }
5346 : else
5347 : {
5348 : /* The result string is ASCII.
5349 : Simple 1:1 conversion. */
5350 : # if USE_SNPRINTF
5351 : /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
5352 : no-op conversion, in-place on the array starting
5353 : at (result + length). */
5354 : if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
5355 : # endif
5356 : {
5357 : const TCHAR_T *tmpsrc;
5358 : DCHAR_T *tmpdst;
5359 : size_t n;
5360 :
5361 : # if USE_SNPRINTF
5362 : if (result == resultbuf)
5363 : {
5364 : tmpsrc = (TCHAR_T *) (result + length);
5365 : /* ENSURE_ALLOCATION will not move tmpsrc
5366 : (because it's part of resultbuf). */
5367 : ENSURE_ALLOCATION (xsum (length, count));
5368 : }
5369 : else
5370 : {
5371 : /* ENSURE_ALLOCATION will move the array
5372 : (because it uses realloc(). */
5373 : ENSURE_ALLOCATION (xsum (length, count));
5374 : tmpsrc = (TCHAR_T *) (result + length);
5375 : }
5376 : # else
5377 : tmpsrc = tmp;
5378 : ENSURE_ALLOCATION (xsum (length, count));
5379 : # endif
5380 : tmpdst = result + length;
5381 : /* Copy backwards, because of overlapping. */
5382 : tmpsrc += count;
5383 : tmpdst += count;
5384 : for (n = count; n > 0; n--)
5385 : *--tmpdst = *--tmpsrc;
5386 : }
5387 : }
5388 : #endif
5389 :
5390 : #if DCHAR_IS_TCHAR && !USE_SNPRINTF
5391 : /* Make room for the result. */
5392 : if (count > allocated - length)
5393 : {
5394 : /* Need at least count elements. But allocate
5395 : proportionally. */
5396 : size_t n =
5397 : xmax (xsum (length, count), xtimes (allocated, 2));
5398 :
5399 : ENSURE_ALLOCATION (n);
5400 : }
5401 : #endif
5402 :
5403 : /* Here count <= allocated - length. */
5404 :
5405 : /* Perform padding. */
5406 : #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5407 : if (pad_ourselves && has_width)
5408 : {
5409 : size_t w;
5410 : # if ENABLE_UNISTDIO
5411 : /* Outside POSIX, it's preferable to compare the width
5412 : against the number of _characters_ of the converted
5413 : value. */
5414 : w = DCHAR_MBSNLEN (result + length, count);
5415 : # else
5416 : /* The width is compared against the number of _bytes_
5417 : of the converted value, says POSIX. */
5418 : w = count;
5419 : # endif
5420 : if (w < width)
5421 : {
5422 : size_t pad = width - w;
5423 :
5424 : /* Make room for the result. */
5425 : if (xsum (count, pad) > allocated - length)
5426 : {
5427 : /* Need at least count + pad elements. But
5428 : allocate proportionally. */
5429 : size_t n =
5430 : xmax (xsum3 (length, count, pad),
5431 : xtimes (allocated, 2));
5432 :
5433 : # if USE_SNPRINTF
5434 : length += count;
5435 : ENSURE_ALLOCATION (n);
5436 : length -= count;
5437 : # else
5438 : ENSURE_ALLOCATION (n);
5439 : # endif
5440 : }
5441 : /* Here count + pad <= allocated - length. */
5442 :
5443 : {
5444 : # if !DCHAR_IS_TCHAR || USE_SNPRINTF
5445 : DCHAR_T * const rp = result + length;
5446 : # else
5447 : DCHAR_T * const rp = tmp;
5448 : # endif
5449 : DCHAR_T *p = rp + count;
5450 : DCHAR_T *end = p + pad;
5451 : DCHAR_T *pad_ptr;
5452 : # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
5453 : if (dp->conversion == 'c'
5454 : || dp->conversion == 's')
5455 : /* No zero-padding for string directives. */
5456 : pad_ptr = NULL;
5457 : else
5458 : # endif
5459 : {
5460 : pad_ptr = (*rp == '-' ? rp + 1 : rp);
5461 : /* No zero-padding of "inf" and "nan". */
5462 : if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
5463 : || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
5464 : pad_ptr = NULL;
5465 : }
5466 : /* The generated string now extends from rp to p,
5467 : with the zero padding insertion point being at
5468 : pad_ptr. */
5469 :
5470 : count = count + pad; /* = end - rp */
5471 :
5472 : if (flags & FLAG_LEFT)
5473 : {
5474 : /* Pad with spaces on the right. */
5475 : for (; pad > 0; pad--)
5476 : *p++ = ' ';
5477 : }
5478 : else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
5479 : {
5480 : /* Pad with zeroes. */
5481 : DCHAR_T *q = end;
5482 :
5483 : while (p > pad_ptr)
5484 : *--q = *--p;
5485 : for (; pad > 0; pad--)
5486 : *p++ = '0';
5487 : }
5488 : else
5489 : {
5490 : /* Pad with spaces on the left. */
5491 : DCHAR_T *q = end;
5492 :
5493 : while (p > rp)
5494 : *--q = *--p;
5495 : for (; pad > 0; pad--)
5496 : *p++ = ' ';
5497 : }
5498 : }
5499 : }
5500 : }
5501 : #endif
5502 :
5503 : /* Here still count <= allocated - length. */
5504 :
5505 : #if !DCHAR_IS_TCHAR || USE_SNPRINTF
5506 : /* The snprintf() result did fit. */
5507 : #else
5508 : /* Append the sprintf() result. */
5509 : memcpy (result + length, tmp, count * sizeof (DCHAR_T));
5510 : #endif
5511 : #if !USE_SNPRINTF
5512 : if (tmp != tmpbuf)
5513 : free (tmp);
5514 : #endif
5515 :
5516 : #if NEED_PRINTF_DIRECTIVE_F
5517 : if (dp->conversion == 'F')
5518 : {
5519 : /* Convert the %f result to upper case for %F. */
5520 : DCHAR_T *rp = result + length;
5521 : size_t rc;
5522 : for (rc = count; rc > 0; rc--, rp++)
5523 : if (*rp >= 'a' && *rp <= 'z')
5524 : *rp = *rp - 'a' + 'A';
5525 : }
5526 : #endif
5527 :
5528 0 : length += count;
5529 0 : break;
5530 0 : }
5531 0 : errno = orig_errno;
5532 : #undef pad_ourselves
5533 : #undef prec_ourselves
5534 : }
5535 : }
5536 0 : }
5537 :
5538 : /* Add the final NUL. */
5539 0 : ENSURE_ALLOCATION (xsum (length, 1));
5540 0 : result[length] = '\0';
5541 :
5542 0 : if (result != resultbuf && length + 1 < allocated)
5543 : {
5544 : /* Shrink the allocated memory if possible. */
5545 : DCHAR_T *memory;
5546 :
5547 0 : memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
5548 0 : if (memory != NULL)
5549 0 : result = memory;
5550 : }
5551 :
5552 0 : if (buf_malloced != NULL)
5553 0 : free (buf_malloced);
5554 0 : CLEANUP ();
5555 0 : *lengthp = length;
5556 : /* Note that we can produce a big string of a length > INT_MAX. POSIX
5557 : says that snprintf() fails with errno = EOVERFLOW in this case, but
5558 : that's only because snprintf() returns an 'int'. This function does
5559 : not have this limitation. */
5560 0 : return result;
5561 :
5562 : #if USE_SNPRINTF
5563 : overflow:
5564 0 : if (!(result == resultbuf || result == NULL))
5565 0 : free (result);
5566 0 : if (buf_malloced != NULL)
5567 0 : free (buf_malloced);
5568 0 : CLEANUP ();
5569 0 : errno = EOVERFLOW;
5570 0 : return NULL;
5571 : #endif
5572 :
5573 : out_of_memory:
5574 0 : if (!(result == resultbuf || result == NULL))
5575 0 : free (result);
5576 0 : if (buf_malloced != NULL)
5577 0 : free (buf_malloced);
5578 : out_of_memory_1:
5579 0 : CLEANUP ();
5580 0 : errno = ENOMEM;
5581 0 : return NULL;
5582 : }
5583 : }
5584 :
5585 : #undef MAX_ROOM_NEEDED
5586 : #undef TCHARS_PER_DCHAR
5587 : #undef SNPRINTF
5588 : #undef USE_SNPRINTF
5589 : #undef DCHAR_SET
5590 : #undef DCHAR_CPY
5591 : #undef PRINTF_PARSE
5592 : #undef DIRECTIVES
5593 : #undef DIRECTIVE
5594 : #undef DCHAR_IS_TCHAR
5595 : #undef TCHAR_T
5596 : #undef DCHAR_T
5597 : #undef FCHAR_T
5598 : #undef VASNPRINTF
|