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