1 /* Formatted output to strings, using POSIX/XSI format strings with positions.
2 Copyright (C) 2003, 2006-2007, 2009-2011, 2015 Free Software
4 Written by Bruno Haible <bruno@clisp.org>, 2003.
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 # define alloca __builtin_alloca
25 # define HAVE_ALLOCA 1
29 # define alloca _alloca
31 # if defined HAVE_ALLOCA_H || defined _LIBC
47 #if !HAVE_POSIX_PRINTF
54 /* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */
56 # define EOVERFLOW E2BIG
59 /* When building a DLL, we must export some functions. Note that because
60 the functions are only defined for binary backward compatibility, we
61 don't need to use __declspec(dllimport) in any case. */
62 #if HAVE_VISIBILITY && BUILDING_DLL
63 # define DLL_EXPORTED __attribute__((__visibility__("default")))
64 #elif defined _MSC_VER && BUILDING_DLL
65 # define DLL_EXPORTED __declspec(dllexport)
72 /* This needs to be consistent with libgnuintl.in.h. */
73 #if defined __NetBSD__ || defined __BEOS__ || defined __CYGWIN__ || defined __MINGW32__
74 /* Don't break __attribute__((format(printf,M,N))).
75 This redefinition is only possible because the libc in NetBSD, Cygwin,
76 mingw does not have a function __printf__. */
77 # define libintl_printf __printf__
80 /* Define auxiliary functions declared in "printf-args.h". */
81 #include "printf-args.c"
83 /* Define auxiliary functions declared in "printf-parse.h". */
84 #include "printf-parse.c"
86 /* Define functions declared in "vasnprintf.h". */
87 #define vasnprintf libintl_vasnprintf
88 #include "vasnprintf.c"
89 #if 0 /* not needed */
90 #define asnprintf libintl_asnprintf
91 #include "asnprintf.c"
96 libintl_vfprintf (FILE *stream, const char *format, va_list args)
98 if (strchr (format, '$') == NULL)
99 return vfprintf (stream, format, args);
103 char *result = libintl_vasnprintf (NULL, &length, format, args);
107 size_t written = fwrite (result, 1, length, stream);
109 if (written == length)
111 if (length > INT_MAX)
123 libintl_fprintf (FILE *stream, const char *format, ...)
128 va_start (args, format);
129 retval = libintl_vfprintf (stream, format, args);
136 libintl_vprintf (const char *format, va_list args)
138 return libintl_vfprintf (stdout, format, args);
143 libintl_printf (const char *format, ...)
148 va_start (args, format);
149 retval = libintl_vprintf (format, args);
156 libintl_vsprintf (char *resultbuf, const char *format, va_list args)
158 if (strchr (format, '$') == NULL)
159 return vsprintf (resultbuf, format, args);
162 size_t length = (size_t) ~0 / (4 * sizeof (char));
163 char *result = libintl_vasnprintf (resultbuf, &length, format, args);
164 if (result != resultbuf)
169 if (length > INT_MAX)
181 libintl_sprintf (char *resultbuf, const char *format, ...)
186 va_start (args, format);
187 retval = libintl_vsprintf (resultbuf, format, args);
194 # if HAVE_DECL__SNPRINTF
195 /* Windows. The mingw function vsnprintf() has fewer bugs than the MSVCRT
196 function _vsnprintf(), so prefer that. */
197 # if defined __MINGW32__
198 # define system_vsnprintf vsnprintf
200 # define system_vsnprintf _vsnprintf
204 # define system_vsnprintf vsnprintf
209 libintl_vsnprintf (char *resultbuf, size_t length, const char *format, va_list args)
211 if (strchr (format, '$') == NULL)
212 return system_vsnprintf (resultbuf, length, format, args);
215 size_t maxlength = length;
216 char *result = libintl_vasnprintf (resultbuf, &length, format, args);
219 if (result != resultbuf)
223 size_t pruned_length =
224 (length < maxlength ? length : maxlength - 1);
225 memcpy (resultbuf, result, pruned_length);
226 resultbuf[pruned_length] = '\0';
230 if (length > INT_MAX)
242 libintl_snprintf (char *resultbuf, size_t length, const char *format, ...)
247 va_start (args, format);
248 retval = libintl_vsnprintf (resultbuf, length, format, args);
259 libintl_vasprintf (char **resultp, const char *format, va_list args)
262 char *result = libintl_vasnprintf (NULL, &length, format, args);
265 if (length > INT_MAX)
277 libintl_asprintf (char **resultp, const char *format, ...)
282 va_start (args, format);
283 retval = libintl_vasprintf (resultp, format, args);
294 #define WIDE_CHAR_VERSION 1
296 #include "wprintf-parse.h"
297 /* Define auxiliary functions declared in "wprintf-parse.h". */
298 #define CHAR_T wchar_t
299 #define DIRECTIVE wchar_t_directive
300 #define DIRECTIVES wchar_t_directives
301 #define PRINTF_PARSE wprintf_parse
302 #include "printf-parse.c"
304 /* Define functions declared in "vasnprintf.h". */
305 #define vasnwprintf libintl_vasnwprintf
306 #include "vasnprintf.c"
307 #if 0 /* not needed */
308 #define asnwprintf libintl_asnwprintf
309 #include "asnprintf.c"
312 # if HAVE_DECL__SNWPRINTF
313 /* Windows. The function vswprintf() has a different signature than
314 on Unix; we use the function _vsnwprintf() instead. */
315 # define system_vswprintf _vsnwprintf
318 # define system_vswprintf vswprintf
323 libintl_vfwprintf (FILE *stream, const wchar_t *format, va_list args)
325 if (wcschr (format, '$') == NULL)
326 return vfwprintf (stream, format, args);
330 wchar_t *result = libintl_vasnwprintf (NULL, &length, format, args);
335 for (i = 0; i < length; i++)
336 if (fputwc (result[i], stream) == WEOF)
341 if (length > INT_MAX)
353 libintl_fwprintf (FILE *stream, const wchar_t *format, ...)
358 va_start (args, format);
359 retval = libintl_vfwprintf (stream, format, args);
366 libintl_vwprintf (const wchar_t *format, va_list args)
368 return libintl_vfwprintf (stdout, format, args);
373 libintl_wprintf (const wchar_t *format, ...)
378 va_start (args, format);
379 retval = libintl_vwprintf (format, args);
386 libintl_vswprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, va_list args)
388 if (wcschr (format, '$') == NULL)
389 return system_vswprintf (resultbuf, length, format, args);
392 size_t maxlength = length;
393 wchar_t *result = libintl_vasnwprintf (resultbuf, &length, format, args);
396 if (result != resultbuf)
400 size_t pruned_length =
401 (length < maxlength ? length : maxlength - 1);
402 memcpy (resultbuf, result, pruned_length * sizeof (wchar_t));
403 resultbuf[pruned_length] = 0;
406 /* Unlike vsnprintf, which has to return the number of character that
407 would have been produced if the resultbuf had been sufficiently
408 large, the vswprintf function has to return a negative value if
409 the resultbuf was not sufficiently large. */
410 if (length >= maxlength)
413 if (length > INT_MAX)
425 libintl_swprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, ...)
430 va_start (args, format);
431 retval = libintl_vswprintf (resultbuf, length, format, args);