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