xref: /netbsd-src/external/lgpl3/mpfr/dist/src/vasprintf.c (revision 202963173a0b2c6212990c3f0aad56ef00baad1a)
1 /* mpfr_vasnprintf_aux -- helper function for the formatted output functions
2    (printf functions family).
3 
4 Copyright 2007-2023 Free Software Foundation, Inc.
5 Contributed by the AriC and Caramba 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 https://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 /* If the number of output characters is larger than INT_MAX, the
25    ISO C99 / C11 standards are silent, but POSIX[*] requires the
26    function to return a negative value and set errno to EOVERFLOW.
27    [*] The Open Group Base Specifications Issue 7, 2018 edition
28        IEEE Std 1003.1-2017 (Revision of IEEE Std 1003.1-2008)
29    https://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html
30    This follows a defect report submitted in 2007 to austin-review-l.
31    Even in case of such a failure (just because of the limitation on int),
32    we try to support %n, %ln, %jn when possible. That's why the sizes (or
33    lengths) are expressed using mpfr_intmax_t in the code below. */
34 
35 /* Notes about limitations on some platforms:
36 
37    Due to limitations from the C standard and GMP, if size_t < unsigned int
38    (which is allowed by the C standard but unlikely to occur on any
39    platform), the behavior is undefined for output that would reach
40    SIZE_MAX = (size_t) -1 (if the result cannot be delivered, there should
41    be an assertion failure, but this could not be tested).
42 
43    The stdarg(3) Linux man page says:
44       On some systems, va_end contains a closing '}' matching a '{' in
45       va_start, so that both macros must occur in the same function,
46       and in a way that allows this.
47    However, the only requirement from ISO C is that both macros must be
48    invoked in the same function (MPFR uses va_copy instead of va_start,
49    but the requirement is the same). Here, MPFR just follows ISO C.
50 */
51 
52 /* Needed due to the tests on HAVE_STDARG and MPFR_USE_MINI_GMP */
53 #ifdef HAVE_CONFIG_H
54 # include "config.h"
55 #endif
56 
57 /* The mpfr_printf-like functions are defined only if <stdarg.h> exists.
58    Since they use mpf_t, they cannot be defined with mini-gmp. */
59 #if defined(HAVE_STDARG) && !defined(MPFR_USE_MINI_GMP)
60 
61 #include <stdarg.h>
62 
63 #ifndef HAVE_VA_COPY
64 # ifdef HAVE___VA_COPY
65 #  define va_copy(dst,src) __va_copy(dst, src)
66 # else
67 /* autoconf manual advocates this fallback.
68    This is also the solution chosen by gmp */
69 #  define va_copy(dst,src) \
70   do { memcpy(&(dst), &(src), sizeof(va_list)); } while (0)
71 # endif /* HAVE___VA_COPY */
72 #endif /* HAVE_VA_COPY */
73 
74 #ifdef HAVE_WCHAR_H
75 #include <wchar.h>
76 #endif
77 
78 #if defined (__cplusplus)
79 #include <cstddef>
80 #else
81 #include <stddef.h>             /* for ptrdiff_t */
82 #endif
83 
84 #include <errno.h>
85 
86 #define MPFR_NEED_LONGLONG_H
87 #define MPFR_NEED_INTMAX_H
88 #include "mpfr-impl.h"
89 
90 /* Define a length modifier corresponding to mpfr_prec_t.
91    We use literal string instead of literal character so as to permit future
92    extension to long long int ("ll"). */
93 #if   _MPFR_PREC_FORMAT == 1
94 #define MPFR_PREC_FORMAT_TYPE "h"
95 #define MPFR_PREC_FORMAT_SIZE 1
96 #elif _MPFR_PREC_FORMAT == 2
97 #define MPFR_PREC_FORMAT_TYPE ""
98 #define MPFR_PREC_FORMAT_SIZE 0
99 #elif _MPFR_PREC_FORMAT == 3
100 #define MPFR_PREC_FORMAT_TYPE "l"
101 #define MPFR_PREC_FORMAT_SIZE 1
102 #else
103 #error "mpfr_prec_t size not supported"
104 #endif
105 
106 /* Output for special values defined in the C99 standard */
107 #define MPFR_NAN_STRING_LC "nan"
108 #define MPFR_NAN_STRING_UC "NAN"
109 #define MPFR_NAN_STRING_LENGTH 3
110 #define MPFR_INF_STRING_LC "inf"
111 #define MPFR_INF_STRING_UC "INF"
112 #define MPFR_INF_STRING_LENGTH 3
113 
114 #define DEFAULT_DECIMAL_PREC 6
115 
116 /* The implicit \0 is useless, but we do not write num_to_text[16]
117    otherwise g++ complains. */
118 static const char num_to_text[] = "0123456789abcdef";
119 
120 /* some macro and functions for parsing format string */
121 
122 /* Read an integer var of type mpfr_intmax_t. In case of overflow, set
123    overflow to 1.
124    The variable var must be 0 on input. If there are no digits, it is
125    left to 0.
126    This macro will be used to read the field width and the precision.
127    The behavior will be similar to ISO C99. Note that unless "*" is
128    used, the result will be non-negative (ISO C99 and C11 just specify
129    "optional decimal integer" for the precision, but the behavior with
130    a hardcoded negative integer is not explicitly defined, thus it is
131    undefined, so that it is fine to reject such integers; the C2x draft
132    now clarifies this: "an optional non-negative decimal integer").
133    Note: Since mpfr_intmax_t = int is theoretically possible, all values
134    of var are potentially valid values (via '*'). Hence the need of an
135    overflow flag instead of a special value that would indicate overflow.
136    Just saturating would not be OK either as the maximum value could be
137    meaningful with %jn and/or in the case mpfr_intmax_t = int, for
138    MPFR_PREC_ARG, i.e. one must be able to distinguish the maximum value
139    from an overflow.
140 */
141 #define READ_INT(ap, format, var)                                       \
142   do {                                                                  \
143     MPFR_ASSERTD ((var) == 0);                                          \
144     if (*(format) == '*')                                               \
145       {                                                                 \
146         (var) = va_arg ((ap), int);                                     \
147         ++(format);                                                     \
148       }                                                                 \
149     else                                                                \
150       for ( ; *(format) >= '0' && *(format) <= '9' ; ++(format))        \
151         if (!(overflow))                                                \
152           {                                                             \
153             if ((var) > MPFR_INTMAX_MAX / 10)                           \
154               (overflow) = 1;                                           \
155             else                                                        \
156               {                                                         \
157                 int _i;                                                 \
158                 (var) *= 10;                                            \
159                 _i = *(format) - '0';                                   \
160                 MPFR_ASSERTN (_i >= 0 && _i <= 9);                      \
161                 if ((var) > MPFR_INTMAX_MAX - _i)                       \
162                   (overflow) = 1;                                       \
163                 else                                                    \
164                   (var) += _i;                                          \
165               }                                                         \
166           }                                                             \
167   } while (0)
168 
169 /* arg_t contains all the types described by the 'type' field of the
170    format string */
171 enum arg_t
172   {
173     NONE,
174     CHAR_ARG,
175     SHORT_ARG,
176     LONG_ARG,
177     LONG_LONG_ARG,
178     INTMAX_ARG,
179     SIZE_ARG,
180     PTRDIFF_ARG,
181     LONG_DOUBLE_ARG,
182     MPF_ARG,
183     MPQ_ARG,
184     MP_LIMB_ARG,
185     MP_LIMB_ARRAY_ARG,
186     MPZ_ARG,
187     MPFR_PREC_ARG,
188     MPFR_ARG,
189     UNSUPPORTED
190   };
191 
192 /* Each conversion specification of the format string will be translated in a
193    printf_spec structure by the parser.
194    This structure is adapted from the GNU libc one. */
195 struct printf_spec
196 {
197   unsigned int alt:1;           /* # flag */
198   unsigned int space:1;         /* Space flag */
199   unsigned int left:1;          /* - flag */
200   unsigned int showsign:1;      /* + flag */
201   unsigned int group:1;         /* ' flag */
202 
203   mpfr_intmax_t width;          /* Width */
204   mpfr_intmax_t prec;           /* Precision, or negative if omitted */
205   size_t size;                  /* Wanted size (0 iff snprintf with size=0) */
206 
207   enum arg_t arg_type;          /* Type of argument */
208   mpfr_rnd_t rnd_mode;          /* Rounding mode */
209   char spec;                    /* Conversion specifier */
210 
211   char pad;                     /* Padding character */
212 };
213 
214 static void
specinfo_init(struct printf_spec * specinfo)215 specinfo_init (struct printf_spec *specinfo)
216 {
217   specinfo->alt = 0;
218   specinfo->space = 0;
219   specinfo->left = 0;
220   specinfo->showsign = 0;
221   specinfo->group = 0;
222   specinfo->width = 0;
223   specinfo->prec = 0;
224   specinfo->size = 1;
225   specinfo->arg_type = NONE;
226   specinfo->rnd_mode = MPFR_RNDN;
227   specinfo->spec = '\0';
228   specinfo->pad = ' ';
229 }
230 
231 /* Note: LONG_ARG is unusual, but is accepted (ISO C99 says "as no effect
232    on a following a, A, e, E, f, F, g, or G conversion specifier"). */
233 #define FLOATING_POINT_ARG_TYPE(at) \
234   ((at) == MPFR_ARG || (at) == MPF_ARG \
235    || (at) == LONG_ARG || (at) == LONG_DOUBLE_ARG)
236 
237 #define INTEGER_LIKE_ARG_TYPE(at)                                       \
238   ((at) == SHORT_ARG || (at) == LONG_ARG || (at) == LONG_LONG_ARG       \
239    || (at) == INTMAX_ARG  || (at) == MPFR_PREC_ARG || (at) == MPZ_ARG   \
240    || (at) == MPQ_ARG || (at) == MP_LIMB_ARG || (at) == MP_LIMB_ARRAY_ARG \
241    || (at) == CHAR_ARG || (at) == SIZE_ARG || (at) == PTRDIFF_ARG)
242 
243 static int
specinfo_is_valid(struct printf_spec spec)244 specinfo_is_valid (struct printf_spec spec)
245 {
246   switch (spec.spec)
247     {
248     case 'n':
249       return -1;
250 
251     case 'a':    case 'A':
252     case 'e':    case 'E':
253     case 'f':    /* 'F': see below */
254     case 'g':    case 'G':
255       return (spec.arg_type == NONE
256               || FLOATING_POINT_ARG_TYPE (spec.arg_type));
257 
258     case 'F':  /* only MPFR_ARG is supported since GMP doesn't support it
259                   due to its use as the mpf_t type specifier */
260     case 'b':
261       return spec.arg_type == MPFR_ARG;
262 
263     case 'd':    case 'i':
264     case 'o':    case 'u':
265     case 'x':    case 'X':
266       return (spec.arg_type == NONE
267               || INTEGER_LIKE_ARG_TYPE (spec.arg_type));
268 
269     case 'c':
270     case 's':
271       return (spec.arg_type == NONE || spec.arg_type == LONG_ARG);
272 
273     case 'p':
274       return spec.arg_type == NONE;
275 
276     default:
277       return 0;
278     }
279 }
280 
281 /* Note: additional flags should be added to the MPFR_PREC_ARG code
282    for gmp_asprintf (when supported). */
283 MPFR_RETURNS_NONNULL static const char *
parse_flags(const char * format,struct printf_spec * specinfo)284 parse_flags (const char *format, struct printf_spec *specinfo)
285 {
286   while (*format)
287     {
288       switch (*format)
289         {
290         case '0':
291           specinfo->pad = '0';
292           ++format;
293           break;
294         case '#':
295           specinfo->alt = 1;
296           ++format;
297           break;
298         case '+':
299           specinfo->showsign = 1;
300           ++format;
301           break;
302         case ' ':
303           specinfo->space = 1;
304           ++format;
305           break;
306         case '-':
307           specinfo->left = 1;
308           ++format;
309           break;
310         case '\'':
311           /* Single UNIX Specification for thousand separator */
312           specinfo->group = 1;
313           ++format;
314           break;
315         default:
316           return format;
317         }
318     }
319   return format;
320 }
321 
322 MPFR_RETURNS_NONNULL static const char *
parse_arg_type(const char * format,struct printf_spec * specinfo)323 parse_arg_type (const char *format, struct printf_spec *specinfo)
324 {
325   switch (*format)
326     {
327     case '\0':
328       break;
329     case 'h':
330       if (*++format == 'h')
331         {
332           ++format;
333           specinfo->arg_type = CHAR_ARG;
334         }
335       else
336         specinfo->arg_type = SHORT_ARG;
337       break;
338     case 'l':
339       if (*++format == 'l')
340         {
341           ++format;
342 #if defined (HAVE_LONG_LONG)
343           specinfo->arg_type = LONG_LONG_ARG;
344 #else
345           specinfo->arg_type = UNSUPPORTED;
346 #endif
347           break;
348         }
349       else
350         {
351           specinfo->arg_type = LONG_ARG;
352           break;
353         }
354     case 'j':
355       ++format;
356 #if defined(_MPFR_H_HAVE_INTMAX_T)
357       specinfo->arg_type = INTMAX_ARG;
358 #else
359       specinfo->arg_type = UNSUPPORTED;
360 #endif
361       break;
362     case 'z':
363       ++format;
364       specinfo->arg_type = SIZE_ARG;
365       break;
366     case 't':
367       ++format;
368       specinfo->arg_type = PTRDIFF_ARG;
369       break;
370     case 'L':
371       ++format;
372       specinfo->arg_type = LONG_DOUBLE_ARG;
373       break;
374     case 'F':
375       ++format;
376       specinfo->arg_type = MPF_ARG;
377       break;
378     case 'Q':
379       ++format;
380       specinfo->arg_type = MPQ_ARG;
381       break;
382     case 'M':
383       ++format;
384       /* The 'M' specifier was added in gmp 4.2.0 */
385       specinfo->arg_type = MP_LIMB_ARG;
386       break;
387     case 'N':
388       ++format;
389       specinfo->arg_type = MP_LIMB_ARRAY_ARG;
390       break;
391     case 'Z':
392       ++format;
393       specinfo->arg_type = MPZ_ARG;
394       break;
395 
396       /* mpfr specific specifiers */
397     case 'P':
398       ++format;
399       specinfo->arg_type = MPFR_PREC_ARG;
400       break;
401     case 'R':
402       ++format;
403       specinfo->arg_type = MPFR_ARG;
404     }
405   return format;
406 }
407 
408 
409 /* some macros and functions filling the buffer */
410 
411 /* CONSUME_VA_ARG removes from va_list AP the type expected by SPECINFO */
412 
413 /* With a C++ compiler wchar_t and enumeration in va_list are converted to
414    integer type : int, unsigned int, long or unsigned long (unfortunately,
415    this is implementation dependent).
416    We follow gmp which assumes in print/doprnt.c that wchar_t is converted
417    to int (because wchar_t <= int).
418    For wint_t, we assume that the case WINT_MAX < INT_MAX yields an
419    integer promotion. */
420 #if defined(WINT_MAX) && WINT_MAX < INT_MAX
421 typedef int    mpfr_va_wint;  /* integer promotion */
422 #else
423 typedef wint_t mpfr_va_wint;
424 #endif
425 #define CASE_LONG_ARG(specinfo, ap)                                     \
426   case LONG_ARG:                                                        \
427   if ((specinfo).spec == 'd' || (specinfo).spec == 'i'                  \
428       || (specinfo).spec == 'o' || (specinfo).spec == 'u'               \
429       || (specinfo).spec == 'x' || (specinfo).spec == 'X')              \
430     (void) va_arg ((ap), long);                                         \
431   else if ((specinfo).spec == 'c')                                      \
432     (void) va_arg ((ap), mpfr_va_wint);                                 \
433   else if ((specinfo).spec == 's')                                      \
434     (void) va_arg ((ap), int); /* we assume integer promotion */        \
435   else if ((specinfo).spec == 'a' || (specinfo).spec == 'A'             \
436            || (specinfo).spec == 'e' || (specinfo).spec == 'E'          \
437            || (specinfo).spec == 'f' /* 'F' impossible */               \
438            || (specinfo).spec == 'g' || (specinfo).spec == 'G')         \
439     (void) va_arg ((ap), double);                                       \
440   else                                                                  \
441     MPFR_RET_NEVER_GO_HERE();                                           \
442   break;
443 
444 #if defined(_MPFR_H_HAVE_INTMAX_T)
445 #define CASE_INTMAX_ARG(specinfo, ap)           \
446   case INTMAX_ARG:                              \
447   (void) va_arg ((ap), intmax_t);               \
448   break;
449 #else
450 #define CASE_INTMAX_ARG(specinfo, ap)
451 #endif
452 
453 #ifdef HAVE_LONG_LONG
454 #define CASE_LONG_LONG_ARG(specinfo, ap)        \
455   case LONG_LONG_ARG:                           \
456   (void) va_arg ((ap), long long);              \
457   break;
458 #else
459 #define CASE_LONG_LONG_ARG(specinfo, ap)
460 #endif
461 
462 /* Note: (specinfo).width may be incorrect in case of overflow,
463    but it is not used by CONSUME_VA_ARG. */
464 #define CONSUME_VA_ARG(specinfo, ap)            \
465   do {                                          \
466     switch ((specinfo).arg_type)                \
467       {                                         \
468       case CHAR_ARG:                            \
469       case SHORT_ARG:                           \
470         (void) va_arg ((ap), int);              \
471         break;                                  \
472       CASE_LONG_ARG (specinfo, ap)              \
473       CASE_LONG_LONG_ARG (specinfo, ap)         \
474       CASE_INTMAX_ARG (specinfo, ap)            \
475       case SIZE_ARG:                            \
476         (void) va_arg ((ap), size_t);           \
477         break;                                  \
478       case PTRDIFF_ARG:                         \
479         (void) va_arg ((ap), ptrdiff_t);        \
480         break;                                  \
481       case LONG_DOUBLE_ARG:                     \
482         (void) va_arg ((ap), long double);      \
483         break;                                  \
484       case MPF_ARG:                             \
485         (void) va_arg ((ap), mpf_srcptr);       \
486         break;                                  \
487       case MPQ_ARG:                             \
488         (void) va_arg ((ap), mpq_srcptr);       \
489         break;                                  \
490       case MP_LIMB_ARG:                         \
491         (void) va_arg ((ap), mp_limb_t);        \
492         break;                                  \
493       case MP_LIMB_ARRAY_ARG:                   \
494         (void) va_arg ((ap), mpfr_limb_ptr);    \
495         (void) va_arg ((ap), mp_size_t);        \
496         break;                                  \
497       case MPZ_ARG:                             \
498         (void) va_arg ((ap), mpz_srcptr);       \
499         break;                                  \
500       default:                                  \
501         switch ((specinfo).spec)                \
502           {                                     \
503           case 'd':                             \
504           case 'i':                             \
505           case 'o':                             \
506           case 'u':                             \
507           case 'x':                             \
508           case 'X':                             \
509           case 'c':                             \
510             (void) va_arg ((ap), int);          \
511             break;                              \
512           case 'a':                             \
513           case 'A':                             \
514           case 'e':                             \
515           case 'E':                             \
516           case 'f':                             \
517           /* 'F' impossible */                  \
518           case 'g':                             \
519           case 'G':                             \
520             (void) va_arg ((ap), double);       \
521             break;                              \
522           case 's':                             \
523             (void) va_arg ((ap), char *);       \
524             break;                              \
525           case 'p':                             \
526             (void) va_arg ((ap), void *);       \
527           }                                     \
528       }                                         \
529   } while (0)
530 
531 /* Process the format part which does not deal with mpfr types,
532    Jump to external label 'error' if gmp_asprintf return -1.
533    Note: start and end are pointers to the format string, so that
534    size_t is the best type to express the difference.
535    FIXME: If buf.size = 0 or size != 0, gmp_vsnprintf should be called
536    instead of gmp_vasprintf, outputting data directly to the buffer
537    when applicable.
538 */
539 #define FLUSH(flag, start, end, ap, buf_ptr)                            \
540   do {                                                                  \
541     const size_t n = (end) - (start);                                   \
542     if ((flag))                                                         \
543       /* previous specifiers are understood by gmp_printf */            \
544       {                                                                 \
545         MPFR_TMP_DECL (marker);                                         \
546         char *fmt_copy, *s;                                             \
547         int length;                                                     \
548                                                                         \
549         MPFR_TMP_MARK (marker);                                         \
550         fmt_copy = (char *) MPFR_TMP_ALLOC (n + 1);                     \
551         strncpy (fmt_copy, (start), n);                                 \
552         fmt_copy[n] = '\0';                                             \
553         length = gmp_vasprintf (&s, fmt_copy, (ap));                    \
554         if (length < 0)                                                 \
555           {                                                             \
556             MPFR_TMP_FREE (marker);                                     \
557             goto error;                                                 \
558           }                                                             \
559         buffer_cat ((buf_ptr), s, length);                              \
560         mpfr_free_str (s);                                              \
561         (flag) = 0;                                                     \
562         MPFR_TMP_FREE (marker);                                         \
563       }                                                                 \
564     else if ((start) != (end))                                          \
565       /* no conversion specification, just simple characters */         \
566       buffer_cat ((buf_ptr), (start), n);                               \
567   } while (0)
568 
569 /* Note: in case some form of %n is used in the format string,
570    we may need the maximum signed integer type for len. */
571 struct string_buffer
572 {
573   char *start;                  /* beginning of the buffer */
574   char *curr;                   /* null terminating character */
575   size_t size;                  /* buffer capacity */
576   mpfr_intmax_t len;            /* string length or -1 if overflow */
577 };
578 
579 static void
buffer_init(struct string_buffer * b,size_t s)580 buffer_init (struct string_buffer *b, size_t s)
581 {
582   if (s != 0)
583     {
584       b->start = (char *) mpfr_allocate_func (s);
585       b->start[0] = '\0';
586       b->curr = b->start;
587     }
588   b->size = s;
589   b->len = 0;
590 }
591 
592 /* Increase the len field of the buffer. Return non-zero iff overflow. */
593 static int
buffer_incr_len(struct string_buffer * b,mpfr_intmax_t len)594 buffer_incr_len (struct string_buffer *b, mpfr_intmax_t len)
595 {
596   if (b->len == -1)
597     return 1;
598   else
599     {
600       /* We need to take mpfr_uintmax_t as the type must be as large
601          as both size_t (which is unsigned) and mpfr_intmax_t (which
602          is used for the 'n' format specifier). */
603       mpfr_uintmax_t newlen = (mpfr_uintmax_t) b->len + len;
604 
605       /* mpfr_uintmax_t is unsigned, thus the above is valid, but one
606          has newlen < len in case of overflow. */
607 
608       if (MPFR_UNLIKELY (newlen < len || newlen > MPFR_INTMAX_MAX))
609         {
610           MPFR_LOG_MSG (("Overflow\n", 0));
611           b->len = -1;
612           return 1;
613         }
614       else
615         {
616           b->len = newlen;
617           return 0;
618         }
619     }
620 }
621 
622 /* Increase buffer size by a number of character being the least multiple of
623    4096 greater than len+1. */
624 static void
buffer_widen(struct string_buffer * b,size_t len)625 buffer_widen (struct string_buffer *b, size_t len)
626 {
627   const size_t pos = b->curr - b->start;
628   const size_t n = 0x1000 + (len & ~((size_t) 0xfff));
629 
630   /* There are currently limitations here. We would need to switch to
631      the null-size behavior once there is an overflow in the buffer. */
632 
633   MPFR_ASSERTN (n >= 0x1000 && n >= len);
634 
635   MPFR_ASSERTD (*b->curr == '\0');
636   MPFR_ASSERTD (pos < b->size);
637 
638   MPFR_ASSERTN (b->size < ((size_t) -1) - n);
639 
640   b->start = (char *) mpfr_reallocate_func (b->start, b->size, b->size + n);
641   b->size += n;
642   b->curr = b->start + pos;
643 
644   MPFR_ASSERTD (pos < b->size);
645   MPFR_ASSERTD (*b->curr == '\0');
646 }
647 
648 /* Concatenate the first len characters of the string s to the buffer b and
649    expand it if needed. Return non-zero if overflow. */
650 static int
buffer_cat(struct string_buffer * b,const char * s,size_t len)651 buffer_cat (struct string_buffer *b, const char *s, size_t len)
652 {
653   /* If len == 0, which is possible when outputting an integer 0
654      (either a native one or mpfr_prec_t) with precision field = 0,
655      do nothing. This test is not necessary since the code below is
656      valid for len == 0, but this is safer, just in case. */
657   if (len == 0)
658     return 0;
659 
660   MPFR_ASSERTD (len <= strlen (s));
661 
662   if (buffer_incr_len (b, len))
663     return 1;
664 
665   if (b->size != 0)
666     {
667       MPFR_ASSERTD (*b->curr == '\0');
668       MPFR_ASSERTN (b->size < ((size_t) -1) - len);
669       if (MPFR_UNLIKELY (b->curr + len >= b->start + b->size))
670         buffer_widen (b, len);
671 
672       /* strncat is similar to strncpy here, except that strncat ensures
673          that the buffer will be null-terminated. */
674       strncat (b->curr, s, len);
675       b->curr += len;
676 
677       MPFR_ASSERTD (b->curr < b->start + b->size);
678       MPFR_ASSERTD (*b->curr == '\0');
679     }
680 
681   return 0;
682 }
683 
684 /* Add n characters c to the end of buffer b. Return non-zero if overflow. */
685 static int
buffer_pad(struct string_buffer * b,const char c,const mpfr_intmax_t n)686 buffer_pad (struct string_buffer *b, const char c, const mpfr_intmax_t n)
687 {
688   MPFR_ASSERTD (n > 0);
689 
690   if (buffer_incr_len (b, n))
691     return 1;
692 
693   if (b->size != 0)
694     {
695       MPFR_ASSERTD (*b->curr == '\0');
696 
697       if (n > (size_t) -1 || b->size > ((size_t) -1) - n)
698         {
699           /* Reallocation will not be possible. Regard this as an overflow. */
700           b->len = -1;
701           return 1;
702         }
703 
704       if (MPFR_UNLIKELY (b->curr + n >= b->start + b->size))
705         buffer_widen (b, n);
706 
707       if (n == 1)
708         *b->curr = c;
709       else
710         memset (b->curr, c, n);
711       b->curr += n;
712       *b->curr = '\0';
713 
714       MPFR_ASSERTD (b->curr < b->start + b->size);
715     }
716 
717   return 0;
718 }
719 
720 /* Form a string by concatenating the first len characters of str to tz
721    zero(s), insert into one character c each 3 characters starting from end
722    to beginning and concatenate the result to the buffer b.
723    Assume c is not null (\0). Return non-zero if overflow. */
724 static int
buffer_sandwich(struct string_buffer * b,char * str,size_t len,const size_t tz,const char c)725 buffer_sandwich (struct string_buffer *b, char *str, size_t len,
726                  const size_t tz, const char c)
727 {
728   const size_t step = 3;
729   size_t size, q, r, fullsize, i;
730   char *oldcurr;
731 
732   MPFR_ASSERTD (b->size != 0);
733   MPFR_ASSERTD (tz == 0 || tz == 1);
734 
735   if (len <= ULONG_MAX)
736     MPFR_LOG_MSG (("len=%lu\n", (unsigned long) len));
737   if (tz <= ULONG_MAX)
738     MPFR_LOG_MSG (("tz=%lu\n", (unsigned long) tz));
739 
740   MPFR_ASSERTD (len <= strlen (str));
741   MPFR_ASSERTD (c != '\0');
742 
743   /* check that len + tz does not overflow */
744   if (len > (size_t) -1 - tz)
745     return 1;
746 
747   size = len + tz;              /* number of digits */
748   MPFR_ASSERTD (size > 0);
749 
750   q = (size - 1) / step;        /* number of separators C */
751   r = ((size - 1) % step) + 1;  /* number of digits in the leftmost block */
752   MPFR_ASSERTD (r >= 1 && r <= step);
753 
754   /* check that size + q does not overflow */
755   if (size > (size_t) -1 - q)
756     return 1;
757 
758   fullsize = size + q;          /* number of digits and separators */
759 
760   if (buffer_incr_len (b, fullsize))
761     return 1;
762 
763   MPFR_ASSERTD (*b->curr == '\0');
764   MPFR_ASSERTN (b->size < ((size_t) -1) - fullsize);
765   if (MPFR_UNLIKELY (b->curr + fullsize >= b->start + b->size))
766     buffer_widen (b, fullsize);
767 
768   MPFR_DBGRES (oldcurr = b->curr);
769 
770   /* first r significant digits (leftmost block) */
771   if (r <= len)
772     {
773       memcpy (b->curr, str, r);
774       str += r;
775       len -= r;
776     }
777   else
778     {
779       MPFR_ASSERTD (r > len);
780       MPFR_ASSERTD (len < step);    /* as a consequence */
781       MPFR_ASSERTD (size <= step);  /* as a consequence */
782       MPFR_ASSERTD (q == 0);        /* as a consequence */
783       MPFR_ASSERTD (r == size);     /* as a consequence */
784       MPFR_ASSERTD (tz == 1);       /* as a consequence */
785       memcpy (b->curr, str, len);
786       *(b->curr + len) = '0';  /* trailing zero */
787       /* We do not need to set len to 0 since it will not be read again
788          (q = 0, so that the loop below will have 0 iterations). */
789     }
790   b->curr += r;
791 
792   for (i = 0; i < q; ++i)
793     {
794       *b->curr++ = c;
795       if (MPFR_LIKELY (len >= step))
796         {
797           memcpy (b->curr, str, step);
798           len -= step;
799           str += step;
800         }
801       else
802         {
803           /* last digits */
804           MPFR_ASSERTD (i == q - 1 && step - len == 1);
805           memcpy (b->curr, str, len);
806           *(b->curr + len) = '0';  /* trailing zero */
807         }
808       b->curr += step;
809     }
810 
811   MPFR_ASSERTD (b->curr - oldcurr == fullsize);
812 
813   *b->curr = '\0';
814 
815   MPFR_ASSERTD (b->curr < b->start + b->size);
816 
817   return 0;
818 }
819 
820 /* Helper struct and functions for temporary strings management */
821 /* struct for easy string clearing */
822 struct string_list
823 {
824   char *string;
825   struct string_list *next; /* NULL in last node */
826 };
827 
828 /* initialization */
829 static void
init_string_list(struct string_list * sl)830 init_string_list (struct string_list *sl)
831 {
832   sl->string = NULL;
833   sl->next = NULL;
834 }
835 
836 /* clear all strings in the list */
837 static void
clear_string_list(struct string_list * sl)838 clear_string_list (struct string_list *sl)
839 {
840   struct string_list *n;
841 
842   while (sl)
843     {
844       if (sl->string)
845         mpfr_free_str (sl->string);
846       n = sl->next;
847       mpfr_free_func (sl, sizeof(struct string_list));
848       sl = n;
849     }
850 }
851 
852 /* add a string in the list */
853 static char *
register_string(struct string_list * sl,char * new_string)854 register_string (struct string_list *sl, char *new_string)
855 {
856   /* look for the last node */
857   while (sl->next)
858     sl = sl->next;
859 
860   sl->next = (struct string_list *)
861     mpfr_allocate_func (sizeof (struct string_list));
862 
863   sl = sl->next;
864   sl->next = NULL;
865   return sl->string = new_string;
866 }
867 
868 /* padding type: where are the padding characters */
869 enum pad_t
870   {
871     LEFT,          /* spaces in left hand side for right justification */
872     LEADING_ZEROS, /* padding with '0' characters in integral part */
873     RIGHT          /* spaces in right hand side for left justification */
874   };
875 
876 /* number_parts details how much characters are needed in each part of a float
877    print.  */
878 struct number_parts
879 {
880   enum pad_t pad_type;    /* Padding type */
881   mpfr_intmax_t pad_size; /* Number of padding characters */
882 
883   char sign;              /* Sign character ('-', '+', ' ', or '\0') */
884 
885   char *prefix_ptr;       /* Pointer to prefix part */
886   size_t prefix_size;     /* Number of characters in *prefix_ptr */
887 
888   char thousands_sep;     /* Thousands separator (only with style 'f') */
889 
890   char *ip_ptr;           /* Pointer to integral part characters*/
891   size_t ip_size;         /* Number of digits in *ip_ptr */
892   int ip_trailing_digits; /* Number of additional digits in integral part
893                              (if spec.size != 0, this can only be a zero) */
894 
895   char point;             /* Decimal point character */
896 
897   mpfr_intmax_t fp_leading_zeros;  /* Number of additional leading zeros in
898                                       fractional part */
899   char *fp_ptr;           /* Pointer to fractional part characters */
900   size_t fp_size;         /* Number of digits in *fp_ptr */
901   mpfr_intmax_t fp_trailing_zeros;  /* Number of additional trailing zeros in
902                                        fractional part */
903 
904   char *exp_ptr;          /* Pointer to exponent part */
905   size_t exp_size;        /* Number of characters in *exp_ptr */
906 
907   struct string_list *sl; /* List of string buffers in use: we need such a
908                              mechanism because fp_ptr may point into the same
909                              string as ip_ptr */
910 };
911 
912 /* For a real non zero number x, what is the base exponent f when rounding x
913    with rounding mode r to r(x) = m*b^f, where m is a digit and 1 <= m < b ?
914    Return non zero value if x is rounded up to b^f, return zero otherwise */
915 /* FIXME: It seems that the base-2 exponent is taken into account, which is
916    what is expected. In this case, the description is incorrect. */
917 static int
next_base_power_p(mpfr_srcptr x,int base,mpfr_rnd_t rnd)918 next_base_power_p (mpfr_srcptr x, int base, mpfr_rnd_t rnd)
919 {
920   mpfr_prec_t nbits;
921   mp_limb_t pm;
922   mp_limb_t xm;
923 
924   MPFR_ASSERTD (MPFR_IS_PURE_FP (x));
925   MPFR_ASSERTD (base == 2 || base == 16);
926 
927   /* Warning: the decimal point is AFTER THE FIRST DIGIT in this output
928      representation. */
929   nbits = base == 2 ? 1 : 4;
930 
931   if (rnd == MPFR_RNDZ
932       || (rnd == MPFR_RNDD && MPFR_IS_POS (x))
933       || (rnd == MPFR_RNDU && MPFR_IS_NEG (x))
934       || MPFR_PREC (x) <= nbits)
935     /* no rounding when printing x with 1 digit */
936     return 0;
937 
938   xm = MPFR_MANT (x) [MPFR_LIMB_SIZE (x) - 1];
939   pm = MPFR_LIMB_MASK (GMP_NUMB_BITS - nbits);
940   if ((xm & ~pm) ^ ~pm)
941     /* do no round up if some of the nbits first bits are 0s. */
942     return 0;
943 
944   if (rnd == MPFR_RNDN)
945     /* mask for rounding bit */
946     pm = (MPFR_LIMB_ONE << (GMP_NUMB_BITS - nbits - 1));
947 
948   /* round up if some remaining bits are 1 */
949   /* warning: the return value must be an int */
950   return xm & pm ? 1 : 0;
951 }
952 
953 /* Record information from mpfr_get_str() so as to avoid multiple
954    calls to this expensive function. */
955 struct decimal_info
956 {
957   mpfr_exp_t exp;
958   char *str;
959 };
960 
961 /* For a real non zero number x, what is the exponent f so that
962    10^f <= x < 10^(f+1). */
963 static mpfr_exp_t
floor_log10(mpfr_srcptr x)964 floor_log10 (mpfr_srcptr x)
965 {
966   mpfr_t y;
967   mpfr_exp_t exp;
968 
969   /* make sure first that y can represent a mpfr_exp_t exactly
970      and can compare with x */
971   mpfr_prec_t prec = sizeof (mpfr_exp_t) * CHAR_BIT;
972   mpfr_init2 (y, MAX (prec, MPFR_PREC (x)));
973 
974   exp = mpfr_ceil_mul (MPFR_GET_EXP (x), 10, 1) - 1;
975   mpfr_set_exp_t (y, exp, MPFR_RNDU);
976   /* The following call to mpfr_ui_pow should be fast: y is an integer
977      (not too large), so that mpfr_pow_z will be used internally. */
978   mpfr_ui_pow (y, 10, y, MPFR_RNDU);
979   if (mpfr_cmpabs (x, y) < 0)
980     exp--;
981 
982   mpfr_clear (y);
983   return exp;
984 }
985 
986 #define NDIGITS 8
987 
988 MPFR_RETURNS_NONNULL static char *
mpfr_get_str_wrapper(mpfr_exp_t * exp,int base,size_t n,mpfr_srcptr op,const struct printf_spec spec)989 mpfr_get_str_wrapper (mpfr_exp_t *exp, int base, size_t n, mpfr_srcptr op,
990                       const struct printf_spec spec)
991 {
992   size_t ndigits;
993   char *str, *s, nine;
994   int neg;
995 
996   /* Possibles bases for the *printf functions. */
997   MPFR_ASSERTD (base == 2 || base == 10 || base == 16);
998 
999   if (spec.size != 0)
1000     return mpfr_get_str (NULL, exp, base, n, op, spec.rnd_mode);
1001 
1002   /* Special case size = 0, i.e., xxx_snprintf with size = 0: we only want
1003      to compute the number of printed characters. Try to deduce it from
1004      a small number of significant digits. */
1005   nine = base == 2 ? '1' : base == 10 ? '9' : 'f';
1006   for (ndigits = NDIGITS; ; ndigits *= 2)
1007     {
1008       mpfr_rnd_t rnd = MPFR_RNDZ;
1009       /* when ndigits > n, we reduce it to the target size n, and then we use
1010          the wanted rounding mode, to avoid errors for example when n=1 and
1011          x = 9.5 with spec.rnd_mode = RNDU */
1012       if (ndigits >= n)
1013         {
1014           ndigits = n;
1015           rnd = spec.rnd_mode;
1016         }
1017       str = mpfr_get_str (NULL, exp, base, ndigits, op, rnd);
1018       if (ndigits == n)
1019         break;
1020       neg = str[0] == '-';
1021       s = str + neg;
1022       while (*s == nine)
1023         s ++;
1024       if (s < str + neg + ndigits) /* we don't have ndigits 'nines' */
1025         break;
1026       mpfr_free_str (str);
1027       MPFR_ASSERTN (ndigits <= ((size_t) -1) / 2);
1028       /* to make sure that the product by 2 is representable. */
1029     }
1030   return str;
1031 }
1032 
1033 /* Determine the different parts of the string representation of the regular
1034    number P when spec.spec is 'a', 'A', or 'b'.
1035 
1036    Return -1 in case of overflow on the sizes.
1037 
1038    Note for 'a'/'A': If the precision field is non-zero, the output is the
1039    one with a binary exponent that is a multiple of 4 (thus this is similar
1040    to base 16, where base-16 exponent = binary exponent / 4). But if the
1041    precision field is 0, the exponent is no longer restricted to a multiple
1042    of 4; the precision is maximized, but the displayed digit may be 1; this
1043    is completely unintuitive.
1044    The obtained output for 4 values with precision fields 0 and 1:
1045                0         1
1046       30     0xfp+1   0x1.ep+4
1047       31     0x1p+5   0x1.fp+4
1048       32     0x8p+2   0x2.0p+4
1049       33     0x8p+2   0x2.1p+4
1050    First, the output for numbers that round up to the next power of 16
1051    with a precision field 0, like 31 here, has an unexpected form: here
1052    with 31, "0x1p+5" instead of "0x8p+2".
1053    Moreover, if one increases the output precision, the output form
1054    changes (even if no rounding is involved). For instance, for 32,
1055    "0x8p+2" changes to "0x2.0p+4" instead of "0x8.0p+2".
1056    FIXME: choose first digit = always 1. Discussion:
1057      https://sympa.inria.fr/sympa/arc/mpfr/2021-05/msg00002.html
1058 */
1059 static int
regular_ab(struct number_parts * np,mpfr_srcptr p,const struct printf_spec spec)1060 regular_ab (struct number_parts *np, mpfr_srcptr p,
1061             const struct printf_spec spec)
1062 {
1063   int uppercase;
1064   int base;
1065   char *str;
1066   mpfr_exp_t exp;
1067 
1068   uppercase = spec.spec == 'A';
1069 
1070   if (spec.spec == 'a' || spec.spec == 'A')
1071     /* prefix part */
1072     {
1073       np->prefix_size = 2;
1074       str = (char *) mpfr_allocate_func (1 + np->prefix_size);
1075       str[0] = '0';
1076       str[1] = uppercase ? 'X' : 'x';
1077       str[2] = '\0';
1078       np->prefix_ptr = register_string (np->sl, str);
1079     }
1080 
1081   /* integral part */
1082   np->ip_size = 1;
1083   base = (spec.spec == 'b') ? 2 : 16;
1084 
1085   if (spec.prec != 0)
1086     {
1087       size_t nsd;
1088 
1089       /* Number of significant digits:
1090          - if no given precision, let mpfr_get_str determine it;
1091          - if a non-zero precision is specified, then one digit before decimal
1092          point plus SPEC.PREC after it (which will give nsd > 1 below). */
1093       MPFR_ASSERTD (np->ip_size == 1);  /* thus the + 1 below */
1094       if (spec.prec < 0)
1095         nsd = 0;
1096       else
1097         {
1098           if (MPFR_UNLIKELY (spec.prec > (size_t) -2))  /* overflow */
1099             return -1;
1100           nsd = (size_t) spec.prec + 1;
1101           MPFR_ASSERTD (nsd != 1);
1102         }
1103       str = mpfr_get_str_wrapper (&exp, base, nsd, p, spec);
1104       register_string (np->sl, str);
1105       np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str;  /* skip sign if any */
1106 
1107       if (base == 16)
1108         /* EXP is the exponent for radix sixteen with decimal point BEFORE the
1109            first digit, we want the exponent for radix two and the decimal
1110            point AFTER the first digit. */
1111         {
1112           /* An integer overflow is normally not possible since MPFR_EXP_MIN
1113              is twice as large as MPFR_EMIN_MIN. */
1114           MPFR_ASSERTN (exp > (MPFR_EXP_MIN + 3) / 4);
1115           exp = (exp - 1) * 4;
1116         }
1117       else
1118         /* EXP is the exponent for decimal point BEFORE the first digit, we
1119            want the exponent for decimal point AFTER the first digit. */
1120         {
1121           /* An integer overflow is normally not possible since MPFR_EXP_MIN
1122              is twice as large as MPFR_EMIN_MIN. */
1123           MPFR_ASSERTN (exp > MPFR_EXP_MIN);
1124           --exp;
1125         }
1126     }
1127   else if (next_base_power_p (p, base, spec.rnd_mode))
1128     {
1129       str = (char *) mpfr_allocate_func (2);
1130       str[0] = '1';
1131       str[1] = '\0';
1132       np->ip_ptr = register_string (np->sl, str);
1133 
1134       exp = MPFR_GET_EXP (p);
1135     }
1136   else if (base == 2)
1137     {
1138       str = (char *) mpfr_allocate_func (2);
1139       str[0] = '1';
1140       str[1] = '\0';
1141       np->ip_ptr = register_string (np->sl, str);
1142 
1143       exp = MPFR_GET_EXP (p) - 1;
1144     }
1145   else
1146     {
1147       int digit;
1148       mp_limb_t msl = MPFR_MANT (p)[MPFR_LIMB_SIZE (p) - 1];
1149       int rnd_bit = GMP_NUMB_BITS - 5;
1150 
1151       /* pick up the 4 first bits */
1152       digit = msl >> (rnd_bit + 1);
1153       if (spec.rnd_mode == MPFR_RNDA
1154           || (spec.rnd_mode == MPFR_RNDU && MPFR_IS_POS (p))
1155           || (spec.rnd_mode == MPFR_RNDD && MPFR_IS_NEG (p))
1156           || (spec.rnd_mode == MPFR_RNDN
1157               && (msl & (MPFR_LIMB_ONE << rnd_bit))))
1158         digit++;
1159       MPFR_ASSERTD (0 <= digit && digit <= 15);
1160 
1161       str = (char *) mpfr_allocate_func (1 + np->ip_size);
1162       str[0] = num_to_text [digit];
1163       str[1] = '\0';
1164       np->ip_ptr = register_string (np->sl, str);
1165 
1166       exp = MPFR_GET_EXP (p) - 4;
1167     }
1168 
1169   if (uppercase)
1170     /* All digits in upper case */
1171     {
1172       char *s1 = str;
1173       while (*s1)
1174         {
1175           switch (*s1)
1176             {
1177             case 'a':
1178               *s1 = 'A';
1179               break;
1180             case 'b':
1181               *s1 = 'B';
1182               break;
1183             case 'c':
1184               *s1 = 'C';
1185               break;
1186             case 'd':
1187               *s1 = 'D';
1188               break;
1189             case 'e':
1190               *s1 = 'E';
1191               break;
1192             case 'f':
1193               *s1 = 'F';
1194               break;
1195             }
1196           s1++;
1197         }
1198     }
1199 
1200   if (spec.spec == 'b' || spec.prec != 0)
1201     /* compute the number of digits in fractional part */
1202     {
1203       char *ptr;
1204       size_t str_len;
1205 
1206       /* the sign has been skipped, skip also the first digit */
1207       ++str;
1208       str_len = strlen (str);
1209       ptr = str + str_len - 1; /* points to the end of str */
1210 
1211       if (spec.prec < 0)
1212         /* remove trailing zeros, if any */
1213         {
1214           while (*ptr == '0' && str_len != 0)
1215             {
1216               --ptr;
1217               --str_len;
1218             }
1219         }
1220 
1221       if (str_len != 0)
1222         /* there are some non-zero digits in fractional part */
1223         {
1224           np->fp_ptr = str;
1225           np->fp_size = str_len;
1226           /* Warning! str_len has type size_t, which is unsigned. */
1227           if (spec.prec > 0 && str_len < spec.prec)
1228             {
1229               np->fp_trailing_zeros = spec.prec - str_len;
1230               MPFR_ASSERTD (np->fp_trailing_zeros >= 0);
1231             }
1232         }
1233     }
1234 
1235   /* decimal point */
1236   if (np->fp_size != 0 || spec.alt)
1237     np->point = MPFR_DECIMAL_POINT;
1238 
1239   /* the exponent part contains the character 'p', or 'P' plus the sign
1240      character plus at least one digit and only as many more digits as
1241      necessary to represent the exponent.
1242      We assume that |EXP| < 10^INT_MAX. */
1243   np->exp_size = 3;
1244   {
1245     mpfr_uexp_t x;
1246 
1247     x = SAFE_ABS (mpfr_uexp_t, exp);
1248     while (x > 9)
1249       {
1250         np->exp_size++;
1251         x /= 10;
1252       }
1253   }
1254   str = (char *) mpfr_allocate_func (1 + np->exp_size);
1255   np->exp_ptr = register_string (np->sl, str);
1256   {
1257     char exp_fmt[8];  /* contains at most 7 characters like in "p%+.1i",
1258                          or "P%+.2li" */
1259 
1260     exp_fmt[0] = uppercase ? 'P' : 'p';
1261     exp_fmt[1] = '\0';
1262     strcat (exp_fmt, "%+.1" MPFR_EXP_FSPEC "d");
1263 
1264     if (MPFR_UNLIKELY (sprintf (str, exp_fmt, (mpfr_eexp_t) exp) < 0))
1265       return -1;
1266   }
1267 
1268   return 0;
1269 }
1270 
1271 /* Determine the different parts of the string representation of the regular
1272    number P when spec.spec is 'e', 'E', 'g', or 'G'.
1273    dec_info contains the previously computed exponent and string or is
1274    a null pointer.
1275 
1276    Return -1 in case of overflow on the sizes. */
1277 static int
regular_eg(struct number_parts * np,mpfr_srcptr p,const struct printf_spec spec,struct decimal_info * dec_info,int keep_trailing_zeros)1278 regular_eg (struct number_parts *np, mpfr_srcptr p,
1279             const struct printf_spec spec, struct decimal_info *dec_info,
1280             int keep_trailing_zeros)
1281 {
1282   char *str;
1283   mpfr_exp_t exp;
1284 
1285   const int uppercase = spec.spec == 'E' || spec.spec == 'G';
1286 
1287   /* integral part */
1288   np->ip_size = 1;
1289   if (dec_info == NULL)
1290     {
1291       size_t nsd;
1292 
1293       /* Number of significant digits:
1294          - if no given precision, then let mpfr_get_str determine it,
1295          - if a precision is specified, then one digit before decimal point
1296          plus SPEC.PREC after it.
1297          We use the fact here that mpfr_get_str allows us to ask for only one
1298          significant digit when the base is not a power of 2. */
1299       MPFR_ASSERTD (np->ip_size == 1);  /* thus the + 1 below */
1300       if (spec.prec < 0)
1301         nsd = 0;
1302       else
1303         {
1304           if (MPFR_UNLIKELY (spec.prec > (size_t) -2))  /* overflow */
1305             return -1;
1306           nsd = (size_t) spec.prec + 1;
1307         }
1308       str = mpfr_get_str_wrapper (&exp, 10, nsd, p, spec);
1309       register_string (np->sl, str);
1310     }
1311   else
1312     {
1313       exp = dec_info->exp;
1314       str = dec_info->str;
1315     }
1316   np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str;  /* skip sign if any */
1317 
1318   if (spec.prec != 0)
1319     /* compute the number of digits in fractional part */
1320     {
1321       char *ptr;
1322       size_t str_len;
1323 
1324       /* the sign has been skipped, skip also the first digit */
1325       ++str;
1326       str_len = strlen (str);
1327       ptr = str + str_len - 1; /* points to the end of str */
1328 
1329       if (!keep_trailing_zeros)
1330         /* remove trailing zeros, if any */
1331         {
1332           while (*ptr == '0' && str_len != 0)
1333             {
1334               --ptr;
1335               --str_len;
1336             }
1337         }
1338 
1339       if (str_len != 0)
1340         /* there are some non-zero digits in fractional part */
1341         {
1342           np->fp_ptr = str;
1343           np->fp_size = str_len;
1344           /* Warning! str_len has type size_t, which is unsigned. */
1345           if (keep_trailing_zeros && spec.prec > 0 && str_len < spec.prec)
1346             {
1347               /* add missing trailing zeros */
1348               np->fp_trailing_zeros = spec.prec - str_len;
1349               MPFR_ASSERTD (np->fp_trailing_zeros >= 0);
1350             }
1351         }
1352     }
1353 
1354   /* decimal point */
1355   if (np->fp_size != 0 || spec.alt)
1356     np->point = MPFR_DECIMAL_POINT;
1357 
1358   /* EXP is the exponent for decimal point BEFORE the first digit, we want
1359      the exponent for decimal point AFTER the first digit.
1360      Here, no possible overflow because exp < MPFR_EXP (p) / 3 */
1361   exp--;
1362 
1363   /* the exponent part contains the character 'e', or 'E' plus the sign
1364      character plus at least two digits and only as many more digits as
1365      necessary to represent the exponent.
1366      We assume that |EXP| < 10^INT_MAX. */
1367   np->exp_size = 3;
1368   {
1369     mpfr_uexp_t x;
1370 
1371     x = SAFE_ABS (mpfr_uexp_t, exp);
1372     while (x > 9)
1373       {
1374         np->exp_size++;
1375         x /= 10;
1376       }
1377   }
1378   if (np->exp_size < 4)
1379     np->exp_size = 4;
1380 
1381   str = (char *) mpfr_allocate_func (1 + np->exp_size);
1382   np->exp_ptr = register_string (np->sl, str);
1383 
1384   {
1385     char exp_fmt[8];  /* e.g. "e%+.2i", or "E%+.2li" */
1386 
1387     exp_fmt[0] = uppercase ? 'E' : 'e';
1388     exp_fmt[1] = '\0';
1389     strcat (exp_fmt, "%+.2" MPFR_EXP_FSPEC "d");
1390 
1391     if (MPFR_UNLIKELY (sprintf (str, exp_fmt, (mpfr_eexp_t) exp) < 0))
1392       return -1;
1393   }
1394 
1395   return 0;
1396 }
1397 
1398 /* Determine the different parts of the string representation of the regular
1399    number P when spec.spec is 'f', 'F', 'g', or 'G'.
1400    dec_info contains the previously computed exponent and string or is
1401    a null pointer.
1402 
1403    Return -1 in case of overflow on the sizes. */
1404 static int
regular_fg(struct number_parts * np,mpfr_srcptr p,const struct printf_spec spec,struct decimal_info * dec_info,int keep_trailing_zeros)1405 regular_fg (struct number_parts *np, mpfr_srcptr p,
1406             const struct printf_spec spec, struct decimal_info *dec_info,
1407             int keep_trailing_zeros)
1408 {
1409   mpfr_exp_t exp;
1410   char * str;
1411 
1412   /* WARNING: an empty precision field is forbidden (it means precision = 6
1413      and it should have been changed to 6 before the function call) */
1414   MPFR_ASSERTD (spec.prec >= 0);
1415 
1416   if (MPFR_GET_EXP (p) <= 0)
1417     /* 0 < |p| < 1 */
1418     {
1419       /* Most of the time, integral part is 0 */
1420       np->ip_size = 1;
1421       str = (char *) mpfr_allocate_func (1 + np->ip_size);
1422       str[0] = '0';
1423       str[1] = '\0';
1424       np->ip_ptr = register_string (np->sl, str);
1425 
1426       if (spec.prec == 0)
1427         /* only two possibilities: either 1 or 0. */
1428         {
1429           mpfr_t y;
1430           /* y = abs(p) */
1431           MPFR_ALIAS (y, p, 1, MPFR_EXP (p));
1432 
1433           if (spec.rnd_mode == MPFR_RNDA
1434               || (spec.rnd_mode == MPFR_RNDD && MPFR_IS_NEG (p))
1435               || (spec.rnd_mode == MPFR_RNDU && MPFR_IS_POS (p))
1436               || (spec.rnd_mode == MPFR_RNDN && mpfr_cmp_d (y, 0.5) > 0))
1437             /* rounded up to 1: one digit '1' in integral part.
1438                note that 0.5 is rounded to 0 with RNDN (round ties to even) */
1439             np->ip_ptr[0] = '1';
1440         }
1441       else
1442         {
1443           /* exp =  position of the most significant decimal digit. */
1444           exp = floor_log10 (p);
1445           MPFR_ASSERTD (exp < 0);
1446 
1447           if (exp < -spec.prec)
1448             /* only the last digit may be non zero */
1449             {
1450               int round_away;
1451 
1452               /* Due to mpfr_set_si below... */
1453               if (MPFR_UNLIKELY (spec.prec > LONG_MAX))  /* overflow */
1454                 return -1;
1455 
1456               switch (spec.rnd_mode)
1457                 {
1458                 case MPFR_RNDA:
1459                 case MPFR_RNDF:  /* round_away = 1 needed for %Rg */
1460                   round_away = 1;
1461                   break;
1462                 case MPFR_RNDZ:
1463                   round_away = 0;
1464                   break;
1465                 case MPFR_RNDD:
1466                   round_away = MPFR_IS_NEG (p);
1467                   break;
1468                 case MPFR_RNDU:
1469                   round_away = MPFR_IS_POS (p);
1470                   break;
1471                 default:
1472                   {
1473                     /* compare |p| to y = 0.5*10^(-spec.prec) */
1474                     mpfr_t y;
1475                     mpfr_exp_t e = MAX (MPFR_PREC (p), 56);
1476                     int cmp;
1477 
1478                     MPFR_ASSERTN (spec.rnd_mode == MPFR_RNDN);
1479                     mpfr_init2 (y, e + 8);
1480 
1481                     do
1482                       {
1483                         /* find a lower approximation of
1484                            0.5*10^(-spec.prec) different from |p| */
1485                         e += 8;
1486                         mpfr_set_prec (y, e);
1487                         mpfr_set_si (y, -spec.prec, MPFR_RNDN);
1488                         mpfr_exp10 (y, y, MPFR_RNDD);
1489                         mpfr_div_2ui (y, y, 1, MPFR_RNDN);
1490                         cmp = mpfr_cmpabs (y, p);
1491                       }
1492                     while (cmp == 0);
1493 
1494                     round_away = cmp < 0;
1495                     mpfr_clear (y);
1496                   }
1497                   break;
1498                 }
1499 
1500               if (round_away)
1501                 /* round away from zero: the last output digit is '1' */
1502                 {
1503                   np->fp_leading_zeros = spec.prec - 1;
1504 
1505                   np->fp_size = 1;
1506                   str = (char *) mpfr_allocate_func (1 + np->fp_size);
1507                   str[0] = '1';
1508                   str[1] = '\0';
1509                   np->fp_ptr = register_string (np->sl, str);
1510                 }
1511               else
1512                 /* only zeros in fractional part */
1513                 {
1514                   MPFR_ASSERTD (spec.spec == 'f' || spec.spec == 'F');
1515                   np->fp_leading_zeros = spec.prec;
1516                 }
1517             }
1518           else  /* exp >= -spec.prec */
1519             /* the most significant digits are the last
1520                spec.prec + exp + 1 digits in fractional part */
1521             {
1522               char *ptr;
1523               size_t str_len;
1524 
1525               MPFR_ASSERTD (exp >= -spec.prec);
1526               if (dec_info == NULL)
1527                 {
1528                   size_t nsd;
1529 
1530                   MPFR_ASSERTD (exp <= -1);
1531                   MPFR_ASSERTD (spec.prec + (exp + 1) >= 0);
1532                   if (MPFR_UNLIKELY (spec.prec + (exp + 1) > (size_t) -1))
1533                     return -1;
1534                   nsd = spec.prec + (exp + 1);
1535                   /* WARNING: nsd may equal 1, but here we use the
1536                      fact that mpfr_get_str can return one digit with
1537                      base ten (undocumented feature, see comments in
1538                      get_str.c) */
1539 
1540                   str = mpfr_get_str_wrapper (&exp, 10, nsd, p, spec);
1541                   register_string (np->sl, str);
1542                 }
1543               else
1544                 {
1545                   exp = dec_info->exp;
1546                   str = dec_info->str;
1547                 }
1548               if (MPFR_IS_NEG (p))
1549                 /* skip sign */
1550                 ++str;
1551               if (exp == 1)
1552                 /* round up to 1 */
1553                 {
1554                   MPFR_ASSERTD (str[0] == '1');
1555                   np->ip_ptr[0] = '1';
1556                   if (keep_trailing_zeros)
1557                     np->fp_leading_zeros = spec.prec;
1558                 }
1559               else
1560                 {
1561                   np->fp_ptr = str;
1562                   np->fp_leading_zeros = -exp;
1563                   MPFR_ASSERTD (exp <= 0);
1564 
1565                   str_len = strlen (str); /* the sign has been skipped */
1566                   ptr = str + str_len - 1; /* points to the end of str */
1567 
1568                   if (!keep_trailing_zeros)
1569                     /* remove trailing zeros, if any */
1570                     {
1571                       while (*ptr == '0' && str_len != 0)
1572                         {
1573                           --ptr;
1574                           --str_len;
1575                         }
1576                     }
1577 
1578                   MPFR_ASSERTD (str_len > 0);
1579                   np->fp_size = str_len;
1580 
1581                   /* The np->fp_size <= MPFR_INTMAX_MAX test and the
1582                      cast to mpfr_uintmax_t below allow one to avoid
1583                      integer overflow. */
1584                   if (keep_trailing_zeros
1585                       && spec.prec > 0
1586                       && np->fp_size <= MPFR_INTMAX_MAX
1587                       && ((mpfr_uintmax_t)
1588                           np->fp_leading_zeros + np->fp_size) < spec.prec)
1589                     {
1590                       /* add missing trailing zeros */
1591                       np->fp_trailing_zeros = spec.prec
1592                         - np->fp_leading_zeros - np->fp_size;
1593                       MPFR_ASSERTD (np->fp_trailing_zeros >= 0);
1594                     }
1595                 }
1596             }
1597         }
1598 
1599       if (spec.alt || np->fp_leading_zeros != 0 || np->fp_size != 0
1600           || np->fp_trailing_zeros != 0)
1601         np->point = MPFR_DECIMAL_POINT;
1602     }
1603   else
1604     /* 1 <= |p| */
1605     {
1606       size_t str_len;
1607 
1608       /* Determine the position of the most significant decimal digit. */
1609       exp = floor_log10 (p);
1610       MPFR_ASSERTD (exp >= 0);
1611 
1612       if (dec_info == NULL)
1613         {
1614           /* %f case */
1615           mpfr_uintmax_t n;
1616 
1617           n = (mpfr_uintmax_t) spec.prec + (exp + 1);
1618           if (MPFR_UNLIKELY (n > (size_t) -1))
1619             return -1;
1620           str = mpfr_get_str_wrapper (&exp, 10, n, p, spec);
1621           register_string (np->sl, str);
1622         }
1623       else
1624         {
1625           /* %g case */
1626           exp = dec_info->exp;
1627           str = dec_info->str;
1628         }
1629       np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign */
1630       str_len = strlen (str);
1631 
1632       /* integral part */
1633       if (exp > str_len)
1634         {
1635           /* When spec.size == 0, mpfr_get_str may be called in a reduced
1636              precision, so that some trailing digits may have been ignored.
1637              When spec.size != 0, this case is also possible in the case
1638              where p is rounded up to the next power of 10: a zero must be
1639              added since the exponent has been increased by 1. */
1640           np->ip_trailing_digits = exp - str_len;
1641           np->ip_size = str_len;
1642         }
1643       else
1644         np->ip_size = exp;
1645 
1646       if (spec.group)
1647         /* thousands separator in integral part */
1648         np->thousands_sep = MPFR_THOUSANDS_SEPARATOR;
1649 
1650       /* fractional part */
1651       str += np->ip_size;
1652       str_len -= np->ip_size;
1653       if (!keep_trailing_zeros)
1654         /* remove trailing zeros, if any */
1655         {
1656           char *ptr = str + str_len - 1; /* pointer to the last digit of
1657                                             str */
1658           while (*ptr == '0' && str_len != 0)
1659             {
1660               --ptr;
1661               --str_len;
1662             }
1663         }
1664 
1665       if (str_len > 0)
1666         /* some non-zero digits in fractional part */
1667         {
1668           np->point = MPFR_DECIMAL_POINT;
1669           np->fp_ptr = str;
1670           np->fp_size = str_len;
1671         }
1672 
1673       /* Warning! str_len has type size_t, which is unsigned. */
1674       MPFR_ASSERTD (spec.prec >= 0);  /* let's recall this */
1675       if (keep_trailing_zeros && str_len < spec.prec)
1676         /* add missing trailing zeros */
1677         {
1678           np->point = MPFR_DECIMAL_POINT;
1679           np->fp_trailing_zeros = spec.prec - np->fp_size;
1680           MPFR_ASSERTD (np->fp_trailing_zeros >= 0);
1681         }
1682 
1683       if (spec.alt)
1684         /* add decimal point even if no digits follow it */
1685         np->point = MPFR_DECIMAL_POINT;
1686     }
1687 
1688   return 0;
1689 }
1690 
1691 /* partition_number determines the different parts of the string
1692    representation of the number p according to the given specification.
1693    partition_number initializes the given structure np, so all previous
1694    information in that variable is lost.
1695    Return the total number of characters to be written.
1696    Return -1 if an error occurred, in that case np's fields are in an
1697    undefined state but all string buffers have been freed. */
1698 static mpfr_intmax_t
partition_number(struct number_parts * np,mpfr_srcptr p,struct printf_spec spec)1699 partition_number (struct number_parts *np, mpfr_srcptr p,
1700                   struct printf_spec spec)
1701 {
1702   char *str;
1703   mpfr_uintmax_t total;  /* can hold the sum of two non-negative
1704                             signed integers + 1 */
1705   int uppercase;
1706 
1707   /* WARNING: left justification means right space padding */
1708   np->pad_type = spec.left ? RIGHT : spec.pad == '0' ? LEADING_ZEROS : LEFT;
1709   np->pad_size = 0;
1710   np->prefix_ptr = NULL;
1711   np->prefix_size = 0;
1712   np->thousands_sep = '\0';
1713   np->ip_ptr = NULL;
1714   np->ip_size = 0;
1715   np->ip_trailing_digits = 0;
1716   np->point = '\0';
1717   np->fp_leading_zeros = 0;
1718   np->fp_ptr = NULL;
1719   np->fp_size = 0;
1720   np->fp_trailing_zeros = 0;
1721   np->exp_ptr = NULL;
1722   np->exp_size = 0;
1723   np->sl = (struct string_list *)
1724     mpfr_allocate_func (sizeof (struct string_list));
1725   init_string_list (np->sl);
1726 
1727   uppercase = spec.spec == 'A' || spec.spec == 'E' || spec.spec == 'F'
1728     || spec.spec == 'G';
1729 
1730   /* The sign/space rule is the same for all cases. */
1731   np->sign =
1732     MPFR_IS_NEG (p) ? '-' :
1733     spec.showsign ? '+' :
1734     spec.space ? ' ' : '\0';
1735 
1736   if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (p)))
1737     {
1738       if (MPFR_IS_NAN (p))
1739         {
1740           if (np->pad_type == LEADING_ZEROS)
1741             /* don't want "0000nan", change to right justification padding
1742                with left spaces instead */
1743             np->pad_type = LEFT;
1744 
1745           np->ip_size = MPFR_NAN_STRING_LENGTH;
1746           str = (char *) mpfr_allocate_func (1 + np->ip_size);
1747           strcpy (str, uppercase ? MPFR_NAN_STRING_UC : MPFR_NAN_STRING_LC);
1748           np->ip_ptr = register_string (np->sl, str);
1749         }
1750       else if (MPFR_IS_INF (p))
1751         {
1752           if (np->pad_type == LEADING_ZEROS)
1753             /* don't want "0000inf", change to right justification padding
1754                with left spaces instead */
1755             np->pad_type = LEFT;
1756 
1757           np->ip_size = MPFR_INF_STRING_LENGTH;
1758           str = (char *) mpfr_allocate_func (1 + np->ip_size);
1759           strcpy (str, uppercase ? MPFR_INF_STRING_UC : MPFR_INF_STRING_LC);
1760           np->ip_ptr = register_string (np->sl, str);
1761         }
1762       else
1763         {
1764           MPFR_ASSERTD (MPFR_IS_ZERO (p));
1765           /* note: for 'g' spec, zero is always displayed with 'f'-style with
1766              precision spec.prec - 1 and the trailing zeros are removed unless
1767              the flag '#' is used. */
1768 
1769           if (spec.spec == 'a' || spec.spec == 'A')
1770             /* prefix part */
1771             {
1772               np->prefix_size = 2;
1773               str = (char *) mpfr_allocate_func (1 + np->prefix_size);
1774               str[0] = '0';
1775               str[1] = uppercase ? 'X' : 'x';
1776               str[2] = '\0';
1777               np->prefix_ptr = register_string (np->sl, str);
1778             }
1779 
1780           /* integral part */
1781           np->ip_size = 1;
1782           str = (char *) mpfr_allocate_func (1 + np->ip_size);
1783           str[0] = '0';
1784           str[1] = '\0';
1785           np->ip_ptr = register_string (np->sl, str);
1786 
1787           if (spec.prec < 0)  /* empty precision field */
1788             {
1789               if (spec.spec == 'e' || spec.spec == 'E')
1790                 spec.prec = mpfr_get_str_ndigits (10, MPFR_GET_PREC (p)) - 1;
1791               else if (spec.spec == 'f' || spec.spec == 'F' ||
1792                        spec.spec == 'g' || spec.spec == 'G')
1793                 spec.prec = DEFAULT_DECIMAL_PREC;
1794             }
1795 
1796           if (spec.prec > 0
1797               && ((spec.spec != 'g' && spec.spec != 'G') || spec.alt))
1798             /* fractional part */
1799             {
1800               np->point = MPFR_DECIMAL_POINT;
1801               np->fp_trailing_zeros = (spec.spec == 'g' || spec.spec == 'G') ?
1802                 spec.prec - 1 : spec.prec;
1803               MPFR_ASSERTD (np->fp_trailing_zeros >= 0);
1804             }
1805           else if (spec.alt)
1806             np->point = MPFR_DECIMAL_POINT;
1807 
1808           if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b'
1809               || spec.spec == 'e' || spec.spec == 'E')
1810             /* exponent part */
1811             {
1812               np->exp_size = (spec.spec == 'e' || spec.spec == 'E') ? 4 : 3;
1813               str = (char *) mpfr_allocate_func (1 + np->exp_size);
1814               if (spec.spec == 'e' || spec.spec == 'E')
1815                 strcpy (str, uppercase ? "E+00" : "e+00");
1816               else
1817                 strcpy (str, uppercase ? "P+0" : "p+0");
1818               np->exp_ptr = register_string (np->sl, str);
1819             }
1820         }
1821     }
1822   else if (MPFR_UNLIKELY (MPFR_IS_UBF (p)))
1823     {
1824       /* mpfr_get_str does not support UBF, so that UBF numbers are regarded
1825          as special cases here. This is not much a problem since UBF numbers
1826          are internal to MPFR and here, they only for logging. */
1827       if (np->pad_type == LEADING_ZEROS)
1828         /* change to right justification padding with left spaces */
1829         np->pad_type = LEFT;
1830 
1831       np->ip_size = 3;
1832       str = (char *) mpfr_allocate_func (1 + np->ip_size);
1833       strcpy (str, uppercase ? "UBF" : "ubf");
1834       np->ip_ptr = register_string (np->sl, str);
1835       /* TODO: output more information (e.g. the exponent) if need be. */
1836     }
1837   else
1838     {
1839       MPFR_ASSERTD (MPFR_IS_PURE_FP (p));
1840       if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b')
1841         {
1842           if (regular_ab (np, p, spec) == -1)
1843             goto error;
1844         }
1845       else if (spec.spec == 'f' || spec.spec == 'F')
1846         {
1847           if (spec.prec < 0)
1848             spec.prec = DEFAULT_DECIMAL_PREC;
1849           if (regular_fg (np, p, spec, NULL, 1) == -1)
1850             goto error;
1851         }
1852       else if (spec.spec == 'e' || spec.spec == 'E')
1853         {
1854           if (regular_eg (np, p, spec, NULL, 1) == -1)
1855             goto error;
1856         }
1857       else
1858         /* %g case */
1859         {
1860           /* Use the C99 rules:
1861              if T > X >= -4 then the conversion is with style 'f'/'F' and
1862              precision T-(X+1).
1863              otherwise, the conversion is with style 'e'/'E' and
1864              precision T-1.
1865              where T is the threshold computed below and X is the exponent
1866              that would be displayed with style 'e' and precision T-1. */
1867           mpfr_intmax_t threshold;
1868           mpfr_exp_t x, e, k;
1869           struct decimal_info dec_info;
1870 
1871           threshold = spec.prec < 0 ? DEFAULT_DECIMAL_PREC :
1872             spec.prec == 0 ? 1 : spec.prec;
1873           MPFR_ASSERTD (threshold >= 1);
1874 
1875           /* Here we cannot call mpfr_get_str_wrapper since we need the full
1876              significand in dec_info.str.
1877              Moreover, threshold may be huge while one can know that the
1878              number of digits that are not trailing zeros remains limited;
1879              such a limit occurs in practical cases, e.g. with numbers
1880              representable in the IEEE 754-2008 basic formats. Since the
1881              trailing zeros are not necessarily output, we do not want to
1882              waste time and memory by making mpfr_get_str generate them.
1883              So, let us try to find a smaller threshold for mpfr_get_str.
1884              |p| < 2^EXP(p) = 10^(EXP(p)*log10(2)). So, the integer part
1885              takes at most ceil(EXP(p)*log10(2)) digits (unless p rounds
1886              to the next power of 10, but in this case any threshold will
1887              be OK). So, for the integer part, we will take:
1888              max(0,floor((EXP(p)+2)/3)).
1889              Let k = PREC(p) - EXP(p), so that the last bit of p has
1890              weight 2^(-k). If k <= 0, then p is an integer, otherwise
1891              the fractional part in base 10 may have up to k digits
1892              (this bound is reached if the last bit is 1).
1893              Note: The bound could be improved, but this is not critical. */
1894           e = MPFR_GET_EXP (p);
1895           k = MPFR_PREC (p) - e;
1896           e = e <= 0 ? k : (e + 2) / 3 + (k <= 0 ? 0 : k);
1897           MPFR_ASSERTD (e >= 1);
1898 
1899           if (e > threshold)
1900             e = threshold;
1901 
1902           /* error if e does not fit in size_t (for mpfr_get_str) */
1903           if (e > (size_t) -1)
1904             goto error;
1905 
1906           dec_info.str = mpfr_get_str (NULL, &dec_info.exp, 10,
1907                                        e, p, spec.rnd_mode);
1908           register_string (np->sl, dec_info.str);
1909           /* mpfr_get_str corresponds to a significand between 0.1 and 1,
1910              whereas here we want a significand between 1 and 10. */
1911           x = dec_info.exp - 1;
1912 
1913           if (threshold > x && x >= -4)
1914             {
1915               /* the conversion is with style 'f' */
1916               spec.prec = threshold - x - 1;
1917 
1918               if (regular_fg (np, p, spec, &dec_info, spec.alt) == -1)
1919                 goto error;
1920             }
1921           else
1922             {
1923               spec.prec = threshold - 1;
1924 
1925               if (regular_eg (np, p, spec, &dec_info, spec.alt) == -1)
1926                 goto error;
1927             }
1928         }
1929     }
1930 
1931   /* compute the number of characters to be written verifying it is not too
1932      much */
1933 
1934 #define INCR_TOTAL(v)                                   \
1935   do {                                                  \
1936     MPFR_ASSERTD ((v) >= 0);                            \
1937     if (MPFR_UNLIKELY ((v) > MPFR_INTMAX_MAX))          \
1938       goto error;                                       \
1939     total += (v);                                       \
1940     if (MPFR_UNLIKELY (total > MPFR_INTMAX_MAX))        \
1941       goto error;                                       \
1942   } while (0)
1943 
1944   total = np->sign ? 1 : 0;
1945   INCR_TOTAL (np->prefix_size);
1946   INCR_TOTAL (np->ip_size);
1947   INCR_TOTAL (np->ip_trailing_digits);
1948   MPFR_ASSERTD (np->ip_size + np->ip_trailing_digits >= 1);
1949   if (np->thousands_sep)
1950     /* ' flag, style f and the thousands separator in current locale is not
1951        reduced to the null character */
1952     INCR_TOTAL ((np->ip_size + np->ip_trailing_digits - 1) / 3);
1953   if (np->point)
1954     ++total;
1955   INCR_TOTAL (np->fp_leading_zeros);
1956   INCR_TOTAL (np->fp_size);
1957   INCR_TOTAL (np->fp_trailing_zeros);
1958   INCR_TOTAL (np->exp_size);
1959 
1960   if (spec.width > total)
1961     /* pad with spaces or zeros depending on np->pad_type */
1962     {
1963       np->pad_size = spec.width - total;
1964       total = spec.width;
1965     }
1966 
1967   MPFR_ASSERTD (total > 0 && total <= MPFR_INTMAX_MAX);
1968   return total;
1969 
1970  error:
1971   clear_string_list (np->sl);
1972   np->prefix_ptr = NULL;
1973   np->ip_ptr = NULL;
1974   np->fp_ptr = NULL;
1975   np->exp_ptr = NULL;
1976   return -1;
1977 }
1978 
1979 /* sprnt_fp prints a mpfr_t according to spec.spec specification.
1980 
1981    Return the size of the string (not counting the terminating '\0').
1982    Return -1 if the built string is too long (i.e. has more than
1983    INT_MAX or MPFR_INTMAX_MAX characters).
1984 
1985    If spec.size is 0, we only want the size of the string.
1986 */
1987 static int
sprnt_fp(struct string_buffer * buf,mpfr_srcptr p,const struct printf_spec spec)1988 sprnt_fp (struct string_buffer *buf, mpfr_srcptr p,
1989           const struct printf_spec spec)
1990 {
1991   mpfr_intmax_t length, start;
1992   struct number_parts np;
1993 
1994   length = partition_number (&np, p, spec);
1995   if (MPFR_UNLIKELY (length < 0))
1996     {
1997       buf->len = -1;
1998       return -1;
1999     }
2000 
2001   if (spec.size == 0)
2002     {
2003       /* This is equivalent to the following code (no need to fill the buffer
2004          and length is known). */
2005       buffer_incr_len (buf, length);
2006       goto clear_and_exit;
2007     }
2008 
2009   MPFR_DBGRES (start = buf->len);
2010 
2011   /* right justification padding with left spaces */
2012   if (np.pad_type == LEFT && np.pad_size != 0)
2013     buffer_pad (buf, ' ', np.pad_size);
2014 
2015   /* sign character (may be '-', '+', ' ', or '\0') */
2016   if (np.sign)
2017     buffer_pad (buf, np.sign, 1);
2018 
2019   /* prefix part */
2020   if (np.prefix_ptr)
2021     buffer_cat (buf, np.prefix_ptr, np.prefix_size);
2022 
2023   /* right justification  padding with leading zeros */
2024   if (np.pad_type == LEADING_ZEROS && np.pad_size != 0)
2025     buffer_pad (buf, '0', np.pad_size);
2026 
2027   /* integral part (may also be "nan" or "inf") */
2028   MPFR_ASSERTN (np.ip_ptr != NULL); /* never empty */
2029   if (MPFR_UNLIKELY (np.thousands_sep))
2030     {
2031       if (buffer_sandwich (buf, np.ip_ptr, np.ip_size, np.ip_trailing_digits,
2032                            np.thousands_sep))
2033         {
2034           buf->len = -1;
2035           goto clear_and_exit;
2036         }
2037     }
2038   else
2039     {
2040       buffer_cat (buf, np.ip_ptr, np.ip_size);
2041 
2042       /* possible trailing zero in integral part (spec.size != 0) */
2043       MPFR_ASSERTD (np.ip_trailing_digits <= 1);
2044       if (np.ip_trailing_digits != 0)
2045         buffer_pad (buf, '0', 1);
2046     }
2047 
2048   /* decimal point */
2049   if (np.point)
2050     buffer_pad (buf, np.point, 1);
2051 
2052   /* leading zeros in fractional part */
2053   if (np.fp_leading_zeros != 0)
2054     buffer_pad (buf, '0', np.fp_leading_zeros);
2055 
2056   /* significant digits in fractional part */
2057   if (np.fp_ptr)
2058     buffer_cat (buf, np.fp_ptr, np.fp_size);
2059 
2060   /* trailing zeros in fractional part */
2061   if (np.fp_trailing_zeros != 0)
2062     buffer_pad (buf, '0', np.fp_trailing_zeros);
2063 
2064   /* exponent part */
2065   if (np.exp_ptr)
2066     buffer_cat (buf, np.exp_ptr, np.exp_size);
2067 
2068   /* left justification padding with right spaces */
2069   if (np.pad_type == RIGHT && np.pad_size != 0)
2070     buffer_pad (buf, ' ', np.pad_size);
2071 
2072   MPFR_ASSERTD (buf->len == -1 || buf->len - start == length);
2073 
2074  clear_and_exit:
2075   clear_string_list (np.sl);
2076   return buf->len == -1 ? -1 : length;
2077 }
2078 
2079 /* The following internal function implements both mpfr_vasprintf and
2080    mpfr_vsnprintf:
2081    (a) either ptr <> NULL, and then Buf and size are not used, and it
2082        implements mpfr_vasprintf (ptr, fmt, ap)
2083    (b) or ptr = NULL, and it implements mpfr_vsnprintf (Buf, size, fmt, ap)
2084    It returns the number of characters that would have been written had 'size'
2085    been sufficiently large, not counting the terminating null character, or -1
2086    if this number is too large for the return type 'int' (overflow).
2087 */
2088 int
mpfr_vasnprintf_aux(char ** ptr,char * Buf,size_t size,const char * fmt,va_list ap)2089 mpfr_vasnprintf_aux (char **ptr, char *Buf, size_t size, const char *fmt,
2090                      va_list ap)
2091 {
2092   struct string_buffer buf;
2093   int nbchar;
2094 
2095   /* information on the conversion specification filled by the parser */
2096   struct printf_spec spec;
2097   /* flag raised when previous part of fmt need to be processed by
2098      gmp_vsnprintf */
2099   int xgmp_fmt_flag;
2100   /* beginning and end of the previous unprocessed part of fmt */
2101   const char *start, *end;
2102   /* pointer to arguments for gmp_vasprintf */
2103   va_list ap2;
2104 
2105   MPFR_SAVE_EXPO_DECL (expo);
2106   MPFR_SAVE_EXPO_MARK (expo);
2107 
2108   /* FIXME: Once buf.len >= size, switch to size = 0 for efficiency and
2109      avoid potential DoS? i.e. we no longer need to generate the strings
2110      (potentially huge), just compute the lengths. */
2111 
2112   buffer_init (&buf, ptr != NULL || size != 0 ? 4096 : 0);
2113   xgmp_fmt_flag = 0;
2114   va_copy (ap2, ap);
2115   start = fmt;
2116   while (*fmt != '\0')
2117     {
2118       int overflow = 0;
2119 
2120       /* Look for the next format specification */
2121       while (*fmt != '\0' && *fmt != '%')
2122         ++fmt;
2123 
2124       if (*fmt == '\0')
2125         break;
2126 
2127       if (*++fmt == '%')
2128         /* %%: go one step further otherwise the second '%' would be
2129            considered as a new conversion specification introducing
2130            character */
2131         {
2132           ++fmt;
2133           xgmp_fmt_flag = 1;
2134           continue;
2135         }
2136 
2137       end = fmt - 1;
2138 
2139       /* format string analysis */
2140       specinfo_init (&spec);
2141       fmt = parse_flags (fmt, &spec);
2142 
2143       READ_INT (ap, fmt, spec.width);
2144       if (spec.width < 0)  /* integer read via '*', no overflow */
2145         {
2146           spec.left = 1;
2147           /* Since the type of the integer is int, spec.width >= INT_MIN,
2148              so that an overflow is possible here only if mpfr_intmax_t
2149              has the same size of int. The INT_MIN < - MPFR_INTMAX_MAX
2150              test allows the compiler to optimize when it is false. */
2151           if (MPFR_UNLIKELY (INT_MIN < - MPFR_INTMAX_MAX &&
2152                              spec.width < - MPFR_INTMAX_MAX))
2153             overflow = 1;
2154           else
2155             spec.width = - spec.width;
2156         }
2157       /* Note: We will make sure that spec.width is not used in case of
2158          overflow. */
2159       MPFR_ASSERTD (overflow || spec.width >= 0);
2160 
2161       if (*fmt == '.')
2162         {
2163           ++fmt;
2164           READ_INT (ap, fmt, spec.prec);
2165           /* A negative value is possible with ".*" and it will be regarded
2166              as a missing precision (ISO C). We need to make sure that such
2167              a value is representable in an int (see its use below). */
2168           if (spec.prec < 0)
2169             spec.prec = -1;
2170         }
2171       else
2172         spec.prec = -1;  /* missing precision */
2173       MPFR_ASSERTD (spec.prec >= -1);
2174 
2175       fmt = parse_arg_type (fmt, &spec);
2176       if (spec.arg_type == UNSUPPORTED)
2177         /* the current architecture doesn't support the type corresponding to
2178            the format specifier; according to the ISO C99 standard, the
2179            behavior is undefined. We choose to print the format specifier as a
2180            literal string, what may be printed after this string is
2181            undefined. */
2182         continue;
2183       else if (spec.arg_type == MPFR_ARG)
2184         {
2185           switch (*fmt)
2186             {
2187             case '\0':
2188               break;
2189             case '*':
2190               ++fmt;
2191               spec.rnd_mode = (mpfr_rnd_t) va_arg (ap, int);
2192               break;
2193             case 'D':
2194               ++fmt;
2195               spec.rnd_mode = MPFR_RNDD;
2196               break;
2197             case 'U':
2198               ++fmt;
2199               spec.rnd_mode = MPFR_RNDU;
2200               break;
2201             case 'Y':
2202               ++fmt;
2203               spec.rnd_mode = MPFR_RNDA;
2204               break;
2205             case 'Z':
2206               ++fmt;
2207               spec.rnd_mode = MPFR_RNDZ;
2208               break;
2209             case 'N':
2210               ++fmt;
2211               MPFR_FALLTHROUGH;
2212             default:
2213               spec.rnd_mode = MPFR_RNDN;
2214             }
2215         }
2216 
2217       spec.spec = *fmt;
2218       if (!specinfo_is_valid (spec))
2219         /* the format specifier is invalid; according to the ISO C99 standard,
2220            the behavior is undefined. We choose to print the invalid format
2221            specifier as a literal string, what may be printed after this
2222            string is undefined. */
2223         continue;
2224 
2225       if (*fmt != '\0')
2226         fmt++;
2227 
2228       /* Format processing */
2229       if (spec.spec == '\0')
2230         /* end of the format string */
2231         break;
2232       else if (spec.spec == 'n')
2233         /* put the number of characters written so far in the location pointed
2234            by the next va_list argument; the types of pointer accepted are the
2235            same as in GMP (except unsupported quad_t) plus pointer to a mpfr_t
2236            so as to be able to accept the same format strings. */
2237         {
2238           void *p;
2239 
2240           p = va_arg (ap, void *);
2241           FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2242           va_end (ap2);
2243           start = fmt;
2244 
2245           switch (spec.arg_type)
2246             {
2247             case CHAR_ARG:
2248               *(char *) p = (char) buf.len;
2249               break;
2250             case SHORT_ARG:
2251               *(short *) p = (short) buf.len;
2252               break;
2253             case LONG_ARG:
2254               *(long *) p = (long) buf.len;
2255               break;
2256 #ifdef HAVE_LONG_LONG
2257             case LONG_LONG_ARG:
2258               *(long long *) p = (long long) buf.len;
2259               break;
2260 #endif
2261 #ifdef _MPFR_H_HAVE_INTMAX_T
2262             case INTMAX_ARG:
2263               *(intmax_t *) p = (intmax_t) buf.len;
2264               break;
2265 #endif
2266             case SIZE_ARG:
2267               *(size_t *) p = buf.len;
2268               break;
2269             case PTRDIFF_ARG:
2270               *(ptrdiff_t *) p = (ptrdiff_t) buf.len;
2271               break;
2272             case MPF_ARG:
2273               mpf_set_ui ((mpf_ptr) p, (unsigned long) buf.len);
2274               break;
2275             case MPQ_ARG:
2276               mpq_set_ui ((mpq_ptr) p, (unsigned long) buf.len, 1L);
2277               break;
2278             case MP_LIMB_ARG:
2279               *(mp_limb_t *) p = (mp_limb_t) buf.len;
2280               break;
2281             case MP_LIMB_ARRAY_ARG:
2282               {
2283                 mp_limb_t *q = (mp_limb_t *) p;
2284                 mp_size_t n;
2285                 n = va_arg (ap, mp_size_t);
2286                 if (n < 0)
2287                   n = -n;
2288                 else if (n == 0)
2289                   break;
2290 
2291                 /* we assume here that mp_limb_t is wider than int */
2292                 *q = (mp_limb_t) buf.len;
2293                 while (--n != 0)
2294                   {
2295                     q++;
2296                     *q = MPFR_LIMB_ZERO;
2297                   }
2298               }
2299               break;
2300             case MPZ_ARG:
2301               mpz_set_ui ((mpz_ptr) p, (unsigned long) buf.len);
2302               break;
2303 
2304             case MPFR_ARG:
2305               mpfr_set_ui ((mpfr_ptr) p, (unsigned long) buf.len,
2306                            spec.rnd_mode);
2307               break;
2308 
2309             default:
2310               *(int *) p = (int) buf.len;
2311             }
2312           va_copy (ap2, ap); /* after the switch, due to MP_LIMB_ARRAY_ARG
2313                                 case */
2314         }
2315       else if (spec.arg_type == MPFR_PREC_ARG)
2316         /* output mpfr_prec_t variable */
2317         {
2318           char *s;
2319           char format[MPFR_PREC_FORMAT_SIZE + 12]; /* e.g. "%0#+ -'*.*ld\0" */
2320           size_t length;
2321           mpfr_prec_t prec;
2322 
2323           /* FIXME: With buf.size = 0 and a huge width or precision, this
2324              can uselessly take much memory. And even with buf.size != 0,
2325              this would take more memory than necessary and need a large
2326              buffer_cat. A solution: compute a bound on the maximum
2327              number of significant digits, and handle the additional
2328              characters separately. Moreover, if buf.size = 0 or size != 0,
2329              gmp_snprintf should be called instead of gmp_asprintf,
2330              outputting data directly to the buffer when applicable.
2331              See also: https://sourceware.org/bugzilla/show_bug.cgi?id=23432
2332              Add testcases. */
2333 
2334           prec = va_arg (ap, mpfr_prec_t);
2335 
2336           FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2337           va_end (ap2);
2338           va_copy (ap2, ap);
2339           start = fmt;
2340 
2341           /* The restriction to INT_MAX is a limitation due to the fact
2342              that *.* is used below. If the width or precision field is
2343              larger than INT_MAX, then there is a real overflow on the
2344              return value due to the padding characters, thus the error
2345              is correct. The only minor drawback is that some variables
2346              corresponding to the 'n' conversion specifier with a type
2347              larger than int may not be set. This is not a bug, as there
2348              are no strong guarantees for such variables in case of error.
2349              FIXME: If size = 0 and max(spec.width,spec.prec) is large
2350              enough, there is no need to call gmp_asprintf since we are
2351              just interested in the length, which should be this maximum;
2352              in particular, this should avoid the overflow issue. */
2353           if (overflow || spec.width > INT_MAX || spec.prec > INT_MAX)
2354             {
2355               buf.len = -1;
2356               goto error;
2357             }
2358 
2359           /* Recalled from above. */
2360           MPFR_ASSERTD (spec.width >= 0);
2361           MPFR_ASSERTD (spec.prec >= -1);
2362 
2363           /* construct format string, like "%*.*hd" "%*.*d" or "%*.*ld" */
2364           sprintf (format, "%%%s%s%s%s%s%s*.*" MPFR_PREC_FORMAT_TYPE "%c",
2365                    spec.pad == '0' ? "0" : "",
2366                    spec.alt ? "#" : "",
2367                    spec.showsign ? "+" : "",
2368                    spec.space ? " " : "",
2369                    spec.left ? "-" : "",
2370                    spec.group ? "'" : "",
2371                    spec.spec);
2372           MPFR_LOG_MSG (("MPFR_PREC_ARG: format for gmp_asprintf: \"%s\"\n",
2373                          format));
2374           MPFR_LOG_MSG (("MPFR_PREC_ARG: width = %d, prec = %d, value = %"
2375                          MPFR_PREC_FORMAT_TYPE "d\n",
2376                          (int) spec.width, (int) spec.prec, prec));
2377           length = gmp_asprintf (&s, format,
2378                                  (int) spec.width, (int) spec.prec, prec);
2379           MPFR_ASSERTN (length >= 0);  /* guaranteed by GMP 6 */
2380           buffer_cat (&buf, s, length);
2381           mpfr_free_str (s);
2382         }
2383       else if (spec.arg_type == MPFR_ARG)
2384         /* output a mpfr_t variable */
2385         {
2386           mpfr_srcptr p;
2387 
2388           if (spec.spec != 'a' && spec.spec != 'A'
2389               && spec.spec != 'b'
2390               && spec.spec != 'e' && spec.spec != 'E'
2391               && spec.spec != 'f' && spec.spec != 'F'
2392               && spec.spec != 'g' && spec.spec != 'G')
2393             /* The format specifier is invalid; skip the invalid format
2394                specifier so as to print it as a literal string. What may
2395                be printed after this string is undefined. */
2396             continue;
2397 
2398           p = va_arg (ap, mpfr_srcptr);
2399 
2400           FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
2401           va_end (ap2);
2402           va_copy (ap2, ap);
2403           start = fmt;
2404 
2405           if (overflow)
2406             {
2407               buf.len = -1;
2408               goto error;
2409             }
2410 
2411           if (ptr == NULL)
2412             spec.size = size;
2413           sprnt_fp (&buf, p, spec);
2414         }
2415       else
2416         /* gmp_printf specification, step forward in the va_list */
2417         {
2418           CONSUME_VA_ARG (spec, ap);
2419           xgmp_fmt_flag = 1;
2420         }
2421     }
2422 
2423   if (start != fmt)
2424     FLUSH (xgmp_fmt_flag, start, fmt, ap2, &buf);
2425 
2426   va_end (ap2);
2427 
2428   if (buf.len == -1 || buf.len > INT_MAX)  /* overflow */
2429     goto overflow;
2430 
2431   nbchar = buf.len;
2432   MPFR_ASSERTD (nbchar >= 0);
2433 
2434   if (ptr != NULL)  /* implement mpfr_vasprintf */
2435     {
2436       MPFR_ASSERTD (nbchar == strlen (buf.start));
2437       *ptr = (char *) mpfr_reallocate_func (buf.start, buf.size, nbchar + 1);
2438     }
2439   else if (size != 0)  /* implement mpfr_vsnprintf */
2440     {
2441       if (nbchar < size)
2442         {
2443           strncpy (Buf, buf.start, nbchar);
2444           Buf[nbchar] = '\0';
2445         }
2446       else
2447         {
2448           strncpy (Buf, buf.start, size - 1);
2449           Buf[size-1] = '\0';
2450         }
2451       mpfr_free_func (buf.start, buf.size);
2452     }
2453 
2454   MPFR_SAVE_EXPO_FREE (expo);
2455   return nbchar; /* return the number of characters that would have
2456                     been written had 'size' been sufficiently large,
2457                     not counting the terminating null character */
2458 
2459  error:
2460   va_end (ap2);
2461   if (buf.len == -1)  /* overflow */
2462     {
2463     overflow:
2464       MPFR_LOG_MSG (("Overflow\n", 0));
2465       MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_ERANGE);
2466 #ifdef EOVERFLOW
2467       MPFR_LOG_MSG (("Setting errno to EOVERFLOW\n", 0));
2468       errno = EOVERFLOW;
2469 #endif
2470     }
2471 
2472   MPFR_SAVE_EXPO_FREE (expo);
2473   if (ptr != NULL)  /* implement mpfr_vasprintf */
2474     *ptr = NULL;
2475   if (ptr != NULL || size != 0)
2476     mpfr_free_func (buf.start, buf.size);
2477 
2478   return -1;
2479 }
2480 
2481 #else /* HAVE_STDARG */
2482 
2483 /* Avoid an empty translation unit (see ISO C99, 6.9) */
2484 typedef int foo;
2485 
2486 #endif /* HAVE_STDARG */
2487