Mercurial > hg-old > index.cgi
comparison lib/vasnprintf.c @ 272:d5392bb5da3c 2.5
Added generated files
author | lost |
---|---|
date | Sun, 16 Aug 2009 17:16:49 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
271:3b793ba7a6c6 | 272:d5392bb5da3c |
---|---|
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 |