Merge branch 'master' of ssh://crater.dragonflybsd.org/repository/git/dragonfly
[dragonfly.git] / contrib / mpfr / printf.c
1 /* mpfr_printf -- printf function and friends.
2
3 Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
4 Contributed by the Arenaire and Cacao 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 2.1 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.LIB.  If not, write to
20 the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21 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 exist */
28 #ifdef HAVE_STDARG
29
30 #include <stdarg.h>
31 #include <errno.h>
32 #include "mpfr-impl.h"
33
34 #ifdef _MPFR_H_HAVE_FILE
35
36 /* Each printf-like function calls mpfr_vasprintf which
37    - returns the number of characters in the returned string excluding the
38    terminating null
39    - returns -1 and sets the erange flag if the number of produced characters
40    exceeds INT_MAX (in that case, also sets errno to EOVERFLOW in POSIX
41    systems) */
42
43 #define GET_STR_VA(sz, str, fmt, ap)            \
44   do                                            \
45     {                                           \
46       sz = mpfr_vasprintf (&(str), fmt, ap);    \
47       if (sz < 0)                               \
48         {                                       \
49           if (str)                              \
50             mpfr_free_str (str);                \
51           return -1;                            \
52         }                                       \
53     } while (0)
54
55 #define GET_STR(sz, str, fmt)                   \
56   do                                            \
57     {                                           \
58       va_list ap;                               \
59       va_start(ap, fmt);                        \
60       sz = mpfr_vasprintf (&(str), fmt, ap);    \
61       va_end (ap);                              \
62       if (sz < 0)                               \
63         {                                       \
64           if (str)                              \
65             mpfr_free_str (str);                \
66           return -1;                            \
67         }                                       \
68     } while (0)
69
70 int
71 mpfr_printf (const char *fmt, ...)
72 {
73   char *str;
74   int ret;
75
76   GET_STR (ret, str, fmt);
77   ret = printf ("%s", str);
78
79   mpfr_free_str (str);
80   return ret;
81 }
82
83 int
84 mpfr_vprintf (const char *fmt, va_list ap)
85 {
86   char *str;
87   int ret;
88
89   GET_STR_VA (ret, str, fmt, ap);
90   ret = printf ("%s", str);
91
92   mpfr_free_str (str);
93   return ret;
94 }
95
96
97 int
98 mpfr_fprintf (FILE *fp, const char *fmt, ...)
99 {
100   char *str;
101   int ret;
102
103   GET_STR (ret, str, fmt);
104   ret = fprintf (fp, "%s", str);
105
106   mpfr_free_str (str);
107   return ret;
108 }
109
110 int
111 mpfr_vfprintf (FILE *fp, const char *fmt, va_list ap)
112 {
113   char *str;
114   int ret;
115
116   GET_STR_VA (ret, str, fmt, ap);
117   ret = fprintf (fp, "%s", str);
118
119   mpfr_free_str (str);
120   return ret;
121 }
122 #endif /* _MPFR_H_HAVE_FILE */
123
124 int
125 mpfr_sprintf (char *buf, const char *fmt, ...)
126 {
127   char *str;
128   int ret;
129
130   GET_STR (ret, str, fmt);
131   ret = sprintf (buf, "%s", str);
132
133   mpfr_free_str (str);
134   return ret;
135 }
136
137 int
138 mpfr_vsprintf (char *buf, const char *fmt, va_list ap)
139 {
140   char *str;
141   int ret;
142
143   GET_STR_VA (ret, str, fmt, ap);
144   ret = sprintf (buf, "%s", str);
145
146   mpfr_free_str (str);
147   return ret;
148 }
149
150 int
151 mpfr_snprintf (char *buf, size_t size, const char *fmt, ...)
152 {
153   char *str;
154   int ret;
155   size_t min_size;
156
157   GET_STR (ret, str, fmt);
158
159   /* C99 allows SIZE to be zero */
160   if (size != 0)
161     {
162       MPFR_ASSERTN (buf != NULL);
163       min_size = (size_t)ret < size ? (size_t)ret : size - 1;
164       strncpy (buf, str, min_size);
165       buf[min_size] = '\0';
166     }
167
168   mpfr_free_str (str);
169   return ret;
170 }
171
172 int
173 mpfr_vsnprintf (char *buf, size_t size, const char *fmt, va_list ap)
174 {
175   char *str;
176   int ret;
177   int min_size;
178
179   GET_STR_VA (ret, str, fmt, ap);
180
181   /* C99 allows SIZE to be zero */
182   if (size != 0)
183     {
184       MPFR_ASSERTN (buf != NULL);
185       min_size = (size_t)ret < size ? (size_t)ret : size - 1;
186       strncpy (buf, str, min_size);
187       buf[min_size] = '\0';
188     }
189
190   mpfr_free_str (str);
191   return ret;
192 }
193
194 int
195 mpfr_asprintf (char **pp, const char *fmt, ...)
196 {
197   int ret;
198
199   GET_STR (ret, *pp, fmt);
200
201   return ret;
202 }
203 #endif /* HAVE_STDARG */