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