Erich E. Hoover : ntdll: Drop support for floating point numbers in sscanf.

Alexandre Julliard julliard at winehq.org
Mon Dec 23 17:42:11 CST 2019


Module: wine
Branch: master
Commit: 94675cd8e38496c63dc033e015783c589d764193
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=94675cd8e38496c63dc033e015783c589d764193

Author: Erich E. Hoover <erich.e.hoover at gmail.com>
Date:   Sat Dec 21 17:53:57 2019 -0700

ntdll: Drop support for floating point numbers in sscanf.

Takes care of one more use of "long double".

Signed-off-by: Erich E. Hoover <erich.e.hoover at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/string.c       | 140 ----------------------------------------------
 dlls/ntdll/tests/string.c |  47 ++++++++++++++++
 2 files changed, 47 insertions(+), 140 deletions(-)

diff --git a/dlls/ntdll/string.c b/dlls/ntdll/string.c
index 1d6af8558c..709f0ebdbd 100644
--- a/dlls/ntdll/string.c
+++ b/dlls/ntdll/string.c
@@ -848,7 +848,6 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap)
             int base;
             int h_prefix = 0;
             BOOLEAN l_prefix = FALSE;
-            BOOLEAN L_prefix = FALSE;
             BOOLEAN w_prefix = FALSE;
             BOOLEAN I64_prefix = FALSE;
             BOOLEAN prefix_finished = FALSE;
@@ -881,7 +880,6 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap)
                     l_prefix = TRUE;
                     break;
                 case 'w': w_prefix = TRUE; break;
-                case 'L': L_prefix = TRUE; break;
                 case 'I':
                     if (*(format + 1) == '6' &&
                         *(format + 2) == '4')
@@ -990,144 +988,6 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap)
                     }
                 }
                 break;
-            case 'e':
-            case 'E':
-            case 'f':
-            case 'g':
-            case 'G':
-                { /* read a float */
-                    long double cur = 1, expcnt = 10;
-                    ULONGLONG d, hlp;
-                    int exp = 0;
-                    BOOLEAN negative = FALSE;
-                    /*unsigned fpcontrol;*/
-                    BOOLEAN negexp;
-
-                    /* skip initial whitespace */
-                    while (nch != '\0' && isspace( nch ))
-                        nch = (consumed++, *str++);
-
-                    /* get sign */
-                    if (nch == '-' || nch == '+')
-                    {
-                        negative = (nch == '-');
-                        if (width > 0) width--;
-                        if (width == 0) break;
-                        nch = (consumed++, *str++);
-                    }
-
-                    /* get first digit */
-                    if ('.' != nch)
-                    {
-                        if (!isdigit( nch )) break;
-                        d = nch - '0';
-                        nch = (consumed++, *str++);
-                        if (width > 0) width--;
-                        /* read until no more digits */
-                        while (width != 0 && nch != '\0' && isdigit( nch ))
-                        {
-                            hlp = d * 10 + nch - '0';
-                            nch = (consumed++, *str++);
-                            if (width > 0) width--;
-                            if(d > (ULONGLONG)-1/10 || hlp < d)
-                            {
-                                exp++;
-                                break;
-                            }
-                            else
-                                d = hlp;
-                        }
-                        while (width != 0 && nch != '\0' && isdigit( nch ))
-                        {
-                            exp++;
-                            nch = (consumed++, *str++);
-                            if (width > 0) width--;
-                        }
-                    }
-                    else
-                        d = 0; /* Fix: .8 -> 0.8 */
-
-                    /* handle decimals */
-                    if (width != 0 && nch == '.')
-                    {
-                        nch = (consumed++, *str++);
-                        if (width > 0) width--;
-
-                        while (width != 0 && nch != '\0' && isdigit( nch ))
-                        {
-                            hlp = d * 10 + nch - '0';
-                            nch = (consumed++, *str++);
-                            if (width > 0) width--;
-                            if(d > (ULONGLONG)-1/10 || hlp < d)
-                                break;
-
-                            d = hlp;
-                            exp--;
-                        }
-                        while (width != 0 && nch != '\0' && isdigit( nch ))
-                        {
-                            nch = (consumed++, *str++);
-                            if (width > 0) width--;
-                        }
-                    }
-
-                    /* handle exponent */
-                    if (width != 0 && (nch == 'e' || nch == 'E'))
-                    {
-                        int sign = 1, e = 0;
-
-                        nch = (consumed++, *str++);
-                        if (width > 0) width--;
-                        if (width != 0 && (nch == '+' || nch == '-'))
-                        {
-                            if(nch == '-')
-                                sign = -1;
-                            nch = (consumed++, *str++);
-                            if (width > 0) width--;
-                        }
-
-                        /* exponent digits */
-                        while (width != 0 && nch != '\0' && isdigit( nch ))
-                        {
-                            if (e > INT_MAX/10 || (e = e * 10 + nch - '0') < 0)
-                                e = INT_MAX;
-                            nch = (consumed++, *str++);
-                            if (width > 0) width--;
-                        }
-                        e *= sign;
-
-                        if(exp < 0 && e < 0 && e+exp > 0) exp = INT_MIN;
-                        else if(exp > 0 && e > 0 && e+exp < 0) exp = INT_MAX;
-                        else exp += e;
-                    }
-
-                    /*fpcontrol = _control87(0, 0);
-                    _control87(MSVCRT__EM_DENORMAL|MSVCRT__EM_INVALID|MSVCRT__EM_ZERODIVIDE
-                            |MSVCRT__EM_OVERFLOW|MSVCRT__EM_UNDERFLOW|MSVCRT__EM_INEXACT, 0xffffffff);*/
-
-                    negexp = (exp < 0);
-                    if (negexp)
-                        exp = -exp;
-                    /* update 'cur' with this exponent. */
-                    while (exp)
-                    {
-                        if(exp & 1)
-                            cur *= expcnt;
-                        exp /= 2;
-                        expcnt = expcnt*expcnt;
-                    }
-                    cur = (negexp ? d/cur : d*cur);
-
-                    /*_control87(fpcontrol, 0xffffffff);*/
-
-                    st = 1;
-                    if (!suppress)
-                    {
-                        if (L_prefix || l_prefix) _SET_NUMBER_( double );
-                        else _SET_NUMBER_( float );
-                    }
-                }
-                break;
                 /* According to msdn,
                  * 's' reads a character string in a call to fscanf
                  * and 'S' a wide character string and vice versa in a
diff --git a/dlls/ntdll/tests/string.c b/dlls/ntdll/tests/string.c
index 5a2d8458c2..12027e8899 100644
--- a/dlls/ntdll/tests/string.c
+++ b/dlls/ntdll/tests/string.c
@@ -67,6 +67,8 @@ static int      (__cdecl *p_tolower)(int);
 static int      (__cdecl *p_toupper)(int);
 static int      (__cdecl *p__strnicmp)(LPCSTR,LPCSTR,size_t);
 
+static int      (WINAPIV *p_sscanf)(const char *, const char *, ...);
+
 static void InitFunctionPtrs(void)
 {
     hntdll = LoadLibraryA("ntdll.dll");
@@ -109,6 +111,8 @@ static void InitFunctionPtrs(void)
         p_tolower = (void *)GetProcAddress(hntdll, "tolower");
         p_toupper = (void *)GetProcAddress(hntdll, "toupper");
         p__strnicmp = (void *)GetProcAddress(hntdll, "_strnicmp");
+
+        p_sscanf = (void *)GetProcAddress(hntdll, "sscanf");
     } /* if */
 }
 
@@ -1455,6 +1459,48 @@ static void test__strnicmp(void)
     ok(!ret, "_strnicmp returned %d\n", ret);
 }
 
+static void test_sscanf(void)
+{
+    double d = 0.0;
+    float f = 0.0f;
+    int i = 0;
+    int ret;
+
+    if (!p_sscanf)
+    {
+        win_skip("sscanf tests\n");
+        return;
+    }
+
+    ret = p_sscanf("10", "%d", &i);
+    ok(ret == 1, "ret = %d\n", ret);
+    ok(i == 10, "i = %d\n", i);
+
+    ret = p_sscanf("10", "%f", &f);
+    ok(ret == 0 || broken(ret == 1) /* xp/2003 */, "ret = %d\n", ret);
+    ok(f == 0.0f, "f = %f\n", f);
+
+    ret = p_sscanf("10", "%g", &f);
+    ok(ret == 0 || broken(ret == 1) /* xp/2003 */, "ret = %d\n", ret);
+    ok(f == 0.0f, "f = %f\n", f);
+
+    ret = p_sscanf("10", "%e", &f);
+    ok(ret == 0 || broken(ret == 1) /* xp/2003 */, "ret = %d\n", ret);
+    ok(f == 0.0f, "f = %f\n", f);
+
+    ret = p_sscanf("10", "%lf", &d);
+    ok(ret == 0 || broken(ret == 1) /* xp/2003 */, "ret = %d\n", ret);
+    ok(d == 0.0, "d = %lf\n", f);
+
+    ret = p_sscanf("10", "%lg", &d);
+    ok(ret == 0 || broken(ret == 1) /* xp/2003 */, "ret = %d\n", ret);
+    ok(d == 0.0, "d = %lf\n", f);
+
+    ret = p_sscanf("10", "%le", &d);
+    ok(ret == 0 || broken(ret == 1) /* xp/2003 */, "ret = %d\n", ret);
+    ok(d == 0.0, "d = %lf\n", f);
+}
+
 START_TEST(string)
 {
     InitFunctionPtrs();
@@ -1498,4 +1544,5 @@ START_TEST(string)
     test_tolower();
     test_toupper();
     test__strnicmp();
+    test_sscanf();
 }




More information about the wine-cvs mailing list