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