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