~ubuntu-branches/ubuntu/quantal/gnutls26/quantal

« back to all changes in this revision

Viewing changes to gl/vasnprintf.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2011-05-20 13:07:18 UTC
  • mfrom: (12.1.11 sid)
  • Revision ID: james.westby@ubuntu.com-20110520130718-db41dybbanzfvlji
Tags: 2.10.5-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Fix build failure with --no-add-needed.
  - Build for multiarch.

Show diffs side-by-side

added added

removed removed

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