msvcrt: Added _strtod_l implementation.

This commit is contained in:
Piotr Caban 2010-04-21 11:26:22 +02:00 committed by Alexandre Julliard
parent 776998866a
commit 94112ff960
5 changed files with 120 additions and 4 deletions

View File

@ -957,7 +957,7 @@
@ stub _strset_s
@ cdecl _strtime(ptr) msvcrt._strtime
@ stub _strtime_s
@ stub _strtod_l
@ cdecl _strtod_l(str ptr ptr) msvcrt._strtod_l
@ cdecl _strtoi64(str ptr long) msvcrt._strtoi64
@ cdecl _strtoi64_l(str ptr long ptr) msvcrt._strtoi64_l
@ stub _strtol_l

View File

@ -943,7 +943,7 @@
@ stub _strset_s
@ cdecl _strtime(ptr) msvcrt._strtime
@ stub _strtime_s
@ stub _strtod_l
@ cdecl _strtod_l(str ptr ptr) msvcrt._strtod_l
@ cdecl _strtoi64(str ptr long) msvcrt._strtoi64
@ cdecl _strtoi64_l(str ptr long ptr) msvcrt._strtoi64_l
@ stub _strtol_l

View File

@ -891,7 +891,7 @@
# stub _strset_s
@ cdecl _strtime(ptr)
# stub _strtime_s
# stub _strtod_l
@ cdecl _strtod_l(str ptr ptr) MSVCRT_strtod_l
@ cdecl _strtoi64(str ptr long) MSVCRT_strtoi64
@ cdecl _strtoi64_l(str ptr long ptr) MSVCRT_strtoi64_l
# stub _strtol_l

View File

@ -136,12 +136,72 @@ double CDECL MSVCRT_atof( const char *str )
return atof( str );
}
/*********************************************************************
* strtod_l (MSVCRT.@)
*/
double CDECL MSVCRT_strtod_l( const char *str, char **end, MSVCRT__locale_t locale)
{
const char *p, *dec_point=NULL, *exp=NULL;
char *copy;
double ret;
int err = errno;
if(!locale)
locale = get_locale();
if(!str) {
MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
*MSVCRT__errno() = MSVCRT_EINVAL;
return 0;
}
/* FIXME: use *_l functions */
p = str;
while(isspace(*p))
p++;
if(*p=='+' || *p=='-')
p++;
while(isdigit(*p))
p++;
if(*p == *locale->locinfo->lconv->decimal_point) {
if(*p!='.')
dec_point = p;
p++;
}
while(isdigit(*p))
p++;
if(*p=='d' || *p=='D')
exp = p;
/* FIXME: don't copy input string */
if((dec_point || exp) && (copy=_strdup(str))) {
if(dec_point)
copy[dec_point-str] = '.';
if(exp)
copy[exp-str] = 'e';
ret = strtod(copy, end);
if(end)
*end = (char*)str+(*end-copy);
MSVCRT_free(copy);
} else
ret = strtod(str, end);
if(err != errno)
*MSVCRT__errno() = errno;
return ret;
}
/*********************************************************************
* strtod (MSVCRT.@)
*/
double CDECL MSVCRT_strtod( const char *str, char **end )
{
return strtod( str, end );
return MSVCRT_strtod_l( str, end, NULL );
}
/*********************************************************************

View File

@ -1080,6 +1080,61 @@ static void test__strtoi64(void)
ok(errno == ERANGE, "errno = %x\n", errno);
}
static inline BOOL almost_equal(double d1, double d2) {
if(d1-d2>-1e-16 && d1-d2<1e-16)
return TRUE;
return FALSE;
}
static void test__strtod(void)
{
const char double1[] = "12.1";
const char double2[] = "-13.721";
const char double3[] = "INF";
const char double4[] = ".21e12";
const char double5[] = "214353e-3";
char *end;
double d;
d = strtod(double1, &end);
ok(almost_equal(d, 12.1), "d = %lf\n", d);
ok(end == double1+4, "incorrect end (%d)\n", end-double1);
d = strtod(double2, &end);
ok(almost_equal(d, -13.721), "d = %lf\n", d);
ok(end == double2+7, "incorrect end (%d)\n", end-double2);
d = strtod(double3, &end);
todo_wine ok(almost_equal(d, 0), "d = %lf\n", d);
todo_wine ok(end == double3, "incorrect end (%d)\n", end-double3);
d = strtod(double4, &end);
ok(almost_equal(d, 210000000000.0), "d = %lf\n", d);
ok(end == double4+6, "incorrect end (%d)\n", end-double4);
d = strtod(double5, &end);
ok(almost_equal(d, 214.353), "d = %lf\n", d);
ok(end == double5+9, "incorrect end (%d)\n", end-double5);
d = strtod("12.1d2", NULL);
ok(almost_equal(d, 12.1e2), "d = %lf\n", d);
/* Set locale with non '.' decimal point (',') */
if(!setlocale(LC_ALL, "Polish")) {
win_skip("system with limited locales\n");
return;
}
d = strtod("12.1", NULL);
todo_wine ok(almost_equal(d, 12.0), "d = %lf\n", d);
d = strtod("12,1", NULL);
ok(almost_equal(d, 12.1), "d = %lf\n", d);
setlocale(LC_ALL, "C");
}
START_TEST(string)
{
char mem[100];
@ -1133,4 +1188,5 @@ START_TEST(string)
test_strtol();
test_strnlen();
test__strtoi64();
test__strtod();
}