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