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 (at) 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 39 char *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 78 DLL_EXPORTED 79 int 80 libintl_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 99 DLL_EXPORTED 100 int 101 libintl_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 112 DLL_EXPORTED 113 int 114 libintl_vprintf (const char *format, va_list args) 115 { 116 return libintl_vfprintf (stdout, format, args); 117 } 118 119 DLL_EXPORTED 120 int 121 libintl_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 132 DLL_EXPORTED 133 int 134 libintl_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 152 DLL_EXPORTED 153 int 154 libintl_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 175 DLL_EXPORTED 176 int 177 libintl_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 202 DLL_EXPORTED 203 int 204 libintl_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 219 DLL_EXPORTED 220 int 221 libintl_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 231 DLL_EXPORTED 232 int 233 libintl_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 271 DLL_EXPORTED 272 int 273 libintl_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 296 DLL_EXPORTED 297 int 298 libintl_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 309 DLL_EXPORTED 310 int 311 libintl_vwprintf (const wchar_t *format, va_list args) 312 { 313 return libintl_vfwprintf (stdout, format, args); 314 } 315 316 DLL_EXPORTED 317 int 318 libintl_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 329 DLL_EXPORTED 330 int 331 libintl_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 356 DLL_EXPORTED 357 int 358 libintl_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