Line data Source code
1 : /* -*- buffer-read-only: t -*- vi: set ro: */
2 : /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 : #line 1
4 : /* vsprintf with automatic memory allocation.
5 : Copyright (C) 1999, 2002-2008 Free Software Foundation, Inc.
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3, or (at your option)
10 : any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License along
18 : with this program; if not, write to the Free Software Foundation,
19 : Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
20 :
21 : /* This file can be parametrized with the following macros:
22 : VASNPRINTF The name of the function being defined.
23 : FCHAR_T The element type of the format string.
24 : DCHAR_T The element type of the destination (result) string.
25 : FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
26 : in the format string are ASCII. MUST be set if
27 : FCHAR_T and DCHAR_T are not the same type.
28 : DIRECTIVE Structure denoting a format directive.
29 : Depends on FCHAR_T.
30 : DIRECTIVES Structure denoting the set of format directives of a
31 : format string. Depends on FCHAR_T.
32 : PRINTF_PARSE Function that parses a format string.
33 : Depends on FCHAR_T.
34 : DCHAR_CPY memcpy like function for DCHAR_T[] arrays.
35 : DCHAR_SET memset like function for DCHAR_T[] arrays.
36 : DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays.
37 : SNPRINTF The system's snprintf (or similar) function.
38 : This may be either snprintf or swprintf.
39 : TCHAR_T The element type of the argument and result string
40 : of the said SNPRINTF function. This may be either
41 : char or wchar_t. The code exploits that
42 : sizeof (TCHAR_T) | sizeof (DCHAR_T) and
43 : alignof (TCHAR_T) <= alignof (DCHAR_T).
44 : DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type.
45 : DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
46 : DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t.
47 : DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t.
48 : DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */
49 :
50 : /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
51 : This must come before <config.h> because <config.h> may include
52 : <features.h>, and once <features.h> has been included, it's too late. */
53 : #ifndef _GNU_SOURCE
54 : # define _GNU_SOURCE 1
55 : #endif
56 :
57 : #ifndef VASNPRINTF
58 : # include <config.h>
59 : #endif
60 : #ifndef IN_LIBINTL
61 : # include <alloca.h>
62 : #endif
63 :
64 : /* Specification. */
65 : #ifndef VASNPRINTF
66 : # if WIDE_CHAR_VERSION
67 : # include "vasnwprintf.h"
68 : # else
69 : # include "vasnprintf.h"
70 : # endif
71 : #endif
72 :
73 : #include <locale.h> /* localeconv() */
74 : #include <stdio.h> /* snprintf(), sprintf() */
75 : #include <stdlib.h> /* abort(), malloc(), realloc(), free() */
76 : #include <string.h> /* memcpy(), strlen() */
77 : #include <errno.h> /* errno */
78 : #include <limits.h> /* CHAR_BIT */
79 : #include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
80 : #if HAVE_NL_LANGINFO
81 : # include <langinfo.h>
82 : #endif
83 : #ifndef VASNPRINTF
84 : # if WIDE_CHAR_VERSION
85 : # include "wprintf-parse.h"
86 : # else
87 : # include "printf-parse.h"
88 : # endif
89 : #endif
90 :
91 : /* Checked size_t computations. */
92 : #include "xsize.h"
93 :
94 : #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
95 : # include <math.h>
96 : # include "float+.h"
97 : #endif
98 :
99 : #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
100 : # include <math.h>
101 : # include "isnand.h"
102 : #endif
103 :
104 : #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
105 : # include <math.h>
106 : # include "isnanl-nolibm.h"
107 : # include "fpucw.h"
108 : #endif
109 :
110 : #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
111 : # include <math.h>
112 : # include "isnand.h"
113 : # include "printf-frexp.h"
114 : #endif
115 :
116 : #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
117 : # include <math.h>
118 : # include "isnanl-nolibm.h"
119 : # include "printf-frexpl.h"
120 : # include "fpucw.h"
121 : #endif
122 :
123 : #if HAVE_WCHAR_T
124 : # if HAVE_WCSLEN
125 : # define local_wcslen wcslen
126 : # else
127 : /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
128 : a dependency towards this library, here is a local substitute.
129 : Define this substitute only once, even if this file is included
130 : twice in the same compilation unit. */
131 : # ifndef local_wcslen_defined
132 : # define local_wcslen_defined 1
133 : static size_t
134 : local_wcslen (const wchar_t *s)
135 : {
136 : const wchar_t *ptr;
137 :
138 : for (ptr = s; *ptr != (wchar_t) 0; ptr++)
139 : ;
140 : return ptr - s;
141 : }
142 : # endif
143 : # endif
144 : #endif
145 :
146 : /* Default parameters. */
147 : #ifndef VASNPRINTF
148 : # if WIDE_CHAR_VERSION
149 : # define VASNPRINTF vasnwprintf
150 : # define FCHAR_T wchar_t
151 : # define DCHAR_T wchar_t
152 : # define TCHAR_T wchar_t
153 : # define DCHAR_IS_TCHAR 1
154 : # define DIRECTIVE wchar_t_directive
155 : # define DIRECTIVES wchar_t_directives
156 : # define PRINTF_PARSE wprintf_parse
157 : # define DCHAR_CPY wmemcpy
158 : # else
159 : # define VASNPRINTF vasnprintf
160 : # define FCHAR_T char
161 : # define DCHAR_T char
162 : # define TCHAR_T char
163 : # define DCHAR_IS_TCHAR 1
164 : # define DIRECTIVE char_directive
165 : # define DIRECTIVES char_directives
166 : # define PRINTF_PARSE printf_parse
167 : # define DCHAR_CPY memcpy
168 : # endif
169 : #endif
170 : #if WIDE_CHAR_VERSION
171 : /* TCHAR_T is wchar_t. */
172 : # define USE_SNPRINTF 1
173 : # if HAVE_DECL__SNWPRINTF
174 : /* On Windows, the function swprintf() has a different signature than
175 : on Unix; we use the _snwprintf() function instead. */
176 : # define SNPRINTF _snwprintf
177 : # else
178 : /* Unix. */
179 : # define SNPRINTF swprintf
180 : # endif
181 : #else
182 : /* TCHAR_T is char. */
183 : # /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
184 : But don't use it on BeOS, since BeOS snprintf produces no output if the
185 : size argument is >= 0x3000000. */
186 : # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__
187 : # define USE_SNPRINTF 1
188 : # else
189 : # define USE_SNPRINTF 0
190 : # endif
191 : # if HAVE_DECL__SNPRINTF
192 : /* Windows. */
193 : # define SNPRINTF _snprintf
194 : # else
195 : /* Unix. */
196 : # define SNPRINTF snprintf
197 : /* Here we need to call the native snprintf, not rpl_snprintf. */
198 : # undef snprintf
199 : # endif
200 : #endif
201 : /* Here we need to call the native sprintf, not rpl_sprintf. */
202 : #undef sprintf
203 :
204 : #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
205 : /* Determine the decimal-point character according to the current locale. */
206 : # ifndef decimal_point_char_defined
207 : # define decimal_point_char_defined 1
208 : static char
209 : decimal_point_char ()
210 : {
211 : const char *point;
212 : /* Determine it in a multithread-safe way. We know nl_langinfo is
213 : multithread-safe on glibc systems, but is not required to be multithread-
214 : safe by POSIX. sprintf(), however, is multithread-safe. localeconv()
215 : is rarely multithread-safe. */
216 : # if HAVE_NL_LANGINFO && __GLIBC__
217 : point = nl_langinfo (RADIXCHAR);
218 : # elif 1
219 : char pointbuf[5];
220 : sprintf (pointbuf, "%#.0f", 1.0);
221 : point = &pointbuf[1];
222 : # else
223 : point = localeconv () -> decimal_point;
224 : # endif
225 : /* The decimal point is always a single byte: either '.' or ','. */
226 : return (point[0] != '\0' ? point[0] : '.');
227 : }
228 : # endif
229 : #endif
230 :
231 : #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
232 :
233 : /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
234 : static int
235 : is_infinite_or_zero (double x)
236 : {
237 : return isnand (x) || x + x == x;
238 : }
239 :
240 : #endif
241 :
242 : #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
243 18 :
244 : /* Equivalent to !isfinite(x), but does not require libm. */
245 18 : static int
246 : is_infinitel (long double x)
247 : {
248 : return isnanl (x) || (x + x == x && x != 0.0L);
249 : }
250 :
251 : #endif
252 :
253 : #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
254 :
255 : /* Converting 'long double' to decimal without rare rounding bugs requires
256 : real bignums. We use the naming conventions of GNU gmp, but vastly simpler
257 : (and slower) algorithms. */
258 :
259 : typedef unsigned int mp_limb_t;
260 : # define GMP_LIMB_BITS 32
261 : typedef int mp_limb_verify[2 * (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS) - 1];
262 :
263 : typedef unsigned long long mp_twolimb_t;
264 : # define GMP_TWOLIMB_BITS 64
265 : typedef int mp_twolimb_verify[2 * (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS) - 1];
266 :
267 : /* Representation of a bignum >= 0. */
268 : typedef struct
269 : {
270 : size_t nlimbs;
271 : mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */
272 : } mpn_t;
273 :
274 : /* Compute the product of two bignums >= 0.
275 : Return the allocated memory in case of success, NULL in case of memory
276 : allocation failure. */
277 : static void *
278 : multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
279 : {
280 : const mp_limb_t *p1;
281 : const mp_limb_t *p2;
282 : size_t len1;
283 : size_t len2;
284 :
285 : if (src1.nlimbs <= src2.nlimbs)
286 : {
287 : len1 = src1.nlimbs;
288 : p1 = src1.limbs;
289 : len2 = src2.nlimbs;
290 : p2 = src2.limbs;
291 : }
292 : else
293 : {
294 : len1 = src2.nlimbs;
295 : p1 = src2.limbs;
296 : len2 = src1.nlimbs;
297 : p2 = src1.limbs;
298 : }
299 : /* Now 0 <= len1 <= len2. */
300 : if (len1 == 0)
301 : {
302 : /* src1 or src2 is zero. */
303 : dest->nlimbs = 0;
304 : dest->limbs = (mp_limb_t *) malloc (1);
305 : }
306 : else
307 : {
308 : /* Here 1 <= len1 <= len2. */
309 : size_t dlen;
310 : mp_limb_t *dp;
311 : size_t k, i, j;
312 :
313 : dlen = len1 + len2;
314 : dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
315 : if (dp == NULL)
316 : return NULL;
317 : for (k = len2; k > 0; )
318 : dp[--k] = 0;
319 : for (i = 0; i < len1; i++)
320 : {
321 : mp_limb_t digit1 = p1[i];
322 : mp_twolimb_t carry = 0;
323 : for (j = 0; j < len2; j++)
324 : {
325 : mp_limb_t digit2 = p2[j];
326 : carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
327 : carry += dp[i + j];
328 : dp[i + j] = (mp_limb_t) carry;
329 : carry = carry >> GMP_LIMB_BITS;
330 : }
331 : dp[i + len2] = (mp_limb_t) carry;
332 : }
333 : /* Normalise. */
334 : while (dlen > 0 && dp[dlen - 1] == 0)
335 : dlen--;
336 : dest->nlimbs = dlen;
337 : dest->limbs = dp;
338 : }
339 : return dest->limbs;
340 : }
341 :
342 : /* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
343 : a is written as a = q * b + r with 0 <= r < b. q is the quotient, r
344 : the remainder.
345 : Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
346 : q is incremented.
347 : Return the allocated memory in case of success, NULL in case of memory
348 : allocation failure. */
349 : static void *
350 : divide (mpn_t a, mpn_t b, mpn_t *q)
351 : {
352 : /* Algorithm:
353 : First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
354 : with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
355 : If m<n, then q:=0 and r:=a.
356 : If m>=n=1, perform a single-precision division:
357 : r:=0, j:=m,
358 : while j>0 do
359 : {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
360 : = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
361 : j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
362 : Normalise [q[m-1],...,q[0]], yields q.
363 : If m>=n>1, perform a multiple-precision division:
364 : We have a/b < beta^(m-n+1).
365 : s:=intDsize-1-(hightest bit in b[n-1]), 0<=s<intDsize.
366 : Shift a and b left by s bits, copying them. r:=a.
367 : r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
368 : For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
369 : Compute q* :
370 : q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
371 : In case of overflow (q* >= beta) set q* := beta-1.
372 : Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
373 : and c3 := b[n-2] * q*.
374 : {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
375 : occurred. Furthermore 0 <= c3 < beta^2.
376 : If there was overflow and
377 : r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
378 : the next test can be skipped.}
379 : While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
380 : Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
381 : If q* > 0:
382 : Put r := r - b * q* * beta^j. In detail:
383 : [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
384 : hence: u:=0, for i:=0 to n-1 do
385 : u := u + q* * b[i],
386 : r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
387 : u:=u div beta (+ 1, if carry in subtraction)
388 : r[n+j]:=r[n+j]-u.
389 : {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
390 : < q* + 1 <= beta,
391 : the carry u does not overflow.}
392 : If a negative carry occurs, put q* := q* - 1
393 : and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
394 : Set q[j] := q*.
395 : Normalise [q[m-n],..,q[0]]; this yields the quotient q.
396 : Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
397 : rest r.
398 : The room for q[j] can be allocated at the memory location of r[n+j].
399 : Finally, round-to-even:
400 : Shift r left by 1 bit.
401 : If r > b or if r = b and q[0] is odd, q := q+1.
402 : */
403 : const mp_limb_t *a_ptr = a.limbs;
404 : size_t a_len = a.nlimbs;
405 : const mp_limb_t *b_ptr = b.limbs;
406 : size_t b_len = b.nlimbs;
407 : mp_limb_t *roomptr;
408 : mp_limb_t *tmp_roomptr = NULL;
409 : mp_limb_t *q_ptr;
410 : size_t q_len;
411 : mp_limb_t *r_ptr;
412 : size_t r_len;
413 :
414 : /* Allocate room for a_len+2 digits.
415 : (Need a_len+1 digits for the real division and 1 more digit for the
416 : final rounding of q.) */
417 : roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
418 : if (roomptr == NULL)
419 : return NULL;
420 :
421 : /* Normalise a. */
422 : while (a_len > 0 && a_ptr[a_len - 1] == 0)
423 : a_len--;
424 :
425 : /* Normalise b. */
426 : for (;;)
427 : {
428 : if (b_len == 0)
429 : /* Division by zero. */
430 : abort ();
431 : if (b_ptr[b_len - 1] == 0)
432 : b_len--;
433 : else
434 : break;
435 : }
436 :
437 : /* Here m = a_len >= 0 and n = b_len > 0. */
438 :
439 : if (a_len < b_len)
440 : {
441 : /* m<n: trivial case. q=0, r := copy of a. */
442 : r_ptr = roomptr;
443 : r_len = a_len;
444 : memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
445 : q_ptr = roomptr + a_len;
446 : q_len = 0;
447 : }
448 : else if (b_len == 1)
449 : {
450 : /* n=1: single precision division.
451 : beta^(m-1) <= a < beta^m ==> beta^(m-2) <= a/b < beta^m */
452 : r_ptr = roomptr;
453 : q_ptr = roomptr + 1;
454 : {
455 : mp_limb_t den = b_ptr[0];
456 : mp_limb_t remainder = 0;
457 : const mp_limb_t *sourceptr = a_ptr + a_len;
458 : mp_limb_t *destptr = q_ptr + a_len;
459 : size_t count;
460 : for (count = a_len; count > 0; count--)
461 : {
462 : mp_twolimb_t num =
463 : ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
464 : *--destptr = num / den;
465 : remainder = num % den;
466 : }
467 : /* Normalise and store r. */
468 : if (remainder > 0)
469 : {
470 : r_ptr[0] = remainder;
471 : r_len = 1;
472 : }
473 : else
474 : r_len = 0;
475 : /* Normalise q. */
476 : q_len = a_len;
477 : if (q_ptr[q_len - 1] == 0)
478 : q_len--;
479 : }
480 : }
481 : else
482 : {
483 : /* n>1: multiple precision division.
484 : beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n ==>
485 : beta^(m-n-1) <= a/b < beta^(m-n+1). */
486 : /* Determine s. */
487 : size_t s;
488 : {
489 : mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
490 : s = 31;
491 : if (msd >= 0x10000)
492 : {
493 : msd = msd >> 16;
494 : s -= 16;
495 : }
496 : if (msd >= 0x100)
497 : {
498 : msd = msd >> 8;
499 : s -= 8;
500 : }
501 : if (msd >= 0x10)
502 : {
503 : msd = msd >> 4;
504 : s -= 4;
505 : }
506 : if (msd >= 0x4)
507 : {
508 : msd = msd >> 2;
509 : s -= 2;
510 : }
511 : if (msd >= 0x2)
512 : {
513 : msd = msd >> 1;
514 : s -= 1;
515 : }
516 : }
517 : /* 0 <= s < GMP_LIMB_BITS.
518 : Copy b, shifting it left by s bits. */
519 : if (s > 0)
520 : {
521 : tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
522 : if (tmp_roomptr == NULL)
523 : {
524 : free (roomptr);
525 : return NULL;
526 : }
527 : {
528 : const mp_limb_t *sourceptr = b_ptr;
529 : mp_limb_t *destptr = tmp_roomptr;
530 : mp_twolimb_t accu = 0;
531 : size_t count;
532 : for (count = b_len; count > 0; count--)
533 : {
534 : accu += (mp_twolimb_t) *sourceptr++ << s;
535 : *destptr++ = (mp_limb_t) accu;
536 : accu = accu >> GMP_LIMB_BITS;
537 : }
538 : /* accu must be zero, since that was how s was determined. */
539 : if (accu != 0)
540 : abort ();
541 : }
542 : b_ptr = tmp_roomptr;
543 : }
544 : /* Copy a, shifting it left by s bits, yields r.
545 : Memory layout:
546 : At the beginning: r = roomptr[0..a_len],
547 : at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len] */
548 : r_ptr = roomptr;
549 : if (s == 0)
550 : {
551 : memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
552 : r_ptr[a_len] = 0;
553 : }
554 : else
555 : {
556 : const mp_limb_t *sourceptr = a_ptr;
557 : mp_limb_t *destptr = r_ptr;
558 : mp_twolimb_t accu = 0;
559 : size_t count;
560 : for (count = a_len; count > 0; count--)
561 : {
562 : accu += (mp_twolimb_t) *sourceptr++ << s;
563 : *destptr++ = (mp_limb_t) accu;
564 : accu = accu >> GMP_LIMB_BITS;
565 : }
566 : *destptr++ = (mp_limb_t) accu;
567 : }
568 : q_ptr = roomptr + b_len;
569 : q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
570 : {
571 : size_t j = a_len - b_len; /* m-n */
572 : mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
573 : mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
574 : mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
575 : ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
576 : /* Division loop, traversed m-n+1 times.
577 : j counts down, b is unchanged, beta/2 <= b[n-1] < beta. */
578 : for (;;)
579 : {
580 : mp_limb_t q_star;
581 : mp_limb_t c1;
582 : if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
583 : {
584 : /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow. */
585 : mp_twolimb_t num =
586 : ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
587 : | r_ptr[j + b_len - 1];
588 : q_star = num / b_msd;
589 : c1 = num % b_msd;
590 : }
591 : else
592 : {
593 : /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1]. */
594 : q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
595 : /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
596 : <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
597 : <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
598 : {<= beta !}.
599 : If yes, jump directly to the subtraction loop.
600 : (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
601 : <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
602 : if (r_ptr[j + b_len] > b_msd
603 : || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
604 : /* r[j+n] >= b[n-1]+1 or
605 : r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
606 : carry. */
607 : goto subtract;
608 : }
609 : /* q_star = q*,
610 : c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta). */
611 : {
612 : mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
613 : ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
614 : mp_twolimb_t c3 = /* b[n-2] * q* */
615 : (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
616 : /* While c2 < c3, increase c2 and decrease c3.
617 : Consider c3-c2. While it is > 0, decrease it by
618 : b[n-1]*beta+b[n-2]. Because of b[n-1]*beta+b[n-2] >= beta^2/2
619 : this can happen only twice. */
620 : if (c3 > c2)
621 : {
622 : q_star = q_star - 1; /* q* := q* - 1 */
623 : if (c3 - c2 > b_msdd)
624 : q_star = q_star - 1; /* q* := q* - 1 */
625 : }
626 : }
627 : if (q_star > 0)
628 : subtract:
629 : {
630 : /* Subtract r := r - b * q* * beta^j. */
631 : mp_limb_t cr;
632 : {
633 : const mp_limb_t *sourceptr = b_ptr;
634 : mp_limb_t *destptr = r_ptr + j;
635 : mp_twolimb_t carry = 0;
636 : size_t count;
637 : for (count = b_len; count > 0; count--)
638 : {
639 : /* Here 0 <= carry <= q*. */
640 : carry =
641 : carry
642 : + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
643 : + (mp_limb_t) ~(*destptr);
644 : /* Here 0 <= carry <= beta*q* + beta-1. */
645 : *destptr++ = ~(mp_limb_t) carry;
646 : carry = carry >> GMP_LIMB_BITS; /* <= q* */
647 : }
648 : cr = (mp_limb_t) carry;
649 : }
650 : /* Subtract cr from r_ptr[j + b_len], then forget about
651 : r_ptr[j + b_len]. */
652 : if (cr > r_ptr[j + b_len])
653 : {
654 : /* Subtraction gave a carry. */
655 : q_star = q_star - 1; /* q* := q* - 1 */
656 : /* Add b back. */
657 : {
658 : const mp_limb_t *sourceptr = b_ptr;
659 : mp_limb_t *destptr = r_ptr + j;
660 : mp_limb_t carry = 0;
661 : size_t count;
662 : for (count = b_len; count > 0; count--)
663 : {
664 : mp_limb_t source1 = *sourceptr++;
665 : mp_limb_t source2 = *destptr;
666 : *destptr++ = source1 + source2 + carry;
667 : carry =
668 : (carry
669 : ? source1 >= (mp_limb_t) ~source2
670 : : source1 > (mp_limb_t) ~source2);
671 : }
672 : }
673 : /* Forget about the carry and about r[j+n]. */
674 : }
675 : }
676 : /* q* is determined. Store it as q[j]. */
677 : q_ptr[j] = q_star;
678 : if (j == 0)
679 : break;
680 : j--;
681 : }
682 : }
683 : r_len = b_len;
684 : /* Normalise q. */
685 : if (q_ptr[q_len - 1] == 0)
686 : q_len--;
687 : # if 0 /* Not needed here, since we need r only to compare it with b/2, and
688 : b is shifted left by s bits. */
689 : /* Shift r right by s bits. */
690 : if (s > 0)
691 : {
692 : mp_limb_t ptr = r_ptr + r_len;
693 : mp_twolimb_t accu = 0;
694 : size_t count;
695 : for (count = r_len; count > 0; count--)
696 : {
697 : accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
698 : accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
699 : *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
700 : }
701 : }
702 : # endif
703 : /* Normalise r. */
704 : while (r_len > 0 && r_ptr[r_len - 1] == 0)
705 : r_len--;
706 : }
707 : /* Compare r << 1 with b. */
708 : if (r_len > b_len)
709 : goto increment_q;
710 : {
711 : size_t i;
712 : for (i = b_len;;)
713 : {
714 : mp_limb_t r_i =
715 : (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
716 : | (i < r_len ? r_ptr[i] << 1 : 0);
717 : mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
718 : if (r_i > b_i)
719 : goto increment_q;
720 : if (r_i < b_i)
721 : goto keep_q;
722 : if (i == 0)
723 : break;
724 : i--;
725 : }
726 : }
727 : if (q_len > 0 && ((q_ptr[0] & 1) != 0))
728 : /* q is odd. */
729 : increment_q:
730 : {
731 : size_t i;
732 : for (i = 0; i < q_len; i++)
733 : if (++(q_ptr[i]) != 0)
734 : goto keep_q;
735 : q_ptr[q_len++] = 1;
736 : }
737 : keep_q:
738 : if (tmp_roomptr != NULL)
739 : free (tmp_roomptr);
740 : q->limbs = q_ptr;
741 : q->nlimbs = q_len;
742 : return roomptr;
743 : }
744 :
745 : /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
746 : representation.
747 : Destroys the contents of a.
748 : Return the allocated memory - containing the decimal digits in low-to-high
749 : order, terminated with a NUL character - in case of success, NULL in case
750 : of memory allocation failure. */
751 : static char *
752 : convert_to_decimal (mpn_t a, size_t extra_zeroes)
753 : {
754 : mp_limb_t *a_ptr = a.limbs;
755 : size_t a_len = a.nlimbs;
756 : /* 0.03345 is slightly larger than log(2)/(9*log(10)). */
757 : size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
758 : char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes));
759 : if (c_ptr != NULL)
760 : {
761 : char *d_ptr = c_ptr;
762 : for (; extra_zeroes > 0; extra_zeroes--)
763 : *d_ptr++ = '0';
764 : while (a_len > 0)
765 : {
766 : /* Divide a by 10^9, in-place. */
767 : mp_limb_t remainder = 0;
768 : mp_limb_t *ptr = a_ptr + a_len;
769 : size_t count;
770 : for (count = a_len; count > 0; count--)
771 : {
772 : mp_twolimb_t num =
773 : ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
774 : *ptr = num / 1000000000;
775 : remainder = num % 1000000000;
776 : }
777 : /* Store the remainder as 9 decimal digits. */
778 : for (count = 9; count > 0; count--)
779 : {
780 : *d_ptr++ = '0' + (remainder % 10);
781 : remainder = remainder / 10;
782 : }
783 : /* Normalize a. */
784 : if (a_ptr[a_len - 1] == 0)
785 : a_len--;
786 : }
787 : /* Remove leading zeroes. */
788 : while (d_ptr > c_ptr && d_ptr[-1] == '0')
789 : d_ptr--;
790 : /* But keep at least one zero. */
791 : if (d_ptr == c_ptr)
792 : *d_ptr++ = '0';
793 : /* Terminate the string. */
794 : *d_ptr = '\0';
795 : }
796 : return c_ptr;
797 : }
798 :
799 : # if NEED_PRINTF_LONG_DOUBLE
800 :
801 : /* Assuming x is finite and >= 0:
802 : write x as x = 2^e * m, where m is a bignum.
803 : Return the allocated memory in case of success, NULL in case of memory
804 : allocation failure. */
805 : static void *
806 : decode_long_double (long double x, int *ep, mpn_t *mp)
807 : {
808 : mpn_t m;
809 : int exp;
810 : long double y;
811 : size_t i;
812 :
813 : /* Allocate memory for result. */
814 : m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
815 : m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
816 : if (m.limbs == NULL)
817 : return NULL;
818 : /* Split into exponential part and mantissa. */
819 : y = frexpl (x, &exp);
820 : if (!(y >= 0.0L && y < 1.0L))
821 : abort ();
822 : /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * LDBL_MANT_BIT), and the
823 : latter is an integer. */
824 : /* Convert the mantissa (y * LDBL_MANT_BIT) to a sequence of limbs.
825 : I'm not sure whether it's safe to cast a 'long double' value between
826 : 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
827 : 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
828 : doesn't matter). */
829 : # if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
830 : # if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
831 : {
832 : mp_limb_t hi, lo;
833 : y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
834 : hi = (int) y;
835 : y -= hi;
836 : if (!(y >= 0.0L && y < 1.0L))
837 : abort ();
838 : y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
839 : lo = (int) y;
840 : y -= lo;
841 : if (!(y >= 0.0L && y < 1.0L))
842 : abort ();
843 : m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
844 : }
845 : # else
846 : {
847 : mp_limb_t d;
848 : y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
849 : d = (int) y;
850 : y -= d;
851 : if (!(y >= 0.0L && y < 1.0L))
852 : abort ();
853 : m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
854 : }
855 : # endif
856 : # endif
857 : for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
858 : {
859 : mp_limb_t hi, lo;
860 : y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
861 : hi = (int) y;
862 : y -= hi;
863 : if (!(y >= 0.0L && y < 1.0L))
864 : abort ();
865 : y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
866 : lo = (int) y;
867 : y -= lo;
868 : if (!(y >= 0.0L && y < 1.0L))
869 : abort ();
870 : m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
871 : }
872 : #if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
873 : precision. */
874 : if (!(y == 0.0L))
875 : abort ();
876 : #endif
877 : /* Normalise. */
878 : while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
879 : m.nlimbs--;
880 : *mp = m;
881 : *ep = exp - LDBL_MANT_BIT;
882 : return m.limbs;
883 : }
884 :
885 : # endif
886 :
887 : # if NEED_PRINTF_DOUBLE
888 :
889 : /* Assuming x is finite and >= 0:
890 : write x as x = 2^e * m, where m is a bignum.
891 : Return the allocated memory in case of success, NULL in case of memory
892 : allocation failure. */
893 : static void *
894 : decode_double (double x, int *ep, mpn_t *mp)
895 : {
896 : mpn_t m;
897 : int exp;
898 : double y;
899 : size_t i;
900 :
901 : /* Allocate memory for result. */
902 : m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
903 : m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
904 : if (m.limbs == NULL)
905 : return NULL;
906 : /* Split into exponential part and mantissa. */
907 : y = frexp (x, &exp);
908 : if (!(y >= 0.0 && y < 1.0))
909 : abort ();
910 : /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * DBL_MANT_BIT), and the
911 : latter is an integer. */
912 : /* Convert the mantissa (y * DBL_MANT_BIT) to a sequence of limbs.
913 : I'm not sure whether it's safe to cast a 'double' value between
914 : 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
915 : 'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
916 : doesn't matter). */
917 : # if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
918 : # if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
919 : {
920 : mp_limb_t hi, lo;
921 : y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
922 : hi = (int) y;
923 : y -= hi;
924 : if (!(y >= 0.0 && y < 1.0))
925 : abort ();
926 : y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
927 : lo = (int) y;
928 : y -= lo;
929 : if (!(y >= 0.0 && y < 1.0))
930 : abort ();
931 : m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
932 : }
933 : # else
934 : {
935 : mp_limb_t d;
936 : y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
937 : d = (int) y;
938 : y -= d;
939 : if (!(y >= 0.0 && y < 1.0))
940 : abort ();
941 : m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
942 : }
943 : # endif
944 : # endif
945 : for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
946 : {
947 : mp_limb_t hi, lo;
948 : y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
949 : hi = (int) y;
950 : y -= hi;
951 : if (!(y >= 0.0 && y < 1.0))
952 : abort ();
953 : y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
954 : lo = (int) y;
955 : y -= lo;
956 : if (!(y >= 0.0 && y < 1.0))
957 : abort ();
958 : m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
959 : }
960 : if (!(y == 0.0))
961 : abort ();
962 : /* Normalise. */
963 : while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
964 : m.nlimbs--;
965 : *mp = m;
966 : *ep = exp - DBL_MANT_BIT;
967 : return m.limbs;
968 : }
969 :
970 : # endif
971 :
972 : /* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
973 : Returns the decimal representation of round (x * 10^n).
974 : Return the allocated memory - containing the decimal digits in low-to-high
975 : order, terminated with a NUL character - in case of success, NULL in case
976 : of memory allocation failure. */
977 : static char *
978 : scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
979 : {
980 : int s;
981 : size_t extra_zeroes;
982 : unsigned int abs_n;
983 : unsigned int abs_s;
984 : mp_limb_t *pow5_ptr;
985 : size_t pow5_len;
986 : unsigned int s_limbs;
987 : unsigned int s_bits;
988 : mpn_t pow5;
989 : mpn_t z;
990 : void *z_memory;
991 : char *digits;
992 :
993 : if (memory == NULL)
994 : return NULL;
995 : /* x = 2^e * m, hence
996 : y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
997 : = round (2^s * 5^n * m). */
998 : s = e + n;
999 : extra_zeroes = 0;
1000 : /* Factor out a common power of 10 if possible. */
1001 : if (s > 0 && n > 0)
1002 : {
1003 : extra_zeroes = (s < n ? s : n);
1004 : s -= extra_zeroes;
1005 : n -= extra_zeroes;
1006 : }
1007 : /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
1008 : Before converting to decimal, we need to compute
1009 : z = round (2^s * 5^n * m). */
1010 : /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
1011 : sign. 2.322 is slightly larger than log(5)/log(2). */
1012 : abs_n = (n >= 0 ? n : -n);
1013 : abs_s = (s >= 0 ? s : -s);
1014 : pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
1015 : + abs_s / GMP_LIMB_BITS + 1)
1016 : * sizeof (mp_limb_t));
1017 : if (pow5_ptr == NULL)
1018 : {
1019 : free (memory);
1020 : return NULL;
1021 : }
1022 : /* Initialize with 1. */
1023 : pow5_ptr[0] = 1;
1024 : pow5_len = 1;
1025 : /* Multiply with 5^|n|. */
1026 : if (abs_n > 0)
1027 : {
1028 : static mp_limb_t const small_pow5[13 + 1] =
1029 : {
1030 : 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
1031 : 48828125, 244140625, 1220703125
1032 : };
1033 : unsigned int n13;
1034 : for (n13 = 0; n13 <= abs_n; n13 += 13)
1035 : {
1036 : mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
1037 : size_t j;
1038 : mp_twolimb_t carry = 0;
1039 : for (j = 0; j < pow5_len; j++)
1040 : {
1041 : mp_limb_t digit2 = pow5_ptr[j];
1042 : carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
1043 : pow5_ptr[j] = (mp_limb_t) carry;
1044 : carry = carry >> GMP_LIMB_BITS;
1045 : }
1046 : if (carry > 0)
1047 : pow5_ptr[pow5_len++] = (mp_limb_t) carry;
1048 : }
1049 : }
1050 : s_limbs = abs_s / GMP_LIMB_BITS;
1051 : s_bits = abs_s % GMP_LIMB_BITS;
1052 : if (n >= 0 ? s >= 0 : s <= 0)
1053 : {
1054 : /* Multiply with 2^|s|. */
1055 : if (s_bits > 0)
1056 : {
1057 : mp_limb_t *ptr = pow5_ptr;
1058 : mp_twolimb_t accu = 0;
1059 : size_t count;
1060 : for (count = pow5_len; count > 0; count--)
1061 : {
1062 : accu += (mp_twolimb_t) *ptr << s_bits;
1063 : *ptr++ = (mp_limb_t) accu;
1064 : accu = accu >> GMP_LIMB_BITS;
1065 : }
1066 : if (accu > 0)
1067 : {
1068 : *ptr = (mp_limb_t) accu;
1069 : pow5_len++;
1070 : }
1071 : }
1072 : if (s_limbs > 0)
1073 : {
1074 : size_t count;
1075 : for (count = pow5_len; count > 0;)
1076 : {
1077 : count--;
1078 : pow5_ptr[s_limbs + count] = pow5_ptr[count];
1079 : }
1080 : for (count = s_limbs; count > 0;)
1081 : {
1082 : count--;
1083 : pow5_ptr[count] = 0;
1084 : }
1085 : pow5_len += s_limbs;
1086 : }
1087 : pow5.limbs = pow5_ptr;
1088 : pow5.nlimbs = pow5_len;
1089 : if (n >= 0)
1090 : {
1091 : /* Multiply m with pow5. No division needed. */
1092 : z_memory = multiply (m, pow5, &z);
1093 : }
1094 : else
1095 : {
1096 : /* Divide m by pow5 and round. */
1097 : z_memory = divide (m, pow5, &z);
1098 : }
1099 : }
1100 : else
1101 : {
1102 : pow5.limbs = pow5_ptr;
1103 : pow5.nlimbs = pow5_len;
1104 : if (n >= 0)
1105 : {
1106 : /* n >= 0, s < 0.
1107 : Multiply m with pow5, then divide by 2^|s|. */
1108 : mpn_t numerator;
1109 : mpn_t denominator;
1110 : void *tmp_memory;
1111 : tmp_memory = multiply (m, pow5, &numerator);
1112 : if (tmp_memory == NULL)
1113 : {
1114 : free (pow5_ptr);
1115 : free (memory);
1116 : return NULL;
1117 : }
1118 : /* Construct 2^|s|. */
1119 : {
1120 : mp_limb_t *ptr = pow5_ptr + pow5_len;
1121 : size_t i;
1122 : for (i = 0; i < s_limbs; i++)
1123 : ptr[i] = 0;
1124 : ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
1125 : denominator.limbs = ptr;
1126 : denominator.nlimbs = s_limbs + 1;
1127 : }
1128 : z_memory = divide (numerator, denominator, &z);
1129 : free (tmp_memory);
1130 : }
1131 : else
1132 : {
1133 : /* n < 0, s > 0.
1134 : Multiply m with 2^s, then divide by pow5. */
1135 : mpn_t numerator;
1136 : mp_limb_t *num_ptr;
1137 : num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
1138 : * sizeof (mp_limb_t));
1139 : if (num_ptr == NULL)
1140 : {
1141 : free (pow5_ptr);
1142 : free (memory);
1143 : return NULL;
1144 : }
1145 : {
1146 : mp_limb_t *destptr = num_ptr;
1147 : {
1148 : size_t i;
1149 : for (i = 0; i < s_limbs; i++)
1150 : *destptr++ = 0;
1151 : }
1152 : if (s_bits > 0)
1153 : {
1154 : const mp_limb_t *sourceptr = m.limbs;
1155 : mp_twolimb_t accu = 0;
1156 : size_t count;
1157 : for (count = m.nlimbs; count > 0; count--)
1158 : {
1159 : accu += (mp_twolimb_t) *sourceptr++ << s_bits;
1160 : *destptr++ = (mp_limb_t) accu;
1161 : accu = accu >> GMP_LIMB_BITS;
1162 : }
1163 : if (accu > 0)
1164 : *destptr++ = (mp_limb_t) accu;
1165 : }
1166 : else
1167 : {
1168 : const mp_limb_t *sourceptr = m.limbs;
1169 : size_t count;
1170 : for (count = m.nlimbs; count > 0; count--)
1171 : *destptr++ = *sourceptr++;
1172 : }
1173 : numerator.limbs = num_ptr;
1174 : numerator.nlimbs = destptr - num_ptr;
1175 : }
1176 : z_memory = divide (numerator, pow5, &z);
1177 : free (num_ptr);
1178 : }
1179 : }
1180 : free (pow5_ptr);
1181 : free (memory);
1182 :
1183 : /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */
1184 :
1185 : if (z_memory == NULL)
1186 : return NULL;
1187 : digits = convert_to_decimal (z, extra_zeroes);
1188 : free (z_memory);
1189 : return digits;
1190 : }
1191 :
1192 : # if NEED_PRINTF_LONG_DOUBLE
1193 :
1194 : /* Assuming x is finite and >= 0, and n is an integer:
1195 : Returns the decimal representation of round (x * 10^n).
1196 : Return the allocated memory - containing the decimal digits in low-to-high
1197 : order, terminated with a NUL character - in case of success, NULL in case
1198 : of memory allocation failure. */
1199 : static char *
1200 : scale10_round_decimal_long_double (long double x, int n)
1201 : {
1202 : int e;
1203 : mpn_t m;
1204 : void *memory = decode_long_double (x, &e, &m);
1205 : return scale10_round_decimal_decoded (e, m, memory, n);
1206 : }
1207 :
1208 : # endif
1209 :
1210 : # if NEED_PRINTF_DOUBLE
1211 :
1212 : /* Assuming x is finite and >= 0, and n is an integer:
1213 : Returns the decimal representation of round (x * 10^n).
1214 : Return the allocated memory - containing the decimal digits in low-to-high
1215 : order, terminated with a NUL character - in case of success, NULL in case
1216 : of memory allocation failure. */
1217 : static char *
1218 : scale10_round_decimal_double (double x, int n)
1219 : {
1220 : int e;
1221 : mpn_t m;
1222 : void *memory = decode_double (x, &e, &m);
1223 : return scale10_round_decimal_decoded (e, m, memory, n);
1224 : }
1225 :
1226 : # endif
1227 :
1228 : # if NEED_PRINTF_LONG_DOUBLE
1229 :
1230 : /* Assuming x is finite and > 0:
1231 : Return an approximation for n with 10^n <= x < 10^(n+1).
1232 : The approximation is usually the right n, but may be off by 1 sometimes. */
1233 : static int
1234 : floorlog10l (long double x)
1235 : {
1236 : int exp;
1237 : long double y;
1238 : double z;
1239 : double l;
1240 :
1241 : /* Split into exponential part and mantissa. */
1242 : y = frexpl (x, &exp);
1243 : if (!(y >= 0.0L && y < 1.0L))
1244 : abort ();
1245 : if (y == 0.0L)
1246 : return INT_MIN;
1247 : if (y < 0.5L)
1248 : {
1249 : while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1250 : {
1251 : y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1252 : exp -= GMP_LIMB_BITS;
1253 : }
1254 : if (y < (1.0L / (1 << 16)))
1255 : {
1256 : y *= 1.0L * (1 << 16);
1257 : exp -= 16;
1258 : }
1259 : if (y < (1.0L / (1 << 8)))
1260 : {
1261 : y *= 1.0L * (1 << 8);
1262 : exp -= 8;
1263 : }
1264 : if (y < (1.0L / (1 << 4)))
1265 : {
1266 : y *= 1.0L * (1 << 4);
1267 : exp -= 4;
1268 : }
1269 : if (y < (1.0L / (1 << 2)))
1270 : {
1271 : y *= 1.0L * (1 << 2);
1272 : exp -= 2;
1273 : }
1274 : if (y < (1.0L / (1 << 1)))
1275 : {
1276 : y *= 1.0L * (1 << 1);
1277 : exp -= 1;
1278 : }
1279 : }
1280 : if (!(y >= 0.5L && y < 1.0L))
1281 : abort ();
1282 : /* Compute an approximation for l = log2(x) = exp + log2(y). */
1283 : l = exp;
1284 : z = y;
1285 : if (z < 0.70710678118654752444)
1286 : {
1287 : z *= 1.4142135623730950488;
1288 : l -= 0.5;
1289 : }
1290 : if (z < 0.8408964152537145431)
1291 : {
1292 : z *= 1.1892071150027210667;
1293 : l -= 0.25;
1294 : }
1295 : if (z < 0.91700404320467123175)
1296 : {
1297 : z *= 1.0905077326652576592;
1298 : l -= 0.125;
1299 : }
1300 : if (z < 0.9576032806985736469)
1301 : {
1302 : z *= 1.0442737824274138403;
1303 : l -= 0.0625;
1304 : }
1305 : /* Now 0.95 <= z <= 1.01. */
1306 : z = 1 - z;
1307 : /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ...
1308 : Four terms are enough to get an approximation with error < 10^-7. */
1309 : l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1310 : /* Finally multiply with log(2)/log(10), yields an approximation for
1311 : log10(x). */
1312 : l *= 0.30102999566398119523;
1313 : /* Round down to the next integer. */
1314 : return (int) l + (l < 0 ? -1 : 0);
1315 : }
1316 :
1317 : # endif
1318 :
1319 : # if NEED_PRINTF_DOUBLE
1320 :
1321 : /* Assuming x is finite and > 0:
1322 : Return an approximation for n with 10^n <= x < 10^(n+1).
1323 : The approximation is usually the right n, but may be off by 1 sometimes. */
1324 : static int
1325 : floorlog10 (double x)
1326 : {
1327 : int exp;
1328 : double y;
1329 : double z;
1330 : double l;
1331 :
1332 : /* Split into exponential part and mantissa. */
1333 : y = frexp (x, &exp);
1334 : if (!(y >= 0.0 && y < 1.0))
1335 : abort ();
1336 : if (y == 0.0)
1337 : return INT_MIN;
1338 : if (y < 0.5)
1339 : {
1340 : while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1341 : {
1342 : y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1343 : exp -= GMP_LIMB_BITS;
1344 : }
1345 : if (y < (1.0 / (1 << 16)))
1346 : {
1347 : y *= 1.0 * (1 << 16);
1348 : exp -= 16;
1349 : }
1350 : if (y < (1.0 / (1 << 8)))
1351 : {
1352 : y *= 1.0 * (1 << 8);
1353 : exp -= 8;
1354 : }
1355 : if (y < (1.0 / (1 << 4)))
1356 : {
1357 : y *= 1.0 * (1 << 4);
1358 : exp -= 4;
1359 : }
1360 : if (y < (1.0 / (1 << 2)))
1361 : {
1362 : y *= 1.0 * (1 << 2);
1363 : exp -= 2;
1364 : }
1365 : if (y < (1.0 / (1 << 1)))
1366 : {
1367 : y *= 1.0 * (1 << 1);
1368 : exp -= 1;
1369 : }
1370 : }
1371 : if (!(y >= 0.5 && y < 1.0))
1372 : abort ();
1373 : /* Compute an approximation for l = log2(x) = exp + log2(y). */
1374 : l = exp;
1375 : z = y;
1376 : if (z < 0.70710678118654752444)
1377 : {
1378 : z *= 1.4142135623730950488;
1379 : l -= 0.5;
1380 : }
1381 : if (z < 0.8408964152537145431)
1382 : {
1383 : z *= 1.1892071150027210667;
1384 : l -= 0.25;
1385 : }
1386 : if (z < 0.91700404320467123175)
1387 : {
1388 : z *= 1.0905077326652576592;
1389 : l -= 0.125;
1390 : }
1391 : if (z < 0.9576032806985736469)
1392 : {
1393 : z *= 1.0442737824274138403;
1394 : l -= 0.0625;
1395 : }
1396 : /* Now 0.95 <= z <= 1.01. */
1397 : z = 1 - z;
1398 : /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ...
1399 : Four terms are enough to get an approximation with error < 10^-7. */
1400 : l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1401 : /* Finally multiply with log(2)/log(10), yields an approximation for
1402 : log10(x). */
1403 : l *= 0.30102999566398119523;
1404 : /* Round down to the next integer. */
1405 : return (int) l + (l < 0 ? -1 : 0);
1406 : }
1407 :
1408 : # endif
1409 :
1410 731 : #endif
1411 :
1412 : DCHAR_T *
1413 : VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
1414 : const FCHAR_T *format, va_list args)
1415 : {
1416 731 : DIRECTIVES d;
1417 : arguments a;
1418 0 :
1419 : if (PRINTF_PARSE (format, &d, &a) < 0)
1420 : /* errno is already set. */
1421 : return NULL;
1422 :
1423 : #define CLEANUP() \
1424 : free (d.dir); \
1425 731 : if (a.arg) \
1426 : free (a.arg);
1427 0 :
1428 0 : if (PRINTF_FETCHARGS (args, &a) < 0)
1429 0 : {
1430 : CLEANUP ();
1431 : errno = EINVAL;
1432 : return NULL;
1433 : }
1434 :
1435 : {
1436 : size_t buf_neededlength;
1437 : TCHAR_T *buf;
1438 : TCHAR_T *buf_malloced;
1439 : const FCHAR_T *cp;
1440 : size_t i;
1441 : DIRECTIVE *dp;
1442 : /* Output string accumulator. */
1443 : DCHAR_T *result;
1444 : size_t allocated;
1445 : size_t length;
1446 731 :
1447 731 : /* Allocate a small buffer that will hold a directive passed to
1448 : sprintf or snprintf. */
1449 731 : buf_neededlength =
1450 : xsum4 (7, d.max_width_length, d.max_precision_length, 6);
1451 731 : #if HAVE_ALLOCA
1452 731 : if (buf_neededlength < 4000 / sizeof (TCHAR_T))
1453 : {
1454 : buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
1455 : buf_malloced = NULL;
1456 : }
1457 0 : else
1458 0 : #endif
1459 0 : {
1460 0 : size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
1461 0 : if (size_overflow_p (buf_memsize))
1462 0 : goto out_of_memory_1;
1463 0 : buf = (TCHAR_T *) malloc (buf_memsize);
1464 : if (buf == NULL)
1465 : goto out_of_memory_1;
1466 731 : buf_malloced = buf;
1467 : }
1468 131 :
1469 131 : if (resultbuf != NULL)
1470 : {
1471 : result = resultbuf;
1472 : allocated = *lengthp;
1473 600 : }
1474 600 : else
1475 : {
1476 731 : result = NULL;
1477 : allocated = 0;
1478 : }
1479 : length = 0;
1480 : /* Invariants:
1481 : result is either == resultbuf or == NULL or malloc-allocated.
1482 : If length > 0, then result != NULL. */
1483 :
1484 : /* Ensures that allocated >= needed. Aborts through a jump to
1485 : out_of_memory if needed is SIZE_MAX or otherwise too big. */
1486 : #define ENSURE_ALLOCATION(needed) \
1487 : if ((needed) > allocated) \
1488 : { \
1489 : size_t memory_size; \
1490 : DCHAR_T *memory; \
1491 : \
1492 : allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \
1493 : if ((needed) > allocated) \
1494 : allocated = (needed); \
1495 : memory_size = xtimes (allocated, sizeof (DCHAR_T)); \
1496 : if (size_overflow_p (memory_size)) \
1497 : goto out_of_memory; \
1498 : if (result == resultbuf || result == NULL) \
1499 : memory = (DCHAR_T *) malloc (memory_size); \
1500 : else \
1501 : memory = (DCHAR_T *) realloc (result, memory_size); \
1502 : if (memory == NULL) \
1503 : goto out_of_memory; \
1504 : if (result == resultbuf && length > 0) \
1505 : DCHAR_CPY (memory, result, length); \
1506 1678 : result = memory; \
1507 : }
1508 2625 :
1509 : for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
1510 933 : {
1511 933 : if (cp != dp->dir_start)
1512 : {
1513 933 : size_t n = dp->dir_start - cp;
1514 : size_t augmented_length = xsum (length, n);
1515 :
1516 : ENSURE_ALLOCATION (augmented_length);
1517 : /* This copies a piece of FCHAR_T[] into a DCHAR_T[]. Here we
1518 : need that the format string contains only ASCII characters
1519 933 : if FCHAR_T and DCHAR_T are not the same type. */
1520 933 : if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
1521 : {
1522 : DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
1523 : length = augmented_length;
1524 : }
1525 : else
1526 : {
1527 : do
1528 : result[length++] = (unsigned char) *cp++;
1529 1678 : while (--n > 0);
1530 731 : }
1531 : }
1532 : if (i == d.count)
1533 947 : break;
1534 :
1535 : /* Execute a single directive. */
1536 : if (dp->conversion == '%')
1537 0 : {
1538 0 : size_t augmented_length;
1539 0 :
1540 0 : if (!(dp->arg_index == ARG_NONE))
1541 0 : abort ();
1542 0 : augmented_length = xsum (length, 1);
1543 : ENSURE_ALLOCATION (augmented_length);
1544 : result[length] = '%';
1545 : length = augmented_length;
1546 947 : }
1547 0 : else
1548 : {
1549 947 : if (!(dp->arg_index != ARG_NONE))
1550 : abort ();
1551 0 :
1552 : if (dp->conversion == 'n')
1553 0 : {
1554 0 : switch (a.arg[dp->arg_index].type)
1555 0 : {
1556 0 : case TYPE_COUNT_SCHAR_POINTER:
1557 0 : *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
1558 0 : break;
1559 0 : case TYPE_COUNT_SHORT_POINTER:
1560 0 : *a.arg[dp->arg_index].a.a_count_short_pointer = length;
1561 0 : break;
1562 0 : case TYPE_COUNT_INT_POINTER:
1563 0 : *a.arg[dp->arg_index].a.a_count_int_pointer = length;
1564 0 : break;
1565 : case TYPE_COUNT_LONGINT_POINTER:
1566 0 : *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
1567 0 : break;
1568 0 : #if HAVE_LONG_LONG_INT
1569 : case TYPE_COUNT_LONGLONGINT_POINTER:
1570 0 : *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
1571 0 : break;
1572 : #endif
1573 : default:
1574 : abort ();
1575 : }
1576 : }
1577 : #if ENABLE_UNISTDIO
1578 : /* The unistdio extensions. */
1579 : else if (dp->conversion == 'U')
1580 : {
1581 : arg_type type = a.arg[dp->arg_index].type;
1582 : int flags = dp->flags;
1583 : int has_width;
1584 : size_t width;
1585 : int has_precision;
1586 : size_t precision;
1587 :
1588 : has_width = 0;
1589 : width = 0;
1590 : if (dp->width_start != dp->width_end)
1591 : {
1592 : if (dp->width_arg_index != ARG_NONE)
1593 : {
1594 : int arg;
1595 :
1596 : if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
1597 : abort ();
1598 : arg = a.arg[dp->width_arg_index].a.a_int;
1599 : if (arg < 0)
1600 : {
1601 : /* "A negative field width is taken as a '-' flag
1602 : followed by a positive field width." */
1603 : flags |= FLAG_LEFT;
1604 : width = (unsigned int) (-arg);
1605 : }
1606 : else
1607 : width = arg;
1608 : }
1609 : else
1610 : {
1611 : const FCHAR_T *digitp = dp->width_start;
1612 :
1613 : do
1614 : width = xsum (xtimes (width, 10), *digitp++ - '0');
1615 : while (digitp != dp->width_end);
1616 : }
1617 : has_width = 1;
1618 : }
1619 :
1620 : has_precision = 0;
1621 : precision = 0;
1622 : if (dp->precision_start != dp->precision_end)
1623 : {
1624 : if (dp->precision_arg_index != ARG_NONE)
1625 : {
1626 : int arg;
1627 :
1628 : if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1629 : abort ();
1630 : arg = a.arg[dp->precision_arg_index].a.a_int;
1631 : /* "A negative precision is taken as if the precision
1632 : were omitted." */
1633 : if (arg >= 0)
1634 : {
1635 : precision = arg;
1636 : has_precision = 1;
1637 : }
1638 : }
1639 : else
1640 : {
1641 : const FCHAR_T *digitp = dp->precision_start + 1;
1642 :
1643 : precision = 0;
1644 : while (digitp != dp->precision_end)
1645 : precision = xsum (xtimes (precision, 10), *digitp++ - '0');
1646 : has_precision = 1;
1647 : }
1648 : }
1649 :
1650 : switch (type)
1651 : {
1652 : case TYPE_U8_STRING:
1653 : {
1654 : const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
1655 : const uint8_t *arg_end;
1656 : size_t characters;
1657 :
1658 : if (has_precision)
1659 : {
1660 : /* Use only PRECISION characters, from the left. */
1661 : arg_end = arg;
1662 : characters = 0;
1663 : for (; precision > 0; precision--)
1664 : {
1665 : int count = u8_strmblen (arg_end);
1666 : if (count == 0)
1667 : break;
1668 : if (count < 0)
1669 : {
1670 : if (!(result == resultbuf || result == NULL))
1671 : free (result);
1672 : if (buf_malloced != NULL)
1673 : free (buf_malloced);
1674 : CLEANUP ();
1675 : errno = EILSEQ;
1676 : return NULL;
1677 : }
1678 : arg_end += count;
1679 : characters++;
1680 : }
1681 : }
1682 : else if (has_width)
1683 : {
1684 : /* Use the entire string, and count the number of
1685 : characters. */
1686 : arg_end = arg;
1687 : characters = 0;
1688 : for (;;)
1689 : {
1690 : int count = u8_strmblen (arg_end);
1691 : if (count == 0)
1692 : break;
1693 : if (count < 0)
1694 : {
1695 : if (!(result == resultbuf || result == NULL))
1696 : free (result);
1697 : if (buf_malloced != NULL)
1698 : free (buf_malloced);
1699 : CLEANUP ();
1700 : errno = EILSEQ;
1701 : return NULL;
1702 : }
1703 : arg_end += count;
1704 : characters++;
1705 : }
1706 : }
1707 : else
1708 : {
1709 : /* Use the entire string. */
1710 : arg_end = arg + u8_strlen (arg);
1711 : /* The number of characters doesn't matter. */
1712 : characters = 0;
1713 : }
1714 :
1715 : if (has_width && width > characters
1716 : && !(dp->flags & FLAG_LEFT))
1717 : {
1718 : size_t n = width - characters;
1719 : ENSURE_ALLOCATION (xsum (length, n));
1720 : DCHAR_SET (result + length, ' ', n);
1721 : length += n;
1722 : }
1723 :
1724 : # if DCHAR_IS_UINT8_T
1725 : {
1726 : size_t n = arg_end - arg;
1727 : ENSURE_ALLOCATION (xsum (length, n));
1728 : DCHAR_CPY (result + length, arg, n);
1729 : length += n;
1730 : }
1731 : # else
1732 : { /* Convert. */
1733 : DCHAR_T *converted = result + length;
1734 : size_t converted_len = allocated - length;
1735 : # if DCHAR_IS_TCHAR
1736 : /* Convert from UTF-8 to locale encoding. */
1737 : if (u8_conv_to_encoding (locale_charset (),
1738 : iconveh_question_mark,
1739 : arg, arg_end - arg, NULL,
1740 : &converted, &converted_len)
1741 : < 0)
1742 : # else
1743 : /* Convert from UTF-8 to UTF-16/UTF-32. */
1744 : converted =
1745 : U8_TO_DCHAR (arg, arg_end - arg,
1746 : converted, &converted_len);
1747 : if (converted == NULL)
1748 : # endif
1749 : {
1750 : int saved_errno = errno;
1751 : if (!(result == resultbuf || result == NULL))
1752 : free (result);
1753 : if (buf_malloced != NULL)
1754 : free (buf_malloced);
1755 : CLEANUP ();
1756 : errno = saved_errno;
1757 : return NULL;
1758 : }
1759 : if (converted != result + length)
1760 : {
1761 : ENSURE_ALLOCATION (xsum (length, converted_len));
1762 : DCHAR_CPY (result + length, converted, converted_len);
1763 : free (converted);
1764 : }
1765 : length += converted_len;
1766 : }
1767 : # endif
1768 :
1769 : if (has_width && width > characters
1770 : && (dp->flags & FLAG_LEFT))
1771 : {
1772 : size_t n = width - characters;
1773 : ENSURE_ALLOCATION (xsum (length, n));
1774 : DCHAR_SET (result + length, ' ', n);
1775 : length += n;
1776 : }
1777 : }
1778 : break;
1779 :
1780 : case TYPE_U16_STRING:
1781 : {
1782 : const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
1783 : const uint16_t *arg_end;
1784 : size_t characters;
1785 :
1786 : if (has_precision)
1787 : {
1788 : /* Use only PRECISION characters, from the left. */
1789 : arg_end = arg;
1790 : characters = 0;
1791 : for (; precision > 0; precision--)
1792 : {
1793 : int count = u16_strmblen (arg_end);
1794 : if (count == 0)
1795 : break;
1796 : if (count < 0)
1797 : {
1798 : if (!(result == resultbuf || result == NULL))
1799 : free (result);
1800 : if (buf_malloced != NULL)
1801 : free (buf_malloced);
1802 : CLEANUP ();
1803 : errno = EILSEQ;
1804 : return NULL;
1805 : }
1806 : arg_end += count;
1807 : characters++;
1808 : }
1809 : }
1810 : else if (has_width)
1811 : {
1812 : /* Use the entire string, and count the number of
1813 : characters. */
1814 : arg_end = arg;
1815 : characters = 0;
1816 : for (;;)
1817 : {
1818 : int count = u16_strmblen (arg_end);
1819 : if (count == 0)
1820 : break;
1821 : if (count < 0)
1822 : {
1823 : if (!(result == resultbuf || result == NULL))
1824 : free (result);
1825 : if (buf_malloced != NULL)
1826 : free (buf_malloced);
1827 : CLEANUP ();
1828 : errno = EILSEQ;
1829 : return NULL;
1830 : }
1831 : arg_end += count;
1832 : characters++;
1833 : }
1834 : }
1835 : else
1836 : {
1837 : /* Use the entire string. */
1838 : arg_end = arg + u16_strlen (arg);
1839 : /* The number of characters doesn't matter. */
1840 : characters = 0;
1841 : }
1842 :
1843 : if (has_width && width > characters
1844 : && !(dp->flags & FLAG_LEFT))
1845 : {
1846 : size_t n = width - characters;
1847 : ENSURE_ALLOCATION (xsum (length, n));
1848 : DCHAR_SET (result + length, ' ', n);
1849 : length += n;
1850 : }
1851 :
1852 : # if DCHAR_IS_UINT16_T
1853 : {
1854 : size_t n = arg_end - arg;
1855 : ENSURE_ALLOCATION (xsum (length, n));
1856 : DCHAR_CPY (result + length, arg, n);
1857 : length += n;
1858 : }
1859 : # else
1860 : { /* Convert. */
1861 : DCHAR_T *converted = result + length;
1862 : size_t converted_len = allocated - length;
1863 : # if DCHAR_IS_TCHAR
1864 : /* Convert from UTF-16 to locale encoding. */
1865 : if (u16_conv_to_encoding (locale_charset (),
1866 : iconveh_question_mark,
1867 : arg, arg_end - arg, NULL,
1868 : &converted, &converted_len)
1869 : < 0)
1870 : # else
1871 : /* Convert from UTF-16 to UTF-8/UTF-32. */
1872 : converted =
1873 : U16_TO_DCHAR (arg, arg_end - arg,
1874 : converted, &converted_len);
1875 : if (converted == NULL)
1876 : # endif
1877 : {
1878 : int saved_errno = errno;
1879 : if (!(result == resultbuf || result == NULL))
1880 : free (result);
1881 : if (buf_malloced != NULL)
1882 : free (buf_malloced);
1883 : CLEANUP ();
1884 : errno = saved_errno;
1885 : return NULL;
1886 : }
1887 : if (converted != result + length)
1888 : {
1889 : ENSURE_ALLOCATION (xsum (length, converted_len));
1890 : DCHAR_CPY (result + length, converted, converted_len);
1891 : free (converted);
1892 : }
1893 : length += converted_len;
1894 : }
1895 : # endif
1896 :
1897 : if (has_width && width > characters
1898 : && (dp->flags & FLAG_LEFT))
1899 : {
1900 : size_t n = width - characters;
1901 : ENSURE_ALLOCATION (xsum (length, n));
1902 : DCHAR_SET (result + length, ' ', n);
1903 : length += n;
1904 : }
1905 : }
1906 : break;
1907 :
1908 : case TYPE_U32_STRING:
1909 : {
1910 : const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
1911 : const uint32_t *arg_end;
1912 : size_t characters;
1913 :
1914 : if (has_precision)
1915 : {
1916 : /* Use only PRECISION characters, from the left. */
1917 : arg_end = arg;
1918 : characters = 0;
1919 : for (; precision > 0; precision--)
1920 : {
1921 : int count = u32_strmblen (arg_end);
1922 : if (count == 0)
1923 : break;
1924 : if (count < 0)
1925 : {
1926 : if (!(result == resultbuf || result == NULL))
1927 : free (result);
1928 : if (buf_malloced != NULL)
1929 : free (buf_malloced);
1930 : CLEANUP ();
1931 : errno = EILSEQ;
1932 : return NULL;
1933 : }
1934 : arg_end += count;
1935 : characters++;
1936 : }
1937 : }
1938 : else if (has_width)
1939 : {
1940 : /* Use the entire string, and count the number of
1941 : characters. */
1942 : arg_end = arg;
1943 : characters = 0;
1944 : for (;;)
1945 : {
1946 : int count = u32_strmblen (arg_end);
1947 : if (count == 0)
1948 : break;
1949 : if (count < 0)
1950 : {
1951 : if (!(result == resultbuf || result == NULL))
1952 : free (result);
1953 : if (buf_malloced != NULL)
1954 : free (buf_malloced);
1955 : CLEANUP ();
1956 : errno = EILSEQ;
1957 : return NULL;
1958 : }
1959 : arg_end += count;
1960 : characters++;
1961 : }
1962 : }
1963 : else
1964 : {
1965 : /* Use the entire string. */
1966 : arg_end = arg + u32_strlen (arg);
1967 : /* The number of characters doesn't matter. */
1968 : characters = 0;
1969 : }
1970 :
1971 : if (has_width && width > characters
1972 : && !(dp->flags & FLAG_LEFT))
1973 : {
1974 : size_t n = width - characters;
1975 : ENSURE_ALLOCATION (xsum (length, n));
1976 : DCHAR_SET (result + length, ' ', n);
1977 : length += n;
1978 : }
1979 :
1980 : # if DCHAR_IS_UINT32_T
1981 : {
1982 : size_t n = arg_end - arg;
1983 : ENSURE_ALLOCATION (xsum (length, n));
1984 : DCHAR_CPY (result + length, arg, n);
1985 : length += n;
1986 : }
1987 : # else
1988 : { /* Convert. */
1989 : DCHAR_T *converted = result + length;
1990 : size_t converted_len = allocated - length;
1991 : # if DCHAR_IS_TCHAR
1992 : /* Convert from UTF-32 to locale encoding. */
1993 : if (u32_conv_to_encoding (locale_charset (),
1994 : iconveh_question_mark,
1995 : arg, arg_end - arg, NULL,
1996 : &converted, &converted_len)
1997 : < 0)
1998 : # else
1999 : /* Convert from UTF-32 to UTF-8/UTF-16. */
2000 : converted =
2001 : U32_TO_DCHAR (arg, arg_end - arg,
2002 : converted, &converted_len);
2003 : if (converted == NULL)
2004 : # endif
2005 : {
2006 : int saved_errno = errno;
2007 : if (!(result == resultbuf || result == NULL))
2008 : free (result);
2009 : if (buf_malloced != NULL)
2010 : free (buf_malloced);
2011 : CLEANUP ();
2012 : errno = saved_errno;
2013 : return NULL;
2014 : }
2015 : if (converted != result + length)
2016 : {
2017 : ENSURE_ALLOCATION (xsum (length, converted_len));
2018 : DCHAR_CPY (result + length, converted, converted_len);
2019 : free (converted);
2020 : }
2021 : length += converted_len;
2022 : }
2023 : # endif
2024 :
2025 : if (has_width && width > characters
2026 : && (dp->flags & FLAG_LEFT))
2027 : {
2028 : size_t n = width - characters;
2029 : ENSURE_ALLOCATION (xsum (length, n));
2030 : DCHAR_SET (result + length, ' ', n);
2031 : length += n;
2032 : }
2033 : }
2034 : break;
2035 :
2036 : default:
2037 : abort ();
2038 : }
2039 : }
2040 : #endif
2041 : #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
2042 : else if ((dp->conversion == 'a' || dp->conversion == 'A')
2043 : # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
2044 : && (0
2045 : # if NEED_PRINTF_DOUBLE
2046 : || a.arg[dp->arg_index].type == TYPE_DOUBLE
2047 : # endif
2048 : # if NEED_PRINTF_LONG_DOUBLE
2049 : || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2050 : # endif
2051 : )
2052 : # endif
2053 : )
2054 : {
2055 : arg_type type = a.arg[dp->arg_index].type;
2056 : int flags = dp->flags;
2057 : int has_width;
2058 : size_t width;
2059 : int has_precision;
2060 : size_t precision;
2061 : size_t tmp_length;
2062 : DCHAR_T tmpbuf[700];
2063 : DCHAR_T *tmp;
2064 : DCHAR_T *pad_ptr;
2065 : DCHAR_T *p;
2066 :
2067 : has_width = 0;
2068 : width = 0;
2069 : if (dp->width_start != dp->width_end)
2070 : {
2071 : if (dp->width_arg_index != ARG_NONE)
2072 : {
2073 : int arg;
2074 :
2075 : if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2076 : abort ();
2077 : arg = a.arg[dp->width_arg_index].a.a_int;
2078 : if (arg < 0)
2079 : {
2080 : /* "A negative field width is taken as a '-' flag
2081 : followed by a positive field width." */
2082 : flags |= FLAG_LEFT;
2083 : width = (unsigned int) (-arg);
2084 : }
2085 : else
2086 : width = arg;
2087 : }
2088 : else
2089 : {
2090 : const FCHAR_T *digitp = dp->width_start;
2091 :
2092 : do
2093 : width = xsum (xtimes (width, 10), *digitp++ - '0');
2094 : while (digitp != dp->width_end);
2095 : }
2096 : has_width = 1;
2097 : }
2098 :
2099 : has_precision = 0;
2100 : precision = 0;
2101 : if (dp->precision_start != dp->precision_end)
2102 : {
2103 : if (dp->precision_arg_index != ARG_NONE)
2104 : {
2105 : int arg;
2106 :
2107 : if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2108 : abort ();
2109 : arg = a.arg[dp->precision_arg_index].a.a_int;
2110 : /* "A negative precision is taken as if the precision
2111 : were omitted." */
2112 : if (arg >= 0)
2113 : {
2114 : precision = arg;
2115 : has_precision = 1;
2116 : }
2117 : }
2118 : else
2119 : {
2120 : const FCHAR_T *digitp = dp->precision_start + 1;
2121 :
2122 : precision = 0;
2123 : while (digitp != dp->precision_end)
2124 : precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2125 : has_precision = 1;
2126 : }
2127 : }
2128 :
2129 : /* Allocate a temporary buffer of sufficient size. */
2130 : if (type == TYPE_LONGDOUBLE)
2131 : tmp_length =
2132 : (unsigned int) ((LDBL_DIG + 1)
2133 : * 0.831 /* decimal -> hexadecimal */
2134 : )
2135 : + 1; /* turn floor into ceil */
2136 : else
2137 : tmp_length =
2138 : (unsigned int) ((DBL_DIG + 1)
2139 : * 0.831 /* decimal -> hexadecimal */
2140 : )
2141 : + 1; /* turn floor into ceil */
2142 : if (tmp_length < precision)
2143 : tmp_length = precision;
2144 : /* Account for sign, decimal point etc. */
2145 : tmp_length = xsum (tmp_length, 12);
2146 :
2147 : if (tmp_length < width)
2148 : tmp_length = width;
2149 :
2150 : tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
2151 :
2152 : if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
2153 : tmp = tmpbuf;
2154 : else
2155 : {
2156 : size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
2157 :
2158 : if (size_overflow_p (tmp_memsize))
2159 : /* Overflow, would lead to out of memory. */
2160 : goto out_of_memory;
2161 : tmp = (DCHAR_T *) malloc (tmp_memsize);
2162 : if (tmp == NULL)
2163 : /* Out of memory. */
2164 : goto out_of_memory;
2165 : }
2166 :
2167 : pad_ptr = NULL;
2168 : p = tmp;
2169 : if (type == TYPE_LONGDOUBLE)
2170 : {
2171 : # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
2172 : long double arg = a.arg[dp->arg_index].a.a_longdouble;
2173 :
2174 : if (isnanl (arg))
2175 : {
2176 : if (dp->conversion == 'A')
2177 : {
2178 : *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
2179 : }
2180 : else
2181 : {
2182 : *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
2183 : }
2184 : }
2185 : else
2186 : {
2187 : int sign = 0;
2188 : DECL_LONG_DOUBLE_ROUNDING
2189 :
2190 : BEGIN_LONG_DOUBLE_ROUNDING ();
2191 :
2192 : if (signbit (arg)) /* arg < 0.0L or negative zero */
2193 : {
2194 : sign = -1;
2195 : arg = -arg;
2196 : }
2197 :
2198 : if (sign < 0)
2199 : *p++ = '-';
2200 : else if (flags & FLAG_SHOWSIGN)
2201 : *p++ = '+';
2202 : else if (flags & FLAG_SPACE)
2203 : *p++ = ' ';
2204 :
2205 : if (arg > 0.0L && arg + arg == arg)
2206 : {
2207 : if (dp->conversion == 'A')
2208 : {
2209 : *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
2210 : }
2211 : else
2212 : {
2213 : *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
2214 : }
2215 : }
2216 : else
2217 : {
2218 : int exponent;
2219 : long double mantissa;
2220 :
2221 : if (arg > 0.0L)
2222 : mantissa = printf_frexpl (arg, &exponent);
2223 : else
2224 : {
2225 : exponent = 0;
2226 : mantissa = 0.0L;
2227 : }
2228 :
2229 : if (has_precision
2230 : && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
2231 : {
2232 : /* Round the mantissa. */
2233 : long double tail = mantissa;
2234 : size_t q;
2235 :
2236 : for (q = precision; ; q--)
2237 : {
2238 : int digit = (int) tail;
2239 : tail -= digit;
2240 : if (q == 0)
2241 : {
2242 : if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
2243 : tail = 1 - tail;
2244 : else
2245 : tail = - tail;
2246 : break;
2247 : }
2248 : tail *= 16.0L;
2249 : }
2250 : if (tail != 0.0L)
2251 : for (q = precision; q > 0; q--)
2252 : tail *= 0.0625L;
2253 : mantissa += tail;
2254 : }
2255 :
2256 : *p++ = '0';
2257 : *p++ = dp->conversion - 'A' + 'X';
2258 : pad_ptr = p;
2259 : {
2260 : int digit;
2261 :
2262 : digit = (int) mantissa;
2263 : mantissa -= digit;
2264 : *p++ = '0' + digit;
2265 : if ((flags & FLAG_ALT)
2266 : || mantissa > 0.0L || precision > 0)
2267 : {
2268 : *p++ = decimal_point_char ();
2269 : /* This loop terminates because we assume
2270 : that FLT_RADIX is a power of 2. */
2271 : while (mantissa > 0.0L)
2272 : {
2273 : mantissa *= 16.0L;
2274 : digit = (int) mantissa;
2275 : mantissa -= digit;
2276 : *p++ = digit
2277 : + (digit < 10
2278 : ? '0'
2279 : : dp->conversion - 10);
2280 : if (precision > 0)
2281 : precision--;
2282 : }
2283 : while (precision > 0)
2284 : {
2285 : *p++ = '0';
2286 : precision--;
2287 : }
2288 : }
2289 : }
2290 : *p++ = dp->conversion - 'A' + 'P';
2291 : # if WIDE_CHAR_VERSION
2292 : {
2293 : static const wchar_t decimal_format[] =
2294 : { '%', '+', 'd', '\0' };
2295 : SNPRINTF (p, 6 + 1, decimal_format, exponent);
2296 : }
2297 : while (*p != '\0')
2298 : p++;
2299 : # else
2300 : if (sizeof (DCHAR_T) == 1)
2301 : {
2302 : sprintf ((char *) p, "%+d", exponent);
2303 : while (*p != '\0')
2304 : p++;
2305 : }
2306 : else
2307 : {
2308 : char expbuf[6 + 1];
2309 : const char *ep;
2310 : sprintf (expbuf, "%+d", exponent);
2311 : for (ep = expbuf; (*p = *ep) != '\0'; ep++)
2312 : p++;
2313 : }
2314 : # endif
2315 : }
2316 :
2317 : END_LONG_DOUBLE_ROUNDING ();
2318 : }
2319 : # else
2320 : abort ();
2321 : # endif
2322 : }
2323 : else
2324 : {
2325 : # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
2326 : double arg = a.arg[dp->arg_index].a.a_double;
2327 :
2328 : if (isnand (arg))
2329 : {
2330 : if (dp->conversion == 'A')
2331 : {
2332 : *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
2333 : }
2334 : else
2335 : {
2336 : *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
2337 : }
2338 : }
2339 : else
2340 : {
2341 : int sign = 0;
2342 :
2343 : if (signbit (arg)) /* arg < 0.0 or negative zero */
2344 : {
2345 : sign = -1;
2346 : arg = -arg;
2347 : }
2348 :
2349 : if (sign < 0)
2350 : *p++ = '-';
2351 : else if (flags & FLAG_SHOWSIGN)
2352 : *p++ = '+';
2353 : else if (flags & FLAG_SPACE)
2354 : *p++ = ' ';
2355 :
2356 : if (arg > 0.0 && arg + arg == arg)
2357 : {
2358 : if (dp->conversion == 'A')
2359 : {
2360 : *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
2361 : }
2362 : else
2363 : {
2364 : *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
2365 : }
2366 : }
2367 : else
2368 : {
2369 : int exponent;
2370 : double mantissa;
2371 :
2372 : if (arg > 0.0)
2373 : mantissa = printf_frexp (arg, &exponent);
2374 : else
2375 : {
2376 : exponent = 0;
2377 : mantissa = 0.0;
2378 : }
2379 :
2380 : if (has_precision
2381 : && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
2382 : {
2383 : /* Round the mantissa. */
2384 : double tail = mantissa;
2385 : size_t q;
2386 :
2387 : for (q = precision; ; q--)
2388 : {
2389 : int digit = (int) tail;
2390 : tail -= digit;
2391 : if (q == 0)
2392 : {
2393 : if (digit & 1 ? tail >= 0.5 : tail > 0.5)
2394 : tail = 1 - tail;
2395 : else
2396 : tail = - tail;
2397 : break;
2398 : }
2399 : tail *= 16.0;
2400 : }
2401 : if (tail != 0.0)
2402 : for (q = precision; q > 0; q--)
2403 : tail *= 0.0625;
2404 : mantissa += tail;
2405 : }
2406 :
2407 : *p++ = '0';
2408 : *p++ = dp->conversion - 'A' + 'X';
2409 : pad_ptr = p;
2410 : {
2411 : int digit;
2412 :
2413 : digit = (int) mantissa;
2414 : mantissa -= digit;
2415 : *p++ = '0' + digit;
2416 : if ((flags & FLAG_ALT)
2417 : || mantissa > 0.0 || precision > 0)
2418 : {
2419 : *p++ = decimal_point_char ();
2420 : /* This loop terminates because we assume
2421 : that FLT_RADIX is a power of 2. */
2422 : while (mantissa > 0.0)
2423 : {
2424 : mantissa *= 16.0;
2425 : digit = (int) mantissa;
2426 : mantissa -= digit;
2427 : *p++ = digit
2428 : + (digit < 10
2429 : ? '0'
2430 : : dp->conversion - 10);
2431 : if (precision > 0)
2432 : precision--;
2433 : }
2434 : while (precision > 0)
2435 : {
2436 : *p++ = '0';
2437 : precision--;
2438 : }
2439 : }
2440 : }
2441 : *p++ = dp->conversion - 'A' + 'P';
2442 : # if WIDE_CHAR_VERSION
2443 : {
2444 : static const wchar_t decimal_format[] =
2445 : { '%', '+', 'd', '\0' };
2446 : SNPRINTF (p, 6 + 1, decimal_format, exponent);
2447 : }
2448 : while (*p != '\0')
2449 : p++;
2450 : # else
2451 : if (sizeof (DCHAR_T) == 1)
2452 : {
2453 : sprintf ((char *) p, "%+d", exponent);
2454 : while (*p != '\0')
2455 : p++;
2456 : }
2457 : else
2458 : {
2459 : char expbuf[6 + 1];
2460 : const char *ep;
2461 : sprintf (expbuf, "%+d", exponent);
2462 : for (ep = expbuf; (*p = *ep) != '\0'; ep++)
2463 : p++;
2464 : }
2465 : # endif
2466 : }
2467 : }
2468 : # else
2469 : abort ();
2470 : # endif
2471 : }
2472 : /* The generated string now extends from tmp to p, with the
2473 : zero padding insertion point being at pad_ptr. */
2474 : if (has_width && p - tmp < width)
2475 : {
2476 : size_t pad = width - (p - tmp);
2477 : DCHAR_T *end = p + pad;
2478 :
2479 : if (flags & FLAG_LEFT)
2480 : {
2481 : /* Pad with spaces on the right. */
2482 : for (; pad > 0; pad--)
2483 : *p++ = ' ';
2484 : }
2485 : else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
2486 : {
2487 : /* Pad with zeroes. */
2488 : DCHAR_T *q = end;
2489 :
2490 : while (p > pad_ptr)
2491 : *--q = *--p;
2492 : for (; pad > 0; pad--)
2493 : *p++ = '0';
2494 : }
2495 : else
2496 : {
2497 : /* Pad with spaces on the left. */
2498 : DCHAR_T *q = end;
2499 :
2500 : while (p > tmp)
2501 : *--q = *--p;
2502 : for (; pad > 0; pad--)
2503 : *p++ = ' ';
2504 : }
2505 :
2506 : p = end;
2507 : }
2508 :
2509 : {
2510 : size_t count = p - tmp;
2511 :
2512 : if (count >= tmp_length)
2513 : /* tmp_length was incorrectly calculated - fix the
2514 : code above! */
2515 : abort ();
2516 :
2517 : /* Make room for the result. */
2518 : if (count >= allocated - length)
2519 : {
2520 : size_t n = xsum (length, count);
2521 :
2522 : ENSURE_ALLOCATION (n);
2523 : }
2524 :
2525 : /* Append the result. */
2526 : memcpy (result + length, tmp, count * sizeof (DCHAR_T));
2527 : if (tmp != tmpbuf)
2528 : free (tmp);
2529 : length += count;
2530 : }
2531 947 : }
2532 936 : #endif
2533 934 : #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
2534 931 : else if ((dp->conversion == 'f' || dp->conversion == 'F'
2535 18 : || dp->conversion == 'e' || dp->conversion == 'E'
2536 : || dp->conversion == 'g' || dp->conversion == 'G'
2537 : || dp->conversion == 'a' || dp->conversion == 'A')
2538 : && (0
2539 : # if NEED_PRINTF_DOUBLE
2540 : || a.arg[dp->arg_index].type == TYPE_DOUBLE
2541 : # elif NEED_PRINTF_INFINITE_DOUBLE
2542 : || (a.arg[dp->arg_index].type == TYPE_DOUBLE
2543 : /* The systems (mingw) which produce wrong output
2544 : for Inf, -Inf, and NaN also do so for -0.0.
2545 : Therefore we treat this case here as well. */
2546 : && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
2547 : # endif
2548 36 : # if NEED_PRINTF_LONG_DOUBLE
2549 : || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2550 : # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
2551 18 : || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2552 : /* Some systems produce wrong output for Inf,
2553 : -Inf, and NaN. */
2554 0 : && is_infinitel (a.arg[dp->arg_index].a.a_longdouble))
2555 : # endif
2556 : ))
2557 : {
2558 0 : # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
2559 : arg_type type = a.arg[dp->arg_index].type;
2560 : # endif
2561 : int flags = dp->flags;
2562 : int has_width;
2563 : size_t width;
2564 : int has_precision;
2565 : size_t precision;
2566 : size_t tmp_length;
2567 : DCHAR_T tmpbuf[700];
2568 : DCHAR_T *tmp;
2569 0 : DCHAR_T *pad_ptr;
2570 0 : DCHAR_T *p;
2571 0 :
2572 : has_width = 0;
2573 0 : width = 0;
2574 : if (dp->width_start != dp->width_end)
2575 : {
2576 : if (dp->width_arg_index != ARG_NONE)
2577 0 : {
2578 0 : int arg;
2579 0 :
2580 0 : if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2581 : abort ();
2582 : arg = a.arg[dp->width_arg_index].a.a_int;
2583 : if (arg < 0)
2584 0 : {
2585 0 : /* "A negative field width is taken as a '-' flag
2586 : followed by a positive field width." */
2587 : flags |= FLAG_LEFT;
2588 0 : width = (unsigned int) (-arg);
2589 : }
2590 : else
2591 : width = arg;
2592 0 : }
2593 : else
2594 : {
2595 0 : const FCHAR_T *digitp = dp->width_start;
2596 0 :
2597 : do
2598 0 : width = xsum (xtimes (width, 10), *digitp++ - '0');
2599 : while (digitp != dp->width_end);
2600 : }
2601 0 : has_width = 1;
2602 0 : }
2603 0 :
2604 : has_precision = 0;
2605 0 : precision = 0;
2606 : if (dp->precision_start != dp->precision_end)
2607 : {
2608 : if (dp->precision_arg_index != ARG_NONE)
2609 0 : {
2610 0 : int arg;
2611 0 :
2612 : if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2613 : abort ();
2614 0 : arg = a.arg[dp->precision_arg_index].a.a_int;
2615 : /* "A negative precision is taken as if the precision
2616 0 : were omitted." */
2617 0 : if (arg >= 0)
2618 : {
2619 : precision = arg;
2620 : has_precision = 1;
2621 : }
2622 0 : }
2623 : else
2624 0 : {
2625 0 : const FCHAR_T *digitp = dp->precision_start + 1;
2626 0 :
2627 0 : precision = 0;
2628 : while (digitp != dp->precision_end)
2629 : precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2630 : has_precision = 1;
2631 : }
2632 : }
2633 :
2634 0 : /* POSIX specifies the default precision to be 6 for %f, %F,
2635 0 : %e, %E, but not for %g, %G. Implementations appear to use
2636 : the same default precision also for %g, %G. */
2637 : if (!has_precision)
2638 : precision = 6;
2639 :
2640 : /* Allocate a temporary buffer of sufficient size. */
2641 : # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
2642 : tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
2643 : # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
2644 : tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
2645 : # elif NEED_PRINTF_LONG_DOUBLE
2646 : tmp_length = LDBL_DIG + 1;
2647 0 : # elif NEED_PRINTF_DOUBLE
2648 : tmp_length = DBL_DIG + 1;
2649 0 : # else
2650 0 : tmp_length = 0;
2651 : # endif
2652 : if (tmp_length < precision)
2653 : tmp_length = precision;
2654 : # if NEED_PRINTF_LONG_DOUBLE
2655 : # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
2656 : if (type == TYPE_LONGDOUBLE)
2657 : # endif
2658 : if (dp->conversion == 'f' || dp->conversion == 'F')
2659 : {
2660 : long double arg = a.arg[dp->arg_index].a.a_longdouble;
2661 : if (!(isnanl (arg) || arg + arg == arg))
2662 : {
2663 : /* arg is finite and nonzero. */
2664 : int exponent = floorlog10l (arg < 0 ? -arg : arg);
2665 : if (exponent >= 0 && tmp_length < exponent + precision)
2666 : tmp_length = exponent + precision;
2667 : }
2668 : }
2669 : # endif
2670 : # if NEED_PRINTF_DOUBLE
2671 : # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
2672 : if (type == TYPE_DOUBLE)
2673 : # endif
2674 : if (dp->conversion == 'f' || dp->conversion == 'F')
2675 : {
2676 : double arg = a.arg[dp->arg_index].a.a_double;
2677 : if (!(isnand (arg) || arg + arg == arg))
2678 : {
2679 : /* arg is finite and nonzero. */
2680 : int exponent = floorlog10 (arg < 0 ? -arg : arg);
2681 : if (exponent >= 0 && tmp_length < exponent + precision)
2682 : tmp_length = exponent + precision;
2683 : }
2684 0 : }
2685 : # endif
2686 0 : /* Account for sign, decimal point etc. */
2687 0 : tmp_length = xsum (tmp_length, 12);
2688 :
2689 0 : if (tmp_length < width)
2690 : tmp_length = width;
2691 0 :
2692 0 : tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
2693 :
2694 : if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
2695 0 : tmp = tmpbuf;
2696 : else
2697 0 : {
2698 : size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
2699 0 :
2700 0 : if (size_overflow_p (tmp_memsize))
2701 0 : /* Overflow, would lead to out of memory. */
2702 : goto out_of_memory;
2703 0 : tmp = (DCHAR_T *) malloc (tmp_memsize);
2704 : if (tmp == NULL)
2705 : /* Out of memory. */
2706 0 : goto out_of_memory;
2707 0 : }
2708 :
2709 : pad_ptr = NULL;
2710 : p = tmp;
2711 :
2712 : # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
2713 : # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
2714 0 : if (type == TYPE_LONGDOUBLE)
2715 : # endif
2716 0 : {
2717 : long double arg = a.arg[dp->arg_index].a.a_longdouble;
2718 0 :
2719 : if (isnanl (arg))
2720 0 : {
2721 : if (dp->conversion >= 'A' && dp->conversion <= 'Z')
2722 : {
2723 : *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
2724 0 : }
2725 : else
2726 : {
2727 : *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
2728 : }
2729 0 : }
2730 : else
2731 : {
2732 0 : int sign = 0;
2733 : DECL_LONG_DOUBLE_ROUNDING
2734 0 :
2735 : BEGIN_LONG_DOUBLE_ROUNDING ();
2736 0 :
2737 0 : if (signbit (arg)) /* arg < 0.0L or negative zero */
2738 : {
2739 : sign = -1;
2740 0 : arg = -arg;
2741 0 : }
2742 0 :
2743 0 : if (sign < 0)
2744 0 : *p++ = '-';
2745 0 : else if (flags & FLAG_SHOWSIGN)
2746 : *p++ = '+';
2747 0 : else if (flags & FLAG_SPACE)
2748 : *p++ = ' ';
2749 0 :
2750 : if (arg > 0.0L && arg + arg == arg)
2751 0 : {
2752 : if (dp->conversion >= 'A' && dp->conversion <= 'Z')
2753 : {
2754 : *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
2755 0 : }
2756 : else
2757 : {
2758 : *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
2759 : }
2760 : }
2761 : else
2762 : {
2763 : # if NEED_PRINTF_LONG_DOUBLE
2764 : pad_ptr = p;
2765 :
2766 : if (dp->conversion == 'f' || dp->conversion == 'F')
2767 : {
2768 : char *digits;
2769 : size_t ndigits;
2770 :
2771 : digits =
2772 : scale10_round_decimal_long_double (arg, precision);
2773 : if (digits == NULL)
2774 : {
2775 : END_LONG_DOUBLE_ROUNDING ();
2776 : goto out_of_memory;
2777 : }
2778 : ndigits = strlen (digits);
2779 :
2780 : if (ndigits > precision)
2781 : do
2782 : {
2783 : --ndigits;
2784 : *p++ = digits[ndigits];
2785 : }
2786 : while (ndigits > precision);
2787 : else
2788 : *p++ = '0';
2789 : /* Here ndigits <= precision. */
2790 : if ((flags & FLAG_ALT) || precision > 0)
2791 : {
2792 : *p++ = decimal_point_char ();
2793 : for (; precision > ndigits; precision--)
2794 : *p++ = '0';
2795 : while (ndigits > 0)
2796 : {
2797 : --ndigits;
2798 : *p++ = digits[ndigits];
2799 : }
2800 : }
2801 :
2802 : free (digits);
2803 : }
2804 : else if (dp->conversion == 'e' || dp->conversion == 'E')
2805 : {
2806 : int exponent;
2807 :
2808 : if (arg == 0.0L)
2809 : {
2810 : exponent = 0;
2811 : *p++ = '0';
2812 : if ((flags & FLAG_ALT) || precision > 0)
2813 : {
2814 : *p++ = decimal_point_char ();
2815 : for (; precision > 0; precision--)
2816 : *p++ = '0';
2817 : }
2818 : }
2819 : else
2820 : {
2821 : /* arg > 0.0L. */
2822 : int adjusted;
2823 : char *digits;
2824 : size_t ndigits;
2825 :
2826 : exponent = floorlog10l (arg);
2827 : adjusted = 0;
2828 : for (;;)
2829 : {
2830 : digits =
2831 : scale10_round_decimal_long_double (arg,
2832 : (int)precision - exponent);
2833 : if (digits == NULL)
2834 : {
2835 : END_LONG_DOUBLE_ROUNDING ();
2836 : goto out_of_memory;
2837 : }
2838 : ndigits = strlen (digits);
2839 :
2840 : if (ndigits == precision + 1)
2841 : break;
2842 : if (ndigits < precision
2843 : || ndigits > precision + 2)
2844 : /* The exponent was not guessed
2845 : precisely enough. */
2846 : abort ();
2847 : if (adjusted)
2848 : /* None of two values of exponent is
2849 : the right one. Prevent an endless
2850 : loop. */
2851 : abort ();
2852 : free (digits);
2853 : if (ndigits == precision)
2854 : exponent -= 1;
2855 : else
2856 : exponent += 1;
2857 : adjusted = 1;
2858 : }
2859 :
2860 : /* Here ndigits = precision+1. */
2861 : *p++ = digits[--ndigits];
2862 : if ((flags & FLAG_ALT) || precision > 0)
2863 : {
2864 : *p++ = decimal_point_char ();
2865 : while (ndigits > 0)
2866 : {
2867 : --ndigits;
2868 : *p++ = digits[ndigits];
2869 : }
2870 : }
2871 :
2872 : free (digits);
2873 : }
2874 :
2875 : *p++ = dp->conversion; /* 'e' or 'E' */
2876 : # if WIDE_CHAR_VERSION
2877 : {
2878 : static const wchar_t decimal_format[] =
2879 : { '%', '+', '.', '2', 'd', '\0' };
2880 : SNPRINTF (p, 6 + 1, decimal_format, exponent);
2881 : }
2882 : while (*p != '\0')
2883 : p++;
2884 : # else
2885 : if (sizeof (DCHAR_T) == 1)
2886 : {
2887 : sprintf ((char *) p, "%+.2d", exponent);
2888 : while (*p != '\0')
2889 : p++;
2890 : }
2891 : else
2892 : {
2893 : char expbuf[6 + 1];
2894 : const char *ep;
2895 : sprintf (expbuf, "%+.2d", exponent);
2896 : for (ep = expbuf; (*p = *ep) != '\0'; ep++)
2897 : p++;
2898 : }
2899 : # endif
2900 : }
2901 : else if (dp->conversion == 'g' || dp->conversion == 'G')
2902 : {
2903 : if (precision == 0)
2904 : precision = 1;
2905 : /* precision >= 1. */
2906 :
2907 : if (arg == 0.0L)
2908 : /* The exponent is 0, >= -4, < precision.
2909 : Use fixed-point notation. */
2910 : {
2911 : size_t ndigits = precision;
2912 : /* Number of trailing zeroes that have to be
2913 : dropped. */
2914 : size_t nzeroes =
2915 : (flags & FLAG_ALT ? 0 : precision - 1);
2916 :
2917 : --ndigits;
2918 : *p++ = '0';
2919 : if ((flags & FLAG_ALT) || ndigits > nzeroes)
2920 : {
2921 : *p++ = decimal_point_char ();
2922 : while (ndigits > nzeroes)
2923 : {
2924 : --ndigits;
2925 : *p++ = '0';
2926 : }
2927 : }
2928 : }
2929 : else
2930 : {
2931 : /* arg > 0.0L. */
2932 : int exponent;
2933 : int adjusted;
2934 : char *digits;
2935 : size_t ndigits;
2936 : size_t nzeroes;
2937 :
2938 : exponent = floorlog10l (arg);
2939 : adjusted = 0;
2940 : for (;;)
2941 : {
2942 : digits =
2943 : scale10_round_decimal_long_double (arg,
2944 : (int)(precision - 1) - exponent);
2945 : if (digits == NULL)
2946 : {
2947 : END_LONG_DOUBLE_ROUNDING ();
2948 : goto out_of_memory;
2949 : }
2950 : ndigits = strlen (digits);
2951 :
2952 : if (ndigits == precision)
2953 : break;
2954 : if (ndigits < precision - 1
2955 : || ndigits > precision + 1)
2956 : /* The exponent was not guessed
2957 : precisely enough. */
2958 : abort ();
2959 : if (adjusted)
2960 : /* None of two values of exponent is
2961 : the right one. Prevent an endless
2962 : loop. */
2963 : abort ();
2964 : free (digits);
2965 : if (ndigits < precision)
2966 : exponent -= 1;
2967 : else
2968 : exponent += 1;
2969 : adjusted = 1;
2970 : }
2971 : /* Here ndigits = precision. */
2972 :
2973 : /* Determine the number of trailing zeroes
2974 : that have to be dropped. */
2975 : nzeroes = 0;
2976 : if ((flags & FLAG_ALT) == 0)
2977 : while (nzeroes < ndigits
2978 : && digits[nzeroes] == '0')
2979 : nzeroes++;
2980 :
2981 : /* The exponent is now determined. */
2982 : if (exponent >= -4
2983 : && exponent < (long)precision)
2984 : {
2985 : /* Fixed-point notation:
2986 : max(exponent,0)+1 digits, then the
2987 : decimal point, then the remaining
2988 : digits without trailing zeroes. */
2989 : if (exponent >= 0)
2990 : {
2991 : size_t count = exponent + 1;
2992 : /* Note: count <= precision = ndigits. */
2993 : for (; count > 0; count--)
2994 : *p++ = digits[--ndigits];
2995 : if ((flags & FLAG_ALT) || ndigits > nzeroes)
2996 : {
2997 : *p++ = decimal_point_char ();
2998 : while (ndigits > nzeroes)
2999 : {
3000 : --ndigits;
3001 : *p++ = digits[ndigits];
3002 : }
3003 : }
3004 : }
3005 : else
3006 : {
3007 : size_t count = -exponent - 1;
3008 : *p++ = '0';
3009 : *p++ = decimal_point_char ();
3010 : for (; count > 0; count--)
3011 : *p++ = '0';
3012 : while (ndigits > nzeroes)
3013 : {
3014 : --ndigits;
3015 : *p++ = digits[ndigits];
3016 : }
3017 : }
3018 : }
3019 : else
3020 : {
3021 : /* Exponential notation. */
3022 : *p++ = digits[--ndigits];
3023 : if ((flags & FLAG_ALT) || ndigits > nzeroes)
3024 : {
3025 : *p++ = decimal_point_char ();
3026 : while (ndigits > nzeroes)
3027 : {
3028 : --ndigits;
3029 : *p++ = digits[ndigits];
3030 : }
3031 : }
3032 : *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3033 : # if WIDE_CHAR_VERSION
3034 : {
3035 : static const wchar_t decimal_format[] =
3036 : { '%', '+', '.', '2', 'd', '\0' };
3037 : SNPRINTF (p, 6 + 1, decimal_format, exponent);
3038 : }
3039 : while (*p != '\0')
3040 : p++;
3041 : # else
3042 : if (sizeof (DCHAR_T) == 1)
3043 : {
3044 : sprintf ((char *) p, "%+.2d", exponent);
3045 : while (*p != '\0')
3046 : p++;
3047 : }
3048 : else
3049 : {
3050 : char expbuf[6 + 1];
3051 : const char *ep;
3052 : sprintf (expbuf, "%+.2d", exponent);
3053 : for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3054 : p++;
3055 : }
3056 : # endif
3057 : }
3058 :
3059 : free (digits);
3060 : }
3061 : }
3062 : else
3063 0 : abort ();
3064 : # else
3065 : /* arg is finite. */
3066 : abort ();
3067 0 : # endif
3068 : }
3069 :
3070 : END_LONG_DOUBLE_ROUNDING ();
3071 : }
3072 : }
3073 : # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3074 : else
3075 : # endif
3076 : # endif
3077 : # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3078 : {
3079 : double arg = a.arg[dp->arg_index].a.a_double;
3080 :
3081 : if (isnand (arg))
3082 : {
3083 : if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3084 : {
3085 : *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3086 : }
3087 : else
3088 : {
3089 : *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3090 : }
3091 : }
3092 : else
3093 : {
3094 : int sign = 0;
3095 :
3096 : if (signbit (arg)) /* arg < 0.0 or negative zero */
3097 : {
3098 : sign = -1;
3099 : arg = -arg;
3100 : }
3101 :
3102 : if (sign < 0)
3103 : *p++ = '-';
3104 : else if (flags & FLAG_SHOWSIGN)
3105 : *p++ = '+';
3106 : else if (flags & FLAG_SPACE)
3107 : *p++ = ' ';
3108 :
3109 : if (arg > 0.0 && arg + arg == arg)
3110 : {
3111 : if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3112 : {
3113 : *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3114 : }
3115 : else
3116 : {
3117 : *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3118 : }
3119 : }
3120 : else
3121 : {
3122 : # if NEED_PRINTF_DOUBLE
3123 : pad_ptr = p;
3124 :
3125 : if (dp->conversion == 'f' || dp->conversion == 'F')
3126 : {
3127 : char *digits;
3128 : size_t ndigits;
3129 :
3130 : digits =
3131 : scale10_round_decimal_double (arg, precision);
3132 : if (digits == NULL)
3133 : goto out_of_memory;
3134 : ndigits = strlen (digits);
3135 :
3136 : if (ndigits > precision)
3137 : do
3138 : {
3139 : --ndigits;
3140 : *p++ = digits[ndigits];
3141 : }
3142 : while (ndigits > precision);
3143 : else
3144 : *p++ = '0';
3145 : /* Here ndigits <= precision. */
3146 : if ((flags & FLAG_ALT) || precision > 0)
3147 : {
3148 : *p++ = decimal_point_char ();
3149 : for (; precision > ndigits; precision--)
3150 : *p++ = '0';
3151 : while (ndigits > 0)
3152 : {
3153 : --ndigits;
3154 : *p++ = digits[ndigits];
3155 : }
3156 : }
3157 :
3158 : free (digits);
3159 : }
3160 : else if (dp->conversion == 'e' || dp->conversion == 'E')
3161 : {
3162 : int exponent;
3163 :
3164 : if (arg == 0.0)
3165 : {
3166 : exponent = 0;
3167 : *p++ = '0';
3168 : if ((flags & FLAG_ALT) || precision > 0)
3169 : {
3170 : *p++ = decimal_point_char ();
3171 : for (; precision > 0; precision--)
3172 : *p++ = '0';
3173 : }
3174 : }
3175 : else
3176 : {
3177 : /* arg > 0.0. */
3178 : int adjusted;
3179 : char *digits;
3180 : size_t ndigits;
3181 :
3182 : exponent = floorlog10 (arg);
3183 : adjusted = 0;
3184 : for (;;)
3185 : {
3186 : digits =
3187 : scale10_round_decimal_double (arg,
3188 : (int)precision - exponent);
3189 : if (digits == NULL)
3190 : goto out_of_memory;
3191 : ndigits = strlen (digits);
3192 :
3193 : if (ndigits == precision + 1)
3194 : break;
3195 : if (ndigits < precision
3196 : || ndigits > precision + 2)
3197 : /* The exponent was not guessed
3198 : precisely enough. */
3199 : abort ();
3200 : if (adjusted)
3201 : /* None of two values of exponent is
3202 : the right one. Prevent an endless
3203 : loop. */
3204 : abort ();
3205 : free (digits);
3206 : if (ndigits == precision)
3207 : exponent -= 1;
3208 : else
3209 : exponent += 1;
3210 : adjusted = 1;
3211 : }
3212 :
3213 : /* Here ndigits = precision+1. */
3214 : *p++ = digits[--ndigits];
3215 : if ((flags & FLAG_ALT) || precision > 0)
3216 : {
3217 : *p++ = decimal_point_char ();
3218 : while (ndigits > 0)
3219 : {
3220 : --ndigits;
3221 : *p++ = digits[ndigits];
3222 : }
3223 : }
3224 :
3225 : free (digits);
3226 : }
3227 :
3228 : *p++ = dp->conversion; /* 'e' or 'E' */
3229 : # if WIDE_CHAR_VERSION
3230 : {
3231 : static const wchar_t decimal_format[] =
3232 : /* Produce the same number of exponent digits
3233 : as the native printf implementation. */
3234 : # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3235 : { '%', '+', '.', '3', 'd', '\0' };
3236 : # else
3237 : { '%', '+', '.', '2', 'd', '\0' };
3238 : # endif
3239 : SNPRINTF (p, 6 + 1, decimal_format, exponent);
3240 : }
3241 : while (*p != '\0')
3242 : p++;
3243 : # else
3244 : {
3245 : static const char decimal_format[] =
3246 : /* Produce the same number of exponent digits
3247 : as the native printf implementation. */
3248 : # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3249 : "%+.3d";
3250 : # else
3251 : "%+.2d";
3252 : # endif
3253 : if (sizeof (DCHAR_T) == 1)
3254 : {
3255 : sprintf ((char *) p, decimal_format, exponent);
3256 : while (*p != '\0')
3257 : p++;
3258 : }
3259 : else
3260 : {
3261 : char expbuf[6 + 1];
3262 : const char *ep;
3263 : sprintf (expbuf, decimal_format, exponent);
3264 : for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3265 : p++;
3266 : }
3267 : }
3268 : # endif
3269 : }
3270 : else if (dp->conversion == 'g' || dp->conversion == 'G')
3271 : {
3272 : if (precision == 0)
3273 : precision = 1;
3274 : /* precision >= 1. */
3275 :
3276 : if (arg == 0.0)
3277 : /* The exponent is 0, >= -4, < precision.
3278 : Use fixed-point notation. */
3279 : {
3280 : size_t ndigits = precision;
3281 : /* Number of trailing zeroes that have to be
3282 : dropped. */
3283 : size_t nzeroes =
3284 : (flags & FLAG_ALT ? 0 : precision - 1);
3285 :
3286 : --ndigits;
3287 : *p++ = '0';
3288 : if ((flags & FLAG_ALT) || ndigits > nzeroes)
3289 : {
3290 : *p++ = decimal_point_char ();
3291 : while (ndigits > nzeroes)
3292 : {
3293 : --ndigits;
3294 : *p++ = '0';
3295 : }
3296 : }
3297 : }
3298 : else
3299 : {
3300 : /* arg > 0.0. */
3301 : int exponent;
3302 : int adjusted;
3303 : char *digits;
3304 : size_t ndigits;
3305 : size_t nzeroes;
3306 :
3307 : exponent = floorlog10 (arg);
3308 : adjusted = 0;
3309 : for (;;)
3310 : {
3311 : digits =
3312 : scale10_round_decimal_double (arg,
3313 : (int)(precision - 1) - exponent);
3314 : if (digits == NULL)
3315 : goto out_of_memory;
3316 : ndigits = strlen (digits);
3317 :
3318 : if (ndigits == precision)
3319 : break;
3320 : if (ndigits < precision - 1
3321 : || ndigits > precision + 1)
3322 : /* The exponent was not guessed
3323 : precisely enough. */
3324 : abort ();
3325 : if (adjusted)
3326 : /* None of two values of exponent is
3327 : the right one. Prevent an endless
3328 : loop. */
3329 : abort ();
3330 : free (digits);
3331 : if (ndigits < precision)
3332 : exponent -= 1;
3333 : else
3334 : exponent += 1;
3335 : adjusted = 1;
3336 : }
3337 : /* Here ndigits = precision. */
3338 :
3339 : /* Determine the number of trailing zeroes
3340 : that have to be dropped. */
3341 : nzeroes = 0;
3342 : if ((flags & FLAG_ALT) == 0)
3343 : while (nzeroes < ndigits
3344 : && digits[nzeroes] == '0')
3345 : nzeroes++;
3346 :
3347 : /* The exponent is now determined. */
3348 : if (exponent >= -4
3349 : && exponent < (long)precision)
3350 : {
3351 : /* Fixed-point notation:
3352 : max(exponent,0)+1 digits, then the
3353 : decimal point, then the remaining
3354 : digits without trailing zeroes. */
3355 : if (exponent >= 0)
3356 : {
3357 : size_t count = exponent + 1;
3358 : /* Note: count <= precision = ndigits. */
3359 : for (; count > 0; count--)
3360 : *p++ = digits[--ndigits];
3361 : if ((flags & FLAG_ALT) || ndigits > nzeroes)
3362 : {
3363 : *p++ = decimal_point_char ();
3364 : while (ndigits > nzeroes)
3365 : {
3366 : --ndigits;
3367 : *p++ = digits[ndigits];
3368 : }
3369 : }
3370 : }
3371 : else
3372 : {
3373 : size_t count = -exponent - 1;
3374 : *p++ = '0';
3375 : *p++ = decimal_point_char ();
3376 : for (; count > 0; count--)
3377 : *p++ = '0';
3378 : while (ndigits > nzeroes)
3379 : {
3380 : --ndigits;
3381 : *p++ = digits[ndigits];
3382 : }
3383 : }
3384 : }
3385 : else
3386 : {
3387 : /* Exponential notation. */
3388 : *p++ = digits[--ndigits];
3389 : if ((flags & FLAG_ALT) || ndigits > nzeroes)
3390 : {
3391 : *p++ = decimal_point_char ();
3392 : while (ndigits > nzeroes)
3393 : {
3394 : --ndigits;
3395 : *p++ = digits[ndigits];
3396 : }
3397 : }
3398 : *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3399 : # if WIDE_CHAR_VERSION
3400 : {
3401 : static const wchar_t decimal_format[] =
3402 : /* Produce the same number of exponent digits
3403 : as the native printf implementation. */
3404 : # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3405 : { '%', '+', '.', '3', 'd', '\0' };
3406 : # else
3407 : { '%', '+', '.', '2', 'd', '\0' };
3408 : # endif
3409 : SNPRINTF (p, 6 + 1, decimal_format, exponent);
3410 : }
3411 : while (*p != '\0')
3412 : p++;
3413 : # else
3414 : {
3415 : static const char decimal_format[] =
3416 : /* Produce the same number of exponent digits
3417 : as the native printf implementation. */
3418 : # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3419 : "%+.3d";
3420 : # else
3421 : "%+.2d";
3422 : # endif
3423 : if (sizeof (DCHAR_T) == 1)
3424 : {
3425 : sprintf ((char *) p, decimal_format, exponent);
3426 : while (*p != '\0')
3427 : p++;
3428 : }
3429 : else
3430 : {
3431 : char expbuf[6 + 1];
3432 : const char *ep;
3433 : sprintf (expbuf, decimal_format, exponent);
3434 : for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3435 : p++;
3436 : }
3437 : }
3438 : # endif
3439 : }
3440 :
3441 : free (digits);
3442 : }
3443 : }
3444 : else
3445 : abort ();
3446 : # else
3447 : /* arg is finite. */
3448 : if (!(arg == 0.0))
3449 : abort ();
3450 :
3451 : pad_ptr = p;
3452 :
3453 : if (dp->conversion == 'f' || dp->conversion == 'F')
3454 : {
3455 : *p++ = '0';
3456 : if ((flags & FLAG_ALT) || precision > 0)
3457 : {
3458 : *p++ = decimal_point_char ();
3459 : for (; precision > 0; precision--)
3460 : *p++ = '0';
3461 : }
3462 : }
3463 : else if (dp->conversion == 'e' || dp->conversion == 'E')
3464 : {
3465 : *p++ = '0';
3466 : if ((flags & FLAG_ALT) || precision > 0)
3467 : {
3468 : *p++ = decimal_point_char ();
3469 : for (; precision > 0; precision--)
3470 : *p++ = '0';
3471 : }
3472 : *p++ = dp->conversion; /* 'e' or 'E' */
3473 : *p++ = '+';
3474 : /* Produce the same number of exponent digits as
3475 : the native printf implementation. */
3476 : # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3477 : *p++ = '0';
3478 : # endif
3479 : *p++ = '0';
3480 : *p++ = '0';
3481 : }
3482 : else if (dp->conversion == 'g' || dp->conversion == 'G')
3483 : {
3484 : *p++ = '0';
3485 : if (flags & FLAG_ALT)
3486 : {
3487 : size_t ndigits =
3488 : (precision > 0 ? precision - 1 : 0);
3489 : *p++ = decimal_point_char ();
3490 : for (; ndigits > 0; --ndigits)
3491 : *p++ = '0';
3492 : }
3493 : }
3494 : else
3495 : abort ();
3496 : # endif
3497 : }
3498 : }
3499 : }
3500 : # endif
3501 0 :
3502 : /* The generated string now extends from tmp to p, with the
3503 0 : zero padding insertion point being at pad_ptr. */
3504 0 : if (has_width && p - tmp < width)
3505 : {
3506 0 : size_t pad = width - (p - tmp);
3507 : DCHAR_T *end = p + pad;
3508 :
3509 0 : if (flags & FLAG_LEFT)
3510 0 : {
3511 : /* Pad with spaces on the right. */
3512 0 : for (; pad > 0; pad--)
3513 0 : *p++ = ' ';
3514 : }
3515 0 : else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3516 : {
3517 0 : /* Pad with zeroes. */
3518 0 : DCHAR_T *q = end;
3519 0 :
3520 0 : while (p > pad_ptr)
3521 : *--q = *--p;
3522 : for (; pad > 0; pad--)
3523 : *p++ = '0';
3524 : }
3525 0 : else
3526 : {
3527 0 : /* Pad with spaces on the left. */
3528 0 : DCHAR_T *q = end;
3529 0 :
3530 0 : while (p > tmp)
3531 : *--q = *--p;
3532 : for (; pad > 0; pad--)
3533 0 : *p++ = ' ';
3534 : }
3535 :
3536 : p = end;
3537 0 : }
3538 :
3539 0 : {
3540 : size_t count = p - tmp;
3541 :
3542 0 : if (count >= tmp_length)
3543 : /* tmp_length was incorrectly calculated - fix the
3544 : code above! */
3545 0 : abort ();
3546 :
3547 0 : /* Make room for the result. */
3548 : if (count >= allocated - length)
3549 0 : {
3550 : size_t n = xsum (length, count);
3551 :
3552 : ENSURE_ALLOCATION (n);
3553 0 : }
3554 0 :
3555 0 : /* Append the result. */
3556 0 : memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3557 : if (tmp != tmpbuf)
3558 : free (tmp);
3559 : length += count;
3560 : }
3561 : }
3562 947 : #endif
3563 947 : else
3564 : {
3565 : arg_type type = a.arg[dp->arg_index].type;
3566 : int flags = dp->flags;
3567 : #if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
3568 : int has_width;
3569 : size_t width;
3570 : #endif
3571 : #if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
3572 : int has_precision;
3573 : size_t precision;
3574 : #endif
3575 : #if NEED_PRINTF_UNBOUNDED_PRECISION
3576 : int prec_ourselves;
3577 : #else
3578 : # define prec_ourselves 0
3579 : #endif
3580 : #if NEED_PRINTF_FLAG_LEFTADJUST
3581 : # define pad_ourselves 1
3582 : #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
3583 : int pad_ourselves;
3584 : #else
3585 : # define pad_ourselves 0
3586 : #endif
3587 : TCHAR_T *fbp;
3588 : unsigned int prefix_count;
3589 : int prefixes[2];
3590 : #if !USE_SNPRINTF
3591 : size_t tmp_length;
3592 : TCHAR_T tmpbuf[700];
3593 : TCHAR_T *tmp;
3594 : #endif
3595 :
3596 : #if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
3597 : has_width = 0;
3598 : width = 0;
3599 : if (dp->width_start != dp->width_end)
3600 : {
3601 : if (dp->width_arg_index != ARG_NONE)
3602 : {
3603 : int arg;
3604 :
3605 : if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3606 : abort ();
3607 : arg = a.arg[dp->width_arg_index].a.a_int;
3608 : if (arg < 0)
3609 : {
3610 : /* "A negative field width is taken as a '-' flag
3611 : followed by a positive field width." */
3612 : flags |= FLAG_LEFT;
3613 : width = (unsigned int) (-arg);
3614 : }
3615 : else
3616 : width = arg;
3617 : }
3618 : else
3619 : {
3620 : const FCHAR_T *digitp = dp->width_start;
3621 :
3622 : do
3623 : width = xsum (xtimes (width, 10), *digitp++ - '0');
3624 : while (digitp != dp->width_end);
3625 : }
3626 : has_width = 1;
3627 : }
3628 : #endif
3629 :
3630 : #if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
3631 : has_precision = 0;
3632 : precision = 6;
3633 : if (dp->precision_start != dp->precision_end)
3634 : {
3635 : if (dp->precision_arg_index != ARG_NONE)
3636 : {
3637 : int arg;
3638 :
3639 : if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3640 : abort ();
3641 : arg = a.arg[dp->precision_arg_index].a.a_int;
3642 : /* "A negative precision is taken as if the precision
3643 : were omitted." */
3644 : if (arg >= 0)
3645 : {
3646 : precision = arg;
3647 : has_precision = 1;
3648 : }
3649 : }
3650 : else
3651 : {
3652 : const FCHAR_T *digitp = dp->precision_start + 1;
3653 :
3654 : precision = 0;
3655 : while (digitp != dp->precision_end)
3656 : precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3657 : has_precision = 1;
3658 : }
3659 : }
3660 : #endif
3661 :
3662 : /* Decide whether to handle the precision ourselves. */
3663 : #if NEED_PRINTF_UNBOUNDED_PRECISION
3664 : switch (dp->conversion)
3665 : {
3666 : case 'd': case 'i': case 'u':
3667 : case 'o':
3668 : case 'x': case 'X': case 'p':
3669 : prec_ourselves = has_precision && (precision > 0);
3670 : break;
3671 : default:
3672 : prec_ourselves = 0;
3673 : break;
3674 : }
3675 : #endif
3676 :
3677 : /* Decide whether to perform the padding ourselves. */
3678 : #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
3679 : switch (dp->conversion)
3680 : {
3681 : # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
3682 : /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
3683 : to perform the padding after this conversion. Functions
3684 : with unistdio extensions perform the padding based on
3685 : character count rather than element count. */
3686 : case 'c': case 's':
3687 : # endif
3688 : # if NEED_PRINTF_FLAG_ZERO
3689 : case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
3690 : case 'a': case 'A':
3691 : # endif
3692 : pad_ourselves = 1;
3693 : break;
3694 : default:
3695 : pad_ourselves = prec_ourselves;
3696 : break;
3697 : }
3698 : #endif
3699 :
3700 : #if !USE_SNPRINTF
3701 : /* Allocate a temporary buffer of sufficient size for calling
3702 : sprintf. */
3703 : {
3704 : switch (dp->conversion)
3705 : {
3706 :
3707 : case 'd': case 'i': case 'u':
3708 : # if HAVE_LONG_LONG_INT
3709 : if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
3710 : tmp_length =
3711 : (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
3712 : * 0.30103 /* binary -> decimal */
3713 : )
3714 : + 1; /* turn floor into ceil */
3715 : else
3716 : # endif
3717 : if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
3718 : tmp_length =
3719 : (unsigned int) (sizeof (unsigned long) * CHAR_BIT
3720 : * 0.30103 /* binary -> decimal */
3721 : )
3722 : + 1; /* turn floor into ceil */
3723 : else
3724 : tmp_length =
3725 : (unsigned int) (sizeof (unsigned int) * CHAR_BIT
3726 : * 0.30103 /* binary -> decimal */
3727 : )
3728 : + 1; /* turn floor into ceil */
3729 : if (tmp_length < precision)
3730 : tmp_length = precision;
3731 : /* Multiply by 2, as an estimate for FLAG_GROUP. */
3732 : tmp_length = xsum (tmp_length, tmp_length);
3733 : /* Add 1, to account for a leading sign. */
3734 : tmp_length = xsum (tmp_length, 1);
3735 : break;
3736 :
3737 : case 'o':
3738 : # if HAVE_LONG_LONG_INT
3739 : if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
3740 : tmp_length =
3741 : (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
3742 : * 0.333334 /* binary -> octal */
3743 : )
3744 : + 1; /* turn floor into ceil */
3745 : else
3746 : # endif
3747 : if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
3748 : tmp_length =
3749 : (unsigned int) (sizeof (unsigned long) * CHAR_BIT
3750 : * 0.333334 /* binary -> octal */
3751 : )
3752 : + 1; /* turn floor into ceil */
3753 : else
3754 : tmp_length =
3755 : (unsigned int) (sizeof (unsigned int) * CHAR_BIT
3756 : * 0.333334 /* binary -> octal */
3757 : )
3758 : + 1; /* turn floor into ceil */
3759 : if (tmp_length < precision)
3760 : tmp_length = precision;
3761 : /* Add 1, to account for a leading sign. */
3762 : tmp_length = xsum (tmp_length, 1);
3763 : break;
3764 :
3765 : case 'x': case 'X':
3766 : # if HAVE_LONG_LONG_INT
3767 : if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
3768 : tmp_length =
3769 : (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
3770 : * 0.25 /* binary -> hexadecimal */
3771 : )
3772 : + 1; /* turn floor into ceil */
3773 : else
3774 : # endif
3775 : if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
3776 : tmp_length =
3777 : (unsigned int) (sizeof (unsigned long) * CHAR_BIT
3778 : * 0.25 /* binary -> hexadecimal */
3779 : )
3780 : + 1; /* turn floor into ceil */
3781 : else
3782 : tmp_length =
3783 : (unsigned int) (sizeof (unsigned int) * CHAR_BIT
3784 : * 0.25 /* binary -> hexadecimal */
3785 : )
3786 : + 1; /* turn floor into ceil */
3787 : if (tmp_length < precision)
3788 : tmp_length = precision;
3789 : /* Add 2, to account for a leading sign or alternate form. */
3790 : tmp_length = xsum (tmp_length, 2);
3791 : break;
3792 :
3793 : case 'f': case 'F':
3794 : if (type == TYPE_LONGDOUBLE)
3795 : tmp_length =
3796 : (unsigned int) (LDBL_MAX_EXP
3797 : * 0.30103 /* binary -> decimal */
3798 : * 2 /* estimate for FLAG_GROUP */
3799 : )
3800 : + 1 /* turn floor into ceil */
3801 : + 10; /* sign, decimal point etc. */
3802 : else
3803 : tmp_length =
3804 : (unsigned int) (DBL_MAX_EXP
3805 : * 0.30103 /* binary -> decimal */
3806 : * 2 /* estimate for FLAG_GROUP */
3807 : )
3808 : + 1 /* turn floor into ceil */
3809 : + 10; /* sign, decimal point etc. */
3810 : tmp_length = xsum (tmp_length, precision);
3811 : break;
3812 :
3813 : case 'e': case 'E': case 'g': case 'G':
3814 : tmp_length =
3815 : 12; /* sign, decimal point, exponent etc. */
3816 : tmp_length = xsum (tmp_length, precision);
3817 : break;
3818 :
3819 : case 'a': case 'A':
3820 : if (type == TYPE_LONGDOUBLE)
3821 : tmp_length =
3822 : (unsigned int) (LDBL_DIG
3823 : * 0.831 /* decimal -> hexadecimal */
3824 : )
3825 : + 1; /* turn floor into ceil */
3826 : else
3827 : tmp_length =
3828 : (unsigned int) (DBL_DIG
3829 : * 0.831 /* decimal -> hexadecimal */
3830 : )
3831 : + 1; /* turn floor into ceil */
3832 : if (tmp_length < precision)
3833 : tmp_length = precision;
3834 : /* Account for sign, decimal point etc. */
3835 : tmp_length = xsum (tmp_length, 12);
3836 : break;
3837 :
3838 : case 'c':
3839 : # if HAVE_WINT_T && !WIDE_CHAR_VERSION
3840 : if (type == TYPE_WIDE_CHAR)
3841 : tmp_length = MB_CUR_MAX;
3842 : else
3843 : # endif
3844 : tmp_length = 1;
3845 : break;
3846 :
3847 : case 's':
3848 : # if HAVE_WCHAR_T
3849 : if (type == TYPE_WIDE_STRING)
3850 : {
3851 : tmp_length =
3852 : local_wcslen (a.arg[dp->arg_index].a.a_wide_string);
3853 :
3854 : # if !WIDE_CHAR_VERSION
3855 : tmp_length = xtimes (tmp_length, MB_CUR_MAX);
3856 : # endif
3857 : }
3858 : else
3859 : # endif
3860 : tmp_length = strlen (a.arg[dp->arg_index].a.a_string);
3861 : break;
3862 :
3863 : case 'p':
3864 : tmp_length =
3865 : (unsigned int) (sizeof (void *) * CHAR_BIT
3866 : * 0.25 /* binary -> hexadecimal */
3867 : )
3868 : + 1 /* turn floor into ceil */
3869 : + 2; /* account for leading 0x */
3870 : break;
3871 :
3872 : default:
3873 : abort ();
3874 : }
3875 :
3876 : if (!pad_ourselves)
3877 : {
3878 : # if ENABLE_UNISTDIO
3879 : /* Padding considers the number of characters, therefore
3880 : the number of elements after padding may be
3881 : > max (tmp_length, width)
3882 : but is certainly
3883 : <= tmp_length + width. */
3884 : tmp_length = xsum (tmp_length, width);
3885 : # else
3886 : /* Padding considers the number of elements,
3887 : says POSIX. */
3888 : if (tmp_length < width)
3889 : tmp_length = width;
3890 : # endif
3891 : }
3892 :
3893 : tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3894 : }
3895 :
3896 : if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
3897 : tmp = tmpbuf;
3898 : else
3899 : {
3900 : size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
3901 :
3902 : if (size_overflow_p (tmp_memsize))
3903 : /* Overflow, would lead to out of memory. */
3904 : goto out_of_memory;
3905 : tmp = (TCHAR_T *) malloc (tmp_memsize);
3906 : if (tmp == NULL)
3907 : /* Out of memory. */
3908 : goto out_of_memory;
3909 : }
3910 : #endif
3911 947 :
3912 947 : /* Construct the format string for calling snprintf or
3913 : sprintf. */
3914 : fbp = buf;
3915 : *fbp++ = '%';
3916 : #if NEED_PRINTF_FLAG_GROUPING
3917 : /* The underlying implementation doesn't support the ' flag.
3918 947 : Produce no grouping characters in this case; this is
3919 1 : acceptable because the grouping is locale dependent. */
3920 : #else
3921 947 : if (flags & FLAG_GROUP)
3922 14 : *fbp++ = '\'';
3923 947 : #endif
3924 3 : if (flags & FLAG_LEFT)
3925 947 : *fbp++ = '-';
3926 1 : if (flags & FLAG_SHOWSIGN)
3927 947 : *fbp++ = '+';
3928 3 : if (flags & FLAG_SPACE)
3929 : *fbp++ = ' ';
3930 : if (flags & FLAG_ALT)
3931 947 : *fbp++ = '#';
3932 2 : if (!pad_ourselves)
3933 947 : {
3934 : if (flags & FLAG_ZERO)
3935 24 : *fbp++ = '0';
3936 : if (dp->width_start != dp->width_end)
3937 : {
3938 : size_t n = dp->width_end - dp->width_start;
3939 : /* The width specification is known to consist only
3940 24 : of standard ASCII characters. */
3941 24 : if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
3942 : {
3943 : memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
3944 : fbp += n;
3945 : }
3946 : else
3947 : {
3948 : const FCHAR_T *mp = dp->width_start;
3949 : do
3950 : *fbp++ = (unsigned char) *mp++;
3951 : while (--n > 0);
3952 : }
3953 : }
3954 947 : }
3955 : if (!prec_ourselves)
3956 11 : {
3957 : if (dp->precision_start != dp->precision_end)
3958 : {
3959 : size_t n = dp->precision_end - dp->precision_start;
3960 : /* The precision specification is known to consist only
3961 11 : of standard ASCII characters. */
3962 11 : if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
3963 : {
3964 : memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
3965 : fbp += n;
3966 : }
3967 : else
3968 : {
3969 : const FCHAR_T *mp = dp->precision_start;
3970 : do
3971 : *fbp++ = (unsigned char) *mp++;
3972 : while (--n > 0);
3973 : }
3974 947 : }
3975 : }
3976 :
3977 0 : switch (type)
3978 : {
3979 : #if HAVE_LONG_LONG_INT
3980 : case TYPE_LONGLONGINT:
3981 : case TYPE_ULONGLONGINT:
3982 : # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3983 : *fbp++ = 'I';
3984 : *fbp++ = '6';
3985 0 : *fbp++ = '4';
3986 : break;
3987 : # else
3988 : *fbp++ = 'l';
3989 61 : /*FALLTHROUGH*/
3990 : # endif
3991 : #endif
3992 : case TYPE_LONGINT:
3993 : case TYPE_ULONGINT:
3994 : #if HAVE_WINT_T
3995 : case TYPE_WIDE_CHAR:
3996 : #endif
3997 61 : #if HAVE_WCHAR_T
3998 61 : case TYPE_WIDE_STRING:
3999 18 : #endif
4000 18 : *fbp++ = 'l';
4001 18 : break;
4002 868 : case TYPE_LONGDOUBLE:
4003 868 : *fbp++ = 'L';
4004 : break;
4005 : default:
4006 : break;
4007 : }
4008 : #if NEED_PRINTF_DIRECTIVE_F
4009 : if (dp->conversion == 'F')
4010 947 : *fbp = 'f';
4011 : else
4012 : #endif
4013 : *fbp = dp->conversion;
4014 : #if USE_SNPRINTF
4015 : # if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
4016 : fbp[1] = '%';
4017 : fbp[2] = 'n';
4018 : fbp[3] = '\0';
4019 : # else
4020 : /* On glibc2 systems from glibc >= 2.3 - probably also older
4021 : ones - we know that snprintf's returns value conforms to
4022 : ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes.
4023 : Therefore we can avoid using %n in this situation.
4024 : On glibc2 systems from 2004-10-18 or newer, the use of %n
4025 : in format strings in writable memory may crash the program
4026 : (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
4027 : in this situation. */
4028 : /* On native Win32 systems (such as mingw), we can avoid using
4029 : %n because:
4030 : - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
4031 : snprintf does not write more than the specified number
4032 : of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
4033 : '4', '5', '6' into buf, not '4', '5', '\0'.)
4034 : - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
4035 : allows us to recognize the case of an insufficient
4036 : buffer size: it returns -1 in this case.
4037 : On native Win32 systems (such as mingw) where the OS is
4038 : Windows Vista, the use of %n in format strings by default
4039 : crashes the program. See
4040 947 : <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
4041 : <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
4042 : So we should avoid %n in this situation. */
4043 : fbp[1] = '\0';
4044 : # endif
4045 : #else
4046 : fbp[1] = '\0';
4047 947 : #endif
4048 947 :
4049 : /* Construct the arguments for calling snprintf or sprintf. */
4050 9 : prefix_count = 0;
4051 0 : if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
4052 9 : {
4053 : if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4054 947 : abort ();
4055 : prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
4056 6 : }
4057 0 : if (dp->precision_arg_index != ARG_NONE)
4058 6 : {
4059 : if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4060 : abort ();
4061 : prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
4062 : }
4063 :
4064 : #if USE_SNPRINTF
4065 : /* The SNPRINTF result is appended after result[0..length].
4066 : The latter is an array of DCHAR_T; SNPRINTF appends an
4067 : array of TCHAR_T to it. This is possible because
4068 : sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
4069 : alignof (TCHAR_T) <= alignof (DCHAR_T). */
4070 947 : # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
4071 : /* Ensure that maxlen below will be >= 2. Needed on BeOS,
4072 : where an snprintf() with maxlen==1 acts like sprintf(). */
4073 : ENSURE_ALLOCATION (xsum (length,
4074 : (2 + TCHARS_PER_DCHAR - 1)
4075 947 : / TCHARS_PER_DCHAR));
4076 : /* Prepare checking whether snprintf returns the count
4077 : via %n. */
4078 : *(TCHAR_T *) (result + length) = '\0';
4079 52 : #endif
4080 999 :
4081 : for (;;)
4082 : {
4083 999 : int count = -1;
4084 999 :
4085 : #if USE_SNPRINTF
4086 : int retcount = 0;
4087 999 : size_t maxlen = allocated - length;
4088 0 : /* SNPRINTF can fail if its second argument is
4089 999 : > INT_MAX. */
4090 : if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
4091 : maxlen = INT_MAX / TCHARS_PER_DCHAR;
4092 : maxlen = maxlen * TCHARS_PER_DCHAR;
4093 : # define SNPRINTF_BUF(arg) \
4094 : switch (prefix_count) \
4095 : { \
4096 : case 0: \
4097 : retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4098 : maxlen, buf, \
4099 : arg, &count); \
4100 : break; \
4101 : case 1: \
4102 : retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4103 : maxlen, buf, \
4104 : prefixes[0], arg, &count); \
4105 : break; \
4106 : case 2: \
4107 : retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4108 : maxlen, buf, \
4109 : prefixes[0], prefixes[1], arg, \
4110 : &count); \
4111 : break; \
4112 : default: \
4113 : abort (); \
4114 : }
4115 : #else
4116 : # define SNPRINTF_BUF(arg) \
4117 : switch (prefix_count) \
4118 : { \
4119 : case 0: \
4120 : count = sprintf (tmp, buf, arg); \
4121 : break; \
4122 : case 1: \
4123 : count = sprintf (tmp, buf, prefixes[0], arg); \
4124 : break; \
4125 : case 2: \
4126 : count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
4127 : arg); \
4128 : break; \
4129 : default: \
4130 : abort (); \
4131 999 : }
4132 : #endif
4133 0 :
4134 : switch (type)
4135 0 : {
4136 0 : case TYPE_SCHAR:
4137 : {
4138 0 : int arg = a.arg[dp->arg_index].a.a_schar;
4139 0 : SNPRINTF_BUF (arg);
4140 : }
4141 0 : break;
4142 0 : case TYPE_UCHAR:
4143 : {
4144 0 : unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
4145 0 : SNPRINTF_BUF (arg);
4146 : }
4147 0 : break;
4148 0 : case TYPE_SHORT:
4149 : {
4150 0 : int arg = a.arg[dp->arg_index].a.a_short;
4151 0 : SNPRINTF_BUF (arg);
4152 : }
4153 0 : break;
4154 0 : case TYPE_USHORT:
4155 : {
4156 0 : unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
4157 27 : SNPRINTF_BUF (arg);
4158 : }
4159 27 : break;
4160 27 : case TYPE_INT:
4161 : {
4162 27 : int arg = a.arg[dp->arg_index].a.a_int;
4163 0 : SNPRINTF_BUF (arg);
4164 : }
4165 0 : break;
4166 0 : case TYPE_UINT:
4167 : {
4168 0 : unsigned int arg = a.arg[dp->arg_index].a.a_uint;
4169 4 : SNPRINTF_BUF (arg);
4170 : }
4171 4 : break;
4172 4 : case TYPE_LONGINT:
4173 : {
4174 4 : long int arg = a.arg[dp->arg_index].a.a_longint;
4175 70 : SNPRINTF_BUF (arg);
4176 : }
4177 70 : break;
4178 70 : case TYPE_ULONGINT:
4179 : {
4180 70 : unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
4181 : SNPRINTF_BUF (arg);
4182 0 : }
4183 : break;
4184 0 : #if HAVE_LONG_LONG_INT
4185 0 : case TYPE_LONGLONGINT:
4186 : {
4187 0 : long long int arg = a.arg[dp->arg_index].a.a_longlongint;
4188 0 : SNPRINTF_BUF (arg);
4189 : }
4190 0 : break;
4191 0 : case TYPE_ULONGLONGINT:
4192 : {
4193 0 : unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
4194 : SNPRINTF_BUF (arg);
4195 0 : }
4196 : break;
4197 0 : #endif
4198 0 : case TYPE_DOUBLE:
4199 : {
4200 0 : double arg = a.arg[dp->arg_index].a.a_double;
4201 18 : SNPRINTF_BUF (arg);
4202 : }
4203 18 : break;
4204 18 : case TYPE_LONGDOUBLE:
4205 : {
4206 18 : long double arg = a.arg[dp->arg_index].a.a_longdouble;
4207 2 : SNPRINTF_BUF (arg);
4208 : }
4209 2 : break;
4210 2 : case TYPE_CHAR:
4211 : {
4212 2 : int arg = a.arg[dp->arg_index].a.a_char;
4213 : SNPRINTF_BUF (arg);
4214 0 : }
4215 : break;
4216 0 : #if HAVE_WINT_T
4217 0 : case TYPE_WIDE_CHAR:
4218 : {
4219 0 : wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
4220 : SNPRINTF_BUF (arg);
4221 878 : }
4222 : break;
4223 878 : #endif
4224 878 : case TYPE_STRING:
4225 : {
4226 878 : const char *arg = a.arg[dp->arg_index].a.a_string;
4227 : SNPRINTF_BUF (arg);
4228 0 : }
4229 : break;
4230 0 : #if HAVE_WCHAR_T
4231 0 : case TYPE_WIDE_STRING:
4232 : {
4233 0 : const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
4234 : SNPRINTF_BUF (arg);
4235 0 : }
4236 : break;
4237 0 : #endif
4238 0 : case TYPE_POINTER:
4239 : {
4240 0 : void *arg = a.arg[dp->arg_index].a.a_pointer;
4241 0 : SNPRINTF_BUF (arg);
4242 0 : }
4243 : break;
4244 : default:
4245 : abort ();
4246 : }
4247 :
4248 : #if USE_SNPRINTF
4249 : /* Portability: Not all implementations of snprintf()
4250 999 : are ISO C 99 compliant. Determine the number of
4251 : bytes that snprintf() has produced or would have
4252 : produced. */
4253 : if (count >= 0)
4254 0 : {
4255 0 : /* Verify that snprintf() has NUL-terminated its
4256 0 : result. */
4257 : if (count < maxlen
4258 0 : && ((TCHAR_T *) (result + length)) [count] != '\0')
4259 0 : abort ();
4260 : /* Portability hack. */
4261 : if (retcount > count)
4262 : count = retcount;
4263 : }
4264 : else
4265 999 : {
4266 : /* snprintf() doesn't understand the '%n'
4267 : directive. */
4268 : if (fbp[1] != '\0')
4269 0 : {
4270 52 : /* Don't use the '%n' directive; instead, look
4271 : at the snprintf() return value. */
4272 : fbp[1] = '\0';
4273 : continue;
4274 : }
4275 999 : else
4276 : {
4277 : /* Look at the snprintf() return value. */
4278 : if (retcount < 0)
4279 : {
4280 : /* HP-UX 10.20 snprintf() is doubly deficient:
4281 : It doesn't understand the '%n' directive,
4282 0 : *and* it returns -1 (rather than the length
4283 0 : that would have been required) when the
4284 0 : buffer is too small. */
4285 0 : size_t bigger_need =
4286 : xsum (xtimes (allocated, 2), 12);
4287 : ENSURE_ALLOCATION (bigger_need);
4288 999 : continue;
4289 : }
4290 : else
4291 : count = retcount;
4292 : }
4293 : }
4294 999 : #endif
4295 :
4296 0 : /* Attempt to handle failure. */
4297 0 : if (count < 0)
4298 0 : {
4299 0 : if (!(result == resultbuf || result == NULL))
4300 0 : free (result);
4301 0 : if (buf_malloced != NULL)
4302 0 : free (buf_malloced);
4303 : CLEANUP ();
4304 : errno = EINVAL;
4305 : return NULL;
4306 : }
4307 :
4308 : #if USE_SNPRINTF
4309 : /* Handle overflow of the allocated buffer.
4310 : If such an overflow occurs, a C99 compliant snprintf()
4311 999 : returns a count >= maxlen. However, a non-compliant
4312 : snprintf() function returns only count = maxlen - 1. To
4313 : cover both cases, test whether count >= maxlen - 1. */
4314 : if ((unsigned int) count + 1 >= maxlen)
4315 : {
4316 52 : /* If maxlen already has attained its allowed maximum,
4317 0 : allocating more memory will not increase maxlen.
4318 : Instead of looping, bail out. */
4319 : if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
4320 : goto overflow;
4321 : else
4322 : {
4323 : /* Need at least (count + 1) * sizeof (TCHAR_T)
4324 : bytes. (The +1 is for the trailing NUL.)
4325 : But ask for (count + 2) * sizeof (TCHAR_T)
4326 : bytes, so that in the next round, we likely get
4327 : maxlen > (unsigned int) count + 1
4328 : and so we don't get here again.
4329 52 : And allocate proportionally, to avoid looping
4330 104 : eternally if snprintf() reports a too small
4331 52 : count. */
4332 : size_t n =
4333 : xmax (xsum (length,
4334 52 : ((unsigned int) count + 2
4335 : + TCHARS_PER_DCHAR - 1)
4336 52 : / TCHARS_PER_DCHAR),
4337 52 : xtimes (allocated, 2));
4338 :
4339 : ENSURE_ALLOCATION (n);
4340 : continue;
4341 : }
4342 : }
4343 : #endif
4344 :
4345 : #if NEED_PRINTF_UNBOUNDED_PRECISION
4346 : if (prec_ourselves)
4347 : {
4348 : /* Handle the precision. */
4349 : TCHAR_T *prec_ptr =
4350 : # if USE_SNPRINTF
4351 : (TCHAR_T *) (result + length);
4352 : # else
4353 : tmp;
4354 : # endif
4355 : size_t prefix_count;
4356 : size_t move;
4357 :
4358 : prefix_count = 0;
4359 : /* Put the additional zeroes after the sign. */
4360 : if (count >= 1
4361 : && (*prec_ptr == '-' || *prec_ptr == '+'
4362 : || *prec_ptr == ' '))
4363 : prefix_count = 1;
4364 : /* Put the additional zeroes after the 0x prefix if
4365 : (flags & FLAG_ALT) || (dp->conversion == 'p'). */
4366 : else if (count >= 2
4367 : && prec_ptr[0] == '0'
4368 : && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
4369 : prefix_count = 2;
4370 :
4371 : move = count - prefix_count;
4372 : if (precision > move)
4373 : {
4374 : /* Insert zeroes. */
4375 : size_t insert = precision - move;
4376 : TCHAR_T *prec_end;
4377 :
4378 : # if USE_SNPRINTF
4379 : size_t n =
4380 : xsum (length,
4381 : (count + insert + TCHARS_PER_DCHAR - 1)
4382 : / TCHARS_PER_DCHAR);
4383 : length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
4384 : ENSURE_ALLOCATION (n);
4385 : length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
4386 : prec_ptr = (TCHAR_T *) (result + length);
4387 : # endif
4388 :
4389 : prec_end = prec_ptr + count;
4390 : prec_ptr += prefix_count;
4391 :
4392 : while (prec_end > prec_ptr)
4393 : {
4394 : prec_end--;
4395 : prec_end[insert] = prec_end[0];
4396 : }
4397 :
4398 : prec_end += insert;
4399 : do
4400 : *--prec_end = '0';
4401 : while (prec_end > prec_ptr);
4402 :
4403 : count += insert;
4404 : }
4405 : }
4406 : #endif
4407 :
4408 : #if !USE_SNPRINTF
4409 : if (count >= tmp_length)
4410 : /* tmp_length was incorrectly calculated - fix the
4411 : code above! */
4412 : abort ();
4413 : #endif
4414 :
4415 : #if !DCHAR_IS_TCHAR
4416 : /* Convert from TCHAR_T[] to DCHAR_T[]. */
4417 : if (dp->conversion == 'c' || dp->conversion == 's')
4418 : {
4419 : /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
4420 : TYPE_WIDE_STRING.
4421 : The result string is not certainly ASCII. */
4422 : const TCHAR_T *tmpsrc;
4423 : DCHAR_T *tmpdst;
4424 : size_t tmpdst_len;
4425 : /* This code assumes that TCHAR_T is 'char'. */
4426 : typedef int TCHAR_T_verify
4427 : [2 * (sizeof (TCHAR_T) == 1) - 1];
4428 : # if USE_SNPRINTF
4429 : tmpsrc = (TCHAR_T *) (result + length);
4430 : # else
4431 : tmpsrc = tmp;
4432 : # endif
4433 : tmpdst = NULL;
4434 : tmpdst_len = 0;
4435 : if (DCHAR_CONV_FROM_ENCODING (locale_charset (),
4436 : iconveh_question_mark,
4437 : tmpsrc, count,
4438 : NULL,
4439 : &tmpdst, &tmpdst_len)
4440 : < 0)
4441 : {
4442 : int saved_errno = errno;
4443 : if (!(result == resultbuf || result == NULL))
4444 : free (result);
4445 : if (buf_malloced != NULL)
4446 : free (buf_malloced);
4447 : CLEANUP ();
4448 : errno = saved_errno;
4449 : return NULL;
4450 : }
4451 : ENSURE_ALLOCATION (xsum (length, tmpdst_len));
4452 : DCHAR_CPY (result + length, tmpdst, tmpdst_len);
4453 : free (tmpdst);
4454 : count = tmpdst_len;
4455 : }
4456 : else
4457 : {
4458 : /* The result string is ASCII.
4459 : Simple 1:1 conversion. */
4460 : # if USE_SNPRINTF
4461 : /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
4462 : no-op conversion, in-place on the array starting
4463 : at (result + length). */
4464 : if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
4465 : # endif
4466 : {
4467 : const TCHAR_T *tmpsrc;
4468 : DCHAR_T *tmpdst;
4469 : size_t n;
4470 :
4471 : # if USE_SNPRINTF
4472 : if (result == resultbuf)
4473 : {
4474 : tmpsrc = (TCHAR_T *) (result + length);
4475 : /* ENSURE_ALLOCATION will not move tmpsrc
4476 : (because it's part of resultbuf). */
4477 : ENSURE_ALLOCATION (xsum (length, count));
4478 : }
4479 : else
4480 : {
4481 : /* ENSURE_ALLOCATION will move the array
4482 : (because it uses realloc(). */
4483 : ENSURE_ALLOCATION (xsum (length, count));
4484 : tmpsrc = (TCHAR_T *) (result + length);
4485 : }
4486 : # else
4487 : tmpsrc = tmp;
4488 : ENSURE_ALLOCATION (xsum (length, count));
4489 : # endif
4490 : tmpdst = result + length;
4491 : /* Copy backwards, because of overlapping. */
4492 : tmpsrc += count;
4493 : tmpdst += count;
4494 : for (n = count; n > 0; n--)
4495 : *--tmpdst = (unsigned char) *--tmpsrc;
4496 : }
4497 : }
4498 : #endif
4499 :
4500 : #if DCHAR_IS_TCHAR && !USE_SNPRINTF
4501 : /* Make room for the result. */
4502 : if (count > allocated - length)
4503 : {
4504 : /* Need at least count elements. But allocate
4505 : proportionally. */
4506 : size_t n =
4507 : xmax (xsum (length, count), xtimes (allocated, 2));
4508 :
4509 : ENSURE_ALLOCATION (n);
4510 : }
4511 : #endif
4512 :
4513 : /* Here count <= allocated - length. */
4514 :
4515 : /* Perform padding. */
4516 : #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4517 : if (pad_ourselves && has_width)
4518 : {
4519 : size_t w;
4520 : # if ENABLE_UNISTDIO
4521 : /* Outside POSIX, it's preferrable to compare the width
4522 : against the number of _characters_ of the converted
4523 : value. */
4524 : w = DCHAR_MBSNLEN (result + length, count);
4525 : # else
4526 : /* The width is compared against the number of _bytes_
4527 : of the converted value, says POSIX. */
4528 : w = count;
4529 : # endif
4530 : if (w < width)
4531 : {
4532 : size_t pad = width - w;
4533 :
4534 : /* Make room for the result. */
4535 : if (xsum (count, pad) > allocated - length)
4536 : {
4537 : /* Need at least count + pad elements. But
4538 : allocate proportionally. */
4539 : size_t n =
4540 : xmax (xsum3 (length, count, pad),
4541 : xtimes (allocated, 2));
4542 :
4543 : # if USE_SNPRINTF
4544 : length += count;
4545 : ENSURE_ALLOCATION (n);
4546 : length -= count;
4547 : # else
4548 : ENSURE_ALLOCATION (n);
4549 : # endif
4550 : }
4551 : /* Here count + pad <= allocated - length. */
4552 :
4553 : {
4554 : # if !DCHAR_IS_TCHAR || USE_SNPRINTF
4555 : DCHAR_T * const rp = result + length;
4556 : # else
4557 : DCHAR_T * const rp = tmp;
4558 : # endif
4559 : DCHAR_T *p = rp + count;
4560 : DCHAR_T *end = p + pad;
4561 : DCHAR_T *pad_ptr;
4562 : # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4563 : if (dp->conversion == 'c'
4564 : || dp->conversion == 's')
4565 : /* No zero-padding for string directives. */
4566 : pad_ptr = NULL;
4567 : else
4568 : # endif
4569 : {
4570 : pad_ptr = (*rp == '-' ? rp + 1 : rp);
4571 : /* No zero-padding of "inf" and "nan". */
4572 : if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
4573 : || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
4574 : pad_ptr = NULL;
4575 : }
4576 : /* The generated string now extends from rp to p,
4577 : with the zero padding insertion point being at
4578 : pad_ptr. */
4579 :
4580 : count = count + pad; /* = end - rp */
4581 :
4582 : if (flags & FLAG_LEFT)
4583 : {
4584 : /* Pad with spaces on the right. */
4585 : for (; pad > 0; pad--)
4586 : *p++ = ' ';
4587 : }
4588 : else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4589 : {
4590 : /* Pad with zeroes. */
4591 : DCHAR_T *q = end;
4592 :
4593 : while (p > pad_ptr)
4594 : *--q = *--p;
4595 : for (; pad > 0; pad--)
4596 : *p++ = '0';
4597 : }
4598 : else
4599 : {
4600 : /* Pad with spaces on the left. */
4601 : DCHAR_T *q = end;
4602 :
4603 : while (p > rp)
4604 : *--q = *--p;
4605 : for (; pad > 0; pad--)
4606 : *p++ = ' ';
4607 : }
4608 : }
4609 : }
4610 : }
4611 : #endif
4612 :
4613 : /* Here still count <= allocated - length. */
4614 :
4615 : #if !DCHAR_IS_TCHAR || USE_SNPRINTF
4616 : /* The snprintf() result did fit. */
4617 : #else
4618 : /* Append the sprintf() result. */
4619 : memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4620 : #endif
4621 : #if !USE_SNPRINTF
4622 : if (tmp != tmpbuf)
4623 : free (tmp);
4624 : #endif
4625 :
4626 : #if NEED_PRINTF_DIRECTIVE_F
4627 : if (dp->conversion == 'F')
4628 : {
4629 : /* Convert the %f result to upper case for %F. */
4630 : DCHAR_T *rp = result + length;
4631 : size_t rc;
4632 : for (rc = count; rc > 0; rc--, rp++)
4633 : if (*rp >= 'a' && *rp <= 'z')
4634 : *rp = *rp - 'a' + 'A';
4635 947 : }
4636 947 : #endif
4637 :
4638 : length += count;
4639 : break;
4640 : }
4641 : }
4642 : }
4643 731 : }
4644 731 :
4645 : /* Add the final NUL. */
4646 731 : ENSURE_ALLOCATION (xsum (length, 1));
4647 : result[length] = '\0';
4648 :
4649 : if (result != resultbuf && length + 1 < allocated)
4650 : {
4651 552 : /* Shrink the allocated memory if possible. */
4652 552 : DCHAR_T *memory;
4653 552 :
4654 : memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
4655 : if (memory != NULL)
4656 731 : result = memory;
4657 0 : }
4658 731 :
4659 731 : if (buf_malloced != NULL)
4660 : free (buf_malloced);
4661 : CLEANUP ();
4662 : *lengthp = length;
4663 : /* Note that we can produce a big string of a length > INT_MAX. POSIX
4664 731 : says that snprintf() fails with errno = EOVERFLOW in this case, but
4665 : that's only because snprintf() returns an 'int'. This function does
4666 : not have this limitation. */
4667 0 : return result;
4668 0 :
4669 0 : #if USE_SNPRINTF
4670 0 : overflow:
4671 0 : if (!(result == resultbuf || result == NULL))
4672 0 : free (result);
4673 0 : if (buf_malloced != NULL)
4674 0 : free (buf_malloced);
4675 : CLEANUP ();
4676 : errno = EOVERFLOW;
4677 0 : return NULL;
4678 0 : #endif
4679 0 :
4680 0 : out_of_memory:
4681 0 : if (!(result == resultbuf || result == NULL))
4682 0 : free (result);
4683 0 : if (buf_malloced != NULL)
4684 0 : free (buf_malloced);
4685 0 : out_of_memory_1:
4686 : CLEANUP ();
4687 : errno = ENOMEM;
4688 : return NULL;
4689 : }
4690 : }
4691 :
4692 : #undef TCHARS_PER_DCHAR
4693 : #undef SNPRINTF
4694 : #undef USE_SNPRINTF
4695 : #undef DCHAR_CPY
4696 : #undef PRINTF_PARSE
4697 : #undef DIRECTIVES
4698 : #undef DIRECTIVE
4699 : #undef DCHAR_IS_TCHAR
4700 : #undef TCHAR_T
4701 : #undef DCHAR_T
4702 : #undef FCHAR_T
4703 : #undef VASNPRINTF
|