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
41char *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
80DLL_EXPORTED
81int
82libintl_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
101DLL_EXPORTED
102int
103libintl_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
114DLL_EXPORTED
115int
116libintl_vprintf (const char *format, va_list args)
117{
118  return libintl_vfprintf (stdout, format, args);
119}
120
121DLL_EXPORTED
122int
123libintl_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
134DLL_EXPORTED
135int
136libintl_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
154DLL_EXPORTED
155int
156libintl_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
177DLL_EXPORTED
178int
179libintl_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
204DLL_EXPORTED
205int
206libintl_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
221DLL_EXPORTED
222int
223libintl_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
233DLL_EXPORTED
234int
235libintl_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
273DLL_EXPORTED
274int
275libintl_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
298DLL_EXPORTED
299int
300libintl_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
311DLL_EXPORTED
312int
313libintl_vwprintf (const wchar_t *format, va_list args)
314{
315  return libintl_vfwprintf (stdout, format, args);
316}
317
318DLL_EXPORTED
319int
320libintl_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
331DLL_EXPORTED
332int
333libintl_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
358DLL_EXPORTED
359int
360libintl_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