summaryrefslogtreecommitdiffstats
path: root/contrib/gdtoa/g__fmt.c
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2009-01-28 04:36:34 +0000
committerdas <das@FreeBSD.org>2009-01-28 04:36:34 +0000
commit1dd1bae7b6975b8f90638d416af36744406345b4 (patch)
treec4d28a7b5d5d1902de89c3a33988ed7f5638277b /contrib/gdtoa/g__fmt.c
parent0ae48d48ab38ccf64f5cda7e2bc3a30aa4b7c4c2 (diff)
parent5606fb59f1820207cf2c2c8709586e36f114a8f7 (diff)
downloadFreeBSD-src-1dd1bae7b6975b8f90638d416af36744406345b4.zip
FreeBSD-src-1dd1bae7b6975b8f90638d416af36744406345b4.tar.gz
Vendor import of gdtoa 20081205.
Diffstat (limited to 'contrib/gdtoa/g__fmt.c')
-rw-r--r--contrib/gdtoa/g__fmt.c70
1 files changed, 59 insertions, 11 deletions
diff --git a/contrib/gdtoa/g__fmt.c b/contrib/gdtoa/g__fmt.c
index 021ecfb..fbccb7d 100644
--- a/contrib/gdtoa/g__fmt.c
+++ b/contrib/gdtoa/g__fmt.c
@@ -37,24 +37,51 @@ THIS SOFTWARE.
char *
#ifdef KR_headers
-g__fmt(b, s, se, decpt, sign) char *b; char *s; char *se; int decpt; ULong sign;
+g__fmt(b, s, se, decpt, sign, blen) char *b; char *s; char *se; int decpt; ULong sign; size_t blen;
#else
-g__fmt(char *b, char *s, char *se, int decpt, ULong sign)
+g__fmt(char *b, char *s, char *se, int decpt, ULong sign, size_t blen)
#endif
{
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++;
}
@@ -69,6 +96,8 @@ g__fmt(char *b, char *s, char *se, int decpt, ULong sign)
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;
@@ -78,22 +107,41 @@ g__fmt(char *b, char *s, char *se, int decpt, ULong sign)
*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;
}
OpenPOWER on IntegriCloud