1 /* mpfr_vasprintf -- main function for the printf functions family
2 plus helper macros & functions.
4 Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
5 Contributed by the Arenaire and Cacao 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 2.1 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.LIB. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
22 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 */
56 # include <inttypes.h> /* for intmax_t */
59 # include <stdint.h> /* for WINT_MAX in particular */
63 #define MPFR_NEED_LONGLONG_H
64 #include "mpfr-impl.h"
66 /* Define a length modifier corresponding to mp_prec_t.
67 We use literal string instead of literal character so as to permit future
68 extension to long long int ("ll"). */
69 #if _MPFR_PREC_FORMAT == 1
70 #define MPFR_PREC_FORMAT_TYPE "h"
71 #define MPFR_PREC_FORMAT_SIZE 1
72 #elif _MPFR_PREC_FORMAT == 2
73 #define MPFR_PREC_FORMAT_TYPE ""
74 #define MPFR_PREC_FORMAT_SIZE 0
75 #elif _MPFR_PREC_FORMAT == 3
76 #define MPFR_PREC_FORMAT_TYPE "l"
77 #define MPFR_PREC_FORMAT_SIZE 1
79 #error "mpfr_prec_t size not supported"
82 #if (__GMP_MP_SIZE_T_INT == 1)
83 #define MPFR_EXP_FORMAT_SPEC "i"
84 #elif (__GMP_MP_SIZE_T_INT == 0)
85 #define MPFR_EXP_FORMAT_SPEC "li"
87 #error "mp_exp_t size not supported"
90 /* Output for special values defined in the C99 standard */
91 #define MPFR_NAN_STRING_LC "nan"
92 #define MPFR_NAN_STRING_UC "NAN"
93 #define MPFR_NAN_STRING_LENGTH 3
94 #define MPFR_INF_STRING_LC "inf"
95 #define MPFR_INF_STRING_UC "INF"
96 #define MPFR_INF_STRING_LENGTH 3
98 /* The implicit \0 is useless, but we do not write num_to_text[16]
99 otherwise g++ complains. */
100 static const char num_to_text[] = "0123456789abcdef";
102 /* some macro and functions for parsing format string */
104 /* Read an integer; saturate to INT_MAX. */
105 #define READ_INT(ap, format, specinfo, field, label_out) \
122 specinfo.field = (specinfo.field <= INT_MAX / 10) ? \
123 specinfo.field * 10 : INT_MAX; \
124 _i = *(format) - '0'; \
125 MPFR_ASSERTN (_i >= 0 && _i <= 9); \
126 specinfo.field = (specinfo.field <= INT_MAX - _i) ? \
127 specinfo.field + _i : INT_MAX; \
131 specinfo.field = va_arg ((ap), int); \
139 /* arg_t contains all the types described by the 'type' field of the
162 /* Each conversion specification of the format string will be translated in a
163 printf_spec structure by the parser.
164 This structure is adapted from the GNU libc one. */
167 unsigned int alt:1; /* # flag */
168 unsigned int space:1; /* Space flag */
169 unsigned int left:1; /* - flag */
170 unsigned int showsign:1; /* + flag */
171 unsigned int group:1; /* ' flag */
173 int width; /* Width */
174 int prec; /* Precision */
176 enum arg_t arg_type; /* Type of argument */
177 mp_rnd_t rnd_mode; /* Rounding mode */
178 char spec; /* Conversion specifier */
180 char pad; /* Padding character */
184 specinfo_init (struct printf_spec *specinfo)
189 specinfo->showsign = 0;
193 specinfo->arg_type = NONE;
194 specinfo->rnd_mode = GMP_RNDN;
195 specinfo->spec = '\0';
199 #define FLOATING_POINT_ARG_TYPE(at) \
200 ((at) == MPFR_ARG || (at) == MPF_ARG || (at) == LONG_DOUBLE_ARG)
202 #define INTEGER_LIKE_ARG_TYPE(at) \
203 ((at) == SHORT_ARG || (at) == LONG_ARG || (at) == LONG_LONG_ARG \
204 || (at) == INTMAX_ARG || (at) == MPFR_PREC_ARG || (at) == MPZ_ARG \
205 || (at) == MPQ_ARG || (at) == MP_LIMB_ARG || (at) == MP_LIMB_ARRAY_ARG \
206 || (at) == CHAR_ARG || (at) == SIZE_ARG || (at) == PTRDIFF_ARG)
209 specinfo_is_valid (struct printf_spec spec)
220 return (spec.arg_type == NONE
221 || FLOATING_POINT_ARG_TYPE (spec.arg_type));
224 return spec.arg_type == MPFR_ARG;
229 return (spec.arg_type == NONE
230 || INTEGER_LIKE_ARG_TYPE (spec.arg_type));
234 return (spec.arg_type == NONE || spec.arg_type == LONG_ARG);
237 return spec.arg_type == NONE;
245 parse_flags (const char *format, struct printf_spec *specinfo)
260 specinfo->showsign = 1;
272 /* Single UNIX Specification for thousand separator */
284 parse_arg_type (const char *format, struct printf_spec *specinfo)
291 if (*++format == 'h')
295 specinfo->arg_type = CHAR_ARG;
298 specinfo->arg_type = UNSUPPORTED;
301 specinfo->arg_type = SHORT_ARG;
304 if (*++format == 'l')
307 #if defined (HAVE_LONG_LONG) && !defined(NPRINTF_LL)
308 specinfo->arg_type = LONG_LONG_ARG;
310 specinfo->arg_type = UNSUPPORTED;
316 specinfo->arg_type = LONG_ARG;
321 #if defined(_MPFR_H_HAVE_INTMAX_T) && !defined(NPRINTF_J)
322 specinfo->arg_type = INTMAX_ARG;
324 specinfo->arg_type = UNSUPPORTED;
329 specinfo->arg_type = SIZE_ARG;
334 specinfo->arg_type = PTRDIFF_ARG;
336 specinfo->arg_type = UNSUPPORTED;
342 specinfo->arg_type = LONG_DOUBLE_ARG;
344 specinfo->arg_type = UNSUPPORTED;
349 specinfo->arg_type = MPF_ARG;
353 specinfo->arg_type = MPQ_ARG;
357 /* The 'M' specifier was added in gmp 4.2.0 */
358 specinfo->arg_type = MP_LIMB_ARG;
362 specinfo->arg_type = MP_LIMB_ARRAY_ARG;
366 specinfo->arg_type = MPZ_ARG;
369 /* mpfr specific specifiers */
372 specinfo->arg_type = MPFR_PREC_ARG;
376 specinfo->arg_type = MPFR_ARG;
382 /* some macros and functions filling the buffer */
384 /* CONSUME_VA_ARG removes from va_list AP the type expected by SPECINFO */
386 /* With a C++ compiler wchar_t and enumeration in va_list are converted to
387 integer type : int, unsigned int, long or unsigned long (unfortunately,
388 this is implementation dependant).
389 We follow gmp which assumes in print/doprnt.c that wchar_t is converted
390 to int (because wchar_t <= int).
391 For wint_t, we assume that the case WINT_MAX < INT_MAX yields an
392 integer promotion. */
394 #if defined(WINT_MAX) && WINT_MAX < INT_MAX
395 typedef int mpfr_va_wint; /* integer promotion */
397 typedef wint_t mpfr_va_wint;
399 #define CASE_LONG_ARG(specinfo, ap) \
401 if (((specinfo).spec == 'd') || ((specinfo).spec == 'i') \
402 || ((specinfo).spec == 'o') || ((specinfo).spec == 'u') \
403 || ((specinfo).spec == 'x') || ((specinfo).spec == 'X')) \
404 (void) va_arg ((ap), long); \
405 else if ((specinfo).spec == 'c') \
406 (void) va_arg ((ap), mpfr_va_wint); \
407 else if ((specinfo).spec == 's') \
408 (void) va_arg ((ap), int); /* we assume integer promotion */ \
411 #define CASE_LONG_ARG(specinfo, ap) \
413 (void) va_arg ((ap), long); \
417 #if defined(_MPFR_H_HAVE_INTMAX_T)
418 #define CASE_INTMAX_ARG(specinfo, ap) \
420 (void) va_arg ((ap), intmax_t); \
423 #define CASE_INTMAX_ARG(specinfo, ap)
426 #ifdef HAVE_LONG_LONG
427 #define CASE_LONG_LONG_ARG(specinfo, ap) \
428 case LONG_LONG_ARG: \
429 (void) va_arg ((ap), long long); \
432 #define CASE_LONG_LONG_ARG(specinfo, ap)
435 #define CONSUME_VA_ARG(specinfo, ap) \
437 switch ((specinfo).arg_type) \
441 (void) va_arg ((ap), int); \
443 CASE_LONG_ARG (specinfo, ap) \
444 CASE_LONG_LONG_ARG (specinfo, ap) \
445 CASE_INTMAX_ARG (specinfo, ap) \
447 (void) va_arg ((ap), size_t); \
450 (void) va_arg ((ap), ptrdiff_t); \
452 case LONG_DOUBLE_ARG: \
453 (void) va_arg ((ap), long double); \
456 (void) va_arg ((ap), mpf_srcptr); \
459 (void) va_arg ((ap), mpq_srcptr); \
462 (void) va_arg ((ap), mp_limb_t); \
464 case MP_LIMB_ARRAY_ARG: \
465 (void) va_arg ((ap), mp_ptr); \
466 (void) va_arg ((ap), mp_size_t); \
469 (void) va_arg ((ap), mpz_srcptr); \
472 switch ((specinfo).spec) \
481 (void) va_arg ((ap), int); \
491 (void) va_arg ((ap), double); \
494 (void) va_arg ((ap), char *); \
497 (void) va_arg ((ap), void *); \
502 /* process the format part which does not deal with mpfr types,
503 jump to external label 'error' if gmp_asprintf return -1. */
504 #define FLUSH(flag, start, end, ap, buf_ptr) \
506 const size_t n = (end) - (start); \
508 /* previous specifiers are understood by gmp_printf */ \
510 MPFR_TMP_DECL (marker); \
512 MPFR_TMP_MARK (marker); \
513 fmt_copy = (char*) MPFR_TMP_ALLOC ((n + 1) * sizeof(char)); \
514 strncpy (fmt_copy, (start), n); \
515 fmt_copy[n] = '\0'; \
516 if (sprntf_gmp ((buf_ptr), (fmt_copy), (ap)) == -1) \
518 MPFR_TMP_FREE (marker); \
522 MPFR_TMP_FREE (marker); \
524 else if ((start) != (end)) \
525 /* no conversion specification, just simple characters */ \
526 buffer_cat ((buf_ptr), (start), n); \
531 char *start; /* beginning of the buffer */
532 char *curr; /* null terminating character */
533 size_t size; /* buffer capacity */
537 buffer_init (struct string_buffer *b, size_t s)
539 b->start = (char *) (*__gmp_allocate_func) (s);
545 /* Increase buffer size by a number of character being the least multiple of
546 4096 greater than LEN+1. */
548 buffer_widen (struct string_buffer *b, size_t len)
550 const size_t pos = b->curr - b->start;
551 const size_t n = sizeof (char) * (0x1000 + (len & ~((size_t) 0xfff)));
552 MPFR_ASSERTD (pos < b->size);
554 MPFR_ASSERTN ((len & ~((size_t) 4095)) <= SIZE_MAX / sizeof (char) - 4096);
555 MPFR_ASSERTN (b->size < SIZE_MAX - n);
558 (char *) (*__gmp_reallocate_func) (b->start, b->size, b->size + n);
560 b->curr = b->start + pos;
562 MPFR_ASSERTD (pos < b->size);
563 MPFR_ASSERTD (*b->curr == '\0');
566 /* Concatenate the LEN first characters of the string S to the buffer B and
567 expand it if needed. */
569 buffer_cat (struct string_buffer *b, const char *s, size_t len)
571 MPFR_ASSERTD (len != 0);
572 MPFR_ASSERTD (len <= strlen (s));
574 if (MPFR_UNLIKELY ((b->curr + len) >= (b->start + b->size)))
575 buffer_widen (b, len);
577 strncat (b->curr, s, len);
580 MPFR_ASSERTD (b->curr < b->start + b->size);
581 MPFR_ASSERTD (*b->curr == '\0');
584 /* Add N characters C to the end of buffer B */
586 buffer_pad (struct string_buffer *b, const char c, const size_t n)
588 MPFR_ASSERTD (n != 0);
590 MPFR_ASSERTN (b->size < SIZE_MAX - n - 1);
591 if (MPFR_UNLIKELY ((b->curr + n + 1) > (b->start + b->size)))
597 memset (b->curr, c, n);
601 MPFR_ASSERTD (b->curr < b->start + b->size);
604 /* Form a string by concatenating the first LEN characters of STR to TZ
605 zero(s), insert into one character C each 3 characters starting from end
606 to begining and concatenate the result to the buffer B. */
608 buffer_sandwich (struct string_buffer *b, char *str, size_t len,
609 const size_t tz, const char c)
611 const size_t step = 3;
612 const size_t size = len + tz;
613 const size_t r = size % step == 0 ? step : size % step;
614 const size_t q = size % step == 0 ? size / step - 1 : size / step;
617 MPFR_ASSERTD (size != 0);
620 buffer_cat (b, str, len);
621 buffer_pad (b, '0', tz);
625 MPFR_ASSERTN (b->size < SIZE_MAX - size - 1 - q);
626 MPFR_ASSERTD (len <= strlen (str));
627 if (MPFR_UNLIKELY ((b->curr + size + 1 + q) > (b->start + b->size)))
628 buffer_widen (b, size + q);
630 /* first R significant digits */
631 memcpy (b->curr, str, r);
636 /* blocks of thousands. Warning: STR might end in the middle of a block */
637 for (i = 0; i < q; ++i)
640 if (MPFR_LIKELY (len > 0))
642 if (MPFR_LIKELY (len >= step))
643 /* step significant digits */
645 memcpy (b->curr, str, step);
649 /* last digits in STR, fill up thousand block with zeros */
651 memcpy (b->curr, str, len);
652 memset (b->curr + len, '0', step - len);
658 memset (b->curr, '0', step);
666 MPFR_ASSERTD (b->curr < b->start + b->size);
669 /* let gmp_xprintf process the part it can understand */
671 sprntf_gmp (struct string_buffer *b, const char *fmt, va_list ap)
676 length = gmp_vasprintf (&s, fmt, ap);
678 buffer_cat (b, s, length);
684 /* Helper struct and functions for temporary strings management */
685 /* struct for easy string clearing */
689 struct string_list *next; /* NULL in last node */
694 init_string_list (struct string_list *sl)
700 /* clear all strings in the list */
702 clear_string_list (struct string_list *sl)
704 struct string_list *n;
709 mpfr_free_str (sl->string);
711 (*__gmp_free_func) (sl, sizeof(struct string_list));
716 /* add a string in the list */
718 register_string (struct string_list *sl, char *new_string)
720 /* look for the last node */
724 sl->next = (struct string_list*)
725 (*__gmp_allocate_func) (sizeof (struct string_list));
729 return sl->string = new_string;
732 /* padding type: where are the padding characters */
735 LEFT, /* spaces in left hand side for right justification */
736 LEADING_ZEROS, /* padding with '0' characters in integral part */
737 RIGHT /* spaces in right hand side for left justification */
740 /* number_parts details how much characters are needed in each part of a float
744 enum pad_t pad_type; /* Padding type */
745 size_t pad_size; /* Number of padding characters */
747 char sign; /* Sign character */
749 char *prefix_ptr; /* Pointer to prefix part */
750 size_t prefix_size; /* Number of characters in *prefix_ptr */
752 char thousands_sep; /* Thousands separator (only with style 'f') */
754 char *ip_ptr; /* Pointer to integral part characters*/
755 size_t ip_size; /* Number of digits in *ip_ptr */
756 int ip_trailing_zeros; /* Number of additional null digits in integral
759 char point; /* Decimal point character */
761 int fp_leading_zeros; /* Number of additional leading zeros in fractional
763 char *fp_ptr; /* Pointer to fractional part characters */
764 size_t fp_size; /* Number of digits in *fp_ptr */
765 int fp_trailing_zeros; /* Number of additional trailing zeros in fractional
768 char *exp_ptr; /* Pointer to exponent part */
769 size_t exp_size; /* Number of characters in *exp_ptr */
771 struct string_list *sl; /* List of string buffers in use: we need such a
772 mechanism because fp_ptr may point into the same
776 /* For a real non zero number x, what is the base exponent f when rounding x
777 with rounding mode r to r(x) = m*b^f, where m is a digit and 1 <= m < b ?
778 Return non zero value if x is rounded up to b^f, return zero otherwise */
780 next_base_power_p (mpfr_srcptr x, int base, mpfr_rnd_t rnd)
786 MPFR_ASSERTD (MPFR_IS_PURE_FP (x));
787 MPFR_ASSERTD (base == 2 || base == 16);
789 /* Warning: the decimal point is AFTER THE FIRST DIGIT in this output
791 nbits = base == 2 ? 1 : 4;
794 || (rnd == GMP_RNDD && MPFR_IS_POS (x))
795 || (rnd == GMP_RNDU && MPFR_IS_NEG (x))
796 || MPFR_PREC (x) <= nbits)
797 /* no rounding when printing x with 1 digit */
800 xm = MPFR_MANT (x) [MPFR_LIMB_SIZE (x) - 1];
801 pm = MPFR_LIMB_MASK (BITS_PER_MP_LIMB - nbits);
802 if ((xm & ~pm) ^ ~pm)
803 /* do no round up if some of the nbits first bits are 0s. */
807 /* mask for rounding bit */
808 pm = (MPFR_LIMB_ONE << (BITS_PER_MP_LIMB - nbits - 1));
810 /* round up if some remaining bits are 1 */
811 /* warning: the return value must be an int */
812 return xm & pm ? 1 : 0;
815 /* For a real non zero number x, what is the exponent f when rounding x with
816 rounding mode r to r(x) = m*10^f, where m has p+1 digits and 1 <= m < 10 ?
818 Return +1 if x is rounded up to 10^f, return zero otherwise.
819 If e is not NULL, *e is set to f. */
821 round_to_10_power (mp_exp_t *e, mpfr_srcptr x, mp_prec_t p, mpfr_rnd_t r)
827 int roundup = -1; /* boolean (-1: not set) */
829 MPFR_ZIV_DECL (loop);
832 MPFR_ALIAS (y, x, 1, MPFR_EXP(x));
834 /* we want f = floor(log(|x|)/log(10)) exactly.
835 we have |f| >= |Exp(x)|/3,
836 then m = ceil(log(uexp/3)/log(2)) > log(f)/log(2)
837 is a sufficient precision for f. */
838 ex = mpfr_get_exp (x);
839 uexp = SAFE_ABS (mpfr_uexp_t, ex) / 3;
849 mpfr_log10 (f, y, GMP_RNDD);
852 /* In most cases, the output exponent is f. */
854 *e = (mp_exp_t)mpfr_get_si (f, GMP_RNDD);
857 || (MPFR_IS_POS (x) && r == GMP_RNDD)
858 || (MPFR_IS_NEG (x) && r == GMP_RNDU))
859 /* If rounding toward zero, the exponent is f */
865 /* Is |x| less than 10^(f+1) - 10^(f-p)? */
868 int inex_u, inex_v, inex_w;
869 mp_exp_t exp_u, exp_v, exp_w;
872 m += MPFR_INT_CEIL_LOG2 (m);
876 MPFR_ZIV_INIT (loop, m);
879 mpfr_set_prec (u, m);
880 mpfr_set_prec (v, m);
882 /* u = o(10^(f+1)) rounding toward -infinity
884 error(u) = 0 if inex_u = 0 */
885 mpfr_add_ui (u, f, 1, GMP_RNDN);
886 inex_u = mpfr_ui_pow (u, 10, u, GMP_RNDD);
887 exp_u = MPFR_EXP (u);
889 /* if r = rounding to nearest
890 v = o(0.5 * 10^(f-p)) rounding toward +infinity
892 v = o(10^(f-p)) rounding toward +infinity
895 error(v) = 0 if inex_v = 0 */
896 mpfr_sub_ui (v, f, p, GMP_RNDN);
897 inex_v = mpfr_ui_pow (v, 10, v, GMP_RNDU);
899 mpfr_div_2ui (v, v, 1, GMP_RNDN);
900 exp_v = MPFR_EXP (v);
902 /* w = o(u-v) rounding toward -infinity
903 w is an approximation of 10^(f+1) - v with
904 error(w) < 1 ulp(w) + error(u) + error(v)
905 error(w) = 0 iff inex_u = inex_v = inex_diff = 0 */
906 inex_w = mpfr_sub (u, u, v, GMP_RNDD);
907 exp_w = MPFR_EXP (u);
909 cmp = mpfr_cmp (y, u);
912 /* |x| < u <= 10^(f+1) - v, the exponent is f */
917 else if (cmp == 0 && inex_u == 0 && inex_v == 0 && inex_w == 0)
918 /* |x| = u = 10^(f+1) - v, the exponent is f+1 */
927 /* compare |x| with w + error(w) */
929 mpfr_set_ui_2exp (v, 1, exp_u - m, GMP_RNDU);
931 mpfr_set_ui (v, 0, GMP_RNDN);
933 mpfr_set_ui_2exp (v, 1, exp_v - m, GMP_RNDU);
935 mpfr_set_ui_2exp (v, 1, exp_w - m, GMP_RNDU);
937 mpfr_add (u, u, v, GMP_RNDU);
938 if (mpfr_cmp (y, u) >= 0)
941 *e = (mp_exp_t)mpfr_get_si (f, GMP_RNDD) + 1;
947 MPFR_ZIV_NEXT (loop, m);
949 MPFR_ZIV_FREE (loop);
954 MPFR_ASSERTD (roundup != -1);
959 /* Determine the different parts of the string representation of the regular
960 number P when SPEC.SPEC is 'a', 'A', or 'b'.
962 return -1 if some field > INT_MAX */
964 regular_ab (struct number_parts *np, mpfr_srcptr p,
965 const struct printf_spec spec)
972 uppercase = spec.spec == 'A';
977 else if (spec.showsign || spec.space)
978 np->sign = spec.showsign ? '+' : ' ';
980 if (spec.spec == 'a' || spec.spec == 'A')
984 str = (char *) (*__gmp_allocate_func) (1 + np->prefix_size);
986 str[1] = uppercase ? 'X' : 'x';
988 np->prefix_ptr = register_string (np->sl, str);
993 base = (spec.spec == 'b') ? 2 : 16;
999 /* Number of significant digits:
1000 - if no given precision, let mpfr_get_str determine it;
1001 - if a non-zero precision is specified, then one digit before decimal
1002 point plus SPEC.PREC after it. */
1003 nsd = spec.prec < 0 ? 0 : spec.prec + np->ip_size;
1004 str = mpfr_get_str (0, &exp, base, nsd, p, spec.rnd_mode);
1005 register_string (np->sl, str);
1006 np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign if any */
1009 /* EXP is the exponent for radix sixteen with decimal point BEFORE the
1010 first digit, we want the exponent for radix two and the decimal
1011 point AFTER the first digit. */
1013 MPFR_ASSERTN (exp > MPFR_EMIN_MIN /4); /* possible overflow */
1014 exp = (exp - 1) * 4;
1017 /* EXP is the exponent for decimal point BEFORE the first digit, we
1018 want the exponent for decimal point AFTER the first digit. */
1020 MPFR_ASSERTN (exp > MPFR_EMIN_MIN); /* possible overflow */
1024 else if (next_base_power_p (p, base, spec.rnd_mode))
1026 str = (char *)(*__gmp_allocate_func) (2);
1029 np->ip_ptr = register_string (np->sl, str);
1031 exp = MPFR_GET_EXP (p);
1035 str = (char *)(*__gmp_allocate_func) (2);
1038 np->ip_ptr = register_string (np->sl, str);
1040 exp = MPFR_GET_EXP (p) - 1;
1045 mp_limb_t msl = MPFR_MANT (p)[MPFR_LIMB_SIZE (p) - 1];
1046 int rnd_bit = BITS_PER_MP_LIMB - 5;
1048 /* pick up the 4 first bits */
1049 digit = msl >> (rnd_bit+1);
1050 if ((spec.rnd_mode == GMP_RNDU && MPFR_IS_POS (p))
1051 || (spec.rnd_mode == GMP_RNDD && MPFR_IS_NEG (p))
1052 || (spec.rnd_mode == GMP_RNDN
1053 && (msl & (MPFR_LIMB_ONE << rnd_bit))))
1055 MPFR_ASSERTD ((0 <= digit) && (digit <= 15));
1057 str = (char *)(*__gmp_allocate_func) (1 + np->ip_size);
1058 str[0] = num_to_text [digit];
1060 np->ip_ptr = register_string (np->sl, str);
1062 exp = MPFR_GET_EXP (p) - 4;
1066 /* All digits in upper case */
1096 if (spec.spec == 'b' || spec.prec != 0)
1097 /* compute the number of digits in fractional part */
1102 /* the sign has been skipped, skip also the first digit */
1104 str_len = strlen (str);
1105 ptr = str + str_len - 1; /* points to the end of str */
1108 /* remove trailing zeros, if any */
1110 while ((*ptr == '0') && (str_len != 0))
1117 if (str_len > INT_MAX)
1118 /* too many digits in fractional part */
1122 /* there are some non-zero digits in fractional part */
1125 np->fp_size = str_len;
1126 if ((int) str_len < spec.prec)
1127 np->fp_trailing_zeros = spec.prec - str_len;
1132 if ((np->fp_size != 0) || spec.alt)
1133 np->point = MPFR_DECIMAL_POINT;
1135 /* the exponent part contains the character 'p', or 'P' plus the sign
1136 character plus at least one digit and only as many more digits as
1137 necessary to represent the exponent.
1138 We assume that |EXP| < 10^INT_MAX. */
1141 mp_exp_unsigned_t x;
1143 x = SAFE_ABS (mp_exp_unsigned_t, exp);
1150 str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
1151 np->exp_ptr = register_string (np->sl, str);
1153 char exp_fmt[8]; /* contains at most 7 characters like in "p%+.1i",
1156 exp_fmt[0] = uppercase ? 'P' : 'p';
1158 strcat (exp_fmt, "%+.1" MPFR_EXP_FORMAT_SPEC);
1160 if (sprintf (str, exp_fmt, exp) < 0)
1167 /* Determine the different parts of the string representation of the regular
1168 number P when SPEC.SPEC is 'e', 'E', 'g', or 'G'.
1170 return -1 if some field > INT_MAX */
1172 regular_eg (struct number_parts *np, mpfr_srcptr p,
1173 const struct printf_spec spec)
1178 const int uppercase = spec.spec == 'E' || spec.spec == 'G';
1179 const int spec_g = spec.spec == 'g' || spec.spec == 'G';
1180 const int keep_trailing_zeros = (spec_g && spec.alt)
1181 || (!spec_g && (spec.prec > 0));
1184 if (MPFR_IS_NEG (p))
1186 else if (spec.showsign || spec.space)
1187 np->sign = spec.showsign ? '+' : ' ';
1194 /* Number of significant digits:
1195 - if no given precision, then let mpfr_get_str determine it,
1196 - if a precision is specified, then one digit before decimal point
1197 plus SPEC.PREC after it.
1198 We use the fact here that mpfr_get_str allows us to ask for only one
1199 significant digit when the base is not a power of 2. */
1200 nsd = (spec.prec < 0) ? 0 : spec.prec + np->ip_size;
1201 str = mpfr_get_str (0, &exp, 10, nsd, p, spec.rnd_mode);
1203 register_string (np->sl, str);
1204 np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign if any */
1207 /* compute the number of digits in fractional part */
1212 /* the sign has been skipped, skip also the first digit */
1214 str_len = strlen (str);
1215 ptr = str + str_len - 1; /* points to the end of str */
1217 if (!keep_trailing_zeros)
1218 /* remove trailing zeros, if any */
1220 while ((*ptr == '0') && (str_len != 0))
1227 if (str_len > INT_MAX)
1228 /* too many digits in fractional part */
1232 /* there are some non-zero digits in fractional part */
1235 np->fp_size = str_len;
1236 if ((!spec_g || spec.alt) && (spec.prec > 0)
1237 && ((int)str_len < spec.prec))
1238 /* add missing trailing zeros */
1239 np->fp_trailing_zeros = spec.prec - str_len;
1244 if (np->fp_size != 0 || spec.alt)
1245 np->point = MPFR_DECIMAL_POINT;
1247 /* EXP is the exponent for decimal point BEFORE the first digit, we want
1248 the exponent for decimal point AFTER the first digit.
1249 Here, no possible overflow because exp < MPFR_EXP (p) / 3 */
1252 /* the exponent part contains the character 'e', or 'E' plus the sign
1253 character plus at least two digits and only as many more digits as
1254 necessary to represent the exponent.
1255 We assume that |EXP| < 10^INT_MAX. */
1258 mp_exp_unsigned_t x;
1260 x = SAFE_ABS (mp_exp_unsigned_t, exp);
1267 if (np->exp_size < 4)
1270 str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
1271 np->exp_ptr = register_string (np->sl, str);
1274 char exp_fmt[8]; /* e.g. "e%+.2i", or "E%+.2li" */
1276 exp_fmt[0] = uppercase ? 'E' : 'e';
1278 strcat (exp_fmt, "%+.2" MPFR_EXP_FORMAT_SPEC);
1280 if (sprintf (str, exp_fmt, exp) < 0)
1287 /* Determine the different parts of the string representation of the regular
1288 number P when SPEC.SPEC is 'f', 'F', 'g', or 'G'.
1290 return -1 if some field of number_parts is greater than INT_MAX */
1292 regular_fg (struct number_parts *np, mpfr_srcptr p,
1293 const struct printf_spec spec)
1297 const int spec_g = (spec.spec == 'g' || spec.spec == 'G');
1298 const int keep_trailing_zeros = spec_g && spec.alt;
1300 /* WARNING: an empty precision field is forbidden (it means precision = 6
1301 and it should have been changed to 6 before the function call) */
1302 MPFR_ASSERTD (spec.prec >= 0);
1305 if (MPFR_IS_NEG (p))
1307 else if (spec.showsign || spec.space)
1308 np->sign = spec.showsign ? '+' : ' ';
1310 if (MPFR_GET_EXP (p) <= 0)
1313 /* Most of the time, integral part is 0 */
1315 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1318 np->ip_ptr = register_string (np->sl, str);
1321 /* only two possibilities: either 1 or 0. */
1325 MPFR_ALIAS (y, p, 1, MPFR_EXP (p));
1327 if ((spec.rnd_mode == GMP_RNDD && MPFR_IS_NEG (p))
1328 || (spec.rnd_mode == GMP_RNDU && MPFR_IS_POS (p))
1329 || (spec.rnd_mode == GMP_RNDN && mpfr_cmp_d (y, 0.5) > 0))
1330 /* rounded up to 1: one digit '1' in integral part.
1331 note that 0.5 is rounded to 0 with RNDN (round ties to even) */
1332 np->ip_ptr[0] = '1';
1336 /* exp = position of the most significant decimal digit. */
1337 round_to_10_power (&exp, p, 0, GMP_RNDZ);
1338 MPFR_ASSERTD (exp < 0);
1340 if (exp < -spec.prec)
1341 /* only the last digit may be non zero */
1344 switch (spec.rnd_mode)
1347 round_away = MPFR_IS_NEG (p);
1350 round_away = MPFR_IS_POS (p);
1354 /* compare |p| to y = 0.5*10^(-spec.prec) */
1356 mp_exp_t e = MAX (MPFR_PREC (p), 56);
1357 mpfr_init2 (y, e + 8);
1360 /* find a lower approximation of
1361 0.5*10^(-spec.prec) different from |p| */
1363 mpfr_set_prec (y, e);
1364 mpfr_set_si (y, -spec.prec, GMP_RNDN);
1365 mpfr_exp10 (y, y, GMP_RNDD);
1366 mpfr_div_2ui (y, y, 1, GMP_RNDN);
1367 } while (mpfr_cmpabs (y, p) == 0);
1369 round_away = mpfr_cmpabs (y, p) < 0;
1378 /* round away from zero: the last output digit is '1' */
1380 np->fp_leading_zeros = spec.prec - 1;
1384 (char *) (*__gmp_allocate_func) (1 + np->fp_size);
1387 np->fp_ptr = register_string (np->sl, str);
1390 /* only zeros in fractional part */
1392 MPFR_ASSERTD (!spec_g);
1393 np->fp_leading_zeros = spec.prec;
1397 /* the most significant digits are the last
1398 spec.prec + exp + 1 digits in fractional part */
1402 size_t nsd = spec.prec + exp + 1;
1403 /* WARNING: nsd may equal 1, but here we use the fact that
1404 mpfr_get_str can return one digit with base ten
1405 (undocumented feature, see comments in get_str.c) */
1407 str = mpfr_get_str (NULL, &exp, 10, nsd, p, spec.rnd_mode);
1408 register_string (np->sl, str);
1409 if (MPFR_IS_NEG (p))
1414 MPFR_ASSERTD (str[0] == '1');
1415 np->ip_ptr[0] = '1';
1416 if (!spec_g || spec.alt)
1417 np->fp_leading_zeros = spec.prec;
1423 np->fp_leading_zeros = -exp;
1424 MPFR_ASSERTD (exp <= 0);
1426 str_len = strlen (str); /* the sign has been skipped */
1427 ptr = str + str_len - 1; /* points to the end of str */
1429 if (!keep_trailing_zeros)
1430 /* remove trailing zeros, if any */
1432 while ((*ptr == '0') && str_len)
1439 if (str_len > INT_MAX)
1440 /* too many digits in fractional part */
1443 MPFR_ASSERTD (str_len > 0);
1444 np->fp_size = str_len;
1446 if ((!spec_g || spec.alt)
1448 && (np->fp_leading_zeros + np->fp_size < spec.prec))
1449 /* add missing trailing zeros */
1450 np->fp_trailing_zeros = spec.prec - np->fp_leading_zeros
1456 if (spec.alt || np->fp_leading_zeros != 0 || np->fp_size != 0
1457 || np->fp_trailing_zeros != 0)
1458 np->point = MPFR_DECIMAL_POINT;
1463 size_t nsd; /* Number of significant digits */
1465 /* Determine the position of the most significant decimal digit. */
1466 round_to_10_power (&exp, p, 0, GMP_RNDZ);
1468 MPFR_ASSERTD (exp >= 0);
1470 /* P is too large to print all its integral part digits */
1473 np->ip_size = exp + 1;
1475 nsd = spec.prec + np->ip_size;
1476 str = mpfr_get_str (NULL, &exp, 10, nsd, p, spec.rnd_mode);
1477 register_string (np->sl, str);
1478 np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign */
1481 /* thousands separator in integral part */
1482 np->thousands_sep = MPFR_THOUSANDS_SEPARATOR;
1484 if (nsd == 0 || (spec_g && !spec.alt))
1485 /* compute how much non-zero digits in integral and fractional
1489 str_len = strlen (str); /* note: the sign has been skipped */
1492 /* mpfr_get_str doesn't give the trailing zeros when p is a
1493 multiple of 10 (p integer, so no fractional part) */
1495 np->ip_trailing_zeros = exp - str_len;
1496 np->ip_size = str_len;
1498 np->point = MPFR_DECIMAL_POINT;
1501 /* str may contain some digits which are in fractional part */
1505 ptr = str + str_len - 1; /* points to the end of str */
1506 str_len -= np->ip_size; /* number of digits in fractional
1509 if (!keep_trailing_zeros)
1510 /* remove trailing zeros, if any */
1512 while ((*ptr == '0') && (str_len != 0))
1519 if (str_len > INT_MAX)
1520 /* too many digits in fractional part */
1524 /* some digits in fractional part */
1526 np->point = MPFR_DECIMAL_POINT;
1527 np->fp_ptr = str + np->ip_size;
1528 np->fp_size = str_len;
1533 /* spec.prec digits in fractional part */
1535 if (np->ip_size == exp - 1)
1536 /* the absolute value of the number has been rounded up to a power
1538 Insert an additional zero in integral part and put the rest of
1539 them in fractional part. */
1540 np->ip_trailing_zeros = 1;
1544 MPFR_ASSERTD (np->ip_size + np->ip_trailing_zeros == exp);
1545 MPFR_ASSERTD (np->ip_size + spec.prec == nsd);
1547 np->point = MPFR_DECIMAL_POINT;
1548 np->fp_ptr = str + np->ip_size;
1549 np->fp_size = spec.prec;
1552 np->point = MPFR_DECIMAL_POINT;
1559 /* partition_number determines the different parts of the string
1560 representation of the number p according to the given specification.
1561 partition_number initializes the given structure np, so all previous
1562 information in that variable is lost.
1563 return the total number of characters to be written.
1564 return -1 if an error occured, in that case np's fields are in an undefined
1565 state but all string buffers have been freed. */
1567 partition_number (struct number_parts *np, mpfr_srcptr p,
1568 struct printf_spec spec)
1574 /* WARNING: left justification means right space padding */
1575 np->pad_type = spec.left ? RIGHT : spec.pad == '0' ? LEADING_ZEROS : LEFT;
1578 np->prefix_ptr =NULL;
1579 np->prefix_size = 0;
1580 np->thousands_sep = '\0';
1583 np->ip_trailing_zeros = 0;
1585 np->fp_leading_zeros = 0;
1588 np->fp_trailing_zeros = 0;
1591 np->sl = (struct string_list *)
1592 (*__gmp_allocate_func) (sizeof (struct string_list));
1593 init_string_list (np->sl);
1595 uppercase = spec.spec == 'A' || spec.spec == 'E' || spec.spec == 'F'
1596 || spec.spec == 'G';
1598 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (p)))
1600 if (MPFR_IS_NAN (p))
1602 if (np->pad_type == LEADING_ZEROS)
1603 /* don't want "0000nan", change to right justification padding
1604 with left spaces instead */
1605 np->pad_type = LEFT;
1609 np->ip_size = MPFR_NAN_STRING_LENGTH;
1610 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1611 strcpy (str, MPFR_NAN_STRING_UC);
1612 np->ip_ptr = register_string (np->sl, str);
1616 np->ip_size = MPFR_NAN_STRING_LENGTH;
1617 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1618 strcpy (str, MPFR_NAN_STRING_LC);
1619 np->ip_ptr = register_string (np->sl, str);
1622 else if (MPFR_IS_INF (p))
1624 if (np->pad_type == LEADING_ZEROS)
1625 /* don't want "0000inf", change to right justification padding
1626 with left spaces instead */
1627 np->pad_type = LEFT;
1629 if (MPFR_IS_NEG (p))
1634 np->ip_size = MPFR_INF_STRING_LENGTH;
1635 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1636 strcpy (str, MPFR_INF_STRING_UC);
1637 np->ip_ptr = register_string (np->sl, str);
1641 np->ip_size = MPFR_INF_STRING_LENGTH;
1642 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1643 strcpy (str, MPFR_INF_STRING_LC);
1644 np->ip_ptr = register_string (np->sl, str);
1650 /* note: for 'g' spec, zero is always displayed with 'f'-style with
1651 precision spec.prec - 1 and the trailing zeros are removed unless
1652 the flag '#' is used. */
1653 if (MPFR_IS_NEG (p))
1656 else if (spec.showsign || spec.space)
1657 np->sign = spec.showsign ? '+' : ' ';
1659 if (spec.spec == 'a' || spec.spec == 'A')
1662 np->prefix_size = 2;
1663 str = (char *) (*__gmp_allocate_func) (1 + np->prefix_size);
1665 str[1] = uppercase ? 'X' : 'x';
1667 np->prefix_ptr = register_string (np->sl, str);
1672 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
1675 np->ip_ptr = register_string (np->sl, str);
1678 && ((spec.spec != 'g' && spec.spec != 'G') || spec.alt))
1679 /* fractional part */
1681 np->point = MPFR_DECIMAL_POINT;
1682 np->fp_trailing_zeros = (spec.spec == 'g' && spec.spec == 'G') ?
1683 spec.prec - 1 : spec.prec;
1686 np->point = MPFR_DECIMAL_POINT;
1688 if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b'
1689 || spec.spec == 'e' || spec.spec == 'E')
1692 np->exp_size = (spec.spec == 'e' || spec.spec == 'E') ? 4 : 3;
1693 str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
1694 if (spec.spec == 'e' || spec.spec == 'E')
1695 strcpy (str, uppercase ? "E+00" : "e+00");
1697 strcpy (str, uppercase ? "P+0" : "p+0");
1698 np->exp_ptr = register_string (np->sl, str);
1703 /* regular p, p != 0 */
1705 if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b')
1707 if (regular_ab (np, p, spec) == -1)
1710 else if (spec.spec == 'f' || spec.spec == 'F')
1712 if (spec.prec == -1)
1714 if (regular_fg (np, p, spec) == -1)
1717 else if (spec.spec == 'e' || spec.spec == 'E')
1719 if (regular_eg (np, p, spec) == -1)
1725 /* Use the C99 rules:
1726 if T > X >= -4 then the conversion is with style 'f'/'F' and
1728 otherwise, the conversion is with style 'e'/'E' and
1730 where T is the threshold computed below and X is the exponent
1731 that would be displayed with style 'e' and precision T-1. */
1735 threshold = (spec.prec < 0) ? 6 : (spec.prec == 0) ? 1 : spec.prec;
1736 round_to_10_power (&x, p, threshold - 1, spec.rnd_mode);
1738 if (threshold > x && x >= -4)
1740 /* the conversion is with style 'f' */
1741 spec.prec = threshold - x - 1;
1743 if (regular_fg (np, p, spec) == -1)
1748 spec.prec = threshold - 1;
1750 if (regular_eg (np, p, spec) == -1)
1756 /* compute the number of characters to be written verifying it is not too
1758 total = np->sign ? 1 : 0;
1759 total += np->prefix_size;
1760 total += np->ip_size;
1761 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1763 total += np->ip_trailing_zeros;
1764 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1766 if (np->thousands_sep)
1767 /* ' flag, style f and the thousands separator in current locale is not
1768 reduced to the null character */
1769 total += (np->ip_size + np->ip_trailing_zeros) / 3;
1770 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1774 total += np->fp_leading_zeros;
1775 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1777 total += np->fp_size;
1778 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1780 total += np->fp_trailing_zeros;
1781 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1783 total += np->exp_size;
1784 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
1787 if (spec.width > total)
1788 /* pad with spaces or zeros depending on np->pad_type */
1790 np->pad_size = spec.width - total;
1791 total += np->pad_size; /* here total == spec.width,
1792 so 0 < total < INT_MAX */
1798 clear_string_list (np->sl);
1799 np->prefix_ptr = NULL;
1806 /* sprnt_fp prints a mpfr_t according to spec.spec specification.
1808 return the size of the string (not counting the terminating '\0')
1809 return -1 if the built string is too long (i.e. has more than
1810 INT_MAX characters). */
1812 sprnt_fp (struct string_buffer *buf, mpfr_srcptr p,
1813 const struct printf_spec spec)
1816 struct number_parts np;
1818 length = partition_number (&np, p, spec);
1822 /* right justification padding with left spaces */
1823 if (np.pad_type == LEFT && np.pad_size != 0)
1824 buffer_pad (buf, ' ', np.pad_size);
1826 /* sign character (may be '-', '+', or ' ') */
1828 buffer_pad (buf, np.sign, 1);
1832 buffer_cat (buf, np.prefix_ptr, np.prefix_size);
1834 /* right justification padding with leading zeros */
1835 if (np.pad_type == LEADING_ZEROS && np.pad_size != 0)
1836 buffer_pad (buf, '0', np.pad_size);
1838 /* integral part (may also be "nan" or "inf") */
1839 MPFR_ASSERTN (np.ip_ptr != NULL); /* never empty */
1840 if (MPFR_UNLIKELY (np.thousands_sep))
1841 buffer_sandwich (buf, np.ip_ptr, np.ip_size, np.ip_trailing_zeros,
1845 buffer_cat (buf, np.ip_ptr, np.ip_size);
1847 /* trailing zeros in integral part */
1848 if (np.ip_trailing_zeros != 0)
1849 buffer_pad (buf, '0', np.ip_trailing_zeros);
1854 buffer_pad (buf, np.point, 1);
1856 /* leading zeros in fractional part */
1857 if (np.fp_leading_zeros != 0)
1858 buffer_pad (buf, '0', np.fp_leading_zeros);
1860 /* significant digits in fractional part */
1862 buffer_cat (buf, np.fp_ptr, np.fp_size);
1864 /* trailing zeros in fractional part */
1865 if (np.fp_trailing_zeros != 0)
1866 buffer_pad (buf, '0', np.fp_trailing_zeros);
1870 buffer_cat (buf, np.exp_ptr, np.exp_size);
1872 /* left justication padding with right spaces */
1873 if (np.pad_type == RIGHT && np.pad_size != 0)
1874 buffer_pad (buf, ' ', np.pad_size);
1876 clear_string_list (np.sl);
1881 mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
1883 struct string_buffer buf;
1886 /* informations on the conversion specification filled by the parser */
1887 struct printf_spec spec;
1888 /* flag raised when previous part of fmt need to be processed by
1891 /* beginning and end of the previous unprocessed part of fmt */
1892 const char *start, *end;
1893 /* pointer to arguments for gmp_vasprintf */
1896 MPFR_SAVE_EXPO_DECL (expo);
1897 MPFR_SAVE_EXPO_MARK (expo);
1900 buffer_init (&buf, 4096 * sizeof (char));
1906 /* Look for the next format specification */
1907 while ((*fmt) && (*fmt != '%'))
1914 /* %%: go one step further otherwise the second '%' would be
1915 considered as a new conversion specification introducing
1925 /* format string analysis */
1926 specinfo_init (&spec);
1927 fmt = parse_flags (fmt, &spec);
1929 READ_INT (ap, fmt, spec, width, width_analysis);
1934 spec.width = -spec.width;
1935 MPFR_ASSERTN (spec.width < INT_MAX);
1939 const char *f = ++fmt;
1940 READ_INT (ap, fmt, spec, prec, prec_analysis);
1948 fmt = parse_arg_type (fmt, &spec);
1949 if (spec.arg_type == UNSUPPORTED)
1950 /* the current architecture doesn't support this type */
1954 else if (spec.arg_type == MPFR_ARG)
1962 spec.rnd_mode = (mpfr_rnd_t) va_arg (ap, int);
1966 spec.rnd_mode = GMP_RNDD;
1970 spec.rnd_mode = GMP_RNDU;
1974 spec.rnd_mode = GMP_RNDZ;
1979 spec.rnd_mode = GMP_RNDN;
1984 if (!specinfo_is_valid (spec))
1990 /* Format processing */
1991 if (spec.spec == '\0')
1992 /* end of the format string */
1994 else if (spec.spec == 'n')
1995 /* put the number of characters written so far in the location pointed
1996 by the next va_list argument; the types of pointer accepted are the
1997 same as in GMP (except unsupported quad_t) plus pointer to a mpfr_t
1998 so as to be able to accept the same format strings. */
2003 p = va_arg (ap, void *);
2004 FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2007 nchar = buf.curr - buf.start;
2009 switch (spec.arg_type)
2012 *(char *) p = (char) nchar;
2015 *(short *) p = (short) nchar;
2018 *(long *) p = (long) nchar;
2020 #ifdef HAVE_LONG_LONG
2022 *(long long *) p = (long long) nchar;
2025 #ifdef _MPFR_H_HAVE_INTMAX_T
2027 *(intmax_t *) p = (intmax_t) nchar;
2031 *(size_t *) p = nchar;
2034 *(ptrdiff_t *) p = (ptrdiff_t) nchar;
2037 mpf_set_ui ((mpf_ptr) p, (unsigned long) nchar);
2040 mpq_set_ui ((mpq_ptr) p, (unsigned long) nchar, 1L);
2043 *(mp_limb_t *) p = (mp_limb_t) nchar;
2045 case MP_LIMB_ARRAY_ARG:
2047 mp_limb_t *q = (mp_limb_t *) p;
2049 n = va_arg (ap, mp_size_t);
2055 /* we assume here that mp_limb_t is wider than int */
2056 *q = (mp_limb_t) nchar;
2065 mpz_set_ui ((mpz_ptr) p, (unsigned long) nchar);
2069 mpfr_set_ui ((mpfr_ptr) p, (unsigned long) nchar,
2074 *(int *) p = (int) nchar;
2076 va_copy (ap2, ap); /* after the switch, due to MP_LIMB_ARRAY_ARG
2079 else if (spec.arg_type == MPFR_PREC_ARG)
2080 /* output mp_prec_t variable */
2083 char format[MPFR_PREC_FORMAT_SIZE + 6]; /* see examples below */
2086 prec = va_arg (ap, mpfr_prec_t);
2088 FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2093 /* construct format string, like "%*.*hu" "%*.*u" or "%*.*lu" */
2099 strcat (format, MPFR_PREC_FORMAT_TYPE);
2100 format[4 + MPFR_PREC_FORMAT_SIZE] = spec.spec;
2101 format[5 + MPFR_PREC_FORMAT_SIZE] = '\0';
2102 length = gmp_asprintf (&s, format, spec.width, spec.prec, prec);
2103 if (buf.size <= INT_MAX - length)
2105 buffer_cat (&buf, s, length);
2111 goto overflow_error;
2114 else if (spec.arg_type == MPFR_ARG)
2115 /* output a mpfr_t variable */
2119 p = va_arg (ap, mpfr_srcptr);
2121 FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2137 if (sprnt_fp (&buf, p, spec) < 0)
2138 goto overflow_error;
2142 /* unsupported specifier */
2147 /* gmp_printf specification, step forward in the va_list */
2149 CONSUME_VA_ARG (spec, ap);
2155 FLUSH (xgmp_fmt_flag, start, fmt, ap2, &buf);
2158 nbchar = buf.curr - buf.start;
2159 MPFR_ASSERTD (nbchar == strlen (buf.start));
2161 (char *) (*__gmp_reallocate_func) (buf.start, buf.size, nbchar + 1);
2162 buf.size = nbchar + 1; /* update needed for __gmp_free_func below when
2163 nbchar is too large (overflow_error) */
2166 /* If nbchar is larger than INT_MAX, the ISO C99 standard is silent, but
2167 POSIX says concerning the snprintf() function:
2168 "[EOVERFLOW] The value of n is greater than {INT_MAX} or the
2169 number of bytes needed to hold the output excluding the
2170 terminating null is greater than {INT_MAX}." See:
2171 http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
2172 But it doesn't say anything concerning the other printf-like functions.
2173 A defect report has been submitted to austin-review-l (item 2532).
2174 So, for the time being, we return a negative value and set the erange
2175 flag, and set errno to EOVERFLOW in POSIX system. */
2176 if (nbchar <= INT_MAX)
2178 MPFR_SAVE_EXPO_FREE (expo);
2183 MPFR_SAVE_EXPO_UPDATE_FLAGS(expo, MPFR_FLAGS_ERANGE);
2189 MPFR_SAVE_EXPO_FREE (expo);
2191 (*__gmp_free_func) (buf.start, buf.size);
2196 #endif /* HAVE_STDARG */