1 /* mpfr_vasprintf -- main function for the printf functions family
2 plus helper macros & functions.
4 Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
5 Contributed by the AriC and Caramel projects, INRIA.
7 This file is part of the GNU MPFR Library.
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.
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.
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 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
22 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
28 /* The mpfr_printf-like functions are defined only if <stdarg.h> exists */
34 # ifdef HAVE___VA_COPY
35 # define va_copy(dst,src) __va_copy(dst, src)
37 /* autoconf manual advocates this fallback.
38 This is also the solution chosen by gmp */
39 # define va_copy(dst,src) \
40 do { memcpy(&(dst), &(src), sizeof(va_list)); } while (0)
41 # endif /* HAVE___VA_COPY */
42 #endif /* HAVE_VA_COPY */
48 #if defined (__cplusplus)
50 #define __STDC_LIMIT_MACROS /* SIZE_MAX defined with <stdint.h> inclusion */
52 #include <stddef.h> /* for ptrdiff_t */
55 #define MPFR_NEED_LONGLONG_H
56 #include "mpfr-intmax.h"
57 #include "mpfr-impl.h"
59 /* Define a length modifier corresponding to mpfr_prec_t.
60 We use literal string instead of literal character so as to permit future
61 extension to long long int ("ll"). */
62 #if _MPFR_PREC_FORMAT == 1
63 #define MPFR_PREC_FORMAT_TYPE "h"
64 #define MPFR_PREC_FORMAT_SIZE 1
65 #elif _MPFR_PREC_FORMAT == 2
66 #define MPFR_PREC_FORMAT_TYPE ""
67 #define MPFR_PREC_FORMAT_SIZE 0
68 #elif _MPFR_PREC_FORMAT == 3
69 #define MPFR_PREC_FORMAT_TYPE "l"
70 #define MPFR_PREC_FORMAT_SIZE 1
72 #error "mpfr_prec_t size not supported"
75 /* Output for special values defined in the C99 standard */
76 #define MPFR_NAN_STRING_LC "nan"
77 #define MPFR_NAN_STRING_UC "NAN"
78 #define MPFR_NAN_STRING_LENGTH 3
79 #define MPFR_INF_STRING_LC "inf"
80 #define MPFR_INF_STRING_UC "INF"
81 #define MPFR_INF_STRING_LENGTH 3
83 /* The implicit \0 is useless, but we do not write num_to_text[16]
84 otherwise g++ complains. */
85 static const char num_to_text[] = "0123456789abcdef";
87 /* some macro and functions for parsing format string */
89 /* Read an integer; saturate to INT_MAX. */
90 #define READ_INT(ap, format, specinfo, field, label_out) \
107 specinfo.field = (specinfo.field <= INT_MAX / 10) ? \
108 specinfo.field * 10 : INT_MAX; \
109 _i = *(format) - '0'; \
110 MPFR_ASSERTN (_i >= 0 && _i <= 9); \
111 specinfo.field = (specinfo.field <= INT_MAX - _i) ? \
112 specinfo.field + _i : INT_MAX; \
116 specinfo.field = va_arg ((ap), int); \
124 /* arg_t contains all the types described by the 'type' field of the
147 /* Each conversion specification of the format string will be translated in a
148 printf_spec structure by the parser.
149 This structure is adapted from the GNU libc one. */
152 unsigned int alt:1; /* # flag */
153 unsigned int space:1; /* Space flag */
154 unsigned int left:1; /* - flag */
155 unsigned int showsign:1; /* + flag */
156 unsigned int group:1; /* ' flag */
158 int width; /* Width */
159 int prec; /* Precision */
161 enum arg_t arg_type; /* Type of argument */
162 mpfr_rnd_t rnd_mode; /* Rounding mode */
163 char spec; /* Conversion specifier */
165 char pad; /* Padding character */
169 specinfo_init (struct printf_spec *specinfo)
174 specinfo->showsign = 0;
178 specinfo->arg_type = NONE;
179 specinfo->rnd_mode = MPFR_RNDN;
180 specinfo->spec = '\0';
184 #define FLOATING_POINT_ARG_TYPE(at) \
185 ((at) == MPFR_ARG || (at) == MPF_ARG || (at) == LONG_DOUBLE_ARG)
187 #define INTEGER_LIKE_ARG_TYPE(at) \
188 ((at) == SHORT_ARG || (at) == LONG_ARG || (at) == LONG_LONG_ARG \
189 || (at) == INTMAX_ARG || (at) == MPFR_PREC_ARG || (at) == MPZ_ARG \
190 || (at) == MPQ_ARG || (at) == MP_LIMB_ARG || (at) == MP_LIMB_ARRAY_ARG \
191 || (at) == CHAR_ARG || (at) == SIZE_ARG || (at) == PTRDIFF_ARG)
194 specinfo_is_valid (struct printf_spec spec)
205 return (spec.arg_type == NONE
206 || FLOATING_POINT_ARG_TYPE (spec.arg_type));
209 return spec.arg_type == MPFR_ARG;
214 return (spec.arg_type == NONE
215 || INTEGER_LIKE_ARG_TYPE (spec.arg_type));
219 return (spec.arg_type == NONE || spec.arg_type == LONG_ARG);
222 return spec.arg_type == NONE;
230 parse_flags (const char *format, struct printf_spec *specinfo)
245 specinfo->showsign = 1;
257 /* Single UNIX Specification for thousand separator */
269 parse_arg_type (const char *format, struct printf_spec *specinfo)
276 if (*++format == 'h')
280 specinfo->arg_type = CHAR_ARG;
283 specinfo->arg_type = UNSUPPORTED;
286 specinfo->arg_type = SHORT_ARG;
289 if (*++format == 'l')
292 #if defined (HAVE_LONG_LONG) && !defined(NPRINTF_LL)
293 specinfo->arg_type = LONG_LONG_ARG;
295 specinfo->arg_type = UNSUPPORTED;
301 specinfo->arg_type = LONG_ARG;
306 #if defined(_MPFR_H_HAVE_INTMAX_T) && !defined(NPRINTF_J)
307 specinfo->arg_type = INTMAX_ARG;
309 specinfo->arg_type = UNSUPPORTED;
314 specinfo->arg_type = SIZE_ARG;
319 specinfo->arg_type = PTRDIFF_ARG;
321 specinfo->arg_type = UNSUPPORTED;
327 specinfo->arg_type = LONG_DOUBLE_ARG;
329 specinfo->arg_type = UNSUPPORTED;
334 specinfo->arg_type = MPF_ARG;
338 specinfo->arg_type = MPQ_ARG;
342 /* The 'M' specifier was added in gmp 4.2.0 */
343 specinfo->arg_type = MP_LIMB_ARG;
347 specinfo->arg_type = MP_LIMB_ARRAY_ARG;
351 specinfo->arg_type = MPZ_ARG;
354 /* mpfr specific specifiers */
357 specinfo->arg_type = MPFR_PREC_ARG;
361 specinfo->arg_type = MPFR_ARG;
367 /* some macros and functions filling the buffer */
369 /* CONSUME_VA_ARG removes from va_list AP the type expected by SPECINFO */
371 /* With a C++ compiler wchar_t and enumeration in va_list are converted to
372 integer type : int, unsigned int, long or unsigned long (unfortunately,
373 this is implementation dependant).
374 We follow gmp which assumes in print/doprnt.c that wchar_t is converted
375 to int (because wchar_t <= int).
376 For wint_t, we assume that the case WINT_MAX < INT_MAX yields an
377 integer promotion. */
379 #if defined(WINT_MAX) && WINT_MAX < INT_MAX
380 typedef int mpfr_va_wint; /* integer promotion */
382 typedef wint_t mpfr_va_wint;
384 #define CASE_LONG_ARG(specinfo, ap) \
386 if (((specinfo).spec == 'd') || ((specinfo).spec == 'i') \
387 || ((specinfo).spec == 'o') || ((specinfo).spec == 'u') \
388 || ((specinfo).spec == 'x') || ((specinfo).spec == 'X')) \
389 (void) va_arg ((ap), long); \
390 else if ((specinfo).spec == 'c') \
391 (void) va_arg ((ap), mpfr_va_wint); \
392 else if ((specinfo).spec == 's') \
393 (void) va_arg ((ap), int); /* we assume integer promotion */ \
396 #define CASE_LONG_ARG(specinfo, ap) \
398 (void) va_arg ((ap), long); \
402 #if defined(_MPFR_H_HAVE_INTMAX_T)
403 #define CASE_INTMAX_ARG(specinfo, ap) \
405 (void) va_arg ((ap), intmax_t); \
408 #define CASE_INTMAX_ARG(specinfo, ap)
411 #ifdef HAVE_LONG_LONG
412 #define CASE_LONG_LONG_ARG(specinfo, ap) \
413 case LONG_LONG_ARG: \
414 (void) va_arg ((ap), long long); \
417 #define CASE_LONG_LONG_ARG(specinfo, ap)
420 #define CONSUME_VA_ARG(specinfo, ap) \
422 switch ((specinfo).arg_type) \
426 (void) va_arg ((ap), int); \
428 CASE_LONG_ARG (specinfo, ap) \
429 CASE_LONG_LONG_ARG (specinfo, ap) \
430 CASE_INTMAX_ARG (specinfo, ap) \
432 (void) va_arg ((ap), size_t); \
435 (void) va_arg ((ap), ptrdiff_t); \
437 case LONG_DOUBLE_ARG: \
438 (void) va_arg ((ap), long double); \
441 (void) va_arg ((ap), mpf_srcptr); \
444 (void) va_arg ((ap), mpq_srcptr); \
447 (void) va_arg ((ap), mp_limb_t); \
449 case MP_LIMB_ARRAY_ARG: \
450 (void) va_arg ((ap), mpfr_limb_ptr); \
451 (void) va_arg ((ap), mp_size_t); \
454 (void) va_arg ((ap), mpz_srcptr); \
457 switch ((specinfo).spec) \
466 (void) va_arg ((ap), int); \
476 (void) va_arg ((ap), double); \
479 (void) va_arg ((ap), char *); \
482 (void) va_arg ((ap), void *); \
487 /* process the format part which does not deal with mpfr types,
488 jump to external label 'error' if gmp_asprintf return -1. */
489 #define FLUSH(flag, start, end, ap, buf_ptr) \
491 const size_t n = (end) - (start); \
493 /* previous specifiers are understood by gmp_printf */ \
495 MPFR_TMP_DECL (marker); \
497 MPFR_TMP_MARK (marker); \
498 fmt_copy = (char*) MPFR_TMP_ALLOC (n + 1); \
499 strncpy (fmt_copy, (start), n); \
500 fmt_copy[n] = '\0'; \
501 if (sprntf_gmp ((buf_ptr), (fmt_copy), (ap)) == -1) \
503 MPFR_TMP_FREE (marker); \
507 MPFR_TMP_FREE (marker); \
509 else if ((start) != (end)) \
510 /* no conversion specification, just simple characters */ \
511 buffer_cat ((buf_ptr), (start), n); \
516 char *start; /* beginning of the buffer */
517 char *curr; /* null terminating character */
518 size_t size; /* buffer capacity */
522 buffer_init (struct string_buffer *b, size_t s)
524 b->start = (char *) (*__gmp_allocate_func) (s);
530 /* Increase buffer size by a number of character being the least multiple of
531 4096 greater than LEN+1. */
533 buffer_widen (struct string_buffer *b, size_t len)
535 const size_t pos = b->curr - b->start;
536 const size_t n = 0x1000 + (len & ~((size_t) 0xfff));
537 MPFR_ASSERTD (pos < b->size);
539 MPFR_ASSERTN ((len & ~((size_t) 4095)) <= (size_t)(SIZE_MAX - 4096));
540 MPFR_ASSERTN (b->size < SIZE_MAX - n);
543 (char *) (*__gmp_reallocate_func) (b->start, b->size, b->size + n);
545 b->curr = b->start + pos;
547 MPFR_ASSERTD (pos < b->size);
548 MPFR_ASSERTD (*b->curr == '\0');
551 /* Concatenate the LEN first characters of the string S to the buffer B and
552 expand it if needed. */
554 buffer_cat (struct string_buffer *b, const char *s, size_t len)
556 MPFR_ASSERTD (len != 0);
557 MPFR_ASSERTD (len <= strlen (s));
559 if (MPFR_UNLIKELY ((b->curr + len) >= (b->start + b->size)))
560 buffer_widen (b, len);
562 strncat (b->curr, s, len);
565 MPFR_ASSERTD (b->curr < b->start + b->size);
566 MPFR_ASSERTD (*b->curr == '\0');
569 /* Add N characters C to the end of buffer B */
571 buffer_pad (struct string_buffer *b, const char c, const size_t n)
573 MPFR_ASSERTD (n != 0);
575 MPFR_ASSERTN (b->size < SIZE_MAX - n - 1);
576 if (MPFR_UNLIKELY ((b->curr + n + 1) > (b->start + b->size)))
582 memset (b->curr, c, n);
586 MPFR_ASSERTD (b->curr < b->start + b->size);
589 /* Form a string by concatenating the first LEN characters of STR to TZ
590 zero(s), insert into one character C each 3 characters starting from end
591 to begining and concatenate the result to the buffer B. */
593 buffer_sandwich (struct string_buffer *b, char *str, size_t len,
594 const size_t tz, const char c)
596 const size_t step = 3;
597 const size_t size = len + tz;
598 const size_t r = size % step == 0 ? step : size % step;
599 const size_t q = size % step == 0 ? size / step - 1 : size / step;
602 MPFR_ASSERTD (size != 0);
605 buffer_cat (b, str, len);
606 buffer_pad (b, '0', tz);
610 MPFR_ASSERTN (b->size < SIZE_MAX - size - 1 - q);
611 MPFR_ASSERTD (len <= strlen (str));
612 if (MPFR_UNLIKELY ((b->curr + size + 1 + q) > (b->start + b->size)))
613 buffer_widen (b, size + q);
615 /* first R significant digits */
616 memcpy (b->curr, str, r);
621 /* blocks of thousands. Warning: STR might end in the middle of a block */
622 for (i = 0; i < q; ++i)
625 if (MPFR_LIKELY (len > 0))
627 if (MPFR_LIKELY (len >= step))
628 /* step significant digits */
630 memcpy (b->curr, str, step);
634 /* last digits in STR, fill up thousand block with zeros */
636 memcpy (b->curr, str, len);
637 memset (b->curr + len, '0', step - len);
643 memset (b->curr, '0', step);
651 MPFR_ASSERTD (b->curr < b->start + b->size);
654 /* let gmp_xprintf process the part it can understand */
656 sprntf_gmp (struct string_buffer *b, const char *fmt, va_list ap)
661 length = gmp_vasprintf (&s, fmt, ap);
663 buffer_cat (b, s, length);
669 /* Helper struct and functions for temporary strings management */
670 /* struct for easy string clearing */
674 struct string_list *next; /* NULL in last node */
679 init_string_list (struct string_list *sl)
685 /* clear all strings in the list */
687 clear_string_list (struct string_list *sl)
689 struct string_list *n;
694 mpfr_free_str (sl->string);
696 (*__gmp_free_func) (sl, sizeof(struct string_list));
701 /* add a string in the list */
703 register_string (struct string_list *sl, char *new_string)
705 /* look for the last node */
709 sl->next = (struct string_list*)
710 (*__gmp_allocate_func) (sizeof (struct string_list));
714 return sl->string = new_string;
717 /* padding type: where are the padding characters */
720 LEFT, /* spaces in left hand side for right justification */
721 LEADING_ZEROS, /* padding with '0' characters in integral part */
722 RIGHT /* spaces in right hand side for left justification */
725 /* number_parts details how much characters are needed in each part of a float
729 enum pad_t pad_type; /* Padding type */
730 size_t pad_size; /* Number of padding characters */
732 char sign; /* Sign character */
734 char *prefix_ptr; /* Pointer to prefix part */
735 size_t prefix_size; /* Number of characters in *prefix_ptr */
737 char thousands_sep; /* Thousands separator (only with style 'f') */
739 char *ip_ptr; /* Pointer to integral part characters*/
740 size_t ip_size; /* Number of digits in *ip_ptr */
741 int ip_trailing_zeros; /* Number of additional null digits in integral
744 char point; /* Decimal point character */
746 int fp_leading_zeros; /* Number of additional leading zeros in fractional
748 char *fp_ptr; /* Pointer to fractional part characters */
749 size_t fp_size; /* Number of digits in *fp_ptr */
750 int fp_trailing_zeros; /* Number of additional trailing zeros in fractional
753 char *exp_ptr; /* Pointer to exponent part */
754 size_t exp_size; /* Number of characters in *exp_ptr */
756 struct string_list *sl; /* List of string buffers in use: we need such a
757 mechanism because fp_ptr may point into the same
761 /* For a real non zero number x, what is the base exponent f when rounding x
762 with rounding mode r to r(x) = m*b^f, where m is a digit and 1 <= m < b ?
763 Return non zero value if x is rounded up to b^f, return zero otherwise */
765 next_base_power_p (mpfr_srcptr x, int base, mpfr_rnd_t rnd)
771 MPFR_ASSERTD (MPFR_IS_PURE_FP (x));
772 MPFR_ASSERTD (base == 2 || base == 16);
774 /* Warning: the decimal point is AFTER THE FIRST DIGIT in this output
776 nbits = base == 2 ? 1 : 4;
779 || (rnd == MPFR_RNDD && MPFR_IS_POS (x))
780 || (rnd == MPFR_RNDU && MPFR_IS_NEG (x))
781 || MPFR_PREC (x) <= nbits)
782 /* no rounding when printing x with 1 digit */
785 xm = MPFR_MANT (x) [MPFR_LIMB_SIZE (x) - 1];
786 pm = MPFR_LIMB_MASK (GMP_NUMB_BITS - nbits);
787 if ((xm & ~pm) ^ ~pm)
788 /* do no round up if some of the nbits first bits are 0s. */
791 if (rnd == MPFR_RNDN)
792 /* mask for rounding bit */
793 pm = (MPFR_LIMB_ONE << (GMP_NUMB_BITS - nbits - 1));
795 /* round up if some remaining bits are 1 */
796 /* warning: the return value must be an int */
797 return xm & pm ? 1 : 0;
800 /* Record information from mpfr_get_str() so as to avoid multiple
801 calls to this expensive function. */
808 /* For a real non zero number x, what is the exponent f so that
809 10^f <= x < 10^(f+1). */
811 floor_log10 (mpfr_srcptr x)
816 /* make sure first that y can represent a mpfr_exp_t exactly
817 and can compare with x */
818 mpfr_prec_t prec = sizeof (mpfr_exp_t) * CHAR_BIT;
819 mpfr_init2 (y, MAX (prec, MPFR_PREC (x)));
821 exp = mpfr_ceil_mul (MPFR_GET_EXP (x), 10, 1) - 1;
822 mpfr_set_exp_t (y, exp, MPFR_RNDU);
823 /* The following call to mpfr_ui_pow should be fast: y is an integer
824 (not too large), so that mpfr_pow_z will be used internally. */
825 mpfr_ui_pow (y, 10, y, MPFR_RNDU);
826 if (mpfr_cmpabs (x, y) < 0)
833 /* Determine the different parts of the string representation of the regular
834 number P when SPEC.SPEC is 'a', 'A', or 'b'.
836 return -1 if some field > INT_MAX */
838 regular_ab (struct number_parts *np, mpfr_srcptr p,
839 const struct printf_spec spec)
846 uppercase = spec.spec == 'A';
851 else if (spec.showsign || spec.space)
852 np->sign = spec.showsign ? '+' : ' ';
854 if (spec.spec == 'a' || spec.spec == 'A')
858 str = (char *) (*__gmp_allocate_func) (1 + np->prefix_size);
860 str[1] = uppercase ? 'X' : 'x';
862 np->prefix_ptr = register_string (np->sl, str);
867 base = (spec.spec == 'b') ? 2 : 16;
873 /* Number of significant digits:
874 - if no given precision, let mpfr_get_str determine it;
875 - if a non-zero precision is specified, then one digit before decimal
876 point plus SPEC.PREC after it. */
877 nsd = spec.prec < 0 ? 0 : spec.prec + np->ip_size;
878 str = mpfr_get_str (0, &exp, base, nsd, p, spec.rnd_mode);
879 register_string (np->sl, str);
880 np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign if any */
883 /* EXP is the exponent for radix sixteen with decimal point BEFORE the
884 first digit, we want the exponent for radix two and the decimal
885 point AFTER the first digit. */
887 MPFR_ASSERTN (exp > MPFR_EMIN_MIN /4); /* possible overflow */
891 /* EXP is the exponent for decimal point BEFORE the first digit, we
892 want the exponent for decimal point AFTER the first digit. */
894 MPFR_ASSERTN (exp > MPFR_EMIN_MIN); /* possible overflow */
898 else if (next_base_power_p (p, base, spec.rnd_mode))
900 str = (char *)(*__gmp_allocate_func) (2);
903 np->ip_ptr = register_string (np->sl, str);
905 exp = MPFR_GET_EXP (p);
909 str = (char *)(*__gmp_allocate_func) (2);
912 np->ip_ptr = register_string (np->sl, str);
914 exp = MPFR_GET_EXP (p) - 1;
919 mp_limb_t msl = MPFR_MANT (p)[MPFR_LIMB_SIZE (p) - 1];
920 int rnd_bit = GMP_NUMB_BITS - 5;
922 /* pick up the 4 first bits */
923 digit = msl >> (rnd_bit+1);
924 if (spec.rnd_mode == MPFR_RNDA
925 || (spec.rnd_mode == MPFR_RNDU && MPFR_IS_POS (p))
926 || (spec.rnd_mode == MPFR_RNDD && MPFR_IS_NEG (p))
927 || (spec.rnd_mode == MPFR_RNDN
928 && (msl & (MPFR_LIMB_ONE << rnd_bit))))
930 MPFR_ASSERTD ((0 <= digit) && (digit <= 15));
932 str = (char *)(*__gmp_allocate_func) (1 + np->ip_size);
933 str[0] = num_to_text [digit];
935 np->ip_ptr = register_string (np->sl, str);
937 exp = MPFR_GET_EXP (p) - 4;
941 /* All digits in upper case */
971 if (spec.spec == 'b' || spec.prec != 0)
972 /* compute the number of digits in fractional part */
977 /* the sign has been skipped, skip also the first digit */
979 str_len = strlen (str);
980 ptr = str + str_len - 1; /* points to the end of str */
983 /* remove trailing zeros, if any */
985 while ((*ptr == '0') && (str_len != 0))
992 if (str_len > INT_MAX)
993 /* too many digits in fractional part */
997 /* there are some non-zero digits in fractional part */
1000 np->fp_size = str_len;
1001 if ((int) str_len < spec.prec)
1002 np->fp_trailing_zeros = spec.prec - str_len;
1007 if ((np->fp_size != 0) || spec.alt)
1008 np->point = MPFR_DECIMAL_POINT;
1010 /* the exponent part contains the character 'p', or 'P' plus the sign
1011 character plus at least one digit and only as many more digits as
1012 necessary to represent the exponent.
1013 We assume that |EXP| < 10^INT_MAX. */
1018 x = SAFE_ABS (mpfr_uexp_t, exp);
1025 str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
1026 np->exp_ptr = register_string (np->sl, str);
1028 char exp_fmt[8]; /* contains at most 7 characters like in "p%+.1i",
1031 exp_fmt[0] = uppercase ? 'P' : 'p';
1033 strcat (exp_fmt, "%+.1" MPFR_EXP_FSPEC "d");
1035 if (sprintf (str, exp_fmt, (mpfr_eexp_t) exp) < 0)
1042 /* Determine the different parts of the string representation of the regular
1043 number P when SPEC.SPEC is 'e', 'E', 'g', or 'G'.
1044 DEC_INFO contains the previously computed exponent and string or is NULL.
1046 return -1 if some field > INT_MAX */
1048 regular_eg (struct number_parts *np, mpfr_srcptr p,
1049 const struct printf_spec spec, struct decimal_info *dec_info)
1054 const int uppercase = spec.spec == 'E' || spec.spec == 'G';
1055 const int spec_g = spec.spec == 'g' || spec.spec == 'G';
1056 const int keep_trailing_zeros = (spec_g && spec.alt)
1057 || (!spec_g && (spec.prec > 0));
1060 if (MPFR_IS_NEG (p))
1062 else if (spec.showsign || spec.space)
1063 np->sign = spec.showsign ? '+' : ' ';
1067 if (dec_info == NULL)
1071 /* Number of significant digits:
1072 - if no given precision, then let mpfr_get_str determine it,
1073 - if a precision is specified, then one digit before decimal point
1074 plus SPEC.PREC after it.
1075 We use the fact here that mpfr_get_str allows us to ask for only one
1076 significant digit when the base is not a power of 2. */
1077 nsd = (spec.prec < 0) ? 0 : spec.prec + np->ip_size;
1078 str = mpfr_get_str (0, &exp, 10, nsd, p, spec.rnd_mode);
1079 register_string (np->sl, str);
1083 exp = dec_info->exp;
1084 str = dec_info->str;
1086 np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign if any */
1089 /* compute the number of digits in fractional part */
1094 /* the sign has been skipped, skip also the first digit */
1096 str_len = strlen (str);
1097 ptr = str + str_len - 1; /* points to the end of str */
1099 if (!keep_trailing_zeros)
1100 /* remove trailing zeros, if any */
1102 while ((*ptr == '0') && (str_len != 0))
1109 if (str_len > INT_MAX)
1110 /* too many digits in fractional part */
1114 /* there are some non-zero digits in fractional part */
1117 np->fp_size = str_len;
1118 if ((!spec_g || spec.alt) && (spec.prec > 0)
1119 && ((int)str_len < spec.prec))
1120 /* add missing trailing zeros */
1121 np->fp_trailing_zeros = spec.prec - str_len;
1126 if (np->fp_size != 0 || spec.alt)
1127 np->point = MPFR_DECIMAL_POINT;
1129 /* EXP is the exponent for decimal point BEFORE the first digit, we want
1130 the exponent for decimal point AFTER the first digit.
1131 Here, no possible overflow because exp < MPFR_EXP (p) / 3 */
1134 /* the exponent part contains the character 'e', or 'E' plus the sign
1135 character plus at least two digits and only as many more digits as
1136 necessary to represent the exponent.
1137 We assume that |EXP| < 10^INT_MAX. */
1142 x = SAFE_ABS (mpfr_uexp_t, exp);
1149 if (np->exp_size < 4)
1152 str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
1153 np->exp_ptr = register_string (np->sl, str);
1156 char exp_fmt[8]; /* e.g. "e%+.2i", or "E%+.2li" */
1158 exp_fmt[0] = uppercase ? 'E' : 'e';
1160 strcat (exp_fmt, "%+.2" MPFR_EXP_FSPEC "d");
1162 if (sprintf (str, exp_fmt, (mpfr_eexp_t) exp) < 0)
1169 /* Determine the different parts of the string representation of the regular
1170 number P when SPEC.SPEC is 'f', 'F', 'g', or 'G'.
1171 DEC_INFO contains the previously computed exponent and string or is NULL.
1173 return -1 if some field of number_parts is greater than INT_MAX */
1175 regular_fg (struct number_parts *np, mpfr_srcptr p,
1176 const struct printf_spec spec, struct decimal_info *dec_info)
1180 const int spec_g = (spec.spec == 'g' || spec.spec == 'G');
1181 const int keep_trailing_zeros = !spec_g || spec.alt;
1183 /* WARNING: an empty precision field is forbidden (it means precision = 6
1184 and it should have been changed to 6 before the function call) */
1185 MPFR_ASSERTD (spec.prec >= 0);
1188 if (MPFR_IS_NEG (p))
1190 else if (spec.showsign || spec.space)
1191 np->sign = spec.showsign ? '+' : ' ';
1193 if (MPFR_GET_EXP (p) <= 0)
1196 /* Most of the time, integral part is 0 */
1198 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1201 np->ip_ptr = register_string (np->sl, str);
1204 /* only two possibilities: either 1 or 0. */
1208 MPFR_ALIAS (y, p, 1, MPFR_EXP (p));
1210 if (spec.rnd_mode == MPFR_RNDA
1211 || (spec.rnd_mode == MPFR_RNDD && MPFR_IS_NEG (p))
1212 || (spec.rnd_mode == MPFR_RNDU && MPFR_IS_POS (p))
1213 || (spec.rnd_mode == MPFR_RNDN && mpfr_cmp_d (y, 0.5) > 0))
1214 /* rounded up to 1: one digit '1' in integral part.
1215 note that 0.5 is rounded to 0 with RNDN (round ties to even) */
1216 np->ip_ptr[0] = '1';
1220 /* exp = position of the most significant decimal digit. */
1221 exp = floor_log10 (p);
1222 MPFR_ASSERTD (exp < 0);
1224 if (exp < -spec.prec)
1225 /* only the last digit may be non zero */
1228 switch (spec.rnd_mode)
1234 round_away = MPFR_IS_NEG (p);
1237 round_away = MPFR_IS_POS (p);
1241 /* compare |p| to y = 0.5*10^(-spec.prec) */
1243 mpfr_exp_t e = MAX (MPFR_PREC (p), 56);
1244 mpfr_init2 (y, e + 8);
1247 /* find a lower approximation of
1248 0.5*10^(-spec.prec) different from |p| */
1250 mpfr_set_prec (y, e);
1251 mpfr_set_si (y, -spec.prec, MPFR_RNDN);
1252 mpfr_exp10 (y, y, MPFR_RNDD);
1253 mpfr_div_2ui (y, y, 1, MPFR_RNDN);
1254 } while (mpfr_cmpabs (y, p) == 0);
1256 round_away = mpfr_cmpabs (y, p) < 0;
1265 /* round away from zero: the last output digit is '1' */
1267 np->fp_leading_zeros = spec.prec - 1;
1271 (char *) (*__gmp_allocate_func) (1 + np->fp_size);
1274 np->fp_ptr = register_string (np->sl, str);
1277 /* only zeros in fractional part */
1279 MPFR_ASSERTD (!spec_g);
1280 np->fp_leading_zeros = spec.prec;
1284 /* the most significant digits are the last
1285 spec.prec + exp + 1 digits in fractional part */
1289 if (dec_info == NULL)
1291 size_t nsd = spec.prec + exp + 1;
1292 /* WARNING: nsd may equal 1, but here we use the
1293 fact that mpfr_get_str can return one digit with
1294 base ten (undocumented feature, see comments in
1297 str = mpfr_get_str (NULL, &exp, 10, nsd, p, spec.rnd_mode);
1298 register_string (np->sl, str);
1302 exp = dec_info->exp;
1303 str = dec_info->str;
1305 if (MPFR_IS_NEG (p))
1311 MPFR_ASSERTD (str[0] == '1');
1312 np->ip_ptr[0] = '1';
1313 if (!spec_g || spec.alt)
1314 np->fp_leading_zeros = spec.prec;
1319 np->fp_leading_zeros = -exp;
1320 MPFR_ASSERTD (exp <= 0);
1322 str_len = strlen (str); /* the sign has been skipped */
1323 ptr = str + str_len - 1; /* points to the end of str */
1325 if (!keep_trailing_zeros)
1326 /* remove trailing zeros, if any */
1328 while ((*ptr == '0') && str_len)
1335 if (str_len > INT_MAX)
1336 /* too many digits in fractional part */
1339 MPFR_ASSERTD (str_len > 0);
1340 np->fp_size = str_len;
1342 if ((!spec_g || spec.alt)
1344 && (np->fp_leading_zeros + np->fp_size < spec.prec))
1345 /* add missing trailing zeros */
1346 np->fp_trailing_zeros = spec.prec - np->fp_leading_zeros
1352 if (spec.alt || np->fp_leading_zeros != 0 || np->fp_size != 0
1353 || np->fp_trailing_zeros != 0)
1354 np->point = MPFR_DECIMAL_POINT;
1361 /* Determine the position of the most significant decimal digit. */
1362 exp = floor_log10 (p);
1363 MPFR_ASSERTD (exp >= 0);
1365 /* P is too large to print all its integral part digits */
1368 if (dec_info == NULL)
1369 { /* this case occurs with mpfr_printf ("%.0RUf", x) with x=9.5 */
1371 mpfr_get_str (NULL, &exp, 10, spec.prec+exp+1, p, spec.rnd_mode);
1372 register_string (np->sl, str);
1376 exp = dec_info->exp;
1377 str = dec_info->str;
1379 np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign */
1380 str_len = strlen (str);
1384 /* mpfr_get_str gives no trailing zero when p is rounded up to the next
1385 power of 10 (p integer, so no fractional part) */
1387 np->ip_trailing_zeros = exp - str_len;
1388 np->ip_size = str_len;
1394 /* thousands separator in integral part */
1395 np->thousands_sep = MPFR_THOUSANDS_SEPARATOR;
1397 /* fractional part */
1399 str_len -= np->ip_size;
1400 if (!keep_trailing_zeros)
1401 /* remove trailing zeros, if any */
1403 char *ptr = str + str_len - 1; /* pointer to the last digit of
1405 while ((*ptr == '0') && (str_len != 0))
1413 /* some nonzero digits in fractional part */
1415 if (str_len > INT_MAX)
1416 /* too many digits in fractional part */
1419 np->point = MPFR_DECIMAL_POINT;
1421 np->fp_size = str_len;
1424 if (keep_trailing_zeros && str_len < spec.prec)
1425 /* add missing trailing zeros */
1427 np->point = MPFR_DECIMAL_POINT;
1428 np->fp_trailing_zeros = spec.prec - np->fp_size;
1432 /* add decimal point even if no digits follow it */
1433 np->point = MPFR_DECIMAL_POINT;
1439 /* partition_number determines the different parts of the string
1440 representation of the number p according to the given specification.
1441 partition_number initializes the given structure np, so all previous
1442 information in that variable is lost.
1443 return the total number of characters to be written.
1444 return -1 if an error occured, in that case np's fields are in an undefined
1445 state but all string buffers have been freed. */
1447 partition_number (struct number_parts *np, mpfr_srcptr p,
1448 struct printf_spec spec)
1454 /* WARNING: left justification means right space padding */
1455 np->pad_type = spec.left ? RIGHT : spec.pad == '0' ? LEADING_ZEROS : LEFT;
1458 np->prefix_ptr =NULL;
1459 np->prefix_size = 0;
1460 np->thousands_sep = '\0';
1463 np->ip_trailing_zeros = 0;
1465 np->fp_leading_zeros = 0;
1468 np->fp_trailing_zeros = 0;
1471 np->sl = (struct string_list *)
1472 (*__gmp_allocate_func) (sizeof (struct string_list));
1473 init_string_list (np->sl);
1475 uppercase = spec.spec == 'A' || spec.spec == 'E' || spec.spec == 'F'
1476 || spec.spec == 'G';
1478 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (p)))
1480 if (MPFR_IS_NAN (p))
1482 if (np->pad_type == LEADING_ZEROS)
1483 /* don't want "0000nan", change to right justification padding
1484 with left spaces instead */
1485 np->pad_type = LEFT;
1489 np->ip_size = MPFR_NAN_STRING_LENGTH;
1490 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1491 strcpy (str, MPFR_NAN_STRING_UC);
1492 np->ip_ptr = register_string (np->sl, str);
1496 np->ip_size = MPFR_NAN_STRING_LENGTH;
1497 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1498 strcpy (str, MPFR_NAN_STRING_LC);
1499 np->ip_ptr = register_string (np->sl, str);
1502 else if (MPFR_IS_INF (p))
1504 if (np->pad_type == LEADING_ZEROS)
1505 /* don't want "0000inf", change to right justification padding
1506 with left spaces instead */
1507 np->pad_type = LEFT;
1509 if (MPFR_IS_NEG (p))
1514 np->ip_size = MPFR_INF_STRING_LENGTH;
1515 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1516 strcpy (str, MPFR_INF_STRING_UC);
1517 np->ip_ptr = register_string (np->sl, str);
1521 np->ip_size = MPFR_INF_STRING_LENGTH;
1522 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1523 strcpy (str, MPFR_INF_STRING_LC);
1524 np->ip_ptr = register_string (np->sl, str);
1530 /* note: for 'g' spec, zero is always displayed with 'f'-style with
1531 precision spec.prec - 1 and the trailing zeros are removed unless
1532 the flag '#' is used. */
1533 if (MPFR_IS_NEG (p))
1536 else if (spec.showsign || spec.space)
1537 np->sign = spec.showsign ? '+' : ' ';
1539 if (spec.spec == 'a' || spec.spec == 'A')
1542 np->prefix_size = 2;
1543 str = (char *) (*__gmp_allocate_func) (1 + np->prefix_size);
1545 str[1] = uppercase ? 'X' : 'x';
1547 np->prefix_ptr = register_string (np->sl, str);
1552 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1555 np->ip_ptr = register_string (np->sl, str);
1558 && ((spec.spec != 'g' && spec.spec != 'G') || spec.alt))
1559 /* fractional part */
1561 np->point = MPFR_DECIMAL_POINT;
1562 np->fp_trailing_zeros = (spec.spec == 'g' && spec.spec == 'G') ?
1563 spec.prec - 1 : spec.prec;
1566 np->point = MPFR_DECIMAL_POINT;
1568 if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b'
1569 || spec.spec == 'e' || spec.spec == 'E')
1572 np->exp_size = (spec.spec == 'e' || spec.spec == 'E') ? 4 : 3;
1573 str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
1574 if (spec.spec == 'e' || spec.spec == 'E')
1575 strcpy (str, uppercase ? "E+00" : "e+00");
1577 strcpy (str, uppercase ? "P+0" : "p+0");
1578 np->exp_ptr = register_string (np->sl, str);
1583 /* regular p, p != 0 */
1585 if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b')
1587 if (regular_ab (np, p, spec) == -1)
1590 else if (spec.spec == 'f' || spec.spec == 'F')
1592 if (spec.prec == -1)
1594 if (regular_fg (np, p, spec, NULL) == -1)
1597 else if (spec.spec == 'e' || spec.spec == 'E')
1599 if (regular_eg (np, p, spec, NULL) == -1)
1605 /* Use the C99 rules:
1606 if T > X >= -4 then the conversion is with style 'f'/'F' and
1608 otherwise, the conversion is with style 'e'/'E' and
1610 where T is the threshold computed below and X is the exponent
1611 that would be displayed with style 'e' and precision T-1. */
1614 struct decimal_info dec_info;
1616 threshold = (spec.prec < 0) ? 6 : (spec.prec == 0) ? 1 : spec.prec;
1617 dec_info.str = mpfr_get_str (NULL, &dec_info.exp, 10, threshold,
1619 register_string (np->sl, dec_info.str);
1620 /* mpfr_get_str corresponds to a significand between 0.1 and 1,
1621 whereas here we want a significand between 1 and 10. */
1622 x = dec_info.exp - 1;
1624 if (threshold > x && x >= -4)
1626 /* the conversion is with style 'f' */
1627 spec.prec = threshold - x - 1;
1629 if (regular_fg (np, p, spec, &dec_info) == -1)
1634 spec.prec = threshold - 1;
1636 if (regular_eg (np, p, spec, &dec_info) == -1)
1642 /* compute the number of characters to be written verifying it is not too
1644 total = np->sign ? 1 : 0;
1645 total += np->prefix_size;
1646 total += np->ip_size;
1647 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1649 total += np->ip_trailing_zeros;
1650 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1652 if (np->thousands_sep)
1653 /* ' flag, style f and the thousands separator in current locale is not
1654 reduced to the null character */
1655 total += (np->ip_size + np->ip_trailing_zeros) / 3;
1656 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1660 total += np->fp_leading_zeros;
1661 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1663 total += np->fp_size;
1664 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1666 total += np->fp_trailing_zeros;
1667 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1669 total += np->exp_size;
1670 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1673 if (spec.width > total)
1674 /* pad with spaces or zeros depending on np->pad_type */
1676 np->pad_size = spec.width - total;
1677 total += np->pad_size; /* here total == spec.width,
1678 so 0 < total < INT_MAX */
1684 clear_string_list (np->sl);
1685 np->prefix_ptr = NULL;
1692 /* sprnt_fp prints a mpfr_t according to spec.spec specification.
1694 return the size of the string (not counting the terminating '\0')
1695 return -1 if the built string is too long (i.e. has more than
1696 INT_MAX characters). */
1698 sprnt_fp (struct string_buffer *buf, mpfr_srcptr p,
1699 const struct printf_spec spec)
1702 struct number_parts np;
1704 length = partition_number (&np, p, spec);
1708 /* right justification padding with left spaces */
1709 if (np.pad_type == LEFT && np.pad_size != 0)
1710 buffer_pad (buf, ' ', np.pad_size);
1712 /* sign character (may be '-', '+', or ' ') */
1714 buffer_pad (buf, np.sign, 1);
1718 buffer_cat (buf, np.prefix_ptr, np.prefix_size);
1720 /* right justification padding with leading zeros */
1721 if (np.pad_type == LEADING_ZEROS && np.pad_size != 0)
1722 buffer_pad (buf, '0', np.pad_size);
1724 /* integral part (may also be "nan" or "inf") */
1725 MPFR_ASSERTN (np.ip_ptr != NULL); /* never empty */
1726 if (MPFR_UNLIKELY (np.thousands_sep))
1727 buffer_sandwich (buf, np.ip_ptr, np.ip_size, np.ip_trailing_zeros,
1731 buffer_cat (buf, np.ip_ptr, np.ip_size);
1733 /* trailing zeros in integral part */
1734 if (np.ip_trailing_zeros != 0)
1735 buffer_pad (buf, '0', np.ip_trailing_zeros);
1740 buffer_pad (buf, np.point, 1);
1742 /* leading zeros in fractional part */
1743 if (np.fp_leading_zeros != 0)
1744 buffer_pad (buf, '0', np.fp_leading_zeros);
1746 /* significant digits in fractional part */
1748 buffer_cat (buf, np.fp_ptr, np.fp_size);
1750 /* trailing zeros in fractional part */
1751 if (np.fp_trailing_zeros != 0)
1752 buffer_pad (buf, '0', np.fp_trailing_zeros);
1756 buffer_cat (buf, np.exp_ptr, np.exp_size);
1758 /* left justication padding with right spaces */
1759 if (np.pad_type == RIGHT && np.pad_size != 0)
1760 buffer_pad (buf, ' ', np.pad_size);
1762 clear_string_list (np.sl);
1767 mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
1769 struct string_buffer buf;
1772 /* informations on the conversion specification filled by the parser */
1773 struct printf_spec spec;
1774 /* flag raised when previous part of fmt need to be processed by
1777 /* beginning and end of the previous unprocessed part of fmt */
1778 const char *start, *end;
1779 /* pointer to arguments for gmp_vasprintf */
1782 MPFR_SAVE_EXPO_DECL (expo);
1783 MPFR_SAVE_EXPO_MARK (expo);
1786 buffer_init (&buf, 4096);
1792 /* Look for the next format specification */
1793 while ((*fmt) && (*fmt != '%'))
1800 /* %%: go one step further otherwise the second '%' would be
1801 considered as a new conversion specification introducing
1811 /* format string analysis */
1812 specinfo_init (&spec);
1813 fmt = parse_flags (fmt, &spec);
1815 READ_INT (ap, fmt, spec, width, width_analysis);
1820 spec.width = -spec.width;
1821 MPFR_ASSERTN (spec.width < INT_MAX);
1825 const char *f = ++fmt;
1826 READ_INT (ap, fmt, spec, prec, prec_analysis);
1834 fmt = parse_arg_type (fmt, &spec);
1835 if (spec.arg_type == UNSUPPORTED)
1836 /* the current architecture doesn't support this type */
1840 else if (spec.arg_type == MPFR_ARG)
1848 spec.rnd_mode = (mpfr_rnd_t) va_arg (ap, int);
1852 spec.rnd_mode = MPFR_RNDD;
1856 spec.rnd_mode = MPFR_RNDU;
1860 spec.rnd_mode = MPFR_RNDA;
1864 spec.rnd_mode = MPFR_RNDZ;
1869 spec.rnd_mode = MPFR_RNDN;
1874 if (!specinfo_is_valid (spec))
1880 /* Format processing */
1881 if (spec.spec == '\0')
1882 /* end of the format string */
1884 else if (spec.spec == 'n')
1885 /* put the number of characters written so far in the location pointed
1886 by the next va_list argument; the types of pointer accepted are the
1887 same as in GMP (except unsupported quad_t) plus pointer to a mpfr_t
1888 so as to be able to accept the same format strings. */
1893 p = va_arg (ap, void *);
1894 FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
1897 nchar = buf.curr - buf.start;
1899 switch (spec.arg_type)
1902 *(char *) p = (char) nchar;
1905 *(short *) p = (short) nchar;
1908 *(long *) p = (long) nchar;
1910 #ifdef HAVE_LONG_LONG
1912 *(long long *) p = (long long) nchar;
1915 #ifdef _MPFR_H_HAVE_INTMAX_T
1917 *(intmax_t *) p = (intmax_t) nchar;
1921 *(size_t *) p = nchar;
1924 *(ptrdiff_t *) p = (ptrdiff_t) nchar;
1927 mpf_set_ui ((mpf_ptr) p, (unsigned long) nchar);
1930 mpq_set_ui ((mpq_ptr) p, (unsigned long) nchar, 1L);
1933 *(mp_limb_t *) p = (mp_limb_t) nchar;
1935 case MP_LIMB_ARRAY_ARG:
1937 mp_limb_t *q = (mp_limb_t *) p;
1939 n = va_arg (ap, mp_size_t);
1945 /* we assume here that mp_limb_t is wider than int */
1946 *q = (mp_limb_t) nchar;
1955 mpz_set_ui ((mpz_ptr) p, (unsigned long) nchar);
1959 mpfr_set_ui ((mpfr_ptr) p, (unsigned long) nchar,
1964 *(int *) p = (int) nchar;
1966 va_copy (ap2, ap); /* after the switch, due to MP_LIMB_ARRAY_ARG
1969 else if (spec.arg_type == MPFR_PREC_ARG)
1970 /* output mpfr_prec_t variable */
1973 char format[MPFR_PREC_FORMAT_SIZE + 6]; /* see examples below */
1976 prec = va_arg (ap, mpfr_prec_t);
1978 FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
1983 /* construct format string, like "%*.*hu" "%*.*u" or "%*.*lu" */
1989 strcat (format, MPFR_PREC_FORMAT_TYPE);
1990 format[4 + MPFR_PREC_FORMAT_SIZE] = spec.spec;
1991 format[5 + MPFR_PREC_FORMAT_SIZE] = '\0';
1992 length = gmp_asprintf (&s, format, spec.width, spec.prec, prec);
1993 if (buf.size <= INT_MAX - length)
1995 buffer_cat (&buf, s, length);
2001 goto overflow_error;
2004 else if (spec.arg_type == MPFR_ARG)
2005 /* output a mpfr_t variable */
2009 p = va_arg (ap, mpfr_srcptr);
2011 FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2027 if (sprnt_fp (&buf, p, spec) < 0)
2028 goto overflow_error;
2032 /* unsupported specifier */
2037 /* gmp_printf specification, step forward in the va_list */
2039 CONSUME_VA_ARG (spec, ap);
2045 FLUSH (xgmp_fmt_flag, start, fmt, ap2, &buf);
2048 nbchar = buf.curr - buf.start;
2049 MPFR_ASSERTD (nbchar == strlen (buf.start));
2051 (char *) (*__gmp_reallocate_func) (buf.start, buf.size, nbchar + 1);
2052 buf.size = nbchar + 1; /* update needed for __gmp_free_func below when
2053 nbchar is too large (overflow_error) */
2056 /* If nbchar is larger than INT_MAX, the ISO C99 standard is silent, but
2057 POSIX says concerning the snprintf() function:
2058 "[EOVERFLOW] The value of n is greater than {INT_MAX} or the
2059 number of bytes needed to hold the output excluding the
2060 terminating null is greater than {INT_MAX}." See:
2061 http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
2062 But it doesn't say anything concerning the other printf-like functions.
2063 A defect report has been submitted to austin-review-l (item 2532).
2064 So, for the time being, we return a negative value and set the erange
2065 flag, and set errno to EOVERFLOW in POSIX system. */
2066 if (nbchar <= INT_MAX)
2068 MPFR_SAVE_EXPO_FREE (expo);
2073 MPFR_SAVE_EXPO_UPDATE_FLAGS(expo, MPFR_FLAGS_ERANGE);
2079 MPFR_SAVE_EXPO_FREE (expo);
2081 (*__gmp_free_func) (buf.start, buf.size);
2086 #endif /* HAVE_STDARG */