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