diff options
Diffstat (limited to 'winsup/mingw/mingwex/gdtoa/g__fmt.c')
-rwxr-xr-x | winsup/mingw/mingwex/gdtoa/g__fmt.c | 87 |
1 files changed, 65 insertions, 22 deletions
diff --git a/winsup/mingw/mingwex/gdtoa/g__fmt.c b/winsup/mingw/mingwex/gdtoa/g__fmt.c index e40d4bb..49bd95a 100755 --- a/winsup/mingw/mingwex/gdtoa/g__fmt.c +++ b/winsup/mingw/mingwex/gdtoa/g__fmt.c @@ -35,65 +35,108 @@ THIS SOFTWARE. #include "locale.h" #endif - char * -#ifdef KR_headers -__g__fmt(b, s, se, decpt, sign) char *b; char *s; char *se; int decpt; ULong sign; -#else -__g__fmt(char *b, char *s, char *se, int decpt, ULong sign) -#endif +char *__g__fmt (char *b, char *s, char *se, int decpt, ULong sign, size_t blen) { int i, j, k; - char *s0 = s; + char *be, *s0; + size_t len; #ifdef USE_LOCALE - char decimalpoint = *localeconv()->decimal_point; +#ifdef NO_LOCALE_CACHE + char *decimalpoint = localeconv()->decimal_point; + size_t dlen = strlen(decimalpoint); #else -#define decimalpoint '.' + char *decimalpoint; + static char *decimalpoint_cache; + static size_t dlen; + if (!(s0 = decimalpoint_cache)) { + s0 = localeconv()->decimal_point; + dlen = strlen(s0); + if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { + strcpy(decimalpoint_cache, s0); + s0 = decimalpoint_cache; + } + } + decimalpoint = s0; #endif +#else +#define dlen 0 +#endif + s0 = s; + len = (se-s) + dlen + 6; /* 6 = sign + e+dd + trailing null */ + if (blen < len) + goto ret0; + be = b + blen - 1; if (sign) *b++ = '-'; if (decpt <= -4 || decpt > se - s + 5) { *b++ = *s++; if (*s) { - *b++ = decimalpoint; +#ifdef USE_LOCALE + while((*b = *decimalpoint++)) + ++b; +#else + *b++ = '.'; +#endif while((*b = *s++) !=0) b++; - } + } *b++ = 'e'; /* sprintf(b, "%+.2d", decpt - 1); */ if (--decpt < 0) { *b++ = '-'; decpt = -decpt; - } + } else *b++ = '+'; for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){} for(;;) { i = decpt / k; + if (b >= be) + goto ret0; *b++ = i + '0'; if (--j <= 0) break; decpt -= i*k; decpt *= 10; - } - *b = 0; } + *b = 0; + } else if (decpt <= 0) { - *b++ = decimalpoint; +#ifdef USE_LOCALE + while((*b = *decimalpoint++)) + ++b; +#else + *b++ = '.'; +#endif + if (be < b - decpt + (se - s)) + goto ret0; for(; decpt < 0; decpt++) *b++ = '0'; - while((*b = *s++) !=0) + while((*b = *s++) != 0) b++; - } + } else { - while((*b = *s++) !=0) { + while((*b = *s++) != 0) { b++; - if (--decpt == 0 && *s) - *b++ = decimalpoint; + if (--decpt == 0 && *s) { +#ifdef USE_LOCALE + while((*b = *decimalpoint++)) + ++b; +#else + *b++ = '.'; +#endif } + } + if (b + decpt > be) { + ret0: + b = 0; + goto ret; + } for(; decpt > 0; decpt--) *b++ = '0'; *b = 0; - } + } + ret: __freedtoa(s0); return b; - } +} |