VirtualBox

source: kBuild/vendor/grep/current/gnulib-tests/vasnprintf.c

Last change on this file was 3529, checked in by bird, 3 years ago

Imported grep 3.7 from grep-3.7.tar.gz (sha256: c22b0cf2d4f6bbe599c902387e8058990e1eee99aef333a203829e5fd3dbb342), applying minimal auto-props.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette