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