Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
a22adf18
Commit
a22adf18
authored
Jul 23, 2020
by
Piotr Caban
Committed by
Alexandre Julliard
Jul 23, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcrt: Don't use strtold in __STRINGTOLD_L.
Signed-off-by:
Piotr Caban
<
piotr@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
b22ffa58
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
179 additions
and
20 deletions
+179
-20
bnum.h
dlls/msvcrt/bnum.h
+1
-0
msvcrt.h
dlls/msvcrt/msvcrt.h
+3
-1
scanf.h
dlls/msvcrt/scanf.h
+1
-1
string.c
dlls/msvcrt/string.c
+173
-17
wcs.c
dlls/msvcrt/wcs.c
+1
-1
No files found.
dlls/msvcrt/bnum.h
View file @
a22adf18
...
...
@@ -28,6 +28,7 @@ static const int p10s[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
#define LIMB_MAX 1000000000
/* 10^9 */
#define BNUM_PREC64 128
/* data size needed to store 64-bit double */
#define BNUM_PREC80 2048
/* data size needed to store 80-bit double */
/* bnum represents real number with fixed decimal point */
struct
bnum
{
...
...
dlls/msvcrt/msvcrt.h
View file @
a22adf18
...
...
@@ -53,6 +53,8 @@
#define MSVCRT_FLT_MIN_10_EXP (-37)
#define MSVCRT_DBL_MAX_10_EXP 308
#define MSVCRT_DBL_MIN_10_EXP (-307)
#define DBL80_MAX_10_EXP 4932
#define DBL80_MIN_10_EXP -4951
#define MSVCRT_DBL_DIG 15
#ifdef _WIN64
#define MSVCRT_SIZE_MAX MSVCRT_UI64_MAX
...
...
@@ -1230,7 +1232,7 @@ struct fpnum {
enum
fpmod
mod
;
};
struct
fpnum
fpnum_parse
(
MSVCRT_wchar_t
(
*
)(
void
*
),
void
(
*
)(
void
*
),
void
*
,
MSVCRT_pthreadlocinfo
)
DECLSPEC_HIDDEN
;
void
*
,
MSVCRT_pthreadlocinfo
,
BOOL
)
DECLSPEC_HIDDEN
;
int
fpnum_double
(
struct
fpnum
*
,
double
*
)
DECLSPEC_HIDDEN
;
/* Maybe one day we'll enable the invalid parameter handlers with the full set of information (msvcrXXd)
* #define MSVCRT_INVALID_PMT(x) MSVCRT_call_invalid_parameter_handler(x, __FUNCTION__, __FILE__, __LINE__, 0)
...
...
dlls/msvcrt/scanf.h
View file @
a22adf18
...
...
@@ -405,7 +405,7 @@ _FUNCTION_ {
#endif
fp
=
fpnum_parse
(
_STRTOD_NAME_
(
strtod_scanf_get
),
_STRTOD_NAME_
(
strtod_scanf_unget
),
&
ctx
,
locinfo
);
_STRTOD_NAME_
(
strtod_scanf_unget
),
&
ctx
,
locinfo
,
FALSE
);
fpnum_double
(
&
fp
,
&
cur
);
if
(
!
rd
&&
ctx
.
err
)
{
_UNLOCK_FILE_
(
file
);
...
...
dlls/msvcrt/string.c
View file @
a22adf18
...
...
@@ -468,6 +468,132 @@ int fpnum_double(struct fpnum *fp, double *d)
return
0
;
}
#define LDBL_EXP_BITS 15
#define LDBL_MANT_BITS 64
int
fpnum_ldouble
(
struct
fpnum
*
fp
,
MSVCRT__LDOUBLE
*
d
)
{
if
(
fp
->
mod
==
FP_VAL_INFINITY
)
{
d
->
x80
[
0
]
=
0
;
d
->
x80
[
1
]
=
0x80000000
;
d
->
x80
[
2
]
=
(
1
<<
LDBL_EXP_BITS
)
-
1
;
if
(
fp
->
sign
==
-
1
)
d
->
x80
[
2
]
|=
1
<<
LDBL_EXP_BITS
;
return
0
;
}
if
(
fp
->
mod
==
FP_VAL_NAN
)
{
d
->
x80
[
0
]
=
~
0
;
d
->
x80
[
1
]
=
~
0
;
d
->
x80
[
2
]
=
(
1
<<
LDBL_EXP_BITS
)
-
1
;
if
(
fp
->
sign
==
-
1
)
d
->
x80
[
2
]
|=
1
<<
LDBL_EXP_BITS
;
return
0
;
}
TRACE
(
"%c %s *2^%d (round %d)
\n
"
,
fp
->
sign
==
-
1
?
'-'
:
'+'
,
wine_dbgstr_longlong
(
fp
->
m
),
fp
->
exp
,
fp
->
mod
);
if
(
!
fp
->
m
)
{
d
->
x80
[
0
]
=
0
;
d
->
x80
[
1
]
=
0
;
d
->
x80
[
2
]
=
0
;
if
(
fp
->
sign
==
-
1
)
d
->
x80
[
2
]
|=
1
<<
LDBL_EXP_BITS
;
return
0
;
}
/* make sure that we don't overflow modifying exponent */
if
(
fp
->
exp
>
1
<<
LDBL_EXP_BITS
)
{
d
->
x80
[
0
]
=
0
;
d
->
x80
[
1
]
=
0x80000000
;
d
->
x80
[
2
]
=
(
1
<<
LDBL_EXP_BITS
)
-
1
;
if
(
fp
->
sign
==
-
1
)
d
->
x80
[
2
]
|=
1
<<
LDBL_EXP_BITS
;
return
MSVCRT_ERANGE
;
}
if
(
fp
->
exp
<
-
(
1
<<
LDBL_EXP_BITS
))
{
d
->
x80
[
0
]
=
0
;
d
->
x80
[
1
]
=
0
;
d
->
x80
[
2
]
=
0
;
if
(
fp
->
sign
==
-
1
)
d
->
x80
[
2
]
|=
1
<<
LDBL_EXP_BITS
;
return
MSVCRT_ERANGE
;
}
fp
->
exp
+=
LDBL_MANT_BITS
-
1
;
/* normalize mantissa */
while
(
fp
->
m
<
(
ULONGLONG
)
1
<<
(
LDBL_MANT_BITS
-
1
))
{
fp
->
m
<<=
1
;
fp
->
exp
--
;
}
fp
->
exp
+=
(
1
<<
(
LDBL_EXP_BITS
-
1
))
-
1
;
/* handle subnormals */
if
(
fp
->
exp
<=
0
)
{
if
(
fp
->
m
&
1
&&
fp
->
mod
==
FP_ROUND_ZERO
)
fp
->
mod
=
FP_ROUND_EVEN
;
else
if
(
fp
->
m
&
1
)
fp
->
mod
=
FP_ROUND_UP
;
else
if
(
fp
->
mod
!=
FP_ROUND_ZERO
)
fp
->
mod
=
FP_ROUND_DOWN
;
fp
->
m
>>=
1
;
}
while
(
fp
->
m
&&
fp
->
exp
<
0
)
{
if
(
fp
->
m
&
1
&&
fp
->
mod
==
FP_ROUND_ZERO
)
fp
->
mod
=
FP_ROUND_EVEN
;
else
if
(
fp
->
m
&
1
)
fp
->
mod
=
FP_ROUND_UP
;
else
if
(
fp
->
mod
!=
FP_ROUND_ZERO
)
fp
->
mod
=
FP_ROUND_DOWN
;
fp
->
m
>>=
1
;
fp
->
exp
++
;
}
/* round mantissa */
if
(
fp
->
mod
==
FP_ROUND_UP
||
(
fp
->
mod
==
FP_ROUND_EVEN
&&
fp
->
m
&
1
))
{
if
(
fp
->
m
==
MSVCRT_UI64_MAX
)
{
fp
->
m
=
(
ULONGLONG
)
1
<<
(
LDBL_MANT_BITS
-
1
);
fp
->
exp
++
;
}
else
{
fp
->
m
++
;
/* handle subnormal that falls into regular range due to rounding */
if
((
fp
->
m
^
(
fp
->
m
-
1
))
&
((
ULONGLONG
)
1
<<
(
LDBL_MANT_BITS
-
1
)))
fp
->
exp
++
;
}
}
if
(
fp
->
exp
>=
(
1
<<
LDBL_EXP_BITS
)
-
1
)
{
d
->
x80
[
0
]
=
0
;
d
->
x80
[
1
]
=
0x80000000
;
d
->
x80
[
2
]
=
(
1
<<
LDBL_EXP_BITS
)
-
1
;
if
(
fp
->
sign
==
-
1
)
d
->
x80
[
2
]
|=
1
<<
LDBL_EXP_BITS
;
return
MSVCRT_ERANGE
;
}
if
(
!
fp
->
m
||
fp
->
exp
<
0
)
{
d
->
x80
[
0
]
=
0
;
d
->
x80
[
1
]
=
0
;
d
->
x80
[
2
]
=
0
;
if
(
fp
->
sign
==
-
1
)
d
->
x80
[
2
]
|=
1
<<
LDBL_EXP_BITS
;
return
MSVCRT_ERANGE
;
}
d
->
x80
[
0
]
=
fp
->
m
;
d
->
x80
[
1
]
=
fp
->
m
>>
32
;
d
->
x80
[
2
]
=
fp
->
exp
;
if
(
fp
->
sign
==
-
1
)
d
->
x80
[
2
]
|=
1
<<
LDBL_EXP_BITS
;
return
0
;
}
#if _MSVCR_VER >= 140
static
inline
int
hex2int
(
char
c
)
...
...
@@ -612,8 +738,8 @@ static inline BOOL bnum_to_mant(struct bnum *b, ULONGLONG *m)
return
TRUE
;
}
st
ruct
fpnum
fpnum_parse
(
MSVCRT_wchar_t
(
*
get
)(
void
*
ctx
),
void
(
*
unget
)(
void
*
ctx
),
void
*
ctx
,
MSVCRT_pthreadlocinfo
locinfo
)
st
atic
struct
fpnum
fpnum_parse_bnum
(
MSVCRT_wchar_t
(
*
get
)(
void
*
ctx
),
void
(
*
unget
)(
void
*
ctx
),
void
*
ctx
,
MSVCRT_pthreadlocinfo
locinfo
,
BOOL
ldouble
,
struct
bnum
*
b
)
{
#if _MSVCR_VER >= 140
MSVCRT_wchar_t
_infinity
[]
=
{
'i'
,
'n'
,
'f'
,
'i'
,
'n'
,
'i'
,
't'
,
'y'
,
0
};
...
...
@@ -622,9 +748,7 @@ struct fpnum fpnum_parse(MSVCRT_wchar_t (*get)(void *ctx), void (*unget)(void *c
int
matched
=
0
;
#endif
BOOL
found_digit
=
FALSE
,
found_dp
=
FALSE
,
found_sign
=
FALSE
;
BYTE
bnum_data
[
FIELD_OFFSET
(
struct
bnum
,
data
[
BNUM_PREC64
])];
int
e2
=
0
,
dp
=
0
,
sign
=
1
,
off
,
limb_digits
=
0
,
i
;
struct
bnum
*
b
=
(
struct
bnum
*
)
bnum_data
;
enum
fpmod
round
=
FP_ROUND_ZERO
;
MSVCRT_wchar_t
nch
;
ULONGLONG
m
;
...
...
@@ -684,7 +808,6 @@ struct fpnum fpnum_parse(MSVCRT_wchar_t (*get)(void *ctx), void (*unget)(void *c
b
->
b
=
0
;
b
->
e
=
1
;
b
->
size
=
BNUM_PREC64
;
b
->
data
[
0
]
=
0
;
while
(
nch
>=
'0'
&&
nch
<=
'9'
)
{
found_digit
=
TRUE
;
...
...
@@ -806,11 +929,11 @@ struct fpnum fpnum_parse(MSVCRT_wchar_t (*get)(void *ctx), void (*unget)(void *c
if
(
off
<
0
)
off
+=
LIMB_DIGITS
;
if
(
off
)
bnum_mult
(
b
,
p10s
[
off
]);
if
(
dp
-
1
>
MSVCRT_DBL_MAX_10_EXP
)
if
(
dp
-
1
>
(
ldouble
?
DBL80_MAX_10_EXP
:
MSVCRT_DBL_MAX_10_EXP
)
)
return
fpnum
(
sign
,
INT_MAX
,
1
,
FP_ROUND_ZERO
);
/* Count part of exponent stored in denormalized mantissa. */
/* Increase exponent range to handle subnormals. */
if
(
dp
-
1
<
MSVCRT_DBL_MIN_10_EXP
-
MSVCRT_DBL_DIG
-
18
)
if
(
dp
-
1
<
(
ldouble
?
DBL80_MIN_10_EXP
:
MSVCRT_DBL_MIN_10_EXP
-
MSVCRT_DBL_DIG
-
18
)
)
return
fpnum
(
sign
,
INT_MIN
,
1
,
FP_ROUND_ZERO
);
while
(
dp
>
3
*
LIMB_DIGITS
)
{
...
...
@@ -847,6 +970,24 @@ struct fpnum fpnum_parse(MSVCRT_wchar_t (*get)(void *ctx), void (*unget)(void *c
return
fpnum
(
sign
,
e2
,
m
,
round
);
}
struct
fpnum
fpnum_parse
(
MSVCRT_wchar_t
(
*
get
)(
void
*
ctx
),
void
(
*
unget
)(
void
*
ctx
),
void
*
ctx
,
MSVCRT_pthreadlocinfo
locinfo
,
BOOL
ldouble
)
{
if
(
!
ldouble
)
{
BYTE
bnum_data
[
FIELD_OFFSET
(
struct
bnum
,
data
[
BNUM_PREC64
])];
struct
bnum
*
b
=
(
struct
bnum
*
)
bnum_data
;
b
->
size
=
BNUM_PREC64
;
return
fpnum_parse_bnum
(
get
,
unget
,
ctx
,
locinfo
,
ldouble
,
b
);
}
else
{
BYTE
bnum_data
[
FIELD_OFFSET
(
struct
bnum
,
data
[
BNUM_PREC80
])];
struct
bnum
*
b
=
(
struct
bnum
*
)
bnum_data
;
b
->
size
=
BNUM_PREC80
;
return
fpnum_parse_bnum
(
get
,
unget
,
ctx
,
locinfo
,
ldouble
,
b
);
}
}
static
MSVCRT_wchar_t
strtod_str_get
(
void
*
ctx
)
{
const
char
**
p
=
ctx
;
...
...
@@ -888,7 +1029,7 @@ static inline double strtod_helper(const char *str, char **end, MSVCRT__locale_t
p
++
;
beg
=
p
;
fp
=
fpnum_parse
(
strtod_str_get
,
strtod_str_unget
,
&
p
,
locinfo
);
fp
=
fpnum_parse
(
strtod_str_get
,
strtod_str_unget
,
&
p
,
locinfo
,
FALSE
);
if
(
end
)
*
end
=
(
p
==
beg
?
(
char
*
)
str
:
(
char
*
)
p
);
err
=
fpnum_double
(
&
fp
,
&
ret
);
...
...
@@ -1300,15 +1441,30 @@ MSVCRT_size_t CDECL MSVCRT_strxfrm( char *dest, const char *src, MSVCRT_size_t l
int
CDECL
__STRINGTOLD_L
(
MSVCRT__LDOUBLE
*
value
,
char
**
endptr
,
const
char
*
str
,
int
flags
,
MSVCRT__locale_t
locale
)
{
#ifdef HAVE_STRTOLD
long
double
ld
;
FIXME
(
"%p %p %s %x %p partial stub
\n
"
,
value
,
endptr
,
str
,
flags
,
locale
);
ld
=
strtold
(
str
,
0
);
memcpy
(
value
,
&
ld
,
10
);
#else
FIXME
(
"%p %p %s %x stub
\n
"
,
value
,
endptr
,
str
,
flags
);
#endif
return
0
;
MSVCRT_pthreadlocinfo
locinfo
;
const
char
*
beg
,
*
p
;
int
err
,
ret
=
0
;
struct
fpnum
fp
;
if
(
flags
)
FIXME
(
"flags not supported: %x
\n
"
,
flags
);
if
(
!
locale
)
locinfo
=
get_locinfo
();
else
locinfo
=
locale
->
locinfo
;
p
=
str
;
while
(
MSVCRT__isspace_l
((
unsigned
char
)
*
p
,
locale
))
p
++
;
beg
=
p
;
fp
=
fpnum_parse
(
strtod_str_get
,
strtod_str_unget
,
&
p
,
locinfo
,
TRUE
);
if
(
endptr
)
*
endptr
=
(
p
==
beg
?
(
char
*
)
str
:
(
char
*
)
p
);
if
(
p
==
beg
)
ret
=
4
;
err
=
fpnum_ldouble
(
&
fp
,
value
);
if
(
err
)
ret
=
(
value
->
x80
[
2
]
&
0x7fff
?
2
:
1
);
return
ret
;
}
/********************************************************************
...
...
dlls/msvcrt/wcs.c
View file @
a22adf18
...
...
@@ -529,7 +529,7 @@ double CDECL MSVCRT__wcstod_l(const MSVCRT_wchar_t* str, MSVCRT_wchar_t** end,
p
++
;
beg
=
p
;
fp
=
fpnum_parse
(
strtod_wstr_get
,
strtod_wstr_unget
,
&
p
,
locinfo
);
fp
=
fpnum_parse
(
strtod_wstr_get
,
strtod_wstr_unget
,
&
p
,
locinfo
,
FALSE
);
if
(
end
)
*
end
=
(
p
==
beg
?
(
MSVCRT_wchar_t
*
)
str
:
(
MSVCRT_wchar_t
*
)
p
);
err
=
fpnum_double
(
&
fp
,
&
ret
);
...
...
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