]>
Commit | Line | Data |
---|---|---|
b0cacab0 TT |
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 | |
8785aaea | 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
b0cacab0 TT |
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 | |
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 | |
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 | |
114 | libintl_vprintf (const char *format, va_list args) | |
115 | { | |
116 | return libintl_vfprintf (stdout, format, args); | |
117 | } | |
118 | ||
119 | DLL_EXPORTED | |
120 | int | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 |