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