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