Piotr Caban : msvcrt: Don' t duplicate floating-point number parsing code in MSVCRT__atoflt_l.
Alexandre Julliard
julliard at winehq.org
Mon Dec 17 13:58:23 CST 2012
Module: wine
Branch: master
Commit: 38bf8ac44bbc9d9f9cb121158e51bfe7ca02dd2b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=38bf8ac44bbc9d9f9cb121158e51bfe7ca02dd2b
Author: Piotr Caban <piotr at codeweavers.com>
Date: Mon Dec 17 15:18:54 2012 +0100
msvcrt: Don't duplicate floating-point number parsing code in MSVCRT__atoflt_l.
---
dlls/msvcrt/string.c | 137 +++++++++++---------------------------------------
1 files changed, 29 insertions(+), 108 deletions(-)
diff --git a/dlls/msvcrt/string.c b/dlls/msvcrt/string.c
index 2748c8d..90518bc 100644
--- a/dlls/msvcrt/string.c
+++ b/dlls/msvcrt/string.c
@@ -280,10 +280,7 @@ void CDECL MSVCRT__swab(char* src, char* dst, int len)
}
}
-/*********************************************************************
- * strtod_l (MSVCRT.@)
- */
-double CDECL MSVCRT_strtod_l( const char *str, char **end, MSVCRT__locale_t locale)
+static double strtod_helper(const char *str, char **end, MSVCRT__locale_t locale, int *err)
{
MSVCRT_pthreadlocinfo locinfo;
unsigned __int64 d=0, hlp;
@@ -294,7 +291,10 @@ double CDECL MSVCRT_strtod_l( const char *str, char **end, MSVCRT__locale_t loca
long double lret=1, expcnt = 10;
BOOL found_digit = FALSE, negexp;
- if (!MSVCRT_CHECK_PMT(str != NULL)) return 0;
+ if(err)
+ *err = 0;
+ else
+ if(!MSVCRT_CHECK_PMT(str != NULL)) return 0;
if(!locale)
locinfo = get_locinfo();
@@ -392,8 +392,12 @@ double CDECL MSVCRT_strtod_l( const char *str, char **end, MSVCRT__locale_t loca
_control87(fpcontrol, 0xffffffff);
- if((d && ret==0.0) || isinf(ret))
- *MSVCRT__errno() = MSVCRT_ERANGE;
+ if((d && ret==0.0) || isinf(ret)) {
+ if(err)
+ *err = MSVCRT_ERANGE;
+ else
+ *MSVCRT__errno() = MSVCRT_ERANGE;
+ }
if(end)
*end = (char*)p;
@@ -402,6 +406,14 @@ double CDECL MSVCRT_strtod_l( const char *str, char **end, MSVCRT__locale_t loca
}
/*********************************************************************
+ * strtod_l (MSVCRT.@)
+ */
+double CDECL MSVCRT_strtod_l(const char *str, char **end, MSVCRT__locale_t locale)
+{
+ return strtod_helper(str, end, locale, NULL);
+}
+
+/*********************************************************************
* strtod (MSVCRT.@)
*/
double CDECL MSVCRT_strtod( const char *str, char **end )
@@ -430,107 +442,16 @@ double CDECL MSVCRT__atof_l( const char *str, MSVCRT__locale_t locale)
*/
int CDECL MSVCRT__atoflt_l( MSVCRT__CRT_FLOAT *value, char *str, MSVCRT__locale_t locale)
{
- MSVCRT_pthreadlocinfo locinfo;
- unsigned __int64 d=0, hlp;
- unsigned fpcontrol;
- int exp=0, sign=1;
- const char *p;
- int ret=0;
- BOOL found_digit = FALSE;
-
- if(!locale)
- locinfo = get_locinfo();
- else
- locinfo = locale->locinfo;
-
- /* FIXME: use *_l functions */
- p = str;
- while(isspace(*p))
- p++;
-
- if(*p == '-') {
- sign = -1;
- p++;
- } else if(*p == '+')
- p++;
-
- while(isdigit(*p)) {
- found_digit = TRUE;
- hlp = d*10+*(p++)-'0';
- if(d>MSVCRT_UI64_MAX/10 || hlp<d) {
- exp++;
- break;
- } else
- d = hlp;
- }
- while(isdigit(*p)) {
- exp++;
- p++;
- }
-
- if(*p == *locinfo->lconv->decimal_point)
- p++;
-
- while(isdigit(*p)) {
- found_digit = TRUE;
- hlp = d*10+*(p++)-'0';
- if(d>MSVCRT_UI64_MAX/10 || hlp<d)
- break;
-
- d = hlp;
- exp--;
- }
- while(isdigit(*p))
- p++;
-
- if(!found_digit) {
- value->f = 0.0;
- return 0;
- }
-
- if(*p=='e' || *p=='E' || *p=='d' || *p=='D') {
- int e=0, s=1;
-
- p++;
- if(*p == '-') {
- s = -1;
- p++;
- } else if(*p == '+')
- p++;
-
- if(isdigit(*p)) {
- while(isdigit(*p)) {
- if(e>INT_MAX/10 || (e=e*10+*p-'0')<0)
- e = INT_MAX;
- p++;
- }
- e *= s;
-
- if(exp<0 && e<0 && exp+e>=0) exp = INT_MIN;
- else if(exp>0 && e>0 && exp+e<0) exp = INT_MAX;
- else exp += e;
- } else {
- if(*p=='-' || *p=='+')
- p--;
- p--;
- }
- }
-
- fpcontrol = _control87(0, 0);
- _control87(MSVCRT__EM_DENORMAL|MSVCRT__EM_INVALID|MSVCRT__EM_ZERODIVIDE
- |MSVCRT__EM_OVERFLOW|MSVCRT__EM_UNDERFLOW|MSVCRT__EM_INEXACT, 0xffffffff);
-
- if(exp>0)
- value->f = (double)sign*d*pow(10, exp);
- else
- value->f = (double)sign*d/pow(10, -exp);
-
- _control87(fpcontrol, 0xffffffff);
-
- if((d && value->f>-MSVCRT_FLT_MIN && value->f<MSVCRT_FLT_MIN) || isinf(value->f))
- ret = exp > 0 ? MSVCRT__OVERFLOW : MSVCRT__UNDERFLOW;
-
- return ret;
+ double d;
+ int err;
+
+ d = strtod_helper(str, NULL, locale, &err);
+ value->f = d;
+ if(isinf(value->f))
+ return MSVCRT__OVERFLOW;
+ if((d!=0 || err) && value->f>-MSVCRT_FLT_MIN && value->f<MSVCRT_FLT_MIN)
+ return MSVCRT__UNDERFLOW;
+ return 0;
}
/*********************************************************************
More information about the wine-cvs
mailing list