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