1 /* Formatted output to strings, using POSIX/XSI format strings with positions.
2 Copyright (C) 2003 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2003.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU Library General Public License as published
7 by the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18 USA. */
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #ifdef __GNUC__
25 # define alloca __builtin_alloca
26 # define HAVE_ALLOCA 1
27 #else
28 # ifdef _MSC_VER
29 # include <malloc.h>
30 # define alloca _alloca
31 # else
32 # if defined HAVE_ALLOCA_H || defined _LIBC
33 # include <alloca.h>
34 # else
35 # ifdef _AIX
36 #pragma alloca
37 # else
38 # ifndef alloca
39 char *alloca ();
40 # endif
41 # endif
42 # endif
43 # endif
44 #endif
45
46 #include <stdio.h>
47
48 #if !HAVE_POSIX_PRINTF
49
50 #include <stdlib.h>
51 #include <string.h>
52
53 /* When building a DLL, we must export some functions. Note that because
54 the functions are only defined for binary backward compatibility, we
55 don't need to use __declspec(dllimport) in any case. */
56 #if defined _MSC_VER && BUILDING_DLL
57 # define DLL_EXPORTED __declspec(dllexport)
58 #else
59 # define DLL_EXPORTED
60 #endif
61
62 #define STATIC static
63
64 /* Define auxiliary functions declared in "printf-args.h". */
65 #include "printf-args.c"
66
67 /* Define auxiliary functions declared in "printf-parse.h". */
68 #include "printf-parse.c"
69
70 /* Define functions declared in "vasnprintf.h". */
71 #define vasnprintf libintl_vasnprintf
72 #include "vasnprintf.c"
73 #if 0 /* not needed */
74 #define asnprintf libintl_asnprintf
75 #include "asnprintf.c"
76 #endif
77
78 DLL_EXPORTED
79 int
libintl_vfprintf(FILE * stream,const char * format,va_list args)80 libintl_vfprintf (FILE *stream, const char *format, va_list args)
81 {
82 if (strchr (format, '$') == NULL)
83 return vfprintf (stream, format, args);
84 else
85 {
86 size_t length;
87 char *result = libintl_vasnprintf (NULL, &length, format, args);
88 int retval = -1;
89 if (result != NULL)
90 {
91 if (fwrite (result, 1, length, stream) == length)
92 retval = length;
93 free (result);
94 }
95 return retval;
96 }
97 }
98
99 DLL_EXPORTED
100 int
libintl_fprintf(FILE * stream,const char * format,...)101 libintl_fprintf (FILE *stream, const char *format, ...)
102 {
103 va_list args;
104 int retval;
105
106 va_start (args, format);
107 retval = libintl_vfprintf (stream, format, args);
108 va_end (args);
109 return retval;
110 }
111
112 DLL_EXPORTED
113 int
libintl_vprintf(const char * format,va_list args)114 libintl_vprintf (const char *format, va_list args)
115 {
116 return libintl_vfprintf (stdout, format, args);
117 }
118
119 DLL_EXPORTED
120 int
libintl_printf(const char * format,...)121 libintl_printf (const char *format, ...)
122 {
123 va_list args;
124 int retval;
125
126 va_start (args, format);
127 retval = libintl_vprintf (format, args);
128 va_end (args);
129 return retval;
130 }
131
132 DLL_EXPORTED
133 int
libintl_vsprintf(char * resultbuf,const char * format,va_list args)134 libintl_vsprintf (char *resultbuf, const char *format, va_list args)
135 {
136 if (strchr (format, '$') == NULL)
137 return vsprintf (resultbuf, format, args);
138 else
139 {
140 size_t length = (size_t) ~0 / (4 * sizeof (char));
141 char *result = libintl_vasnprintf (resultbuf, &length, format, args);
142 if (result != resultbuf)
143 {
144 free (result);
145 return -1;
146 }
147 else
148 return length;
149 }
150 }
151
152 DLL_EXPORTED
153 int
libintl_sprintf(char * resultbuf,const char * format,...)154 libintl_sprintf (char *resultbuf, const char *format, ...)
155 {
156 va_list args;
157 int retval;
158
159 va_start (args, format);
160 retval = libintl_vsprintf (resultbuf, format, args);
161 va_end (args);
162 return retval;
163 }
164
165 #if HAVE_SNPRINTF
166
167 # if HAVE_DECL__SNPRINTF
168 /* Windows. */
169 # define system_vsnprintf _vsnprintf
170 # else
171 /* Unix. */
172 # define system_vsnprintf vsnprintf
173 # endif
174
175 DLL_EXPORTED
176 int
libintl_vsnprintf(char * resultbuf,size_t length,const char * format,va_list args)177 libintl_vsnprintf (char *resultbuf, size_t length, const char *format, va_list args)
178 {
179 if (strchr (format, '$') == NULL)
180 return system_vsnprintf (resultbuf, length, format, args);
181 else
182 {
183 size_t maxlength = length;
184 char *result = libintl_vasnprintf (resultbuf, &length, format, args);
185 if (result != resultbuf)
186 {
187 if (maxlength > 0)
188 {
189 if (length < maxlength)
190 abort ();
191 memcpy (resultbuf, result, maxlength - 1);
192 resultbuf[maxlength - 1] = '\0';
193 }
194 free (result);
195 return -1;
196 }
197 else
198 return length;
199 }
200 }
201
202 DLL_EXPORTED
203 int
libintl_snprintf(char * resultbuf,size_t length,const char * format,...)204 libintl_snprintf (char *resultbuf, size_t length, const char *format, ...)
205 {
206 va_list args;
207 int retval;
208
209 va_start (args, format);
210 retval = libintl_vsnprintf (resultbuf, length, format, args);
211 va_end (args);
212 return retval;
213 }
214
215 #endif
216
217 #if HAVE_ASPRINTF
218
219 DLL_EXPORTED
220 int
libintl_vasprintf(char ** resultp,const char * format,va_list args)221 libintl_vasprintf (char **resultp, const char *format, va_list args)
222 {
223 size_t length;
224 char *result = libintl_vasnprintf (NULL, &length, format, args);
225 if (result == NULL)
226 return -1;
227 *resultp = result;
228 return length;
229 }
230
231 DLL_EXPORTED
232 int
libintl_asprintf(char ** resultp,const char * format,...)233 libintl_asprintf (char **resultp, const char *format, ...)
234 {
235 va_list args;
236 int retval;
237
238 va_start (args, format);
239 retval = libintl_vasprintf (resultp, format, args);
240 va_end (args);
241 return retval;
242 }
243
244 #endif
245
246 #if HAVE_FWPRINTF
247
248 #include <wchar.h>
249
250 #define WIDE_CHAR_VERSION 1
251
252 /* Define auxiliary functions declared in "wprintf-parse.h". */
253 #include "printf-parse.c"
254
255 /* Define functions declared in "vasnprintf.h". */
256 #define vasnwprintf libintl_vasnwprintf
257 #include "vasnprintf.c"
258 #if 0 /* not needed */
259 #define asnwprintf libintl_asnwprintf
260 #include "asnprintf.c"
261 #endif
262
263 # if HAVE_DECL__SNWPRINTF
264 /* Windows. */
265 # define system_vswprintf _vsnwprintf
266 # else
267 /* Unix. */
268 # define system_vswprintf vswprintf
269 # endif
270
271 DLL_EXPORTED
272 int
libintl_vfwprintf(FILE * stream,const wchar_t * format,va_list args)273 libintl_vfwprintf (FILE *stream, const wchar_t *format, va_list args)
274 {
275 if (wcschr (format, '$') == NULL)
276 return vfwprintf (stream, format, args);
277 else
278 {
279 size_t length;
280 wchar_t *result = libintl_vasnwprintf (NULL, &length, format, args);
281 int retval = -1;
282 if (result != NULL)
283 {
284 size_t i;
285 for (i = 0; i < length; i++)
286 if (fputwc (result[i], stream) == WEOF)
287 break;
288 if (i == length)
289 retval = length;
290 free (result);
291 }
292 return retval;
293 }
294 }
295
296 DLL_EXPORTED
297 int
libintl_fwprintf(FILE * stream,const wchar_t * format,...)298 libintl_fwprintf (FILE *stream, const wchar_t *format, ...)
299 {
300 va_list args;
301 int retval;
302
303 va_start (args, format);
304 retval = libintl_vfwprintf (stream, format, args);
305 va_end (args);
306 return retval;
307 }
308
309 DLL_EXPORTED
310 int
libintl_vwprintf(const wchar_t * format,va_list args)311 libintl_vwprintf (const wchar_t *format, va_list args)
312 {
313 return libintl_vfwprintf (stdout, format, args);
314 }
315
316 DLL_EXPORTED
317 int
libintl_wprintf(const wchar_t * format,...)318 libintl_wprintf (const wchar_t *format, ...)
319 {
320 va_list args;
321 int retval;
322
323 va_start (args, format);
324 retval = libintl_vwprintf (format, args);
325 va_end (args);
326 return retval;
327 }
328
329 DLL_EXPORTED
330 int
libintl_vswprintf(wchar_t * resultbuf,size_t length,const wchar_t * format,va_list args)331 libintl_vswprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, va_list args)
332 {
333 if (wcschr (format, '$') == NULL)
334 return system_vswprintf (resultbuf, length, format, args);
335 else
336 {
337 size_t maxlength = length;
338 wchar_t *result = libintl_vasnwprintf (resultbuf, &length, format, args);
339 if (result != resultbuf)
340 {
341 if (maxlength > 0)
342 {
343 if (length < maxlength)
344 abort ();
345 memcpy (resultbuf, result, (maxlength - 1) * sizeof (wchar_t));
346 resultbuf[maxlength - 1] = 0;
347 }
348 free (result);
349 return -1;
350 }
351 else
352 return length;
353 }
354 }
355
356 DLL_EXPORTED
357 int
libintl_swprintf(wchar_t * resultbuf,size_t length,const wchar_t * format,...)358 libintl_swprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, ...)
359 {
360 va_list args;
361 int retval;
362
363 va_start (args, format);
364 retval = libintl_vswprintf (resultbuf, length, format, args);
365 va_end (args);
366 return retval;
367 }
368
369 #endif
370
371 #endif
372