]> git.deb.at Git - pkg/abook.git/blob - intl/printf.c
autotools update: 1/2: main files
[pkg/abook.git] / intl / printf.c
1 /* Formatted output to strings, using POSIX/XSI format strings with positions.
2    Copyright (C) 2003, 2006-2007, 2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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 <errno.h>
51 #include <limits.h>
52 #include <stdlib.h>
53 #include <string.h>
54
55 /* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW.  */
56 #ifndef EOVERFLOW
57 # define EOVERFLOW E2BIG
58 #endif
59
60 /* When building a DLL, we must export some functions.  Note that because
61    the functions are only defined for binary backward compatibility, we
62    don't need to use __declspec(dllimport) in any case.  */
63 #if HAVE_VISIBILITY && BUILDING_DLL
64 # define DLL_EXPORTED __attribute__((__visibility__("default")))
65 #elif defined _MSC_VER && BUILDING_DLL
66 # define DLL_EXPORTED __declspec(dllexport)
67 #else
68 # define DLL_EXPORTED
69 #endif
70
71 #define STATIC static
72
73 /* This needs to be consistent with libgnuintl.h.in.  */
74 #if defined __NetBSD__ || defined __BEOS__ || defined __CYGWIN__ || defined __MINGW32__
75 /* Don't break __attribute__((format(printf,M,N))).
76    This redefinition is only possible because the libc in NetBSD, Cygwin,
77    mingw does not have a function __printf__.  */
78 # define libintl_printf __printf__
79 #endif
80
81 /* Define auxiliary functions declared in "printf-args.h".  */
82 #include "printf-args.c"
83
84 /* Define auxiliary functions declared in "printf-parse.h".  */
85 #include "printf-parse.c"
86
87 /* Define functions declared in "vasnprintf.h".  */
88 #define vasnprintf libintl_vasnprintf
89 #include "vasnprintf.c"
90 #if 0 /* not needed */
91 #define asnprintf libintl_asnprintf
92 #include "asnprintf.c"
93 #endif
94
95 DLL_EXPORTED
96 int
97 libintl_vfprintf (FILE *stream, const char *format, va_list args)
98 {
99   if (strchr (format, '$') == NULL)
100     return vfprintf (stream, format, args);
101   else
102     {
103       size_t length;
104       char *result = libintl_vasnprintf (NULL, &length, format, args);
105       int retval = -1;
106       if (result != NULL)
107         {
108           size_t written = fwrite (result, 1, length, stream);
109           free (result);
110           if (written == length)
111             {
112               if (length > INT_MAX)
113                 errno = EOVERFLOW;
114               else
115                 retval = length;
116             }
117         }
118       return retval;
119     }
120 }
121
122 DLL_EXPORTED
123 int
124 libintl_fprintf (FILE *stream, const char *format, ...)
125 {
126   va_list args;
127   int retval;
128
129   va_start (args, format);
130   retval = libintl_vfprintf (stream, format, args);
131   va_end (args);
132   return retval;
133 }
134
135 DLL_EXPORTED
136 int
137 libintl_vprintf (const char *format, va_list args)
138 {
139   return libintl_vfprintf (stdout, format, args);
140 }
141
142 DLL_EXPORTED
143 int
144 libintl_printf (const char *format, ...)
145 {
146   va_list args;
147   int retval;
148
149   va_start (args, format);
150   retval = libintl_vprintf (format, args);
151   va_end (args);
152   return retval;
153 }
154
155 DLL_EXPORTED
156 int
157 libintl_vsprintf (char *resultbuf, const char *format, va_list args)
158 {
159   if (strchr (format, '$') == NULL)
160     return vsprintf (resultbuf, format, args);
161   else
162     {
163       size_t length = (size_t) ~0 / (4 * sizeof (char));
164       char *result = libintl_vasnprintf (resultbuf, &length, format, args);
165       if (result != resultbuf)
166         {
167           free (result);
168           return -1;
169         }
170       if (length > INT_MAX)
171         {
172           errno = EOVERFLOW;
173           return -1;
174         }
175       else
176         return length;
177     }
178 }
179
180 DLL_EXPORTED
181 int
182 libintl_sprintf (char *resultbuf, const char *format, ...)
183 {
184   va_list args;
185   int retval;
186
187   va_start (args, format);
188   retval = libintl_vsprintf (resultbuf, format, args);
189   va_end (args);
190   return retval;
191 }
192
193 #if HAVE_SNPRINTF
194
195 # if HAVE_DECL__SNPRINTF
196    /* Windows.  */
197 #  define system_vsnprintf _vsnprintf
198 # else
199    /* Unix.  */
200 #  define system_vsnprintf vsnprintf
201 # endif
202
203 DLL_EXPORTED
204 int
205 libintl_vsnprintf (char *resultbuf, size_t length, const char *format, va_list args)
206 {
207   if (strchr (format, '$') == NULL)
208     return system_vsnprintf (resultbuf, length, format, args);
209   else
210     {
211       size_t maxlength = length;
212       char *result = libintl_vasnprintf (resultbuf, &length, format, args);
213       if (result != resultbuf)
214         {
215           if (maxlength > 0)
216             {
217               size_t pruned_length =
218                 (length < maxlength ? length : maxlength - 1);
219               memcpy (resultbuf, result, pruned_length);
220               resultbuf[pruned_length] = '\0';
221             }
222           free (result);
223         }
224       if (length > INT_MAX)
225         {
226           errno = EOVERFLOW;
227           return -1;
228         }
229       else
230         return length;
231     }
232 }
233
234 DLL_EXPORTED
235 int
236 libintl_snprintf (char *resultbuf, size_t length, const char *format, ...)
237 {
238   va_list args;
239   int retval;
240
241   va_start (args, format);
242   retval = libintl_vsnprintf (resultbuf, length, format, args);
243   va_end (args);
244   return retval;
245 }
246
247 #endif
248
249 #if HAVE_ASPRINTF
250
251 DLL_EXPORTED
252 int
253 libintl_vasprintf (char **resultp, const char *format, va_list args)
254 {
255   size_t length;
256   char *result = libintl_vasnprintf (NULL, &length, format, args);
257   if (result == NULL)
258     return -1;
259   if (length > INT_MAX)
260     {
261       free (result);
262       errno = EOVERFLOW;
263       return -1;
264     }
265   *resultp = result;
266   return length;
267 }
268
269 DLL_EXPORTED
270 int
271 libintl_asprintf (char **resultp, const char *format, ...)
272 {
273   va_list args;
274   int retval;
275
276   va_start (args, format);
277   retval = libintl_vasprintf (resultp, format, args);
278   va_end (args);
279   return retval;
280 }
281
282 #endif
283
284 #if HAVE_FWPRINTF
285
286 #include <wchar.h>
287
288 #define WIDE_CHAR_VERSION 1
289
290 #include "wprintf-parse.h"
291 /* Define auxiliary functions declared in "wprintf-parse.h".  */
292 #define CHAR_T wchar_t
293 #define DIRECTIVE wchar_t_directive
294 #define DIRECTIVES wchar_t_directives
295 #define PRINTF_PARSE wprintf_parse
296 #include "printf-parse.c"
297
298 /* Define functions declared in "vasnprintf.h".  */
299 #define vasnwprintf libintl_vasnwprintf
300 #include "vasnprintf.c"
301 #if 0 /* not needed */
302 #define asnwprintf libintl_asnwprintf
303 #include "asnprintf.c"
304 #endif
305
306 # if HAVE_DECL__SNWPRINTF
307    /* Windows.  */
308 #  define system_vswprintf _vsnwprintf
309 # else
310    /* Unix.  */
311 #  define system_vswprintf vswprintf
312 # endif
313
314 DLL_EXPORTED
315 int
316 libintl_vfwprintf (FILE *stream, const wchar_t *format, va_list args)
317 {
318   if (wcschr (format, '$') == NULL)
319     return vfwprintf (stream, format, args);
320   else
321     {
322       size_t length;
323       wchar_t *result = libintl_vasnwprintf (NULL, &length, format, args);
324       int retval = -1;
325       if (result != NULL)
326         {
327           size_t i;
328           for (i = 0; i < length; i++)
329             if (fputwc (result[i], stream) == WEOF)
330               break;
331           free (result);
332           if (i == length)
333             {
334               if (length > INT_MAX)
335                 errno = EOVERFLOW;
336               else
337                 retval = length;
338             }
339         }
340       return retval;
341     }
342 }
343
344 DLL_EXPORTED
345 int
346 libintl_fwprintf (FILE *stream, const wchar_t *format, ...)
347 {
348   va_list args;
349   int retval;
350
351   va_start (args, format);
352   retval = libintl_vfwprintf (stream, format, args);
353   va_end (args);
354   return retval;
355 }
356
357 DLL_EXPORTED
358 int
359 libintl_vwprintf (const wchar_t *format, va_list args)
360 {
361   return libintl_vfwprintf (stdout, format, args);
362 }
363
364 DLL_EXPORTED
365 int
366 libintl_wprintf (const wchar_t *format, ...)
367 {
368   va_list args;
369   int retval;
370
371   va_start (args, format);
372   retval = libintl_vwprintf (format, args);
373   va_end (args);
374   return retval;
375 }
376
377 DLL_EXPORTED
378 int
379 libintl_vswprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, va_list args)
380 {
381   if (wcschr (format, '$') == NULL)
382     return system_vswprintf (resultbuf, length, format, args);
383   else
384     {
385       size_t maxlength = length;
386       wchar_t *result = libintl_vasnwprintf (resultbuf, &length, format, args);
387       if (result != resultbuf)
388         {
389           if (maxlength > 0)
390             {
391               size_t pruned_length =
392                 (length < maxlength ? length : maxlength - 1);
393               memcpy (resultbuf, result, pruned_length * sizeof (wchar_t));
394               resultbuf[pruned_length] = 0;
395             }
396           free (result);
397           /* Unlike vsnprintf, which has to return the number of character that
398              would have been produced if the resultbuf had been sufficiently
399              large, the vswprintf function has to return a negative value if
400              the resultbuf was not sufficiently large.  */
401           if (length >= maxlength)
402             return -1;
403         }
404       if (length > INT_MAX)
405         {
406           errno = EOVERFLOW;
407           return -1;
408         }
409       else
410         return length;
411     }
412 }
413
414 DLL_EXPORTED
415 int
416 libintl_swprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, ...)
417 {
418   va_list args;
419   int retval;
420
421   va_start (args, format);
422   retval = libintl_vswprintf (resultbuf, length, format, args);
423   va_end (args);
424   return retval;
425 }
426
427 #endif
428
429 #endif