~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to grub-core/gnulib/vasnprintf.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

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