152 |
* |
* |
153 |
* If HAVE_SNPRINTF is defined this module will not produce code for |
* If HAVE_SNPRINTF is defined this module will not produce code for |
154 |
* snprintf and vsnprintf, unless PREFER_PORTABLE_SNPRINTF is defined as well, |
* snprintf and vsnprintf, unless PREFER_PORTABLE_SNPRINTF is defined as well, |
155 |
* causing this portable version of snprintf to be called portable_snprintf |
* causing this portable version of snprintf to be called fl_portable_snprintf |
156 |
* (and portable_vsnprintf). |
* (and fl_portable_vsnprintf). |
157 |
*/ |
*/ |
158 |
/* #define HAVE_SNPRINTF */ |
/* #define HAVE_SNPRINTF */ |
159 |
|
|
160 |
/* Define PREFER_PORTABLE_SNPRINTF if your system does have snprintf and |
/* Define PREFER_PORTABLE_SNPRINTF if your system does have snprintf and |
161 |
* vsnprintf but you would prefer to use the portable routine(s) instead. |
* vsnprintf but you would prefer to use the portable routine(s) instead. |
162 |
* In this case the portable routine is declared as portable_snprintf |
* In this case the portable routine is declared as fl_portable_snprintf |
163 |
* (and portable_vsnprintf) and a macro 'snprintf' (and 'vsnprintf') |
* (and fl_portable_vsnprintf) and a macro 'snprintf' (and 'vsnprintf') |
164 |
* is defined to expand to 'portable_v?snprintf' - see file snprintf.h . |
* is defined to expand to 'portable_v?snprintf' - see file snprintf.h . |
165 |
* Defining this macro is only useful if HAVE_SNPRINTF is also defined, |
* Defining this macro is only useful if HAVE_SNPRINTF is also defined, |
166 |
* but does does no harm if defined nevertheless. |
* but does does no harm if defined nevertheless. |
189 |
/* Define NEED_V?ASN?PRINTF macros if you need library extension |
/* Define NEED_V?ASN?PRINTF macros if you need library extension |
190 |
* routines asprintf, vasprintf, asnprintf, vasnprintf respectively, |
* routines asprintf, vasprintf, asnprintf, vasnprintf respectively, |
191 |
* and your system library does not provide them. They are all small |
* and your system library does not provide them. They are all small |
192 |
* wrapper routines around portable_vsnprintf. Defining any of the four |
* wrapper routines around fl_portable_vsnprintf. Defining any of the four |
193 |
* NEED_V?ASN?PRINTF macros automatically turns off NEED_SNPRINTF_ONLY |
* NEED_V?ASN?PRINTF macros automatically turns off NEED_SNPRINTF_ONLY |
194 |
* and turns on PREFER_PORTABLE_SNPRINTF. |
* and turns on PREFER_PORTABLE_SNPRINTF. |
195 |
* |
* |
309 |
#define va_copy(ap2,ap) ap2 = ap |
#define va_copy(ap2,ap) ap2 = ap |
310 |
#endif |
#endif |
311 |
|
|
312 |
|
#if 0 |
313 |
#if defined(HAVE_SNPRINTF) |
#if defined(HAVE_SNPRINTF) |
314 |
/* declare our portable snprintf routine under name portable_snprintf */ |
/* declare our portable snprintf routine under name fl_portable_snprintf */ |
315 |
/* declare our portable vsnprintf routine under name portable_vsnprintf */ |
/* declare our portable vsnprintf routine under name fl_portable_vsnprintf */ |
316 |
#else |
#else |
317 |
/* declare our portable routines under names snprintf and vsnprintf */ |
/* declare our portable routines under names snprintf and vsnprintf */ |
318 |
#define portable_snprintf snprintf |
#define fl_portable_snprintf snprintf |
319 |
#if !defined(NEED_SNPRINTF_ONLY) |
#if !defined(NEED_SNPRINTF_ONLY) |
320 |
#define portable_vsnprintf vsnprintf |
#define fl_portable_vsnprintf vsnprintf |
321 |
#endif |
#endif |
322 |
#endif |
#endif |
323 |
|
#endif /* 0 */ |
324 |
|
|
325 |
#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) |
#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) |
326 |
static int |
int fl_portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...); |
|
portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...); |
|
327 |
#if !defined(NEED_SNPRINTF_ONLY) |
#if !defined(NEED_SNPRINTF_ONLY) |
328 |
static int |
int fl_portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap); |
|
portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap); |
|
329 |
#endif |
#endif |
330 |
#endif |
#endif |
331 |
|
|
346 |
|
|
347 |
*ptr = NULL; |
*ptr = NULL; |
348 |
va_start(ap, fmt); /* measure the required size */ |
va_start(ap, fmt); /* measure the required size */ |
349 |
str_l = portable_vsnprintf(NULL, (size_t) 0, fmt, ap); |
str_l = fl_portable_vsnprintf(NULL, (size_t) 0, fmt, ap); |
350 |
va_end(ap); |
va_end(ap); |
351 |
assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ |
assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ |
352 |
*ptr = (char *) malloc(str_m = (size_t)str_l + 1); |
*ptr = (char *) malloc(str_m = (size_t)str_l + 1); |
354 |
else { |
else { |
355 |
int str_l2; |
int str_l2; |
356 |
va_start(ap, fmt); |
va_start(ap, fmt); |
357 |
str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); |
str_l2 = fl_portable_vsnprintf(*ptr, str_m, fmt, ap); |
358 |
va_end(ap); |
va_end(ap); |
359 |
assert(str_l2 == str_l); |
assert(str_l2 == str_l); |
360 |
} |
} |
371 |
{ va_list ap2; |
{ va_list ap2; |
372 |
va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ |
va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ |
373 |
/* measure the required size: */ |
/* measure the required size: */ |
374 |
str_l = portable_vsnprintf(NULL, (size_t) 0, fmt, ap2); |
str_l = fl_portable_vsnprintf(NULL, (size_t) 0, fmt, ap2); |
375 |
va_end(ap2); |
va_end(ap2); |
376 |
} |
} |
377 |
assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ |
assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ |
378 |
*ptr = (char *) malloc(str_m = (size_t)str_l + 1); |
*ptr = (char *) malloc(str_m = (size_t)str_l + 1); |
379 |
if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } |
if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } |
380 |
else { |
else { |
381 |
int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); |
int str_l2 = fl_portable_vsnprintf(*ptr, str_m, fmt, ap); |
382 |
assert(str_l2 == str_l); |
assert(str_l2 == str_l); |
383 |
} |
} |
384 |
return str_l; |
return str_l; |
392 |
|
|
393 |
*ptr = NULL; |
*ptr = NULL; |
394 |
va_start(ap, fmt); /* measure the required size */ |
va_start(ap, fmt); /* measure the required size */ |
395 |
str_l = portable_vsnprintf(NULL, (size_t) 0, fmt, ap); |
str_l = fl_portable_vsnprintf(NULL, (size_t) 0, fmt, ap); |
396 |
va_end(ap); |
va_end(ap); |
397 |
assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ |
assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ |
398 |
if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */ |
if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */ |
404 |
else { |
else { |
405 |
int str_l2; |
int str_l2; |
406 |
va_start(ap, fmt); |
va_start(ap, fmt); |
407 |
str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); |
str_l2 = fl_portable_vsnprintf(*ptr, str_m, fmt, ap); |
408 |
va_end(ap); |
va_end(ap); |
409 |
assert(str_l2 == str_l); |
assert(str_l2 == str_l); |
410 |
} |
} |
421 |
{ va_list ap2; |
{ va_list ap2; |
422 |
va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ |
va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ |
423 |
/* measure the required size: */ |
/* measure the required size: */ |
424 |
str_l = portable_vsnprintf(NULL, (size_t) 0, fmt, ap2); |
str_l = fl_portable_vsnprintf(NULL, (size_t) 0, fmt, ap2); |
425 |
va_end(ap2); |
va_end(ap2); |
426 |
} |
} |
427 |
assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ |
assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ |
432 |
*ptr = (char *) malloc(str_m); |
*ptr = (char *) malloc(str_m); |
433 |
if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } |
if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } |
434 |
else { |
else { |
435 |
int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); |
int str_l2 = fl_portable_vsnprintf(*ptr, str_m, fmt, ap); |
436 |
assert(str_l2 == str_l); |
assert(str_l2 == str_l); |
437 |
} |
} |
438 |
} |
} |
447 |
#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) |
#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) |
448 |
|
|
449 |
#if !defined(NEED_SNPRINTF_ONLY) |
#if !defined(NEED_SNPRINTF_ONLY) |
450 |
static int |
int fl_portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { |
|
portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { |
|
451 |
va_list ap; |
va_list ap; |
452 |
int str_l; |
int str_l; |
453 |
|
|
454 |
va_start(ap, fmt); |
va_start(ap, fmt); |
455 |
str_l = portable_vsnprintf(str, str_m, fmt, ap); |
str_l = fl_portable_vsnprintf(str, str_m, fmt, ap); |
456 |
va_end(ap); |
va_end(ap); |
457 |
return str_l; |
return str_l; |
458 |
} |
} |
459 |
#endif |
#endif |
460 |
|
|
461 |
#if defined(NEED_SNPRINTF_ONLY) |
#if defined(NEED_SNPRINTF_ONLY) |
462 |
static int |
int fl_portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { |
|
portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { |
|
463 |
#else |
#else |
464 |
static int |
int fl_portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) { |
|
portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) { |
|
465 |
#endif |
#endif |
466 |
|
|
467 |
#if defined(NEED_SNPRINTF_ONLY) |
#if defined(NEED_SNPRINTF_ONLY) |
843 |
written to the buffer if it were large enough */ |
written to the buffer if it were large enough */ |
844 |
} |
} |
845 |
#endif |
#endif |
|
|
|
|
/* added by Angus Leeming, the xforms project */ |
|
|
#if defined(HAVE_SNPRINTF) |
|
|
#define portable_snprintf snprintf |
|
|
#define portable_vsnprintf vsnprintf |
|
|
#endif |
|
|
|
|
|
int fl_snprintf(char *str, size_t str_m, const char *fmt, ...) |
|
|
{ |
|
|
int result; |
|
|
va_list args; |
|
|
va_start(args, fmt); |
|
|
result = portable_vsnprintf(str, str_m, fmt, args); |
|
|
va_end(args); |
|
|
return result; |
|
|
} |
|
|
|
|
|
|
|
|
int fl_vsnprintf(char *str, size_t str_m, const char *fmt, va_list args) |
|
|
{ |
|
|
return portable_vsnprintf(str, str_m, fmt, args); |
|
|
} |
|