1/* mpfr_vasprintf -- main function for the printf functions family
2   plus helper macros & functions.
3
4Copyright 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
5Contributed by the Arenaire and Cacao projects, INRIA.
6
7This file is part of the GNU MPFR Library.
8
9The GNU MPFR Library is free software; you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation; either version 3 of the License, or (at your
12option) any later version.
13
14The GNU MPFR Library is distributed in the hope that it will be useful, but
15WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
17License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
21http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
2251 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28/* The mpfr_printf-like functions are defined only if stdarg.h exists */
29#ifdef HAVE_STDARG
30
31#include <stdarg.h>
32
33#ifndef HAVE_VA_COPY
34# ifdef HAVE___VA_COPY
35#  define va_copy(dst,src) __va_copy(dst, src)
36# else
37/* autoconf manual advocates this fallback.
38   This is also the solution chosen by gmp */
39#  define va_copy(dst,src) \
40  do { memcpy(&(dst), &(src), sizeof(va_list)); } while (0)
41# endif /* HAVE___VA_COPY */
42#endif /* HAVE_VA_COPY */
43
44#ifdef HAVE_WCHAR_H
45#include <wchar.h>
46#endif
47
48#if defined (__cplusplus)
49#include <cstddef>
50#define __STDC_LIMIT_MACROS   /* SIZE_MAX defined with stdint.h inclusion */
51#else
52#include <stddef.h>             /* for ptrdiff_t */
53#endif
54
55#if HAVE_INTTYPES_H
56# include <inttypes.h> /* for intmax_t */
57#else
58# if HAVE_STDINT_H
59#  include <stdint.h> /* for WINT_MAX in particular */
60# endif
61#endif
62
63#define MPFR_NEED_LONGLONG_H
64#include "mpfr-impl.h"
65
66/* Define a length modifier corresponding to mpfr_prec_t.
67   We use literal string instead of literal character so as to permit future
68   extension to long long int ("ll"). */
69#if   _MPFR_PREC_FORMAT == 1
70#define MPFR_PREC_FORMAT_TYPE "h"
71#define MPFR_PREC_FORMAT_SIZE 1
72#elif _MPFR_PREC_FORMAT == 2
73#define MPFR_PREC_FORMAT_TYPE ""
74#define MPFR_PREC_FORMAT_SIZE 0
75#elif _MPFR_PREC_FORMAT == 3
76#define MPFR_PREC_FORMAT_TYPE "l"
77#define MPFR_PREC_FORMAT_SIZE 1
78#else
79#error "mpfr_prec_t size not supported"
80#endif
81
82#if (__GMP_MP_SIZE_T_INT == 1)
83#define MPFR_EXP_FORMAT_SPEC "i"
84#elif (__GMP_MP_SIZE_T_INT == 0)
85#define MPFR_EXP_FORMAT_SPEC "li"
86#else
87#error "mpfr_exp_t size not supported"
88#endif
89
90/* Output for special values defined in the C99 standard */
91#define MPFR_NAN_STRING_LC "nan"
92#define MPFR_NAN_STRING_UC "NAN"
93#define MPFR_NAN_STRING_LENGTH 3
94#define MPFR_INF_STRING_LC "inf"
95#define MPFR_INF_STRING_UC "INF"
96#define MPFR_INF_STRING_LENGTH 3
97
98/* The implicit \0 is useless, but we do not write num_to_text[16]
99   otherwise g++ complains. */
100static const char num_to_text[] = "0123456789abcdef";
101
102/* some macro and functions for parsing format string */
103
104/* Read an integer; saturate to INT_MAX. */
105#define READ_INT(ap, format, specinfo, field, label_out)                \
106  do {                                                                  \
107    while (*(format))                                                   \
108      {                                                                 \
109        int _i;                                                         \
110        switch (*(format))                                              \
111          {                                                             \
112          case '0':                                                     \
113          case '1':                                                     \
114          case '2':                                                     \
115          case '3':                                                     \
116          case '4':                                                     \
117          case '5':                                                     \
118          case '6':                                                     \
119          case '7':                                                     \
120          case '8':                                                     \
121          case '9':                                                     \
122            specinfo.field = (specinfo.field <= INT_MAX / 10) ?         \
123              specinfo.field * 10 : INT_MAX;                            \
124            _i = *(format) - '0';                                       \
125            MPFR_ASSERTN (_i >= 0 && _i <= 9);                          \
126            specinfo.field = (specinfo.field <= INT_MAX - _i) ?         \
127              specinfo.field + _i : INT_MAX;                            \
128            ++(format);                                                 \
129            break;                                                      \
130          case '*':                                                     \
131            specinfo.field = va_arg ((ap), int);                        \
132            ++(format);                                                 \
133          default:                                                      \
134            goto label_out;                                             \
135          }                                                             \
136      }                                                                 \
137  } while (0)
138
139/* arg_t contains all the types described by the 'type' field of the
140   format string */
141enum arg_t
142  {
143    NONE,
144    CHAR_ARG,
145    SHORT_ARG,
146    LONG_ARG,
147    LONG_LONG_ARG,
148    INTMAX_ARG,
149    SIZE_ARG,
150    PTRDIFF_ARG,
151    LONG_DOUBLE_ARG,
152    MPF_ARG,
153    MPQ_ARG,
154    MP_LIMB_ARG,
155    MP_LIMB_ARRAY_ARG,
156    MPZ_ARG,
157    MPFR_PREC_ARG,
158    MPFR_ARG,
159    UNSUPPORTED
160  };
161
162/* Each conversion specification of the format string will be translated in a
163   printf_spec structure by the parser.
164   This structure is adapted from the GNU libc one. */
165struct printf_spec
166{
167  unsigned int alt:1;           /* # flag */
168  unsigned int space:1;         /* Space flag */
169  unsigned int left:1;          /* - flag */
170  unsigned int showsign:1;      /* + flag */
171  unsigned int group:1;         /* ' flag */
172
173  int width;                    /* Width */
174  int prec;                     /* Precision */
175
176  enum arg_t arg_type;          /* Type of argument */
177  mpfr_rnd_t rnd_mode;            /* Rounding mode */
178  char spec;                    /* Conversion specifier */
179
180  char pad;                     /* Padding character */
181};
182
183static void
184specinfo_init (struct printf_spec *specinfo)
185{
186  specinfo->alt = 0;
187  specinfo->space = 0;
188  specinfo->left = 0;
189  specinfo->showsign = 0;
190  specinfo->group = 0;
191  specinfo->width = 0;
192  specinfo->prec = 0;
193  specinfo->arg_type = NONE;
194  specinfo->rnd_mode = MPFR_RNDN;
195  specinfo->spec = '\0';
196  specinfo->pad = ' ';
197}
198
199#define FLOATING_POINT_ARG_TYPE(at) \
200  ((at) == MPFR_ARG || (at) == MPF_ARG || (at) == LONG_DOUBLE_ARG)
201
202#define INTEGER_LIKE_ARG_TYPE(at)                                       \
203  ((at) == SHORT_ARG || (at) == LONG_ARG || (at) == LONG_LONG_ARG       \
204   || (at) == INTMAX_ARG  || (at) == MPFR_PREC_ARG || (at) == MPZ_ARG   \
205   || (at) == MPQ_ARG || (at) == MP_LIMB_ARG || (at) == MP_LIMB_ARRAY_ARG \
206   || (at) == CHAR_ARG || (at) == SIZE_ARG || (at) == PTRDIFF_ARG)
207
208static int
209specinfo_is_valid (struct printf_spec spec)
210{
211  switch (spec.spec)
212    {
213    case 'n':
214      return -1;
215
216    case 'a':    case 'A':
217    case 'e':    case 'E':
218    case 'f':    case 'F':
219    case 'g':    case 'G':
220      return (spec.arg_type == NONE
221              || FLOATING_POINT_ARG_TYPE (spec.arg_type));
222
223    case 'b':
224      return spec.arg_type == MPFR_ARG;
225
226    case 'd':    case 'i':
227    case 'u':    case 'o':
228    case 'x':    case 'X':
229      return (spec.arg_type == NONE
230              || INTEGER_LIKE_ARG_TYPE (spec.arg_type));
231
232    case 'c':
233    case 's':
234      return (spec.arg_type == NONE || spec.arg_type == LONG_ARG);
235
236    case 'p':
237      return spec.arg_type == NONE;
238
239    default:
240      return 0;
241    }
242}
243
244static const char *
245parse_flags (const char *format, struct printf_spec *specinfo)
246{
247  while (*format)
248    {
249      switch (*format)
250        {
251        case '0':
252          specinfo->pad = '0';
253          ++format;
254          break;
255        case '#':
256          specinfo->alt = 1;
257          ++format;
258          break;
259        case '+':
260          specinfo->showsign = 1;
261          ++format;
262          break;
263        case ' ':
264          specinfo->space = 1;
265          ++format;
266          break;
267        case '-':
268          specinfo->left = 1;
269          ++format;
270          break;
271        case '\'':
272          /* Single UNIX Specification for thousand separator */
273          specinfo->group = 1;
274          ++format;
275          break;
276        default:
277          return format;
278        }
279    }
280  return format;
281}
282
283static const char *
284parse_arg_type (const char *format, struct printf_spec *specinfo)
285{
286  switch (*format)
287    {
288    case '\0':
289      break;
290    case 'h':
291      if (*++format == 'h')
292#ifndef NPRINTF_HH
293        {
294          ++format;
295          specinfo->arg_type = CHAR_ARG;
296        }
297#else
298        specinfo->arg_type = UNSUPPORTED;
299#endif
300      else
301        specinfo->arg_type = SHORT_ARG;
302      break;
303    case 'l':
304      if (*++format == 'l')
305        {
306          ++format;
307#if defined (HAVE_LONG_LONG) && !defined(NPRINTF_LL)
308          specinfo->arg_type = LONG_LONG_ARG;
309#else
310          specinfo->arg_type = UNSUPPORTED;
311#endif
312          break;
313        }
314      else
315        {
316          specinfo->arg_type = LONG_ARG;
317          break;
318        }
319    case 'j':
320      ++format;
321#if defined(_MPFR_H_HAVE_INTMAX_T) && !defined(NPRINTF_J)
322      specinfo->arg_type = INTMAX_ARG;
323#else
324      specinfo->arg_type = UNSUPPORTED;
325#endif
326      break;
327    case 'z':
328      ++format;
329      specinfo->arg_type = SIZE_ARG;
330      break;
331    case 't':
332      ++format;
333#ifndef NPRINTF_T
334      specinfo->arg_type = PTRDIFF_ARG;
335#else
336      specinfo->arg_type = UNSUPPORTED;
337#endif
338      break;
339    case 'L':
340      ++format;
341#ifndef NPRINTF_L
342      specinfo->arg_type = LONG_DOUBLE_ARG;
343#else
344      specinfo->arg_type = UNSUPPORTED;
345#endif
346      break;
347    case 'F':
348      ++format;
349      specinfo->arg_type = MPF_ARG;
350      break;
351    case 'Q':
352      ++format;
353      specinfo->arg_type = MPQ_ARG;
354      break;
355    case 'M':
356      ++format;
357      /* The 'M' specifier was added in gmp 4.2.0 */
358      specinfo->arg_type = MP_LIMB_ARG;
359      break;
360    case 'N':
361      ++format;
362      specinfo->arg_type = MP_LIMB_ARRAY_ARG;
363      break;
364    case 'Z':
365      ++format;
366      specinfo->arg_type = MPZ_ARG;
367      break;
368
369      /* mpfr specific specifiers */
370    case 'P':
371      ++format;
372      specinfo->arg_type = MPFR_PREC_ARG;
373      break;
374    case 'R':
375      ++format;
376      specinfo->arg_type = MPFR_ARG;
377    }
378  return format;
379}
380
381
382/* some macros and functions filling the buffer */
383
384/* CONSUME_VA_ARG removes from va_list AP the type expected by SPECINFO */
385
386/* With a C++ compiler wchar_t and enumeration in va_list are converted to
387   integer type : int, unsigned int, long or unsigned long (unfortunately,
388   this is implementation dependant).
389   We follow gmp which assumes in print/doprnt.c that wchar_t is converted
390   to int (because wchar_t <= int).
391   For wint_t, we assume that the case WINT_MAX < INT_MAX yields an
392   integer promotion. */
393#ifdef HAVE_WCHAR_H
394#if defined(WINT_MAX) && WINT_MAX < INT_MAX
395typedef int    mpfr_va_wint;  /* integer promotion */
396#else
397typedef wint_t mpfr_va_wint;
398#endif
399#define CASE_LONG_ARG(specinfo, ap)                                     \
400  case LONG_ARG:                                                        \
401  if (((specinfo).spec == 'd') || ((specinfo).spec == 'i')              \
402      || ((specinfo).spec == 'o') || ((specinfo).spec == 'u')           \
403      || ((specinfo).spec == 'x') || ((specinfo).spec == 'X'))          \
404    (void) va_arg ((ap), long);                                         \
405  else if ((specinfo).spec == 'c')                                      \
406    (void) va_arg ((ap), mpfr_va_wint);                                 \
407  else if ((specinfo).spec == 's')                                      \
408    (void) va_arg ((ap), int); /* we assume integer promotion */        \
409  break;
410#else
411#define CASE_LONG_ARG(specinfo, ap)             \
412  case LONG_ARG:                                \
413  (void) va_arg ((ap), long);                   \
414  break;
415#endif
416
417#if defined(_MPFR_H_HAVE_INTMAX_T)
418#define CASE_INTMAX_ARG(specinfo, ap)           \
419  case INTMAX_ARG:                              \
420  (void) va_arg ((ap), intmax_t);               \
421  break;
422#else
423#define CASE_INTMAX_ARG(specinfo, ap)
424#endif
425
426#ifdef HAVE_LONG_LONG
427#define CASE_LONG_LONG_ARG(specinfo, ap)        \
428  case LONG_LONG_ARG:                           \
429  (void) va_arg ((ap), long long);              \
430  break;
431#else
432#define CASE_LONG_LONG_ARG(specinfo, ap)
433#endif
434
435#define CONSUME_VA_ARG(specinfo, ap)            \
436  do {                                          \
437    switch ((specinfo).arg_type)                \
438      {                                         \
439      case CHAR_ARG:                            \
440      case SHORT_ARG:                           \
441        (void) va_arg ((ap), int);              \
442        break;                                  \
443      CASE_LONG_ARG (specinfo, ap)              \
444      CASE_LONG_LONG_ARG (specinfo, ap)         \
445      CASE_INTMAX_ARG (specinfo, ap)            \
446      case SIZE_ARG:                            \
447        (void) va_arg ((ap), size_t);           \
448        break;                                  \
449      case PTRDIFF_ARG:                         \
450        (void) va_arg ((ap), ptrdiff_t);        \
451        break;                                  \
452      case LONG_DOUBLE_ARG:                     \
453        (void) va_arg ((ap), long double);      \
454        break;                                  \
455      case MPF_ARG:                             \
456        (void) va_arg ((ap), mpf_srcptr);       \
457        break;                                  \
458      case MPQ_ARG:                             \
459        (void) va_arg ((ap), mpq_srcptr);       \
460        break;                                  \
461      case MP_LIMB_ARG:                         \
462        (void) va_arg ((ap), mp_limb_t);        \
463        break;                                  \
464      case MP_LIMB_ARRAY_ARG:                   \
465        (void) va_arg ((ap), mpfr_limb_ptr);    \
466        (void) va_arg ((ap), mp_size_t);        \
467        break;                                  \
468      case MPZ_ARG:                             \
469        (void) va_arg ((ap), mpz_srcptr);       \
470        break;                                  \
471      default:                                  \
472        switch ((specinfo).spec)                \
473          {                                     \
474          case 'd':                             \
475          case 'i':                             \
476          case 'o':                             \
477          case 'u':                             \
478          case 'x':                             \
479          case 'X':                             \
480          case 'c':                             \
481            (void) va_arg ((ap), int);          \
482            break;                              \
483          case 'f':                             \
484          case 'F':                             \
485          case 'e':                             \
486          case 'E':                             \
487          case 'g':                             \
488          case 'G':                             \
489          case 'a':                             \
490          case 'A':                             \
491            (void) va_arg ((ap), double);       \
492            break;                              \
493          case 's':                             \
494            (void) va_arg ((ap), char *);       \
495            break;                              \
496          case 'p':                             \
497            (void) va_arg ((ap), void *);       \
498          }                                     \
499      }                                         \
500  } while (0)
501
502/* process the format part which does not deal with mpfr types,
503   jump to external label 'error' if gmp_asprintf return -1. */
504#define FLUSH(flag, start, end, ap, buf_ptr)                            \
505  do {                                                                  \
506    const size_t n = (end) - (start);                                   \
507    if ((flag))                                                         \
508      /* previous specifiers are understood by gmp_printf */            \
509      {                                                                 \
510        MPFR_TMP_DECL (marker);                                         \
511        char *fmt_copy;                                                 \
512        MPFR_TMP_MARK (marker);                                         \
513        fmt_copy = (char*) MPFR_TMP_ALLOC (n + 1);                      \
514        strncpy (fmt_copy, (start), n);                                 \
515        fmt_copy[n] = '\0';                                             \
516        if (sprntf_gmp ((buf_ptr), (fmt_copy), (ap)) == -1)             \
517          {                                                             \
518            MPFR_TMP_FREE (marker);                                     \
519            goto error;                                                 \
520          }                                                             \
521        (flag) = 0;                                                     \
522        MPFR_TMP_FREE (marker);                                         \
523      }                                                                 \
524    else if ((start) != (end))                                          \
525      /* no conversion specification, just simple characters */         \
526      buffer_cat ((buf_ptr), (start), n);                               \
527  } while (0)
528
529struct string_buffer
530{
531  char *start;                  /* beginning of the buffer */
532  char *curr;                   /* null terminating character */
533  size_t size;                  /* buffer capacity */
534};
535
536static void
537buffer_init (struct string_buffer *b, size_t s)
538{
539  b->start = (char *) (*__gmp_allocate_func) (s);
540  b->start[0] = '\0';
541  b->curr = b->start;
542  b->size = s;
543}
544
545/* Increase buffer size by a number of character being the least multiple of
546   4096 greater than LEN+1. */
547static void
548buffer_widen (struct string_buffer *b, size_t len)
549{
550  const size_t pos = b->curr - b->start;
551  const size_t n = 0x1000 + (len & ~((size_t) 0xfff));
552  MPFR_ASSERTD (pos < b->size);
553
554  MPFR_ASSERTN ((len & ~((size_t) 4095)) <= (size_t)(SIZE_MAX - 4096));
555  MPFR_ASSERTN (b->size < SIZE_MAX - n);
556
557  b->start =
558    (char *) (*__gmp_reallocate_func) (b->start, b->size, b->size + n);
559  b->size += n;
560  b->curr = b->start + pos;
561
562  MPFR_ASSERTD (pos < b->size);
563  MPFR_ASSERTD (*b->curr == '\0');
564}
565
566/* Concatenate the LEN first characters of the string S to the buffer B and
567   expand it if needed. */
568static void
569buffer_cat (struct string_buffer *b, const char *s, size_t len)
570{
571  MPFR_ASSERTD (len != 0);
572  MPFR_ASSERTD (len <= strlen (s));
573
574  if (MPFR_UNLIKELY ((b->curr + len) >= (b->start + b->size)))
575    buffer_widen (b, len);
576
577  strncat (b->curr, s, len);
578  b->curr += len;
579
580  MPFR_ASSERTD (b->curr < b->start + b->size);
581  MPFR_ASSERTD (*b->curr == '\0');
582}
583
584/* Add N characters C to the end of buffer B */
585static void
586buffer_pad (struct string_buffer *b, const char c, const size_t n)
587{
588  MPFR_ASSERTD (n != 0);
589
590  MPFR_ASSERTN (b->size < SIZE_MAX - n - 1);
591  if (MPFR_UNLIKELY ((b->curr + n + 1) > (b->start + b->size)))
592    buffer_widen (b, n);
593
594  if (n == 1)
595    *b->curr = c;
596  else
597    memset (b->curr, c, n);
598  b->curr += n;
599  *b->curr = '\0';
600
601  MPFR_ASSERTD (b->curr < b->start + b->size);
602}
603
604/* Form a string by concatenating the first LEN characters of STR to TZ
605   zero(s), insert into one character C each 3 characters starting from end
606   to begining and concatenate the result to the buffer B. */
607static void
608buffer_sandwich (struct string_buffer *b, char *str, size_t len,
609                 const size_t tz, const char c)
610{
611  const size_t step = 3;
612  const size_t size = len + tz;
613  const size_t r = size % step == 0 ? step : size % step;
614  const size_t q = size % step == 0 ? size / step - 1 : size / step;
615  size_t i;
616
617  MPFR_ASSERTD (size != 0);
618  if (c == '\0')
619    {
620      buffer_cat (b, str, len);
621      buffer_pad (b, '0', tz);
622      return;
623    }
624
625  MPFR_ASSERTN (b->size < SIZE_MAX - size - 1 - q);
626  MPFR_ASSERTD (len <= strlen (str));
627  if (MPFR_UNLIKELY ((b->curr + size + 1 + q) > (b->start + b->size)))
628    buffer_widen (b, size + q);
629
630  /* first R significant digits */
631  memcpy (b->curr, str, r);
632  b->curr += r;
633  str += r;
634  len -= r;
635
636  /* blocks of thousands. Warning: STR might end in the middle of a block */
637  for (i = 0; i < q; ++i)
638    {
639      *b->curr++ = c;
640      if (MPFR_LIKELY (len > 0))
641        {
642          if (MPFR_LIKELY (len >= step))
643            /* step significant digits */
644            {
645              memcpy (b->curr, str, step);
646              len -= step;
647            }
648          else
649            /* last digits in STR, fill up thousand block with zeros */
650            {
651              memcpy (b->curr, str, len);
652              memset (b->curr + len, '0', step - len);
653              len = 0;
654            }
655        }
656      else
657        /* trailing zeros */
658        memset (b->curr, '0', step);
659
660      b->curr += step;
661      str += step;
662    }
663
664  *b->curr = '\0';
665
666  MPFR_ASSERTD (b->curr < b->start + b->size);
667}
668
669/* let gmp_xprintf process the part it can understand */
670static int
671sprntf_gmp (struct string_buffer *b, const char *fmt, va_list ap)
672{
673  int length;
674  char *s;
675
676  length = gmp_vasprintf (&s, fmt, ap);
677  if (length > 0)
678    buffer_cat (b, s, length);
679
680  mpfr_free_str (s);
681  return length;
682}
683
684/* Helper struct and functions for temporary strings management */
685/* struct for easy string clearing */
686struct string_list
687{
688  char *string;
689  struct string_list *next; /* NULL in last node */
690};
691
692/* initialisation */
693static void
694init_string_list (struct string_list *sl)
695{
696  sl->string = NULL;
697  sl->next = NULL;
698}
699
700/* clear all strings in the list */
701static void
702clear_string_list (struct string_list *sl)
703{
704  struct string_list *n;
705
706  while (sl)
707    {
708      if (sl->string)
709        mpfr_free_str (sl->string);
710      n = sl->next;
711      (*__gmp_free_func) (sl, sizeof(struct string_list));
712      sl = n;
713    }
714}
715
716/* add a string in the list */
717static char *
718register_string (struct string_list *sl, char *new_string)
719{
720  /* look for the last node */
721  while (sl->next)
722    sl = sl->next;
723
724  sl->next = (struct string_list*)
725    (*__gmp_allocate_func) (sizeof (struct string_list));
726
727  sl = sl->next;
728  sl->next = NULL;
729  return sl->string = new_string;
730}
731
732/* padding type: where are the padding characters */
733enum pad_t
734  {
735    LEFT,          /* spaces in left hand side for right justification */
736    LEADING_ZEROS, /* padding with '0' characters in integral part */
737    RIGHT          /* spaces in right hand side for left justification */
738  };
739
740/* number_parts details how much characters are needed in each part of a float
741   print.  */
742struct number_parts
743{
744  enum pad_t pad_type;    /* Padding type */
745  size_t pad_size;        /* Number of padding characters */
746
747  char sign;              /* Sign character */
748
749  char *prefix_ptr;       /* Pointer to prefix part */
750  size_t prefix_size;     /* Number of characters in *prefix_ptr */
751
752  char thousands_sep;     /* Thousands separator (only with style 'f') */
753
754  char *ip_ptr;           /* Pointer to integral part characters*/
755  size_t ip_size;         /* Number of digits in *ip_ptr */
756  int ip_trailing_zeros;  /* Number of additional null digits in integral
757                             part */
758
759  char point;             /* Decimal point character */
760
761  int fp_leading_zeros;   /* Number of additional leading zeros in fractional
762                             part */
763  char *fp_ptr;           /* Pointer to fractional part characters */
764  size_t fp_size;         /* Number of digits in *fp_ptr */
765  int fp_trailing_zeros;  /* Number of additional trailing zeros in fractional
766                             part */
767
768  char *exp_ptr;          /* Pointer to exponent part */
769  size_t exp_size;        /* Number of characters in *exp_ptr */
770
771  struct string_list *sl; /* List of string buffers in use: we need such a
772                             mechanism because fp_ptr may point into the same
773                             string as ip_ptr */
774};
775
776/* For a real non zero number x, what is the base exponent f when rounding x
777   with rounding mode r to r(x) = m*b^f, where m is a digit and 1 <= m < b ?
778   Return non zero value if x is rounded up to b^f, return zero otherwise */
779static int
780next_base_power_p (mpfr_srcptr x, int base, mpfr_rnd_t rnd)
781{
782  mpfr_prec_t nbits;
783  mp_limb_t pm;
784  mp_limb_t xm;
785
786  MPFR_ASSERTD (MPFR_IS_PURE_FP (x));
787  MPFR_ASSERTD (base == 2 || base == 16);
788
789  /* Warning: the decimal point is AFTER THE FIRST DIGIT in this output
790     representation. */
791  nbits = base == 2 ? 1 : 4;
792
793  if (rnd == MPFR_RNDZ
794      || (rnd == MPFR_RNDD && MPFR_IS_POS (x))
795      || (rnd == MPFR_RNDU && MPFR_IS_NEG (x))
796      || MPFR_PREC (x) <= nbits)
797    /* no rounding when printing x with 1 digit */
798    return 0;
799
800  xm = MPFR_MANT (x) [MPFR_LIMB_SIZE (x) - 1];
801  pm = MPFR_LIMB_MASK (GMP_NUMB_BITS - nbits);
802  if ((xm & ~pm) ^ ~pm)
803    /* do no round up if some of the nbits first bits are 0s. */
804    return 0;
805
806  if (rnd == MPFR_RNDN)
807    /* mask for rounding bit */
808    pm = (MPFR_LIMB_ONE << (GMP_NUMB_BITS - nbits - 1));
809
810  /* round up if some remaining bits are 1 */
811  /* warning: the return value must be an int */
812  return xm & pm ? 1 : 0;
813}
814
815/* For a real non zero number x, what is the exponent f when rounding x with
816   rounding mode r to r(x) = m*10^f, where m has p+1 digits and 1 <= m < 10 ?
817
818   Return +1 if x is rounded up to 10^f, return zero otherwise.
819   If e is not NULL, *e is set to f. */
820static int
821round_to_10_power (mpfr_exp_t *e, mpfr_srcptr x, mpfr_prec_t p, mpfr_rnd_t r)
822{
823  mpfr_t f, u, v, y;
824  mpfr_prec_t m;
825  mpfr_exp_t ex;
826  mpfr_uexp_t uexp;
827  int roundup = -1; /* boolean (-1: not set) */
828
829  MPFR_ZIV_DECL (loop);
830
831  /* y = abs(x) */
832  MPFR_ALIAS (y, x, 1, MPFR_EXP(x));
833
834  /* we want f = floor(log(|x|)/log(10)) exactly.
835     we have |f| >= |Exp(x)|/3,
836     then m = ceil(log(uexp/3)/log(2)) > log(f)/log(2)
837     is a sufficient precision for f. */
838  ex = mpfr_get_exp (x);
839  uexp = SAFE_ABS (mpfr_uexp_t, ex) / 3;
840  m = 1;
841  while (uexp)
842    {
843      uexp >>= 1;
844      m++;
845    }
846  if (m < 2)
847    m = 2;
848  mpfr_init2 (f, m);
849  mpfr_log10 (f, y, MPFR_RNDD);
850  mpfr_floor (f, f);
851
852  /* In most cases, the output exponent is f. */
853  if (e != NULL)
854    *e = (mpfr_exp_t)mpfr_get_si (f, MPFR_RNDD);
855
856  if (r == MPFR_RNDZ
857      || (MPFR_IS_POS (x) && r == MPFR_RNDD)
858      || (MPFR_IS_NEG (x) && r == MPFR_RNDU))
859    /* If rounding toward zero, the exponent is f */
860    {
861      mpfr_clear (f);
862      return 0;
863    }
864
865  /* Is |x| less than 10^(f+1) - 10^(f-p)? */
866  {
867    int cmp;
868    int inex_u, inex_v, inex_w;
869    mpfr_exp_t exp_u, exp_v, exp_w;
870
871    m = MPFR_PREC (x);
872    m += MPFR_INT_CEIL_LOG2 (m);
873    mpfr_init2 (u, m);
874    mpfr_init2 (v, m);
875
876    MPFR_ZIV_INIT (loop, m);
877    for (;;)
878      {
879        mpfr_set_prec (u, m);
880        mpfr_set_prec (v, m);
881
882        /* u = o(10^(f+1)) rounding toward -infinity
883           error (u) < 1 ulp(u)
884           error(u) = 0 if inex_u = 0 */
885        mpfr_add_ui (u, f, 1, MPFR_RNDN);
886        inex_u = mpfr_ui_pow (u, 10, u, MPFR_RNDD);
887        exp_u = MPFR_EXP (u);
888
889        /* if r = rounding to nearest
890           v = o(0.5 * 10^(f-p)) rounding toward +infinity
891           else
892           v = o(10^(f-p)) rounding toward +infinity
893
894           error(v) < 1 ulp(v)
895           error(v) = 0 if inex_v = 0 */
896        mpfr_sub_ui (v, f, p, MPFR_RNDN);
897        inex_v = mpfr_ui_pow (v, 10, v, MPFR_RNDU);
898        if (r == MPFR_RNDN)
899          mpfr_div_2ui (v, v, 1, MPFR_RNDN);
900        exp_v = MPFR_EXP (v);
901
902        /* w = o(u-v) rounding toward -infinity
903           w is an approximation of 10^(f+1) - v with
904           error(w) < 1 ulp(w) + error(u) + error(v)
905           error(w) = 0 iff inex_u = inex_v = inex_diff = 0 */
906        inex_w = mpfr_sub (u, u, v, MPFR_RNDD);
907        exp_w = MPFR_EXP (u);
908
909        cmp = mpfr_cmp (y, u);
910
911        if (cmp < 0)
912          /* |x| < u <= 10^(f+1) - v, the exponent is f */
913          {
914            roundup = 0;
915            break;
916          }
917        else if (cmp == 0 && inex_u == 0 && inex_v == 0 && inex_w == 0)
918          /* |x| = u = 10^(f+1) - v, the exponent is f+1 */
919          {
920            if (e != NULL)
921              (*e)++;
922
923            roundup = +1;
924            break;
925          }
926
927          /* compare |x| with w + error(w) */
928        if (inex_u)
929          mpfr_set_ui_2exp (v, 1, exp_u - m, MPFR_RNDU);
930        else
931          mpfr_set_ui (v, 0, MPFR_RNDN);
932        if (inex_v)
933          mpfr_set_ui_2exp (v, 1, exp_v - m, MPFR_RNDU);
934        if (inex_w)
935          mpfr_set_ui_2exp (v, 1, exp_w - m, MPFR_RNDU);
936
937        mpfr_add (u, u, v, MPFR_RNDU);
938        if (mpfr_cmp (y, u) >= 0)
939          {
940            if (e != NULL)
941              *e = (mpfr_exp_t)mpfr_get_si (f, MPFR_RNDD) + 1;
942
943            roundup = +1;
944            break;
945          }
946
947        MPFR_ZIV_NEXT (loop, m);
948      }
949    MPFR_ZIV_FREE (loop);
950    mpfr_clear (u);
951    mpfr_clear (v);
952  }
953
954  MPFR_ASSERTD (roundup != -1);
955  mpfr_clear (f);
956  return roundup;
957}
958
959/* Determine the different parts of the string representation of the regular
960   number P when SPEC.SPEC is 'a', 'A', or 'b'.
961
962   return -1 if some field > INT_MAX */
963static int
964regular_ab (struct number_parts *np, mpfr_srcptr p,
965            const struct printf_spec spec)
966{
967  int uppercase;
968  int base;
969  char *str;
970  mpfr_exp_t exp;
971
972  uppercase = spec.spec == 'A';
973
974  /* sign */
975  if (MPFR_IS_NEG (p))
976    np->sign = '-';
977  else if (spec.showsign || spec.space)
978    np->sign = spec.showsign ? '+' : ' ';
979
980  if (spec.spec == 'a' || spec.spec == 'A')
981    /* prefix part */
982    {
983      np->prefix_size = 2;
984      str = (char *) (*__gmp_allocate_func) (1 + np->prefix_size);
985      str[0] = '0';
986      str[1] = uppercase ? 'X' : 'x';
987      str[2] = '\0';
988      np->prefix_ptr = register_string (np->sl, str);
989    }
990
991  /* integral part */
992  np->ip_size = 1;
993  base = (spec.spec == 'b') ? 2 : 16;
994
995  if (spec.prec != 0)
996    {
997      size_t nsd;
998
999      /* Number of significant digits:
1000         - if no given precision, let mpfr_get_str determine it;
1001         - if a non-zero precision is specified, then one digit before decimal
1002         point plus SPEC.PREC after it. */
1003      nsd = spec.prec < 0 ? 0 : spec.prec + np->ip_size;
1004      str = mpfr_get_str (0, &exp, base, nsd, p, spec.rnd_mode);
1005      register_string (np->sl, str);
1006      np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str;  /* skip sign if any */
1007
1008      if (base == 16)
1009        /* EXP is the exponent for radix sixteen with decimal point BEFORE the
1010           first digit, we want the exponent for radix two and the decimal
1011           point AFTER the first digit. */
1012        {
1013          MPFR_ASSERTN (exp > MPFR_EMIN_MIN /4); /* possible overflow */
1014          exp = (exp - 1) * 4;
1015        }
1016      else
1017        /* EXP is the exponent for decimal point BEFORE the first digit, we
1018           want the exponent for decimal point AFTER the first digit. */
1019        {
1020          MPFR_ASSERTN (exp > MPFR_EMIN_MIN); /* possible overflow */
1021          --exp;
1022        }
1023    }
1024  else if (next_base_power_p (p, base, spec.rnd_mode))
1025    {
1026      str = (char *)(*__gmp_allocate_func) (2);
1027      str[0] = '1';
1028      str[1] = '\0';
1029      np->ip_ptr = register_string (np->sl, str);
1030
1031      exp = MPFR_GET_EXP (p);
1032    }
1033  else if (base == 2)
1034    {
1035      str = (char *)(*__gmp_allocate_func) (2);
1036      str[0] = '1';
1037      str[1] = '\0';
1038      np->ip_ptr = register_string (np->sl, str);
1039
1040      exp = MPFR_GET_EXP (p) - 1;
1041    }
1042  else
1043    {
1044      int digit;
1045      mp_limb_t msl = MPFR_MANT (p)[MPFR_LIMB_SIZE (p) - 1];
1046      int rnd_bit = GMP_NUMB_BITS - 5;
1047
1048      /* pick up the 4 first bits */
1049      digit = msl >> (rnd_bit+1);
1050      if (spec.rnd_mode == MPFR_RNDA
1051          || (spec.rnd_mode == MPFR_RNDU && MPFR_IS_POS (p))
1052          || (spec.rnd_mode == MPFR_RNDD && MPFR_IS_NEG (p))
1053          || (spec.rnd_mode == MPFR_RNDN
1054              && (msl & (MPFR_LIMB_ONE << rnd_bit))))
1055        digit++;
1056      MPFR_ASSERTD ((0 <= digit) && (digit <= 15));
1057
1058      str = (char *)(*__gmp_allocate_func) (1 + np->ip_size);
1059      str[0] = num_to_text [digit];
1060      str[1] = '\0';
1061      np->ip_ptr = register_string (np->sl, str);
1062
1063      exp = MPFR_GET_EXP (p) - 4;
1064    }
1065
1066  if (uppercase)
1067    /* All digits in upper case */
1068    {
1069      char *s1 = str;
1070      while (*s1)
1071        {
1072          switch (*s1)
1073            {
1074            case 'a':
1075              *s1 = 'A';
1076              break;
1077            case 'b':
1078              *s1 = 'B';
1079              break;
1080            case 'c':
1081              *s1 = 'C';
1082              break;
1083            case 'd':
1084              *s1 = 'D';
1085              break;
1086            case 'e':
1087              *s1 = 'E';
1088              break;
1089            case 'f':
1090              *s1 = 'F';
1091              break;
1092            }
1093          s1++;
1094        }
1095    }
1096
1097  if (spec.spec == 'b' || spec.prec != 0)
1098    /* compute the number of digits in fractional part */
1099    {
1100      char *ptr;
1101      size_t str_len;
1102
1103      /* the sign has been skipped, skip also the first digit */
1104      ++str;
1105      str_len = strlen (str);
1106      ptr = str + str_len - 1; /* points to the end of str */
1107
1108      if (spec.prec < 0)
1109        /* remove trailing zeros, if any */
1110        {
1111          while ((*ptr == '0') && (str_len != 0))
1112            {
1113              --ptr;
1114              --str_len;
1115            }
1116        }
1117
1118      if (str_len > INT_MAX)
1119        /* too many digits in fractional part */
1120        return -1;
1121
1122      if (str_len != 0)
1123        /* there are some non-zero digits in fractional part */
1124        {
1125          np->fp_ptr = str;
1126          np->fp_size = str_len;
1127          if ((int) str_len < spec.prec)
1128            np->fp_trailing_zeros = spec.prec - str_len;
1129        }
1130    }
1131
1132  /* decimal point */
1133  if ((np->fp_size != 0) || spec.alt)
1134    np->point = MPFR_DECIMAL_POINT;
1135
1136  /* the exponent part contains the character 'p', or 'P' plus the sign
1137     character plus at least one digit and only as many more digits as
1138     necessary to represent the exponent.
1139     We assume that |EXP| < 10^INT_MAX. */
1140  np->exp_size = 3;
1141  {
1142    mpfr_uexp_t x;
1143
1144    x = SAFE_ABS (mpfr_uexp_t, exp);
1145    while (x > 9)
1146      {
1147        np->exp_size++;
1148        x /= 10;
1149      }
1150  }
1151  str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
1152  np->exp_ptr = register_string (np->sl, str);
1153  {
1154    char exp_fmt[8];  /* contains at most 7 characters like in "p%+.1i",
1155                         or "P%+.2li" */
1156
1157    exp_fmt[0] = uppercase ? 'P' : 'p';
1158    exp_fmt[1] = '\0';
1159    strcat (exp_fmt, "%+.1" MPFR_EXP_FORMAT_SPEC);
1160
1161    if (sprintf (str, exp_fmt, exp) < 0)
1162      return -1;
1163  }
1164
1165  return 0;
1166}
1167
1168/* Determine the different parts of the string representation of the regular
1169   number P when SPEC.SPEC is 'e', 'E', 'g', or 'G'.
1170
1171   return -1 if some field > INT_MAX */
1172static int
1173regular_eg (struct number_parts *np, mpfr_srcptr p,
1174            const struct printf_spec spec)
1175{
1176  char *str;
1177  mpfr_exp_t exp;
1178
1179  const int uppercase = spec.spec == 'E' || spec.spec == 'G';
1180  const int spec_g = spec.spec == 'g' || spec.spec == 'G';
1181  const int keep_trailing_zeros = (spec_g && spec.alt)
1182    || (!spec_g && (spec.prec > 0));
1183
1184  /* sign */
1185  if (MPFR_IS_NEG (p))
1186    np->sign = '-';
1187  else if (spec.showsign || spec.space)
1188    np->sign = spec.showsign ? '+' : ' ';
1189
1190  /* integral part */
1191  np->ip_size = 1;
1192  {
1193    size_t nsd;
1194
1195    /* Number of significant digits:
1196       - if no given precision, then let mpfr_get_str determine it,
1197       - if a precision is specified, then one digit before decimal point
1198       plus SPEC.PREC after it.
1199       We use the fact here that mpfr_get_str allows us to ask for only one
1200       significant digit when the base is not a power of 2. */
1201    nsd = (spec.prec < 0) ? 0 : spec.prec + np->ip_size;
1202    str = mpfr_get_str (0, &exp, 10, nsd, p, spec.rnd_mode);
1203  }
1204  register_string (np->sl, str);
1205  np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str;  /* skip sign if any */
1206
1207  if (spec.prec != 0)
1208    /* compute the number of digits in fractional part */
1209    {
1210      char *ptr;
1211      size_t str_len;
1212
1213      /* the sign has been skipped, skip also the first digit */
1214      ++str;
1215      str_len = strlen (str);
1216      ptr = str + str_len - 1; /* points to the end of str */
1217
1218      if (!keep_trailing_zeros)
1219        /* remove trailing zeros, if any */
1220        {
1221          while ((*ptr == '0') && (str_len != 0))
1222            {
1223              --ptr;
1224              --str_len;
1225            }
1226        }
1227
1228      if (str_len > INT_MAX)
1229        /* too many digits in fractional part */
1230        return -1;
1231
1232      if (str_len != 0)
1233        /* there are some non-zero digits in fractional part */
1234        {
1235          np->fp_ptr = str;
1236          np->fp_size = str_len;
1237          if ((!spec_g || spec.alt) && (spec.prec > 0)
1238              && ((int)str_len < spec.prec))
1239            /* add missing trailing zeros */
1240            np->fp_trailing_zeros = spec.prec - str_len;
1241        }
1242    }
1243
1244  /* decimal point */
1245  if (np->fp_size != 0 || spec.alt)
1246    np->point = MPFR_DECIMAL_POINT;
1247
1248  /* EXP is the exponent for decimal point BEFORE the first digit, we want
1249     the exponent for decimal point AFTER the first digit.
1250     Here, no possible overflow because exp < MPFR_EXP (p) / 3 */
1251  exp--;
1252
1253  /* the exponent part contains the character 'e', or 'E' plus the sign
1254     character plus at least two digits and only as many more digits as
1255     necessary to represent the exponent.
1256     We assume that |EXP| < 10^INT_MAX. */
1257  np->exp_size = 3;
1258  {
1259    mpfr_uexp_t x;
1260
1261    x = SAFE_ABS (mpfr_uexp_t, exp);
1262    while (x > 9)
1263      {
1264        np->exp_size++;
1265        x /= 10;
1266      }
1267  }
1268  if (np->exp_size < 4)
1269    np->exp_size = 4;
1270
1271  str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
1272  np->exp_ptr = register_string (np->sl, str);
1273
1274  {
1275    char exp_fmt[8];  /* e.g. "e%+.2i", or "E%+.2li" */
1276
1277    exp_fmt[0] = uppercase ? 'E' : 'e';
1278    exp_fmt[1] = '\0';
1279    strcat (exp_fmt, "%+.2" MPFR_EXP_FORMAT_SPEC);
1280
1281    if (sprintf (str, exp_fmt, exp) < 0)
1282      return -1;
1283  }
1284
1285  return 0;
1286}
1287
1288/* Determine the different parts of the string representation of the regular
1289   number P when SPEC.SPEC is 'f', 'F', 'g', or 'G'.
1290
1291   return -1 if some field of number_parts is greater than INT_MAX */
1292static int
1293regular_fg (struct number_parts *np, mpfr_srcptr p,
1294            const struct printf_spec spec)
1295{
1296  mpfr_exp_t exp;
1297  char * str;
1298  const int spec_g = (spec.spec == 'g' || spec.spec == 'G');
1299  const int keep_trailing_zeros = spec_g && spec.alt;
1300
1301  /* WARNING: an empty precision field is forbidden (it means precision = 6
1302     and it should have been changed to 6 before the function call) */
1303  MPFR_ASSERTD (spec.prec >= 0);
1304
1305  /* sign */
1306  if (MPFR_IS_NEG (p))
1307    np->sign = '-';
1308  else if (spec.showsign || spec.space)
1309    np->sign = spec.showsign ? '+' : ' ';
1310
1311  if (MPFR_GET_EXP (p) <= 0)
1312    /* 0 < |p| < 1 */
1313    {
1314      /* Most of the time, integral part is 0 */
1315      np->ip_size = 1;
1316      str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1317      str[0] = '0';
1318      str[1] = '\0';
1319      np->ip_ptr = register_string (np->sl, str);
1320
1321      if (spec.prec == 0)
1322        /* only two possibilities: either 1 or 0. */
1323        {
1324          mpfr_t y;
1325          /* y = abs(p) */
1326          MPFR_ALIAS (y, p, 1, MPFR_EXP (p));
1327
1328          if (spec.rnd_mode == MPFR_RNDA
1329              || (spec.rnd_mode == MPFR_RNDD && MPFR_IS_NEG (p))
1330              || (spec.rnd_mode == MPFR_RNDU && MPFR_IS_POS (p))
1331              || (spec.rnd_mode == MPFR_RNDN && mpfr_cmp_d (y, 0.5) > 0))
1332            /* rounded up to 1: one digit '1' in integral part.
1333               note that 0.5 is rounded to 0 with RNDN (round ties to even) */
1334            np->ip_ptr[0] = '1';
1335        }
1336      else
1337        {
1338          /* exp =  position of the most significant decimal digit. */
1339          round_to_10_power (&exp, p, 0, MPFR_RNDZ);
1340          MPFR_ASSERTD (exp < 0);
1341
1342          if (exp < -spec.prec)
1343            /* only the last digit may be non zero */
1344            {
1345              int round_away;
1346              switch (spec.rnd_mode)
1347                {
1348                case MPFR_RNDA:
1349                  round_away = 1;
1350                  break;
1351                case MPFR_RNDD:
1352                  round_away = MPFR_IS_NEG (p);
1353                  break;
1354                case MPFR_RNDU:
1355                  round_away = MPFR_IS_POS (p);
1356                  break;
1357                case MPFR_RNDN:
1358                  {
1359                    /* compare |p| to y = 0.5*10^(-spec.prec) */
1360                    mpfr_t y;
1361                    mpfr_exp_t e = MAX (MPFR_PREC (p), 56);
1362                    mpfr_init2 (y, e + 8);
1363                    do
1364                      {
1365                        /* find a lower approximation of
1366                           0.5*10^(-spec.prec) different from |p| */
1367                        e += 8;
1368                        mpfr_set_prec (y, e);
1369                        mpfr_set_si (y, -spec.prec, MPFR_RNDN);
1370                        mpfr_exp10 (y, y, MPFR_RNDD);
1371                        mpfr_div_2ui (y, y, 1, MPFR_RNDN);
1372                      } while (mpfr_cmpabs (y, p) == 0);
1373
1374                    round_away = mpfr_cmpabs (y, p) < 0;
1375                    mpfr_clear (y);
1376                  }
1377                  break;
1378                default:
1379                  round_away = 0;
1380                }
1381
1382              if (round_away)
1383                /* round away from zero: the last output digit is '1' */
1384                {
1385                  np->fp_leading_zeros = spec.prec - 1;
1386
1387                  np->fp_size = 1;
1388                  str =
1389                    (char *) (*__gmp_allocate_func) (1 + np->fp_size);
1390                  str[0] = '1';
1391                  str[1] = '\0';
1392                  np->fp_ptr = register_string (np->sl, str);
1393                }
1394              else
1395                /* only zeros in fractional part */
1396                {
1397                  MPFR_ASSERTD (!spec_g);
1398                  np->fp_leading_zeros = spec.prec;
1399                }
1400            }
1401          else
1402            /* the most significant digits are the last
1403               spec.prec + exp + 1 digits in fractional part */
1404            {
1405              char *ptr;
1406              size_t str_len;
1407              size_t nsd = spec.prec + exp + 1;
1408              /* WARNING: nsd may equal 1, but here we use the fact that
1409                 mpfr_get_str can return one digit with base ten
1410                 (undocumented feature, see comments in get_str.c) */
1411
1412              str = mpfr_get_str (NULL, &exp, 10, nsd, p, spec.rnd_mode);
1413              register_string (np->sl, str);
1414              if (MPFR_IS_NEG (p))
1415                ++str;
1416              if (exp == 1)
1417                /* round up to 1 */
1418                {
1419                  MPFR_ASSERTD (str[0] == '1');
1420                  np->ip_ptr[0] = '1';
1421                  if (!spec_g || spec.alt)
1422                    np->fp_leading_zeros = spec.prec;
1423                }
1424              else
1425                {
1426                  /* skip sign */
1427                  np->fp_ptr = str;
1428                  np->fp_leading_zeros = -exp;
1429                  MPFR_ASSERTD (exp <= 0);
1430
1431                  str_len = strlen (str); /* the sign has been skipped */
1432                  ptr = str + str_len - 1; /* points to the end of str */
1433
1434                  if (!keep_trailing_zeros)
1435                    /* remove trailing zeros, if any */
1436                    {
1437                      while ((*ptr == '0') && str_len)
1438                        {
1439                          --ptr;
1440                          --str_len;
1441                        }
1442                    }
1443
1444                  if (str_len > INT_MAX)
1445                    /* too many digits in fractional part */
1446                    return -1;
1447
1448                  MPFR_ASSERTD (str_len > 0);
1449                  np->fp_size = str_len;
1450
1451                  if ((!spec_g || spec.alt)
1452                      && spec.prec > 0
1453                      && (np->fp_leading_zeros + np->fp_size < spec.prec))
1454                    /* add missing trailing zeros */
1455                    np->fp_trailing_zeros = spec.prec - np->fp_leading_zeros
1456                      - np->fp_size;
1457                }
1458            }
1459        }
1460
1461      if (spec.alt || np->fp_leading_zeros != 0 || np->fp_size != 0
1462          || np->fp_trailing_zeros != 0)
1463        np->point = MPFR_DECIMAL_POINT;
1464    }
1465  else
1466    /* 1 <= |p| */
1467    {
1468      size_t nsd;  /* Number of significant digits */
1469
1470      /* Determine the position of the most significant decimal digit. */
1471      round_to_10_power (&exp, p, 0, MPFR_RNDZ);
1472
1473      MPFR_ASSERTD (exp >= 0);
1474      if (exp > INT_MAX)
1475        /* P is too large to print all its integral part digits */
1476        return -1;
1477
1478      np->ip_size = exp + 1;
1479
1480      nsd = spec.prec + np->ip_size;
1481      str = mpfr_get_str (NULL, &exp, 10, nsd, p, spec.rnd_mode);
1482      register_string (np->sl, str);
1483      np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign */
1484
1485      if (spec.group)
1486        /* thousands separator in integral part */
1487        np->thousands_sep = MPFR_THOUSANDS_SEPARATOR;
1488
1489      if (nsd == 0 || (spec_g && !spec.alt))
1490        /* compute how much non-zero digits in integral and fractional
1491           parts */
1492        {
1493          size_t str_len;
1494          str_len = strlen (str); /* note: the sign has been skipped */
1495
1496          if (exp > str_len)
1497            /* mpfr_get_str doesn't give the trailing zeros when p is a
1498               multiple of 10 (p integer, so no fractional part) */
1499            {
1500              np->ip_trailing_zeros = exp - str_len;
1501              np->ip_size = str_len;
1502              if (spec.alt)
1503                np->point = MPFR_DECIMAL_POINT;
1504            }
1505          else
1506            /* str may contain some digits which are in fractional part */
1507            {
1508              char *ptr;
1509
1510              ptr = str + str_len - 1; /* points to the end of str */
1511              str_len -= np->ip_size;  /* number of digits in fractional
1512                                          part */
1513
1514              if (!keep_trailing_zeros)
1515                /* remove trailing zeros, if any */
1516                {
1517                  while ((*ptr == '0') && (str_len != 0))
1518                    {
1519                      --ptr;
1520                      --str_len;
1521                    }
1522                }
1523
1524              if (str_len > INT_MAX)
1525                /* too many digits in fractional part */
1526                return -1;
1527
1528              if (str_len != 0)
1529                /* some digits in fractional part */
1530                {
1531                  np->point = MPFR_DECIMAL_POINT;
1532                  np->fp_ptr = str + np->ip_size;
1533                  np->fp_size = str_len;
1534                }
1535            }
1536        }
1537      else
1538        /* spec.prec digits in fractional part */
1539        {
1540          if (np->ip_size == exp - 1)
1541            /* the absolute value of the number has been rounded up to a power
1542               of ten.
1543               Insert an additional zero in integral part and put the rest of
1544               them in fractional part. */
1545            np->ip_trailing_zeros = 1;
1546
1547          if (spec.prec != 0)
1548            {
1549              MPFR_ASSERTD (np->ip_size + np->ip_trailing_zeros == exp);
1550              MPFR_ASSERTD (np->ip_size + spec.prec == nsd);
1551
1552              np->point = MPFR_DECIMAL_POINT;
1553              np->fp_ptr = str + np->ip_size;
1554              np->fp_size = spec.prec;
1555            }
1556          else if (spec.alt)
1557            np->point = MPFR_DECIMAL_POINT;
1558        }
1559    }
1560
1561  return 0;
1562}
1563
1564/* partition_number determines the different parts of the string
1565   representation of the number p according to the given specification.
1566   partition_number initializes the given structure np, so all previous
1567   information in that variable is lost.
1568   return the total number of characters to be written.
1569   return -1 if an error occured, in that case np's fields are in an undefined
1570   state but all string buffers have been freed. */
1571static int
1572partition_number (struct number_parts *np, mpfr_srcptr p,
1573                  struct printf_spec spec)
1574{
1575  char *str;
1576  long total;
1577  int uppercase;
1578
1579  /* WARNING: left justification means right space padding */
1580  np->pad_type = spec.left ? RIGHT : spec.pad == '0' ? LEADING_ZEROS : LEFT;
1581  np->pad_size = 0;
1582  np->sign = '\0';
1583  np->prefix_ptr =NULL;
1584  np->prefix_size = 0;
1585  np->thousands_sep = '\0';
1586  np->ip_ptr = NULL;
1587  np->ip_size = 0;
1588  np->ip_trailing_zeros = 0;
1589  np->point = '\0';
1590  np->fp_leading_zeros = 0;
1591  np->fp_ptr = NULL;
1592  np->fp_size = 0;
1593  np->fp_trailing_zeros = 0;
1594  np->exp_ptr = NULL;
1595  np->exp_size = 0;
1596  np->sl = (struct string_list *)
1597    (*__gmp_allocate_func) (sizeof (struct string_list));
1598  init_string_list (np->sl);
1599
1600  uppercase = spec.spec == 'A' || spec.spec == 'E' || spec.spec == 'F'
1601    || spec.spec == 'G';
1602
1603  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (p)))
1604    {
1605      if (MPFR_IS_NAN (p))
1606        {
1607          if (np->pad_type == LEADING_ZEROS)
1608            /* don't want "0000nan", change to right justification padding
1609               with left spaces instead */
1610            np->pad_type = LEFT;
1611
1612          if (uppercase)
1613            {
1614              np->ip_size = MPFR_NAN_STRING_LENGTH;
1615              str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1616              strcpy (str, MPFR_NAN_STRING_UC);
1617              np->ip_ptr = register_string (np->sl, str);
1618            }
1619          else
1620            {
1621              np->ip_size = MPFR_NAN_STRING_LENGTH;
1622              str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1623              strcpy (str, MPFR_NAN_STRING_LC);
1624              np->ip_ptr = register_string (np->sl, str);
1625            }
1626        }
1627      else if (MPFR_IS_INF (p))
1628        {
1629          if (np->pad_type == LEADING_ZEROS)
1630            /* don't want "0000inf", change to right justification padding
1631               with left spaces instead */
1632            np->pad_type = LEFT;
1633
1634          if (MPFR_IS_NEG (p))
1635            np->sign = '-';
1636
1637          if (uppercase)
1638            {
1639              np->ip_size = MPFR_INF_STRING_LENGTH;
1640              str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1641              strcpy (str, MPFR_INF_STRING_UC);
1642              np->ip_ptr = register_string (np->sl, str);
1643            }
1644          else
1645            {
1646              np->ip_size = MPFR_INF_STRING_LENGTH;
1647              str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1648              strcpy (str, MPFR_INF_STRING_LC);
1649              np->ip_ptr = register_string (np->sl, str);
1650            }
1651        }
1652      else
1653        /* p == 0 */
1654        {
1655          /* note: for 'g' spec, zero is always displayed with 'f'-style with
1656             precision spec.prec - 1 and the trailing zeros are removed unless
1657             the flag '#' is used. */
1658          if (MPFR_IS_NEG (p))
1659            /* signed zero */
1660            np->sign = '-';
1661          else if (spec.showsign || spec.space)
1662            np->sign = spec.showsign ? '+' : ' ';
1663
1664          if (spec.spec == 'a' || spec.spec == 'A')
1665            /* prefix part */
1666            {
1667              np->prefix_size = 2;
1668              str = (char *) (*__gmp_allocate_func) (1 + np->prefix_size);
1669              str[0] = '0';
1670              str[1] = uppercase ? 'X' : 'x';
1671              str[2] = '\0';
1672              np->prefix_ptr = register_string (np->sl, str);
1673            }
1674
1675          /* integral part */
1676          np->ip_size = 1;
1677          str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1678          str[0] = '0';
1679          str[1] = '\0';
1680          np->ip_ptr = register_string (np->sl, str);
1681
1682          if (spec.prec > 0
1683              && ((spec.spec != 'g' && spec.spec != 'G') || spec.alt))
1684            /* fractional part */
1685            {
1686              np->point = MPFR_DECIMAL_POINT;
1687              np->fp_trailing_zeros = (spec.spec == 'g' && spec.spec == 'G') ?
1688                spec.prec - 1 : spec.prec;
1689            }
1690          else if (spec.alt)
1691            np->point = MPFR_DECIMAL_POINT;
1692
1693          if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b'
1694              || spec.spec == 'e' || spec.spec == 'E')
1695            /* exponent part */
1696            {
1697              np->exp_size = (spec.spec == 'e' || spec.spec == 'E') ? 4 : 3;
1698              str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
1699              if (spec.spec == 'e' || spec.spec == 'E')
1700                strcpy (str, uppercase ? "E+00" : "e+00");
1701              else
1702                strcpy (str, uppercase ? "P+0" : "p+0");
1703              np->exp_ptr = register_string (np->sl, str);
1704            }
1705        }
1706    }
1707  else
1708    /* regular p, p != 0 */
1709    {
1710      if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b')
1711        {
1712          if (regular_ab (np, p, spec) == -1)
1713            goto error;
1714        }
1715      else if (spec.spec == 'f' || spec.spec == 'F')
1716        {
1717          if (spec.prec == -1)
1718            spec.prec = 6;
1719          if (regular_fg (np, p, spec) == -1)
1720            goto error;
1721        }
1722      else if (spec.spec == 'e' || spec.spec == 'E')
1723        {
1724          if (regular_eg (np, p, spec) == -1)
1725            goto error;
1726        }
1727      else
1728        /* %g case */
1729        {
1730          /* Use the C99 rules:
1731             if T > X >= -4 then the conversion is with style 'f'/'F' and
1732             precision T-(X+1).
1733             otherwise, the conversion is with style 'e'/'E' and
1734             precision T-1.
1735             where T is the threshold computed below and X is the exponent
1736             that would be displayed with style 'e' and precision T-1. */
1737          int threshold;
1738          mpfr_exp_t x;
1739
1740          threshold = (spec.prec < 0) ? 6 : (spec.prec == 0) ? 1 : spec.prec;
1741          round_to_10_power (&x, p, threshold - 1, spec.rnd_mode);
1742
1743          if (threshold > x && x >= -4)
1744            {
1745              /* the conversion is with style 'f' */
1746              spec.prec = threshold - x - 1;
1747
1748              if (regular_fg (np, p, spec) == -1)
1749                goto error;
1750            }
1751          else
1752            {
1753              spec.prec = threshold - 1;
1754
1755              if (regular_eg (np, p, spec) == -1)
1756                goto error;
1757            }
1758        }
1759    }
1760
1761  /* compute the number of characters to be written verifying it is not too
1762     much */
1763  total = np->sign ? 1 : 0;
1764  total += np->prefix_size;
1765  total += np->ip_size;
1766  if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1767    goto error;
1768  total += np->ip_trailing_zeros;
1769  if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1770    goto error;
1771  if (np->thousands_sep)
1772    /* ' flag, style f and the thousands separator in current locale is not
1773       reduced to the null character */
1774    total += (np->ip_size + np->ip_trailing_zeros) / 3;
1775  if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1776    goto error;
1777  if (np->point)
1778    ++total;
1779  total += np->fp_leading_zeros;
1780  if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1781    goto error;
1782  total += np->fp_size;
1783  if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1784    goto error;
1785  total += np->fp_trailing_zeros;
1786  if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1787    goto error;
1788  total += np->exp_size;
1789  if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1790    goto error;
1791
1792  if (spec.width > total)
1793    /* pad with spaces or zeros depending on np->pad_type */
1794    {
1795      np->pad_size = spec.width - total;
1796      total += np->pad_size; /* here total == spec.width,
1797                                so 0 < total < INT_MAX */
1798    }
1799
1800  return total;
1801
1802 error:
1803  clear_string_list (np->sl);
1804  np->prefix_ptr = NULL;
1805  np->ip_ptr = NULL;
1806  np->fp_ptr = NULL;
1807  np->exp_ptr = NULL;
1808  return -1;
1809}
1810
1811/* sprnt_fp prints a mpfr_t according to spec.spec specification.
1812
1813   return the size of the string (not counting the terminating '\0')
1814   return -1 if the built string is too long (i.e. has more than
1815   INT_MAX characters). */
1816static int
1817sprnt_fp (struct string_buffer *buf, mpfr_srcptr p,
1818          const struct printf_spec spec)
1819{
1820  int length;
1821  struct number_parts np;
1822
1823  length = partition_number (&np, p, spec);
1824  if (length < 0)
1825    return -1;
1826
1827  /* right justification padding with left spaces */
1828  if (np.pad_type == LEFT && np.pad_size != 0)
1829    buffer_pad (buf, ' ', np.pad_size);
1830
1831  /* sign character (may be '-', '+', or ' ') */
1832  if (np.sign)
1833    buffer_pad (buf, np.sign, 1);
1834
1835  /* prefix part */
1836  if (np.prefix_ptr)
1837    buffer_cat (buf, np.prefix_ptr, np.prefix_size);
1838
1839  /* right justification  padding with leading zeros */
1840  if (np.pad_type == LEADING_ZEROS && np.pad_size != 0)
1841    buffer_pad (buf, '0', np.pad_size);
1842
1843  /* integral part (may also be "nan" or "inf") */
1844  MPFR_ASSERTN (np.ip_ptr != NULL); /* never empty */
1845  if (MPFR_UNLIKELY (np.thousands_sep))
1846    buffer_sandwich (buf, np.ip_ptr, np.ip_size, np.ip_trailing_zeros,
1847                     np.thousands_sep);
1848  else
1849    {
1850      buffer_cat (buf, np.ip_ptr, np.ip_size);
1851
1852      /* trailing zeros in integral part */
1853      if (np.ip_trailing_zeros != 0)
1854        buffer_pad (buf, '0', np.ip_trailing_zeros);
1855    }
1856
1857  /* decimal point */
1858  if (np.point)
1859    buffer_pad (buf, np.point, 1);
1860
1861  /* leading zeros in fractional part */
1862  if (np.fp_leading_zeros != 0)
1863    buffer_pad (buf, '0', np.fp_leading_zeros);
1864
1865  /* significant digits in fractional part */
1866  if (np.fp_ptr)
1867    buffer_cat (buf, np.fp_ptr, np.fp_size);
1868
1869  /* trailing zeros in fractional part */
1870  if (np.fp_trailing_zeros != 0)
1871    buffer_pad (buf, '0', np.fp_trailing_zeros);
1872
1873  /* exponent part */
1874  if (np.exp_ptr)
1875    buffer_cat (buf, np.exp_ptr, np.exp_size);
1876
1877  /* left justication padding with right spaces */
1878  if (np.pad_type == RIGHT && np.pad_size != 0)
1879    buffer_pad (buf, ' ', np.pad_size);
1880
1881  clear_string_list (np.sl);
1882  return length;
1883}
1884
1885int
1886mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
1887{
1888  struct string_buffer buf;
1889  size_t nbchar;
1890
1891  /* informations on the conversion specification filled by the parser */
1892  struct printf_spec spec;
1893  /* flag raised when previous part of fmt need to be processed by
1894     gmp_vsnprintf */
1895  int xgmp_fmt_flag;
1896  /* beginning and end of the previous unprocessed part of fmt */
1897  const char *start, *end;
1898  /* pointer to arguments for gmp_vasprintf */
1899  va_list ap2;
1900
1901  MPFR_SAVE_EXPO_DECL (expo);
1902  MPFR_SAVE_EXPO_MARK (expo);
1903
1904  nbchar = 0;
1905  buffer_init (&buf, 4096);
1906  xgmp_fmt_flag = 0;
1907  va_copy (ap2, ap);
1908  start = fmt;
1909  while (*fmt)
1910    {
1911      /* Look for the next format specification */
1912      while ((*fmt) && (*fmt != '%'))
1913        ++fmt;
1914
1915      if (*fmt == '\0')
1916        break;
1917
1918      if (*++fmt == '%')
1919        /* %%: go one step further otherwise the second '%' would be
1920           considered as a new conversion specification introducing
1921           character */
1922        {
1923          ++fmt;
1924          xgmp_fmt_flag = 1;
1925          continue;
1926        }
1927
1928      end = fmt - 1;
1929
1930      /* format string analysis */
1931      specinfo_init (&spec);
1932      fmt = parse_flags (fmt, &spec);
1933
1934      READ_INT (ap, fmt, spec, width, width_analysis);
1935    width_analysis:
1936      if (spec.width < 0)
1937        {
1938          spec.left = 1;
1939          spec.width = -spec.width;
1940          MPFR_ASSERTN (spec.width < INT_MAX);
1941        }
1942      if (*fmt == '.')
1943        {
1944          const char *f = ++fmt;
1945          READ_INT (ap, fmt, spec, prec, prec_analysis);
1946        prec_analysis:
1947          if (f == fmt)
1948            spec.prec = -1;
1949        }
1950      else
1951        spec.prec = -1;
1952
1953      fmt = parse_arg_type (fmt, &spec);
1954      if (spec.arg_type == UNSUPPORTED)
1955        /* the current architecture doesn't support this type */
1956        {
1957          goto error;
1958        }
1959      else if (spec.arg_type == MPFR_ARG)
1960        {
1961          switch (*fmt)
1962            {
1963            case '\0':
1964              break;
1965            case '*':
1966              ++fmt;
1967              spec.rnd_mode = (mpfr_rnd_t) va_arg (ap, int);
1968              break;
1969            case 'D':
1970              ++fmt;
1971              spec.rnd_mode = MPFR_RNDD;
1972              break;
1973            case 'U':
1974              ++fmt;
1975              spec.rnd_mode = MPFR_RNDU;
1976              break;
1977            case 'Y':
1978              ++fmt;
1979              spec.rnd_mode = MPFR_RNDA;
1980              break;
1981            case 'Z':
1982              ++fmt;
1983              spec.rnd_mode = MPFR_RNDZ;
1984              break;
1985            case 'N':
1986              ++fmt;
1987            default:
1988              spec.rnd_mode = MPFR_RNDN;
1989            }
1990        }
1991
1992      spec.spec = *fmt;
1993      if (!specinfo_is_valid (spec))
1994        goto error;
1995
1996      if (*fmt)
1997        fmt++;
1998
1999      /* Format processing */
2000      if (spec.spec == '\0')
2001        /* end of the format string */
2002        break;
2003      else if (spec.spec == 'n')
2004        /* put the number of characters written so far in the location pointed
2005           by the next va_list argument; the types of pointer accepted are the
2006           same as in GMP (except unsupported quad_t) plus pointer to a mpfr_t
2007           so as to be able to accept the same format strings. */
2008        {
2009          void *p;
2010          size_t nchar;
2011
2012          p = va_arg (ap, void *);
2013          FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2014          va_end (ap2);
2015          start = fmt;
2016          nchar = buf.curr - buf.start;
2017
2018          switch (spec.arg_type)
2019            {
2020            case CHAR_ARG:
2021              *(char *) p = (char) nchar;
2022              break;
2023            case SHORT_ARG:
2024              *(short *) p = (short) nchar;
2025              break;
2026            case LONG_ARG:
2027              *(long *) p = (long) nchar;
2028              break;
2029#ifdef HAVE_LONG_LONG
2030            case LONG_LONG_ARG:
2031              *(long long *) p = (long long) nchar;
2032              break;
2033#endif
2034#ifdef _MPFR_H_HAVE_INTMAX_T
2035            case INTMAX_ARG:
2036              *(intmax_t *) p = (intmax_t) nchar;
2037              break;
2038#endif
2039            case SIZE_ARG:
2040              *(size_t *) p = nchar;
2041              break;
2042            case PTRDIFF_ARG:
2043              *(ptrdiff_t *) p = (ptrdiff_t) nchar;
2044              break;
2045            case MPF_ARG:
2046              mpf_set_ui ((mpf_ptr) p, (unsigned long) nchar);
2047              break;
2048            case MPQ_ARG:
2049              mpq_set_ui ((mpq_ptr) p, (unsigned long) nchar, 1L);
2050              break;
2051            case MP_LIMB_ARG:
2052              *(mp_limb_t *) p = (mp_limb_t) nchar;
2053              break;
2054            case MP_LIMB_ARRAY_ARG:
2055              {
2056                mp_limb_t *q = (mp_limb_t *) p;
2057                mp_size_t n;
2058                n = va_arg (ap, mp_size_t);
2059                if (n < 0)
2060                  n = -n;
2061                else if (n == 0)
2062                  break;
2063
2064                /* we assume here that mp_limb_t is wider than int */
2065                *q = (mp_limb_t) nchar;
2066                while (--n != 0)
2067                  {
2068                    q++;
2069                    *q = (mp_limb_t) 0;
2070                  }
2071              }
2072              break;
2073            case MPZ_ARG:
2074              mpz_set_ui ((mpz_ptr) p, (unsigned long) nchar);
2075              break;
2076
2077            case MPFR_ARG:
2078              mpfr_set_ui ((mpfr_ptr) p, (unsigned long) nchar,
2079                           spec.rnd_mode);
2080              break;
2081
2082            default:
2083              *(int *) p = (int) nchar;
2084            }
2085          va_copy (ap2, ap); /* after the switch, due to MP_LIMB_ARRAY_ARG
2086                                case */
2087        }
2088      else if (spec.arg_type == MPFR_PREC_ARG)
2089        /* output mpfr_prec_t variable */
2090        {
2091          char *s;
2092          char format[MPFR_PREC_FORMAT_SIZE + 6]; /* see examples below */
2093          size_t length;
2094          mpfr_prec_t prec;
2095          prec = va_arg (ap, mpfr_prec_t);
2096
2097          FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2098          va_end (ap2);
2099          va_copy (ap2, ap);
2100          start = fmt;
2101
2102          /* construct format string, like "%*.*hu" "%*.*u" or "%*.*lu" */
2103          format[0] = '%';
2104          format[1] = '*';
2105          format[2] = '.';
2106          format[3] = '*';
2107          format[4] = '\0';
2108          strcat (format, MPFR_PREC_FORMAT_TYPE);
2109          format[4 + MPFR_PREC_FORMAT_SIZE] = spec.spec;
2110          format[5 + MPFR_PREC_FORMAT_SIZE] = '\0';
2111          length = gmp_asprintf (&s, format, spec.width, spec.prec, prec);
2112          if (buf.size <= INT_MAX - length)
2113            {
2114              buffer_cat (&buf, s, length);
2115              mpfr_free_str (s);
2116            }
2117          else
2118            {
2119              mpfr_free_str (s);
2120              goto overflow_error;
2121            }
2122        }
2123      else if (spec.arg_type == MPFR_ARG)
2124        /* output a mpfr_t variable */
2125        {
2126          mpfr_srcptr p;
2127
2128          p = va_arg (ap, mpfr_srcptr);
2129
2130          FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2131          va_end (ap2);
2132          va_copy (ap2, ap);
2133          start = fmt;
2134
2135          switch (spec.spec)
2136            {
2137            case 'a':
2138            case 'A':
2139            case 'b':
2140            case 'e':
2141            case 'E':
2142            case 'f':
2143            case 'F':
2144            case 'g':
2145            case 'G':
2146              if (sprnt_fp (&buf, p, spec) < 0)
2147                goto overflow_error;
2148              break;
2149
2150            default:
2151              /* unsupported specifier */
2152              goto error;
2153            }
2154        }
2155      else
2156        /* gmp_printf specification, step forward in the va_list */
2157        {
2158          CONSUME_VA_ARG (spec, ap);
2159          xgmp_fmt_flag = 1;
2160        }
2161    }
2162
2163  if (start != fmt)
2164    FLUSH (xgmp_fmt_flag, start, fmt, ap2, &buf);
2165
2166  va_end (ap2);
2167  nbchar = buf.curr - buf.start;
2168  MPFR_ASSERTD (nbchar == strlen (buf.start));
2169  buf.start =
2170    (char *) (*__gmp_reallocate_func) (buf.start, buf.size, nbchar + 1);
2171  buf.size = nbchar + 1; /* update needed for __gmp_free_func below when
2172                            nbchar is too large (overflow_error) */
2173  *ptr = buf.start;
2174
2175  /* If nbchar is larger than INT_MAX, the ISO C99 standard is silent, but
2176     POSIX says concerning the snprintf() function:
2177     "[EOVERFLOW] The value of n is greater than {INT_MAX} or the
2178     number of bytes needed to hold the output excluding the
2179     terminating null is greater than {INT_MAX}." See:
2180     http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
2181     But it doesn't say anything concerning the other printf-like functions.
2182     A defect report has been submitted to austin-review-l (item 2532).
2183     So, for the time being, we return a negative value and set the erange
2184     flag, and set errno to EOVERFLOW in POSIX system. */
2185  if (nbchar <= INT_MAX)
2186    {
2187      MPFR_SAVE_EXPO_FREE (expo);
2188      return nbchar;
2189    }
2190
2191 overflow_error:
2192  MPFR_SAVE_EXPO_UPDATE_FLAGS(expo, MPFR_FLAGS_ERANGE);
2193#ifdef EOVERFLOW
2194  errno = EOVERFLOW;
2195#endif
2196
2197 error:
2198  MPFR_SAVE_EXPO_FREE (expo);
2199  *ptr = NULL;
2200  (*__gmp_free_func) (buf.start, buf.size);
2201
2202  return -1;
2203}
2204
2205#endif /* HAVE_STDARG */
2206