1 /* mpfr_vasprintf -- main function for the printf functions family
2 plus helper macros & functions.
4 Copyright 2007-2016 Free Software Foundation, Inc.
5 Contributed by the AriC and Caramba 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 dependent).
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 /* An integer overflow is normally not possible since MPFR_EXP_MIN
888 is twice as large as MPFR_EMIN_MIN. */
889 MPFR_ASSERTN (exp
> (MPFR_EXP_MIN
+ 3) / 4);
893 /* EXP is the exponent for decimal point BEFORE the first digit, we
894 want the exponent for decimal point AFTER the first digit. */
896 /* An integer overflow is normally not possible since MPFR_EXP_MIN
897 is twice as large as MPFR_EMIN_MIN. */
898 MPFR_ASSERTN (exp
> MPFR_EXP_MIN
);
902 else if (next_base_power_p (p
, base
, spec
.rnd_mode
))
904 str
= (char *)(*__gmp_allocate_func
) (2);
907 np
->ip_ptr
= register_string (np
->sl
, str
);
909 exp
= MPFR_GET_EXP (p
);
913 str
= (char *)(*__gmp_allocate_func
) (2);
916 np
->ip_ptr
= register_string (np
->sl
, str
);
918 exp
= MPFR_GET_EXP (p
) - 1;
923 mp_limb_t msl
= MPFR_MANT (p
)[MPFR_LIMB_SIZE (p
) - 1];
924 int rnd_bit
= GMP_NUMB_BITS
- 5;
926 /* pick up the 4 first bits */
927 digit
= msl
>> (rnd_bit
+1);
928 if (spec
.rnd_mode
== MPFR_RNDA
929 || (spec
.rnd_mode
== MPFR_RNDU
&& MPFR_IS_POS (p
))
930 || (spec
.rnd_mode
== MPFR_RNDD
&& MPFR_IS_NEG (p
))
931 || (spec
.rnd_mode
== MPFR_RNDN
932 && (msl
& (MPFR_LIMB_ONE
<< rnd_bit
))))
934 MPFR_ASSERTD ((0 <= digit
) && (digit
<= 15));
936 str
= (char *)(*__gmp_allocate_func
) (1 + np
->ip_size
);
937 str
[0] = num_to_text
[digit
];
939 np
->ip_ptr
= register_string (np
->sl
, str
);
941 exp
= MPFR_GET_EXP (p
) - 4;
945 /* All digits in upper case */
975 if (spec
.spec
== 'b' || spec
.prec
!= 0)
976 /* compute the number of digits in fractional part */
981 /* the sign has been skipped, skip also the first digit */
983 str_len
= strlen (str
);
984 ptr
= str
+ str_len
- 1; /* points to the end of str */
987 /* remove trailing zeros, if any */
989 while ((*ptr
== '0') && (str_len
!= 0))
996 if (str_len
> INT_MAX
)
997 /* too many digits in fractional part */
1001 /* there are some non-zero digits in fractional part */
1004 np
->fp_size
= str_len
;
1005 if ((int) str_len
< spec
.prec
)
1006 np
->fp_trailing_zeros
= spec
.prec
- str_len
;
1011 if ((np
->fp_size
!= 0) || spec
.alt
)
1012 np
->point
= MPFR_DECIMAL_POINT
;
1014 /* the exponent part contains the character 'p', or 'P' plus the sign
1015 character plus at least one digit and only as many more digits as
1016 necessary to represent the exponent.
1017 We assume that |EXP| < 10^INT_MAX. */
1022 x
= SAFE_ABS (mpfr_uexp_t
, exp
);
1029 str
= (char *) (*__gmp_allocate_func
) (1 + np
->exp_size
);
1030 np
->exp_ptr
= register_string (np
->sl
, str
);
1032 char exp_fmt
[8]; /* contains at most 7 characters like in "p%+.1i",
1035 exp_fmt
[0] = uppercase
? 'P' : 'p';
1037 strcat (exp_fmt
, "%+.1" MPFR_EXP_FSPEC
"d");
1039 if (sprintf (str
, exp_fmt
, (mpfr_eexp_t
) exp
) < 0)
1046 /* Determine the different parts of the string representation of the regular
1047 number P when spec.spec is 'e', 'E', 'g', or 'G'.
1048 DEC_INFO contains the previously computed exponent and string or is NULL.
1050 return -1 if some field > INT_MAX */
1052 regular_eg (struct number_parts
*np
, mpfr_srcptr p
,
1053 const struct printf_spec spec
, struct decimal_info
*dec_info
)
1058 const int uppercase
= spec
.spec
== 'E' || spec
.spec
== 'G';
1059 const int spec_g
= spec
.spec
== 'g' || spec
.spec
== 'G';
1060 const int keep_trailing_zeros
= (spec_g
&& spec
.alt
)
1061 || (!spec_g
&& (spec
.prec
> 0));
1064 if (MPFR_IS_NEG (p
))
1066 else if (spec
.showsign
|| spec
.space
)
1067 np
->sign
= spec
.showsign
? '+' : ' ';
1071 if (dec_info
== NULL
)
1075 /* Number of significant digits:
1076 - if no given precision, then let mpfr_get_str determine it,
1077 - if a precision is specified, then one digit before decimal point
1078 plus SPEC.PREC after it.
1079 We use the fact here that mpfr_get_str allows us to ask for only one
1080 significant digit when the base is not a power of 2. */
1081 nsd
= (spec
.prec
< 0) ? 0 : spec
.prec
+ np
->ip_size
;
1082 str
= mpfr_get_str (0, &exp
, 10, nsd
, p
, spec
.rnd_mode
);
1083 register_string (np
->sl
, str
);
1087 exp
= dec_info
->exp
;
1088 str
= dec_info
->str
;
1090 np
->ip_ptr
= MPFR_IS_NEG (p
) ? ++str
: str
; /* skip sign if any */
1093 /* compute the number of digits in fractional part */
1098 /* the sign has been skipped, skip also the first digit */
1100 str_len
= strlen (str
);
1101 ptr
= str
+ str_len
- 1; /* points to the end of str */
1103 if (!keep_trailing_zeros
)
1104 /* remove trailing zeros, if any */
1106 while ((*ptr
== '0') && (str_len
!= 0))
1113 if (str_len
> INT_MAX
)
1114 /* too many digits in fractional part */
1118 /* there are some non-zero digits in fractional part */
1121 np
->fp_size
= str_len
;
1122 if ((!spec_g
|| spec
.alt
) && (spec
.prec
> 0)
1123 && ((int)str_len
< spec
.prec
))
1124 /* add missing trailing zeros */
1125 np
->fp_trailing_zeros
= spec
.prec
- str_len
;
1130 if (np
->fp_size
!= 0 || spec
.alt
)
1131 np
->point
= MPFR_DECIMAL_POINT
;
1133 /* EXP is the exponent for decimal point BEFORE the first digit, we want
1134 the exponent for decimal point AFTER the first digit.
1135 Here, no possible overflow because exp < MPFR_EXP (p) / 3 */
1138 /* the exponent part contains the character 'e', or 'E' plus the sign
1139 character plus at least two digits and only as many more digits as
1140 necessary to represent the exponent.
1141 We assume that |EXP| < 10^INT_MAX. */
1146 x
= SAFE_ABS (mpfr_uexp_t
, exp
);
1153 if (np
->exp_size
< 4)
1156 str
= (char *) (*__gmp_allocate_func
) (1 + np
->exp_size
);
1157 np
->exp_ptr
= register_string (np
->sl
, str
);
1160 char exp_fmt
[8]; /* e.g. "e%+.2i", or "E%+.2li" */
1162 exp_fmt
[0] = uppercase
? 'E' : 'e';
1164 strcat (exp_fmt
, "%+.2" MPFR_EXP_FSPEC
"d");
1166 if (sprintf (str
, exp_fmt
, (mpfr_eexp_t
) exp
) < 0)
1173 /* Determine the different parts of the string representation of the regular
1174 number P when spec.spec is 'f', 'F', 'g', or 'G'.
1175 DEC_INFO contains the previously computed exponent and string or is NULL.
1177 return -1 if some field of number_parts is greater than INT_MAX */
1179 regular_fg (struct number_parts
*np
, mpfr_srcptr p
,
1180 const struct printf_spec spec
, struct decimal_info
*dec_info
)
1184 const int spec_g
= (spec
.spec
== 'g' || spec
.spec
== 'G');
1185 const int keep_trailing_zeros
= !spec_g
|| spec
.alt
;
1187 /* WARNING: an empty precision field is forbidden (it means precision = 6
1188 and it should have been changed to 6 before the function call) */
1189 MPFR_ASSERTD (spec
.prec
>= 0);
1192 if (MPFR_IS_NEG (p
))
1194 else if (spec
.showsign
|| spec
.space
)
1195 np
->sign
= spec
.showsign
? '+' : ' ';
1197 if (MPFR_GET_EXP (p
) <= 0)
1200 /* Most of the time, integral part is 0 */
1202 str
= (char *) (*__gmp_allocate_func
) (1 + np
->ip_size
);
1205 np
->ip_ptr
= register_string (np
->sl
, str
);
1208 /* only two possibilities: either 1 or 0. */
1212 MPFR_ALIAS (y
, p
, 1, MPFR_EXP (p
));
1214 if (spec
.rnd_mode
== MPFR_RNDA
1215 || (spec
.rnd_mode
== MPFR_RNDD
&& MPFR_IS_NEG (p
))
1216 || (spec
.rnd_mode
== MPFR_RNDU
&& MPFR_IS_POS (p
))
1217 || (spec
.rnd_mode
== MPFR_RNDN
&& mpfr_cmp_d (y
, 0.5) > 0))
1218 /* rounded up to 1: one digit '1' in integral part.
1219 note that 0.5 is rounded to 0 with RNDN (round ties to even) */
1220 np
->ip_ptr
[0] = '1';
1224 /* exp = position of the most significant decimal digit. */
1225 exp
= floor_log10 (p
);
1226 MPFR_ASSERTD (exp
< 0);
1228 if (exp
< -spec
.prec
)
1229 /* only the last digit may be non zero */
1232 switch (spec
.rnd_mode
)
1238 round_away
= MPFR_IS_NEG (p
);
1241 round_away
= MPFR_IS_POS (p
);
1245 /* compare |p| to y = 0.5*10^(-spec.prec) */
1247 mpfr_exp_t e
= MAX (MPFR_PREC (p
), 56);
1248 mpfr_init2 (y
, e
+ 8);
1251 /* find a lower approximation of
1252 0.5*10^(-spec.prec) different from |p| */
1254 mpfr_set_prec (y
, e
);
1255 mpfr_set_si (y
, -spec
.prec
, MPFR_RNDN
);
1256 mpfr_exp10 (y
, y
, MPFR_RNDD
);
1257 mpfr_div_2ui (y
, y
, 1, MPFR_RNDN
);
1258 } while (mpfr_cmpabs (y
, p
) == 0);
1260 round_away
= mpfr_cmpabs (y
, p
) < 0;
1269 /* round away from zero: the last output digit is '1' */
1271 np
->fp_leading_zeros
= spec
.prec
- 1;
1275 (char *) (*__gmp_allocate_func
) (1 + np
->fp_size
);
1278 np
->fp_ptr
= register_string (np
->sl
, str
);
1281 /* only zeros in fractional part */
1283 MPFR_ASSERTD (!spec_g
);
1284 np
->fp_leading_zeros
= spec
.prec
;
1288 /* the most significant digits are the last
1289 spec.prec + exp + 1 digits in fractional part */
1293 if (dec_info
== NULL
)
1295 size_t nsd
= spec
.prec
+ exp
+ 1;
1296 /* WARNING: nsd may equal 1, but here we use the
1297 fact that mpfr_get_str can return one digit with
1298 base ten (undocumented feature, see comments in
1301 str
= mpfr_get_str (NULL
, &exp
, 10, nsd
, p
, spec
.rnd_mode
);
1302 register_string (np
->sl
, str
);
1306 exp
= dec_info
->exp
;
1307 str
= dec_info
->str
;
1309 if (MPFR_IS_NEG (p
))
1315 MPFR_ASSERTD (str
[0] == '1');
1316 np
->ip_ptr
[0] = '1';
1317 if (!spec_g
|| spec
.alt
)
1318 np
->fp_leading_zeros
= spec
.prec
;
1323 np
->fp_leading_zeros
= -exp
;
1324 MPFR_ASSERTD (exp
<= 0);
1326 str_len
= strlen (str
); /* the sign has been skipped */
1327 ptr
= str
+ str_len
- 1; /* points to the end of str */
1329 if (!keep_trailing_zeros
)
1330 /* remove trailing zeros, if any */
1332 while ((*ptr
== '0') && str_len
)
1339 if (str_len
> INT_MAX
)
1340 /* too many digits in fractional part */
1343 MPFR_ASSERTD (str_len
> 0);
1344 np
->fp_size
= str_len
;
1346 if ((!spec_g
|| spec
.alt
)
1348 && (np
->fp_leading_zeros
+ np
->fp_size
< spec
.prec
))
1349 /* add missing trailing zeros */
1350 np
->fp_trailing_zeros
= spec
.prec
- np
->fp_leading_zeros
1356 if (spec
.alt
|| np
->fp_leading_zeros
!= 0 || np
->fp_size
!= 0
1357 || np
->fp_trailing_zeros
!= 0)
1358 np
->point
= MPFR_DECIMAL_POINT
;
1365 /* Determine the position of the most significant decimal digit. */
1366 exp
= floor_log10 (p
);
1367 MPFR_ASSERTD (exp
>= 0);
1369 /* P is too large to print all its integral part digits */
1372 if (dec_info
== NULL
)
1373 { /* this case occurs with mpfr_printf ("%.0RUf", x) with x=9.5 */
1375 mpfr_get_str (NULL
, &exp
, 10, spec
.prec
+exp
+1, p
, spec
.rnd_mode
);
1376 register_string (np
->sl
, str
);
1380 exp
= dec_info
->exp
;
1381 str
= dec_info
->str
;
1383 np
->ip_ptr
= MPFR_IS_NEG (p
) ? ++str
: str
; /* skip sign */
1384 str_len
= strlen (str
);
1388 /* mpfr_get_str gives no trailing zero when p is rounded up to the next
1389 power of 10 (p integer, so no fractional part) */
1391 np
->ip_trailing_zeros
= exp
- str_len
;
1392 np
->ip_size
= str_len
;
1398 /* thousands separator in integral part */
1399 np
->thousands_sep
= MPFR_THOUSANDS_SEPARATOR
;
1401 /* fractional part */
1403 str_len
-= np
->ip_size
;
1404 if (!keep_trailing_zeros
)
1405 /* remove trailing zeros, if any */
1407 char *ptr
= str
+ str_len
- 1; /* pointer to the last digit of
1409 while ((*ptr
== '0') && (str_len
!= 0))
1417 /* some nonzero digits in fractional part */
1419 if (str_len
> INT_MAX
)
1420 /* too many digits in fractional part */
1423 np
->point
= MPFR_DECIMAL_POINT
;
1425 np
->fp_size
= str_len
;
1428 if (keep_trailing_zeros
&& str_len
< spec
.prec
)
1429 /* add missing trailing zeros */
1431 np
->point
= MPFR_DECIMAL_POINT
;
1432 np
->fp_trailing_zeros
= spec
.prec
- np
->fp_size
;
1436 /* add decimal point even if no digits follow it */
1437 np
->point
= MPFR_DECIMAL_POINT
;
1443 /* partition_number determines the different parts of the string
1444 representation of the number p according to the given specification.
1445 partition_number initializes the given structure np, so all previous
1446 information in that variable is lost.
1447 return the total number of characters to be written.
1448 return -1 if an error occured, in that case np's fields are in an undefined
1449 state but all string buffers have been freed. */
1451 partition_number (struct number_parts
*np
, mpfr_srcptr p
,
1452 struct printf_spec spec
)
1458 /* WARNING: left justification means right space padding */
1459 np
->pad_type
= spec
.left
? RIGHT
: spec
.pad
== '0' ? LEADING_ZEROS
: LEFT
;
1462 np
->prefix_ptr
=NULL
;
1463 np
->prefix_size
= 0;
1464 np
->thousands_sep
= '\0';
1467 np
->ip_trailing_zeros
= 0;
1469 np
->fp_leading_zeros
= 0;
1472 np
->fp_trailing_zeros
= 0;
1475 np
->sl
= (struct string_list
*)
1476 (*__gmp_allocate_func
) (sizeof (struct string_list
));
1477 init_string_list (np
->sl
);
1479 uppercase
= spec
.spec
== 'A' || spec
.spec
== 'E' || spec
.spec
== 'F'
1480 || spec
.spec
== 'G';
1482 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (p
)))
1484 if (MPFR_IS_NAN (p
))
1486 if (np
->pad_type
== LEADING_ZEROS
)
1487 /* don't want "0000nan", change to right justification padding
1488 with left spaces instead */
1489 np
->pad_type
= LEFT
;
1493 np
->ip_size
= MPFR_NAN_STRING_LENGTH
;
1494 str
= (char *) (*__gmp_allocate_func
) (1 + np
->ip_size
);
1495 strcpy (str
, MPFR_NAN_STRING_UC
);
1496 np
->ip_ptr
= register_string (np
->sl
, str
);
1500 np
->ip_size
= MPFR_NAN_STRING_LENGTH
;
1501 str
= (char *) (*__gmp_allocate_func
) (1 + np
->ip_size
);
1502 strcpy (str
, MPFR_NAN_STRING_LC
);
1503 np
->ip_ptr
= register_string (np
->sl
, str
);
1506 else if (MPFR_IS_INF (p
))
1508 if (np
->pad_type
== LEADING_ZEROS
)
1509 /* don't want "0000inf", change to right justification padding
1510 with left spaces instead */
1511 np
->pad_type
= LEFT
;
1513 if (MPFR_IS_NEG (p
))
1518 np
->ip_size
= MPFR_INF_STRING_LENGTH
;
1519 str
= (char *) (*__gmp_allocate_func
) (1 + np
->ip_size
);
1520 strcpy (str
, MPFR_INF_STRING_UC
);
1521 np
->ip_ptr
= register_string (np
->sl
, str
);
1525 np
->ip_size
= MPFR_INF_STRING_LENGTH
;
1526 str
= (char *) (*__gmp_allocate_func
) (1 + np
->ip_size
);
1527 strcpy (str
, MPFR_INF_STRING_LC
);
1528 np
->ip_ptr
= register_string (np
->sl
, str
);
1534 /* note: for 'g' spec, zero is always displayed with 'f'-style with
1535 precision spec.prec - 1 and the trailing zeros are removed unless
1536 the flag '#' is used. */
1537 if (MPFR_IS_NEG (p
))
1540 else if (spec
.showsign
|| spec
.space
)
1541 np
->sign
= spec
.showsign
? '+' : ' ';
1543 if (spec
.spec
== 'a' || spec
.spec
== 'A')
1546 np
->prefix_size
= 2;
1547 str
= (char *) (*__gmp_allocate_func
) (1 + np
->prefix_size
);
1549 str
[1] = uppercase
? 'X' : 'x';
1551 np
->prefix_ptr
= register_string (np
->sl
, str
);
1556 str
= (char *) (*__gmp_allocate_func
) (1 + np
->ip_size
);
1559 np
->ip_ptr
= register_string (np
->sl
, str
);
1562 && ((spec
.spec
!= 'g' && spec
.spec
!= 'G') || spec
.alt
))
1563 /* fractional part */
1565 np
->point
= MPFR_DECIMAL_POINT
;
1566 np
->fp_trailing_zeros
= (spec
.spec
== 'g' || spec
.spec
== 'G') ?
1567 spec
.prec
- 1 : spec
.prec
;
1570 np
->point
= MPFR_DECIMAL_POINT
;
1572 if (spec
.spec
== 'a' || spec
.spec
== 'A' || spec
.spec
== 'b'
1573 || spec
.spec
== 'e' || spec
.spec
== 'E')
1576 np
->exp_size
= (spec
.spec
== 'e' || spec
.spec
== 'E') ? 4 : 3;
1577 str
= (char *) (*__gmp_allocate_func
) (1 + np
->exp_size
);
1578 if (spec
.spec
== 'e' || spec
.spec
== 'E')
1579 strcpy (str
, uppercase
? "E+00" : "e+00");
1581 strcpy (str
, uppercase
? "P+0" : "p+0");
1582 np
->exp_ptr
= register_string (np
->sl
, str
);
1587 /* regular p, p != 0 */
1589 if (spec
.spec
== 'a' || spec
.spec
== 'A' || spec
.spec
== 'b')
1591 if (regular_ab (np
, p
, spec
) == -1)
1594 else if (spec
.spec
== 'f' || spec
.spec
== 'F')
1596 if (spec
.prec
== -1)
1598 if (regular_fg (np
, p
, spec
, NULL
) == -1)
1601 else if (spec
.spec
== 'e' || spec
.spec
== 'E')
1603 if (regular_eg (np
, p
, spec
, NULL
) == -1)
1609 /* Use the C99 rules:
1610 if T > X >= -4 then the conversion is with style 'f'/'F' and
1612 otherwise, the conversion is with style 'e'/'E' and
1614 where T is the threshold computed below and X is the exponent
1615 that would be displayed with style 'e' and precision T-1. */
1618 struct decimal_info dec_info
;
1620 threshold
= (spec
.prec
< 0) ? 6 : (spec
.prec
== 0) ? 1 : spec
.prec
;
1621 dec_info
.str
= mpfr_get_str (NULL
, &dec_info
.exp
, 10, threshold
,
1623 register_string (np
->sl
, dec_info
.str
);
1624 /* mpfr_get_str corresponds to a significand between 0.1 and 1,
1625 whereas here we want a significand between 1 and 10. */
1626 x
= dec_info
.exp
- 1;
1628 if (threshold
> x
&& x
>= -4)
1630 /* the conversion is with style 'f' */
1631 spec
.prec
= threshold
- x
- 1;
1633 if (regular_fg (np
, p
, spec
, &dec_info
) == -1)
1638 spec
.prec
= threshold
- 1;
1640 if (regular_eg (np
, p
, spec
, &dec_info
) == -1)
1646 /* compute the number of characters to be written verifying it is not too
1648 total
= np
->sign
? 1 : 0;
1649 total
+= np
->prefix_size
;
1650 total
+= np
->ip_size
;
1651 if (MPFR_UNLIKELY (total
< 0 || total
> INT_MAX
))
1653 total
+= np
->ip_trailing_zeros
;
1654 if (MPFR_UNLIKELY (total
< 0 || total
> INT_MAX
))
1656 if (np
->thousands_sep
)
1657 /* ' flag, style f and the thousands separator in current locale is not
1658 reduced to the null character */
1659 total
+= (np
->ip_size
+ np
->ip_trailing_zeros
) / 3;
1660 if (MPFR_UNLIKELY (total
< 0 || total
> INT_MAX
))
1664 total
+= np
->fp_leading_zeros
;
1665 if (MPFR_UNLIKELY (total
< 0 || total
> INT_MAX
))
1667 total
+= np
->fp_size
;
1668 if (MPFR_UNLIKELY (total
< 0 || total
> INT_MAX
))
1670 total
+= np
->fp_trailing_zeros
;
1671 if (MPFR_UNLIKELY (total
< 0 || total
> INT_MAX
))
1673 total
+= np
->exp_size
;
1674 if (MPFR_UNLIKELY (total
< 0 || total
> INT_MAX
))
1677 if (spec
.width
> total
)
1678 /* pad with spaces or zeros depending on np->pad_type */
1680 np
->pad_size
= spec
.width
- total
;
1681 total
+= np
->pad_size
; /* here total == spec.width,
1682 so 0 < total < INT_MAX */
1688 clear_string_list (np
->sl
);
1689 np
->prefix_ptr
= NULL
;
1696 /* sprnt_fp prints a mpfr_t according to spec.spec specification.
1698 return the size of the string (not counting the terminating '\0')
1699 return -1 if the built string is too long (i.e. has more than
1700 INT_MAX characters). */
1702 sprnt_fp (struct string_buffer
*buf
, mpfr_srcptr p
,
1703 const struct printf_spec spec
)
1706 struct number_parts np
;
1708 length
= partition_number (&np
, p
, spec
);
1712 /* right justification padding with left spaces */
1713 if (np
.pad_type
== LEFT
&& np
.pad_size
!= 0)
1714 buffer_pad (buf
, ' ', np
.pad_size
);
1716 /* sign character (may be '-', '+', or ' ') */
1718 buffer_pad (buf
, np
.sign
, 1);
1722 buffer_cat (buf
, np
.prefix_ptr
, np
.prefix_size
);
1724 /* right justification padding with leading zeros */
1725 if (np
.pad_type
== LEADING_ZEROS
&& np
.pad_size
!= 0)
1726 buffer_pad (buf
, '0', np
.pad_size
);
1728 /* integral part (may also be "nan" or "inf") */
1729 MPFR_ASSERTN (np
.ip_ptr
!= NULL
); /* never empty */
1730 if (MPFR_UNLIKELY (np
.thousands_sep
))
1731 buffer_sandwich (buf
, np
.ip_ptr
, np
.ip_size
, np
.ip_trailing_zeros
,
1735 buffer_cat (buf
, np
.ip_ptr
, np
.ip_size
);
1737 /* trailing zeros in integral part */
1738 if (np
.ip_trailing_zeros
!= 0)
1739 buffer_pad (buf
, '0', np
.ip_trailing_zeros
);
1744 buffer_pad (buf
, np
.point
, 1);
1746 /* leading zeros in fractional part */
1747 if (np
.fp_leading_zeros
!= 0)
1748 buffer_pad (buf
, '0', np
.fp_leading_zeros
);
1750 /* significant digits in fractional part */
1752 buffer_cat (buf
, np
.fp_ptr
, np
.fp_size
);
1754 /* trailing zeros in fractional part */
1755 if (np
.fp_trailing_zeros
!= 0)
1756 buffer_pad (buf
, '0', np
.fp_trailing_zeros
);
1760 buffer_cat (buf
, np
.exp_ptr
, np
.exp_size
);
1762 /* left justication padding with right spaces */
1763 if (np
.pad_type
== RIGHT
&& np
.pad_size
!= 0)
1764 buffer_pad (buf
, ' ', np
.pad_size
);
1766 clear_string_list (np
.sl
);
1771 mpfr_vasprintf (char **ptr
, const char *fmt
, va_list ap
)
1773 struct string_buffer buf
;
1776 /* informations on the conversion specification filled by the parser */
1777 struct printf_spec spec
;
1778 /* flag raised when previous part of fmt need to be processed by
1781 /* beginning and end of the previous unprocessed part of fmt */
1782 const char *start
, *end
;
1783 /* pointer to arguments for gmp_vasprintf */
1786 MPFR_SAVE_EXPO_DECL (expo
);
1787 MPFR_SAVE_EXPO_MARK (expo
);
1790 buffer_init (&buf
, 4096);
1796 /* Look for the next format specification */
1797 while ((*fmt
) && (*fmt
!= '%'))
1804 /* %%: go one step further otherwise the second '%' would be
1805 considered as a new conversion specification introducing
1815 /* format string analysis */
1816 specinfo_init (&spec
);
1817 fmt
= parse_flags (fmt
, &spec
);
1819 READ_INT (ap
, fmt
, spec
, width
, width_analysis
);
1824 spec
.width
= -spec
.width
;
1825 MPFR_ASSERTN (spec
.width
< INT_MAX
);
1829 const char *f
= ++fmt
;
1830 READ_INT (ap
, fmt
, spec
, prec
, prec_analysis
);
1838 fmt
= parse_arg_type (fmt
, &spec
);
1839 if (spec
.arg_type
== UNSUPPORTED
)
1840 /* the current architecture doesn't support this type */
1844 else if (spec
.arg_type
== MPFR_ARG
)
1852 spec
.rnd_mode
= (mpfr_rnd_t
) va_arg (ap
, int);
1856 spec
.rnd_mode
= MPFR_RNDD
;
1860 spec
.rnd_mode
= MPFR_RNDU
;
1864 spec
.rnd_mode
= MPFR_RNDA
;
1868 spec
.rnd_mode
= MPFR_RNDZ
;
1873 spec
.rnd_mode
= MPFR_RNDN
;
1878 if (!specinfo_is_valid (spec
))
1884 /* Format processing */
1885 if (spec
.spec
== '\0')
1886 /* end of the format string */
1888 else if (spec
.spec
== 'n')
1889 /* put the number of characters written so far in the location pointed
1890 by the next va_list argument; the types of pointer accepted are the
1891 same as in GMP (except unsupported quad_t) plus pointer to a mpfr_t
1892 so as to be able to accept the same format strings. */
1897 p
= va_arg (ap
, void *);
1898 FLUSH (xgmp_fmt_flag
, start
, end
, ap2
, &buf
);
1901 nchar
= buf
.curr
- buf
.start
;
1903 switch (spec
.arg_type
)
1906 *(char *) p
= (char) nchar
;
1909 *(short *) p
= (short) nchar
;
1912 *(long *) p
= (long) nchar
;
1914 #ifdef HAVE_LONG_LONG
1916 *(long long *) p
= (long long) nchar
;
1919 #ifdef _MPFR_H_HAVE_INTMAX_T
1921 *(intmax_t *) p
= (intmax_t) nchar
;
1925 *(size_t *) p
= nchar
;
1928 *(ptrdiff_t *) p
= (ptrdiff_t) nchar
;
1931 mpf_set_ui ((mpf_ptr
) p
, (unsigned long) nchar
);
1934 mpq_set_ui ((mpq_ptr
) p
, (unsigned long) nchar
, 1L);
1937 *(mp_limb_t
*) p
= (mp_limb_t
) nchar
;
1939 case MP_LIMB_ARRAY_ARG
:
1941 mp_limb_t
*q
= (mp_limb_t
*) p
;
1943 n
= va_arg (ap
, mp_size_t
);
1949 /* we assume here that mp_limb_t is wider than int */
1950 *q
= (mp_limb_t
) nchar
;
1959 mpz_set_ui ((mpz_ptr
) p
, (unsigned long) nchar
);
1963 mpfr_set_ui ((mpfr_ptr
) p
, (unsigned long) nchar
,
1968 *(int *) p
= (int) nchar
;
1970 va_copy (ap2
, ap
); /* after the switch, due to MP_LIMB_ARRAY_ARG
1973 else if (spec
.arg_type
== MPFR_PREC_ARG
)
1974 /* output mpfr_prec_t variable */
1977 char format
[MPFR_PREC_FORMAT_SIZE
+ 6]; /* see examples below */
1980 prec
= va_arg (ap
, mpfr_prec_t
);
1982 FLUSH (xgmp_fmt_flag
, start
, end
, ap2
, &buf
);
1987 /* construct format string, like "%*.*hd" "%*.*d" or "%*.*ld" */
1993 strcat (format
, MPFR_PREC_FORMAT_TYPE
);
1994 format
[4 + MPFR_PREC_FORMAT_SIZE
] = spec
.spec
;
1995 format
[5 + MPFR_PREC_FORMAT_SIZE
] = '\0';
1996 length
= gmp_asprintf (&s
, format
, spec
.width
, spec
.prec
, prec
);
1997 if (buf
.size
<= INT_MAX
- length
)
1999 buffer_cat (&buf
, s
, length
);
2005 goto overflow_error
;
2008 else if (spec
.arg_type
== MPFR_ARG
)
2009 /* output a mpfr_t variable */
2013 p
= va_arg (ap
, mpfr_srcptr
);
2015 FLUSH (xgmp_fmt_flag
, start
, end
, ap2
, &buf
);
2031 if (sprnt_fp (&buf
, p
, spec
) < 0)
2032 goto overflow_error
;
2036 /* unsupported specifier */
2041 /* gmp_printf specification, step forward in the va_list */
2043 CONSUME_VA_ARG (spec
, ap
);
2049 FLUSH (xgmp_fmt_flag
, start
, fmt
, ap2
, &buf
);
2052 nbchar
= buf
.curr
- buf
.start
;
2053 MPFR_ASSERTD (nbchar
== strlen (buf
.start
));
2055 (char *) (*__gmp_reallocate_func
) (buf
.start
, buf
.size
, nbchar
+ 1);
2056 buf
.size
= nbchar
+ 1; /* update needed for __gmp_free_func below when
2057 nbchar is too large (overflow_error) */
2060 /* If nbchar is larger than INT_MAX, the ISO C99 standard is silent, but
2061 POSIX says concerning the snprintf() function:
2062 "[EOVERFLOW] The value of n is greater than {INT_MAX} or the
2063 number of bytes needed to hold the output excluding the
2064 terminating null is greater than {INT_MAX}." See:
2065 http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
2066 But it doesn't say anything concerning the other printf-like functions.
2067 A defect report has been submitted to austin-review-l (item 2532).
2068 So, for the time being, we return a negative value and set the erange
2069 flag, and set errno to EOVERFLOW in POSIX system. */
2070 if (nbchar
<= INT_MAX
)
2072 MPFR_SAVE_EXPO_FREE (expo
);
2077 MPFR_SAVE_EXPO_UPDATE_FLAGS(expo
, MPFR_FLAGS_ERANGE
);
2083 MPFR_SAVE_EXPO_FREE (expo
);
2085 (*__gmp_free_func
) (buf
.start
, buf
.size
);
2090 #endif /* HAVE_STDARG */