265
|
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
|