]> git.ipfire.org Git - thirdparty/glibc.git/blame - stdio-common/printf_fp.c
aarch64: Remove ld.so __tls_get_addr plt usage
[thirdparty/glibc.git] / stdio-common / printf_fp.c
CommitLineData
28f540f4 1/* Floating point output for `printf'.
dff8da6b 2 Copyright (C) 1995-2024 Free Software Foundation, Inc.
4c02bf1a 3
feb3c934 4 This file is part of the GNU C Library.
feb3c934
UD
5
6 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
feb3c934
UD
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 14 Lesser General Public License for more details.
feb3c934 15
41bdb6e2 16 You should have received a copy of the GNU Lesser General Public
59ba27a6 17 License along with the GNU C Library; if not, see
5a82c748 18 <https://www.gnu.org/licenses/>. */
28f540f4 19
3f92886a
RM
20/* The gmp headers need some configuration frobs. */
21#define HAVE_ALLOCA 1
22
d10b132b 23#include <array_length.h>
8a7455e7 24#include <libioP.h>
28f540f4 25#include <alloca.h>
28f540f4
RM
26#include <ctype.h>
27#include <float.h>
28#include <gmp-mparam.h>
48896b9d 29#include <gmp.h>
003c9895 30#include <ieee754.h>
8f2ece69
UD
31#include <stdlib/gmp-impl.h>
32#include <stdlib/longlong.h>
33#include <stdlib/fpioconst.h>
34#include <locale/localeinfo.h>
933e73fa 35#include <limits.h>
28f540f4
RM
36#include <math.h>
37#include <printf.h>
28f540f4
RM
38#include <string.h>
39#include <unistd.h>
40#include <stdlib.h>
8d8c6efa 41#include <wchar.h>
784761be
JM
42#include <stdbool.h>
43#include <rounding-mode.h>
e88b9f0e
FW
44#include <printf_buffer.h>
45#include <printf_buffer_to_file.h>
46#include <grouping_iterator.h>
28f540f4 47
28f540f4
RM
48#include <assert.h>
49
28f540f4
RM
50/* We use the GNU MP library to handle large numbers.
51
52 An MP variable occupies a varying number of entries in its array. We keep
53 track of this number for efficiency reasons. Otherwise we would always
54 have to process the whole array. */
0e3426bb 55#define MPN_VAR(name) mp_limb_t *name; mp_size_t name##size
28f540f4
RM
56
57#define MPN_ASSIGN(dst,src) \
0e3426bb 58 memcpy (dst, src, (dst##size = src##size) * sizeof (mp_limb_t))
28f540f4
RM
59#define MPN_GE(u,v) \
60 (u##size > v##size || (u##size == v##size && __mpn_cmp (u, v, u##size) >= 0))
61
28f540f4
RM
62extern mp_size_t __mpn_extract_double (mp_ptr res_ptr, mp_size_t size,
63 int *expt, int *is_neg,
64 double value);
65extern mp_size_t __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
66 int *expt, int *is_neg,
67 long double value);
68
28f540f4 69
8e257a29
KS
70struct hack_digit_param
71{
72 /* Sign of the exponent. */
73 int expsign;
74 /* The type of output format that will be used: 'e'/'E' or 'f'. */
75 int type;
76 /* and the exponent. */
77 int exponent;
78 /* The fraction of the floting-point value in question */
79 MPN_VAR(frac);
80 /* Scaling factor. */
81 MPN_VAR(scale);
82 /* Temporary bignum value. */
83 MPN_VAR(tmp);
84};
85
e88b9f0e 86static char
8e257a29
KS
87hack_digit (struct hack_digit_param *p)
88{
89 mp_limb_t hi;
90
91 if (p->expsign != 0 && p->type == 'f' && p->exponent-- > 0)
92 hi = 0;
93 else if (p->scalesize == 0)
94 {
95 hi = p->frac[p->fracsize - 1];
96 p->frac[p->fracsize - 1] = __mpn_mul_1 (p->frac, p->frac,
97 p->fracsize - 1, 10);
98 }
99 else
100 {
101 if (p->fracsize < p->scalesize)
102 hi = 0;
103 else
104 {
105 hi = mpn_divmod (p->tmp, p->frac, p->fracsize,
106 p->scale, p->scalesize);
107 p->tmp[p->fracsize - p->scalesize] = hi;
108 hi = p->tmp[0];
109
110 p->fracsize = p->scalesize;
111 while (p->fracsize != 0 && p->frac[p->fracsize - 1] == 0)
112 --p->fracsize;
113 if (p->fracsize == 0)
114 {
115 /* We're not prepared for an mpn variable with zero
116 limbs. */
117 p->fracsize = 1;
e88b9f0e 118 return '0' + hi;
8e257a29
KS
119 }
120 }
121
122 mp_limb_t _cy = __mpn_mul_1 (p->frac, p->frac, p->fracsize, 10);
123 if (_cy != 0)
124 p->frac[p->fracsize++] = _cy;
125 }
126
e88b9f0e 127 return '0' + hi;
8e257a29 128}
28f540f4 129
e88b9f0e
FW
130/* Version that performs grouping (if INFO->group && THOUSANDS_SEP != 0),
131 but not i18n digit translation.
132
133 The output buffer is always multibyte (not wide) at this stage.
134 Wide conversion and i18n digit translation happen later, with a
135 temporary buffer. To prepare for that, THOUSANDS_SEP_LENGTH is the
136 final length of the thousands separator. */
137static void
138__printf_fp_buffer_1 (struct __printf_buffer *buf, locale_t loc,
139 char thousands_sep, char decimal,
140 unsigned int thousands_sep_length,
141 const struct printf_info *info,
142 const void *const *args)
28f540f4
RM
143{
144 /* The floating-point value to output. */
145 union
146 {
147 double dbl;
8b164787 148 long double ldbl;
cf2046ec
GG
149#if __HAVE_DISTINCT_FLOAT128
150 _Float128 f128;
151#endif
28f540f4
RM
152 }
153 fpnum;
154
28f540f4 155 /* "NaN" or "Inf" for the special cases. */
0e3426bb 156 const char *special = NULL;
e88b9f0e
FW
157
158 /* Used to determine grouping rules. */
159 int lc_category = info->extra ? LC_MONETARY : LC_NUMERIC;
28f540f4 160
cf2046ec
GG
161 /* When _Float128 is enabled in the library and ABI-distinct from long
162 double, we need mp_limbs enough for any of them. */
163#if __HAVE_DISTINCT_FLOAT128
164# define GREATER_MANT_DIG FLT128_MANT_DIG
165#else
166# define GREATER_MANT_DIG LDBL_MANT_DIG
167#endif
28f540f4
RM
168 /* We need just a few limbs for the input before shifting to the right
169 position. */
cf2046ec
GG
170 mp_limb_t fp_input[(GREATER_MANT_DIG + BITS_PER_MP_LIMB - 1)
171 / BITS_PER_MP_LIMB];
28f540f4 172 /* We need to shift the contents of fp_input by this amount of bits. */
ba1ffaa1 173 int to_shift = 0;
28f540f4 174
8e257a29 175 struct hack_digit_param p;
28f540f4
RM
176 /* Sign of float number. */
177 int is_neg = 0;
178
28f540f4 179 /* General helper (carry limb). */
0e3426bb 180 mp_limb_t cy;
28f540f4 181
c7df983c 182 /* Buffer in which we produce the output. */
e88b9f0e 183 char *wbuffer = NULL;
90663e9c 184 /* Flag whether wbuffer and buffer are malloc'ed or not. */
c7df983c
UD
185 int buffer_malloced = 0;
186
8e257a29 187 p.expsign = 0;
28f540f4 188
aab0f374
GG
189#define PRINTF_FP_FETCH(FLOAT, VAR, SUFFIX, MANT_DIG) \
190 { \
191 (VAR) = *(const FLOAT *) args[0]; \
192 \
193 /* Check for special values: not a number or infinity. */ \
194 if (isnan (VAR)) \
195 { \
196 is_neg = signbit (VAR); \
197 if (isupper (info->spec)) \
e88b9f0e 198 special = "NAN"; \
aab0f374 199 else \
e88b9f0e 200 special = "nan"; \
aab0f374
GG
201 } \
202 else if (isinf (VAR)) \
203 { \
204 is_neg = signbit (VAR); \
205 if (isupper (info->spec)) \
e88b9f0e 206 special = "INF"; \
aab0f374 207 else \
e88b9f0e 208 special = "inf"; \
aab0f374
GG
209 } \
210 else \
211 { \
212 p.fracsize = __mpn_extract_##SUFFIX \
d10b132b 213 (fp_input, array_length (fp_input), \
aab0f374
GG
214 &p.exponent, &is_neg, VAR); \
215 to_shift = 1 + p.fracsize * BITS_PER_MP_LIMB - MANT_DIG; \
216 } \
217 }
218
28f540f4 219 /* Fetch the argument value. */
cf2046ec
GG
220#if __HAVE_DISTINCT_FLOAT128
221 if (info->is_binary128)
222 PRINTF_FP_FETCH (_Float128, fpnum.f128, float128, FLT128_MANT_DIG)
223 else
224#endif
f98b4bbd 225#ifndef __NO_LONG_DOUBLE_MATH
28f540f4 226 if (info->is_long_double && sizeof (long double) > sizeof (double))
aab0f374 227 PRINTF_FP_FETCH (long double, fpnum.ldbl, long_double, LDBL_MANT_DIG)
28f540f4 228 else
aab0f374
GG
229#endif
230 PRINTF_FP_FETCH (double, fpnum.dbl, double, DBL_MANT_DIG)
28f540f4 231
aab0f374 232#undef PRINTF_FP_FETCH
28f540f4
RM
233
234 if (special)
235 {
1f205a47 236 int width = info->width;
28f540f4
RM
237
238 if (is_neg || info->showsign || info->space)
239 --width;
240 width -= 3;
241
e88b9f0e
FW
242 if (!info->left)
243 __printf_buffer_pad (buf, ' ', width);
28f540f4
RM
244
245 if (is_neg)
e88b9f0e 246 __printf_buffer_putc (buf, '-');
28f540f4 247 else if (info->showsign)
e88b9f0e 248 __printf_buffer_putc (buf, '+');
28f540f4 249 else if (info->space)
e88b9f0e 250 __printf_buffer_putc (buf, ' ');
28f540f4 251
e88b9f0e 252 __printf_buffer_puts (buf, special);
28f540f4 253
e88b9f0e
FW
254 if (info->left)
255 __printf_buffer_pad (buf, ' ', width);
28f540f4 256
e88b9f0e 257 return;
28f540f4
RM
258 }
259
260
8e257a29 261 /* We need three multiprecision variables. Now that we have the p.exponent
28f540f4
RM
262 of the number we can allocate the needed memory. It would be more
263 efficient to use variables of the fixed maximum size but because this
264 would be really big it could lead to memory problems. */
265 {
0e9be4db 266 mp_size_t bignum_size = ((abs (p.exponent) + BITS_PER_MP_LIMB - 1)
9ce0ecbe 267 / BITS_PER_MP_LIMB
cf2046ec
GG
268 + (GREATER_MANT_DIG / BITS_PER_MP_LIMB > 2
269 ? 8 : 4))
9ce0ecbe 270 * sizeof (mp_limb_t);
8e257a29
KS
271 p.frac = (mp_limb_t *) alloca (bignum_size);
272 p.tmp = (mp_limb_t *) alloca (bignum_size);
273 p.scale = (mp_limb_t *) alloca (bignum_size);
28f540f4
RM
274 }
275
276 /* We now have to distinguish between numbers with positive and negative
277 exponents because the method used for the one is not applicable/efficient
278 for the other. */
8e257a29
KS
279 p.scalesize = 0;
280 if (p.exponent > 2)
28f540f4 281 {
77a58cad 282 /* |FP| >= 8.0. */
28f540f4 283 int scaleexpo = 0;
cf2046ec
GG
284 int explog;
285#if __HAVE_DISTINCT_FLOAT128
286 if (info->is_binary128)
287 explog = FLT128_MAX_10_EXP_LOG;
288 else
289 explog = LDBL_MAX_10_EXP_LOG;
290#else
291 explog = LDBL_MAX_10_EXP_LOG;
292#endif
28f540f4 293 int exp10 = 0;
c4563d2d 294 const struct mp_power *powers = &_fpioconst_pow10[explog + 1];
28f540f4
RM
295 int cnt_h, cnt_l, i;
296
8e257a29 297 if ((p.exponent + to_shift) % BITS_PER_MP_LIMB == 0)
28f540f4 298 {
8e257a29
KS
299 MPN_COPY_DECR (p.frac + (p.exponent + to_shift) / BITS_PER_MP_LIMB,
300 fp_input, p.fracsize);
301 p.fracsize += (p.exponent + to_shift) / BITS_PER_MP_LIMB;
28f540f4
RM
302 }
303 else
304 {
34a5a146
JM
305 cy = __mpn_lshift (p.frac
306 + (p.exponent + to_shift) / BITS_PER_MP_LIMB,
8e257a29
KS
307 fp_input, p.fracsize,
308 (p.exponent + to_shift) % BITS_PER_MP_LIMB);
309 p.fracsize += (p.exponent + to_shift) / BITS_PER_MP_LIMB;
28f540f4 310 if (cy)
8e257a29 311 p.frac[p.fracsize++] = cy;
28f540f4 312 }
8e257a29 313 MPN_ZERO (p.frac, (p.exponent + to_shift) / BITS_PER_MP_LIMB);
28f540f4 314
c4563d2d 315 assert (powers > &_fpioconst_pow10[0]);
28f540f4
RM
316 do
317 {
c4563d2d 318 --powers;
28f540f4
RM
319
320 /* The number of the product of two binary numbers with n and m
321 bits respectively has m+n or m+n-1 bits. */
8e257a29 322 if (p.exponent >= scaleexpo + powers->p_expo - 1)
28f540f4 323 {
8e257a29 324 if (p.scalesize == 0)
c4563d2d 325 {
cf2046ec
GG
326#if __HAVE_DISTINCT_FLOAT128
327 if ((FLT128_MANT_DIG
328 > _FPIO_CONST_OFFSET * BITS_PER_MP_LIMB)
329 && info->is_binary128)
330 {
331#define _FLT128_FPIO_CONST_SHIFT \
332 (((FLT128_MANT_DIG + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB) \
333 - _FPIO_CONST_OFFSET)
334 /* 64bit const offset is not enough for
335 IEEE 854 quad long double (_Float128). */
336 p.tmpsize = powers->arraysize + _FLT128_FPIO_CONST_SHIFT;
337 memcpy (p.tmp + _FLT128_FPIO_CONST_SHIFT,
338 &__tens[powers->arrayoff],
339 p.tmpsize * sizeof (mp_limb_t));
340 MPN_ZERO (p.tmp, _FLT128_FPIO_CONST_SHIFT);
341 /* Adjust p.exponent, as scaleexpo will be this much
342 bigger too. */
343 p.exponent += _FLT128_FPIO_CONST_SHIFT * BITS_PER_MP_LIMB;
344 }
345 else
346#endif /* __HAVE_DISTINCT_FLOAT128 */
abfbdde1
UD
347#ifndef __NO_LONG_DOUBLE_MATH
348 if (LDBL_MANT_DIG > _FPIO_CONST_OFFSET * BITS_PER_MP_LIMB
349 && info->is_long_double)
350 {
351#define _FPIO_CONST_SHIFT \
352 (((LDBL_MANT_DIG + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB) \
353 - _FPIO_CONST_OFFSET)
354 /* 64bit const offset is not enough for
355 IEEE quad long double. */
8e257a29
KS
356 p.tmpsize = powers->arraysize + _FPIO_CONST_SHIFT;
357 memcpy (p.tmp + _FPIO_CONST_SHIFT,
abfbdde1 358 &__tens[powers->arrayoff],
8e257a29
KS
359 p.tmpsize * sizeof (mp_limb_t));
360 MPN_ZERO (p.tmp, _FPIO_CONST_SHIFT);
361 /* Adjust p.exponent, as scaleexpo will be this much
52e1b618 362 bigger too. */
8e257a29 363 p.exponent += _FPIO_CONST_SHIFT * BITS_PER_MP_LIMB;
abfbdde1
UD
364 }
365 else
366#endif
367 {
8e257a29
KS
368 p.tmpsize = powers->arraysize;
369 memcpy (p.tmp, &__tens[powers->arrayoff],
370 p.tmpsize * sizeof (mp_limb_t));
abfbdde1 371 }
c4563d2d 372 }
28f540f4
RM
373 else
374 {
8e257a29 375 cy = __mpn_mul (p.tmp, p.scale, p.scalesize,
c4563d2d
UD
376 &__tens[powers->arrayoff
377 + _FPIO_CONST_OFFSET],
378 powers->arraysize - _FPIO_CONST_OFFSET);
34a5a146
JM
379 p.tmpsize = p.scalesize
380 + powers->arraysize - _FPIO_CONST_OFFSET;
28f540f4 381 if (cy == 0)
8e257a29 382 --p.tmpsize;
28f540f4
RM
383 }
384
8e257a29 385 if (MPN_GE (p.frac, p.tmp))
28f540f4
RM
386 {
387 int cnt;
8e257a29
KS
388 MPN_ASSIGN (p.scale, p.tmp);
389 count_leading_zeros (cnt, p.scale[p.scalesize - 1]);
390 scaleexpo = (p.scalesize - 2) * BITS_PER_MP_LIMB - cnt - 1;
28f540f4
RM
391 exp10 |= 1 << explog;
392 }
393 }
394 --explog;
395 }
c4563d2d 396 while (powers > &_fpioconst_pow10[0]);
8e257a29 397 p.exponent = exp10;
28f540f4
RM
398
399 /* Optimize number representations. We want to represent the numbers
400 with the lowest number of bytes possible without losing any
401 bytes. Also the highest bit in the scaling factor has to be set
402 (this is a requirement of the MPN division routines). */
8e257a29 403 if (p.scalesize > 0)
28f540f4
RM
404 {
405 /* Determine minimum number of zero bits at the end of
406 both numbers. */
8e257a29 407 for (i = 0; p.scale[i] == 0 && p.frac[i] == 0; i++)
28f540f4
RM
408 ;
409
410 /* Determine number of bits the scaling factor is misplaced. */
8e257a29 411 count_leading_zeros (cnt_h, p.scale[p.scalesize - 1]);
28f540f4
RM
412
413 if (cnt_h == 0)
414 {
415 /* The highest bit of the scaling factor is already set. So
416 we only have to remove the trailing empty limbs. */
417 if (i > 0)
418 {
8e257a29
KS
419 MPN_COPY_INCR (p.scale, p.scale + i, p.scalesize - i);
420 p.scalesize -= i;
421 MPN_COPY_INCR (p.frac, p.frac + i, p.fracsize - i);
422 p.fracsize -= i;
28f540f4
RM
423 }
424 }
425 else
426 {
8e257a29 427 if (p.scale[i] != 0)
28f540f4 428 {
8e257a29
KS
429 count_trailing_zeros (cnt_l, p.scale[i]);
430 if (p.frac[i] != 0)
28f540f4
RM
431 {
432 int cnt_l2;
8e257a29 433 count_trailing_zeros (cnt_l2, p.frac[i]);
28f540f4
RM
434 if (cnt_l2 < cnt_l)
435 cnt_l = cnt_l2;
436 }
437 }
438 else
8e257a29 439 count_trailing_zeros (cnt_l, p.frac[i]);
28f540f4
RM
440
441 /* Now shift the numbers to their optimal position. */
442 if (i == 0 && BITS_PER_MP_LIMB - cnt_h > cnt_l)
443 {
444 /* We cannot save any memory. So just roll both numbers
445 so that the scaling factor has its highest bit set. */
446
8e257a29
KS
447 (void) __mpn_lshift (p.scale, p.scale, p.scalesize, cnt_h);
448 cy = __mpn_lshift (p.frac, p.frac, p.fracsize, cnt_h);
28f540f4 449 if (cy != 0)
8e257a29 450 p.frac[p.fracsize++] = cy;
28f540f4
RM
451 }
452 else if (BITS_PER_MP_LIMB - cnt_h <= cnt_l)
453 {
454 /* We can save memory by removing the trailing zero limbs
455 and by packing the non-zero limbs which gain another
456 free one. */
457
8e257a29 458 (void) __mpn_rshift (p.scale, p.scale + i, p.scalesize - i,
28f540f4 459 BITS_PER_MP_LIMB - cnt_h);
8e257a29
KS
460 p.scalesize -= i + 1;
461 (void) __mpn_rshift (p.frac, p.frac + i, p.fracsize - i,
28f540f4 462 BITS_PER_MP_LIMB - cnt_h);
8e257a29 463 p.fracsize -= p.frac[p.fracsize - i - 1] == 0 ? i + 1 : i;
28f540f4
RM
464 }
465 else
466 {
467 /* We can only save the memory of the limbs which are zero.
468 The non-zero parts occupy the same number of limbs. */
469
8e257a29
KS
470 (void) __mpn_rshift (p.scale, p.scale + (i - 1),
471 p.scalesize - (i - 1),
28f540f4 472 BITS_PER_MP_LIMB - cnt_h);
8e257a29
KS
473 p.scalesize -= i;
474 (void) __mpn_rshift (p.frac, p.frac + (i - 1),
475 p.fracsize - (i - 1),
28f540f4 476 BITS_PER_MP_LIMB - cnt_h);
8e257a29
KS
477 p.fracsize -=
478 p.frac[p.fracsize - (i - 1) - 1] == 0 ? i : i - 1;
28f540f4
RM
479 }
480 }
481 }
482 }
8e257a29 483 else if (p.exponent < 0)
28f540f4
RM
484 {
485 /* |FP| < 1.0. */
486 int exp10 = 0;
cf2046ec
GG
487 int explog;
488#if __HAVE_DISTINCT_FLOAT128
489 if (info->is_binary128)
490 explog = FLT128_MAX_10_EXP_LOG;
491 else
492 explog = LDBL_MAX_10_EXP_LOG;
493#else
494 explog = LDBL_MAX_10_EXP_LOG;
495#endif
c4563d2d 496 const struct mp_power *powers = &_fpioconst_pow10[explog + 1];
28f540f4
RM
497
498 /* Now shift the input value to its right place. */
8e257a29
KS
499 cy = __mpn_lshift (p.frac, fp_input, p.fracsize, to_shift);
500 p.frac[p.fracsize++] = cy;
501 assert (cy == 1 || (p.frac[p.fracsize - 2] == 0 && p.frac[0] == 0));
28f540f4 502
8e257a29
KS
503 p.expsign = 1;
504 p.exponent = -p.exponent;
28f540f4 505
c4563d2d 506 assert (powers != &_fpioconst_pow10[0]);
28f540f4
RM
507 do
508 {
c4563d2d 509 --powers;
28f540f4 510
8e257a29 511 if (p.exponent >= powers->m_expo)
28f540f4
RM
512 {
513 int i, incr, cnt_h, cnt_l;
0e3426bb 514 mp_limb_t topval[2];
28f540f4
RM
515
516 /* The __mpn_mul function expects the first argument to be
517 bigger than the second. */
8e257a29
KS
518 if (p.fracsize < powers->arraysize - _FPIO_CONST_OFFSET)
519 cy = __mpn_mul (p.tmp, &__tens[powers->arrayoff
c4563d2d
UD
520 + _FPIO_CONST_OFFSET],
521 powers->arraysize - _FPIO_CONST_OFFSET,
8e257a29 522 p.frac, p.fracsize);
28f540f4 523 else
8e257a29 524 cy = __mpn_mul (p.tmp, p.frac, p.fracsize,
c4563d2d
UD
525 &__tens[powers->arrayoff + _FPIO_CONST_OFFSET],
526 powers->arraysize - _FPIO_CONST_OFFSET);
8e257a29 527 p.tmpsize = p.fracsize + powers->arraysize - _FPIO_CONST_OFFSET;
28f540f4 528 if (cy == 0)
8e257a29 529 --p.tmpsize;
28f540f4 530
8e257a29
KS
531 count_leading_zeros (cnt_h, p.tmp[p.tmpsize - 1]);
532 incr = (p.tmpsize - p.fracsize) * BITS_PER_MP_LIMB
28f540f4
RM
533 + BITS_PER_MP_LIMB - 1 - cnt_h;
534
c4563d2d 535 assert (incr <= powers->p_expo);
28f540f4 536
8e257a29 537 /* If we increased the p.exponent by exactly 3 we have to test
28f540f4
RM
538 for overflow. This is done by comparing with 10 shifted
539 to the right position. */
8e257a29 540 if (incr == p.exponent + 3)
6e4c40ba
UD
541 {
542 if (cnt_h <= BITS_PER_MP_LIMB - 4)
543 {
544 topval[0] = 0;
545 topval[1]
546 = ((mp_limb_t) 10) << (BITS_PER_MP_LIMB - 4 - cnt_h);
547 }
548 else
549 {
550 topval[0] = ((mp_limb_t) 10) << (BITS_PER_MP_LIMB - 4);
551 topval[1] = 0;
552 (void) __mpn_lshift (topval, topval, 2,
553 BITS_PER_MP_LIMB - cnt_h);
554 }
555 }
28f540f4
RM
556
557 /* We have to be careful when multiplying the last factor.
558 If the result is greater than 1.0 be have to test it
559 against 10.0. If it is greater or equal to 10.0 the
560 multiplication was not valid. This is because we cannot
561 determine the number of bits in the result in advance. */
8e257a29 562 if (incr < p.exponent + 3
34a5a146
JM
563 || (incr == p.exponent + 3
564 && (p.tmp[p.tmpsize - 1] < topval[1]
565 || (p.tmp[p.tmpsize - 1] == topval[1]
566 && p.tmp[p.tmpsize - 2] < topval[0]))))
28f540f4
RM
567 {
568 /* The factor is right. Adapt binary and decimal
96aa2d94 569 exponents. */
8e257a29 570 p.exponent -= incr;
28f540f4
RM
571 exp10 |= 1 << explog;
572
573 /* If this factor yields a number greater or equal to
574 1.0, we must not shift the non-fractional digits down. */
8e257a29
KS
575 if (p.exponent < 0)
576 cnt_h += -p.exponent;
28f540f4
RM
577
578 /* Now we optimize the number representation. */
8e257a29 579 for (i = 0; p.tmp[i] == 0; ++i);
28f540f4
RM
580 if (cnt_h == BITS_PER_MP_LIMB - 1)
581 {
8e257a29
KS
582 MPN_COPY (p.frac, p.tmp + i, p.tmpsize - i);
583 p.fracsize = p.tmpsize - i;
28f540f4
RM
584 }
585 else
586 {
8e257a29 587 count_trailing_zeros (cnt_l, p.tmp[i]);
28f540f4
RM
588
589 /* Now shift the numbers to their optimal position. */
590 if (i == 0 && BITS_PER_MP_LIMB - 1 - cnt_h > cnt_l)
591 {
592 /* We cannot save any memory. Just roll the
593 number so that the leading digit is in a
6d52618b 594 separate limb. */
28f540f4 595
8e257a29
KS
596 cy = __mpn_lshift (p.frac, p.tmp, p.tmpsize,
597 cnt_h + 1);
598 p.fracsize = p.tmpsize + 1;
599 p.frac[p.fracsize - 1] = cy;
28f540f4
RM
600 }
601 else if (BITS_PER_MP_LIMB - 1 - cnt_h <= cnt_l)
602 {
8e257a29 603 (void) __mpn_rshift (p.frac, p.tmp + i, p.tmpsize - i,
28f540f4 604 BITS_PER_MP_LIMB - 1 - cnt_h);
8e257a29 605 p.fracsize = p.tmpsize - i;
28f540f4
RM
606 }
607 else
608 {
609 /* We can only save the memory of the limbs which
610 are zero. The non-zero parts occupy the same
611 number of limbs. */
612
8e257a29
KS
613 (void) __mpn_rshift (p.frac, p.tmp + (i - 1),
614 p.tmpsize - (i - 1),
28f540f4 615 BITS_PER_MP_LIMB - 1 - cnt_h);
8e257a29 616 p.fracsize = p.tmpsize - (i - 1);
28f540f4
RM
617 }
618 }
28f540f4
RM
619 }
620 }
621 --explog;
622 }
8e257a29 623 while (powers != &_fpioconst_pow10[1] && p.exponent > 0);
28f540f4 624 /* All factors but 10^-1 are tested now. */
8e257a29 625 if (p.exponent > 0)
28f540f4 626 {
19bc17a9
RM
627 int cnt_l;
628
8e257a29
KS
629 cy = __mpn_mul_1 (p.tmp, p.frac, p.fracsize, 10);
630 p.tmpsize = p.fracsize;
631 assert (cy == 0 || p.tmp[p.tmpsize - 1] < 20);
28f540f4 632
8e257a29
KS
633 count_trailing_zeros (cnt_l, p.tmp[0]);
634 if (cnt_l < MIN (4, p.exponent))
19bc17a9 635 {
8e257a29
KS
636 cy = __mpn_lshift (p.frac, p.tmp, p.tmpsize,
637 BITS_PER_MP_LIMB - MIN (4, p.exponent));
19bc17a9 638 if (cy != 0)
8e257a29 639 p.frac[p.tmpsize++] = cy;
19bc17a9
RM
640 }
641 else
8e257a29
KS
642 (void) __mpn_rshift (p.frac, p.tmp, p.tmpsize, MIN (4, p.exponent));
643 p.fracsize = p.tmpsize;
28f540f4 644 exp10 |= 1;
8e257a29 645 assert (p.frac[p.fracsize - 1] < 10);
28f540f4 646 }
8e257a29 647 p.exponent = exp10;
28f540f4
RM
648 }
649 else
650 {
651 /* This is a special case. We don't need a factor because the
b866373d 652 numbers are in the range of 1.0 <= |fp| < 8.0. We simply
28f540f4
RM
653 shift it to the right place and divide it by 1.0 to get the
654 leading digit. (Of course this division is not really made.) */
34a5a146
JM
655 assert (0 <= p.exponent && p.exponent < 3
656 && p.exponent + to_shift < BITS_PER_MP_LIMB);
28f540f4
RM
657
658 /* Now shift the input value to its right place. */
8e257a29
KS
659 cy = __mpn_lshift (p.frac, fp_input, p.fracsize, (p.exponent + to_shift));
660 p.frac[p.fracsize++] = cy;
661 p.exponent = 0;
28f540f4
RM
662 }
663
664 {
665 int width = info->width;
e88b9f0e 666 char *wstartp, *wcp;
9ca230d6 667 size_t chars_needed;
28f540f4
RM
668 int expscale;
669 int intdig_max, intdig_no = 0;
4c02bf1a
UD
670 int fracdig_min;
671 int fracdig_max;
28f540f4
RM
672 int dig_max;
673 int significant;
4c02bf1a 674 char spec = _tolower (info->spec);
28f540f4 675
4c02bf1a 676 if (spec == 'e')
28f540f4 677 {
8e257a29 678 p.type = info->spec;
28f540f4
RM
679 intdig_max = 1;
680 fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
9ca230d6 681 chars_needed = 1 + 1 + (size_t) fracdig_max + 1 + 1 + 4;
28f540f4
RM
682 /* d . ddd e +- ddd */
683 dig_max = INT_MAX; /* Unlimited. */
684 significant = 1; /* Does not matter here. */
685 }
4c02bf1a 686 else if (spec == 'f')
28f540f4 687 {
8e257a29 688 p.type = 'f';
28f540f4 689 fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
a3022b82
UD
690 dig_max = INT_MAX; /* Unlimited. */
691 significant = 1; /* Does not matter here. */
8e257a29 692 if (p.expsign == 0)
28f540f4 693 {
8e257a29 694 intdig_max = p.exponent + 1;
28f540f4 695 /* This can be really big! */ /* XXX Maybe malloc if too big? */
8e257a29 696 chars_needed = (size_t) p.exponent + 1 + 1 + (size_t) fracdig_max;
28f540f4
RM
697 }
698 else
699 {
700 intdig_max = 1;
9ca230d6 701 chars_needed = 1 + 1 + (size_t) fracdig_max;
28f540f4 702 }
28f540f4
RM
703 }
704 else
705 {
706 dig_max = info->prec < 0 ? 6 : (info->prec == 0 ? 1 : info->prec);
8e257a29
KS
707 if ((p.expsign == 0 && p.exponent >= dig_max)
708 || (p.expsign != 0 && p.exponent > 4))
28f540f4 709 {
d64b6ad0 710 if ('g' - 'G' == 'e' - 'E')
8e257a29 711 p.type = 'E' + (info->spec - 'G');
d64b6ad0 712 else
8e257a29 713 p.type = isupper (info->spec) ? 'E' : 'e';
28f540f4
RM
714 fracdig_max = dig_max - 1;
715 intdig_max = 1;
9ca230d6 716 chars_needed = 1 + 1 + (size_t) fracdig_max + 1 + 1 + 4;
28f540f4
RM
717 }
718 else
719 {
8e257a29
KS
720 p.type = 'f';
721 intdig_max = p.expsign == 0 ? p.exponent + 1 : 0;
28f540f4 722 fracdig_max = dig_max - intdig_max;
0f6b172f
UD
723 /* We need space for the significant digits and perhaps
724 for leading zeros when < 1.0. The number of leading
725 zeros can be as many as would be required for
726 exponential notation with a negative two-digit
8e257a29 727 p.exponent, which is 4. */
9ca230d6 728 chars_needed = (size_t) dig_max + 1 + 4;
28f540f4
RM
729 }
730 fracdig_min = info->alt ? fracdig_max : 0;
731 significant = 0; /* We count significant digits. */
732 }
733
28f540f4
RM
734 /* Allocate buffer for output. We need two more because while rounding
735 it is possible that we need two more characters in front of all the
b526f8ac
UD
736 other output. If the amount of memory we have to allocate is too
737 large use `malloc' instead of `alloca'. */
e88b9f0e
FW
738 if (__glibc_unlikely (chars_needed >= (size_t) -1 - 2
739 || chars_needed < fracdig_max))
199eb0de
AS
740 {
741 /* Some overflow occurred. */
742 __set_errno (ERANGE);
e88b9f0e
FW
743 __printf_buffer_mark_failed (buf);
744 return;
199eb0de 745 }
e88b9f0e 746 size_t wbuffer_to_alloc = 2 + chars_needed;
199eb0de 747 buffer_malloced = ! __libc_use_alloca (wbuffer_to_alloc);
4c02bf1a 748 if (__builtin_expect (buffer_malloced, 0))
b526f8ac 749 {
e88b9f0e 750 wbuffer = malloc (wbuffer_to_alloc);
a1d84548 751 if (wbuffer == NULL)
e88b9f0e
FW
752 {
753 /* Signal an error to the caller. */
754 __printf_buffer_mark_failed (buf);
755 return;
756 }
b526f8ac
UD
757 }
758 else
e88b9f0e 759 wbuffer = alloca (wbuffer_to_alloc);
a1d84548 760 wcp = wstartp = wbuffer + 2; /* Let room for rounding. */
28f540f4
RM
761
762 /* Do the real work: put digits in allocated buffer. */
8e257a29 763 if (p.expsign == 0 || p.type != 'f')
28f540f4 764 {
8e257a29 765 assert (p.expsign == 0 || intdig_max == 1);
28f540f4
RM
766 while (intdig_no < intdig_max)
767 {
768 ++intdig_no;
8e257a29 769 *wcp++ = hack_digit (&p);
28f540f4
RM
770 }
771 significant = 1;
772 if (info->alt
773 || fracdig_min > 0
8e257a29 774 || (fracdig_max > 0 && (p.fracsize > 1 || p.frac[0] != 0)))
e88b9f0e 775 *wcp++ = decimal;
28f540f4
RM
776 }
777 else
778 {
8e257a29 779 /* |fp| < 1.0 and the selected p.type is 'f', so put "0."
28f540f4 780 in the buffer. */
e88b9f0e 781 *wcp++ = '0';
8e257a29 782 --p.exponent;
e88b9f0e 783 *wcp++ = decimal;
28f540f4
RM
784 }
785
786 /* Generate the needed number of fractional digits. */
4c02bf1a 787 int fracdig_no = 0;
0f7769f7
UD
788 int added_zeros = 0;
789 while (fracdig_no < fracdig_min + added_zeros
8e257a29 790 || (fracdig_no < fracdig_max && (p.fracsize > 1 || p.frac[0] != 0)))
28f540f4
RM
791 {
792 ++fracdig_no;
8e257a29 793 *wcp = hack_digit (&p);
e88b9f0e 794 if (*wcp++ != '0')
28f540f4
RM
795 significant = 1;
796 else if (significant == 0)
797 {
798 ++fracdig_max;
799 if (fracdig_min > 0)
0f7769f7 800 ++added_zeros;
28f540f4 801 }
28f540f4
RM
802 }
803
804 /* Do rounding. */
e88b9f0e
FW
805 char last_digit = wcp[-1] != decimal ? wcp[-1] : wcp[-2];
806 char next_digit = hack_digit (&p);
784761be 807 bool more_bits;
e88b9f0e 808 if (next_digit != '0' && next_digit != '5')
784761be 809 more_bits = true;
8e257a29 810 else if (p.fracsize == 1 && p.frac[0] == 0)
784761be
JM
811 /* Rest of the number is zero. */
812 more_bits = false;
8e257a29 813 else if (p.scalesize == 0)
784761be
JM
814 {
815 /* Here we have to see whether all limbs are zero since no
816 normalization happened. */
8e257a29
KS
817 size_t lcnt = p.fracsize;
818 while (lcnt >= 1 && p.frac[lcnt - 1] == 0)
784761be
JM
819 --lcnt;
820 more_bits = lcnt > 0;
821 }
822 else
823 more_bits = true;
824 int rounding_mode = get_rounding_mode ();
e88b9f0e 825 if (round_away (is_neg, (last_digit - '0') & 1, next_digit >= '5',
784761be 826 more_bits, rounding_mode))
28f540f4 827 {
e88b9f0e 828 char *wtp = wcp;
28f540f4 829
28f540f4
RM
830 if (fracdig_no > 0)
831 {
832 /* Process fractional digits. Terminate if not rounded or
833 radix character is reached. */
0f7769f7 834 int removed = 0;
e88b9f0e 835 while (*--wtp != decimal && *wtp == '9')
0f7769f7 836 {
e88b9f0e 837 *wtp = '0';
0f7769f7
UD
838 ++removed;
839 }
840 if (removed == fracdig_min && added_zeros > 0)
841 --added_zeros;
e88b9f0e 842 if (*wtp != decimal)
28f540f4 843 /* Round up. */
a1d84548 844 (*wtp)++;
8e257a29 845 else if (__builtin_expect (spec == 'g' && p.type == 'f' && info->alt
8f5e1400 846 && wtp == wstartp + 1
e88b9f0e 847 && wstartp[0] == '0',
0f7769f7
UD
848 0))
849 /* This is a special case: the rounded number is 1.0,
850 the format is 'g' or 'G', and the alternative format
d40e67f5 851 is selected. This means the result must be "1.". */
0f7769f7 852 --added_zeros;
28f540f4
RM
853 }
854
e88b9f0e 855 if (fracdig_no == 0 || *wtp == decimal)
28f540f4
RM
856 {
857 /* Round the integer digits. */
e88b9f0e 858 if (*(wtp - 1) == decimal)
a1d84548 859 --wtp;
28f540f4 860
e88b9f0e
FW
861 while (--wtp >= wstartp && *wtp == '9')
862 *wtp = '0';
28f540f4 863
a1d84548 864 if (wtp >= wstartp)
28f540f4 865 /* Round up. */
a1d84548 866 (*wtp)++;
28f540f4 867 else
6d52618b 868 /* It is more critical. All digits were 9's. */
28f540f4 869 {
8e257a29 870 if (p.type != 'f')
28f540f4 871 {
a1d84548 872 *wstartp = '1';
8e257a29 873 p.exponent += p.expsign == 0 ? 1 : -1;
b866373d 874
8e257a29
KS
875 /* The above p.exponent adjustment could lead to 1.0e-00,
876 e.g. for 0.999999999. Make sure p.exponent 0 always
b866373d 877 uses + sign. */
8e257a29
KS
878 if (p.exponent == 0)
879 p.expsign = 0;
28f540f4
RM
880 }
881 else if (intdig_no == dig_max)
882 {
8e257a29 883 /* This is the case where for p.type %g the number fits
28f540f4
RM
884 really in the range for %f output but after rounding
885 the number of digits is too big. */
e88b9f0e
FW
886 *--wstartp = decimal;
887 *--wstartp = '1';
28f540f4
RM
888
889 if (info->alt || fracdig_no > 0)
890 {
891 /* Overwrite the old radix character. */
e88b9f0e 892 wstartp[intdig_no + 2] = '0';
28f540f4
RM
893 ++fracdig_no;
894 }
895
896 fracdig_no += intdig_no;
897 intdig_no = 1;
898 fracdig_max = intdig_max - intdig_no;
8e257a29
KS
899 ++p.exponent;
900 /* Now we must print the p.exponent. */
901 p.type = isupper (info->spec) ? 'E' : 'e';
28f540f4
RM
902 }
903 else
904 {
905 /* We can simply add another another digit before the
906 radix. */
e88b9f0e 907 *--wstartp = '1';
28f540f4
RM
908 ++intdig_no;
909 }
910
911 /* While rounding the number of digits can change.
912 If the number now exceeds the limits remove some
913 fractional digits. */
914 if (intdig_no + fracdig_no > dig_max)
915 {
a1d84548 916 wcp -= intdig_no + fracdig_no - dig_max;
28f540f4
RM
917 fracdig_no -= intdig_no + fracdig_no - dig_max;
918 }
919 }
920 }
921 }
922
28f540f4 923 /* Now remove unnecessary '0' at the end of the string. */
e88b9f0e 924 while (fracdig_no > fracdig_min + added_zeros && *(wcp - 1) == '0')
28f540f4 925 {
a1d84548 926 --wcp;
28f540f4
RM
927 --fracdig_no;
928 }
929 /* If we eliminate all fractional digits we perhaps also can remove
930 the radix character. */
e88b9f0e 931 if (fracdig_no == 0 && !info->alt && *(wcp - 1) == decimal)
a1d84548 932 --wcp;
28f540f4 933
8e257a29
KS
934 /* Write the p.exponent if it is needed. */
935 if (p.type != 'f')
28f540f4 936 {
8e257a29 937 if (__glibc_unlikely (p.expsign != 0 && p.exponent == 4 && spec == 'g'))
0f7769f7 938 {
8e257a29 939 /* This is another special case. The p.exponent of the number is
0f7769f7 940 really smaller than -4, which requires the 'e'/'E' format.
8e257a29 941 But after rounding the number has an p.exponent of -4. */
d40e67f5 942 assert (wcp >= wstartp + 1);
e88b9f0e
FW
943 assert (wstartp[0] == '1');
944 memcpy (wstartp, "0.0001", 6);
945 wstartp[1] = decimal;
d40e67f5
UD
946 if (wcp >= wstartp + 2)
947 {
e88b9f0e 948 memset (wstartp + 6, '0', wcp - (wstartp + 2));
d40e67f5
UD
949 wcp += 4;
950 }
951 else
952 wcp += 5;
0f7769f7
UD
953 }
954 else
955 {
e88b9f0e
FW
956 *wcp++ = p.type;
957 *wcp++ = p.expsign ? '-' : '+';
28f540f4 958
8e257a29 959 /* Find the magnitude of the p.exponent. */
0f7769f7 960 expscale = 10;
8e257a29 961 while (expscale <= p.exponent)
0f7769f7 962 expscale *= 10;
28f540f4 963
8e257a29 964 if (p.exponent < 10)
0f7769f7 965 /* Exponent always has at least two digits. */
e88b9f0e 966 *wcp++ = '0';
0f7769f7
UD
967 else
968 do
969 {
970 expscale /= 10;
e88b9f0e 971 *wcp++ = '0' + (p.exponent / expscale);
8e257a29 972 p.exponent %= expscale;
0f7769f7
UD
973 }
974 while (expscale > 10);
e88b9f0e 975 *wcp++ = '0' + p.exponent;
0f7769f7 976 }
28f540f4
RM
977 }
978
e88b9f0e
FW
979 struct grouping_iterator iter;
980 if (thousands_sep != '\0' && info->group)
981 __grouping_iterator_init (&iter, lc_category, loc, intdig_no);
982 else
983 iter.separators = 0;
984
28f540f4 985 /* Compute number of characters which must be filled with the padding
96aa2d94 986 character. */
28f540f4
RM
987 if (is_neg || info->showsign || info->space)
988 --width;
e88b9f0e
FW
989 /* To count bytes, we would have to use __translated_number_width
990 for info->i18n && !info->wide. See bug 28943. */
a1d84548 991 width -= wcp - wstartp;
e88b9f0e
FW
992 /* For counting bytes, we would have to multiply by
993 thousands_sep_length. */
994 width -= iter.separators;
28f540f4 995
e88b9f0e
FW
996 if (!info->left && info->pad != '0')
997 __printf_buffer_pad (buf, info->pad, width);
28f540f4
RM
998
999 if (is_neg)
e88b9f0e 1000 __printf_buffer_putc (buf, '-');
28f540f4 1001 else if (info->showsign)
e88b9f0e 1002 __printf_buffer_putc (buf, '+');
28f540f4 1003 else if (info->space)
e88b9f0e 1004 __printf_buffer_putc (buf, ' ');
28f540f4 1005
e88b9f0e
FW
1006 if (!info->left && info->pad == '0')
1007 __printf_buffer_pad (buf, '0', width);
28f540f4 1008
e88b9f0e
FW
1009 if (iter.separators > 0)
1010 {
1011 char *cp = wstartp;
1012 for (int i = 0; i < intdig_no; ++i)
1013 {
1014 if (__grouping_iterator_next (&iter))
1015 __printf_buffer_putc (buf, thousands_sep);
1016 __printf_buffer_putc (buf, *cp);
1017 ++cp;
1018 }
1019 __printf_buffer_write (buf, cp, wcp - cp);
1020 }
1021 else
1022 __printf_buffer_write (buf, wstartp, wcp - wstartp);
a1d84548 1023
e88b9f0e
FW
1024 if (info->left)
1025 __printf_buffer_pad (buf, info->pad, width);
1026 }
a1d84548 1027
e88b9f0e
FW
1028 if (buffer_malloced)
1029 free (wbuffer);
1030}
a1d84548 1031
e88b9f0e
FW
1032/* ASCII to localization translation. Multibyte version. */
1033struct __printf_buffer_fp
1034{
1035 struct __printf_buffer base;
a1d84548 1036
e88b9f0e
FW
1037 /* Replacement for ',' and '.'. */
1038 const char *thousands_sep;
1039 const char *decimal;
1040 unsigned char decimal_point_bytes;
1041 unsigned char thousands_sep_length;
a1d84548 1042
e88b9f0e
FW
1043 /* Buffer to write to. */
1044 struct __printf_buffer *next;
1045
1046 /* Activates outdigit translation if not NULL. */
1047 struct __locale_data *ctype;
8a7455e7 1048
e88b9f0e
FW
1049 /* Buffer to which the untranslated ASCII digits are written. */
1050 char untranslated[PRINTF_BUFFER_SIZE_DIGITS];
1051};
a1d84548 1052
e88b9f0e
FW
1053/* Multibyte buffer-to-buffer flush function with full translation. */
1054void
1055__printf_buffer_flush_fp (struct __printf_buffer_fp *buf)
1056{
1057 /* No need to update buf->base.written; the actual count is
1058 maintained in buf->next->written. */
1059 for (char *p = buf->untranslated; p < buf->base.write_ptr; ++p)
1060 {
1061 char ch = *p;
1062 const char *replacement = NULL;
1063 unsigned int replacement_bytes;
1064 if (ch == ',')
1065 {
1066 replacement = buf->thousands_sep;
1067 replacement_bytes = buf->thousands_sep_length;
1068 }
1069 else if (ch == '.')
1070 {
1071 replacement = buf->decimal;
1072 replacement_bytes = buf->decimal_point_bytes;
1073 }
1074 else if (buf->ctype != NULL && '0' <= ch && ch <= '9')
a1d84548 1075 {
e88b9f0e
FW
1076 int digit = ch - '0';
1077 replacement
1078 = buf->ctype->values[_NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_MB)
1079 + digit].string;
1080 struct lc_ctype_data *ctype = buf->ctype->private;
1081 replacement_bytes = ctype->outdigit_bytes[digit];
a1d84548 1082 }
e88b9f0e
FW
1083 if (replacement == NULL)
1084 __printf_buffer_putc (buf->next, ch);
1085 else
1086 __printf_buffer_write (buf->next, replacement, replacement_bytes);
a1d84548 1087 }
28f540f4 1088
e88b9f0e
FW
1089 if (!__printf_buffer_has_failed (buf->next))
1090 buf->base.write_ptr = buf->untranslated;
1091 else
1092 __printf_buffer_mark_failed (&buf->base);
28f540f4 1093}
985fc132 1094
e88b9f0e
FW
1095void
1096__printf_fp_l_buffer (struct __printf_buffer *buf, locale_t loc,
1097 const struct printf_info *info,
1098 const void *const *args)
985fc132 1099{
e88b9f0e
FW
1100 struct __printf_buffer_fp tmp;
1101
1102 if (info->extra)
1103 {
1104 tmp.thousands_sep = _nl_lookup (loc, LC_MONETARY, MON_THOUSANDS_SEP);
1105 tmp.decimal = _nl_lookup (loc, LC_MONETARY, MON_DECIMAL_POINT);
1106 if (tmp.decimal[0] == '\0')
1107 tmp.decimal = _nl_lookup (loc, LC_NUMERIC, DECIMAL_POINT);
1108 }
1109 else
1110 {
1111 tmp.thousands_sep = _nl_lookup (loc, LC_NUMERIC, THOUSANDS_SEP);
1112 tmp.decimal = _nl_lookup (loc, LC_NUMERIC, DECIMAL_POINT);
1113 }
1114
1115 tmp.thousands_sep_length = strlen (tmp.thousands_sep);
1116 if (tmp.decimal[1] == '\0' && tmp.thousands_sep_length <= 1
1117 && !info->i18n)
1118 {
1119 /* Emit the the characters directly. This is only possible if the
1120 separators have length 1 (or 0 in case of thousands_sep). i18n
1121 digit translation still needs the full conversion. */
1122 __printf_fp_buffer_1 (buf, loc,
1123 tmp.thousands_sep[0], tmp.decimal[0],
1124 tmp.thousands_sep_length,
1125 info, args);
1126 return;
1127 }
1128
1129 tmp.decimal_point_bytes = strlen (tmp.decimal);
1130
1131 if (info->i18n)
1132 tmp.ctype = loc->__locales[LC_CTYPE];
1133 else
1134 tmp.ctype = NULL;
1135 tmp.next = buf;
1136
1137 __printf_buffer_init (&tmp.base, tmp.untranslated, sizeof (tmp.untranslated),
1138 __printf_buffer_mode_fp);
1139 __printf_fp_buffer_1 (&tmp.base, loc, ',', '.',
1140 tmp.thousands_sep_length, info, args);
1141 if (__printf_buffer_has_failed (&tmp.base))
1142 {
1143 __printf_buffer_mark_failed (tmp.next);
1144 return;
1145 }
1146 __printf_buffer_flush_fp (&tmp);
985fc132 1147}
985fc132 1148
e88b9f0e
FW
1149/* The wide version is implemented on top of the multibyte version using
1150 translation. */
28f540f4 1151
e88b9f0e 1152struct __printf_buffer_fp_to_wide
28f540f4 1153{
e88b9f0e
FW
1154 struct __printf_buffer base;
1155 wchar_t thousands_sep_wc;
1156 wchar_t decimalwc;
1157 struct __wprintf_buffer *next;
28f540f4 1158
e88b9f0e
FW
1159 /* Activates outdigit translation if not NULL. */
1160 struct __locale_data *ctype;
28f540f4 1161
e88b9f0e
FW
1162 char untranslated[PRINTF_BUFFER_SIZE_DIGITS];
1163};
28f540f4 1164
e88b9f0e
FW
1165void
1166__printf_buffer_flush_fp_to_wide (struct __printf_buffer_fp_to_wide *buf)
1167{
1168 /* No need to update buf->base.written; the actual count is
1169 maintained in buf->next->written. */
1170 for (char *p = buf->untranslated; p < buf->base.write_ptr; ++p)
28f540f4 1171 {
e88b9f0e
FW
1172 /* wchar_t overlaps with char in the ASCII range. */
1173 wchar_t ch = *p;
1174 if (ch == L',')
28f540f4 1175 {
e88b9f0e
FW
1176 ch = buf->thousands_sep_wc;
1177 if (ch == 0)
1178 continue;
28f540f4 1179 }
e88b9f0e
FW
1180 else if (ch == L'.')
1181 ch = buf->decimalwc;
1182 else if (buf->ctype != NULL && L'0' <= ch && ch <= L'9')
1183 ch = buf->ctype->values[_NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_WC)
1184 + ch - L'0'].word;
1185 __wprintf_buffer_putc (buf->next, ch);
28f540f4
RM
1186 }
1187
e88b9f0e
FW
1188 if (!__wprintf_buffer_has_failed (buf->next))
1189 buf->base.write_ptr = buf->untranslated;
1190 else
1191 __printf_buffer_mark_failed (&buf->base);
28f540f4
RM
1192}
1193
e88b9f0e
FW
1194void
1195__wprintf_fp_l_buffer (struct __wprintf_buffer *buf, locale_t loc,
1196 const struct printf_info *info,
1197 const void *const *args)
28f540f4 1198{
e88b9f0e
FW
1199 struct __printf_buffer_fp_to_wide tmp;
1200 if (info->extra)
1201 {
1202 tmp.decimalwc = _nl_lookup_word (loc, LC_MONETARY,
1203 _NL_MONETARY_DECIMAL_POINT_WC);
1204 tmp.thousands_sep_wc = _nl_lookup_word (loc, LC_MONETARY,
1205 _NL_MONETARY_THOUSANDS_SEP_WC);
1206 if (tmp.decimalwc == 0)
1207 tmp.decimalwc = _nl_lookup_word (loc, LC_NUMERIC,
1208 _NL_NUMERIC_DECIMAL_POINT_WC);
1209 }
1210 else
1211 {
1212 tmp.decimalwc = _nl_lookup_word (loc, LC_NUMERIC,
1213 _NL_NUMERIC_DECIMAL_POINT_WC);
1214 tmp.thousands_sep_wc = _nl_lookup_word (loc, LC_NUMERIC,
1215 _NL_NUMERIC_THOUSANDS_SEP_WC);
1216 }
28f540f4 1217
e88b9f0e
FW
1218 if (info->i18n)
1219 tmp.ctype = loc->__locales[LC_CTYPE];
1220 else
1221 tmp.ctype = NULL;
1222 tmp.next = buf;
28f540f4 1223
e88b9f0e
FW
1224 __printf_buffer_init (&tmp.base, tmp.untranslated, sizeof (tmp.untranslated),
1225 __printf_buffer_mode_fp_to_wide);
1226 __printf_fp_buffer_1 (&tmp.base, loc, ',', '.', 1, info, args);
1227 if (__printf_buffer_has_failed (&tmp.base))
28f540f4 1228 {
e88b9f0e
FW
1229 __wprintf_buffer_mark_failed (tmp.next);
1230 return;
1231 }
1232 __printf_buffer_flush (&tmp.base);
1233}
28f540f4 1234
e88b9f0e
FW
1235int
1236___printf_fp (FILE *fp, const struct printf_info *info,
1237 const void *const *args)
1238{
1239 if (info->wide)
1240 {
1241 struct __wprintf_buffer_to_file buf;
1242 __wprintf_buffer_to_file_init (&buf, fp);
1243 __wprintf_fp_l_buffer (&buf.base, _NL_CURRENT_LOCALE, info, args);
1244 return __wprintf_buffer_to_file_done (&buf);
1245 }
1246 else
1247 {
1248 struct __printf_buffer_to_file buf;
1249 __printf_buffer_to_file_init (&buf, fp);
1250 __printf_fp_l_buffer (&buf.base, _NL_CURRENT_LOCALE, info, args);
1251 return __printf_buffer_to_file_done (&buf);
1252 }
28f540f4 1253}
e88b9f0e
FW
1254ldbl_hidden_def (___printf_fp, __printf_fp)
1255ldbl_strong_alias (___printf_fp, __printf_fp)