1 /* mpfr_vasprintf -- main function for the printf functions family
2 plus helper macros & functions.
4 Copyright 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
5 Contributed by the Arenaire 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))
1310 MPFR_ASSERTD (str[0] == '1');
1311 np->ip_ptr[0] = '1';
1312 if (!spec_g || spec.alt)
1313 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;
1359 size_t nsd; /* Number of significant digits */
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 np->ip_size = exp + 1;
1370 nsd = spec.prec + np->ip_size;
1371 if (dec_info == NULL)
1373 str = mpfr_get_str (NULL, &exp, 10, nsd, p, spec.rnd_mode);
1374 register_string (np->sl, str);
1378 exp = dec_info->exp;
1379 str = dec_info->str;
1381 np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign */
1384 /* thousands separator in integral part */
1385 np->thousands_sep = MPFR_THOUSANDS_SEPARATOR;
1387 if (nsd == 0 || (spec_g && !spec.alt))
1388 /* compute how much non-zero digits in integral and fractional
1392 str_len = strlen (str); /* note: the sign has been skipped */
1395 /* mpfr_get_str doesn't give the trailing zeros when p is a
1396 multiple of 10 (p integer, so no fractional part) */
1398 np->ip_trailing_zeros = exp - str_len;
1399 np->ip_size = str_len;
1401 np->point = MPFR_DECIMAL_POINT;
1404 /* str may contain some digits which are in fractional part */
1408 ptr = str + str_len - 1; /* points to the end of str */
1409 str_len -= np->ip_size; /* number of digits in fractional
1412 if (!keep_trailing_zeros)
1413 /* remove trailing zeros, if any */
1415 while ((*ptr == '0') && (str_len != 0))
1422 if (str_len > INT_MAX)
1423 /* too many digits in fractional part */
1427 /* some digits in fractional part */
1429 np->point = MPFR_DECIMAL_POINT;
1430 np->fp_ptr = str + np->ip_size;
1431 np->fp_size = str_len;
1436 /* spec.prec digits in fractional part */
1438 if (np->ip_size == exp - 1)
1439 /* the absolute value of the number has been rounded up to a power
1441 Insert an additional zero in integral part and put the rest of
1442 them in fractional part. */
1443 np->ip_trailing_zeros = 1;
1447 MPFR_ASSERTD (np->ip_size + np->ip_trailing_zeros == exp);
1448 MPFR_ASSERTD (np->ip_size + spec.prec == nsd);
1450 np->point = MPFR_DECIMAL_POINT;
1451 np->fp_ptr = str + np->ip_size;
1452 np->fp_size = spec.prec;
1455 np->point = MPFR_DECIMAL_POINT;
1462 /* partition_number determines the different parts of the string
1463 representation of the number p according to the given specification.
1464 partition_number initializes the given structure np, so all previous
1465 information in that variable is lost.
1466 return the total number of characters to be written.
1467 return -1 if an error occured, in that case np's fields are in an undefined
1468 state but all string buffers have been freed. */
1470 partition_number (struct number_parts *np, mpfr_srcptr p,
1471 struct printf_spec spec)
1477 /* WARNING: left justification means right space padding */
1478 np->pad_type = spec.left ? RIGHT : spec.pad == '0' ? LEADING_ZEROS : LEFT;
1481 np->prefix_ptr =NULL;
1482 np->prefix_size = 0;
1483 np->thousands_sep = '\0';
1486 np->ip_trailing_zeros = 0;
1488 np->fp_leading_zeros = 0;
1491 np->fp_trailing_zeros = 0;
1494 np->sl = (struct string_list *)
1495 (*__gmp_allocate_func) (sizeof (struct string_list));
1496 init_string_list (np->sl);
1498 uppercase = spec.spec == 'A' || spec.spec == 'E' || spec.spec == 'F'
1499 || spec.spec == 'G';
1501 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (p)))
1503 if (MPFR_IS_NAN (p))
1505 if (np->pad_type == LEADING_ZEROS)
1506 /* don't want "0000nan", change to right justification padding
1507 with left spaces instead */
1508 np->pad_type = LEFT;
1512 np->ip_size = MPFR_NAN_STRING_LENGTH;
1513 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1514 strcpy (str, MPFR_NAN_STRING_UC);
1515 np->ip_ptr = register_string (np->sl, str);
1519 np->ip_size = MPFR_NAN_STRING_LENGTH;
1520 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1521 strcpy (str, MPFR_NAN_STRING_LC);
1522 np->ip_ptr = register_string (np->sl, str);
1525 else if (MPFR_IS_INF (p))
1527 if (np->pad_type == LEADING_ZEROS)
1528 /* don't want "0000inf", change to right justification padding
1529 with left spaces instead */
1530 np->pad_type = LEFT;
1532 if (MPFR_IS_NEG (p))
1537 np->ip_size = MPFR_INF_STRING_LENGTH;
1538 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1539 strcpy (str, MPFR_INF_STRING_UC);
1540 np->ip_ptr = register_string (np->sl, str);
1544 np->ip_size = MPFR_INF_STRING_LENGTH;
1545 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1546 strcpy (str, MPFR_INF_STRING_LC);
1547 np->ip_ptr = register_string (np->sl, str);
1553 /* note: for 'g' spec, zero is always displayed with 'f'-style with
1554 precision spec.prec - 1 and the trailing zeros are removed unless
1555 the flag '#' is used. */
1556 if (MPFR_IS_NEG (p))
1559 else if (spec.showsign || spec.space)
1560 np->sign = spec.showsign ? '+' : ' ';
1562 if (spec.spec == 'a' || spec.spec == 'A')
1565 np->prefix_size = 2;
1566 str = (char *) (*__gmp_allocate_func) (1 + np->prefix_size);
1568 str[1] = uppercase ? 'X' : 'x';
1570 np->prefix_ptr = register_string (np->sl, str);
1575 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1578 np->ip_ptr = register_string (np->sl, str);
1581 && ((spec.spec != 'g' && spec.spec != 'G') || spec.alt))
1582 /* fractional part */
1584 np->point = MPFR_DECIMAL_POINT;
1585 np->fp_trailing_zeros = (spec.spec == 'g' && spec.spec == 'G') ?
1586 spec.prec - 1 : spec.prec;
1589 np->point = MPFR_DECIMAL_POINT;
1591 if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b'
1592 || spec.spec == 'e' || spec.spec == 'E')
1595 np->exp_size = (spec.spec == 'e' || spec.spec == 'E') ? 4 : 3;
1596 str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
1597 if (spec.spec == 'e' || spec.spec == 'E')
1598 strcpy (str, uppercase ? "E+00" : "e+00");
1600 strcpy (str, uppercase ? "P+0" : "p+0");
1601 np->exp_ptr = register_string (np->sl, str);
1606 /* regular p, p != 0 */
1608 if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b')
1610 if (regular_ab (np, p, spec) == -1)
1613 else if (spec.spec == 'f' || spec.spec == 'F')
1615 if (spec.prec == -1)
1617 if (regular_fg (np, p, spec, NULL) == -1)
1620 else if (spec.spec == 'e' || spec.spec == 'E')
1622 if (regular_eg (np, p, spec, NULL) == -1)
1628 /* Use the C99 rules:
1629 if T > X >= -4 then the conversion is with style 'f'/'F' and
1631 otherwise, the conversion is with style 'e'/'E' and
1633 where T is the threshold computed below and X is the exponent
1634 that would be displayed with style 'e' and precision T-1. */
1637 struct decimal_info dec_info;
1639 threshold = (spec.prec < 0) ? 6 : (spec.prec == 0) ? 1 : spec.prec;
1640 dec_info.str = mpfr_get_str (NULL, &dec_info.exp, 10, threshold,
1642 register_string (np->sl, dec_info.str);
1643 /* mpfr_get_str corresponds to a significand between 0.1 and 1,
1644 whereas here we want a significand between 1 and 10. */
1645 x = dec_info.exp - 1;
1647 if (threshold > x && x >= -4)
1649 /* the conversion is with style 'f' */
1650 spec.prec = threshold - x - 1;
1652 if (regular_fg (np, p, spec, &dec_info) == -1)
1657 spec.prec = threshold - 1;
1659 if (regular_eg (np, p, spec, &dec_info) == -1)
1665 /* compute the number of characters to be written verifying it is not too
1667 total = np->sign ? 1 : 0;
1668 total += np->prefix_size;
1669 total += np->ip_size;
1670 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1672 total += np->ip_trailing_zeros;
1673 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1675 if (np->thousands_sep)
1676 /* ' flag, style f and the thousands separator in current locale is not
1677 reduced to the null character */
1678 total += (np->ip_size + np->ip_trailing_zeros) / 3;
1679 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1683 total += np->fp_leading_zeros;
1684 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1686 total += np->fp_size;
1687 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1689 total += np->fp_trailing_zeros;
1690 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1692 total += np->exp_size;
1693 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1696 if (spec.width > total)
1697 /* pad with spaces or zeros depending on np->pad_type */
1699 np->pad_size = spec.width - total;
1700 total += np->pad_size; /* here total == spec.width,
1701 so 0 < total < INT_MAX */
1707 clear_string_list (np->sl);
1708 np->prefix_ptr = NULL;
1715 /* sprnt_fp prints a mpfr_t according to spec.spec specification.
1717 return the size of the string (not counting the terminating '\0')
1718 return -1 if the built string is too long (i.e. has more than
1719 INT_MAX characters). */
1721 sprnt_fp (struct string_buffer *buf, mpfr_srcptr p,
1722 const struct printf_spec spec)
1725 struct number_parts np;
1727 length = partition_number (&np, p, spec);
1731 /* right justification padding with left spaces */
1732 if (np.pad_type == LEFT && np.pad_size != 0)
1733 buffer_pad (buf, ' ', np.pad_size);
1735 /* sign character (may be '-', '+', or ' ') */
1737 buffer_pad (buf, np.sign, 1);
1741 buffer_cat (buf, np.prefix_ptr, np.prefix_size);
1743 /* right justification padding with leading zeros */
1744 if (np.pad_type == LEADING_ZEROS && np.pad_size != 0)
1745 buffer_pad (buf, '0', np.pad_size);
1747 /* integral part (may also be "nan" or "inf") */
1748 MPFR_ASSERTN (np.ip_ptr != NULL); /* never empty */
1749 if (MPFR_UNLIKELY (np.thousands_sep))
1750 buffer_sandwich (buf, np.ip_ptr, np.ip_size, np.ip_trailing_zeros,
1754 buffer_cat (buf, np.ip_ptr, np.ip_size);
1756 /* trailing zeros in integral part */
1757 if (np.ip_trailing_zeros != 0)
1758 buffer_pad (buf, '0', np.ip_trailing_zeros);
1763 buffer_pad (buf, np.point, 1);
1765 /* leading zeros in fractional part */
1766 if (np.fp_leading_zeros != 0)
1767 buffer_pad (buf, '0', np.fp_leading_zeros);
1769 /* significant digits in fractional part */
1771 buffer_cat (buf, np.fp_ptr, np.fp_size);
1773 /* trailing zeros in fractional part */
1774 if (np.fp_trailing_zeros != 0)
1775 buffer_pad (buf, '0', np.fp_trailing_zeros);
1779 buffer_cat (buf, np.exp_ptr, np.exp_size);
1781 /* left justication padding with right spaces */
1782 if (np.pad_type == RIGHT && np.pad_size != 0)
1783 buffer_pad (buf, ' ', np.pad_size);
1785 clear_string_list (np.sl);
1790 mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
1792 struct string_buffer buf;
1795 /* informations on the conversion specification filled by the parser */
1796 struct printf_spec spec;
1797 /* flag raised when previous part of fmt need to be processed by
1800 /* beginning and end of the previous unprocessed part of fmt */
1801 const char *start, *end;
1802 /* pointer to arguments for gmp_vasprintf */
1805 MPFR_SAVE_EXPO_DECL (expo);
1806 MPFR_SAVE_EXPO_MARK (expo);
1809 buffer_init (&buf, 4096);
1815 /* Look for the next format specification */
1816 while ((*fmt) && (*fmt != '%'))
1823 /* %%: go one step further otherwise the second '%' would be
1824 considered as a new conversion specification introducing
1834 /* format string analysis */
1835 specinfo_init (&spec);
1836 fmt = parse_flags (fmt, &spec);
1838 READ_INT (ap, fmt, spec, width, width_analysis);
1843 spec.width = -spec.width;
1844 MPFR_ASSERTN (spec.width < INT_MAX);
1848 const char *f = ++fmt;
1849 READ_INT (ap, fmt, spec, prec, prec_analysis);
1857 fmt = parse_arg_type (fmt, &spec);
1858 if (spec.arg_type == UNSUPPORTED)
1859 /* the current architecture doesn't support this type */
1863 else if (spec.arg_type == MPFR_ARG)
1871 spec.rnd_mode = (mpfr_rnd_t) va_arg (ap, int);
1875 spec.rnd_mode = MPFR_RNDD;
1879 spec.rnd_mode = MPFR_RNDU;
1883 spec.rnd_mode = MPFR_RNDA;
1887 spec.rnd_mode = MPFR_RNDZ;
1892 spec.rnd_mode = MPFR_RNDN;
1897 if (!specinfo_is_valid (spec))
1903 /* Format processing */
1904 if (spec.spec == '\0')
1905 /* end of the format string */
1907 else if (spec.spec == 'n')
1908 /* put the number of characters written so far in the location pointed
1909 by the next va_list argument; the types of pointer accepted are the
1910 same as in GMP (except unsupported quad_t) plus pointer to a mpfr_t
1911 so as to be able to accept the same format strings. */
1916 p = va_arg (ap, void *);
1917 FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
1920 nchar = buf.curr - buf.start;
1922 switch (spec.arg_type)
1925 *(char *) p = (char) nchar;
1928 *(short *) p = (short) nchar;
1931 *(long *) p = (long) nchar;
1933 #ifdef HAVE_LONG_LONG
1935 *(long long *) p = (long long) nchar;
1938 #ifdef _MPFR_H_HAVE_INTMAX_T
1940 *(intmax_t *) p = (intmax_t) nchar;
1944 *(size_t *) p = nchar;
1947 *(ptrdiff_t *) p = (ptrdiff_t) nchar;
1950 mpf_set_ui ((mpf_ptr) p, (unsigned long) nchar);
1953 mpq_set_ui ((mpq_ptr) p, (unsigned long) nchar, 1L);
1956 *(mp_limb_t *) p = (mp_limb_t) nchar;
1958 case MP_LIMB_ARRAY_ARG:
1960 mp_limb_t *q = (mp_limb_t *) p;
1962 n = va_arg (ap, mp_size_t);
1968 /* we assume here that mp_limb_t is wider than int */
1969 *q = (mp_limb_t) nchar;
1978 mpz_set_ui ((mpz_ptr) p, (unsigned long) nchar);
1982 mpfr_set_ui ((mpfr_ptr) p, (unsigned long) nchar,
1987 *(int *) p = (int) nchar;
1989 va_copy (ap2, ap); /* after the switch, due to MP_LIMB_ARRAY_ARG
1992 else if (spec.arg_type == MPFR_PREC_ARG)
1993 /* output mpfr_prec_t variable */
1996 char format[MPFR_PREC_FORMAT_SIZE + 6]; /* see examples below */
1999 prec = va_arg (ap, mpfr_prec_t);
2001 FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2006 /* construct format string, like "%*.*hu" "%*.*u" or "%*.*lu" */
2012 strcat (format, MPFR_PREC_FORMAT_TYPE);
2013 format[4 + MPFR_PREC_FORMAT_SIZE] = spec.spec;
2014 format[5 + MPFR_PREC_FORMAT_SIZE] = '\0';
2015 length = gmp_asprintf (&s, format, spec.width, spec.prec, prec);
2016 if (buf.size <= INT_MAX - length)
2018 buffer_cat (&buf, s, length);
2024 goto overflow_error;
2027 else if (spec.arg_type == MPFR_ARG)
2028 /* output a mpfr_t variable */
2032 p = va_arg (ap, mpfr_srcptr);
2034 FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2050 if (sprnt_fp (&buf, p, spec) < 0)
2051 goto overflow_error;
2055 /* unsupported specifier */
2060 /* gmp_printf specification, step forward in the va_list */
2062 CONSUME_VA_ARG (spec, ap);
2068 FLUSH (xgmp_fmt_flag, start, fmt, ap2, &buf);
2071 nbchar = buf.curr - buf.start;
2072 MPFR_ASSERTD (nbchar == strlen (buf.start));
2074 (char *) (*__gmp_reallocate_func) (buf.start, buf.size, nbchar + 1);
2075 buf.size = nbchar + 1; /* update needed for __gmp_free_func below when
2076 nbchar is too large (overflow_error) */
2079 /* If nbchar is larger than INT_MAX, the ISO C99 standard is silent, but
2080 POSIX says concerning the snprintf() function:
2081 "[EOVERFLOW] The value of n is greater than {INT_MAX} or the
2082 number of bytes needed to hold the output excluding the
2083 terminating null is greater than {INT_MAX}." See:
2084 http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
2085 But it doesn't say anything concerning the other printf-like functions.
2086 A defect report has been submitted to austin-review-l (item 2532).
2087 So, for the time being, we return a negative value and set the erange
2088 flag, and set errno to EOVERFLOW in POSIX system. */
2089 if (nbchar <= INT_MAX)
2091 MPFR_SAVE_EXPO_FREE (expo);
2096 MPFR_SAVE_EXPO_UPDATE_FLAGS(expo, MPFR_FLAGS_ERANGE);
2102 MPFR_SAVE_EXPO_FREE (expo);
2104 (*__gmp_free_func) (buf.start, buf.size);
2109 #endif /* HAVE_STDARG */