1/* mpfr_vasprintf -- main function for the printf functions family 2 plus helper macros & functions. 3 4Copyright 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 5Contributed by the Arenaire and Cacao projects, INRIA. 6 7This file is part of the GNU MPFR Library. 8 9The GNU MPFR Library is free software; you can redistribute it and/or modify 10it under the terms of the GNU Lesser General Public License as published by 11the Free Software Foundation; either version 3 of the License, or (at your 12option) any later version. 13 14The GNU MPFR Library is distributed in the hope that it will be useful, but 15WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17License for more details. 18 19You should have received a copy of the GNU Lesser General Public License 20along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 21http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 2251 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 23 24#ifdef HAVE_CONFIG_H 25#include "config.h" 26#endif 27 28/* The mpfr_printf-like functions are defined only if stdarg.h exists */ 29#ifdef HAVE_STDARG 30 31#include <stdarg.h> 32 33#ifndef HAVE_VA_COPY 34# ifdef HAVE___VA_COPY 35# define va_copy(dst,src) __va_copy(dst, src) 36# else 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 */ 43 44#ifdef HAVE_WCHAR_H 45#include <wchar.h> 46#endif 47 48#if defined (__cplusplus) 49#include <cstddef> 50#define __STDC_LIMIT_MACROS /* SIZE_MAX defined with stdint.h inclusion */ 51#else 52#include <stddef.h> /* for ptrdiff_t */ 53#endif 54 55#if HAVE_INTTYPES_H 56# include <inttypes.h> /* for intmax_t */ 57#else 58# if HAVE_STDINT_H 59# include <stdint.h> /* for WINT_MAX in particular */ 60# endif 61#endif 62 63#define MPFR_NEED_LONGLONG_H 64#include "mpfr-impl.h" 65 66/* Define a length modifier corresponding to mpfr_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 78#else 79#error "mpfr_prec_t size not supported" 80#endif 81 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" 86#else 87#error "mpfr_exp_t size not supported" 88#endif 89 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 97 98/* The implicit \0 is useless, but we do not write num_to_text[16] 99 otherwise g++ complains. */ 100static const char num_to_text[] = "0123456789abcdef"; 101 102/* some macro and functions for parsing format string */ 103 104/* Read an integer; saturate to INT_MAX. */ 105#define READ_INT(ap, format, specinfo, field, label_out) \ 106 do { \ 107 while (*(format)) \ 108 { \ 109 int _i; \ 110 switch (*(format)) \ 111 { \ 112 case '0': \ 113 case '1': \ 114 case '2': \ 115 case '3': \ 116 case '4': \ 117 case '5': \ 118 case '6': \ 119 case '7': \ 120 case '8': \ 121 case '9': \ 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; \ 128 ++(format); \ 129 break; \ 130 case '*': \ 131 specinfo.field = va_arg ((ap), int); \ 132 ++(format); \ 133 default: \ 134 goto label_out; \ 135 } \ 136 } \ 137 } while (0) 138 139/* arg_t contains all the types described by the 'type' field of the 140 format string */ 141enum arg_t 142 { 143 NONE, 144 CHAR_ARG, 145 SHORT_ARG, 146 LONG_ARG, 147 LONG_LONG_ARG, 148 INTMAX_ARG, 149 SIZE_ARG, 150 PTRDIFF_ARG, 151 LONG_DOUBLE_ARG, 152 MPF_ARG, 153 MPQ_ARG, 154 MP_LIMB_ARG, 155 MP_LIMB_ARRAY_ARG, 156 MPZ_ARG, 157 MPFR_PREC_ARG, 158 MPFR_ARG, 159 UNSUPPORTED 160 }; 161 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. */ 165struct printf_spec 166{ 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 */ 172 173 int width; /* Width */ 174 int prec; /* Precision */ 175 176 enum arg_t arg_type; /* Type of argument */ 177 mpfr_rnd_t rnd_mode; /* Rounding mode */ 178 char spec; /* Conversion specifier */ 179 180 char pad; /* Padding character */ 181}; 182 183static void 184specinfo_init (struct printf_spec *specinfo) 185{ 186 specinfo->alt = 0; 187 specinfo->space = 0; 188 specinfo->left = 0; 189 specinfo->showsign = 0; 190 specinfo->group = 0; 191 specinfo->width = 0; 192 specinfo->prec = 0; 193 specinfo->arg_type = NONE; 194 specinfo->rnd_mode = MPFR_RNDN; 195 specinfo->spec = '\0'; 196 specinfo->pad = ' '; 197} 198 199#define FLOATING_POINT_ARG_TYPE(at) \ 200 ((at) == MPFR_ARG || (at) == MPF_ARG || (at) == LONG_DOUBLE_ARG) 201 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) 207 208static int 209specinfo_is_valid (struct printf_spec spec) 210{ 211 switch (spec.spec) 212 { 213 case 'n': 214 return -1; 215 216 case 'a': case 'A': 217 case 'e': case 'E': 218 case 'f': case 'F': 219 case 'g': case 'G': 220 return (spec.arg_type == NONE 221 || FLOATING_POINT_ARG_TYPE (spec.arg_type)); 222 223 case 'b': 224 return spec.arg_type == MPFR_ARG; 225 226 case 'd': case 'i': 227 case 'u': case 'o': 228 case 'x': case 'X': 229 return (spec.arg_type == NONE 230 || INTEGER_LIKE_ARG_TYPE (spec.arg_type)); 231 232 case 'c': 233 case 's': 234 return (spec.arg_type == NONE || spec.arg_type == LONG_ARG); 235 236 case 'p': 237 return spec.arg_type == NONE; 238 239 default: 240 return 0; 241 } 242} 243 244static const char * 245parse_flags (const char *format, struct printf_spec *specinfo) 246{ 247 while (*format) 248 { 249 switch (*format) 250 { 251 case '0': 252 specinfo->pad = '0'; 253 ++format; 254 break; 255 case '#': 256 specinfo->alt = 1; 257 ++format; 258 break; 259 case '+': 260 specinfo->showsign = 1; 261 ++format; 262 break; 263 case ' ': 264 specinfo->space = 1; 265 ++format; 266 break; 267 case '-': 268 specinfo->left = 1; 269 ++format; 270 break; 271 case '\'': 272 /* Single UNIX Specification for thousand separator */ 273 specinfo->group = 1; 274 ++format; 275 break; 276 default: 277 return format; 278 } 279 } 280 return format; 281} 282 283static const char * 284parse_arg_type (const char *format, struct printf_spec *specinfo) 285{ 286 switch (*format) 287 { 288 case '\0': 289 break; 290 case 'h': 291 if (*++format == 'h') 292#ifndef NPRINTF_HH 293 { 294 ++format; 295 specinfo->arg_type = CHAR_ARG; 296 } 297#else 298 specinfo->arg_type = UNSUPPORTED; 299#endif 300 else 301 specinfo->arg_type = SHORT_ARG; 302 break; 303 case 'l': 304 if (*++format == 'l') 305 { 306 ++format; 307#if defined (HAVE_LONG_LONG) && !defined(NPRINTF_LL) 308 specinfo->arg_type = LONG_LONG_ARG; 309#else 310 specinfo->arg_type = UNSUPPORTED; 311#endif 312 break; 313 } 314 else 315 { 316 specinfo->arg_type = LONG_ARG; 317 break; 318 } 319 case 'j': 320 ++format; 321#if defined(_MPFR_H_HAVE_INTMAX_T) && !defined(NPRINTF_J) 322 specinfo->arg_type = INTMAX_ARG; 323#else 324 specinfo->arg_type = UNSUPPORTED; 325#endif 326 break; 327 case 'z': 328 ++format; 329 specinfo->arg_type = SIZE_ARG; 330 break; 331 case 't': 332 ++format; 333#ifndef NPRINTF_T 334 specinfo->arg_type = PTRDIFF_ARG; 335#else 336 specinfo->arg_type = UNSUPPORTED; 337#endif 338 break; 339 case 'L': 340 ++format; 341#ifndef NPRINTF_L 342 specinfo->arg_type = LONG_DOUBLE_ARG; 343#else 344 specinfo->arg_type = UNSUPPORTED; 345#endif 346 break; 347 case 'F': 348 ++format; 349 specinfo->arg_type = MPF_ARG; 350 break; 351 case 'Q': 352 ++format; 353 specinfo->arg_type = MPQ_ARG; 354 break; 355 case 'M': 356 ++format; 357 /* The 'M' specifier was added in gmp 4.2.0 */ 358 specinfo->arg_type = MP_LIMB_ARG; 359 break; 360 case 'N': 361 ++format; 362 specinfo->arg_type = MP_LIMB_ARRAY_ARG; 363 break; 364 case 'Z': 365 ++format; 366 specinfo->arg_type = MPZ_ARG; 367 break; 368 369 /* mpfr specific specifiers */ 370 case 'P': 371 ++format; 372 specinfo->arg_type = MPFR_PREC_ARG; 373 break; 374 case 'R': 375 ++format; 376 specinfo->arg_type = MPFR_ARG; 377 } 378 return format; 379} 380 381 382/* some macros and functions filling the buffer */ 383 384/* CONSUME_VA_ARG removes from va_list AP the type expected by SPECINFO */ 385 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. */ 393#ifdef HAVE_WCHAR_H 394#if defined(WINT_MAX) && WINT_MAX < INT_MAX 395typedef int mpfr_va_wint; /* integer promotion */ 396#else 397typedef wint_t mpfr_va_wint; 398#endif 399#define CASE_LONG_ARG(specinfo, ap) \ 400 case LONG_ARG: \ 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 */ \ 409 break; 410#else 411#define CASE_LONG_ARG(specinfo, ap) \ 412 case LONG_ARG: \ 413 (void) va_arg ((ap), long); \ 414 break; 415#endif 416 417#if defined(_MPFR_H_HAVE_INTMAX_T) 418#define CASE_INTMAX_ARG(specinfo, ap) \ 419 case INTMAX_ARG: \ 420 (void) va_arg ((ap), intmax_t); \ 421 break; 422#else 423#define CASE_INTMAX_ARG(specinfo, ap) 424#endif 425 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); \ 430 break; 431#else 432#define CASE_LONG_LONG_ARG(specinfo, ap) 433#endif 434 435#define CONSUME_VA_ARG(specinfo, ap) \ 436 do { \ 437 switch ((specinfo).arg_type) \ 438 { \ 439 case CHAR_ARG: \ 440 case SHORT_ARG: \ 441 (void) va_arg ((ap), int); \ 442 break; \ 443 CASE_LONG_ARG (specinfo, ap) \ 444 CASE_LONG_LONG_ARG (specinfo, ap) \ 445 CASE_INTMAX_ARG (specinfo, ap) \ 446 case SIZE_ARG: \ 447 (void) va_arg ((ap), size_t); \ 448 break; \ 449 case PTRDIFF_ARG: \ 450 (void) va_arg ((ap), ptrdiff_t); \ 451 break; \ 452 case LONG_DOUBLE_ARG: \ 453 (void) va_arg ((ap), long double); \ 454 break; \ 455 case MPF_ARG: \ 456 (void) va_arg ((ap), mpf_srcptr); \ 457 break; \ 458 case MPQ_ARG: \ 459 (void) va_arg ((ap), mpq_srcptr); \ 460 break; \ 461 case MP_LIMB_ARG: \ 462 (void) va_arg ((ap), mp_limb_t); \ 463 break; \ 464 case MP_LIMB_ARRAY_ARG: \ 465 (void) va_arg ((ap), mpfr_limb_ptr); \ 466 (void) va_arg ((ap), mp_size_t); \ 467 break; \ 468 case MPZ_ARG: \ 469 (void) va_arg ((ap), mpz_srcptr); \ 470 break; \ 471 default: \ 472 switch ((specinfo).spec) \ 473 { \ 474 case 'd': \ 475 case 'i': \ 476 case 'o': \ 477 case 'u': \ 478 case 'x': \ 479 case 'X': \ 480 case 'c': \ 481 (void) va_arg ((ap), int); \ 482 break; \ 483 case 'f': \ 484 case 'F': \ 485 case 'e': \ 486 case 'E': \ 487 case 'g': \ 488 case 'G': \ 489 case 'a': \ 490 case 'A': \ 491 (void) va_arg ((ap), double); \ 492 break; \ 493 case 's': \ 494 (void) va_arg ((ap), char *); \ 495 break; \ 496 case 'p': \ 497 (void) va_arg ((ap), void *); \ 498 } \ 499 } \ 500 } while (0) 501 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) \ 505 do { \ 506 const size_t n = (end) - (start); \ 507 if ((flag)) \ 508 /* previous specifiers are understood by gmp_printf */ \ 509 { \ 510 MPFR_TMP_DECL (marker); \ 511 char *fmt_copy; \ 512 MPFR_TMP_MARK (marker); \ 513 fmt_copy = (char*) MPFR_TMP_ALLOC (n + 1); \ 514 strncpy (fmt_copy, (start), n); \ 515 fmt_copy[n] = '\0'; \ 516 if (sprntf_gmp ((buf_ptr), (fmt_copy), (ap)) == -1) \ 517 { \ 518 MPFR_TMP_FREE (marker); \ 519 goto error; \ 520 } \ 521 (flag) = 0; \ 522 MPFR_TMP_FREE (marker); \ 523 } \ 524 else if ((start) != (end)) \ 525 /* no conversion specification, just simple characters */ \ 526 buffer_cat ((buf_ptr), (start), n); \ 527 } while (0) 528 529struct string_buffer 530{ 531 char *start; /* beginning of the buffer */ 532 char *curr; /* null terminating character */ 533 size_t size; /* buffer capacity */ 534}; 535 536static void 537buffer_init (struct string_buffer *b, size_t s) 538{ 539 b->start = (char *) (*__gmp_allocate_func) (s); 540 b->start[0] = '\0'; 541 b->curr = b->start; 542 b->size = s; 543} 544 545/* Increase buffer size by a number of character being the least multiple of 546 4096 greater than LEN+1. */ 547static void 548buffer_widen (struct string_buffer *b, size_t len) 549{ 550 const size_t pos = b->curr - b->start; 551 const size_t n = 0x1000 + (len & ~((size_t) 0xfff)); 552 MPFR_ASSERTD (pos < b->size); 553 554 MPFR_ASSERTN ((len & ~((size_t) 4095)) <= (size_t)(SIZE_MAX - 4096)); 555 MPFR_ASSERTN (b->size < SIZE_MAX - n); 556 557 b->start = 558 (char *) (*__gmp_reallocate_func) (b->start, b->size, b->size + n); 559 b->size += n; 560 b->curr = b->start + pos; 561 562 MPFR_ASSERTD (pos < b->size); 563 MPFR_ASSERTD (*b->curr == '\0'); 564} 565 566/* Concatenate the LEN first characters of the string S to the buffer B and 567 expand it if needed. */ 568static void 569buffer_cat (struct string_buffer *b, const char *s, size_t len) 570{ 571 MPFR_ASSERTD (len != 0); 572 MPFR_ASSERTD (len <= strlen (s)); 573 574 if (MPFR_UNLIKELY ((b->curr + len) >= (b->start + b->size))) 575 buffer_widen (b, len); 576 577 strncat (b->curr, s, len); 578 b->curr += len; 579 580 MPFR_ASSERTD (b->curr < b->start + b->size); 581 MPFR_ASSERTD (*b->curr == '\0'); 582} 583 584/* Add N characters C to the end of buffer B */ 585static void 586buffer_pad (struct string_buffer *b, const char c, const size_t n) 587{ 588 MPFR_ASSERTD (n != 0); 589 590 MPFR_ASSERTN (b->size < SIZE_MAX - n - 1); 591 if (MPFR_UNLIKELY ((b->curr + n + 1) > (b->start + b->size))) 592 buffer_widen (b, n); 593 594 if (n == 1) 595 *b->curr = c; 596 else 597 memset (b->curr, c, n); 598 b->curr += n; 599 *b->curr = '\0'; 600 601 MPFR_ASSERTD (b->curr < b->start + b->size); 602} 603 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. */ 607static void 608buffer_sandwich (struct string_buffer *b, char *str, size_t len, 609 const size_t tz, const char c) 610{ 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; 615 size_t i; 616 617 MPFR_ASSERTD (size != 0); 618 if (c == '\0') 619 { 620 buffer_cat (b, str, len); 621 buffer_pad (b, '0', tz); 622 return; 623 } 624 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); 629 630 /* first R significant digits */ 631 memcpy (b->curr, str, r); 632 b->curr += r; 633 str += r; 634 len -= r; 635 636 /* blocks of thousands. Warning: STR might end in the middle of a block */ 637 for (i = 0; i < q; ++i) 638 { 639 *b->curr++ = c; 640 if (MPFR_LIKELY (len > 0)) 641 { 642 if (MPFR_LIKELY (len >= step)) 643 /* step significant digits */ 644 { 645 memcpy (b->curr, str, step); 646 len -= step; 647 } 648 else 649 /* last digits in STR, fill up thousand block with zeros */ 650 { 651 memcpy (b->curr, str, len); 652 memset (b->curr + len, '0', step - len); 653 len = 0; 654 } 655 } 656 else 657 /* trailing zeros */ 658 memset (b->curr, '0', step); 659 660 b->curr += step; 661 str += step; 662 } 663 664 *b->curr = '\0'; 665 666 MPFR_ASSERTD (b->curr < b->start + b->size); 667} 668 669/* let gmp_xprintf process the part it can understand */ 670static int 671sprntf_gmp (struct string_buffer *b, const char *fmt, va_list ap) 672{ 673 int length; 674 char *s; 675 676 length = gmp_vasprintf (&s, fmt, ap); 677 if (length > 0) 678 buffer_cat (b, s, length); 679 680 mpfr_free_str (s); 681 return length; 682} 683 684/* Helper struct and functions for temporary strings management */ 685/* struct for easy string clearing */ 686struct string_list 687{ 688 char *string; 689 struct string_list *next; /* NULL in last node */ 690}; 691 692/* initialisation */ 693static void 694init_string_list (struct string_list *sl) 695{ 696 sl->string = NULL; 697 sl->next = NULL; 698} 699 700/* clear all strings in the list */ 701static void 702clear_string_list (struct string_list *sl) 703{ 704 struct string_list *n; 705 706 while (sl) 707 { 708 if (sl->string) 709 mpfr_free_str (sl->string); 710 n = sl->next; 711 (*__gmp_free_func) (sl, sizeof(struct string_list)); 712 sl = n; 713 } 714} 715 716/* add a string in the list */ 717static char * 718register_string (struct string_list *sl, char *new_string) 719{ 720 /* look for the last node */ 721 while (sl->next) 722 sl = sl->next; 723 724 sl->next = (struct string_list*) 725 (*__gmp_allocate_func) (sizeof (struct string_list)); 726 727 sl = sl->next; 728 sl->next = NULL; 729 return sl->string = new_string; 730} 731 732/* padding type: where are the padding characters */ 733enum pad_t 734 { 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 */ 738 }; 739 740/* number_parts details how much characters are needed in each part of a float 741 print. */ 742struct number_parts 743{ 744 enum pad_t pad_type; /* Padding type */ 745 size_t pad_size; /* Number of padding characters */ 746 747 char sign; /* Sign character */ 748 749 char *prefix_ptr; /* Pointer to prefix part */ 750 size_t prefix_size; /* Number of characters in *prefix_ptr */ 751 752 char thousands_sep; /* Thousands separator (only with style 'f') */ 753 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 757 part */ 758 759 char point; /* Decimal point character */ 760 761 int fp_leading_zeros; /* Number of additional leading zeros in fractional 762 part */ 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 766 part */ 767 768 char *exp_ptr; /* Pointer to exponent part */ 769 size_t exp_size; /* Number of characters in *exp_ptr */ 770 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 773 string as ip_ptr */ 774}; 775 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 */ 779static int 780next_base_power_p (mpfr_srcptr x, int base, mpfr_rnd_t rnd) 781{ 782 mpfr_prec_t nbits; 783 mp_limb_t pm; 784 mp_limb_t xm; 785 786 MPFR_ASSERTD (MPFR_IS_PURE_FP (x)); 787 MPFR_ASSERTD (base == 2 || base == 16); 788 789 /* Warning: the decimal point is AFTER THE FIRST DIGIT in this output 790 representation. */ 791 nbits = base == 2 ? 1 : 4; 792 793 if (rnd == MPFR_RNDZ 794 || (rnd == MPFR_RNDD && MPFR_IS_POS (x)) 795 || (rnd == MPFR_RNDU && MPFR_IS_NEG (x)) 796 || MPFR_PREC (x) <= nbits) 797 /* no rounding when printing x with 1 digit */ 798 return 0; 799 800 xm = MPFR_MANT (x) [MPFR_LIMB_SIZE (x) - 1]; 801 pm = MPFR_LIMB_MASK (GMP_NUMB_BITS - nbits); 802 if ((xm & ~pm) ^ ~pm) 803 /* do no round up if some of the nbits first bits are 0s. */ 804 return 0; 805 806 if (rnd == MPFR_RNDN) 807 /* mask for rounding bit */ 808 pm = (MPFR_LIMB_ONE << (GMP_NUMB_BITS - nbits - 1)); 809 810 /* round up if some remaining bits are 1 */ 811 /* warning: the return value must be an int */ 812 return xm & pm ? 1 : 0; 813} 814 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 ? 817 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. */ 820static int 821round_to_10_power (mpfr_exp_t *e, mpfr_srcptr x, mpfr_prec_t p, mpfr_rnd_t r) 822{ 823 mpfr_t f, u, v, y; 824 mpfr_prec_t m; 825 mpfr_exp_t ex; 826 mpfr_uexp_t uexp; 827 int roundup = -1; /* boolean (-1: not set) */ 828 829 MPFR_ZIV_DECL (loop); 830 831 /* y = abs(x) */ 832 MPFR_ALIAS (y, x, 1, MPFR_EXP(x)); 833 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; 840 m = 1; 841 while (uexp) 842 { 843 uexp >>= 1; 844 m++; 845 } 846 if (m < 2) 847 m = 2; 848 mpfr_init2 (f, m); 849 mpfr_log10 (f, y, MPFR_RNDD); 850 mpfr_floor (f, f); 851 852 /* In most cases, the output exponent is f. */ 853 if (e != NULL) 854 *e = (mpfr_exp_t)mpfr_get_si (f, MPFR_RNDD); 855 856 if (r == MPFR_RNDZ 857 || (MPFR_IS_POS (x) && r == MPFR_RNDD) 858 || (MPFR_IS_NEG (x) && r == MPFR_RNDU)) 859 /* If rounding toward zero, the exponent is f */ 860 { 861 mpfr_clear (f); 862 return 0; 863 } 864 865 /* Is |x| less than 10^(f+1) - 10^(f-p)? */ 866 { 867 int cmp; 868 int inex_u, inex_v, inex_w; 869 mpfr_exp_t exp_u, exp_v, exp_w; 870 871 m = MPFR_PREC (x); 872 m += MPFR_INT_CEIL_LOG2 (m); 873 mpfr_init2 (u, m); 874 mpfr_init2 (v, m); 875 876 MPFR_ZIV_INIT (loop, m); 877 for (;;) 878 { 879 mpfr_set_prec (u, m); 880 mpfr_set_prec (v, m); 881 882 /* u = o(10^(f+1)) rounding toward -infinity 883 error (u) < 1 ulp(u) 884 error(u) = 0 if inex_u = 0 */ 885 mpfr_add_ui (u, f, 1, MPFR_RNDN); 886 inex_u = mpfr_ui_pow (u, 10, u, MPFR_RNDD); 887 exp_u = MPFR_EXP (u); 888 889 /* if r = rounding to nearest 890 v = o(0.5 * 10^(f-p)) rounding toward +infinity 891 else 892 v = o(10^(f-p)) rounding toward +infinity 893 894 error(v) < 1 ulp(v) 895 error(v) = 0 if inex_v = 0 */ 896 mpfr_sub_ui (v, f, p, MPFR_RNDN); 897 inex_v = mpfr_ui_pow (v, 10, v, MPFR_RNDU); 898 if (r == MPFR_RNDN) 899 mpfr_div_2ui (v, v, 1, MPFR_RNDN); 900 exp_v = MPFR_EXP (v); 901 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, MPFR_RNDD); 907 exp_w = MPFR_EXP (u); 908 909 cmp = mpfr_cmp (y, u); 910 911 if (cmp < 0) 912 /* |x| < u <= 10^(f+1) - v, the exponent is f */ 913 { 914 roundup = 0; 915 break; 916 } 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 */ 919 { 920 if (e != NULL) 921 (*e)++; 922 923 roundup = +1; 924 break; 925 } 926 927 /* compare |x| with w + error(w) */ 928 if (inex_u) 929 mpfr_set_ui_2exp (v, 1, exp_u - m, MPFR_RNDU); 930 else 931 mpfr_set_ui (v, 0, MPFR_RNDN); 932 if (inex_v) 933 mpfr_set_ui_2exp (v, 1, exp_v - m, MPFR_RNDU); 934 if (inex_w) 935 mpfr_set_ui_2exp (v, 1, exp_w - m, MPFR_RNDU); 936 937 mpfr_add (u, u, v, MPFR_RNDU); 938 if (mpfr_cmp (y, u) >= 0) 939 { 940 if (e != NULL) 941 *e = (mpfr_exp_t)mpfr_get_si (f, MPFR_RNDD) + 1; 942 943 roundup = +1; 944 break; 945 } 946 947 MPFR_ZIV_NEXT (loop, m); 948 } 949 MPFR_ZIV_FREE (loop); 950 mpfr_clear (u); 951 mpfr_clear (v); 952 } 953 954 MPFR_ASSERTD (roundup != -1); 955 mpfr_clear (f); 956 return roundup; 957} 958 959/* Determine the different parts of the string representation of the regular 960 number P when SPEC.SPEC is 'a', 'A', or 'b'. 961 962 return -1 if some field > INT_MAX */ 963static int 964regular_ab (struct number_parts *np, mpfr_srcptr p, 965 const struct printf_spec spec) 966{ 967 int uppercase; 968 int base; 969 char *str; 970 mpfr_exp_t exp; 971 972 uppercase = spec.spec == 'A'; 973 974 /* sign */ 975 if (MPFR_IS_NEG (p)) 976 np->sign = '-'; 977 else if (spec.showsign || spec.space) 978 np->sign = spec.showsign ? '+' : ' '; 979 980 if (spec.spec == 'a' || spec.spec == 'A') 981 /* prefix part */ 982 { 983 np->prefix_size = 2; 984 str = (char *) (*__gmp_allocate_func) (1 + np->prefix_size); 985 str[0] = '0'; 986 str[1] = uppercase ? 'X' : 'x'; 987 str[2] = '\0'; 988 np->prefix_ptr = register_string (np->sl, str); 989 } 990 991 /* integral part */ 992 np->ip_size = 1; 993 base = (spec.spec == 'b') ? 2 : 16; 994 995 if (spec.prec != 0) 996 { 997 size_t nsd; 998 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 */ 1007 1008 if (base == 16) 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. */ 1012 { 1013 MPFR_ASSERTN (exp > MPFR_EMIN_MIN /4); /* possible overflow */ 1014 exp = (exp - 1) * 4; 1015 } 1016 else 1017 /* EXP is the exponent for decimal point BEFORE the first digit, we 1018 want the exponent for decimal point AFTER the first digit. */ 1019 { 1020 MPFR_ASSERTN (exp > MPFR_EMIN_MIN); /* possible overflow */ 1021 --exp; 1022 } 1023 } 1024 else if (next_base_power_p (p, base, spec.rnd_mode)) 1025 { 1026 str = (char *)(*__gmp_allocate_func) (2); 1027 str[0] = '1'; 1028 str[1] = '\0'; 1029 np->ip_ptr = register_string (np->sl, str); 1030 1031 exp = MPFR_GET_EXP (p); 1032 } 1033 else if (base == 2) 1034 { 1035 str = (char *)(*__gmp_allocate_func) (2); 1036 str[0] = '1'; 1037 str[1] = '\0'; 1038 np->ip_ptr = register_string (np->sl, str); 1039 1040 exp = MPFR_GET_EXP (p) - 1; 1041 } 1042 else 1043 { 1044 int digit; 1045 mp_limb_t msl = MPFR_MANT (p)[MPFR_LIMB_SIZE (p) - 1]; 1046 int rnd_bit = GMP_NUMB_BITS - 5; 1047 1048 /* pick up the 4 first bits */ 1049 digit = msl >> (rnd_bit+1); 1050 if (spec.rnd_mode == MPFR_RNDA 1051 || (spec.rnd_mode == MPFR_RNDU && MPFR_IS_POS (p)) 1052 || (spec.rnd_mode == MPFR_RNDD && MPFR_IS_NEG (p)) 1053 || (spec.rnd_mode == MPFR_RNDN 1054 && (msl & (MPFR_LIMB_ONE << rnd_bit)))) 1055 digit++; 1056 MPFR_ASSERTD ((0 <= digit) && (digit <= 15)); 1057 1058 str = (char *)(*__gmp_allocate_func) (1 + np->ip_size); 1059 str[0] = num_to_text [digit]; 1060 str[1] = '\0'; 1061 np->ip_ptr = register_string (np->sl, str); 1062 1063 exp = MPFR_GET_EXP (p) - 4; 1064 } 1065 1066 if (uppercase) 1067 /* All digits in upper case */ 1068 { 1069 char *s1 = str; 1070 while (*s1) 1071 { 1072 switch (*s1) 1073 { 1074 case 'a': 1075 *s1 = 'A'; 1076 break; 1077 case 'b': 1078 *s1 = 'B'; 1079 break; 1080 case 'c': 1081 *s1 = 'C'; 1082 break; 1083 case 'd': 1084 *s1 = 'D'; 1085 break; 1086 case 'e': 1087 *s1 = 'E'; 1088 break; 1089 case 'f': 1090 *s1 = 'F'; 1091 break; 1092 } 1093 s1++; 1094 } 1095 } 1096 1097 if (spec.spec == 'b' || spec.prec != 0) 1098 /* compute the number of digits in fractional part */ 1099 { 1100 char *ptr; 1101 size_t str_len; 1102 1103 /* the sign has been skipped, skip also the first digit */ 1104 ++str; 1105 str_len = strlen (str); 1106 ptr = str + str_len - 1; /* points to the end of str */ 1107 1108 if (spec.prec < 0) 1109 /* remove trailing zeros, if any */ 1110 { 1111 while ((*ptr == '0') && (str_len != 0)) 1112 { 1113 --ptr; 1114 --str_len; 1115 } 1116 } 1117 1118 if (str_len > INT_MAX) 1119 /* too many digits in fractional part */ 1120 return -1; 1121 1122 if (str_len != 0) 1123 /* there are some non-zero digits in fractional part */ 1124 { 1125 np->fp_ptr = str; 1126 np->fp_size = str_len; 1127 if ((int) str_len < spec.prec) 1128 np->fp_trailing_zeros = spec.prec - str_len; 1129 } 1130 } 1131 1132 /* decimal point */ 1133 if ((np->fp_size != 0) || spec.alt) 1134 np->point = MPFR_DECIMAL_POINT; 1135 1136 /* the exponent part contains the character 'p', or 'P' plus the sign 1137 character plus at least one digit and only as many more digits as 1138 necessary to represent the exponent. 1139 We assume that |EXP| < 10^INT_MAX. */ 1140 np->exp_size = 3; 1141 { 1142 mpfr_uexp_t x; 1143 1144 x = SAFE_ABS (mpfr_uexp_t, exp); 1145 while (x > 9) 1146 { 1147 np->exp_size++; 1148 x /= 10; 1149 } 1150 } 1151 str = (char *) (*__gmp_allocate_func) (1 + np->exp_size); 1152 np->exp_ptr = register_string (np->sl, str); 1153 { 1154 char exp_fmt[8]; /* contains at most 7 characters like in "p%+.1i", 1155 or "P%+.2li" */ 1156 1157 exp_fmt[0] = uppercase ? 'P' : 'p'; 1158 exp_fmt[1] = '\0'; 1159 strcat (exp_fmt, "%+.1" MPFR_EXP_FORMAT_SPEC); 1160 1161 if (sprintf (str, exp_fmt, exp) < 0) 1162 return -1; 1163 } 1164 1165 return 0; 1166} 1167 1168/* Determine the different parts of the string representation of the regular 1169 number P when SPEC.SPEC is 'e', 'E', 'g', or 'G'. 1170 1171 return -1 if some field > INT_MAX */ 1172static int 1173regular_eg (struct number_parts *np, mpfr_srcptr p, 1174 const struct printf_spec spec) 1175{ 1176 char *str; 1177 mpfr_exp_t exp; 1178 1179 const int uppercase = spec.spec == 'E' || spec.spec == 'G'; 1180 const int spec_g = spec.spec == 'g' || spec.spec == 'G'; 1181 const int keep_trailing_zeros = (spec_g && spec.alt) 1182 || (!spec_g && (spec.prec > 0)); 1183 1184 /* sign */ 1185 if (MPFR_IS_NEG (p)) 1186 np->sign = '-'; 1187 else if (spec.showsign || spec.space) 1188 np->sign = spec.showsign ? '+' : ' '; 1189 1190 /* integral part */ 1191 np->ip_size = 1; 1192 { 1193 size_t nsd; 1194 1195 /* Number of significant digits: 1196 - if no given precision, then let mpfr_get_str determine it, 1197 - if a precision is specified, then one digit before decimal point 1198 plus SPEC.PREC after it. 1199 We use the fact here that mpfr_get_str allows us to ask for only one 1200 significant digit when the base is not a power of 2. */ 1201 nsd = (spec.prec < 0) ? 0 : spec.prec + np->ip_size; 1202 str = mpfr_get_str (0, &exp, 10, nsd, p, spec.rnd_mode); 1203 } 1204 register_string (np->sl, str); 1205 np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign if any */ 1206 1207 if (spec.prec != 0) 1208 /* compute the number of digits in fractional part */ 1209 { 1210 char *ptr; 1211 size_t str_len; 1212 1213 /* the sign has been skipped, skip also the first digit */ 1214 ++str; 1215 str_len = strlen (str); 1216 ptr = str + str_len - 1; /* points to the end of str */ 1217 1218 if (!keep_trailing_zeros) 1219 /* remove trailing zeros, if any */ 1220 { 1221 while ((*ptr == '0') && (str_len != 0)) 1222 { 1223 --ptr; 1224 --str_len; 1225 } 1226 } 1227 1228 if (str_len > INT_MAX) 1229 /* too many digits in fractional part */ 1230 return -1; 1231 1232 if (str_len != 0) 1233 /* there are some non-zero digits in fractional part */ 1234 { 1235 np->fp_ptr = str; 1236 np->fp_size = str_len; 1237 if ((!spec_g || spec.alt) && (spec.prec > 0) 1238 && ((int)str_len < spec.prec)) 1239 /* add missing trailing zeros */ 1240 np->fp_trailing_zeros = spec.prec - str_len; 1241 } 1242 } 1243 1244 /* decimal point */ 1245 if (np->fp_size != 0 || spec.alt) 1246 np->point = MPFR_DECIMAL_POINT; 1247 1248 /* EXP is the exponent for decimal point BEFORE the first digit, we want 1249 the exponent for decimal point AFTER the first digit. 1250 Here, no possible overflow because exp < MPFR_EXP (p) / 3 */ 1251 exp--; 1252 1253 /* the exponent part contains the character 'e', or 'E' plus the sign 1254 character plus at least two digits and only as many more digits as 1255 necessary to represent the exponent. 1256 We assume that |EXP| < 10^INT_MAX. */ 1257 np->exp_size = 3; 1258 { 1259 mpfr_uexp_t x; 1260 1261 x = SAFE_ABS (mpfr_uexp_t, exp); 1262 while (x > 9) 1263 { 1264 np->exp_size++; 1265 x /= 10; 1266 } 1267 } 1268 if (np->exp_size < 4) 1269 np->exp_size = 4; 1270 1271 str = (char *) (*__gmp_allocate_func) (1 + np->exp_size); 1272 np->exp_ptr = register_string (np->sl, str); 1273 1274 { 1275 char exp_fmt[8]; /* e.g. "e%+.2i", or "E%+.2li" */ 1276 1277 exp_fmt[0] = uppercase ? 'E' : 'e'; 1278 exp_fmt[1] = '\0'; 1279 strcat (exp_fmt, "%+.2" MPFR_EXP_FORMAT_SPEC); 1280 1281 if (sprintf (str, exp_fmt, exp) < 0) 1282 return -1; 1283 } 1284 1285 return 0; 1286} 1287 1288/* Determine the different parts of the string representation of the regular 1289 number P when SPEC.SPEC is 'f', 'F', 'g', or 'G'. 1290 1291 return -1 if some field of number_parts is greater than INT_MAX */ 1292static int 1293regular_fg (struct number_parts *np, mpfr_srcptr p, 1294 const struct printf_spec spec) 1295{ 1296 mpfr_exp_t exp; 1297 char * str; 1298 const int spec_g = (spec.spec == 'g' || spec.spec == 'G'); 1299 const int keep_trailing_zeros = spec_g && spec.alt; 1300 1301 /* WARNING: an empty precision field is forbidden (it means precision = 6 1302 and it should have been changed to 6 before the function call) */ 1303 MPFR_ASSERTD (spec.prec >= 0); 1304 1305 /* sign */ 1306 if (MPFR_IS_NEG (p)) 1307 np->sign = '-'; 1308 else if (spec.showsign || spec.space) 1309 np->sign = spec.showsign ? '+' : ' '; 1310 1311 if (MPFR_GET_EXP (p) <= 0) 1312 /* 0 < |p| < 1 */ 1313 { 1314 /* Most of the time, integral part is 0 */ 1315 np->ip_size = 1; 1316 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size); 1317 str[0] = '0'; 1318 str[1] = '\0'; 1319 np->ip_ptr = register_string (np->sl, str); 1320 1321 if (spec.prec == 0) 1322 /* only two possibilities: either 1 or 0. */ 1323 { 1324 mpfr_t y; 1325 /* y = abs(p) */ 1326 MPFR_ALIAS (y, p, 1, MPFR_EXP (p)); 1327 1328 if (spec.rnd_mode == MPFR_RNDA 1329 || (spec.rnd_mode == MPFR_RNDD && MPFR_IS_NEG (p)) 1330 || (spec.rnd_mode == MPFR_RNDU && MPFR_IS_POS (p)) 1331 || (spec.rnd_mode == MPFR_RNDN && mpfr_cmp_d (y, 0.5) > 0)) 1332 /* rounded up to 1: one digit '1' in integral part. 1333 note that 0.5 is rounded to 0 with RNDN (round ties to even) */ 1334 np->ip_ptr[0] = '1'; 1335 } 1336 else 1337 { 1338 /* exp = position of the most significant decimal digit. */ 1339 round_to_10_power (&exp, p, 0, MPFR_RNDZ); 1340 MPFR_ASSERTD (exp < 0); 1341 1342 if (exp < -spec.prec) 1343 /* only the last digit may be non zero */ 1344 { 1345 int round_away; 1346 switch (spec.rnd_mode) 1347 { 1348 case MPFR_RNDA: 1349 round_away = 1; 1350 break; 1351 case MPFR_RNDD: 1352 round_away = MPFR_IS_NEG (p); 1353 break; 1354 case MPFR_RNDU: 1355 round_away = MPFR_IS_POS (p); 1356 break; 1357 case MPFR_RNDN: 1358 { 1359 /* compare |p| to y = 0.5*10^(-spec.prec) */ 1360 mpfr_t y; 1361 mpfr_exp_t e = MAX (MPFR_PREC (p), 56); 1362 mpfr_init2 (y, e + 8); 1363 do 1364 { 1365 /* find a lower approximation of 1366 0.5*10^(-spec.prec) different from |p| */ 1367 e += 8; 1368 mpfr_set_prec (y, e); 1369 mpfr_set_si (y, -spec.prec, MPFR_RNDN); 1370 mpfr_exp10 (y, y, MPFR_RNDD); 1371 mpfr_div_2ui (y, y, 1, MPFR_RNDN); 1372 } while (mpfr_cmpabs (y, p) == 0); 1373 1374 round_away = mpfr_cmpabs (y, p) < 0; 1375 mpfr_clear (y); 1376 } 1377 break; 1378 default: 1379 round_away = 0; 1380 } 1381 1382 if (round_away) 1383 /* round away from zero: the last output digit is '1' */ 1384 { 1385 np->fp_leading_zeros = spec.prec - 1; 1386 1387 np->fp_size = 1; 1388 str = 1389 (char *) (*__gmp_allocate_func) (1 + np->fp_size); 1390 str[0] = '1'; 1391 str[1] = '\0'; 1392 np->fp_ptr = register_string (np->sl, str); 1393 } 1394 else 1395 /* only zeros in fractional part */ 1396 { 1397 MPFR_ASSERTD (!spec_g); 1398 np->fp_leading_zeros = spec.prec; 1399 } 1400 } 1401 else 1402 /* the most significant digits are the last 1403 spec.prec + exp + 1 digits in fractional part */ 1404 { 1405 char *ptr; 1406 size_t str_len; 1407 size_t nsd = spec.prec + exp + 1; 1408 /* WARNING: nsd may equal 1, but here we use the fact that 1409 mpfr_get_str can return one digit with base ten 1410 (undocumented feature, see comments in get_str.c) */ 1411 1412 str = mpfr_get_str (NULL, &exp, 10, nsd, p, spec.rnd_mode); 1413 register_string (np->sl, str); 1414 if (MPFR_IS_NEG (p)) 1415 ++str; 1416 if (exp == 1) 1417 /* round up to 1 */ 1418 { 1419 MPFR_ASSERTD (str[0] == '1'); 1420 np->ip_ptr[0] = '1'; 1421 if (!spec_g || spec.alt) 1422 np->fp_leading_zeros = spec.prec; 1423 } 1424 else 1425 { 1426 /* skip sign */ 1427 np->fp_ptr = str; 1428 np->fp_leading_zeros = -exp; 1429 MPFR_ASSERTD (exp <= 0); 1430 1431 str_len = strlen (str); /* the sign has been skipped */ 1432 ptr = str + str_len - 1; /* points to the end of str */ 1433 1434 if (!keep_trailing_zeros) 1435 /* remove trailing zeros, if any */ 1436 { 1437 while ((*ptr == '0') && str_len) 1438 { 1439 --ptr; 1440 --str_len; 1441 } 1442 } 1443 1444 if (str_len > INT_MAX) 1445 /* too many digits in fractional part */ 1446 return -1; 1447 1448 MPFR_ASSERTD (str_len > 0); 1449 np->fp_size = str_len; 1450 1451 if ((!spec_g || spec.alt) 1452 && spec.prec > 0 1453 && (np->fp_leading_zeros + np->fp_size < spec.prec)) 1454 /* add missing trailing zeros */ 1455 np->fp_trailing_zeros = spec.prec - np->fp_leading_zeros 1456 - np->fp_size; 1457 } 1458 } 1459 } 1460 1461 if (spec.alt || np->fp_leading_zeros != 0 || np->fp_size != 0 1462 || np->fp_trailing_zeros != 0) 1463 np->point = MPFR_DECIMAL_POINT; 1464 } 1465 else 1466 /* 1 <= |p| */ 1467 { 1468 size_t nsd; /* Number of significant digits */ 1469 1470 /* Determine the position of the most significant decimal digit. */ 1471 round_to_10_power (&exp, p, 0, MPFR_RNDZ); 1472 1473 MPFR_ASSERTD (exp >= 0); 1474 if (exp > INT_MAX) 1475 /* P is too large to print all its integral part digits */ 1476 return -1; 1477 1478 np->ip_size = exp + 1; 1479 1480 nsd = spec.prec + np->ip_size; 1481 str = mpfr_get_str (NULL, &exp, 10, nsd, p, spec.rnd_mode); 1482 register_string (np->sl, str); 1483 np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign */ 1484 1485 if (spec.group) 1486 /* thousands separator in integral part */ 1487 np->thousands_sep = MPFR_THOUSANDS_SEPARATOR; 1488 1489 if (nsd == 0 || (spec_g && !spec.alt)) 1490 /* compute how much non-zero digits in integral and fractional 1491 parts */ 1492 { 1493 size_t str_len; 1494 str_len = strlen (str); /* note: the sign has been skipped */ 1495 1496 if (exp > str_len) 1497 /* mpfr_get_str doesn't give the trailing zeros when p is a 1498 multiple of 10 (p integer, so no fractional part) */ 1499 { 1500 np->ip_trailing_zeros = exp - str_len; 1501 np->ip_size = str_len; 1502 if (spec.alt) 1503 np->point = MPFR_DECIMAL_POINT; 1504 } 1505 else 1506 /* str may contain some digits which are in fractional part */ 1507 { 1508 char *ptr; 1509 1510 ptr = str + str_len - 1; /* points to the end of str */ 1511 str_len -= np->ip_size; /* number of digits in fractional 1512 part */ 1513 1514 if (!keep_trailing_zeros) 1515 /* remove trailing zeros, if any */ 1516 { 1517 while ((*ptr == '0') && (str_len != 0)) 1518 { 1519 --ptr; 1520 --str_len; 1521 } 1522 } 1523 1524 if (str_len > INT_MAX) 1525 /* too many digits in fractional part */ 1526 return -1; 1527 1528 if (str_len != 0) 1529 /* some digits in fractional part */ 1530 { 1531 np->point = MPFR_DECIMAL_POINT; 1532 np->fp_ptr = str + np->ip_size; 1533 np->fp_size = str_len; 1534 } 1535 } 1536 } 1537 else 1538 /* spec.prec digits in fractional part */ 1539 { 1540 if (np->ip_size == exp - 1) 1541 /* the absolute value of the number has been rounded up to a power 1542 of ten. 1543 Insert an additional zero in integral part and put the rest of 1544 them in fractional part. */ 1545 np->ip_trailing_zeros = 1; 1546 1547 if (spec.prec != 0) 1548 { 1549 MPFR_ASSERTD (np->ip_size + np->ip_trailing_zeros == exp); 1550 MPFR_ASSERTD (np->ip_size + spec.prec == nsd); 1551 1552 np->point = MPFR_DECIMAL_POINT; 1553 np->fp_ptr = str + np->ip_size; 1554 np->fp_size = spec.prec; 1555 } 1556 else if (spec.alt) 1557 np->point = MPFR_DECIMAL_POINT; 1558 } 1559 } 1560 1561 return 0; 1562} 1563 1564/* partition_number determines the different parts of the string 1565 representation of the number p according to the given specification. 1566 partition_number initializes the given structure np, so all previous 1567 information in that variable is lost. 1568 return the total number of characters to be written. 1569 return -1 if an error occured, in that case np's fields are in an undefined 1570 state but all string buffers have been freed. */ 1571static int 1572partition_number (struct number_parts *np, mpfr_srcptr p, 1573 struct printf_spec spec) 1574{ 1575 char *str; 1576 long total; 1577 int uppercase; 1578 1579 /* WARNING: left justification means right space padding */ 1580 np->pad_type = spec.left ? RIGHT : spec.pad == '0' ? LEADING_ZEROS : LEFT; 1581 np->pad_size = 0; 1582 np->sign = '\0'; 1583 np->prefix_ptr =NULL; 1584 np->prefix_size = 0; 1585 np->thousands_sep = '\0'; 1586 np->ip_ptr = NULL; 1587 np->ip_size = 0; 1588 np->ip_trailing_zeros = 0; 1589 np->point = '\0'; 1590 np->fp_leading_zeros = 0; 1591 np->fp_ptr = NULL; 1592 np->fp_size = 0; 1593 np->fp_trailing_zeros = 0; 1594 np->exp_ptr = NULL; 1595 np->exp_size = 0; 1596 np->sl = (struct string_list *) 1597 (*__gmp_allocate_func) (sizeof (struct string_list)); 1598 init_string_list (np->sl); 1599 1600 uppercase = spec.spec == 'A' || spec.spec == 'E' || spec.spec == 'F' 1601 || spec.spec == 'G'; 1602 1603 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (p))) 1604 { 1605 if (MPFR_IS_NAN (p)) 1606 { 1607 if (np->pad_type == LEADING_ZEROS) 1608 /* don't want "0000nan", change to right justification padding 1609 with left spaces instead */ 1610 np->pad_type = LEFT; 1611 1612 if (uppercase) 1613 { 1614 np->ip_size = MPFR_NAN_STRING_LENGTH; 1615 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size); 1616 strcpy (str, MPFR_NAN_STRING_UC); 1617 np->ip_ptr = register_string (np->sl, str); 1618 } 1619 else 1620 { 1621 np->ip_size = MPFR_NAN_STRING_LENGTH; 1622 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size); 1623 strcpy (str, MPFR_NAN_STRING_LC); 1624 np->ip_ptr = register_string (np->sl, str); 1625 } 1626 } 1627 else if (MPFR_IS_INF (p)) 1628 { 1629 if (np->pad_type == LEADING_ZEROS) 1630 /* don't want "0000inf", change to right justification padding 1631 with left spaces instead */ 1632 np->pad_type = LEFT; 1633 1634 if (MPFR_IS_NEG (p)) 1635 np->sign = '-'; 1636 1637 if (uppercase) 1638 { 1639 np->ip_size = MPFR_INF_STRING_LENGTH; 1640 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size); 1641 strcpy (str, MPFR_INF_STRING_UC); 1642 np->ip_ptr = register_string (np->sl, str); 1643 } 1644 else 1645 { 1646 np->ip_size = MPFR_INF_STRING_LENGTH; 1647 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size); 1648 strcpy (str, MPFR_INF_STRING_LC); 1649 np->ip_ptr = register_string (np->sl, str); 1650 } 1651 } 1652 else 1653 /* p == 0 */ 1654 { 1655 /* note: for 'g' spec, zero is always displayed with 'f'-style with 1656 precision spec.prec - 1 and the trailing zeros are removed unless 1657 the flag '#' is used. */ 1658 if (MPFR_IS_NEG (p)) 1659 /* signed zero */ 1660 np->sign = '-'; 1661 else if (spec.showsign || spec.space) 1662 np->sign = spec.showsign ? '+' : ' '; 1663 1664 if (spec.spec == 'a' || spec.spec == 'A') 1665 /* prefix part */ 1666 { 1667 np->prefix_size = 2; 1668 str = (char *) (*__gmp_allocate_func) (1 + np->prefix_size); 1669 str[0] = '0'; 1670 str[1] = uppercase ? 'X' : 'x'; 1671 str[2] = '\0'; 1672 np->prefix_ptr = register_string (np->sl, str); 1673 } 1674 1675 /* integral part */ 1676 np->ip_size = 1; 1677 str = (char *) (*__gmp_allocate_func) (1 + np->ip_size); 1678 str[0] = '0'; 1679 str[1] = '\0'; 1680 np->ip_ptr = register_string (np->sl, str); 1681 1682 if (spec.prec > 0 1683 && ((spec.spec != 'g' && spec.spec != 'G') || spec.alt)) 1684 /* fractional part */ 1685 { 1686 np->point = MPFR_DECIMAL_POINT; 1687 np->fp_trailing_zeros = (spec.spec == 'g' && spec.spec == 'G') ? 1688 spec.prec - 1 : spec.prec; 1689 } 1690 else if (spec.alt) 1691 np->point = MPFR_DECIMAL_POINT; 1692 1693 if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b' 1694 || spec.spec == 'e' || spec.spec == 'E') 1695 /* exponent part */ 1696 { 1697 np->exp_size = (spec.spec == 'e' || spec.spec == 'E') ? 4 : 3; 1698 str = (char *) (*__gmp_allocate_func) (1 + np->exp_size); 1699 if (spec.spec == 'e' || spec.spec == 'E') 1700 strcpy (str, uppercase ? "E+00" : "e+00"); 1701 else 1702 strcpy (str, uppercase ? "P+0" : "p+0"); 1703 np->exp_ptr = register_string (np->sl, str); 1704 } 1705 } 1706 } 1707 else 1708 /* regular p, p != 0 */ 1709 { 1710 if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b') 1711 { 1712 if (regular_ab (np, p, spec) == -1) 1713 goto error; 1714 } 1715 else if (spec.spec == 'f' || spec.spec == 'F') 1716 { 1717 if (spec.prec == -1) 1718 spec.prec = 6; 1719 if (regular_fg (np, p, spec) == -1) 1720 goto error; 1721 } 1722 else if (spec.spec == 'e' || spec.spec == 'E') 1723 { 1724 if (regular_eg (np, p, spec) == -1) 1725 goto error; 1726 } 1727 else 1728 /* %g case */ 1729 { 1730 /* Use the C99 rules: 1731 if T > X >= -4 then the conversion is with style 'f'/'F' and 1732 precision T-(X+1). 1733 otherwise, the conversion is with style 'e'/'E' and 1734 precision T-1. 1735 where T is the threshold computed below and X is the exponent 1736 that would be displayed with style 'e' and precision T-1. */ 1737 int threshold; 1738 mpfr_exp_t x; 1739 1740 threshold = (spec.prec < 0) ? 6 : (spec.prec == 0) ? 1 : spec.prec; 1741 round_to_10_power (&x, p, threshold - 1, spec.rnd_mode); 1742 1743 if (threshold > x && x >= -4) 1744 { 1745 /* the conversion is with style 'f' */ 1746 spec.prec = threshold - x - 1; 1747 1748 if (regular_fg (np, p, spec) == -1) 1749 goto error; 1750 } 1751 else 1752 { 1753 spec.prec = threshold - 1; 1754 1755 if (regular_eg (np, p, spec) == -1) 1756 goto error; 1757 } 1758 } 1759 } 1760 1761 /* compute the number of characters to be written verifying it is not too 1762 much */ 1763 total = np->sign ? 1 : 0; 1764 total += np->prefix_size; 1765 total += np->ip_size; 1766 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX)) 1767 goto error; 1768 total += np->ip_trailing_zeros; 1769 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX)) 1770 goto error; 1771 if (np->thousands_sep) 1772 /* ' flag, style f and the thousands separator in current locale is not 1773 reduced to the null character */ 1774 total += (np->ip_size + np->ip_trailing_zeros) / 3; 1775 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX)) 1776 goto error; 1777 if (np->point) 1778 ++total; 1779 total += np->fp_leading_zeros; 1780 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX)) 1781 goto error; 1782 total += np->fp_size; 1783 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX)) 1784 goto error; 1785 total += np->fp_trailing_zeros; 1786 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX)) 1787 goto error; 1788 total += np->exp_size; 1789 if (MPFR_UNLIKELY (total < 0 || total > INT_MAX)) 1790 goto error; 1791 1792 if (spec.width > total) 1793 /* pad with spaces or zeros depending on np->pad_type */ 1794 { 1795 np->pad_size = spec.width - total; 1796 total += np->pad_size; /* here total == spec.width, 1797 so 0 < total < INT_MAX */ 1798 } 1799 1800 return total; 1801 1802 error: 1803 clear_string_list (np->sl); 1804 np->prefix_ptr = NULL; 1805 np->ip_ptr = NULL; 1806 np->fp_ptr = NULL; 1807 np->exp_ptr = NULL; 1808 return -1; 1809} 1810 1811/* sprnt_fp prints a mpfr_t according to spec.spec specification. 1812 1813 return the size of the string (not counting the terminating '\0') 1814 return -1 if the built string is too long (i.e. has more than 1815 INT_MAX characters). */ 1816static int 1817sprnt_fp (struct string_buffer *buf, mpfr_srcptr p, 1818 const struct printf_spec spec) 1819{ 1820 int length; 1821 struct number_parts np; 1822 1823 length = partition_number (&np, p, spec); 1824 if (length < 0) 1825 return -1; 1826 1827 /* right justification padding with left spaces */ 1828 if (np.pad_type == LEFT && np.pad_size != 0) 1829 buffer_pad (buf, ' ', np.pad_size); 1830 1831 /* sign character (may be '-', '+', or ' ') */ 1832 if (np.sign) 1833 buffer_pad (buf, np.sign, 1); 1834 1835 /* prefix part */ 1836 if (np.prefix_ptr) 1837 buffer_cat (buf, np.prefix_ptr, np.prefix_size); 1838 1839 /* right justification padding with leading zeros */ 1840 if (np.pad_type == LEADING_ZEROS && np.pad_size != 0) 1841 buffer_pad (buf, '0', np.pad_size); 1842 1843 /* integral part (may also be "nan" or "inf") */ 1844 MPFR_ASSERTN (np.ip_ptr != NULL); /* never empty */ 1845 if (MPFR_UNLIKELY (np.thousands_sep)) 1846 buffer_sandwich (buf, np.ip_ptr, np.ip_size, np.ip_trailing_zeros, 1847 np.thousands_sep); 1848 else 1849 { 1850 buffer_cat (buf, np.ip_ptr, np.ip_size); 1851 1852 /* trailing zeros in integral part */ 1853 if (np.ip_trailing_zeros != 0) 1854 buffer_pad (buf, '0', np.ip_trailing_zeros); 1855 } 1856 1857 /* decimal point */ 1858 if (np.point) 1859 buffer_pad (buf, np.point, 1); 1860 1861 /* leading zeros in fractional part */ 1862 if (np.fp_leading_zeros != 0) 1863 buffer_pad (buf, '0', np.fp_leading_zeros); 1864 1865 /* significant digits in fractional part */ 1866 if (np.fp_ptr) 1867 buffer_cat (buf, np.fp_ptr, np.fp_size); 1868 1869 /* trailing zeros in fractional part */ 1870 if (np.fp_trailing_zeros != 0) 1871 buffer_pad (buf, '0', np.fp_trailing_zeros); 1872 1873 /* exponent part */ 1874 if (np.exp_ptr) 1875 buffer_cat (buf, np.exp_ptr, np.exp_size); 1876 1877 /* left justication padding with right spaces */ 1878 if (np.pad_type == RIGHT && np.pad_size != 0) 1879 buffer_pad (buf, ' ', np.pad_size); 1880 1881 clear_string_list (np.sl); 1882 return length; 1883} 1884 1885int 1886mpfr_vasprintf (char **ptr, const char *fmt, va_list ap) 1887{ 1888 struct string_buffer buf; 1889 size_t nbchar; 1890 1891 /* informations on the conversion specification filled by the parser */ 1892 struct printf_spec spec; 1893 /* flag raised when previous part of fmt need to be processed by 1894 gmp_vsnprintf */ 1895 int xgmp_fmt_flag; 1896 /* beginning and end of the previous unprocessed part of fmt */ 1897 const char *start, *end; 1898 /* pointer to arguments for gmp_vasprintf */ 1899 va_list ap2; 1900 1901 MPFR_SAVE_EXPO_DECL (expo); 1902 MPFR_SAVE_EXPO_MARK (expo); 1903 1904 nbchar = 0; 1905 buffer_init (&buf, 4096); 1906 xgmp_fmt_flag = 0; 1907 va_copy (ap2, ap); 1908 start = fmt; 1909 while (*fmt) 1910 { 1911 /* Look for the next format specification */ 1912 while ((*fmt) && (*fmt != '%')) 1913 ++fmt; 1914 1915 if (*fmt == '\0') 1916 break; 1917 1918 if (*++fmt == '%') 1919 /* %%: go one step further otherwise the second '%' would be 1920 considered as a new conversion specification introducing 1921 character */ 1922 { 1923 ++fmt; 1924 xgmp_fmt_flag = 1; 1925 continue; 1926 } 1927 1928 end = fmt - 1; 1929 1930 /* format string analysis */ 1931 specinfo_init (&spec); 1932 fmt = parse_flags (fmt, &spec); 1933 1934 READ_INT (ap, fmt, spec, width, width_analysis); 1935 width_analysis: 1936 if (spec.width < 0) 1937 { 1938 spec.left = 1; 1939 spec.width = -spec.width; 1940 MPFR_ASSERTN (spec.width < INT_MAX); 1941 } 1942 if (*fmt == '.') 1943 { 1944 const char *f = ++fmt; 1945 READ_INT (ap, fmt, spec, prec, prec_analysis); 1946 prec_analysis: 1947 if (f == fmt) 1948 spec.prec = -1; 1949 } 1950 else 1951 spec.prec = -1; 1952 1953 fmt = parse_arg_type (fmt, &spec); 1954 if (spec.arg_type == UNSUPPORTED) 1955 /* the current architecture doesn't support this type */ 1956 { 1957 goto error; 1958 } 1959 else if (spec.arg_type == MPFR_ARG) 1960 { 1961 switch (*fmt) 1962 { 1963 case '\0': 1964 break; 1965 case '*': 1966 ++fmt; 1967 spec.rnd_mode = (mpfr_rnd_t) va_arg (ap, int); 1968 break; 1969 case 'D': 1970 ++fmt; 1971 spec.rnd_mode = MPFR_RNDD; 1972 break; 1973 case 'U': 1974 ++fmt; 1975 spec.rnd_mode = MPFR_RNDU; 1976 break; 1977 case 'Y': 1978 ++fmt; 1979 spec.rnd_mode = MPFR_RNDA; 1980 break; 1981 case 'Z': 1982 ++fmt; 1983 spec.rnd_mode = MPFR_RNDZ; 1984 break; 1985 case 'N': 1986 ++fmt; 1987 default: 1988 spec.rnd_mode = MPFR_RNDN; 1989 } 1990 } 1991 1992 spec.spec = *fmt; 1993 if (!specinfo_is_valid (spec)) 1994 goto error; 1995 1996 if (*fmt) 1997 fmt++; 1998 1999 /* Format processing */ 2000 if (spec.spec == '\0') 2001 /* end of the format string */ 2002 break; 2003 else if (spec.spec == 'n') 2004 /* put the number of characters written so far in the location pointed 2005 by the next va_list argument; the types of pointer accepted are the 2006 same as in GMP (except unsupported quad_t) plus pointer to a mpfr_t 2007 so as to be able to accept the same format strings. */ 2008 { 2009 void *p; 2010 size_t nchar; 2011 2012 p = va_arg (ap, void *); 2013 FLUSH (xgmp_fmt_flag, start, end, ap2, &buf); 2014 va_end (ap2); 2015 start = fmt; 2016 nchar = buf.curr - buf.start; 2017 2018 switch (spec.arg_type) 2019 { 2020 case CHAR_ARG: 2021 *(char *) p = (char) nchar; 2022 break; 2023 case SHORT_ARG: 2024 *(short *) p = (short) nchar; 2025 break; 2026 case LONG_ARG: 2027 *(long *) p = (long) nchar; 2028 break; 2029#ifdef HAVE_LONG_LONG 2030 case LONG_LONG_ARG: 2031 *(long long *) p = (long long) nchar; 2032 break; 2033#endif 2034#ifdef _MPFR_H_HAVE_INTMAX_T 2035 case INTMAX_ARG: 2036 *(intmax_t *) p = (intmax_t) nchar; 2037 break; 2038#endif 2039 case SIZE_ARG: 2040 *(size_t *) p = nchar; 2041 break; 2042 case PTRDIFF_ARG: 2043 *(ptrdiff_t *) p = (ptrdiff_t) nchar; 2044 break; 2045 case MPF_ARG: 2046 mpf_set_ui ((mpf_ptr) p, (unsigned long) nchar); 2047 break; 2048 case MPQ_ARG: 2049 mpq_set_ui ((mpq_ptr) p, (unsigned long) nchar, 1L); 2050 break; 2051 case MP_LIMB_ARG: 2052 *(mp_limb_t *) p = (mp_limb_t) nchar; 2053 break; 2054 case MP_LIMB_ARRAY_ARG: 2055 { 2056 mp_limb_t *q = (mp_limb_t *) p; 2057 mp_size_t n; 2058 n = va_arg (ap, mp_size_t); 2059 if (n < 0) 2060 n = -n; 2061 else if (n == 0) 2062 break; 2063 2064 /* we assume here that mp_limb_t is wider than int */ 2065 *q = (mp_limb_t) nchar; 2066 while (--n != 0) 2067 { 2068 q++; 2069 *q = (mp_limb_t) 0; 2070 } 2071 } 2072 break; 2073 case MPZ_ARG: 2074 mpz_set_ui ((mpz_ptr) p, (unsigned long) nchar); 2075 break; 2076 2077 case MPFR_ARG: 2078 mpfr_set_ui ((mpfr_ptr) p, (unsigned long) nchar, 2079 spec.rnd_mode); 2080 break; 2081 2082 default: 2083 *(int *) p = (int) nchar; 2084 } 2085 va_copy (ap2, ap); /* after the switch, due to MP_LIMB_ARRAY_ARG 2086 case */ 2087 } 2088 else if (spec.arg_type == MPFR_PREC_ARG) 2089 /* output mpfr_prec_t variable */ 2090 { 2091 char *s; 2092 char format[MPFR_PREC_FORMAT_SIZE + 6]; /* see examples below */ 2093 size_t length; 2094 mpfr_prec_t prec; 2095 prec = va_arg (ap, mpfr_prec_t); 2096 2097 FLUSH (xgmp_fmt_flag, start, end, ap2, &buf); 2098 va_end (ap2); 2099 va_copy (ap2, ap); 2100 start = fmt; 2101 2102 /* construct format string, like "%*.*hu" "%*.*u" or "%*.*lu" */ 2103 format[0] = '%'; 2104 format[1] = '*'; 2105 format[2] = '.'; 2106 format[3] = '*'; 2107 format[4] = '\0'; 2108 strcat (format, MPFR_PREC_FORMAT_TYPE); 2109 format[4 + MPFR_PREC_FORMAT_SIZE] = spec.spec; 2110 format[5 + MPFR_PREC_FORMAT_SIZE] = '\0'; 2111 length = gmp_asprintf (&s, format, spec.width, spec.prec, prec); 2112 if (buf.size <= INT_MAX - length) 2113 { 2114 buffer_cat (&buf, s, length); 2115 mpfr_free_str (s); 2116 } 2117 else 2118 { 2119 mpfr_free_str (s); 2120 goto overflow_error; 2121 } 2122 } 2123 else if (spec.arg_type == MPFR_ARG) 2124 /* output a mpfr_t variable */ 2125 { 2126 mpfr_srcptr p; 2127 2128 p = va_arg (ap, mpfr_srcptr); 2129 2130 FLUSH (xgmp_fmt_flag, start, end, ap2, &buf); 2131 va_end (ap2); 2132 va_copy (ap2, ap); 2133 start = fmt; 2134 2135 switch (spec.spec) 2136 { 2137 case 'a': 2138 case 'A': 2139 case 'b': 2140 case 'e': 2141 case 'E': 2142 case 'f': 2143 case 'F': 2144 case 'g': 2145 case 'G': 2146 if (sprnt_fp (&buf, p, spec) < 0) 2147 goto overflow_error; 2148 break; 2149 2150 default: 2151 /* unsupported specifier */ 2152 goto error; 2153 } 2154 } 2155 else 2156 /* gmp_printf specification, step forward in the va_list */ 2157 { 2158 CONSUME_VA_ARG (spec, ap); 2159 xgmp_fmt_flag = 1; 2160 } 2161 } 2162 2163 if (start != fmt) 2164 FLUSH (xgmp_fmt_flag, start, fmt, ap2, &buf); 2165 2166 va_end (ap2); 2167 nbchar = buf.curr - buf.start; 2168 MPFR_ASSERTD (nbchar == strlen (buf.start)); 2169 buf.start = 2170 (char *) (*__gmp_reallocate_func) (buf.start, buf.size, nbchar + 1); 2171 buf.size = nbchar + 1; /* update needed for __gmp_free_func below when 2172 nbchar is too large (overflow_error) */ 2173 *ptr = buf.start; 2174 2175 /* If nbchar is larger than INT_MAX, the ISO C99 standard is silent, but 2176 POSIX says concerning the snprintf() function: 2177 "[EOVERFLOW] The value of n is greater than {INT_MAX} or the 2178 number of bytes needed to hold the output excluding the 2179 terminating null is greater than {INT_MAX}." See: 2180 http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html 2181 But it doesn't say anything concerning the other printf-like functions. 2182 A defect report has been submitted to austin-review-l (item 2532). 2183 So, for the time being, we return a negative value and set the erange 2184 flag, and set errno to EOVERFLOW in POSIX system. */ 2185 if (nbchar <= INT_MAX) 2186 { 2187 MPFR_SAVE_EXPO_FREE (expo); 2188 return nbchar; 2189 } 2190 2191 overflow_error: 2192 MPFR_SAVE_EXPO_UPDATE_FLAGS(expo, MPFR_FLAGS_ERANGE); 2193#ifdef EOVERFLOW 2194 errno = EOVERFLOW; 2195#endif 2196 2197 error: 2198 MPFR_SAVE_EXPO_FREE (expo); 2199 *ptr = NULL; 2200 (*__gmp_free_func) (buf.start, buf.size); 2201 2202 return -1; 2203} 2204 2205#endif /* HAVE_STDARG */ 2206