(root)/
mpfr-4.2.1/
src/
vasprintf.c
       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 */