(root)/
mpfr-4.2.1/
src/
printf.c
       1  /* Formatted output functions (printf functions family).
       2  
       3  Copyright 2007-2023 Free Software Foundation, Inc.
       4  Contributed by the AriC and Caramba projects, INRIA.
       5  
       6  This file is part of the GNU MPFR Library.
       7  
       8  The GNU MPFR Library is free software; you can redistribute it and/or modify
       9  it under the terms of the GNU Lesser General Public License as published by
      10  the Free Software Foundation; either version 3 of the License, or (at your
      11  option) any later version.
      12  
      13  The GNU MPFR Library is distributed in the hope that it will be useful, but
      14  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      15  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
      16  License for more details.
      17  
      18  You should have received a copy of the GNU Lesser General Public License
      19  along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
      20  https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
      21  51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
      22  
      23  #ifdef HAVE_CONFIG_H
      24  # include "config.h"
      25  #endif
      26  
      27  /* The mpfr_printf-like functions are defined only if <stdarg.h> exists.
      28     Since they use mpf_t, they cannot be defined with mini-gmp. */
      29  #if defined(HAVE_STDARG) && !defined(MPFR_USE_MINI_GMP)
      30  
      31  #include <stdarg.h>
      32  
      33  #include "mpfr-impl.h"
      34  
      35  #ifdef _MPFR_H_HAVE_FILE
      36  
      37  /* Each printf-like function calls mpfr_vasnprintf_aux (directly or
      38     via mpfr_vasprintf), which
      39     - returns the number of characters to be written excluding the
      40       terminating null character (disregarding the size argument);
      41     - returns -1 and sets the erange flag if this number exceeds INT_MAX
      42       (in that case, also sets errno to EOVERFLOW on POSIX systems). */
      43  
      44  #define GET_STR_VA(sz, str, fmt, ap)            \
      45    do                                            \
      46      {                                           \
      47        sz = mpfr_vasprintf (&(str), fmt, ap);    \
      48        if (sz < 0)                               \
      49          {                                       \
      50            if (str)                              \
      51              mpfr_free_str (str);                \
      52            return -1;                            \
      53          }                                       \
      54      } while (0)
      55  
      56  #define GET_STR(sz, str, fmt)                   \
      57    do                                            \
      58      {                                           \
      59        va_list ap;                               \
      60        va_start(ap, fmt);                        \
      61        sz = mpfr_vasprintf (&(str), fmt, ap);    \
      62        va_end (ap);                              \
      63        if (sz < 0)                               \
      64          {                                       \
      65            if (str)                              \
      66              mpfr_free_str (str);                \
      67            return -1;                            \
      68          }                                       \
      69      } while (0)
      70  
      71  int
      72  mpfr_printf (const char *fmt, ...)
      73  {
      74    char *str;
      75    int ret;
      76  
      77    GET_STR (ret, str, fmt);
      78    ret = printf ("%s", str);
      79  
      80    mpfr_free_str (str);
      81    return ret;
      82  }
      83  
      84  int
      85  mpfr_vprintf (const char *fmt, va_list ap)
      86  {
      87    char *str;
      88    int ret;
      89  
      90    GET_STR_VA (ret, str, fmt, ap);
      91    ret = printf ("%s", str);
      92  
      93    mpfr_free_str (str);
      94    return ret;
      95  }
      96  
      97  
      98  int
      99  mpfr_fprintf (FILE *fp, const char *fmt, ...)
     100  {
     101    char *str;
     102    int ret;
     103  
     104    GET_STR (ret, str, fmt);
     105    ret = fprintf (fp, "%s", str);
     106  
     107    mpfr_free_str (str);
     108    return ret;
     109  }
     110  
     111  int
     112  mpfr_vfprintf (FILE *fp, const char *fmt, va_list ap)
     113  {
     114    char *str;
     115    int ret;
     116  
     117    GET_STR_VA (ret, str, fmt, ap);
     118    ret = fprintf (fp, "%s", str);
     119  
     120    mpfr_free_str (str);
     121    return ret;
     122  }
     123  
     124  #endif /* _MPFR_H_HAVE_FILE */
     125  
     126  int
     127  mpfr_sprintf (char *buf, const char *fmt, ...)
     128  {
     129    char *str;
     130    int ret;
     131  
     132    GET_STR (ret, str, fmt);
     133    ret = sprintf (buf, "%s", str);
     134  
     135    mpfr_free_str (str);
     136    return ret;
     137  }
     138  
     139  int
     140  mpfr_vsprintf (char *buf, const char *fmt, va_list ap)
     141  {
     142    char *str;
     143    int ret;
     144  
     145    GET_STR_VA (ret, str, fmt, ap);
     146    ret = sprintf (buf, "%s", str);
     147  
     148    mpfr_free_str (str);
     149    return ret;
     150  }
     151  
     152  int
     153  mpfr_snprintf (char *buf, size_t size, const char *fmt, ...)
     154  {
     155    int ret;
     156    va_list ap;
     157  
     158    va_start(ap, fmt);
     159    ret = mpfr_vasnprintf_aux (NULL, buf, size, fmt, ap);
     160    va_end (ap);
     161  
     162    return ret;
     163  }
     164  
     165  int
     166  mpfr_vsnprintf (char *buf, size_t size, const char *fmt, va_list ap)
     167  {
     168    return mpfr_vasnprintf_aux (NULL, buf, size, fmt, ap);
     169  }
     170  
     171  int
     172  mpfr_asprintf (char **pp, const char *fmt, ...)
     173  {
     174    int ret;
     175  
     176    GET_STR (ret, *pp, fmt);
     177  
     178    return ret;
     179  }
     180  
     181  int
     182  mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
     183  {
     184    return mpfr_vasnprintf_aux (ptr, NULL, 0, fmt, ap);
     185  }
     186  
     187  #else /* HAVE_STDARG */
     188  
     189  /* Avoid an empty translation unit (see ISO C99, 6.9) */
     190  typedef int foo;
     191  
     192  #endif /* HAVE_STDARG */