diff options
Diffstat (limited to 'misc/efgcvt.c')
-rw-r--r-- | misc/efgcvt.c | 75 |
1 files changed, 65 insertions, 10 deletions
diff --git a/misc/efgcvt.c b/misc/efgcvt.c index 24d63176d0..8c92766c63 100644 --- a/misc/efgcvt.c +++ b/misc/efgcvt.c @@ -20,28 +20,60 @@ #include <stdio.h> #include <stdlib.h> #include <float.h> +#include <bits/libc-lock.h> #ifndef FLOAT_TYPE -#define FLOAT_TYPE double -#define FUNC_PREFIX -#define FLOAT_FMT_FLAG -#define MAXDIG (DBL_DIG + DBL_MAX_10_EXP) +# define FLOAT_TYPE double +# define FUNC_PREFIX +# define FLOAT_FMT_FLAG +/* Actually we have to write (DBL_DIG + log10 (DBL_MAX_10_EXP)) but we + don't have log10 available in the preprocessor. */ +# define MAXDIG (DBL_DIG + 3) #endif #define APPEND(a, b) APPEND2 (a, b) #define APPEND2(a, b) a##b +#define FCVT_BUFFER APPEND (FUNC_PREFIX, fcvt_buffer) +#define ECVT_BUFFER APPEND (FUNC_PREFIX, ecvt_buffer) + + +static char *FCVT_BUFFER; +static char *ECVT_BUFFER; + + +static void +APPEND (FUNC_PREFIX, fcvt_allocate) (void) +{ + FCVT_BUFFER = (char *) malloc (MAXDIG); +} + char * APPEND (FUNC_PREFIX, fcvt) (value, ndigit, decpt, sign) FLOAT_TYPE value; int ndigit, *decpt, *sign; { - static char buf[MAXDIG]; + __libc_once_define (static, once); + __libc_once (once, APPEND (FUNC_PREFIX, fcvt_allocate)); - (void) fcvt_r (value, ndigit, decpt, sign, buf, sizeof buf); + if (FCVT_BUFFER == NULL) + /* If no core is available we don't have a chance to run the + program successfully and so returning NULL is an acceptable + result. */ + return NULL; - return buf; + (void) APPEND (FUNC_PREFIX, fcvt_r) (value, ndigit, decpt, sign, + FCVT_BUFFER, MAXDIG); + + return FCVT_BUFFER; +} + + +static void +APPEND (FUNC_PREFIX, ecvt_allocate) (void) +{ + ECVT_BUFFER = (char *) malloc (MAXDIG); } char * @@ -49,11 +81,19 @@ APPEND (FUNC_PREFIX, ecvt) (value, ndigit, decpt, sign) FLOAT_TYPE value; int ndigit, *decpt, *sign; { - static char buf[MAXDIG]; + __libc_once_define (static, once); + __libc_once (once, APPEND (FUNC_PREFIX, ecvt_allocate)); - (void) ecvt_r (value, ndigit, decpt, sign, buf, sizeof buf); + if (ECVT_BUFFER == NULL) + /* If no core is available we don't have a chance to run the + program successfully and so returning NULL is an acceptable + result. */ + return NULL; - return buf; + (void) APPEND (FUNC_PREFIX, ecvt_r) (value, ndigit, decpt, sign, + ECVT_BUFFER, MAXDIG); + + return ECVT_BUFFER; } char * @@ -65,3 +105,18 @@ APPEND (FUNC_PREFIX, gcvt) (value, ndigit, buf) sprintf (buf, "%.*" FLOAT_FMT_FLAG "g", ndigit, value); return buf; } + + +/* Make sure the memory is freed if the programs ends while in + memory-debugging mode and something actually was allocated. */ +static void +__attribute__ ((unused)) +free_mem (void) +{ + if (FCVT_BUFFER != NULL) + free (FCVT_BUFFER); + if (ECVT_BUFFER != NULL) + free (ECVT_BUFFER); +} + +text_set_element (__libc_subfreeres, free_mem); |