1/* mpfr_printf -- printf function and friends. 2 3Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. 4Contributed by the AriC and Caramel projects, INRIA. 5 6This file is part of the GNU MPFR Library. 7 8The GNU MPFR Library is free software; you can redistribute it and/or modify 9it under the terms of the GNU Lesser General Public License as published by 10the Free Software Foundation; either version 3 of the License, or (at your 11option) any later version. 12 13The GNU MPFR Library is distributed in the hope that it will be useful, but 14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16License for more details. 17 18You should have received a copy of the GNU Lesser General Public License 19along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 2151 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#ifdef HAVE_STDARG 29 30#include <stdarg.h> 31 32#ifndef HAVE_VA_COPY 33# ifdef HAVE___VA_COPY 34# define va_copy(dst,src) __va_copy(dst, src) 35# else 36/* autoconf manual advocates this fallback. 37 This is also the solution chosen by gmp */ 38# define va_copy(dst,src) \ 39 do { memcpy(&(dst), &(src), sizeof(va_list)); } while (0) 40# endif /* HAVE___VA_COPY */ 41#endif /* HAVE_VA_COPY */ 42 43#include <errno.h> 44#include "mpfr-impl.h" 45 46#ifdef _MPFR_H_HAVE_FILE 47 48/* Each printf-like function calls mpfr_vasprintf which 49 - returns the number of characters in the returned string excluding the 50 terminating null 51 - returns -1 and sets the erange flag if the number of produced characters 52 exceeds INT_MAX (in that case, also sets errno to EOVERFLOW in POSIX 53 systems) */ 54 55#define GET_STR_VA(sz, str, fmt, ap) \ 56 do \ 57 { \ 58 sz = mpfr_vasprintf (&(str), fmt, ap); \ 59 if (sz < 0) \ 60 { \ 61 if (str) \ 62 mpfr_free_str (str); \ 63 return -1; \ 64 } \ 65 } while (0) 66 67#define GET_STR(sz, str, fmt) \ 68 do \ 69 { \ 70 va_list ap; \ 71 va_start(ap, fmt); \ 72 sz = mpfr_vasprintf (&(str), fmt, ap); \ 73 va_end (ap); \ 74 if (sz < 0) \ 75 { \ 76 if (str) \ 77 mpfr_free_str (str); \ 78 return -1; \ 79 } \ 80 } while (0) 81 82int 83mpfr_printf (const char *fmt, ...) 84{ 85 char *str; 86 int ret; 87 88 GET_STR (ret, str, fmt); 89 ret = printf ("%s", str); 90 91 mpfr_free_str (str); 92 return ret; 93} 94 95int 96mpfr_vprintf (const char *fmt, va_list ap) 97{ 98 char *str; 99 int ret; 100 101 GET_STR_VA (ret, str, fmt, ap); 102 ret = printf ("%s", str); 103 104 mpfr_free_str (str); 105 return ret; 106} 107 108 109int 110mpfr_fprintf (FILE *fp, const char *fmt, ...) 111{ 112 char *str; 113 int ret; 114 115 GET_STR (ret, str, fmt); 116 ret = fprintf (fp, "%s", str); 117 118 mpfr_free_str (str); 119 return ret; 120} 121 122int 123mpfr_vfprintf (FILE *fp, const char *fmt, va_list ap) 124{ 125 char *str; 126 int ret; 127 128 GET_STR_VA (ret, str, fmt, ap); 129 ret = fprintf (fp, "%s", str); 130 131 mpfr_free_str (str); 132 return ret; 133} 134#endif /* _MPFR_H_HAVE_FILE */ 135 136int 137mpfr_sprintf (char *buf, const char *fmt, ...) 138{ 139 char *str; 140 int ret; 141 142 GET_STR (ret, str, fmt); 143 ret = sprintf (buf, "%s", str); 144 145 mpfr_free_str (str); 146 return ret; 147} 148 149int 150mpfr_vsprintf (char *buf, const char *fmt, va_list ap) 151{ 152 char *str; 153 int ret; 154 155 GET_STR_VA (ret, str, fmt, ap); 156 ret = sprintf (buf, "%s", str); 157 158 mpfr_free_str (str); 159 return ret; 160} 161 162int 163mpfr_snprintf (char *buf, size_t size, const char *fmt, ...) 164{ 165 char *str; 166 int ret; 167 size_t min_size; 168 169 GET_STR (ret, str, fmt); 170 171 /* C99 allows SIZE to be zero */ 172 if (size != 0) 173 { 174 MPFR_ASSERTN (buf != NULL); 175 min_size = (size_t)ret < size ? (size_t)ret : size - 1; 176 strncpy (buf, str, min_size); 177 buf[min_size] = '\0'; 178 } 179 180 mpfr_free_str (str); 181 return ret; 182} 183 184int 185mpfr_vsnprintf (char *buf, size_t size, const char *fmt, va_list ap) 186{ 187 char *str; 188 int ret; 189 int min_size; 190 191 GET_STR_VA (ret, str, fmt, ap); 192 193 /* C99 allows SIZE to be zero */ 194 if (size != 0) 195 { 196 MPFR_ASSERTN (buf != NULL); 197 min_size = (size_t)ret < size ? (size_t)ret : size - 1; 198 strncpy (buf, str, min_size); 199 buf[min_size] = '\0'; 200 } 201 202 mpfr_free_str (str); 203 return ret; 204} 205 206int 207mpfr_asprintf (char **pp, const char *fmt, ...) 208{ 209 int ret; 210 211 GET_STR (ret, *pp, fmt); 212 213 return ret; 214} 215#endif /* HAVE_STDARG */ 216