~ubuntu-branches/ubuntu/vivid/gzip/vivid

« back to all changes in this revision

Viewing changes to lib/vasnprintf.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-10-19 11:42:42 UTC
  • mfrom: (4.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20111019114242-d8wiiu8kbvdtgmgj
Tags: 1.4-1ubuntu1
* Merge with Debian testing.  Remaining Ubuntu changes:
  - debian/{control,rules}: Remove the Win32 build and mingw64
    build-dependency, since mingw is in universe, and will remain so for
    the forseeable future.

Show diffs side-by-side

added added

removed removed

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