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