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