~ubuntu-branches/ubuntu/maverick/gettext/maverick

« back to all changes in this revision

Viewing changes to gettext-tools/gnulib-lib/vasnprintf.c

  • Committer: Colin Watson
  • Date: 2010-08-01 21:36:08 UTC
  • mfrom: (2.1.10 sid)
  • Revision ID: cjwatson@canonical.com-20100801213608-yy7vkm8lpatep3ci
merge from Debian 0.18.1.1-1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* vsprintf with automatic memory allocation.
2
 
   Copyright (C) 1999, 2002-2007 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
6
 
   the Free Software Foundation; either version 2, or (at your option)
 
6
   the Free Software Foundation; either version 3, or (at your option)
7
7
   any later version.
8
8
 
9
9
   This program is distributed in the hope that it will be useful,
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
95
95
 
96
96
#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
97
97
# include <math.h>
98
 
# include "isnan.h"
 
98
# include "isnand-nolibm.h"
99
99
#endif
100
100
 
101
101
#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
106
106
 
107
107
#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
108
108
# include <math.h>
109
 
# include "isnan.h"
 
109
# include "isnand-nolibm.h"
110
110
# include "printf-frexp.h"
111
111
#endif
112
112
 
117
117
# include "fpucw.h"
118
118
#endif
119
119
 
120
 
/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW.  */
121
 
#ifndef EOVERFLOW
122
 
# define EOVERFLOW E2BIG
123
 
#endif
124
 
 
125
 
#if HAVE_WCHAR_T
126
 
# if HAVE_WCSLEN
127
 
#  define local_wcslen wcslen
128
 
# else
129
 
   /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
130
 
      a dependency towards this library, here is a local substitute.
131
 
      Define this substitute only once, even if this file is included
132
 
      twice in the same compilation unit.  */
133
 
#  ifndef local_wcslen_defined
134
 
#   define local_wcslen_defined 1
135
 
static size_t
136
 
local_wcslen (const wchar_t *s)
137
 
{
138
 
  const wchar_t *ptr;
139
 
 
140
 
  for (ptr = s; *ptr != (wchar_t) 0; ptr++)
141
 
    ;
142
 
  return ptr - s;
143
 
}
144
 
#  endif
145
 
# endif
146
 
#endif
147
 
 
148
120
/* Default parameters.  */
149
121
#ifndef VASNPRINTF
150
122
# if WIDE_CHAR_VERSION
157
129
#  define DIRECTIVES wchar_t_directives
158
130
#  define PRINTF_PARSE wprintf_parse
159
131
#  define DCHAR_CPY wmemcpy
 
132
#  define DCHAR_SET wmemset
160
133
# else
161
134
#  define VASNPRINTF vasnprintf
162
135
#  define FCHAR_T char
167
140
#  define DIRECTIVES char_directives
168
141
#  define PRINTF_PARSE printf_parse
169
142
#  define DCHAR_CPY memcpy
 
143
#  define DCHAR_SET memset
170
144
# endif
171
145
#endif
172
146
#if WIDE_CHAR_VERSION
174
148
# define USE_SNPRINTF 1
175
149
# if HAVE_DECL__SNWPRINTF
176
150
   /* On Windows, the function swprintf() has a different signature than
177
 
      on Unix; we use the _snwprintf() function instead.  */
178
 
#  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
179
159
# else
180
160
   /* Unix.  */
181
161
#  define SNPRINTF swprintf
182
162
# endif
183
163
#else
184
164
  /* TCHAR_T is char.  */
185
 
# /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
 
165
  /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
186
166
     But don't use it on BeOS, since BeOS snprintf produces no output if the
187
 
     size argument is >= 0x3000000.  */
188
 
# if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__
 
167
     size argument is >= 0x3000000.
 
168
     Also don't use it on Linux libc5, since there snprintf with size = 1
 
169
     writes any output without bounds, like sprintf.  */
 
170
# if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
189
171
#  define USE_SNPRINTF 1
190
172
# else
191
173
#  define USE_SNPRINTF 0
192
174
# endif
193
175
# if HAVE_DECL__SNPRINTF
194
 
   /* Windows.  */
195
 
#  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
196
185
# else
197
186
   /* Unix.  */
198
187
#  define SNPRINTF snprintf
203
192
/* Here we need to call the native sprintf, not rpl_sprintf.  */
204
193
#undef sprintf
205
194
 
206
 
#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
 
195
/* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
 
196
   warnings in this file.  Use -Dlint to suppress them.  */
 
197
#ifdef lint
 
198
# define IF_LINT(Code) Code
 
199
#else
 
200
# define IF_LINT(Code) /* empty */
 
201
#endif
 
202
 
 
203
/* Avoid some warnings from "gcc -Wshadow".
 
204
   This file doesn't use the exp() and remainder() functions.  */
 
205
#undef exp
 
206
#define exp expo
 
207
#undef remainder
 
208
#define remainder rem
 
209
 
 
210
#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION
 
211
# if (HAVE_STRNLEN && !defined _AIX)
 
212
#  define local_strnlen strnlen
 
213
# else
 
214
#  ifndef local_strnlen_defined
 
215
#   define local_strnlen_defined 1
 
216
static size_t
 
217
local_strnlen (const char *string, size_t maxlen)
 
218
{
 
219
  const char *end = memchr (string, '\0', maxlen);
 
220
  return end ? (size_t) (end - string) : maxlen;
 
221
}
 
222
#  endif
 
223
# endif
 
224
#endif
 
225
 
 
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
 
227
# if HAVE_WCSLEN
 
228
#  define local_wcslen wcslen
 
229
# else
 
230
   /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
 
231
      a dependency towards this library, here is a local substitute.
 
232
      Define this substitute only once, even if this file is included
 
233
      twice in the same compilation unit.  */
 
234
#  ifndef local_wcslen_defined
 
235
#   define local_wcslen_defined 1
 
236
static size_t
 
237
local_wcslen (const wchar_t *s)
 
238
{
 
239
  const wchar_t *ptr;
 
240
 
 
241
  for (ptr = s; *ptr != (wchar_t) 0; ptr++)
 
242
    ;
 
243
  return ptr - s;
 
244
}
 
245
#  endif
 
246
# endif
 
247
#endif
 
248
 
 
249
#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
 
250
# if HAVE_WCSNLEN
 
251
#  define local_wcsnlen wcsnlen
 
252
# else
 
253
#  ifndef local_wcsnlen_defined
 
254
#   define local_wcsnlen_defined 1
 
255
static size_t
 
256
local_wcsnlen (const wchar_t *s, size_t maxlen)
 
257
{
 
258
  const wchar_t *ptr;
 
259
 
 
260
  for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
 
261
    ;
 
262
  return ptr - s;
 
263
}
 
264
#  endif
 
265
# endif
 
266
#endif
 
267
 
 
268
#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
207
269
/* Determine the decimal-point character according to the current locale.  */
208
270
# ifndef decimal_point_char_defined
209
271
#  define decimal_point_char_defined 1
210
272
static char
211
 
decimal_point_char ()
 
273
decimal_point_char (void)
212
274
{
213
275
  const char *point;
214
276
  /* Determine it in a multithread-safe way.  We know nl_langinfo is
215
 
     multithread-safe on glibc systems, but is not required to be multithread-
216
 
     safe by POSIX.  sprintf(), however, is multithread-safe.  localeconv()
217
 
     is rarely multithread-safe.  */
218
 
#  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__))
219
281
  point = nl_langinfo (RADIXCHAR);
220
282
#  elif 1
221
283
  char pointbuf[5];
236
298
static int
237
299
is_infinite_or_zero (double x)
238
300
{
239
 
  return isnan (x) || x + x == x;
 
301
  return isnand (x) || x + x == x;
240
302
}
241
303
 
242
304
#endif
243
305
 
244
306
#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
245
307
 
246
 
/* Equivalent to !isfinite(x), but does not require libm.  */
 
308
/* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
247
309
static int
248
 
is_infinitel (long double x)
 
310
is_infinite_or_zerol (long double x)
249
311
{
250
 
  return isnanl (x) || (x + x == x && x != 0.0L);
 
312
  return isnanl (x) || x + x == x;
251
313
}
252
314
 
253
315
#endif
315
377
      dlen = len1 + len2;
316
378
      dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
317
379
      if (dp == NULL)
318
 
        return NULL;
 
380
        return NULL;
319
381
      for (k = len2; k > 0; )
320
 
        dp[--k] = 0;
 
382
        dp[--k] = 0;
321
383
      for (i = 0; i < len1; i++)
322
 
        {
323
 
          mp_limb_t digit1 = p1[i];
324
 
          mp_twolimb_t carry = 0;
325
 
          for (j = 0; j < len2; j++)
326
 
            {
327
 
              mp_limb_t digit2 = p2[j];
328
 
              carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
329
 
              carry += dp[i + j];
330
 
              dp[i + j] = (mp_limb_t) carry;
331
 
              carry = carry >> GMP_LIMB_BITS;
332
 
            }
333
 
          dp[i + len2] = (mp_limb_t) carry;
334
 
        }
 
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
        }
335
397
      /* Normalise.  */
336
398
      while (dlen > 0 && dp[dlen - 1] == 0)
337
 
        dlen--;
 
399
        dlen--;
338
400
      dest->nlimbs = dlen;
339
401
      dest->limbs = dp;
340
402
    }
364
426
       Normalise [q[m-1],...,q[0]], yields q.
365
427
     If m>=n>1, perform a multiple-precision division:
366
428
       We have a/b < beta^(m-n+1).
367
 
       s:=intDsize-1-(hightest bit in b[n-1]), 0<=s<intDsize.
 
429
       s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
368
430
       Shift a and b left by s bits, copying them. r:=a.
369
431
       r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
370
432
       For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
428
490
  for (;;)
429
491
    {
430
492
      if (b_len == 0)
431
 
        /* Division by zero.  */
432
 
        abort ();
 
493
        /* Division by zero.  */
 
494
        abort ();
433
495
      if (b_ptr[b_len - 1] == 0)
434
 
        b_len--;
 
496
        b_len--;
435
497
      else
436
 
        break;
 
498
        break;
437
499
    }
438
500
 
439
501
  /* Here m = a_len >= 0 and n = b_len > 0.  */
450
512
  else if (b_len == 1)
451
513
    {
452
514
      /* n=1: single precision division.
453
 
         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  */
454
516
      r_ptr = roomptr;
455
517
      q_ptr = roomptr + 1;
456
518
      {
457
 
        mp_limb_t den = b_ptr[0];
458
 
        mp_limb_t remainder = 0;
459
 
        const mp_limb_t *sourceptr = a_ptr + a_len;
460
 
        mp_limb_t *destptr = q_ptr + a_len;
461
 
        size_t count;
462
 
        for (count = a_len; count > 0; count--)
463
 
          {
464
 
            mp_twolimb_t num =
465
 
              ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
466
 
            *--destptr = num / den;
467
 
            remainder = num % den;
468
 
          }
469
 
        /* Normalise and store r.  */
470
 
        if (remainder > 0)
471
 
          {
472
 
            r_ptr[0] = remainder;
473
 
            r_len = 1;
474
 
          }
475
 
        else
476
 
          r_len = 0;
477
 
        /* Normalise q.  */
478
 
        q_len = a_len;
479
 
        if (q_ptr[q_len - 1] == 0)
480
 
          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--;
481
543
      }
482
544
    }
483
545
  else
484
546
    {
485
547
      /* n>1: multiple precision division.
486
 
         beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n  ==>
487
 
         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).  */
488
550
      /* Determine s.  */
489
551
      size_t s;
490
552
      {
491
 
        mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
492
 
        s = 31;
493
 
        if (msd >= 0x10000)
494
 
          {
495
 
            msd = msd >> 16;
496
 
            s -= 16;
497
 
          }
498
 
        if (msd >= 0x100)
499
 
          {
500
 
            msd = msd >> 8;
501
 
            s -= 8;
502
 
          }
503
 
        if (msd >= 0x10)
504
 
          {
505
 
            msd = msd >> 4;
506
 
            s -= 4;
507
 
          }
508
 
        if (msd >= 0x4)
509
 
          {
510
 
            msd = msd >> 2;
511
 
            s -= 2;
512
 
          }
513
 
        if (msd >= 0x2)
514
 
          {
515
 
            msd = msd >> 1;
516
 
            s -= 1;
517
 
          }
 
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
          }
518
580
      }
519
581
      /* 0 <= s < GMP_LIMB_BITS.
520
 
         Copy b, shifting it left by s bits.  */
 
582
         Copy b, shifting it left by s bits.  */
521
583
      if (s > 0)
522
 
        {
523
 
          tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
524
 
          if (tmp_roomptr == NULL)
525
 
            {
526
 
              free (roomptr);
527
 
              return NULL;
528
 
            }
529
 
          {
530
 
            const mp_limb_t *sourceptr = b_ptr;
531
 
            mp_limb_t *destptr = tmp_roomptr;
532
 
            mp_twolimb_t accu = 0;
533
 
            size_t count;
534
 
            for (count = b_len; count > 0; count--)
535
 
              {
536
 
                accu += (mp_twolimb_t) *sourceptr++ << s;
537
 
                *destptr++ = (mp_limb_t) accu;
538
 
                accu = accu >> GMP_LIMB_BITS;
539
 
              }
540
 
            /* accu must be zero, since that was how s was determined.  */
541
 
            if (accu != 0)
542
 
              abort ();
543
 
          }
544
 
          b_ptr = tmp_roomptr;
545
 
        }
 
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
        }
546
608
      /* Copy a, shifting it left by s bits, yields r.
547
 
         Memory layout:
548
 
         At the beginning: r = roomptr[0..a_len],
549
 
         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]  */
550
612
      r_ptr = roomptr;
551
613
      if (s == 0)
552
 
        {
553
 
          memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
554
 
          r_ptr[a_len] = 0;
555
 
        }
 
614
        {
 
615
          memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
 
616
          r_ptr[a_len] = 0;
 
617
        }
556
618
      else
557
 
        {
558
 
          const mp_limb_t *sourceptr = a_ptr;
559
 
          mp_limb_t *destptr = r_ptr;
560
 
          mp_twolimb_t accu = 0;
561
 
          size_t count;
562
 
          for (count = a_len; count > 0; count--)
563
 
            {
564
 
              accu += (mp_twolimb_t) *sourceptr++ << s;
565
 
              *destptr++ = (mp_limb_t) accu;
566
 
              accu = accu >> GMP_LIMB_BITS;
567
 
            }
568
 
          *destptr++ = (mp_limb_t) accu;
569
 
        }
 
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
        }
570
632
      q_ptr = roomptr + b_len;
571
633
      q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
572
634
      {
573
 
        size_t j = a_len - b_len; /* m-n */
574
 
        mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
575
 
        mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
576
 
        mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
577
 
          ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
578
 
        /* Division loop, traversed m-n+1 times.
579
 
           j counts down, b is unchanged, beta/2 <= b[n-1] < beta.  */
580
 
        for (;;)
581
 
          {
582
 
            mp_limb_t q_star;
583
 
            mp_limb_t c1;
584
 
            if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
585
 
              {
586
 
                /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow.  */
587
 
                mp_twolimb_t num =
588
 
                  ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
589
 
                  | r_ptr[j + b_len - 1];
590
 
                q_star = num / b_msd;
591
 
                c1 = num % b_msd;
592
 
              }
593
 
            else
594
 
              {
595
 
                /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1].  */
596
 
                q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
597
 
                /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
598
 
                   <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
599
 
                   <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
600
 
                        {<= beta !}.
601
 
                   If yes, jump directly to the subtraction loop.
602
 
                   (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
603
 
                    <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
604
 
                if (r_ptr[j + b_len] > b_msd
605
 
                    || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
606
 
                  /* r[j+n] >= b[n-1]+1 or
607
 
                     r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
608
 
                     carry.  */
609
 
                  goto subtract;
610
 
              }
611
 
            /* q_star = q*,
612
 
               c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta).  */
613
 
            {
614
 
              mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
615
 
                ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
616
 
              mp_twolimb_t c3 = /* b[n-2] * q* */
617
 
                (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
618
 
              /* While c2 < c3, increase c2 and decrease c3.
619
 
                 Consider c3-c2.  While it is > 0, decrease it by
620
 
                 b[n-1]*beta+b[n-2].  Because of b[n-1]*beta+b[n-2] >= beta^2/2
621
 
                 this can happen only twice.  */
622
 
              if (c3 > c2)
623
 
                {
624
 
                  q_star = q_star - 1; /* q* := q* - 1 */
625
 
                  if (c3 - c2 > b_msdd)
626
 
                    q_star = q_star - 1; /* q* := q* - 1 */
627
 
                }
628
 
            }
629
 
            if (q_star > 0)
630
 
              subtract:
631
 
              {
632
 
                /* Subtract r := r - b * q* * beta^j.  */
633
 
                mp_limb_t cr;
634
 
                {
635
 
                  const mp_limb_t *sourceptr = b_ptr;
636
 
                  mp_limb_t *destptr = r_ptr + j;
637
 
                  mp_twolimb_t carry = 0;
638
 
                  size_t count;
639
 
                  for (count = b_len; count > 0; count--)
640
 
                    {
641
 
                      /* Here 0 <= carry <= q*.  */
642
 
                      carry =
643
 
                        carry
644
 
                        + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
645
 
                        + (mp_limb_t) ~(*destptr);
646
 
                      /* Here 0 <= carry <= beta*q* + beta-1.  */
647
 
                      *destptr++ = ~(mp_limb_t) carry;
648
 
                      carry = carry >> GMP_LIMB_BITS; /* <= q* */
649
 
                    }
650
 
                  cr = (mp_limb_t) carry;
651
 
                }
652
 
                /* Subtract cr from r_ptr[j + b_len], then forget about
653
 
                   r_ptr[j + b_len].  */
654
 
                if (cr > r_ptr[j + b_len])
655
 
                  {
656
 
                    /* Subtraction gave a carry.  */
657
 
                    q_star = q_star - 1; /* q* := q* - 1 */
658
 
                    /* Add b back.  */
659
 
                    {
660
 
                      const mp_limb_t *sourceptr = b_ptr;
661
 
                      mp_limb_t *destptr = r_ptr + j;
662
 
                      mp_limb_t carry = 0;
663
 
                      size_t count;
664
 
                      for (count = b_len; count > 0; count--)
665
 
                        {
666
 
                          mp_limb_t source1 = *sourceptr++;
667
 
                          mp_limb_t source2 = *destptr;
668
 
                          *destptr++ = source1 + source2 + carry;
669
 
                          carry =
670
 
                            (carry
671
 
                             ? source1 >= (mp_limb_t) ~source2
672
 
                             : source1 > (mp_limb_t) ~source2);
673
 
                        }
674
 
                    }
675
 
                    /* Forget about the carry and about r[j+n].  */
676
 
                  }
677
 
              }
678
 
            /* q* is determined.  Store it as q[j].  */
679
 
            q_ptr[j] = q_star;
680
 
            if (j == 0)
681
 
              break;
682
 
            j--;
683
 
          }
 
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
          }
684
746
      }
685
747
      r_len = b_len;
686
748
      /* Normalise q.  */
687
749
      if (q_ptr[q_len - 1] == 0)
688
 
        q_len--;
 
750
        q_len--;
689
751
# if 0 /* Not needed here, since we need r only to compare it with b/2, and
690
 
          b is shifted left by s bits.  */
 
752
          b is shifted left by s bits.  */
691
753
      /* Shift r right by s bits.  */
692
754
      if (s > 0)
693
 
        {
694
 
          mp_limb_t ptr = r_ptr + r_len;
695
 
          mp_twolimb_t accu = 0;
696
 
          size_t count;
697
 
          for (count = r_len; count > 0; count--)
698
 
            {
699
 
              accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
700
 
              accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
701
 
              *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
702
 
            }
703
 
        }
 
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
        }
704
766
# endif
705
767
      /* Normalise r.  */
706
768
      while (r_len > 0 && r_ptr[r_len - 1] == 0)
707
 
        r_len--;
 
769
        r_len--;
708
770
    }
709
771
  /* Compare r << 1 with b.  */
710
772
  if (r_len > b_len)
713
775
    size_t i;
714
776
    for (i = b_len;;)
715
777
      {
716
 
        mp_limb_t r_i =
717
 
          (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
718
 
          | (i < r_len ? r_ptr[i] << 1 : 0);
719
 
        mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
720
 
        if (r_i > b_i)
721
 
          goto increment_q;
722
 
        if (r_i < b_i)
723
 
          goto keep_q;
724
 
        if (i == 0)
725
 
          break;
726
 
        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--;
727
789
      }
728
790
  }
729
791
  if (q_len > 0 && ((q_ptr[0] & 1) != 0))
732
794
    {
733
795
      size_t i;
734
796
      for (i = 0; i < q_len; i++)
735
 
        if (++(q_ptr[i]) != 0)
736
 
          goto keep_q;
 
797
        if (++(q_ptr[i]) != 0)
 
798
          goto keep_q;
737
799
      q_ptr[q_len++] = 1;
738
800
    }
739
801
  keep_q:
762
824
    {
763
825
      char *d_ptr = c_ptr;
764
826
      for (; extra_zeroes > 0; extra_zeroes--)
765
 
        *d_ptr++ = '0';
 
827
        *d_ptr++ = '0';
766
828
      while (a_len > 0)
767
 
        {
768
 
          /* Divide a by 10^9, in-place.  */
769
 
          mp_limb_t remainder = 0;
770
 
          mp_limb_t *ptr = a_ptr + a_len;
771
 
          size_t count;
772
 
          for (count = a_len; count > 0; count--)
773
 
            {
774
 
              mp_twolimb_t num =
775
 
                ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
776
 
              *ptr = num / 1000000000;
777
 
              remainder = num % 1000000000;
778
 
            }
779
 
          /* Store the remainder as 9 decimal digits.  */
780
 
          for (count = 9; count > 0; count--)
781
 
            {
782
 
              *d_ptr++ = '0' + (remainder % 10);
783
 
              remainder = remainder / 10;
784
 
            }
785
 
          /* Normalize a.  */
786
 
          if (a_ptr[a_len - 1] == 0)
787
 
            a_len--;
788
 
        }
 
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
        }
789
851
      /* Remove leading zeroes.  */
790
852
      while (d_ptr > c_ptr && d_ptr[-1] == '0')
791
 
        d_ptr--;
 
853
        d_ptr--;
792
854
      /* But keep at least one zero.  */
793
855
      if (d_ptr == c_ptr)
794
 
        *d_ptr++ = '0';
 
856
        *d_ptr++ = '0';
795
857
      /* Terminate the string.  */
796
858
      *d_ptr = '\0';
797
859
    }
836
898
      hi = (int) y;
837
899
      y -= hi;
838
900
      if (!(y >= 0.0L && y < 1.0L))
839
 
        abort ();
 
901
        abort ();
840
902
      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
841
903
      lo = (int) y;
842
904
      y -= lo;
843
905
      if (!(y >= 0.0L && y < 1.0L))
844
 
        abort ();
 
906
        abort ();
845
907
      m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
846
908
    }
847
909
#   else
851
913
      d = (int) y;
852
914
      y -= d;
853
915
      if (!(y >= 0.0L && y < 1.0L))
854
 
        abort ();
 
916
        abort ();
855
917
      m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
856
918
    }
857
919
#   endif
863
925
      hi = (int) y;
864
926
      y -= hi;
865
927
      if (!(y >= 0.0L && y < 1.0L))
866
 
        abort ();
 
928
        abort ();
867
929
      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
868
930
      lo = (int) y;
869
931
      y -= lo;
870
932
      if (!(y >= 0.0L && y < 1.0L))
871
 
        abort ();
 
933
        abort ();
872
934
      m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
873
935
    }
 
936
#if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
 
937
         precision.  */
874
938
  if (!(y == 0.0L))
875
939
    abort ();
 
940
#endif
876
941
  /* Normalise.  */
877
942
  while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
878
943
    m.nlimbs--;
921
986
      hi = (int) y;
922
987
      y -= hi;
923
988
      if (!(y >= 0.0 && y < 1.0))
924
 
        abort ();
 
989
        abort ();
925
990
      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
926
991
      lo = (int) y;
927
992
      y -= lo;
928
993
      if (!(y >= 0.0 && y < 1.0))
929
 
        abort ();
 
994
        abort ();
930
995
      m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
931
996
    }
932
997
#   else
936
1001
      d = (int) y;
937
1002
      y -= d;
938
1003
      if (!(y >= 0.0 && y < 1.0))
939
 
        abort ();
 
1004
        abort ();
940
1005
      m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
941
1006
    }
942
1007
#   endif
948
1013
      hi = (int) y;
949
1014
      y -= hi;
950
1015
      if (!(y >= 0.0 && y < 1.0))
951
 
        abort ();
 
1016
        abort ();
952
1017
      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
953
1018
      lo = (int) y;
954
1019
      y -= lo;
955
1020
      if (!(y >= 0.0 && y < 1.0))
956
 
        abort ();
 
1021
        abort ();
957
1022
      m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
958
1023
    }
959
1024
  if (!(y == 0.0))
1011
1076
  abs_n = (n >= 0 ? n : -n);
1012
1077
  abs_s = (s >= 0 ? s : -s);
1013
1078
  pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
1014
 
                                    + abs_s / GMP_LIMB_BITS + 1)
1015
 
                                   * sizeof (mp_limb_t));
 
1079
                                    + abs_s / GMP_LIMB_BITS + 1)
 
1080
                                   * sizeof (mp_limb_t));
1016
1081
  if (pow5_ptr == NULL)
1017
1082
    {
1018
1083
      free (memory);
1025
1090
  if (abs_n > 0)
1026
1091
    {
1027
1092
      static mp_limb_t const small_pow5[13 + 1] =
1028
 
        {
1029
 
          1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
1030
 
          48828125, 244140625, 1220703125
1031
 
        };
 
1093
        {
 
1094
          1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
 
1095
          48828125, 244140625, 1220703125
 
1096
        };
1032
1097
      unsigned int n13;
1033
1098
      for (n13 = 0; n13 <= abs_n; n13 += 13)
1034
 
        {
1035
 
          mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
1036
 
          size_t j;
1037
 
          mp_twolimb_t carry = 0;
1038
 
          for (j = 0; j < pow5_len; j++)
1039
 
            {
1040
 
              mp_limb_t digit2 = pow5_ptr[j];
1041
 
              carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
1042
 
              pow5_ptr[j] = (mp_limb_t) carry;
1043
 
              carry = carry >> GMP_LIMB_BITS;
1044
 
            }
1045
 
          if (carry > 0)
1046
 
            pow5_ptr[pow5_len++] = (mp_limb_t) carry;
1047
 
        }
 
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
        }
1048
1113
    }
1049
1114
  s_limbs = abs_s / GMP_LIMB_BITS;
1050
1115
  s_bits = abs_s % GMP_LIMB_BITS;
1052
1117
    {
1053
1118
      /* Multiply with 2^|s|.  */
1054
1119
      if (s_bits > 0)
1055
 
        {
1056
 
          mp_limb_t *ptr = pow5_ptr;
1057
 
          mp_twolimb_t accu = 0;
1058
 
          size_t count;
1059
 
          for (count = pow5_len; count > 0; count--)
1060
 
            {
1061
 
              accu += (mp_twolimb_t) *ptr << s_bits;
1062
 
              *ptr++ = (mp_limb_t) accu;
1063
 
              accu = accu >> GMP_LIMB_BITS;
1064
 
            }
1065
 
          if (accu > 0)
1066
 
            {
1067
 
              *ptr = (mp_limb_t) accu;
1068
 
              pow5_len++;
1069
 
            }
1070
 
        }
 
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
        }
1071
1136
      if (s_limbs > 0)
1072
 
        {
1073
 
          size_t count;
1074
 
          for (count = pow5_len; count > 0;)
1075
 
            {
1076
 
              count--;
1077
 
              pow5_ptr[s_limbs + count] = pow5_ptr[count];
1078
 
            }
1079
 
          for (count = s_limbs; count > 0;)
1080
 
            {
1081
 
              count--;
1082
 
              pow5_ptr[count] = 0;
1083
 
            }
1084
 
          pow5_len += s_limbs;
1085
 
        }
 
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
        }
1086
1151
      pow5.limbs = pow5_ptr;
1087
1152
      pow5.nlimbs = pow5_len;
1088
1153
      if (n >= 0)
1089
 
        {
1090
 
          /* Multiply m with pow5.  No division needed.  */
1091
 
          z_memory = multiply (m, pow5, &z);
1092
 
        }
 
1154
        {
 
1155
          /* Multiply m with pow5.  No division needed.  */
 
1156
          z_memory = multiply (m, pow5, &z);
 
1157
        }
1093
1158
      else
1094
 
        {
1095
 
          /* Divide m by pow5 and round.  */
1096
 
          z_memory = divide (m, pow5, &z);
1097
 
        }
 
1159
        {
 
1160
          /* Divide m by pow5 and round.  */
 
1161
          z_memory = divide (m, pow5, &z);
 
1162
        }
1098
1163
    }
1099
1164
  else
1100
1165
    {
1101
1166
      pow5.limbs = pow5_ptr;
1102
1167
      pow5.nlimbs = pow5_len;
1103
1168
      if (n >= 0)
1104
 
        {
1105
 
          /* n >= 0, s < 0.
1106
 
             Multiply m with pow5, then divide by 2^|s|.  */
1107
 
          mpn_t numerator;
1108
 
          mpn_t denominator;
1109
 
          void *tmp_memory;
1110
 
          tmp_memory = multiply (m, pow5, &numerator);
1111
 
          if (tmp_memory == NULL)
1112
 
            {
1113
 
              free (pow5_ptr);
1114
 
              free (memory);
1115
 
              return NULL;
1116
 
            }
1117
 
          /* Construct 2^|s|.  */
1118
 
          {
1119
 
            mp_limb_t *ptr = pow5_ptr + pow5_len;
1120
 
            size_t i;
1121
 
            for (i = 0; i < s_limbs; i++)
1122
 
              ptr[i] = 0;
1123
 
            ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
1124
 
            denominator.limbs = ptr;
1125
 
            denominator.nlimbs = s_limbs + 1;
1126
 
          }
1127
 
          z_memory = divide (numerator, denominator, &z);
1128
 
          free (tmp_memory);
1129
 
        }
 
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
        }
1130
1195
      else
1131
 
        {
1132
 
          /* n < 0, s > 0.
1133
 
             Multiply m with 2^s, then divide by pow5.  */
1134
 
          mpn_t numerator;
1135
 
          mp_limb_t *num_ptr;
1136
 
          num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
1137
 
                                          * sizeof (mp_limb_t));
1138
 
          if (num_ptr == NULL)
1139
 
            {
1140
 
              free (pow5_ptr);
1141
 
              free (memory);
1142
 
              return NULL;
1143
 
            }
1144
 
          {
1145
 
            mp_limb_t *destptr = num_ptr;
1146
 
            {
1147
 
              size_t i;
1148
 
              for (i = 0; i < s_limbs; i++)
1149
 
                *destptr++ = 0;
1150
 
            }
1151
 
            if (s_bits > 0)
1152
 
              {
1153
 
                const mp_limb_t *sourceptr = m.limbs;
1154
 
                mp_twolimb_t accu = 0;
1155
 
                size_t count;
1156
 
                for (count = m.nlimbs; count > 0; count--)
1157
 
                  {
1158
 
                    accu += (mp_twolimb_t) *sourceptr++ << s_bits;
1159
 
                    *destptr++ = (mp_limb_t) accu;
1160
 
                    accu = accu >> GMP_LIMB_BITS;
1161
 
                  }
1162
 
                if (accu > 0)
1163
 
                  *destptr++ = (mp_limb_t) accu;
1164
 
              }
1165
 
            else
1166
 
              {
1167
 
                const mp_limb_t *sourceptr = m.limbs;
1168
 
                size_t count;
1169
 
                for (count = m.nlimbs; count > 0; count--)
1170
 
                  *destptr++ = *sourceptr++;
1171
 
              }
1172
 
            numerator.limbs = num_ptr;
1173
 
            numerator.nlimbs = destptr - num_ptr;
1174
 
          }
1175
 
          z_memory = divide (numerator, pow5, &z);
1176
 
          free (num_ptr);
1177
 
        }
 
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
        }
1178
1243
    }
1179
1244
  free (pow5_ptr);
1180
1245
  free (memory);
1198
1263
static char *
1199
1264
scale10_round_decimal_long_double (long double x, int n)
1200
1265
{
1201
 
  int e;
 
1266
  int e IF_LINT(= 0);
1202
1267
  mpn_t m;
1203
1268
  void *memory = decode_long_double (x, &e, &m);
1204
1269
  return scale10_round_decimal_decoded (e, m, memory, n);
1216
1281
static char *
1217
1282
scale10_round_decimal_double (double x, int n)
1218
1283
{
1219
 
  int e;
 
1284
  int e IF_LINT(= 0);
1220
1285
  mpn_t m;
1221
1286
  void *memory = decode_double (x, &e, &m);
1222
1287
  return scale10_round_decimal_decoded (e, m, memory, n);
1246
1311
  if (y < 0.5L)
1247
1312
    {
1248
1313
      while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1249
 
        {
1250
 
          y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1251
 
          exp -= GMP_LIMB_BITS;
1252
 
        }
 
1314
        {
 
1315
          y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
 
1316
          exp -= GMP_LIMB_BITS;
 
1317
        }
1253
1318
      if (y < (1.0L / (1 << 16)))
1254
 
        {
1255
 
          y *= 1.0L * (1 << 16);
1256
 
          exp -= 16;
1257
 
        }
 
1319
        {
 
1320
          y *= 1.0L * (1 << 16);
 
1321
          exp -= 16;
 
1322
        }
1258
1323
      if (y < (1.0L / (1 << 8)))
1259
 
        {
1260
 
          y *= 1.0L * (1 << 8);
1261
 
          exp -= 8;
1262
 
        }
 
1324
        {
 
1325
          y *= 1.0L * (1 << 8);
 
1326
          exp -= 8;
 
1327
        }
1263
1328
      if (y < (1.0L / (1 << 4)))
1264
 
        {
1265
 
          y *= 1.0L * (1 << 4);
1266
 
          exp -= 4;
1267
 
        }
 
1329
        {
 
1330
          y *= 1.0L * (1 << 4);
 
1331
          exp -= 4;
 
1332
        }
1268
1333
      if (y < (1.0L / (1 << 2)))
1269
 
        {
1270
 
          y *= 1.0L * (1 << 2);
1271
 
          exp -= 2;
1272
 
        }
 
1334
        {
 
1335
          y *= 1.0L * (1 << 2);
 
1336
          exp -= 2;
 
1337
        }
1273
1338
      if (y < (1.0L / (1 << 1)))
1274
 
        {
1275
 
          y *= 1.0L * (1 << 1);
1276
 
          exp -= 1;
1277
 
        }
 
1339
        {
 
1340
          y *= 1.0L * (1 << 1);
 
1341
          exp -= 1;
 
1342
        }
1278
1343
    }
1279
1344
  if (!(y >= 0.5L && y < 1.0L))
1280
1345
    abort ();
1303
1368
    }
1304
1369
  /* Now 0.95 <= z <= 1.01.  */
1305
1370
  z = 1 - z;
1306
 
  /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ...
 
1371
  /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1307
1372
     Four terms are enough to get an approximation with error < 10^-7.  */
1308
 
  l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
 
1373
  l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1309
1374
  /* Finally multiply with log(2)/log(10), yields an approximation for
1310
1375
     log10(x).  */
1311
1376
  l *= 0.30102999566398119523;
1337
1402
  if (y < 0.5)
1338
1403
    {
1339
1404
      while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1340
 
        {
1341
 
          y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1342
 
          exp -= GMP_LIMB_BITS;
1343
 
        }
 
1405
        {
 
1406
          y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
 
1407
          exp -= GMP_LIMB_BITS;
 
1408
        }
1344
1409
      if (y < (1.0 / (1 << 16)))
1345
 
        {
1346
 
          y *= 1.0 * (1 << 16);
1347
 
          exp -= 16;
1348
 
        }
 
1410
        {
 
1411
          y *= 1.0 * (1 << 16);
 
1412
          exp -= 16;
 
1413
        }
1349
1414
      if (y < (1.0 / (1 << 8)))
1350
 
        {
1351
 
          y *= 1.0 * (1 << 8);
1352
 
          exp -= 8;
1353
 
        }
 
1415
        {
 
1416
          y *= 1.0 * (1 << 8);
 
1417
          exp -= 8;
 
1418
        }
1354
1419
      if (y < (1.0 / (1 << 4)))
1355
 
        {
1356
 
          y *= 1.0 * (1 << 4);
1357
 
          exp -= 4;
1358
 
        }
 
1420
        {
 
1421
          y *= 1.0 * (1 << 4);
 
1422
          exp -= 4;
 
1423
        }
1359
1424
      if (y < (1.0 / (1 << 2)))
1360
 
        {
1361
 
          y *= 1.0 * (1 << 2);
1362
 
          exp -= 2;
1363
 
        }
 
1425
        {
 
1426
          y *= 1.0 * (1 << 2);
 
1427
          exp -= 2;
 
1428
        }
1364
1429
      if (y < (1.0 / (1 << 1)))
1365
 
        {
1366
 
          y *= 1.0 * (1 << 1);
1367
 
          exp -= 1;
1368
 
        }
 
1430
        {
 
1431
          y *= 1.0 * (1 << 1);
 
1432
          exp -= 1;
 
1433
        }
1369
1434
    }
1370
1435
  if (!(y >= 0.5 && y < 1.0))
1371
1436
    abort ();
1394
1459
    }
1395
1460
  /* Now 0.95 <= z <= 1.01.  */
1396
1461
  z = 1 - z;
1397
 
  /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ...
 
1462
  /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1398
1463
     Four terms are enough to get an approximation with error < 10^-7.  */
1399
 
  l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
 
1464
  l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1400
1465
  /* Finally multiply with log(2)/log(10), yields an approximation for
1401
1466
     log10(x).  */
1402
1467
  l *= 0.30102999566398119523;
1406
1471
 
1407
1472
# endif
1408
1473
 
 
1474
/* Tests whether a string of digits consists of exactly PRECISION zeroes and
 
1475
   a single '1' digit.  */
 
1476
static int
 
1477
is_borderline (const char *digits, size_t precision)
 
1478
{
 
1479
  for (; precision > 0; precision--, digits++)
 
1480
    if (*digits != '0')
 
1481
      return 0;
 
1482
  if (*digits != '1')
 
1483
    return 0;
 
1484
  digits++;
 
1485
  return *digits == '\0';
 
1486
}
 
1487
 
 
1488
#endif
 
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
 
1409
1740
#endif
1410
1741
 
1411
1742
DCHAR_T *
1412
1743
VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
1413
 
            const FCHAR_T *format, va_list args)
 
1744
            const FCHAR_T *format, va_list args)
1414
1745
{
1415
1746
  DIRECTIVES d;
1416
1747
  arguments a;
1420
1751
    return NULL;
1421
1752
 
1422
1753
#define CLEANUP() \
1423
 
  free (d.dir);                                                         \
1424
 
  if (a.arg)                                                            \
 
1754
  free (d.dir);                                                         \
 
1755
  if (a.arg)                                                            \
1425
1756
    free (a.arg);
1426
1757
 
1427
1758
  if (PRINTF_FETCHARGS (args, &a) < 0)
1450
1781
#if HAVE_ALLOCA
1451
1782
    if (buf_neededlength < 4000 / sizeof (TCHAR_T))
1452
1783
      {
1453
 
        buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
1454
 
        buf_malloced = NULL;
 
1784
        buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
 
1785
        buf_malloced = NULL;
1455
1786
      }
1456
1787
    else
1457
1788
#endif
1458
1789
      {
1459
 
        size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
1460
 
        if (size_overflow_p (buf_memsize))
1461
 
          goto out_of_memory_1;
1462
 
        buf = (TCHAR_T *) malloc (buf_memsize);
1463
 
        if (buf == NULL)
1464
 
          goto out_of_memory_1;
1465
 
        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;
1466
1797
      }
1467
1798
 
1468
1799
    if (resultbuf != NULL)
1469
1800
      {
1470
 
        result = resultbuf;
1471
 
        allocated = *lengthp;
 
1801
        result = resultbuf;
 
1802
        allocated = *lengthp;
1472
1803
      }
1473
1804
    else
1474
1805
      {
1475
 
        result = NULL;
1476
 
        allocated = 0;
 
1806
        result = NULL;
 
1807
        allocated = 0;
1477
1808
      }
1478
1809
    length = 0;
1479
1810
    /* Invariants:
1483
1814
    /* Ensures that allocated >= needed.  Aborts through a jump to
1484
1815
       out_of_memory if needed is SIZE_MAX or otherwise too big.  */
1485
1816
#define ENSURE_ALLOCATION(needed) \
1486
 
    if ((needed) > allocated)                                                \
1487
 
      {                                                                      \
1488
 
        size_t memory_size;                                                  \
1489
 
        DCHAR_T *memory;                                                     \
1490
 
                                                                             \
1491
 
        allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);            \
1492
 
        if ((needed) > allocated)                                            \
1493
 
          allocated = (needed);                                              \
1494
 
        memory_size = xtimes (allocated, sizeof (DCHAR_T));                  \
1495
 
        if (size_overflow_p (memory_size))                                   \
1496
 
          goto out_of_memory;                                                \
1497
 
        if (result == resultbuf || result == NULL)                           \
1498
 
          memory = (DCHAR_T *) malloc (memory_size);                         \
1499
 
        else                                                                 \
1500
 
          memory = (DCHAR_T *) realloc (result, memory_size);                \
1501
 
        if (memory == NULL)                                                  \
1502
 
          goto out_of_memory;                                                \
1503
 
        if (result == resultbuf && length > 0)                               \
1504
 
          DCHAR_CPY (memory, result, length);                                \
1505
 
        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;                                                     \
1506
1837
      }
1507
1838
 
1508
1839
    for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
1509
1840
      {
1510
 
        if (cp != dp->dir_start)
1511
 
          {
1512
 
            size_t n = dp->dir_start - cp;
1513
 
            size_t augmented_length = xsum (length, n);
1514
 
 
1515
 
            ENSURE_ALLOCATION (augmented_length);
1516
 
            /* This copies a piece of FCHAR_T[] into a DCHAR_T[].  Here we
1517
 
               need that the format string contains only ASCII characters
1518
 
               if FCHAR_T and DCHAR_T are not the same type.  */
1519
 
            if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
1520
 
              {
1521
 
                DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
1522
 
                length = augmented_length;
1523
 
              }
1524
 
            else
1525
 
              {
1526
 
                do
1527
 
                  result[length++] = (unsigned char) *cp++;
1528
 
                while (--n > 0);
1529
 
              }
1530
 
          }
1531
 
        if (i == d.count)
1532
 
          break;
1533
 
 
1534
 
        /* Execute a single directive.  */
1535
 
        if (dp->conversion == '%')
1536
 
          {
1537
 
            size_t augmented_length;
1538
 
 
1539
 
            if (!(dp->arg_index == ARG_NONE))
1540
 
              abort ();
1541
 
            augmented_length = xsum (length, 1);
1542
 
            ENSURE_ALLOCATION (augmented_length);
1543
 
            result[length] = '%';
1544
 
            length = augmented_length;
1545
 
          }
1546
 
        else
1547
 
          {
1548
 
            if (!(dp->arg_index != ARG_NONE))
1549
 
              abort ();
1550
 
 
1551
 
            if (dp->conversion == 'n')
1552
 
              {
1553
 
                switch (a.arg[dp->arg_index].type)
1554
 
                  {
1555
 
                  case TYPE_COUNT_SCHAR_POINTER:
1556
 
                    *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
1557
 
                    break;
1558
 
                  case TYPE_COUNT_SHORT_POINTER:
1559
 
                    *a.arg[dp->arg_index].a.a_count_short_pointer = length;
1560
 
                    break;
1561
 
                  case TYPE_COUNT_INT_POINTER:
1562
 
                    *a.arg[dp->arg_index].a.a_count_int_pointer = length;
1563
 
                    break;
1564
 
                  case TYPE_COUNT_LONGINT_POINTER:
1565
 
                    *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
1566
 
                    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;
1567
1898
#if HAVE_LONG_LONG_INT
1568
 
                  case TYPE_COUNT_LONGLONGINT_POINTER:
1569
 
                    *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
1570
 
                    break;
 
1899
                  case TYPE_COUNT_LONGLONGINT_POINTER:
 
1900
                    *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
 
1901
                    break;
1571
1902
#endif
1572
 
                  default:
1573
 
                    abort ();
1574
 
                  }
1575
 
              }
 
1903
                  default:
 
1904
                    abort ();
 
1905
                  }
 
1906
              }
1576
1907
#if ENABLE_UNISTDIO
1577
 
            /* The unistdio extensions.  */
1578
 
            else if (dp->conversion == 'U')
1579
 
              {
1580
 
                arg_type type = a.arg[dp->arg_index].type;
1581
 
                int flags = dp->flags;
1582
 
                int has_width;
1583
 
                size_t width;
1584
 
                int has_precision;
1585
 
                size_t precision;
1586
 
 
1587
 
                has_width = 0;
1588
 
                width = 0;
1589
 
                if (dp->width_start != dp->width_end)
1590
 
                  {
1591
 
                    if (dp->width_arg_index != ARG_NONE)
1592
 
                      {
1593
 
                        int arg;
1594
 
 
1595
 
                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
1596
 
                          abort ();
1597
 
                        arg = a.arg[dp->width_arg_index].a.a_int;
1598
 
                        if (arg < 0)
1599
 
                          {
1600
 
                            /* "A negative field width is taken as a '-' flag
1601
 
                                followed by a positive field width."  */
1602
 
                            flags |= FLAG_LEFT;
1603
 
                            width = (unsigned int) (-arg);
1604
 
                          }
1605
 
                        else
1606
 
                          width = arg;
1607
 
                      }
1608
 
                    else
1609
 
                      {
1610
 
                        const FCHAR_T *digitp = dp->width_start;
1611
 
 
1612
 
                        do
1613
 
                          width = xsum (xtimes (width, 10), *digitp++ - '0');
1614
 
                        while (digitp != dp->width_end);
1615
 
                      }
1616
 
                    has_width = 1;
1617
 
                  }
1618
 
 
1619
 
                has_precision = 0;
1620
 
                precision = 0;
1621
 
                if (dp->precision_start != dp->precision_end)
1622
 
                  {
1623
 
                    if (dp->precision_arg_index != ARG_NONE)
1624
 
                      {
1625
 
                        int arg;
1626
 
 
1627
 
                        if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1628
 
                          abort ();
1629
 
                        arg = a.arg[dp->precision_arg_index].a.a_int;
1630
 
                        /* "A negative precision is taken as if the precision
1631
 
                            were omitted."  */
1632
 
                        if (arg >= 0)
1633
 
                          {
1634
 
                            precision = arg;
1635
 
                            has_precision = 1;
1636
 
                          }
1637
 
                      }
1638
 
                    else
1639
 
                      {
1640
 
                        const FCHAR_T *digitp = dp->precision_start + 1;
1641
 
 
1642
 
                        precision = 0;
1643
 
                        while (digitp != dp->precision_end)
1644
 
                          precision = xsum (xtimes (precision, 10), *digitp++ - '0');
1645
 
                        has_precision = 1;
1646
 
                      }
1647
 
                  }
1648
 
 
1649
 
                switch (type)
1650
 
                  {
1651
 
                  case TYPE_U8_STRING:
1652
 
                    {
1653
 
                      const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
1654
 
                      const uint8_t *arg_end;
1655
 
                      size_t characters;
1656
 
 
1657
 
                      if (has_precision)
1658
 
                        {
1659
 
                          /* Use only PRECISION characters, from the left.  */
1660
 
                          arg_end = arg;
1661
 
                          characters = 0;
1662
 
                          for (; precision > 0; precision--)
1663
 
                            {
1664
 
                              int count = u8_strmblen (arg_end);
1665
 
                              if (count == 0)
1666
 
                                break;
1667
 
                              if (count < 0)
1668
 
                                {
1669
 
                                  if (!(result == resultbuf || result == NULL))
1670
 
                                    free (result);
1671
 
                                  if (buf_malloced != NULL)
1672
 
                                    free (buf_malloced);
1673
 
                                  CLEANUP ();
1674
 
                                  errno = EILSEQ;
1675
 
                                  return NULL;
1676
 
                                }
1677
 
                              arg_end += count;
1678
 
                              characters++;
1679
 
                            }
1680
 
                        }
1681
 
                      else if (has_width)
1682
 
                        {
1683
 
                          /* Use the entire string, and count the number of
1684
 
                             characters.  */
1685
 
                          arg_end = arg;
1686
 
                          characters = 0;
1687
 
                          for (;;)
1688
 
                            {
1689
 
                              int count = u8_strmblen (arg_end);
1690
 
                              if (count == 0)
1691
 
                                break;
1692
 
                              if (count < 0)
1693
 
                                {
1694
 
                                  if (!(result == resultbuf || result == NULL))
1695
 
                                    free (result);
1696
 
                                  if (buf_malloced != NULL)
1697
 
                                    free (buf_malloced);
1698
 
                                  CLEANUP ();
1699
 
                                  errno = EILSEQ;
1700
 
                                  return NULL;
1701
 
                                }
1702
 
                              arg_end += count;
1703
 
                              characters++;
1704
 
                            }
1705
 
                        }
1706
 
                      else
1707
 
                        {
1708
 
                          /* Use the entire string.  */
1709
 
                          arg_end = arg + u8_strlen (arg);
1710
 
                          /* The number of characters doesn't matter.  */
1711
 
                          characters = 0;
1712
 
                        }
1713
 
 
1714
 
                      if (has_width && width > characters
1715
 
                          && !(dp->flags & FLAG_LEFT))
1716
 
                        {
1717
 
                          size_t n = width - characters;
1718
 
                          ENSURE_ALLOCATION (xsum (length, n));
1719
 
                          DCHAR_SET (result + length, ' ', n);
1720
 
                          length += n;
1721
 
                        }
 
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
                        }
1722
2053
 
1723
2054
# if DCHAR_IS_UINT8_T
1724
 
                      {
1725
 
                        size_t n = arg_end - arg;
1726
 
                        ENSURE_ALLOCATION (xsum (length, n));
1727
 
                        DCHAR_CPY (result + length, arg, n);
1728
 
                        length += n;
1729
 
                      }
 
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
                      }
1730
2061
# else
1731
 
                      { /* Convert.  */
1732
 
                        DCHAR_T *converted = result + length;
1733
 
                        size_t converted_len = allocated - length;
 
2062
                      { /* Convert.  */
 
2063
                        DCHAR_T *converted = result + length;
 
2064
                        size_t converted_len = allocated - length;
1734
2065
#  if DCHAR_IS_TCHAR
1735
 
                        /* Convert from UTF-8 to locale encoding.  */
1736
 
                        if (u8_conv_to_encoding (locale_charset (),
1737
 
                                                 iconveh_question_mark,
1738
 
                                                 arg, arg_end - arg, NULL,
1739
 
                                                 &converted, &converted_len)
1740
 
                            < 0)
 
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);
1741
2072
#  else
1742
 
                        /* Convert from UTF-8 to UTF-16/UTF-32.  */
1743
 
                        converted =
1744
 
                          U8_TO_DCHAR (arg, arg_end - arg,
1745
 
                                       converted, &converted_len);
1746
 
                        if (converted == NULL)
 
2073
                        /* Convert from UTF-8 to UTF-16/UTF-32.  */
 
2074
                        converted =
 
2075
                          U8_TO_DCHAR (arg, arg_end - arg,
 
2076
                                       converted, &converted_len);
1747
2077
#  endif
1748
 
                          {
1749
 
                            int saved_errno = errno;
1750
 
                            if (!(result == resultbuf || result == NULL))
1751
 
                              free (result);
1752
 
                            if (buf_malloced != NULL)
1753
 
                              free (buf_malloced);
1754
 
                            CLEANUP ();
1755
 
                            errno = saved_errno;
1756
 
                            return NULL;
1757
 
                          }
1758
 
                        if (converted != result + length)
1759
 
                          {
1760
 
                            ENSURE_ALLOCATION (xsum (length, converted_len));
1761
 
                            DCHAR_CPY (result + length, converted, converted_len);
1762
 
                            free (converted);
1763
 
                          }
1764
 
                        length += converted_len;
1765
 
                      }
 
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
                      }
1766
2097
# endif
1767
2098
 
1768
 
                      if (has_width && width > characters
1769
 
                          && (dp->flags & FLAG_LEFT))
1770
 
                        {
1771
 
                          size_t n = width - characters;
1772
 
                          ENSURE_ALLOCATION (xsum (length, n));
1773
 
                          DCHAR_SET (result + length, ' ', n);
1774
 
                          length += n;
1775
 
                        }
1776
 
                    }
1777
 
                    break;
1778
 
 
1779
 
                  case TYPE_U16_STRING:
1780
 
                    {
1781
 
                      const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
1782
 
                      const uint16_t *arg_end;
1783
 
                      size_t characters;
1784
 
 
1785
 
                      if (has_precision)
1786
 
                        {
1787
 
                          /* Use only PRECISION characters, from the left.  */
1788
 
                          arg_end = arg;
1789
 
                          characters = 0;
1790
 
                          for (; precision > 0; precision--)
1791
 
                            {
1792
 
                              int count = u16_strmblen (arg_end);
1793
 
                              if (count == 0)
1794
 
                                break;
1795
 
                              if (count < 0)
1796
 
                                {
1797
 
                                  if (!(result == resultbuf || result == NULL))
1798
 
                                    free (result);
1799
 
                                  if (buf_malloced != NULL)
1800
 
                                    free (buf_malloced);
1801
 
                                  CLEANUP ();
1802
 
                                  errno = EILSEQ;
1803
 
                                  return NULL;
1804
 
                                }
1805
 
                              arg_end += count;
1806
 
                              characters++;
1807
 
                            }
1808
 
                        }
1809
 
                      else if (has_width)
1810
 
                        {
1811
 
                          /* Use the entire string, and count the number of
1812
 
                             characters.  */
1813
 
                          arg_end = arg;
1814
 
                          characters = 0;
1815
 
                          for (;;)
1816
 
                            {
1817
 
                              int count = u16_strmblen (arg_end);
1818
 
                              if (count == 0)
1819
 
                                break;
1820
 
                              if (count < 0)
1821
 
                                {
1822
 
                                  if (!(result == resultbuf || result == NULL))
1823
 
                                    free (result);
1824
 
                                  if (buf_malloced != NULL)
1825
 
                                    free (buf_malloced);
1826
 
                                  CLEANUP ();
1827
 
                                  errno = EILSEQ;
1828
 
                                  return NULL;
1829
 
                                }
1830
 
                              arg_end += count;
1831
 
                              characters++;
1832
 
                            }
1833
 
                        }
1834
 
                      else
1835
 
                        {
1836
 
                          /* Use the entire string.  */
1837
 
                          arg_end = arg + u16_strlen (arg);
1838
 
                          /* The number of characters doesn't matter.  */
1839
 
                          characters = 0;
1840
 
                        }
1841
 
 
1842
 
                      if (has_width && width > characters
1843
 
                          && !(dp->flags & FLAG_LEFT))
1844
 
                        {
1845
 
                          size_t n = width - characters;
1846
 
                          ENSURE_ALLOCATION (xsum (length, n));
1847
 
                          DCHAR_SET (result + length, ' ', n);
1848
 
                          length += n;
1849
 
                        }
 
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
                        }
1850
2181
 
1851
2182
# if DCHAR_IS_UINT16_T
1852
 
                      {
1853
 
                        size_t n = arg_end - arg;
1854
 
                        ENSURE_ALLOCATION (xsum (length, n));
1855
 
                        DCHAR_CPY (result + length, arg, n);
1856
 
                        length += n;
1857
 
                      }
 
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
                      }
1858
2189
# else
1859
 
                      { /* Convert.  */
1860
 
                        DCHAR_T *converted = result + length;
1861
 
                        size_t converted_len = allocated - length;
 
2190
                      { /* Convert.  */
 
2191
                        DCHAR_T *converted = result + length;
 
2192
                        size_t converted_len = allocated - length;
1862
2193
#  if DCHAR_IS_TCHAR
1863
 
                        /* Convert from UTF-16 to locale encoding.  */
1864
 
                        if (u16_conv_to_encoding (locale_charset (),
1865
 
                                                  iconveh_question_mark,
1866
 
                                                  arg, arg_end - arg, NULL,
1867
 
                                                  &converted, &converted_len)
1868
 
                            < 0)
 
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);
1869
2200
#  else
1870
 
                        /* Convert from UTF-16 to UTF-8/UTF-32.  */
1871
 
                        converted =
1872
 
                          U16_TO_DCHAR (arg, arg_end - arg,
1873
 
                                        converted, &converted_len);
1874
 
                        if (converted == NULL)
 
2201
                        /* Convert from UTF-16 to UTF-8/UTF-32.  */
 
2202
                        converted =
 
2203
                          U16_TO_DCHAR (arg, arg_end - arg,
 
2204
                                        converted, &converted_len);
1875
2205
#  endif
1876
 
                          {
1877
 
                            int saved_errno = errno;
1878
 
                            if (!(result == resultbuf || result == NULL))
1879
 
                              free (result);
1880
 
                            if (buf_malloced != NULL)
1881
 
                              free (buf_malloced);
1882
 
                            CLEANUP ();
1883
 
                            errno = saved_errno;
1884
 
                            return NULL;
1885
 
                          }
1886
 
                        if (converted != result + length)
1887
 
                          {
1888
 
                            ENSURE_ALLOCATION (xsum (length, converted_len));
1889
 
                            DCHAR_CPY (result + length, converted, converted_len);
1890
 
                            free (converted);
1891
 
                          }
1892
 
                        length += converted_len;
1893
 
                      }
 
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
                      }
1894
2225
# endif
1895
2226
 
1896
 
                      if (has_width && width > characters
1897
 
                          && (dp->flags & FLAG_LEFT))
1898
 
                        {
1899
 
                          size_t n = width - characters;
1900
 
                          ENSURE_ALLOCATION (xsum (length, n));
1901
 
                          DCHAR_SET (result + length, ' ', n);
1902
 
                          length += n;
1903
 
                        }
1904
 
                    }
1905
 
                    break;
1906
 
 
1907
 
                  case TYPE_U32_STRING:
1908
 
                    {
1909
 
                      const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
1910
 
                      const uint32_t *arg_end;
1911
 
                      size_t characters;
1912
 
 
1913
 
                      if (has_precision)
1914
 
                        {
1915
 
                          /* Use only PRECISION characters, from the left.  */
1916
 
                          arg_end = arg;
1917
 
                          characters = 0;
1918
 
                          for (; precision > 0; precision--)
1919
 
                            {
1920
 
                              int count = u32_strmblen (arg_end);
1921
 
                              if (count == 0)
1922
 
                                break;
1923
 
                              if (count < 0)
1924
 
                                {
1925
 
                                  if (!(result == resultbuf || result == NULL))
1926
 
                                    free (result);
1927
 
                                  if (buf_malloced != NULL)
1928
 
                                    free (buf_malloced);
1929
 
                                  CLEANUP ();
1930
 
                                  errno = EILSEQ;
1931
 
                                  return NULL;
1932
 
                                }
1933
 
                              arg_end += count;
1934
 
                              characters++;
1935
 
                            }
1936
 
                        }
1937
 
                      else if (has_width)
1938
 
                        {
1939
 
                          /* Use the entire string, and count the number of
1940
 
                             characters.  */
1941
 
                          arg_end = arg;
1942
 
                          characters = 0;
1943
 
                          for (;;)
1944
 
                            {
1945
 
                              int count = u32_strmblen (arg_end);
1946
 
                              if (count == 0)
1947
 
                                break;
1948
 
                              if (count < 0)
1949
 
                                {
1950
 
                                  if (!(result == resultbuf || result == NULL))
1951
 
                                    free (result);
1952
 
                                  if (buf_malloced != NULL)
1953
 
                                    free (buf_malloced);
1954
 
                                  CLEANUP ();
1955
 
                                  errno = EILSEQ;
1956
 
                                  return NULL;
1957
 
                                }
1958
 
                              arg_end += count;
1959
 
                              characters++;
1960
 
                            }
1961
 
                        }
1962
 
                      else
1963
 
                        {
1964
 
                          /* Use the entire string.  */
1965
 
                          arg_end = arg + u32_strlen (arg);
1966
 
                          /* The number of characters doesn't matter.  */
1967
 
                          characters = 0;
1968
 
                        }
1969
 
 
1970
 
                      if (has_width && width > characters
1971
 
                          && !(dp->flags & FLAG_LEFT))
1972
 
                        {
1973
 
                          size_t n = width - characters;
1974
 
                          ENSURE_ALLOCATION (xsum (length, n));
1975
 
                          DCHAR_SET (result + length, ' ', n);
1976
 
                          length += n;
1977
 
                        }
 
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
                        }
1978
2309
 
1979
2310
# if DCHAR_IS_UINT32_T
1980
 
                      {
1981
 
                        size_t n = arg_end - arg;
1982
 
                        ENSURE_ALLOCATION (xsum (length, n));
1983
 
                        DCHAR_CPY (result + length, arg, n);
1984
 
                        length += n;
1985
 
                      }
1986
 
# else
1987
 
                      { /* Convert.  */
1988
 
                        DCHAR_T *converted = result + length;
1989
 
                        size_t converted_len = allocated - length;
1990
 
#  if DCHAR_IS_TCHAR
1991
 
                        /* Convert from UTF-32 to locale encoding.  */
1992
 
                        if (u32_conv_to_encoding (locale_charset (),
1993
 
                                                  iconveh_question_mark,
1994
 
                                                  arg, arg_end - arg, NULL,
1995
 
                                                  &converted, &converted_len)
1996
 
                            < 0)
1997
 
#  else
1998
 
                        /* Convert from UTF-32 to UTF-8/UTF-16.  */
1999
 
                        converted =
2000
 
                          U32_TO_DCHAR (arg, arg_end - arg,
2001
 
                                        converted, &converted_len);
2002
 
                        if (converted == NULL)
2003
 
#  endif
2004
 
                          {
2005
 
                            int saved_errno = errno;
2006
 
                            if (!(result == resultbuf || result == NULL))
2007
 
                              free (result);
2008
 
                            if (buf_malloced != NULL)
2009
 
                              free (buf_malloced);
2010
 
                            CLEANUP ();
2011
 
                            errno = saved_errno;
2012
 
                            return NULL;
2013
 
                          }
2014
 
                        if (converted != result + length)
2015
 
                          {
2016
 
                            ENSURE_ALLOCATION (xsum (length, converted_len));
2017
 
                            DCHAR_CPY (result + length, converted, converted_len);
2018
 
                            free (converted);
2019
 
                          }
2020
 
                        length += converted_len;
2021
 
                      }
2022
 
# endif
2023
 
 
2024
 
                      if (has_width && width > characters
2025
 
                          && (dp->flags & FLAG_LEFT))
2026
 
                        {
2027
 
                          size_t n = width - characters;
2028
 
                          ENSURE_ALLOCATION (xsum (length, n));
2029
 
                          DCHAR_SET (result + length, ' ', n);
2030
 
                          length += n;
2031
 
                        }
2032
 
                    }
2033
 
                    break;
2034
 
 
2035
 
                  default:
2036
 
                    abort ();
2037
 
                  }
2038
 
              }
 
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
                      }
 
2317
# else
 
2318
                      { /* Convert.  */
 
2319
                        DCHAR_T *converted = result + length;
 
2320
                        size_t converted_len = allocated - length;
 
2321
#  if DCHAR_IS_TCHAR
 
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);
 
2328
#  else
 
2329
                        /* Convert from UTF-32 to UTF-8/UTF-16.  */
 
2330
                        converted =
 
2331
                          U32_TO_DCHAR (arg, arg_end - arg,
 
2332
                                        converted, &converted_len);
 
2333
#  endif
 
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
                      }
 
2353
# endif
 
2354
 
 
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;
 
2365
 
 
2366
                  default:
 
2367
                    abort ();
 
2368
                  }
 
2369
              }
 
2370
#endif
 
2371
#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
 
2372
            else if (dp->conversion == 's'
 
2373
# if WIDE_CHAR_VERSION
 
2374
                     && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
 
2375
# else
 
2376
                     && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
 
2377
# endif
 
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
                  }
 
2457
 
 
2458
# if WIDE_CHAR_VERSION
 
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
                }
 
2616
# else
 
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));
 
2735
#   endif
 
2736
                    for (remaining = characters; remaining > 0; )
 
2737
                      {
 
2738
                        char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
 
2739
                        int count;
 
2740
 
 
2741
                        if (*arg == 0)
 
2742
                          abort ();
 
2743
#   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
 
2744
                        count = wcrtomb (cbuf, *arg, &state);
 
2745
#   else
 
2746
                        count = wctomb (cbuf, *arg);
 
2747
#   endif
 
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
                  }
 
2759
 
 
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);
 
2780
#  endif
 
2781
 
 
2782
                  if (has_width)
 
2783
                    {
 
2784
#  if ENABLE_UNISTDIO
 
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);
 
2789
#  else
 
2790
                      /* The width is compared against the number of _bytes_
 
2791
                         of the converted value, says POSIX.  */
 
2792
                      w = characters;
 
2793
#  endif
 
2794
                    }
 
2795
                  else
 
2796
                    /* w doesn't matter.  */
 
2797
                    w = 0;
 
2798
 
 
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
                    }
 
2807
 
 
2808
#  if DCHAR_IS_TCHAR
 
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
                    }
 
2876
#  else
 
2877
                  ENSURE_ALLOCATION (xsum (length, tmpdst_len));
 
2878
                  DCHAR_CPY (result + length, tmpdst, tmpdst_len);
 
2879
                  free (tmpdst);
 
2880
                  length += tmpdst_len;
 
2881
#  endif
 
2882
 
 
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
                }
 
2892
# endif
 
2893
              }
2039
2894
#endif
2040
2895
#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
2041
 
            else if ((dp->conversion == 'a' || dp->conversion == 'A')
 
2896
            else if ((dp->conversion == 'a' || dp->conversion == 'A')
2042
2897
# if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
2043
 
                     && (0
 
2898
                     && (0
2044
2899
#  if NEED_PRINTF_DOUBLE
2045
 
                         || a.arg[dp->arg_index].type == TYPE_DOUBLE
 
2900
                         || a.arg[dp->arg_index].type == TYPE_DOUBLE
2046
2901
#  endif
2047
2902
#  if NEED_PRINTF_LONG_DOUBLE
2048
 
                         || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
 
2903
                         || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2049
2904
#  endif
2050
 
                        )
 
2905
                        )
2051
2906
# endif
2052
 
                    )
2053
 
              {
2054
 
                arg_type type = a.arg[dp->arg_index].type;
2055
 
                int flags = dp->flags;
2056
 
                int has_width;
2057
 
                size_t width;
2058
 
                int has_precision;
2059
 
                size_t precision;
2060
 
                size_t tmp_length;
2061
 
                DCHAR_T tmpbuf[700];
2062
 
                DCHAR_T *tmp;
2063
 
                DCHAR_T *pad_ptr;
2064
 
                DCHAR_T *p;
2065
 
 
2066
 
                has_width = 0;
2067
 
                width = 0;
2068
 
                if (dp->width_start != dp->width_end)
2069
 
                  {
2070
 
                    if (dp->width_arg_index != ARG_NONE)
2071
 
                      {
2072
 
                        int arg;
2073
 
 
2074
 
                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2075
 
                          abort ();
2076
 
                        arg = a.arg[dp->width_arg_index].a.a_int;
2077
 
                        if (arg < 0)
2078
 
                          {
2079
 
                            /* "A negative field width is taken as a '-' flag
2080
 
                                followed by a positive field width."  */
2081
 
                            flags |= FLAG_LEFT;
2082
 
                            width = (unsigned int) (-arg);
2083
 
                          }
2084
 
                        else
2085
 
                          width = arg;
2086
 
                      }
2087
 
                    else
2088
 
                      {
2089
 
                        const FCHAR_T *digitp = dp->width_start;
2090
 
 
2091
 
                        do
2092
 
                          width = xsum (xtimes (width, 10), *digitp++ - '0');
2093
 
                        while (digitp != dp->width_end);
2094
 
                      }
2095
 
                    has_width = 1;
2096
 
                  }
2097
 
 
2098
 
                has_precision = 0;
2099
 
                precision = 0;
2100
 
                if (dp->precision_start != dp->precision_end)
2101
 
                  {
2102
 
                    if (dp->precision_arg_index != ARG_NONE)
2103
 
                      {
2104
 
                        int arg;
2105
 
 
2106
 
                        if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2107
 
                          abort ();
2108
 
                        arg = a.arg[dp->precision_arg_index].a.a_int;
2109
 
                        /* "A negative precision is taken as if the precision
2110
 
                            were omitted."  */
2111
 
                        if (arg >= 0)
2112
 
                          {
2113
 
                            precision = arg;
2114
 
                            has_precision = 1;
2115
 
                          }
2116
 
                      }
2117
 
                    else
2118
 
                      {
2119
 
                        const FCHAR_T *digitp = dp->precision_start + 1;
2120
 
 
2121
 
                        precision = 0;
2122
 
                        while (digitp != dp->precision_end)
2123
 
                          precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2124
 
                        has_precision = 1;
2125
 
                      }
2126
 
                  }
2127
 
 
2128
 
                /* Allocate a temporary buffer of sufficient size.  */
2129
 
                if (type == TYPE_LONGDOUBLE)
2130
 
                  tmp_length =
2131
 
                    (unsigned int) ((LDBL_DIG + 1)
2132
 
                                    * 0.831 /* decimal -> hexadecimal */
2133
 
                                   )
2134
 
                    + 1; /* turn floor into ceil */
2135
 
                else
2136
 
                  tmp_length =
2137
 
                    (unsigned int) ((DBL_DIG + 1)
2138
 
                                    * 0.831 /* decimal -> hexadecimal */
2139
 
                                   )
2140
 
                    + 1; /* turn floor into ceil */
2141
 
                if (tmp_length < precision)
2142
 
                  tmp_length = precision;
2143
 
                /* Account for sign, decimal point etc. */
2144
 
                tmp_length = xsum (tmp_length, 12);
2145
 
 
2146
 
                if (tmp_length < width)
2147
 
                  tmp_length = width;
2148
 
 
2149
 
                tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
2150
 
 
2151
 
                if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
2152
 
                  tmp = tmpbuf;
2153
 
                else
2154
 
                  {
2155
 
                    size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
2156
 
 
2157
 
                    if (size_overflow_p (tmp_memsize))
2158
 
                      /* Overflow, would lead to out of memory.  */
2159
 
                      goto out_of_memory;
2160
 
                    tmp = (DCHAR_T *) malloc (tmp_memsize);
2161
 
                    if (tmp == NULL)
2162
 
                      /* Out of memory.  */
2163
 
                      goto out_of_memory;
2164
 
                  }
2165
 
 
2166
 
                pad_ptr = NULL;
2167
 
                p = tmp;
2168
 
                if (type == TYPE_LONGDOUBLE)
2169
 
                  {
 
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
                  {
2170
3025
# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
2171
 
                    long double arg = a.arg[dp->arg_index].a.a_longdouble;
2172
 
 
2173
 
                    if (isnanl (arg))
2174
 
                      {
2175
 
                        if (dp->conversion == 'A')
2176
 
                          {
2177
 
                            *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
2178
 
                          }
2179
 
                        else
2180
 
                          {
2181
 
                            *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
2182
 
                          }
2183
 
                      }
2184
 
                    else
2185
 
                      {
2186
 
                        int sign = 0;
2187
 
                        DECL_LONG_DOUBLE_ROUNDING
2188
 
 
2189
 
                        BEGIN_LONG_DOUBLE_ROUNDING ();
2190
 
 
2191
 
                        if (signbit (arg)) /* arg < 0.0L or negative zero */
2192
 
                          {
2193
 
                            sign = -1;
2194
 
                            arg = -arg;
2195
 
                          }
2196
 
 
2197
 
                        if (sign < 0)
2198
 
                          *p++ = '-';
2199
 
                        else if (flags & FLAG_SHOWSIGN)
2200
 
                          *p++ = '+';
2201
 
                        else if (flags & FLAG_SPACE)
2202
 
                          *p++ = ' ';
2203
 
 
2204
 
                        if (arg > 0.0L && arg + arg == arg)
2205
 
                          {
2206
 
                            if (dp->conversion == 'A')
2207
 
                              {
2208
 
                                *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
2209
 
                              }
2210
 
                            else
2211
 
                              {
2212
 
                                *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
2213
 
                              }
2214
 
                          }
2215
 
                        else
2216
 
                          {
2217
 
                            int exponent;
2218
 
                            long double mantissa;
2219
 
 
2220
 
                            if (arg > 0.0L)
2221
 
                              mantissa = printf_frexpl (arg, &exponent);
2222
 
                            else
2223
 
                              {
2224
 
                                exponent = 0;
2225
 
                                mantissa = 0.0L;
2226
 
                              }
2227
 
 
2228
 
                            if (has_precision
2229
 
                                && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
2230
 
                              {
2231
 
                                /* Round the mantissa.  */
2232
 
                                long double tail = mantissa;
2233
 
                                size_t q;
2234
 
 
2235
 
                                for (q = precision; ; q--)
2236
 
                                  {
2237
 
                                    int digit = (int) tail;
2238
 
                                    tail -= digit;
2239
 
                                    if (q == 0)
2240
 
                                      {
2241
 
                                        if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
2242
 
                                          tail = 1 - tail;
2243
 
                                        else
2244
 
                                          tail = - tail;
2245
 
                                        break;
2246
 
                                      }
2247
 
                                    tail *= 16.0L;
2248
 
                                  }
2249
 
                                if (tail != 0.0L)
2250
 
                                  for (q = precision; q > 0; q--)
2251
 
                                    tail *= 0.0625L;
2252
 
                                mantissa += tail;
2253
 
                              }
2254
 
 
2255
 
                            *p++ = '0';
2256
 
                            *p++ = dp->conversion - 'A' + 'X';
2257
 
                            pad_ptr = p;
2258
 
                            {
2259
 
                              int digit;
2260
 
 
2261
 
                              digit = (int) mantissa;
2262
 
                              mantissa -= digit;
2263
 
                              *p++ = '0' + digit;
2264
 
                              if ((flags & FLAG_ALT)
2265
 
                                  || mantissa > 0.0L || precision > 0)
2266
 
                                {
2267
 
                                  *p++ = decimal_point_char ();
2268
 
                                  /* This loop terminates because we assume
2269
 
                                     that FLT_RADIX is a power of 2.  */
2270
 
                                  while (mantissa > 0.0L)
2271
 
                                    {
2272
 
                                      mantissa *= 16.0L;
2273
 
                                      digit = (int) mantissa;
2274
 
                                      mantissa -= digit;
2275
 
                                      *p++ = digit
2276
 
                                             + (digit < 10
2277
 
                                                ? '0'
2278
 
                                                : dp->conversion - 10);
2279
 
                                      if (precision > 0)
2280
 
                                        precision--;
2281
 
                                    }
2282
 
                                  while (precision > 0)
2283
 
                                    {
2284
 
                                      *p++ = '0';
2285
 
                                      precision--;
2286
 
                                    }
2287
 
                                }
2288
 
                              }
2289
 
                              *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';
2290
3145
#  if WIDE_CHAR_VERSION
2291
 
                              {
2292
 
                                static const wchar_t decimal_format[] =
2293
 
                                  { '%', '+', 'd', '\0' };
2294
 
                                SNPRINTF (p, 6 + 1, decimal_format, exponent);
2295
 
                              }
2296
 
                              while (*p != '\0')
2297
 
                                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++;
2298
3153
#  else
2299
 
                              if (sizeof (DCHAR_T) == 1)
2300
 
                                {
2301
 
                                  sprintf ((char *) p, "%+d", exponent);
2302
 
                                  while (*p != '\0')
2303
 
                                    p++;
2304
 
                                }
2305
 
                              else
2306
 
                                {
2307
 
                                  char expbuf[6 + 1];
2308
 
                                  const char *ep;
2309
 
                                  sprintf (expbuf, "%+d", exponent);
2310
 
                                  for (ep = expbuf; (*p = *ep) != '\0'; ep++)
2311
 
                                    p++;
2312
 
                                }
 
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
                                }
2313
3168
#  endif
2314
 
                          }
 
3169
                          }
2315
3170
 
2316
 
                        END_LONG_DOUBLE_ROUNDING ();
2317
 
                      }
 
3171
                        END_LONG_DOUBLE_ROUNDING ();
 
3172
                      }
2318
3173
# else
2319
 
                    abort ();
 
3174
                    abort ();
2320
3175
# endif
2321
 
                  }
2322
 
                else
2323
 
                  {
 
3176
                  }
 
3177
                else
 
3178
                  {
2324
3179
# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
2325
 
                    double arg = a.arg[dp->arg_index].a.a_double;
2326
 
 
2327
 
                    if (isnan (arg))
2328
 
                      {
2329
 
                        if (dp->conversion == 'A')
2330
 
                          {
2331
 
                            *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
2332
 
                          }
2333
 
                        else
2334
 
                          {
2335
 
                            *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
2336
 
                          }
2337
 
                      }
2338
 
                    else
2339
 
                      {
2340
 
                        int sign = 0;
2341
 
 
2342
 
                        if (signbit (arg)) /* arg < 0.0 or negative zero */
2343
 
                          {
2344
 
                            sign = -1;
2345
 
                            arg = -arg;
2346
 
                          }
2347
 
 
2348
 
                        if (sign < 0)
2349
 
                          *p++ = '-';
2350
 
                        else if (flags & FLAG_SHOWSIGN)
2351
 
                          *p++ = '+';
2352
 
                        else if (flags & FLAG_SPACE)
2353
 
                          *p++ = ' ';
2354
 
 
2355
 
                        if (arg > 0.0 && arg + arg == arg)
2356
 
                          {
2357
 
                            if (dp->conversion == 'A')
2358
 
                              {
2359
 
                                *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
2360
 
                              }
2361
 
                            else
2362
 
                              {
2363
 
                                *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
2364
 
                              }
2365
 
                          }
2366
 
                        else
2367
 
                          {
2368
 
                            int exponent;
2369
 
                            double mantissa;
2370
 
 
2371
 
                            if (arg > 0.0)
2372
 
                              mantissa = printf_frexp (arg, &exponent);
2373
 
                            else
2374
 
                              {
2375
 
                                exponent = 0;
2376
 
                                mantissa = 0.0;
2377
 
                              }
2378
 
 
2379
 
                            if (has_precision
2380
 
                                && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
2381
 
                              {
2382
 
                                /* Round the mantissa.  */
2383
 
                                double tail = mantissa;
2384
 
                                size_t q;
2385
 
 
2386
 
                                for (q = precision; ; q--)
2387
 
                                  {
2388
 
                                    int digit = (int) tail;
2389
 
                                    tail -= digit;
2390
 
                                    if (q == 0)
2391
 
                                      {
2392
 
                                        if (digit & 1 ? tail >= 0.5 : tail > 0.5)
2393
 
                                          tail = 1 - tail;
2394
 
                                        else
2395
 
                                          tail = - tail;
2396
 
                                        break;
2397
 
                                      }
2398
 
                                    tail *= 16.0;
2399
 
                                  }
2400
 
                                if (tail != 0.0)
2401
 
                                  for (q = precision; q > 0; q--)
2402
 
                                    tail *= 0.0625;
2403
 
                                mantissa += tail;
2404
 
                              }
2405
 
 
2406
 
                            *p++ = '0';
2407
 
                            *p++ = dp->conversion - 'A' + 'X';
2408
 
                            pad_ptr = p;
2409
 
                            {
2410
 
                              int digit;
2411
 
 
2412
 
                              digit = (int) mantissa;
2413
 
                              mantissa -= digit;
2414
 
                              *p++ = '0' + digit;
2415
 
                              if ((flags & FLAG_ALT)
2416
 
                                  || mantissa > 0.0 || precision > 0)
2417
 
                                {
2418
 
                                  *p++ = decimal_point_char ();
2419
 
                                  /* This loop terminates because we assume
2420
 
                                     that FLT_RADIX is a power of 2.  */
2421
 
                                  while (mantissa > 0.0)
2422
 
                                    {
2423
 
                                      mantissa *= 16.0;
2424
 
                                      digit = (int) mantissa;
2425
 
                                      mantissa -= digit;
2426
 
                                      *p++ = digit
2427
 
                                             + (digit < 10
2428
 
                                                ? '0'
2429
 
                                                : dp->conversion - 10);
2430
 
                                      if (precision > 0)
2431
 
                                        precision--;
2432
 
                                    }
2433
 
                                  while (precision > 0)
2434
 
                                    {
2435
 
                                      *p++ = '0';
2436
 
                                      precision--;
2437
 
                                    }
2438
 
                                }
2439
 
                              }
2440
 
                              *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';
2441
3296
#  if WIDE_CHAR_VERSION
2442
 
                              {
2443
 
                                static const wchar_t decimal_format[] =
2444
 
                                  { '%', '+', 'd', '\0' };
2445
 
                                SNPRINTF (p, 6 + 1, decimal_format, exponent);
2446
 
                              }
2447
 
                              while (*p != '\0')
2448
 
                                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++;
2449
3304
#  else
2450
 
                              if (sizeof (DCHAR_T) == 1)
2451
 
                                {
2452
 
                                  sprintf ((char *) p, "%+d", exponent);
2453
 
                                  while (*p != '\0')
2454
 
                                    p++;
2455
 
                                }
2456
 
                              else
2457
 
                                {
2458
 
                                  char expbuf[6 + 1];
2459
 
                                  const char *ep;
2460
 
                                  sprintf (expbuf, "%+d", exponent);
2461
 
                                  for (ep = expbuf; (*p = *ep) != '\0'; ep++)
2462
 
                                    p++;
2463
 
                                }
 
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
                                }
2464
3319
#  endif
2465
 
                          }
2466
 
                      }
 
3320
                          }
 
3321
                      }
2467
3322
# else
2468
 
                    abort ();
 
3323
                    abort ();
2469
3324
# endif
2470
 
                  }
2471
 
                /* The generated string now extends from tmp to p, with the
2472
 
                   zero padding insertion point being at pad_ptr.  */
2473
 
                if (has_width && p - tmp < width)
2474
 
                  {
2475
 
                    size_t pad = width - (p - tmp);
2476
 
                    DCHAR_T *end = p + pad;
2477
 
 
2478
 
                    if (flags & FLAG_LEFT)
2479
 
                      {
2480
 
                        /* Pad with spaces on the right.  */
2481
 
                        for (; pad > 0; pad--)
2482
 
                          *p++ = ' ';
2483
 
                      }
2484
 
                    else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
2485
 
                      {
2486
 
                        /* Pad with zeroes.  */
2487
 
                        DCHAR_T *q = end;
2488
 
 
2489
 
                        while (p > pad_ptr)
2490
 
                          *--q = *--p;
2491
 
                        for (; pad > 0; pad--)
2492
 
                          *p++ = '0';
2493
 
                      }
2494
 
                    else
2495
 
                      {
2496
 
                        /* Pad with spaces on the left.  */
2497
 
                        DCHAR_T *q = end;
2498
 
 
2499
 
                        while (p > tmp)
2500
 
                          *--q = *--p;
2501
 
                        for (; pad > 0; pad--)
2502
 
                          *p++ = ' ';
2503
 
                      }
2504
 
 
2505
 
                    p = end;
2506
 
                  }
2507
 
 
2508
 
                {
2509
 
                  size_t count = p - tmp;
2510
 
 
2511
 
                  if (count >= tmp_length)
2512
 
                    /* tmp_length was incorrectly calculated - fix the
2513
 
                       code above!  */
2514
 
                    abort ();
2515
 
 
2516
 
                  /* Make room for the result.  */
2517
 
                  if (count >= allocated - length)
2518
 
                    {
2519
 
                      size_t n = xsum (length, count);
2520
 
 
2521
 
                      ENSURE_ALLOCATION (n);
2522
 
                    }
2523
 
 
2524
 
                  /* Append the result.  */
2525
 
                  memcpy (result + length, tmp, count * sizeof (DCHAR_T));
2526
 
                  if (tmp != tmpbuf)
2527
 
                    free (tmp);
2528
 
                  length += count;
2529
 
                }
2530
 
              }
 
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
              }
2531
3386
#endif
2532
3387
#if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
2533
 
            else if ((dp->conversion == 'f' || dp->conversion == 'F'
2534
 
                      || dp->conversion == 'e' || dp->conversion == 'E'
2535
 
                      || dp->conversion == 'g' || dp->conversion == 'G'
2536
 
                      || dp->conversion == 'a' || dp->conversion == 'A')
2537
 
                     && (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
2538
3393
# if NEED_PRINTF_DOUBLE
2539
 
                         || a.arg[dp->arg_index].type == TYPE_DOUBLE
 
3394
                         || a.arg[dp->arg_index].type == TYPE_DOUBLE
2540
3395
# elif NEED_PRINTF_INFINITE_DOUBLE
2541
 
                         || (a.arg[dp->arg_index].type == TYPE_DOUBLE
2542
 
                             /* The systems (mingw) which produce wrong output
2543
 
                                for Inf, -Inf, and NaN also do so for -0.0.
2544
 
                                Therefore we treat this case here as well.  */
2545
 
                             && 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))
2546
3401
# endif
2547
3402
# if NEED_PRINTF_LONG_DOUBLE
2548
 
                         || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
 
3403
                         || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2549
3404
# elif NEED_PRINTF_INFINITE_LONG_DOUBLE
2550
 
                         || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2551
 
                             /* Some systems produce wrong output for Inf,
2552
 
                                -Inf, and NaN.  */
2553
 
                             && is_infinitel (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))
2554
3411
# endif
2555
 
                        ))
2556
 
              {
 
3412
                        ))
 
3413
              {
2557
3414
# if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
2558
 
                arg_type type = a.arg[dp->arg_index].type;
 
3415
                arg_type type = a.arg[dp->arg_index].type;
2559
3416
# endif
2560
 
                int flags = dp->flags;
2561
 
                int has_width;
2562
 
                size_t width;
2563
 
                int has_precision;
2564
 
                size_t precision;
2565
 
                size_t tmp_length;
2566
 
                DCHAR_T tmpbuf[700];
2567
 
                DCHAR_T *tmp;
2568
 
                DCHAR_T *pad_ptr;
2569
 
                DCHAR_T *p;
2570
 
 
2571
 
                has_width = 0;
2572
 
                width = 0;
2573
 
                if (dp->width_start != dp->width_end)
2574
 
                  {
2575
 
                    if (dp->width_arg_index != ARG_NONE)
2576
 
                      {
2577
 
                        int arg;
2578
 
 
2579
 
                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2580
 
                          abort ();
2581
 
                        arg = a.arg[dp->width_arg_index].a.a_int;
2582
 
                        if (arg < 0)
2583
 
                          {
2584
 
                            /* "A negative field width is taken as a '-' flag
2585
 
                                followed by a positive field width."  */
2586
 
                            flags |= FLAG_LEFT;
2587
 
                            width = (unsigned int) (-arg);
2588
 
                          }
2589
 
                        else
2590
 
                          width = arg;
2591
 
                      }
2592
 
                    else
2593
 
                      {
2594
 
                        const FCHAR_T *digitp = dp->width_start;
2595
 
 
2596
 
                        do
2597
 
                          width = xsum (xtimes (width, 10), *digitp++ - '0');
2598
 
                        while (digitp != dp->width_end);
2599
 
                      }
2600
 
                    has_width = 1;
2601
 
                  }
2602
 
 
2603
 
                has_precision = 0;
2604
 
                precision = 0;
2605
 
                if (dp->precision_start != dp->precision_end)
2606
 
                  {
2607
 
                    if (dp->precision_arg_index != ARG_NONE)
2608
 
                      {
2609
 
                        int arg;
2610
 
 
2611
 
                        if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2612
 
                          abort ();
2613
 
                        arg = a.arg[dp->precision_arg_index].a.a_int;
2614
 
                        /* "A negative precision is taken as if the precision
2615
 
                            were omitted."  */
2616
 
                        if (arg >= 0)
2617
 
                          {
2618
 
                            precision = arg;
2619
 
                            has_precision = 1;
2620
 
                          }
2621
 
                      }
2622
 
                    else
2623
 
                      {
2624
 
                        const FCHAR_T *digitp = dp->precision_start + 1;
2625
 
 
2626
 
                        precision = 0;
2627
 
                        while (digitp != dp->precision_end)
2628
 
                          precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2629
 
                        has_precision = 1;
2630
 
                      }
2631
 
                  }
2632
 
 
2633
 
                /* POSIX specifies the default precision to be 6 for %f, %F,
2634
 
                   %e, %E, but not for %g, %G.  Implementations appear to use
2635
 
                   the same default precision also for %g, %G.  */
2636
 
                if (!has_precision)
2637
 
                  precision = 6;
2638
 
 
2639
 
                /* 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.  */
2640
3499
# if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
2641
 
                tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
 
3500
                tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
2642
3501
# elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
2643
 
                tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
 
3502
                tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
2644
3503
# elif NEED_PRINTF_LONG_DOUBLE
2645
 
                tmp_length = LDBL_DIG + 1;
 
3504
                tmp_length = LDBL_DIG + 1;
2646
3505
# elif NEED_PRINTF_DOUBLE
2647
 
                tmp_length = DBL_DIG + 1;
 
3506
                tmp_length = DBL_DIG + 1;
2648
3507
# else
2649
 
                tmp_length = 0;
 
3508
                tmp_length = 0;
2650
3509
# endif
2651
 
                if (tmp_length < precision)
2652
 
                  tmp_length = precision;
 
3510
                if (tmp_length < precision)
 
3511
                  tmp_length = precision;
2653
3512
# if NEED_PRINTF_LONG_DOUBLE
2654
3513
#  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
2655
 
                if (type == TYPE_LONGDOUBLE)
 
3514
                if (type == TYPE_LONGDOUBLE)
2656
3515
#  endif
2657
 
                  if (dp->conversion == 'f' || dp->conversion == 'F')
2658
 
                    {
2659
 
                      long double arg = a.arg[dp->arg_index].a.a_longdouble;
2660
 
                      if (!(isnanl (arg) || arg + arg == arg))
2661
 
                        {
2662
 
                          /* arg is finite and nonzero.  */
2663
 
                          int exponent = floorlog10l (arg < 0 ? -arg : arg);
2664
 
                          if (exponent >= 0 && tmp_length < exponent + precision)
2665
 
                            tmp_length = exponent + precision;
2666
 
                        }
2667
 
                    }
 
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
                    }
2668
3527
# endif
2669
3528
# if NEED_PRINTF_DOUBLE
2670
3529
#  if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
2671
 
                if (type == TYPE_DOUBLE)
 
3530
                if (type == TYPE_DOUBLE)
2672
3531
#  endif
2673
 
                  if (dp->conversion == 'f' || dp->conversion == 'F')
2674
 
                    {
2675
 
                      double arg = a.arg[dp->arg_index].a.a_double;
2676
 
                      if (!(isnan (arg) || arg + arg == arg))
2677
 
                        {
2678
 
                          /* arg is finite and nonzero.  */
2679
 
                          int exponent = floorlog10 (arg < 0 ? -arg : arg);
2680
 
                          if (exponent >= 0 && tmp_length < exponent + precision)
2681
 
                            tmp_length = exponent + precision;
2682
 
                        }
2683
 
                    }
 
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
                    }
2684
3543
# endif
2685
 
                /* Account for sign, decimal point etc. */
2686
 
                tmp_length = xsum (tmp_length, 12);
2687
 
 
2688
 
                if (tmp_length < width)
2689
 
                  tmp_length = width;
2690
 
 
2691
 
                tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
2692
 
 
2693
 
                if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
2694
 
                  tmp = tmpbuf;
2695
 
                else
2696
 
                  {
2697
 
                    size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
2698
 
 
2699
 
                    if (size_overflow_p (tmp_memsize))
2700
 
                      /* Overflow, would lead to out of memory.  */
2701
 
                      goto out_of_memory;
2702
 
                    tmp = (DCHAR_T *) malloc (tmp_memsize);
2703
 
                    if (tmp == NULL)
2704
 
                      /* Out of memory.  */
2705
 
                      goto out_of_memory;
2706
 
                  }
2707
 
 
2708
 
                pad_ptr = NULL;
2709
 
                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;
2710
3569
 
2711
3570
# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
2712
3571
#  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
2713
 
                if (type == TYPE_LONGDOUBLE)
 
3572
                if (type == TYPE_LONGDOUBLE)
2714
3573
#  endif
2715
 
                  {
2716
 
                    long double arg = a.arg[dp->arg_index].a.a_longdouble;
2717
 
 
2718
 
                    if (isnanl (arg))
2719
 
                      {
2720
 
                        if (dp->conversion >= 'A' && dp->conversion <= 'Z')
2721
 
                          {
2722
 
                            *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
2723
 
                          }
2724
 
                        else
2725
 
                          {
2726
 
                            *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
2727
 
                          }
2728
 
                      }
2729
 
                    else
2730
 
                      {
2731
 
                        int sign = 0;
2732
 
                        DECL_LONG_DOUBLE_ROUNDING
2733
 
 
2734
 
                        BEGIN_LONG_DOUBLE_ROUNDING ();
2735
 
 
2736
 
                        if (signbit (arg)) /* arg < 0.0L or negative zero */
2737
 
                          {
2738
 
                            sign = -1;
2739
 
                            arg = -arg;
2740
 
                          }
2741
 
 
2742
 
                        if (sign < 0)
2743
 
                          *p++ = '-';
2744
 
                        else if (flags & FLAG_SHOWSIGN)
2745
 
                          *p++ = '+';
2746
 
                        else if (flags & FLAG_SPACE)
2747
 
                          *p++ = ' ';
2748
 
 
2749
 
                        if (arg > 0.0L && arg + arg == arg)
2750
 
                          {
2751
 
                            if (dp->conversion >= 'A' && dp->conversion <= 'Z')
2752
 
                              {
2753
 
                                *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
2754
 
                              }
2755
 
                            else
2756
 
                              {
2757
 
                                *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
2758
 
                              }
2759
 
                          }
2760
 
                        else
2761
 
                          {
 
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
                          {
2762
3621
#  if NEED_PRINTF_LONG_DOUBLE
2763
 
                            pad_ptr = p;
2764
 
 
2765
 
                            if (dp->conversion == 'f' || dp->conversion == 'F')
2766
 
                              {
2767
 
                                char *digits;
2768
 
                                size_t ndigits;
2769
 
 
2770
 
                                digits =
2771
 
                                  scale10_round_decimal_long_double (arg, precision);
2772
 
                                if (digits == NULL)
2773
 
                                  {
2774
 
                                    END_LONG_DOUBLE_ROUNDING ();
2775
 
                                    goto out_of_memory;
2776
 
                                  }
2777
 
                                ndigits = strlen (digits);
2778
 
 
2779
 
                                if (ndigits > precision)
2780
 
                                  do
2781
 
                                    {
2782
 
                                      --ndigits;
2783
 
                                      *p++ = digits[ndigits];
2784
 
                                    }
2785
 
                                  while (ndigits > precision);
2786
 
                                else
2787
 
                                  *p++ = '0';
2788
 
                                /* Here ndigits <= precision.  */
2789
 
                                if ((flags & FLAG_ALT) || precision > 0)
2790
 
                                  {
2791
 
                                    *p++ = decimal_point_char ();
2792
 
                                    for (; precision > ndigits; precision--)
2793
 
                                      *p++ = '0';
2794
 
                                    while (ndigits > 0)
2795
 
                                      {
2796
 
                                        --ndigits;
2797
 
                                        *p++ = digits[ndigits];
2798
 
                                      }
2799
 
                                  }
2800
 
 
2801
 
                                free (digits);
2802
 
                              }
2803
 
                            else if (dp->conversion == 'e' || dp->conversion == 'E')
2804
 
                              {
2805
 
                                int exponent;
2806
 
 
2807
 
                                if (arg == 0.0L)
2808
 
                                  {
2809
 
                                    exponent = 0;
2810
 
                                    *p++ = '0';
2811
 
                                    if ((flags & FLAG_ALT) || precision > 0)
2812
 
                                      {
2813
 
                                        *p++ = decimal_point_char ();
2814
 
                                        for (; precision > 0; precision--)
2815
 
                                          *p++ = '0';
2816
 
                                      }
2817
 
                                  }
2818
 
                                else
2819
 
                                  {
2820
 
                                    /* arg > 0.0L.  */
2821
 
                                    int adjusted;
2822
 
                                    char *digits;
2823
 
                                    size_t ndigits;
2824
 
 
2825
 
                                    exponent = floorlog10l (arg);
2826
 
                                    adjusted = 0;
2827
 
                                    for (;;)
2828
 
                                      {
2829
 
                                        digits =
2830
 
                                          scale10_round_decimal_long_double (arg,
2831
 
                                                                             (int)precision - exponent);
2832
 
                                        if (digits == NULL)
2833
 
                                          {
2834
 
                                            END_LONG_DOUBLE_ROUNDING ();
2835
 
                                            goto out_of_memory;
2836
 
                                          }
2837
 
                                        ndigits = strlen (digits);
2838
 
 
2839
 
                                        if (ndigits == precision + 1)
2840
 
                                          break;
2841
 
                                        if (ndigits < precision
2842
 
                                            || ndigits > precision + 2)
2843
 
                                          /* The exponent was not guessed
2844
 
                                             precisely enough.  */
2845
 
                                          abort ();
2846
 
                                        if (adjusted)
2847
 
                                          /* None of two values of exponent is
2848
 
                                             the right one.  Prevent an endless
2849
 
                                             loop.  */
2850
 
                                          abort ();
2851
 
                                        free (digits);
2852
 
                                        if (ndigits == precision)
2853
 
                                          exponent -= 1;
2854
 
                                        else
2855
 
                                          exponent += 1;
2856
 
                                        adjusted = 1;
2857
 
                                      }
2858
 
 
2859
 
                                    /* Here ndigits = precision+1.  */
2860
 
                                    *p++ = digits[--ndigits];
2861
 
                                    if ((flags & FLAG_ALT) || precision > 0)
2862
 
                                      {
2863
 
                                        *p++ = decimal_point_char ();
2864
 
                                        while (ndigits > 0)
2865
 
                                          {
2866
 
                                            --ndigits;
2867
 
                                            *p++ = digits[ndigits];
2868
 
                                          }
2869
 
                                      }
2870
 
 
2871
 
                                    free (digits);
2872
 
                                  }
2873
 
 
2874
 
                                *p++ = dp->conversion; /* 'e' or 'E' */
2875
 
#   if WIDE_CHAR_VERSION
2876
 
                                {
2877
 
                                  static const wchar_t decimal_format[] =
2878
 
                                    { '%', '+', '.', '2', 'd', '\0' };
2879
 
                                  SNPRINTF (p, 6 + 1, decimal_format, exponent);
2880
 
                                }
2881
 
                                while (*p != '\0')
2882
 
                                  p++;
2883
 
#   else
2884
 
                                if (sizeof (DCHAR_T) == 1)
2885
 
                                  {
2886
 
                                    sprintf ((char *) p, "%+.2d", exponent);
2887
 
                                    while (*p != '\0')
2888
 
                                      p++;
2889
 
                                  }
2890
 
                                else
2891
 
                                  {
2892
 
                                    char expbuf[6 + 1];
2893
 
                                    const char *ep;
2894
 
                                    sprintf (expbuf, "%+.2d", exponent);
2895
 
                                    for (ep = expbuf; (*p = *ep) != '\0'; ep++)
2896
 
                                      p++;
2897
 
                                  }
2898
 
#   endif
2899
 
                              }
2900
 
                            else if (dp->conversion == 'g' || dp->conversion == 'G')
2901
 
                              {
2902
 
                                if (precision == 0)
2903
 
                                  precision = 1;
2904
 
                                /* precision >= 1.  */
2905
 
 
2906
 
                                if (arg == 0.0L)
2907
 
                                  /* The exponent is 0, >= -4, < precision.
2908
 
                                     Use fixed-point notation.  */
2909
 
                                  {
2910
 
                                    size_t ndigits = precision;
2911
 
                                    /* Number of trailing zeroes that have to be
2912
 
                                       dropped.  */
2913
 
                                    size_t nzeroes =
2914
 
                                      (flags & FLAG_ALT ? 0 : precision - 1);
2915
 
 
2916
 
                                    --ndigits;
2917
 
                                    *p++ = '0';
2918
 
                                    if ((flags & FLAG_ALT) || ndigits > nzeroes)
2919
 
                                      {
2920
 
                                        *p++ = decimal_point_char ();
2921
 
                                        while (ndigits > nzeroes)
2922
 
                                          {
2923
 
                                            --ndigits;
2924
 
                                            *p++ = '0';
2925
 
                                          }
2926
 
                                      }
2927
 
                                  }
2928
 
                                else
2929
 
                                  {
2930
 
                                    /* arg > 0.0L.  */
2931
 
                                    int exponent;
2932
 
                                    int adjusted;
2933
 
                                    char *digits;
2934
 
                                    size_t ndigits;
2935
 
                                    size_t nzeroes;
2936
 
 
2937
 
                                    exponent = floorlog10l (arg);
2938
 
                                    adjusted = 0;
2939
 
                                    for (;;)
2940
 
                                      {
2941
 
                                        digits =
2942
 
                                          scale10_round_decimal_long_double (arg,
2943
 
                                                                             (int)(precision - 1) - exponent);
2944
 
                                        if (digits == NULL)
2945
 
                                          {
2946
 
                                            END_LONG_DOUBLE_ROUNDING ();
2947
 
                                            goto out_of_memory;
2948
 
                                          }
2949
 
                                        ndigits = strlen (digits);
2950
 
 
2951
 
                                        if (ndigits == precision)
2952
 
                                          break;
2953
 
                                        if (ndigits < precision - 1
2954
 
                                            || ndigits > precision + 1)
2955
 
                                          /* The exponent was not guessed
2956
 
                                             precisely enough.  */
2957
 
                                          abort ();
2958
 
                                        if (adjusted)
2959
 
                                          /* None of two values of exponent is
2960
 
                                             the right one.  Prevent an endless
2961
 
                                             loop.  */
2962
 
                                          abort ();
2963
 
                                        free (digits);
2964
 
                                        if (ndigits < precision)
2965
 
                                          exponent -= 1;
2966
 
                                        else
2967
 
                                          exponent += 1;
2968
 
                                        adjusted = 1;
2969
 
                                      }
2970
 
                                    /* Here ndigits = precision.  */
2971
 
 
2972
 
                                    /* Determine the number of trailing zeroes
2973
 
                                       that have to be dropped.  */
2974
 
                                    nzeroes = 0;
2975
 
                                    if ((flags & FLAG_ALT) == 0)
2976
 
                                      while (nzeroes < ndigits
2977
 
                                             && digits[nzeroes] == '0')
2978
 
                                        nzeroes++;
2979
 
 
2980
 
                                    /* The exponent is now determined.  */
2981
 
                                    if (exponent >= -4
2982
 
                                        && exponent < (long)precision)
2983
 
                                      {
2984
 
                                        /* Fixed-point notation:
2985
 
                                           max(exponent,0)+1 digits, then the
2986
 
                                           decimal point, then the remaining
2987
 
                                           digits without trailing zeroes.  */
2988
 
                                        if (exponent >= 0)
2989
 
                                          {
2990
 
                                            size_t count = exponent + 1;
2991
 
                                            /* Note: count <= precision = ndigits.  */
2992
 
                                            for (; count > 0; count--)
2993
 
                                              *p++ = digits[--ndigits];
2994
 
                                            if ((flags & FLAG_ALT) || ndigits > nzeroes)
2995
 
                                              {
2996
 
                                                *p++ = decimal_point_char ();
2997
 
                                                while (ndigits > nzeroes)
2998
 
                                                  {
2999
 
                                                    --ndigits;
3000
 
                                                    *p++ = digits[ndigits];
3001
 
                                                  }
3002
 
                                              }
3003
 
                                          }
3004
 
                                        else
3005
 
                                          {
3006
 
                                            size_t count = -exponent - 1;
3007
 
                                            *p++ = '0';
3008
 
                                            *p++ = decimal_point_char ();
3009
 
                                            for (; count > 0; count--)
3010
 
                                              *p++ = '0';
3011
 
                                            while (ndigits > nzeroes)
3012
 
                                              {
3013
 
                                                --ndigits;
3014
 
                                                *p++ = digits[ndigits];
3015
 
                                              }
3016
 
                                          }
3017
 
                                      }
3018
 
                                    else
3019
 
                                      {
3020
 
                                        /* Exponential notation.  */
3021
 
                                        *p++ = digits[--ndigits];
3022
 
                                        if ((flags & FLAG_ALT) || ndigits > nzeroes)
3023
 
                                          {
3024
 
                                            *p++ = decimal_point_char ();
3025
 
                                            while (ndigits > nzeroes)
3026
 
                                              {
3027
 
                                                --ndigits;
3028
 
                                                *p++ = digits[ndigits];
3029
 
                                              }
3030
 
                                          }
3031
 
                                        *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3032
 
#   if WIDE_CHAR_VERSION
3033
 
                                        {
3034
 
                                          static const wchar_t decimal_format[] =
3035
 
                                            { '%', '+', '.', '2', 'd', '\0' };
3036
 
                                          SNPRINTF (p, 6 + 1, decimal_format, exponent);
3037
 
                                        }
3038
 
                                        while (*p != '\0')
3039
 
                                          p++;
3040
 
#   else
3041
 
                                        if (sizeof (DCHAR_T) == 1)
3042
 
                                          {
3043
 
                                            sprintf ((char *) p, "%+.2d", exponent);
3044
 
                                            while (*p != '\0')
3045
 
                                              p++;
3046
 
                                          }
3047
 
                                        else
3048
 
                                          {
3049
 
                                            char expbuf[6 + 1];
3050
 
                                            const char *ep;
3051
 
                                            sprintf (expbuf, "%+.2d", exponent);
3052
 
                                            for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3053
 
                                              p++;
3054
 
                                          }
3055
 
#   endif
3056
 
                                      }
3057
 
 
3058
 
                                    free (digits);
3059
 
                                  }
3060
 
                              }
3061
 
                            else
3062
 
                              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 ();
3063
3970
#  else
3064
 
                            /* arg is finite.  */
3065
 
                            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 ();
3066
4031
#  endif
3067
 
                          }
 
4032
                          }
3068
4033
 
3069
 
                        END_LONG_DOUBLE_ROUNDING ();
3070
 
                      }
3071
 
                  }
 
4034
                        END_LONG_DOUBLE_ROUNDING ();
 
4035
                      }
 
4036
                  }
3072
4037
#  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3073
 
                else
 
4038
                else
3074
4039
#  endif
3075
4040
# endif
3076
4041
# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3077
 
                  {
3078
 
                    double arg = a.arg[dp->arg_index].a.a_double;
3079
 
 
3080
 
                    if (isnan (arg))
3081
 
                      {
3082
 
                        if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3083
 
                          {
3084
 
                            *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3085
 
                          }
3086
 
                        else
3087
 
                          {
3088
 
                            *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3089
 
                          }
3090
 
                      }
3091
 
                    else
3092
 
                      {
3093
 
                        int sign = 0;
3094
 
 
3095
 
                        if (signbit (arg)) /* arg < 0.0 or negative zero */
3096
 
                          {
3097
 
                            sign = -1;
3098
 
                            arg = -arg;
3099
 
                          }
3100
 
 
3101
 
                        if (sign < 0)
3102
 
                          *p++ = '-';
3103
 
                        else if (flags & FLAG_SHOWSIGN)
3104
 
                          *p++ = '+';
3105
 
                        else if (flags & FLAG_SPACE)
3106
 
                          *p++ = ' ';
3107
 
 
3108
 
                        if (arg > 0.0 && arg + arg == arg)
3109
 
                          {
3110
 
                            if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3111
 
                              {
3112
 
                                *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3113
 
                              }
3114
 
                            else
3115
 
                              {
3116
 
                                *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3117
 
                              }
3118
 
                          }
3119
 
                        else
3120
 
                          {
 
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
                          {
3121
4086
#  if NEED_PRINTF_DOUBLE
3122
 
                            pad_ptr = p;
3123
 
 
3124
 
                            if (dp->conversion == 'f' || dp->conversion == 'F')
3125
 
                              {
3126
 
                                char *digits;
3127
 
                                size_t ndigits;
3128
 
 
3129
 
                                digits =
3130
 
                                  scale10_round_decimal_double (arg, precision);
3131
 
                                if (digits == NULL)
3132
 
                                  goto out_of_memory;
3133
 
                                ndigits = strlen (digits);
3134
 
 
3135
 
                                if (ndigits > precision)
3136
 
                                  do
3137
 
                                    {
3138
 
                                      --ndigits;
3139
 
                                      *p++ = digits[ndigits];
3140
 
                                    }
3141
 
                                  while (ndigits > precision);
3142
 
                                else
3143
 
                                  *p++ = '0';
3144
 
                                /* Here ndigits <= precision.  */
3145
 
                                if ((flags & FLAG_ALT) || precision > 0)
3146
 
                                  {
3147
 
                                    *p++ = decimal_point_char ();
3148
 
                                    for (; precision > ndigits; precision--)
3149
 
                                      *p++ = '0';
3150
 
                                    while (ndigits > 0)
3151
 
                                      {
3152
 
                                        --ndigits;
3153
 
                                        *p++ = digits[ndigits];
3154
 
                                      }
3155
 
                                  }
3156
 
 
3157
 
                                free (digits);
3158
 
                              }
3159
 
                            else if (dp->conversion == 'e' || dp->conversion == 'E')
3160
 
                              {
3161
 
                                int exponent;
3162
 
 
3163
 
                                if (arg == 0.0)
3164
 
                                  {
3165
 
                                    exponent = 0;
3166
 
                                    *p++ = '0';
3167
 
                                    if ((flags & FLAG_ALT) || precision > 0)
3168
 
                                      {
3169
 
                                        *p++ = decimal_point_char ();
3170
 
                                        for (; precision > 0; precision--)
3171
 
                                          *p++ = '0';
3172
 
                                      }
3173
 
                                  }
3174
 
                                else
3175
 
                                  {
3176
 
                                    /* arg > 0.0.  */
3177
 
                                    int adjusted;
3178
 
                                    char *digits;
3179
 
                                    size_t ndigits;
3180
 
 
3181
 
                                    exponent = floorlog10 (arg);
3182
 
                                    adjusted = 0;
3183
 
                                    for (;;)
3184
 
                                      {
3185
 
                                        digits =
3186
 
                                          scale10_round_decimal_double (arg,
3187
 
                                                                        (int)precision - exponent);
3188
 
                                        if (digits == NULL)
3189
 
                                          goto out_of_memory;
3190
 
                                        ndigits = strlen (digits);
3191
 
 
3192
 
                                        if (ndigits == precision + 1)
3193
 
                                          break;
3194
 
                                        if (ndigits < precision
3195
 
                                            || ndigits > precision + 2)
3196
 
                                          /* The exponent was not guessed
3197
 
                                             precisely enough.  */
3198
 
                                          abort ();
3199
 
                                        if (adjusted)
3200
 
                                          /* None of two values of exponent is
3201
 
                                             the right one.  Prevent an endless
3202
 
                                             loop.  */
3203
 
                                          abort ();
3204
 
                                        free (digits);
3205
 
                                        if (ndigits == precision)
3206
 
                                          exponent -= 1;
3207
 
                                        else
3208
 
                                          exponent += 1;
3209
 
                                        adjusted = 1;
3210
 
                                      }
3211
 
 
3212
 
                                    /* Here ndigits = precision+1.  */
3213
 
                                    *p++ = digits[--ndigits];
3214
 
                                    if ((flags & FLAG_ALT) || precision > 0)
3215
 
                                      {
3216
 
                                        *p++ = decimal_point_char ();
3217
 
                                        while (ndigits > 0)
3218
 
                                          {
3219
 
                                            --ndigits;
3220
 
                                            *p++ = digits[ndigits];
3221
 
                                          }
3222
 
                                      }
3223
 
 
3224
 
                                    free (digits);
3225
 
                                  }
3226
 
 
3227
 
                                *p++ = dp->conversion; /* 'e' or 'E' */
3228
 
#   if WIDE_CHAR_VERSION
3229
 
                                {
3230
 
                                  static const wchar_t decimal_format[] =
3231
 
                                    /* Produce the same number of exponent digits
3232
 
                                       as the native printf implementation.  */
3233
 
#    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3234
 
                                    { '%', '+', '.', '3', 'd', '\0' };
3235
 
#    else
3236
 
                                    { '%', '+', '.', '2', 'd', '\0' };
3237
 
#    endif
3238
 
                                  SNPRINTF (p, 6 + 1, decimal_format, exponent);
3239
 
                                }
3240
 
                                while (*p != '\0')
3241
 
                                  p++;
3242
 
#   else
3243
 
                                {
3244
 
                                  static const char decimal_format[] =
3245
 
                                    /* Produce the same number of exponent digits
3246
 
                                       as the native printf implementation.  */
3247
 
#    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3248
 
                                    "%+.3d";
3249
 
#    else
3250
 
                                    "%+.2d";
3251
 
#    endif
3252
 
                                  if (sizeof (DCHAR_T) == 1)
3253
 
                                    {
3254
 
                                      sprintf ((char *) p, decimal_format, exponent);
3255
 
                                      while (*p != '\0')
3256
 
                                        p++;
3257
 
                                    }
3258
 
                                  else
3259
 
                                    {
3260
 
                                      char expbuf[6 + 1];
3261
 
                                      const char *ep;
3262
 
                                      sprintf (expbuf, decimal_format, exponent);
3263
 
                                      for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3264
 
                                        p++;
3265
 
                                    }
3266
 
                                }
3267
 
#   endif
3268
 
                              }
3269
 
                            else if (dp->conversion == 'g' || dp->conversion == 'G')
3270
 
                              {
3271
 
                                if (precision == 0)
3272
 
                                  precision = 1;
3273
 
                                /* precision >= 1.  */
3274
 
 
3275
 
                                if (arg == 0.0)
3276
 
                                  /* The exponent is 0, >= -4, < precision.
3277
 
                                     Use fixed-point notation.  */
3278
 
                                  {
3279
 
                                    size_t ndigits = precision;
3280
 
                                    /* Number of trailing zeroes that have to be
3281
 
                                       dropped.  */
3282
 
                                    size_t nzeroes =
3283
 
                                      (flags & FLAG_ALT ? 0 : precision - 1);
3284
 
 
3285
 
                                    --ndigits;
3286
 
                                    *p++ = '0';
3287
 
                                    if ((flags & FLAG_ALT) || ndigits > nzeroes)
3288
 
                                      {
3289
 
                                        *p++ = decimal_point_char ();
3290
 
                                        while (ndigits > nzeroes)
3291
 
                                          {
3292
 
                                            --ndigits;
3293
 
                                            *p++ = '0';
3294
 
                                          }
3295
 
                                      }
3296
 
                                  }
3297
 
                                else
3298
 
                                  {
3299
 
                                    /* arg > 0.0.  */
3300
 
                                    int exponent;
3301
 
                                    int adjusted;
3302
 
                                    char *digits;
3303
 
                                    size_t ndigits;
3304
 
                                    size_t nzeroes;
3305
 
 
3306
 
                                    exponent = floorlog10 (arg);
3307
 
                                    adjusted = 0;
3308
 
                                    for (;;)
3309
 
                                      {
3310
 
                                        digits =
3311
 
                                          scale10_round_decimal_double (arg,
3312
 
                                                                        (int)(precision - 1) - exponent);
3313
 
                                        if (digits == NULL)
3314
 
                                          goto out_of_memory;
3315
 
                                        ndigits = strlen (digits);
3316
 
 
3317
 
                                        if (ndigits == precision)
3318
 
                                          break;
3319
 
                                        if (ndigits < precision - 1
3320
 
                                            || ndigits > precision + 1)
3321
 
                                          /* The exponent was not guessed
3322
 
                                             precisely enough.  */
3323
 
                                          abort ();
3324
 
                                        if (adjusted)
3325
 
                                          /* None of two values of exponent is
3326
 
                                             the right one.  Prevent an endless
3327
 
                                             loop.  */
3328
 
                                          abort ();
3329
 
                                        free (digits);
3330
 
                                        if (ndigits < precision)
3331
 
                                          exponent -= 1;
3332
 
                                        else
3333
 
                                          exponent += 1;
3334
 
                                        adjusted = 1;
3335
 
                                      }
3336
 
                                    /* Here ndigits = precision.  */
3337
 
 
3338
 
                                    /* Determine the number of trailing zeroes
3339
 
                                       that have to be dropped.  */
3340
 
                                    nzeroes = 0;
3341
 
                                    if ((flags & FLAG_ALT) == 0)
3342
 
                                      while (nzeroes < ndigits
3343
 
                                             && digits[nzeroes] == '0')
3344
 
                                        nzeroes++;
3345
 
 
3346
 
                                    /* The exponent is now determined.  */
3347
 
                                    if (exponent >= -4
3348
 
                                        && exponent < (long)precision)
3349
 
                                      {
3350
 
                                        /* Fixed-point notation:
3351
 
                                           max(exponent,0)+1 digits, then the
3352
 
                                           decimal point, then the remaining
3353
 
                                           digits without trailing zeroes.  */
3354
 
                                        if (exponent >= 0)
3355
 
                                          {
3356
 
                                            size_t count = exponent + 1;
3357
 
                                            /* Note: count <= precision = ndigits.  */
3358
 
                                            for (; count > 0; count--)
3359
 
                                              *p++ = digits[--ndigits];
3360
 
                                            if ((flags & FLAG_ALT) || ndigits > nzeroes)
3361
 
                                              {
3362
 
                                                *p++ = decimal_point_char ();
3363
 
                                                while (ndigits > nzeroes)
3364
 
                                                  {
3365
 
                                                    --ndigits;
3366
 
                                                    *p++ = digits[ndigits];
3367
 
                                                  }
3368
 
                                              }
3369
 
                                          }
3370
 
                                        else
3371
 
                                          {
3372
 
                                            size_t count = -exponent - 1;
3373
 
                                            *p++ = '0';
3374
 
                                            *p++ = decimal_point_char ();
3375
 
                                            for (; count > 0; count--)
3376
 
                                              *p++ = '0';
3377
 
                                            while (ndigits > nzeroes)
3378
 
                                              {
3379
 
                                                --ndigits;
3380
 
                                                *p++ = digits[ndigits];
3381
 
                                              }
3382
 
                                          }
3383
 
                                      }
3384
 
                                    else
3385
 
                                      {
3386
 
                                        /* Exponential notation.  */
3387
 
                                        *p++ = digits[--ndigits];
3388
 
                                        if ((flags & FLAG_ALT) || ndigits > nzeroes)
3389
 
                                          {
3390
 
                                            *p++ = decimal_point_char ();
3391
 
                                            while (ndigits > nzeroes)
3392
 
                                              {
3393
 
                                                --ndigits;
3394
 
                                                *p++ = digits[ndigits];
3395
 
                                              }
3396
 
                                          }
3397
 
                                        *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3398
 
#   if WIDE_CHAR_VERSION
3399
 
                                        {
3400
 
                                          static const wchar_t decimal_format[] =
3401
 
                                            /* Produce the same number of exponent digits
3402
 
                                               as the native printf implementation.  */
3403
 
#    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3404
 
                                            { '%', '+', '.', '3', 'd', '\0' };
3405
 
#    else
3406
 
                                            { '%', '+', '.', '2', 'd', '\0' };
3407
 
#    endif
3408
 
                                          SNPRINTF (p, 6 + 1, decimal_format, exponent);
3409
 
                                        }
3410
 
                                        while (*p != '\0')
3411
 
                                          p++;
3412
 
#   else
3413
 
                                        {
3414
 
                                          static const char decimal_format[] =
3415
 
                                            /* Produce the same number of exponent digits
3416
 
                                               as the native printf implementation.  */
3417
 
#    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3418
 
                                            "%+.3d";
3419
 
#    else
3420
 
                                            "%+.2d";
3421
 
#    endif
3422
 
                                          if (sizeof (DCHAR_T) == 1)
3423
 
                                            {
3424
 
                                              sprintf ((char *) p, decimal_format, exponent);
3425
 
                                              while (*p != '\0')
3426
 
                                                p++;
3427
 
                                            }
3428
 
                                          else
3429
 
                                            {
3430
 
                                              char expbuf[6 + 1];
3431
 
                                              const char *ep;
3432
 
                                              sprintf (expbuf, decimal_format, exponent);
3433
 
                                              for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3434
 
                                                p++;
3435
 
                                            }
3436
 
                                        }
3437
 
#   endif
3438
 
                                      }
3439
 
 
3440
 
                                    free (digits);
3441
 
                                  }
3442
 
                              }
3443
 
                            else
3444
 
                              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 ();
3445
4456
#  else
3446
 
                            /* arg is finite.  */
3447
 
                            if (!(arg == 0.0))
3448
 
                              abort ();
3449
 
 
3450
 
                            pad_ptr = p;
3451
 
 
3452
 
                            if (dp->conversion == 'f' || dp->conversion == 'F')
3453
 
                              {
3454
 
                                *p++ = '0';
3455
 
                                if ((flags & FLAG_ALT) || precision > 0)
3456
 
                                  {
3457
 
                                    *p++ = decimal_point_char ();
3458
 
                                    for (; precision > 0; precision--)
3459
 
                                      *p++ = '0';
3460
 
                                  }
3461
 
                              }
3462
 
                            else if (dp->conversion == 'e' || dp->conversion == 'E')
3463
 
                              {
3464
 
                                *p++ = '0';
3465
 
                                if ((flags & FLAG_ALT) || precision > 0)
3466
 
                                  {
3467
 
                                    *p++ = decimal_point_char ();
3468
 
                                    for (; precision > 0; precision--)
3469
 
                                      *p++ = '0';
3470
 
                                  }
3471
 
                                *p++ = dp->conversion; /* 'e' or 'E' */
3472
 
                                *p++ = '+';
3473
 
                                /* Produce the same number of exponent digits as
3474
 
                                   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.  */
3475
4486
#   if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3476
 
                                *p++ = '0';
 
4487
                                *p++ = '0';
3477
4488
#   endif
3478
 
                                *p++ = '0';
3479
 
                                *p++ = '0';
3480
 
                              }
3481
 
                            else if (dp->conversion == 'g' || dp->conversion == 'G')
3482
 
                              {
3483
 
                                *p++ = '0';
3484
 
                                if (flags & FLAG_ALT)
3485
 
                                  {
3486
 
                                    size_t ndigits =
3487
 
                                      (precision > 0 ? precision - 1 : 0);
3488
 
                                    *p++ = decimal_point_char ();
3489
 
                                    for (; ndigits > 0; --ndigits)
3490
 
                                      *p++ = '0';
3491
 
                                  }
3492
 
                              }
3493
 
                            else
3494
 
                              abort ();
3495
 
#  endif
3496
 
                          }
3497
 
                      }
3498
 
                  }
3499
 
# endif
3500
 
 
3501
 
                /* The generated string now extends from tmp to p, with the
3502
 
                   zero padding insertion point being at pad_ptr.  */
3503
 
                if (has_width && p - tmp < width)
3504
 
                  {
3505
 
                    size_t pad = width - (p - tmp);
3506
 
                    DCHAR_T *end = p + pad;
3507
 
 
3508
 
                    if (flags & FLAG_LEFT)
3509
 
                      {
3510
 
                        /* Pad with spaces on the right.  */
3511
 
                        for (; pad > 0; pad--)
3512
 
                          *p++ = ' ';
3513
 
                      }
3514
 
                    else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3515
 
                      {
3516
 
                        /* Pad with zeroes.  */
3517
 
                        DCHAR_T *q = end;
3518
 
 
3519
 
                        while (p > pad_ptr)
3520
 
                          *--q = *--p;
3521
 
                        for (; pad > 0; pad--)
3522
 
                          *p++ = '0';
3523
 
                      }
3524
 
                    else
3525
 
                      {
3526
 
                        /* Pad with spaces on the left.  */
3527
 
                        DCHAR_T *q = end;
3528
 
 
3529
 
                        while (p > tmp)
3530
 
                          *--q = *--p;
3531
 
                        for (; pad > 0; pad--)
3532
 
                          *p++ = ' ';
3533
 
                      }
3534
 
 
3535
 
                    p = end;
3536
 
                  }
3537
 
 
3538
 
                {
3539
 
                  size_t count = p - tmp;
3540
 
 
3541
 
                  if (count >= tmp_length)
3542
 
                    /* tmp_length was incorrectly calculated - fix the
3543
 
                       code above!  */
3544
 
                    abort ();
3545
 
 
3546
 
                  /* Make room for the result.  */
3547
 
                  if (count >= allocated - length)
3548
 
                    {
3549
 
                      size_t n = xsum (length, count);
3550
 
 
3551
 
                      ENSURE_ALLOCATION (n);
3552
 
                    }
3553
 
 
3554
 
                  /* Append the result.  */
3555
 
                  memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3556
 
                  if (tmp != tmpbuf)
3557
 
                    free (tmp);
3558
 
                  length += count;
3559
 
                }
3560
 
              }
3561
 
#endif
3562
 
            else
3563
 
              {
3564
 
                arg_type type = a.arg[dp->arg_index].type;
3565
 
                int flags = dp->flags;
3566
 
#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
3567
 
                int has_width;
3568
 
                size_t width;
3569
 
#endif
3570
 
#if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
3571
 
                int has_precision;
3572
 
                size_t precision;
3573
 
#endif
3574
 
#if NEED_PRINTF_UNBOUNDED_PRECISION
3575
 
                int prec_ourselves;
3576
 
#else
3577
 
#               define prec_ourselves 0
3578
 
#endif
3579
 
#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
3580
 
                int pad_ourselves;
3581
 
#else
3582
 
#               define pad_ourselves 0
3583
 
#endif
3584
 
                TCHAR_T *fbp;
3585
 
                unsigned int prefix_count;
3586
 
                int prefixes[2];
3587
 
#if !USE_SNPRINTF
3588
 
                size_t tmp_length;
3589
 
                TCHAR_T tmpbuf[700];
3590
 
                TCHAR_T *tmp;
3591
 
#endif
3592
 
 
3593
 
#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
3594
 
                has_width = 0;
3595
 
                width = 0;
3596
 
                if (dp->width_start != dp->width_end)
3597
 
                  {
3598
 
                    if (dp->width_arg_index != ARG_NONE)
3599
 
                      {
3600
 
                        int arg;
3601
 
 
3602
 
                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3603
 
                          abort ();
3604
 
                        arg = a.arg[dp->width_arg_index].a.a_int;
3605
 
                        if (arg < 0)
3606
 
                          {
3607
 
                            /* "A negative field width is taken as a '-' flag
3608
 
                                followed by a positive field width."  */
3609
 
                            flags |= FLAG_LEFT;
3610
 
                            width = (unsigned int) (-arg);
3611
 
                          }
3612
 
                        else
3613
 
                          width = arg;
3614
 
                      }
3615
 
                    else
3616
 
                      {
3617
 
                        const FCHAR_T *digitp = dp->width_start;
3618
 
 
3619
 
                        do
3620
 
                          width = xsum (xtimes (width, 10), *digitp++ - '0');
3621
 
                        while (digitp != dp->width_end);
3622
 
                      }
3623
 
                    has_width = 1;
3624
 
                  }
3625
 
#endif
3626
 
 
3627
 
#if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
3628
 
                has_precision = 0;
3629
 
                precision = 6;
3630
 
                if (dp->precision_start != dp->precision_end)
3631
 
                  {
3632
 
                    if (dp->precision_arg_index != ARG_NONE)
3633
 
                      {
3634
 
                        int arg;
3635
 
 
3636
 
                        if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3637
 
                          abort ();
3638
 
                        arg = a.arg[dp->precision_arg_index].a.a_int;
3639
 
                        /* "A negative precision is taken as if the precision
3640
 
                            were omitted."  */
3641
 
                        if (arg >= 0)
3642
 
                          {
3643
 
                            precision = arg;
3644
 
                            has_precision = 1;
3645
 
                          }
3646
 
                      }
3647
 
                    else
3648
 
                      {
3649
 
                        const FCHAR_T *digitp = dp->precision_start + 1;
3650
 
 
3651
 
                        precision = 0;
3652
 
                        while (digitp != dp->precision_end)
3653
 
                          precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3654
 
                        has_precision = 1;
3655
 
                      }
3656
 
                  }
3657
 
#endif
3658
 
 
3659
 
#if !USE_SNPRINTF
3660
 
                /* Allocate a temporary buffer of sufficient size for calling
3661
 
                   sprintf.  */
3662
 
                {
3663
 
                  switch (dp->conversion)
3664
 
                    {
3665
 
 
3666
 
                    case 'd': case 'i': case 'u':
3667
 
# if HAVE_LONG_LONG_INT
3668
 
                      if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
3669
 
                        tmp_length =
3670
 
                          (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
3671
 
                                          * 0.30103 /* binary -> decimal */
3672
 
                                         )
3673
 
                          + 1; /* turn floor into ceil */
3674
 
                      else
3675
 
# endif
3676
 
                      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
3677
 
                        tmp_length =
3678
 
                          (unsigned int) (sizeof (unsigned long) * CHAR_BIT
3679
 
                                          * 0.30103 /* binary -> decimal */
3680
 
                                         )
3681
 
                          + 1; /* turn floor into ceil */
3682
 
                      else
3683
 
                        tmp_length =
3684
 
                          (unsigned int) (sizeof (unsigned int) * CHAR_BIT
3685
 
                                          * 0.30103 /* binary -> decimal */
3686
 
                                         )
3687
 
                          + 1; /* turn floor into ceil */
3688
 
                      if (tmp_length < precision)
3689
 
                        tmp_length = precision;
3690
 
                      /* Multiply by 2, as an estimate for FLAG_GROUP.  */
3691
 
                      tmp_length = xsum (tmp_length, tmp_length);
3692
 
                      /* Add 1, to account for a leading sign.  */
3693
 
                      tmp_length = xsum (tmp_length, 1);
3694
 
                      break;
3695
 
 
3696
 
                    case 'o':
3697
 
# if HAVE_LONG_LONG_INT
3698
 
                      if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
3699
 
                        tmp_length =
3700
 
                          (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
3701
 
                                          * 0.333334 /* binary -> octal */
3702
 
                                         )
3703
 
                          + 1; /* turn floor into ceil */
3704
 
                      else
3705
 
# endif
3706
 
                      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
3707
 
                        tmp_length =
3708
 
                          (unsigned int) (sizeof (unsigned long) * CHAR_BIT
3709
 
                                          * 0.333334 /* binary -> octal */
3710
 
                                         )
3711
 
                          + 1; /* turn floor into ceil */
3712
 
                      else
3713
 
                        tmp_length =
3714
 
                          (unsigned int) (sizeof (unsigned int) * CHAR_BIT
3715
 
                                          * 0.333334 /* binary -> octal */
3716
 
                                         )
3717
 
                          + 1; /* turn floor into ceil */
3718
 
                      if (tmp_length < precision)
3719
 
                        tmp_length = precision;
3720
 
                      /* Add 1, to account for a leading sign.  */
3721
 
                      tmp_length = xsum (tmp_length, 1);
3722
 
                      break;
3723
 
 
3724
 
                    case 'x': case 'X':
3725
 
# if HAVE_LONG_LONG_INT
3726
 
                      if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
3727
 
                        tmp_length =
3728
 
                          (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
3729
 
                                          * 0.25 /* binary -> hexadecimal */
3730
 
                                         )
3731
 
                          + 1; /* turn floor into ceil */
3732
 
                      else
3733
 
# endif
3734
 
                      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
3735
 
                        tmp_length =
3736
 
                          (unsigned int) (sizeof (unsigned long) * CHAR_BIT
3737
 
                                          * 0.25 /* binary -> hexadecimal */
3738
 
                                         )
3739
 
                          + 1; /* turn floor into ceil */
3740
 
                      else
3741
 
                        tmp_length =
3742
 
                          (unsigned int) (sizeof (unsigned int) * CHAR_BIT
3743
 
                                          * 0.25 /* binary -> hexadecimal */
3744
 
                                         )
3745
 
                          + 1; /* turn floor into ceil */
3746
 
                      if (tmp_length < precision)
3747
 
                        tmp_length = precision;
3748
 
                      /* Add 2, to account for a leading sign or alternate form.  */
3749
 
                      tmp_length = xsum (tmp_length, 2);
3750
 
                      break;
3751
 
 
3752
 
                    case 'f': case 'F':
3753
 
                      if (type == TYPE_LONGDOUBLE)
3754
 
                        tmp_length =
3755
 
                          (unsigned int) (LDBL_MAX_EXP
3756
 
                                          * 0.30103 /* binary -> decimal */
3757
 
                                          * 2 /* estimate for FLAG_GROUP */
3758
 
                                         )
3759
 
                          + 1 /* turn floor into ceil */
3760
 
                          + 10; /* sign, decimal point etc. */
3761
 
                      else
3762
 
                        tmp_length =
3763
 
                          (unsigned int) (DBL_MAX_EXP
3764
 
                                          * 0.30103 /* binary -> decimal */
3765
 
                                          * 2 /* estimate for FLAG_GROUP */
3766
 
                                         )
3767
 
                          + 1 /* turn floor into ceil */
3768
 
                          + 10; /* sign, decimal point etc. */
3769
 
                      tmp_length = xsum (tmp_length, precision);
3770
 
                      break;
3771
 
 
3772
 
                    case 'e': case 'E': case 'g': case 'G':
3773
 
                      tmp_length =
3774
 
                        12; /* sign, decimal point, exponent etc. */
3775
 
                      tmp_length = xsum (tmp_length, precision);
3776
 
                      break;
3777
 
 
3778
 
                    case 'a': case 'A':
3779
 
                      if (type == TYPE_LONGDOUBLE)
3780
 
                        tmp_length =
3781
 
                          (unsigned int) (LDBL_DIG
3782
 
                                          * 0.831 /* decimal -> hexadecimal */
3783
 
                                         )
3784
 
                          + 1; /* turn floor into ceil */
3785
 
                      else
3786
 
                        tmp_length =
3787
 
                          (unsigned int) (DBL_DIG
3788
 
                                          * 0.831 /* decimal -> hexadecimal */
3789
 
                                         )
3790
 
                          + 1; /* turn floor into ceil */
3791
 
                      if (tmp_length < precision)
3792
 
                        tmp_length = precision;
3793
 
                      /* Account for sign, decimal point etc. */
3794
 
                      tmp_length = xsum (tmp_length, 12);
3795
 
                      break;
3796
 
 
3797
 
                    case 'c':
3798
 
# if HAVE_WINT_T && !WIDE_CHAR_VERSION
3799
 
                      if (type == TYPE_WIDE_CHAR)
3800
 
                        tmp_length = MB_CUR_MAX;
3801
 
                      else
3802
 
# endif
3803
 
                        tmp_length = 1;
3804
 
                      break;
3805
 
 
3806
 
                    case 's':
3807
 
# if HAVE_WCHAR_T
3808
 
                      if (type == TYPE_WIDE_STRING)
3809
 
                        {
3810
 
                          tmp_length =
3811
 
                            local_wcslen (a.arg[dp->arg_index].a.a_wide_string);
3812
 
 
3813
 
#  if !WIDE_CHAR_VERSION
3814
 
                          tmp_length = xtimes (tmp_length, MB_CUR_MAX);
3815
 
#  endif
3816
 
                        }
3817
 
                      else
3818
 
# endif
3819
 
                        tmp_length = strlen (a.arg[dp->arg_index].a.a_string);
3820
 
                      break;
3821
 
 
3822
 
                    case 'p':
3823
 
                      tmp_length =
3824
 
                        (unsigned int) (sizeof (void *) * CHAR_BIT
3825
 
                                        * 0.25 /* binary -> hexadecimal */
3826
 
                                       )
3827
 
                          + 1 /* turn floor into ceil */
3828
 
                          + 2; /* account for leading 0x */
3829
 
                      break;
3830
 
 
3831
 
                    default:
3832
 
                      abort ();
3833
 
                    }
3834
 
 
3835
 
# if ENABLE_UNISTDIO
3836
 
                  /* Padding considers the number of characters, therefore the
3837
 
                     number of elements after padding may be
3838
 
                       > max (tmp_length, width)
3839
 
                     but is certainly
3840
 
                       <= tmp_length + width.  */
3841
 
                  tmp_length = xsum (tmp_length, width);
3842
 
# else
3843
 
                  /* Padding considers the number of elements, says POSIX.  */
3844
 
                  if (tmp_length < width)
3845
 
                    tmp_length = width;
3846
 
# endif
3847
 
 
3848
 
                  tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3849
 
                }
3850
 
 
3851
 
                if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
3852
 
                  tmp = tmpbuf;
3853
 
                else
3854
 
                  {
3855
 
                    size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
3856
 
 
3857
 
                    if (size_overflow_p (tmp_memsize))
3858
 
                      /* Overflow, would lead to out of memory.  */
3859
 
                      goto out_of_memory;
3860
 
                    tmp = (TCHAR_T *) malloc (tmp_memsize);
3861
 
                    if (tmp == NULL)
3862
 
                      /* Out of memory.  */
3863
 
                      goto out_of_memory;
3864
 
                  }
3865
 
#endif
3866
 
 
3867
 
                /* Decide whether to handle the precision ourselves.  */
3868
 
#if NEED_PRINTF_UNBOUNDED_PRECISION
3869
 
                switch (dp->conversion)
3870
 
                  {
3871
 
                  case 'd': case 'i': case 'u':
3872
 
                  case 'o':
3873
 
                  case 'x': case 'X': case 'p':
3874
 
                    prec_ourselves = has_precision && (precision > 0);
3875
 
                    break;
3876
 
                  default:
3877
 
                    prec_ourselves = 0;
3878
 
                    break;
3879
 
                  }
3880
 
#endif
3881
 
 
3882
 
                /* Decide whether to perform the padding ourselves.  */
3883
 
#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
3884
 
                switch (dp->conversion)
3885
 
                  {
 
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 ();
 
4506
#  endif
 
4507
                          }
 
4508
                      }
 
4509
                  }
 
4510
# endif
 
4511
 
 
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;
 
4584
#endif
 
4585
#if NEED_PRINTF_UNBOUNDED_PRECISION
 
4586
                int prec_ourselves;
 
4587
#else
 
4588
#               define prec_ourselves 0
 
4589
#endif
 
4590
#if NEED_PRINTF_FLAG_LEFTADJUST
 
4591
#               define pad_ourselves 1
 
4592
#elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
 
4593
                int pad_ourselves;
 
4594
#else
 
4595
#               define pad_ourselves 0
 
4596
#endif
 
4597
                TCHAR_T *fbp;
 
4598
                unsigned int prefix_count;
 
4599
                int prefixes[2] IF_LINT (= { 0 });
 
4600
#if !USE_SNPRINTF
 
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.  */
 
4673
#if NEED_PRINTF_UNBOUNDED_PRECISION
 
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
                  }
 
4685
#endif
 
4686
 
 
4687
                /* Decide whether to perform the padding ourselves.  */
 
4688
#if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
 
4689
                switch (dp->conversion)
 
4690
                  {
3886
4691
# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
3887
 
                  /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
3888
 
                     to perform the padding after this conversion.  Functions
3889
 
                     with unistdio extensions perform the padding based on
3890
 
                     character count rather than element count.  */
3891
 
                  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':
3892
4697
# endif
3893
4698
# if NEED_PRINTF_FLAG_ZERO
3894
 
                  case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
3895
 
                  case 'a': case 'A':
 
4699
                  case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
 
4700
                  case 'a': case 'A':
3896
4701
# endif
3897
 
                    pad_ourselves = 1;
3898
 
                    break;
3899
 
                  default:
3900
 
                    pad_ourselves = prec_ourselves;
3901
 
                    break;
3902
 
                  }
3903
 
#endif
3904
 
 
3905
 
                /* Construct the format string for calling snprintf or
3906
 
                   sprintf.  */
3907
 
                fbp = buf;
3908
 
                *fbp++ = '%';
 
4702
                    pad_ourselves = 1;
 
4703
                    break;
 
4704
                  default:
 
4705
                    pad_ourselves = prec_ourselves;
 
4706
                    break;
 
4707
                  }
 
4708
#endif
 
4709
 
 
4710
#if !USE_SNPRINTF
 
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
                  }
 
4732
#endif
 
4733
 
 
4734
                /* Construct the format string for calling snprintf or
 
4735
                   sprintf.  */
 
4736
                fbp = buf;
 
4737
                *fbp++ = '%';
3909
4738
#if NEED_PRINTF_FLAG_GROUPING
3910
 
                /* The underlying implementation doesn't support the ' flag.
3911
 
                   Produce no grouping characters in this case; this is
3912
 
                   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.  */
3913
4742
#else
3914
 
                if (flags & FLAG_GROUP)
3915
 
                  *fbp++ = '\'';
 
4743
                if (flags & FLAG_GROUP)
 
4744
                  *fbp++ = '\'';
3916
4745
#endif
3917
 
                if (flags & FLAG_LEFT)
3918
 
                  *fbp++ = '-';
3919
 
                if (flags & FLAG_SHOWSIGN)
3920
 
                  *fbp++ = '+';
3921
 
                if (flags & FLAG_SPACE)
3922
 
                  *fbp++ = ' ';
3923
 
                if (flags & FLAG_ALT)
3924
 
                  *fbp++ = '#';
3925
 
                if (!pad_ourselves)
3926
 
                  {
3927
 
                    if (flags & FLAG_ZERO)
3928
 
                      *fbp++ = '0';
3929
 
                    if (dp->width_start != dp->width_end)
3930
 
                      {
3931
 
                        size_t n = dp->width_end - dp->width_start;
3932
 
                        /* The width specification is known to consist only
3933
 
                           of standard ASCII characters.  */
3934
 
                        if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
3935
 
                          {
3936
 
                            memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
3937
 
                            fbp += n;
3938
 
                          }
3939
 
                        else
3940
 
                          {
3941
 
                            const FCHAR_T *mp = dp->width_start;
3942
 
                            do
3943
 
                              *fbp++ = (unsigned char) *mp++;
3944
 
                            while (--n > 0);
3945
 
                          }
3946
 
                      }
3947
 
                  }
3948
 
                if (!prec_ourselves)
3949
 
                  {
3950
 
                    if (dp->precision_start != dp->precision_end)
3951
 
                      {
3952
 
                        size_t n = dp->precision_end - dp->precision_start;
3953
 
                        /* The precision specification is known to consist only
3954
 
                           of standard ASCII characters.  */
3955
 
                        if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
3956
 
                          {
3957
 
                            memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
3958
 
                            fbp += n;
3959
 
                          }
3960
 
                        else
3961
 
                          {
3962
 
                            const FCHAR_T *mp = dp->precision_start;
3963
 
                            do
3964
 
                              *fbp++ = (unsigned char) *mp++;
3965
 
                            while (--n > 0);
3966
 
                          }
3967
 
                      }
3968
 
                  }
 
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
                  }
3969
4798
 
3970
 
                switch (type)
3971
 
                  {
 
4799
                switch (type)
 
4800
                  {
3972
4801
#if HAVE_LONG_LONG_INT
3973
 
                  case TYPE_LONGLONGINT:
3974
 
                  case TYPE_ULONGLONGINT:
 
4802
                  case TYPE_LONGLONGINT:
 
4803
                  case TYPE_ULONGLONGINT:
3975
4804
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3976
 
                    *fbp++ = 'I';
3977
 
                    *fbp++ = '6';
3978
 
                    *fbp++ = '4';
3979
 
                    break;
 
4805
                    *fbp++ = 'I';
 
4806
                    *fbp++ = '6';
 
4807
                    *fbp++ = '4';
 
4808
                    break;
3980
4809
# else
3981
 
                    *fbp++ = 'l';
3982
 
                    /*FALLTHROUGH*/
 
4810
                    *fbp++ = 'l';
 
4811
                    /*FALLTHROUGH*/
3983
4812
# endif
3984
4813
#endif
3985
 
                  case TYPE_LONGINT:
3986
 
                  case TYPE_ULONGINT:
 
4814
                  case TYPE_LONGINT:
 
4815
                  case TYPE_ULONGINT:
3987
4816
#if HAVE_WINT_T
3988
 
                  case TYPE_WIDE_CHAR:
 
4817
                  case TYPE_WIDE_CHAR:
3989
4818
#endif
3990
4819
#if HAVE_WCHAR_T
3991
 
                  case TYPE_WIDE_STRING:
 
4820
                  case TYPE_WIDE_STRING:
3992
4821
#endif
3993
 
                    *fbp++ = 'l';
3994
 
                    break;
3995
 
                  case TYPE_LONGDOUBLE:
3996
 
                    *fbp++ = 'L';
3997
 
                    break;
3998
 
                  default:
3999
 
                    break;
4000
 
                  }
 
4822
                    *fbp++ = 'l';
 
4823
                    break;
 
4824
                  case TYPE_LONGDOUBLE:
 
4825
                    *fbp++ = 'L';
 
4826
                    break;
 
4827
                  default:
 
4828
                    break;
 
4829
                  }
4001
4830
#if NEED_PRINTF_DIRECTIVE_F
4002
 
                if (dp->conversion == 'F')
4003
 
                  *fbp = 'f';
4004
 
                else
 
4831
                if (dp->conversion == 'F')
 
4832
                  *fbp = 'f';
 
4833
                else
4005
4834
#endif
4006
 
                  *fbp = dp->conversion;
 
4835
                  *fbp = dp->conversion;
4007
4836
#if USE_SNPRINTF
4008
 
# if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3))
4009
 
                fbp[1] = '%';
4010
 
                fbp[2] = 'n';
4011
 
                fbp[3] = '\0';
 
4837
# if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
 
4838
                fbp[1] = '%';
 
4839
                fbp[2] = 'n';
 
4840
                fbp[3] = '\0';
4012
4841
# else
4013
 
                /* On glibc2 systems from glibc >= 2.3 - probably also older
4014
 
                   ones - we know that snprintf's returns value conforms to
4015
 
                   ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes.
4016
 
                   Therefore we can avoid using %n in this situation.
4017
 
                   On glibc2 systems from 2004-10-18 or newer, the use of %n
4018
 
                   in format strings in writable memory may crash the program
4019
 
                   (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
4020
 
                   in this situation.  */
4021
 
                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';
4022
4866
# endif
4023
4867
#else
4024
 
                fbp[1] = '\0';
 
4868
                fbp[1] = '\0';
4025
4869
#endif
4026
4870
 
4027
 
                /* Construct the arguments for calling snprintf or sprintf.  */
4028
 
                prefix_count = 0;
4029
 
                if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
4030
 
                  {
4031
 
                    if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4032
 
                      abort ();
4033
 
                    prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
4034
 
                  }
4035
 
                if (dp->precision_arg_index != ARG_NONE)
4036
 
                  {
4037
 
                    if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4038
 
                      abort ();
4039
 
                    prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
4040
 
                  }
 
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
                  }
4041
4885
 
4042
4886
#if USE_SNPRINTF
4043
 
                /* The SNPRINTF result is appended after result[0..length].
4044
 
                   The latter is an array of DCHAR_T; SNPRINTF appends an
4045
 
                   array of TCHAR_T to it.  This is possible because
4046
 
                   sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
4047
 
                   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).  */
4048
4892
# define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
4049
 
                /* Prepare checking whether snprintf returns the count
4050
 
                   via %n.  */
4051
 
                ENSURE_ALLOCATION (xsum (length, 1));
4052
 
                *(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';
4053
4901
#endif
4054
4902
 
4055
 
                for (;;)
4056
 
                  {
4057
 
                    int count = -1;
 
4903
                for (;;)
 
4904
                  {
 
4905
                    int count = -1;
4058
4906
 
4059
4907
#if USE_SNPRINTF
4060
 
                    int retcount = 0;
4061
 
                    size_t maxlen = allocated - length;
4062
 
                    /* SNPRINTF can fail if its second argument is
4063
 
                       > INT_MAX.  */
4064
 
                    if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
4065
 
                      maxlen = INT_MAX / TCHARS_PER_DCHAR;
4066
 
                    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;
4067
4915
# define SNPRINTF_BUF(arg) \
4068
 
                    switch (prefix_count)                                   \
4069
 
                      {                                                     \
4070
 
                      case 0:                                               \
4071
 
                        retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4072
 
                                             maxlen, buf,                   \
4073
 
                                             arg, &count);                  \
4074
 
                        break;                                              \
4075
 
                      case 1:                                               \
4076
 
                        retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4077
 
                                             maxlen, buf,                   \
4078
 
                                             prefixes[0], arg, &count);     \
4079
 
                        break;                                              \
4080
 
                      case 2:                                               \
4081
 
                        retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4082
 
                                             maxlen, buf,                   \
4083
 
                                             prefixes[0], prefixes[1], arg, \
4084
 
                                             &count);                       \
4085
 
                        break;                                              \
4086
 
                      default:                                              \
4087
 
                        abort ();                                           \
4088
 
                      }
 
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
                      }
4089
4937
#else
4090
4938
# define SNPRINTF_BUF(arg) \
4091
 
                    switch (prefix_count)                                   \
4092
 
                      {                                                     \
4093
 
                      case 0:                                               \
4094
 
                        count = sprintf (tmp, buf, arg);                    \
4095
 
                        break;                                              \
4096
 
                      case 1:                                               \
4097
 
                        count = sprintf (tmp, buf, prefixes[0], arg);       \
4098
 
                        break;                                              \
4099
 
                      case 2:                                               \
4100
 
                        count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
4101
 
                                         arg);                              \
4102
 
                        break;                                              \
4103
 
                      default:                                              \
4104
 
                        abort ();                                           \
4105
 
                      }
 
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
                      }
4106
4954
#endif
4107
4955
 
4108
 
                    switch (type)
4109
 
                      {
4110
 
                      case TYPE_SCHAR:
4111
 
                        {
4112
 
                          int arg = a.arg[dp->arg_index].a.a_schar;
4113
 
                          SNPRINTF_BUF (arg);
4114
 
                        }
4115
 
                        break;
4116
 
                      case TYPE_UCHAR:
4117
 
                        {
4118
 
                          unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
4119
 
                          SNPRINTF_BUF (arg);
4120
 
                        }
4121
 
                        break;
4122
 
                      case TYPE_SHORT:
4123
 
                        {
4124
 
                          int arg = a.arg[dp->arg_index].a.a_short;
4125
 
                          SNPRINTF_BUF (arg);
4126
 
                        }
4127
 
                        break;
4128
 
                      case TYPE_USHORT:
4129
 
                        {
4130
 
                          unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
4131
 
                          SNPRINTF_BUF (arg);
4132
 
                        }
4133
 
                        break;
4134
 
                      case TYPE_INT:
4135
 
                        {
4136
 
                          int arg = a.arg[dp->arg_index].a.a_int;
4137
 
                          SNPRINTF_BUF (arg);
4138
 
                        }
4139
 
                        break;
4140
 
                      case TYPE_UINT:
4141
 
                        {
4142
 
                          unsigned int arg = a.arg[dp->arg_index].a.a_uint;
4143
 
                          SNPRINTF_BUF (arg);
4144
 
                        }
4145
 
                        break;
4146
 
                      case TYPE_LONGINT:
4147
 
                        {
4148
 
                          long int arg = a.arg[dp->arg_index].a.a_longint;
4149
 
                          SNPRINTF_BUF (arg);
4150
 
                        }
4151
 
                        break;
4152
 
                      case TYPE_ULONGINT:
4153
 
                        {
4154
 
                          unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
4155
 
                          SNPRINTF_BUF (arg);
4156
 
                        }
4157
 
                        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;
4158
5007
#if HAVE_LONG_LONG_INT
4159
 
                      case TYPE_LONGLONGINT:
4160
 
                        {
4161
 
                          long long int arg = a.arg[dp->arg_index].a.a_longlongint;
4162
 
                          SNPRINTF_BUF (arg);
4163
 
                        }
4164
 
                        break;
4165
 
                      case TYPE_ULONGLONGINT:
4166
 
                        {
4167
 
                          unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
4168
 
                          SNPRINTF_BUF (arg);
4169
 
                        }
4170
 
                        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;
4171
5020
#endif
4172
 
                      case TYPE_DOUBLE:
4173
 
                        {
4174
 
                          double arg = a.arg[dp->arg_index].a.a_double;
4175
 
                          SNPRINTF_BUF (arg);
4176
 
                        }
4177
 
                        break;
4178
 
                      case TYPE_LONGDOUBLE:
4179
 
                        {
4180
 
                          long double arg = a.arg[dp->arg_index].a.a_longdouble;
4181
 
                          SNPRINTF_BUF (arg);
4182
 
                        }
4183
 
                        break;
4184
 
                      case TYPE_CHAR:
4185
 
                        {
4186
 
                          int arg = a.arg[dp->arg_index].a.a_char;
4187
 
                          SNPRINTF_BUF (arg);
4188
 
                        }
4189
 
                        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;
4190
5039
#if HAVE_WINT_T
4191
 
                      case TYPE_WIDE_CHAR:
4192
 
                        {
4193
 
                          wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
4194
 
                          SNPRINTF_BUF (arg);
4195
 
                        }
4196
 
                        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;
4197
5046
#endif
4198
 
                      case TYPE_STRING:
4199
 
                        {
4200
 
                          const char *arg = a.arg[dp->arg_index].a.a_string;
4201
 
                          SNPRINTF_BUF (arg);
4202
 
                        }
4203
 
                        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;
4204
5053
#if HAVE_WCHAR_T
4205
 
                      case TYPE_WIDE_STRING:
4206
 
                        {
4207
 
                          const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
4208
 
                          SNPRINTF_BUF (arg);
4209
 
                        }
4210
 
                        break;
4211
 
#endif
4212
 
                      case TYPE_POINTER:
4213
 
                        {
4214
 
                          void *arg = a.arg[dp->arg_index].a.a_pointer;
4215
 
                          SNPRINTF_BUF (arg);
4216
 
                        }
4217
 
                        break;
4218
 
                      default:
4219
 
                        abort ();
4220
 
                      }
4221
 
 
4222
 
#if USE_SNPRINTF
4223
 
                    /* Portability: Not all implementations of snprintf()
4224
 
                       are ISO C 99 compliant.  Determine the number of
4225
 
                       bytes that snprintf() has produced or would have
4226
 
                       produced.  */
4227
 
                    if (count >= 0)
4228
 
                      {
4229
 
                        /* Verify that snprintf() has NUL-terminated its
4230
 
                           result.  */
4231
 
                        if (count < maxlen
4232
 
                            && ((TCHAR_T *) (result + length)) [count] != '\0')
4233
 
                          abort ();
4234
 
                        /* Portability hack.  */
4235
 
                        if (retcount > count)
4236
 
                          count = retcount;
4237
 
                      }
4238
 
                    else
4239
 
                      {
4240
 
                        /* snprintf() doesn't understand the '%n'
4241
 
                           directive.  */
4242
 
                        if (fbp[1] != '\0')
4243
 
                          {
4244
 
                            /* Don't use the '%n' directive; instead, look
4245
 
                               at the snprintf() return value.  */
4246
 
                            fbp[1] = '\0';
4247
 
                            continue;
4248
 
                          }
4249
 
                        else
4250
 
                          {
4251
 
                            /* Look at the snprintf() return value.  */
4252
 
                            if (retcount < 0)
4253
 
                              {
4254
 
                                /* HP-UX 10.20 snprintf() is doubly deficient:
4255
 
                                   It doesn't understand the '%n' directive,
4256
 
                                   *and* it returns -1 (rather than the length
4257
 
                                   that would have been required) when the
4258
 
                                   buffer is too small.  */
4259
 
                                size_t bigger_need =
4260
 
                                  xsum (xtimes (allocated, 2), 12);
4261
 
                                ENSURE_ALLOCATION (bigger_need);
4262
 
                                continue;
4263
 
                              }
4264
 
                            else
4265
 
                              count = retcount;
4266
 
                          }
4267
 
                      }
4268
 
#endif
4269
 
 
4270
 
                    /* Attempt to handle failure.  */
4271
 
                    if (count < 0)
4272
 
                      {
4273
 
                        if (!(result == resultbuf || result == NULL))
4274
 
                          free (result);
4275
 
                        if (buf_malloced != NULL)
4276
 
                          free (buf_malloced);
4277
 
                        CLEANUP ();
4278
 
                        errno = EINVAL;
4279
 
                        return NULL;
4280
 
                      }
4281
 
 
4282
 
#if USE_SNPRINTF
4283
 
                    /* Handle overflow of the allocated buffer.
4284
 
                       If such an overflow occurs, a C99 compliant snprintf()
4285
 
                       returns a count >= maxlen.  However, a non-compliant
4286
 
                       snprintf() function returns only count = maxlen - 1.  To
4287
 
                       cover both cases, test whether count >= maxlen - 1.  */
4288
 
                    if ((unsigned int) count + 1 >= maxlen)
4289
 
                      {
4290
 
                        /* If maxlen already has attained its allowed maximum,
4291
 
                           allocating more memory will not increase maxlen.
4292
 
                           Instead of looping, bail out.  */
4293
 
                        if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
4294
 
                          goto overflow;
4295
 
                        else
4296
 
                          {
4297
 
                            /* Need at least count * sizeof (TCHAR_T) bytes.
4298
 
                               But allocate proportionally, to avoid looping
4299
 
                               eternally if snprintf() reports a too small
4300
 
                               count.  */
4301
 
                            size_t n =
4302
 
                              xmax (xsum (length,
4303
 
                                          (count + TCHARS_PER_DCHAR - 1)
4304
 
                                          / TCHARS_PER_DCHAR),
4305
 
                                    xtimes (allocated, 2));
4306
 
 
4307
 
                            ENSURE_ALLOCATION (n);
4308
 
                            continue;
4309
 
                          }
4310
 
                      }
 
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
                      }
4311
5204
#endif
4312
5205
 
4313
5206
#if NEED_PRINTF_UNBOUNDED_PRECISION
4314
 
                    if (prec_ourselves)
4315
 
                      {
4316
 
                        /* Handle the precision.  */
4317
 
                        TCHAR_T *prec_ptr = 
 
5207
                    if (prec_ourselves)
 
5208
                      {
 
5209
                        /* Handle the precision.  */
 
5210
                        TCHAR_T *prec_ptr =
4318
5211
# if USE_SNPRINTF
4319
 
                          (TCHAR_T *) (result + length);
 
5212
                          (TCHAR_T *) (result + length);
4320
5213
# else
4321
 
                          tmp;
 
5214
                          tmp;
4322
5215
# endif
4323
 
                        size_t prefix_count;
4324
 
                        size_t move;
4325
 
 
4326
 
                        prefix_count = 0;
4327
 
                        /* Put the additional zeroes after the sign.  */
4328
 
                        if (count >= 1
4329
 
                            && (*prec_ptr == '-' || *prec_ptr == '+'
4330
 
                                || *prec_ptr == ' '))
4331
 
                          prefix_count = 1;
4332
 
                        /* Put the additional zeroes after the 0x prefix if
4333
 
                           (flags & FLAG_ALT) || (dp->conversion == 'p').  */
4334
 
                        else if (count >= 2
4335
 
                                 && prec_ptr[0] == '0'
4336
 
                                 && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
4337
 
                          prefix_count = 2;
4338
 
 
4339
 
                        move = count - prefix_count;
4340
 
                        if (precision > move)
4341
 
                          {
4342
 
                            /* Insert zeroes.  */
4343
 
                            size_t insert = precision - move;
4344
 
                            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;
4345
5238
 
4346
5239
# if USE_SNPRINTF
4347
 
                            size_t n =
4348
 
                              xsum (length,
4349
 
                                    (count + insert + TCHARS_PER_DCHAR - 1)
4350
 
                                    / TCHARS_PER_DCHAR);
4351
 
                            length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
4352
 
                            ENSURE_ALLOCATION (n);
4353
 
                            length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
4354
 
                            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);
4355
5248
# endif
4356
5249
 
4357
 
                            prec_end = prec_ptr + count;
4358
 
                            prec_ptr += prefix_count;
4359
 
 
4360
 
                            while (prec_end > prec_ptr)
4361
 
                              {
4362
 
                                prec_end--;
4363
 
                                prec_end[insert] = prec_end[0];
4364
 
                              }
4365
 
 
4366
 
                            prec_end += insert;
4367
 
                            do
4368
 
                              *--prec_end = '0';
4369
 
                            while (prec_end > prec_ptr);
4370
 
 
4371
 
                            count += insert;
4372
 
                          }
4373
 
                      }
 
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
                      }
 
5267
#endif
 
5268
 
 
5269
#if !USE_SNPRINTF
 
5270
                    if (count >= tmp_length)
 
5271
                      /* tmp_length was incorrectly calculated - fix the
 
5272
                         code above!  */
 
5273
                      abort ();
4374
5274
#endif
4375
5275
 
4376
5276
#if !DCHAR_IS_TCHAR
4377
 
# if !USE_SNPRINTF
4378
 
                    if (count >= tmp_length)
4379
 
                      /* tmp_length was incorrectly calculated - fix the
4380
 
                         code above!  */
4381
 
                      abort ();
4382
 
# endif
4383
 
 
4384
 
                    /* Convert from TCHAR_T[] to DCHAR_T[].  */
4385
 
                    if (dp->conversion == 'c' || dp->conversion == 's')
4386
 
                      {
4387
 
                        /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
4388
 
                           TYPE_WIDE_STRING.
4389
 
                           The result string is not certainly ASCII.  */
4390
 
                        const TCHAR_T *tmpsrc;
4391
 
                        DCHAR_T *tmpdst;
4392
 
                        size_t tmpdst_len;
4393
 
                        /* This code assumes that TCHAR_T is 'char'.  */
4394
 
                        typedef int TCHAR_T_verify
4395
 
                                    [2 * (sizeof (TCHAR_T) == 1) - 1];
4396
 
# if USE_SNPRINTF
4397
 
                        tmpsrc = (TCHAR_T *) (result + length);
4398
 
# else
4399
 
                        tmpsrc = tmp;
4400
 
# endif
4401
 
                        tmpdst = NULL;
4402
 
                        tmpdst_len = 0;
4403
 
                        if (DCHAR_CONV_FROM_ENCODING (locale_charset (),
4404
 
                                                      iconveh_question_mark,
4405
 
                                                      tmpsrc, count,
4406
 
                                                      NULL,
4407
 
                                                      &tmpdst, &tmpdst_len)
4408
 
                            < 0)
4409
 
                          {
4410
 
                            int saved_errno = errno;
4411
 
                            if (!(result == resultbuf || result == NULL))
4412
 
                              free (result);
4413
 
                            if (buf_malloced != NULL)
4414
 
                              free (buf_malloced);
4415
 
                            CLEANUP ();
4416
 
                            errno = saved_errno;
4417
 
                            return NULL;
4418
 
                          }
4419
 
                        ENSURE_ALLOCATION (xsum (length, tmpdst_len));
4420
 
                        DCHAR_CPY (result + length, tmpdst, tmpdst_len);
4421
 
                        free (tmpdst);
4422
 
                        count = tmpdst_len;
4423
 
                      }
4424
 
                    else
4425
 
                      {
4426
 
                        /* The result string is ASCII.
4427
 
                           Simple 1:1 conversion.  */
4428
 
# if USE_SNPRINTF
4429
 
                        /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
4430
 
                           no-op conversion, in-place on the array starting
4431
 
                           at (result + length).  */
4432
 
                        if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
4433
 
# endif
4434
 
                          {
4435
 
                            const TCHAR_T *tmpsrc;
4436
 
                            DCHAR_T *tmpdst;
4437
 
                            size_t n;
4438
 
 
4439
 
# if USE_SNPRINTF
4440
 
                            if (result == resultbuf)
4441
 
                              {
4442
 
                                tmpsrc = (TCHAR_T *) (result + length);
4443
 
                                /* ENSURE_ALLOCATION will not move tmpsrc
4444
 
                                   (because it's part of resultbuf).  */
4445
 
                                ENSURE_ALLOCATION (xsum (length, count));
4446
 
                              }
4447
 
                            else
4448
 
                              {
4449
 
                                /* ENSURE_ALLOCATION will move the array
4450
 
                                   (because it uses realloc().  */
4451
 
                                ENSURE_ALLOCATION (xsum (length, count));
4452
 
                                tmpsrc = (TCHAR_T *) (result + length);
4453
 
                              }
4454
 
# else
4455
 
                            tmpsrc = tmp;
4456
 
                            ENSURE_ALLOCATION (xsum (length, count));
4457
 
# endif
4458
 
                            tmpdst = result + length;
4459
 
                            /* Copy backwards, because of overlapping.  */
4460
 
                            tmpsrc += count;
4461
 
                            tmpdst += count;
4462
 
                            for (n = count; n > 0; n--)
4463
 
                              *--tmpdst = (unsigned char) *--tmpsrc;
4464
 
                          }
4465
 
                      }
 
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];
 
5289
# if USE_SNPRINTF
 
5290
                        tmpsrc = (TCHAR_T *) (result + length);
 
5291
# else
 
5292
                        tmpsrc = tmp;
 
5293
# endif
 
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.  */
 
5320
# if USE_SNPRINTF
 
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))
 
5325
# endif
 
5326
                          {
 
5327
                            const TCHAR_T *tmpsrc;
 
5328
                            DCHAR_T *tmpdst;
 
5329
                            size_t n;
 
5330
 
 
5331
# if USE_SNPRINTF
 
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
                              }
 
5346
# else
 
5347
                            tmpsrc = tmp;
 
5348
                            ENSURE_ALLOCATION (xsum (length, count));
 
5349
# endif
 
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
                      }
4466
5358
#endif
4467
5359
 
4468
5360
#if DCHAR_IS_TCHAR && !USE_SNPRINTF
4469
 
                    /* Make room for the result.  */
4470
 
                    if (count > allocated - length)
4471
 
                      {
4472
 
                        /* Need at least count elements.  But allocate
4473
 
                           proportionally.  */
4474
 
                        size_t n =
4475
 
                          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));
4476
5368
 
4477
 
                        ENSURE_ALLOCATION (n);
4478
 
                      }
 
5369
                        ENSURE_ALLOCATION (n);
 
5370
                      }
4479
5371
#endif
4480
5372
 
4481
 
                    /* Here count <= allocated - length.  */
 
5373
                    /* Here count <= allocated - length.  */
4482
5374
 
4483
 
                    /* Perform padding.  */
4484
 
#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4485
 
                    if (pad_ourselves && has_width)
4486
 
                      {
4487
 
                        size_t w;
 
5375
                    /* Perform padding.  */
 
5376
#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
 
5377
                    if (pad_ourselves && has_width)
 
5378
                      {
 
5379
                        size_t w;
4488
5380
# if ENABLE_UNISTDIO
4489
 
                        /* Outside POSIX, it's preferrable to compare the width
4490
 
                           against the number of _characters_ of the converted
4491
 
                           value.  */
4492
 
                        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);
4493
5385
# else
4494
 
                        /* The width is compared against the number of _bytes_
4495
 
                           of the converted value, says POSIX.  */
4496
 
                        w = count;
 
5386
                        /* The width is compared against the number of _bytes_
 
5387
                           of the converted value, says POSIX.  */
 
5388
                        w = count;
4497
5389
# endif
4498
 
                        if (w < width)
4499
 
                          {
4500
 
                            size_t pad = width - w;
 
5390
                        if (w < width)
 
5391
                          {
 
5392
                            size_t pad = width - w;
 
5393
 
 
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));
 
5402
 
4501
5403
# if USE_SNPRINTF
4502
 
                            /* Make room for the result.  */
4503
 
                            if (xsum (count, pad) > allocated - length)
4504
 
                              {
4505
 
                                /* Need at least count + pad elements.  But
4506
 
                                   allocate proportionally.  */
4507
 
                                size_t n =
4508
 
                                  xmax (xsum3 (length, count, pad),
4509
 
                                        xtimes (allocated, 2));
 
5404
                                length += count;
 
5405
                                ENSURE_ALLOCATION (n);
 
5406
                                length -= count;
 
5407
# else
 
5408
                                ENSURE_ALLOCATION (n);
 
5409
# endif
 
5410
                              }
 
5411
                            /* Here count + pad <= allocated - length.  */
4510
5412
 
4511
 
                                length += count;
4512
 
                                ENSURE_ALLOCATION (n);
4513
 
                                length -= count;
4514
 
                              }
4515
 
                            /* Here count + pad <= allocated - length.  */
4516
 
# endif
4517
 
                            {
 
5413
                            {
4518
5414
# if !DCHAR_IS_TCHAR || USE_SNPRINTF
4519
 
                              DCHAR_T * const rp = result + length;
 
5415
                              DCHAR_T * const rp = result + length;
4520
5416
# else
4521
 
                              DCHAR_T * const rp = tmp;
4522
 
# endif
4523
 
                              DCHAR_T *p = rp + count;
4524
 
                              DCHAR_T *end = p + pad;
4525
 
# if NEED_PRINTF_FLAG_ZERO
4526
 
                              DCHAR_T *pad_ptr;
4527
 
#  if !DCHAR_IS_TCHAR
4528
 
                              if (dp->conversion == 'c'
4529
 
                                  || dp->conversion == 's')
4530
 
                                /* No zero-padding for string directives.  */
4531
 
                                pad_ptr = NULL;
4532
 
                              else
4533
 
#  endif
4534
 
                                {
4535
 
                                  pad_ptr = (*rp == '-' ? rp + 1 : rp);
4536
 
                                  /* No zero-padding of "inf" and "nan".  */
4537
 
                                  if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
4538
 
                                      || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
4539
 
                                    pad_ptr = NULL;
4540
 
                                }
4541
 
# endif
4542
 
                              /* The generated string now extends from rp to p,
4543
 
                                 with the zero padding insertion point being at
4544
 
                                 pad_ptr.  */
4545
 
 
4546
 
                              count = count + pad; /* = end - rp */
4547
 
 
4548
 
                              if (flags & FLAG_LEFT)
4549
 
                                {
4550
 
                                  /* Pad with spaces on the right.  */
4551
 
                                  for (; pad > 0; pad--)
4552
 
                                    *p++ = ' ';
4553
 
                                }
4554
 
# if NEED_PRINTF_FLAG_ZERO
4555
 
                              else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4556
 
                                {
4557
 
                                  /* Pad with zeroes.  */
4558
 
                                  DCHAR_T *q = end;
4559
 
 
4560
 
                                  while (p > pad_ptr)
4561
 
                                    *--q = *--p;
4562
 
                                  for (; pad > 0; pad--)
4563
 
                                    *p++ = '0';
4564
 
                                }
4565
 
# endif
4566
 
                              else
4567
 
                                {
4568
 
                                  /* Pad with spaces on the left.  */
4569
 
                                  DCHAR_T *q = end;
4570
 
 
4571
 
                                  while (p > rp)
4572
 
                                    *--q = *--p;
4573
 
                                  for (; pad > 0; pad--)
4574
 
                                    *p++ = ' ';
4575
 
                                }
4576
 
                            }
4577
 
                          }
4578
 
                      }
4579
 
#endif
4580
 
 
4581
 
#if DCHAR_IS_TCHAR && !USE_SNPRINTF
4582
 
                    if (count >= tmp_length)
4583
 
                      /* tmp_length was incorrectly calculated - fix the
4584
 
                         code above!  */
4585
 
                      abort ();
4586
 
#endif
4587
 
 
4588
 
                    /* Here still count <= allocated - length.  */
 
5417
                              DCHAR_T * const rp = tmp;
 
5418
# endif
 
5419
                              DCHAR_T *p = rp + count;
 
5420
                              DCHAR_T *end = p + pad;
 
5421
                              DCHAR_T *pad_ptr;
 
5422
# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
 
5423
                              if (dp->conversion == 'c'
 
5424
                                  || dp->conversion == 's')
 
5425
                                /* No zero-padding for string directives.  */
 
5426
                                pad_ptr = NULL;
 
5427
                              else
 
5428
# endif
 
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
                      }
 
5471
#endif
 
5472
 
 
5473
                    /* Here still count <= allocated - length.  */
4589
5474
 
4590
5475
#if !DCHAR_IS_TCHAR || USE_SNPRINTF
4591
 
                    /* The snprintf() result did fit.  */
 
5476
                    /* The snprintf() result did fit.  */
4592
5477
#else
4593
 
                    /* Append the sprintf() result.  */
4594
 
                    memcpy (result + length, tmp, count * sizeof (DCHAR_T));
 
5478
                    /* Append the sprintf() result.  */
 
5479
                    memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4595
5480
#endif
4596
5481
#if !USE_SNPRINTF
4597
 
                    if (tmp != tmpbuf)
4598
 
                      free (tmp);
 
5482
                    if (tmp != tmpbuf)
 
5483
                      free (tmp);
4599
5484
#endif
4600
5485
 
4601
5486
#if NEED_PRINTF_DIRECTIVE_F
4602
 
                    if (dp->conversion == 'F')
4603
 
                      {
4604
 
                        /* Convert the %f result to upper case for %F.  */
4605
 
                        DCHAR_T *rp = result + length;
4606
 
                        size_t rc;
4607
 
                        for (rc = count; rc > 0; rc--, rp++)
4608
 
                          if (*rp >= 'a' && *rp <= 'z')
4609
 
                            *rp = *rp - 'a' + 'A';
4610
 
                      }
 
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
                      }
4611
5496
#endif
4612
5497
 
4613
 
                    length += count;
4614
 
                    break;
4615
 
                  }
4616
 
              }
4617
 
          }
 
5498
                    length += count;
 
5499
                    break;
 
5500
                  }
 
5501
#undef pad_ourselves
 
5502
#undef prec_ourselves
 
5503
              }
 
5504
          }
4618
5505
      }
4619
5506
 
4620
5507
    /* Add the final NUL.  */
4623
5510
 
4624
5511
    if (result != resultbuf && length + 1 < allocated)
4625
5512
      {
4626
 
        /* Shrink the allocated memory if possible.  */
4627
 
        DCHAR_T *memory;
 
5513
        /* Shrink the allocated memory if possible.  */
 
5514
        DCHAR_T *memory;
4628
5515
 
4629
 
        memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
4630
 
        if (memory != NULL)
4631
 
          result = memory;
 
5516
        memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
 
5517
        if (memory != NULL)
 
5518
          result = memory;
4632
5519
      }
4633
5520
 
4634
5521
    if (buf_malloced != NULL)
4641
5528
       not have this limitation.  */
4642
5529
    return result;
4643
5530
 
 
5531
#if USE_SNPRINTF
4644
5532
  overflow:
4645
5533
    if (!(result == resultbuf || result == NULL))
4646
5534
      free (result);
4649
5537
    CLEANUP ();
4650
5538
    errno = EOVERFLOW;
4651
5539
    return NULL;
 
5540
#endif
4652
5541
 
4653
5542
  out_of_memory:
4654
5543
    if (!(result == resultbuf || result == NULL))
4662
5551
  }
4663
5552
}
4664
5553
 
 
5554
#undef MAX_ROOM_NEEDED
4665
5555
#undef TCHARS_PER_DCHAR
4666
5556
#undef SNPRINTF
4667
5557
#undef USE_SNPRINTF
 
5558
#undef DCHAR_SET
4668
5559
#undef DCHAR_CPY
4669
5560
#undef PRINTF_PARSE
4670
5561
#undef DIRECTIVES