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