X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/865f97c868ce92518b1cf4f23e23bd1b16b7917c..7e9089a13ddf2e277b8c25877aef808174f9fffa:/src/xbt/snprintf.c diff --git a/src/xbt/snprintf.c b/src/xbt/snprintf.c index 5fbb4100ea..89df5fbaae 100644 --- a/src/xbt/snprintf.c +++ b/src/xbt/snprintf.c @@ -1,3 +1,8 @@ +/* Copyright (c) 2005-2010, 2012-2015. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ /* * snprintf.c - a portable implementation of snprintf @@ -113,76 +118,76 @@ * http://www.ijs.si/software/snprintf/ * * REVISION HISTORY - * 1999-04 V0.9 Mark Martinec - * - initial version, some modifications after comparing printf - * man pages for Digital Unix 4.0, Solaris 2.6 and HPUX 10, - * and checking how Perl handles sprintf (differently!); - * 1999-04-09 V1.0 Mark Martinec - * - added main test program, fixed remaining inconsistencies, - * added optional (long long int) support; - * 1999-04-12 V1.1 Mark Martinec - * - support the 'p' conversion (pointer to void); - * - if a string precision is specified - * make sure the string beyond the specified precision - * will not be referenced (e.g. by strlen); - * 1999-04-13 V1.2 Mark Martinec - * - support synonyms %D=%ld, %U=%lu, %O=%lo; - * - speed up the case of long format string with few conversions; - * 1999-06-30 V1.3 Mark Martinec - * - fixed runaway loop (eventually crashing when str_l wraps - * beyond 2^31) while copying format string without - * conversion specifiers to a buffer that is too short - * (thanks to Edwin Young for - * spotting the problem); - * - added macros PORTABLE_SNPRINTF_VERSION_(MAJOR|MINOR) - * to snprintf.h - * 2000-02-14 V2.0 (never released) Mark Martinec - * - relaxed license terms: The Artistic License now applies. - * You may still apply the GNU GENERAL PUBLIC LICENSE - * as was distributed with previous versions, if you prefer; - * - changed REVISION HISTORY dates to use ISO 8601 date format; - * - added vsnprintf (patch also independently proposed by - * Caolan McNamara 2000-05-04, and Keith M Willenson 2000-06-01) - * 2000-06-27 V2.1 Mark Martinec - * - removed POSIX check for str_m<1; value 0 for str_m is - * allowed by ISO C99 (and GNU C library 2.1) - (pointed out - * on 2000-05-04 by Caolan McNamara, caolan@ csn dot ul dot ie). - * Besides relaxed license this change in standards adherence - * is the main reason to bump up the major version number; - * - added nonstandard routines asnprintf, vasnprintf, asprintf, - * vasprintf that dynamically allocate storage for the - * resulting string; these routines are not compiled by default, - * see comments where NEED_V?ASN?PRINTF macros are defined; - * - autoconf contributed by Caolan McNamara - * 2000-10-06 V2.2 Mark Martinec - * - BUG FIX: the %c conversion used a temporary variable - * that was no longer in scope when referenced, - * possibly causing incorrect resulting character; - * - BUG FIX: make precision and minimal field width unsigned - * to handle huge values (2^31 <= n < 2^32) correctly; - * also be more careful in the use of signed/unsigned/size_t - * internal variables - probably more careful than many - * vendor implementations, but there may still be a case - * where huge values of str_m, precision or minimal field - * could cause incorrect behaviour; - * - use separate variables for signed/unsigned arguments, - * and for short/int, long, and long long argument lengths - * to avoid possible incompatibilities on certain - * computer architectures. Also use separate variable - * arg_sign to hold sign of a numeric argument, - * to make code more transparent; - * - some fiddling with zero padding and "0x" to make it - * Linux compatible; - * - systematically use macros fast_memcpy and fast_memset - * instead of case-by-case hand optimization; determine some - * breakeven string lengths for different architectures; - * - terminology change: 'format' -> 'conversion specifier', - * 'C9x' -> 'ISO/IEC 9899:1999 ("ISO C99")', - * 'alternative form' -> 'alternate form', - * 'data type modifier' -> 'length modifier'; - * - several comments rephrased and new ones added; - * - make compiler not complain about 'credits' defined but - * not used; + * 1999-04 V0.9 Mark Martinec + * - initial version, some modifications after comparing printf + * man pages for Digital Unix 4.0, Solaris 2.6 and HPUX 10, + * and checking how Perl handles sprintf (differently!); + * 1999-04-09 V1.0 Mark Martinec + * - added main test program, fixed remaining inconsistencies, + * added optional (long long int) support; + * 1999-04-12 V1.1 Mark Martinec + * - support the 'p' conversion (pointer to void); + * - if a string precision is specified + * make sure the string beyond the specified precision + * will not be referenced (e.g. by strlen); + * 1999-04-13 V1.2 Mark Martinec + * - support synonyms %D=%ld, %U=%lu, %O=%lo; + * - speed up the case of long format string with few conversions; + * 1999-06-30 V1.3 Mark Martinec + * - fixed runaway loop (eventually crashing when str_l wraps + * beyond 2^31) while copying format string without + * conversion specifiers to a buffer that is too short + * (thanks to Edwin Young for + * spotting the problem); + * - added macros PORTABLE_SNPRINTF_VERSION_(MAJOR|MINOR) + * to snprintf.h + * 2000-02-14 V2.0 (never released) Mark Martinec + * - relaxed license terms: The Artistic License now applies. + * You may still apply the GNU GENERAL PUBLIC LICENSE + * as was distributed with previous versions, if you prefer; + * - changed REVISION HISTORY dates to use ISO 8601 date format; + * - added vsnprintf (patch also independently proposed by + * Caolan McNamara 2000-05-04, and Keith M Willenson 2000-06-01) + * 2000-06-27 V2.1 Mark Martinec + * - removed POSIX check for str_m<1; value 0 for str_m is + * allowed by ISO C99 (and GNU C library 2.1) - (pointed out + * on 2000-05-04 by Caolan McNamara, caolan@ csn dot ul dot ie). + * Besides relaxed license this change in standards adherence + * is the main reason to bump up the major version number; + * - added nonstandard routines asnprintf, vasnprintf, asprintf, + * vasprintf that dynamically allocate storage for the + * resulting string; these routines are not compiled by default, + * see comments where NEED_V?ASN?PRINTF macros are defined; + * - autoconf contributed by Caolan McNamara + * 2000-10-06 V2.2 Mark Martinec + * - BUG FIX: the %c conversion used a temporary variable + * that was no longer in scope when referenced, + * possibly causing incorrect resulting character; + * - BUG FIX: make precision and minimal field width unsigned + * to handle huge values (2^31 <= n < 2^32) correctly; + * also be more careful in the use of signed/unsigned/size_t + * internal variables - probably more careful than many + * vendor implementations, but there may still be a case + * where huge values of str_m, precision or minimal field + * could cause incorrect behaviour; + * - use separate variables for signed/unsigned arguments, + * and for short/int, long, and long long argument lengths + * to avoid possible incompatibilities on certain + * computer architectures. Also use separate variable + * arg_sign to hold sign of a numeric argument, + * to make code more transparent; + * - some fiddling with zero padding and "0x" to make it + * Linux compatible; + * - systematically use macros fast_memcpy and fast_memset + * instead of case-by-case hand optimization; determine some + * breakeven string lengths for different architectures; + * - terminology change: 'format' -> 'conversion specifier', + * 'C9x' -> 'ISO/IEC 9899:1999 ("ISO C99")', + * 'alternative form' -> 'alternate form', + * 'data type modifier' -> 'length modifier'; + * - several comments rephrased and new ones added; + * - make compiler not complain about 'credits' defined but + * not used; */ @@ -316,7 +321,7 @@ #define LINUX_COMPATIBLE #endif -#include "portable.h" /* to get a working stdarg.h */ +#include "src/portable.h" /* to get a working stdarg.h */ #include #include @@ -357,25 +362,25 @@ #endif /* some other values of possible interest: */ - /* #define breakeven_point 8 *//* VAX 4000 - vaxc */ - /* #define breakeven_point 19 *//* VAX 4000 - gcc 2.7.0 */ + /* #define breakeven_point 8 *//* VAX 4000 - vaxc */ + /* #define breakeven_point 19 *//* VAX 4000 - gcc 2.7.0 */ #ifndef breakeven_point # define breakeven_point 6 /* some reasonable one-size-fits-all value */ #endif #define fast_memcpy(d,s,n) \ - { register size_t nn = (size_t)(n); \ + { size_t nn = (size_t)(n); \ if (nn >= breakeven_point) memcpy((d), (s), nn); \ else if (nn > 0) { /* proc call overhead is worth only for large strings*/\ - register char *dd; register const char *ss; \ + char *dd; const char *ss; \ for (ss=(s), dd=(d); nn>0; nn--) *dd++ = *ss++; } } #define fast_memset(d,c,n) \ - { register size_t nn = (size_t)(n); \ + { size_t nn = (size_t)(n); \ if (nn >= breakeven_point) memset((d), (int)(c), nn); \ else if (nn > 0) { /* proc call overhead is worth only for large strings*/\ - register char *dd; register const int cc=(int)(c); \ + char *dd; const int cc=(int)(c); \ for (dd=(d); nn>0; nn--) *dd++ = cc; } } /* prototypes */ @@ -417,22 +422,22 @@ int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap); int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args */ ...); #if !defined(NEED_SNPRINTF_ONLY) -int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap); +int portable_vsnprintf(char *str, size_t str_m, const char *fmt, + va_list ap); #endif #endif -/* declarations */ + /* FIXME: better place */ +#include "xbt/sysdep.h" -static char credits[] = "\n\ - @(#)snprintf.c, v2.2: Mark Martinec, \n\ - @(#)snprintf.c, v2.2: Copyright 1999, Mark Martinec. Frontier Artistic License applies.\n\ - @(#)snprintf.c, v2.2: http://www.ijs.si/software/snprintf/\n"; +/* declarations */ -static void __foo__(void) -{ - printf("%s", credits); - __foo__(); -} +/* + Old copyright + snprintf.c, v2.2: Mark Martinec, + snprintf.c, v2.2: Copyright 1999, Mark Martinec. Frontier Artistic License applies. + snprintf.c, v2.2: http://www.ijs.si/software/snprintf +*/ #if defined(NEED_ASPRINTF) int asprintf(char **ptr, const char *fmt, /*args */ ...) @@ -446,7 +451,7 @@ int asprintf(char **ptr, const char *fmt, /*args */ ...) str_l = portable_vsnprintf(NULL, (size_t) 0, fmt, ap); va_end(ap); assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ - *ptr = (char *) malloc(str_m = (size_t) str_l + 1); + *ptr = (char *) xbt_malloc(str_m = (size_t) str_l + 1); if (*ptr == NULL) { errno = ENOMEM; str_l = -1; @@ -475,7 +480,7 @@ int vasprintf(char **ptr, const char *fmt, va_list ap) va_end(ap2); } assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ - *ptr = (char *) malloc(str_m = (size_t) str_l + 1); + *ptr = (char *) xbt_malloc(str_m = (size_t) str_l + 1); if (*ptr == NULL) { errno = ENOMEM; str_l = -1; @@ -503,7 +508,7 @@ int asnprintf(char **ptr, size_t str_m, const char *fmt, /*args */ ...) /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */ if (str_m == 0) { /* not interested in resulting string, just return size */ } else { - *ptr = (char *) malloc(str_m); + *ptr = (char *) xbt_malloc(str_m); if (*ptr == NULL) { errno = ENOMEM; str_l = -1; @@ -537,7 +542,7 @@ int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap) /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */ if (str_m == 0) { /* not interested in resulting string, just return size */ } else { - *ptr = (char *) malloc(str_m); + *ptr = (char *) xbt_malloc(str_m); if (*ptr == NULL) { errno = ENOMEM; str_l = -1; @@ -557,7 +562,8 @@ int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap) #if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) #if !defined(NEED_SNPRINTF_ONLY) -int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args */ ...) +int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args */ + ...) { va_list ap; int str_l; @@ -570,10 +576,12 @@ int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args */ ...) #endif #if defined(NEED_SNPRINTF_ONLY) -int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args */ ...) +int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args */ + ...) { #else -int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) +int portable_vsnprintf(char *str, size_t str_m, const char *fmt, + va_list ap) { #endif @@ -937,7 +945,7 @@ int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) /* Actually it uses 0x prefix even for a zero value. */ && arg_sign != 0 #endif - ) { + ) { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = 'x'; } @@ -953,7 +961,7 @@ int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) * converting a zero value with a precision of zero is a null string. * Actually HP returns all zeroes, and Linux returns "(nil)". */ #endif - ) { + ) { /* converted to null string */ /* When zero value is formatted with an explicit precision 0, the resulting formatted string is empty (d, i, u, o, x, X, p). */ @@ -1027,7 +1035,7 @@ int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) && !(zero_padding_insertion_ind < str_arg_l && tmp[zero_padding_insertion_ind] == '0') #endif - ) { /* assure leading zero for alternate-form octal numbers */ + ) { /* assure leading zero for alternate-form octal numbers */ if (!precision_specified || precision < num_of_digits + 1) { /* precision is increased to force the first character to be zero, except if a zero value is formatted with an explicit precision @@ -1161,19 +1169,26 @@ int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) #endif - /* FIXME: better place */ -#include "xbt/sysdep.h" +char *bvprintf(const char *fmt, va_list ap) +{ + char *res; + + if (vasprintf(&res, fmt, ap) < 0) { + /* Do not want to use xbt_die() here, as it uses the logging + * infrastucture and may fail to allocate memory too. */ + fprintf(stderr, "bprintf: vasprintf failed. Aborting.\n"); + xbt_abort(); + } + return res; +} char *bprintf(const char *fmt, ...) { va_list ap; char *res; - int len; va_start(ap, fmt); - - len = vasprintf(&res, fmt, ap); - + res = bvprintf(fmt, ap); va_end(ap); return res; }