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