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