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@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
2ba39c8901
commit
94675cd8e3
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue