Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
f76eef74
Commit
f76eef74
authored
Apr 26, 2010
by
Piotr Caban
Committed by
Alexandre Julliard
Apr 26, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcrt: Change strtod_l implementation.
parent
815840e9
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
106 additions
and
32 deletions
+106
-32
string.c
dlls/msvcrt/string.c
+76
-28
string.c
dlls/msvcrt/tests/string.c
+30
-4
No files found.
dlls/msvcrt/string.c
View file @
f76eef74
...
...
@@ -23,8 +23,11 @@
#define _ISOC99_SOURCE
#include "config.h"
#include "wine/port.h"
#include <stdlib.h>
#include <math.h>
#include <limits.h>
#include <errno.h>
#include "msvcrt.h"
#include "wine/debug.h"
...
...
@@ -141,13 +144,10 @@ double CDECL MSVCRT_atof( const char *str )
*/
double
CDECL
MSVCRT_strtod_l
(
const
char
*
str
,
char
**
end
,
MSVCRT__locale_t
locale
)
{
const
char
*
p
,
*
dec_point
=
NULL
,
*
exp
=
NULL
;
char
*
copy
;
unsigned
__int64
d
=
0
,
hlp
;
int
exp
=
0
,
sign
=
1
;
const
char
*
p
;
double
ret
;
int
err
=
errno
;
if
(
!
locale
)
locale
=
get_locale
();
if
(
!
str
)
{
MSVCRT__invalid_parameter
(
NULL
,
NULL
,
NULL
,
0
,
0
);
...
...
@@ -155,45 +155,93 @@ double CDECL MSVCRT_strtod_l( const char *str, char **end, MSVCRT__locale_t loca
return
0
;
}
if
(
!
locale
)
locale
=
get_locale
();
/* FIXME: use *_l functions */
p
=
str
;
while
(
isspace
(
*
p
))
p
++
;
if
(
*
p
==
'+'
||
*
p
==
'-'
)
if
(
*
p
==
'-'
)
{
sign
=
-
1
;
p
++
;
while
(
isdigit
(
*
p
)
)
}
else
if
(
*
p
==
'+'
)
p
++
;
if
(
*
p
==
*
locale
->
locinfo
->
lconv
->
decimal_point
)
{
if
(
*
p
!=
'.'
)
dec_point
=
p
;
while
(
isdigit
(
*
p
))
{
hlp
=
d
*
10
+*
(
p
++
)
-
'0'
;
if
(
d
>
MSVCRT_UI64_MAX
/
10
||
hlp
<
d
)
{
exp
++
;
break
;
}
else
d
=
hlp
;
}
while
(
isdigit
(
*
p
))
{
exp
++
;
p
++
;
}
while
(
isdigit
(
*
p
))
if
(
*
p
==
*
locale
->
locinfo
->
lconv
->
decimal_point
)
p
++
;
if
(
*
p
==
'd'
||
*
p
==
'D'
)
exp
=
p
;
/* FIXME: don't copy input string */
if
((
dec_point
||
exp
)
&&
(
copy
=
_strdup
(
str
)))
{
if
(
d
ec_point
)
copy
[
dec_point
-
str
]
=
'.'
;
while
(
isdigit
(
*
p
))
{
hlp
=
d
*
10
+*
(
p
++
)
-
'0'
;
if
(
d
>
MSVCRT_UI64_MAX
/
10
||
hlp
<
d
)
break
;
if
(
exp
)
copy
[
exp
-
str
]
=
'e'
;
d
=
hlp
;
exp
--
;
}
while
(
isdigit
(
*
p
))
p
++
;
ret
=
strtod
(
copy
,
end
);
if
(
p
==
str
)
{
if
(
end
)
*
end
=
(
char
*
)
str
+
(
*
end
-
copy
);
*
end
=
(
char
*
)
str
;
return
0
.
0
;
}
MSVCRT_free
(
copy
);
}
else
ret
=
strtod
(
str
,
end
);
if
(
*
p
==
'e'
||
*
p
==
'E'
||
*
p
==
'd'
||
*
p
==
'D'
)
{
int
e
=
0
,
s
=
1
;
if
(
err
!=
errno
)
*
MSVCRT__errno
()
=
errno
;
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
;
return
ret
;
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
--
;
}
}
if
(
exp
>
0
)
ret
=
(
double
)
sign
*
d
*
pow
(
10
,
exp
);
else
ret
=
(
double
)
sign
*
d
/
pow
(
10
,
-
exp
);
if
((
d
&&
ret
==
0
.
0
)
||
isinf
(
ret
))
*
MSVCRT__errno
()
=
MSVCRT_ERANGE
;
if
(
end
)
*
end
=
(
char
*
)
p
;
return
ret
;
}
/*********************************************************************
...
...
dlls/msvcrt/tests/string.c
View file @
f76eef74
...
...
@@ -1081,7 +1081,7 @@ static void test__strtoi64(void)
}
static
inline
BOOL
almost_equal
(
double
d1
,
double
d2
)
{
if
(
d1
-
d2
>-
1e-
16
&&
d1
-
d2
<
1e-16
)
if
(
d1
-
d2
>-
1e-
30
&&
d1
-
d2
<
1e-30
)
return
TRUE
;
return
FALSE
;
}
...
...
@@ -1093,6 +1093,7 @@ static void test__strtod(void)
const
char
double3
[]
=
"INF"
;
const
char
double4
[]
=
".21e12"
;
const
char
double5
[]
=
"214353e-3"
;
const
char
overflow
[]
=
"1d9999999999999999999"
;
char
*
end
;
double
d
;
...
...
@@ -1106,8 +1107,8 @@ static void test__strtod(void)
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
);
ok
(
almost_equal
(
d
,
0
),
"d = %lf
\n
"
,
d
);
ok
(
end
==
double3
,
"incorrect end (%d)
\n
"
,
end
-
double3
);
d
=
strtod
(
double4
,
&
end
);
ok
(
almost_equal
(
d
,
210000000000
.
0
),
"d = %lf
\n
"
,
d
);
...
...
@@ -1127,12 +1128,37 @@ static void test__strtod(void)
}
d
=
strtod
(
"12.1"
,
NULL
);
todo_wine
ok
(
almost_equal
(
d
,
12
.
0
),
"d = %lf
\n
"
,
d
);
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"
);
/* Precision tests */
d
=
strtod
(
"0.1"
,
NULL
);
ok
(
almost_equal
(
d
,
0
.
1
),
"d = %lf
\n
"
,
d
);
d
=
strtod
(
"-0.1"
,
NULL
);
ok
(
almost_equal
(
d
,
-
0
.
1
),
"d = %lf
\n
"
,
d
);
d
=
strtod
(
"0.1281832188491894198128921"
,
NULL
);
ok
(
almost_equal
(
d
,
0
.
1281832188491894198128921
),
"d = %lf
\n
"
,
d
);
d
=
strtod
(
"0.82181281288121"
,
NULL
);
ok
(
almost_equal
(
d
,
0
.
82181281288121
),
"d = %lf
\n
"
,
d
);
d
=
strtod
(
"21921922352523587651128218821"
,
NULL
);
ok
(
almost_equal
(
d
,
21921922352523587651128218821
.
0
),
"d = %lf
\n
"
,
d
);
d
=
strtod
(
"0.1d238"
,
NULL
);
ok
(
almost_equal
(
d
,
0.1e238L
),
"d = %lf
\n
"
,
d
);
d
=
strtod
(
"0.1D-4736"
,
NULL
);
ok
(
almost_equal
(
d
,
0.1e-4736L
),
"d = %lf
\n
"
,
d
);
errno
=
0xdeadbeef
;
d
=
strtod
(
overflow
,
&
end
);
ok
(
errno
==
ERANGE
,
"errno = %x
\n
"
,
errno
);
ok
(
end
==
overflow
+
21
,
"incorrect end (%d)
\n
"
,
end
-
overflow
);
errno
=
0xdeadbeef
;
strtod
(
"-1d309"
,
NULL
);
ok
(
errno
==
ERANGE
,
"errno = %x
\n
"
,
errno
);
}
START_TEST
(
string
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment