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
1f273618
Commit
1f273618
authored
Nov 17, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcrt: Avoid long double type in $I10_OUTPUT().
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
b9002cc8
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
64 additions
and
69 deletions
+64
-69
string.c
dlls/msvcrt/string.c
+18
-25
misc.c
dlls/msvcrt/tests/misc.c
+46
-44
No files found.
dlls/msvcrt/string.c
View file @
1f273618
...
...
@@ -2390,20 +2390,29 @@ struct _I10_OUTPUT_DATA {
*/
int
CDECL
MSVCRT_I10_OUTPUT
(
MSVCRT__LDOUBLE
ld80
,
int
prec
,
int
flag
,
struct
_I10_OUTPUT_DATA
*
data
)
{
static
const
char
inf_str
[]
=
"1#INF"
;
static
const
char
nan_str
[]
=
"1#QNAN"
;
/* MS' long double type wants 12 bytes for Intel's 80 bit FP format.
* Some UNIX have sizeof(long double) == 16, yet only 80 bit are used.
* Assume long double uses 80 bit FP, never seen 128 bit FP. */
long
double
ld
=
0
;
struct
fpnum
num
;
double
d
;
char
format
[
8
];
char
buf
[
I10_OUTPUT_MAX_PREC
+
9
];
/* 9 = strlen("0.e+0000") + '\0' */
char
*
p
;
memcpy
(
&
ld
,
&
ld80
,
10
);
d
=
ld
;
if
((
ld80
.
x80
[
2
]
&
0x7fff
)
==
0x7fff
)
{
if
(
ld80
.
x80
[
0
]
==
0
&&
ld80
.
x80
[
1
]
==
0x80000000
)
strcpy
(
data
->
str
,
"1#INF"
);
else
strcpy
(
data
->
str
,
(
ld80
.
x80
[
1
]
&
0x40000000
)
?
"1#QNAN"
:
"1#SNAN"
);
data
->
pos
=
1
;
data
->
sign
=
(
ld80
.
x80
[
2
]
&
0x8000
)
?
'-'
:
' '
;
data
->
len
=
strlen
(
data
->
str
);
return
0
;
}
num
.
sign
=
(
ld80
.
x80
[
2
]
&
0x8000
)
?
-
1
:
1
;
num
.
exp
=
(
ld80
.
x80
[
2
]
&
0x7fff
)
-
0x3fff
-
63
;
num
.
m
=
ld80
.
x80
[
0
]
|
((
ULONGLONG
)
ld80
.
x80
[
1
]
<<
32
);
num
.
mod
=
FP_ROUND_EVEN
;
fpnum_double
(
&
num
,
&
d
);
TRACE
(
"(%lf %d %x %p)
\n
"
,
d
,
prec
,
flag
,
data
);
if
(
d
<
0
)
{
...
...
@@ -2412,22 +2421,6 @@ int CDECL MSVCRT_I10_OUTPUT(MSVCRT__LDOUBLE ld80, int prec, int flag, struct _I1
}
else
data
->
sign
=
' '
;
if
(
isinf
(
d
))
{
data
->
pos
=
1
;
data
->
len
=
5
;
memcpy
(
data
->
str
,
inf_str
,
sizeof
(
inf_str
));
return
0
;
}
if
(
isnan
(
d
))
{
data
->
pos
=
1
;
data
->
len
=
6
;
memcpy
(
data
->
str
,
nan_str
,
sizeof
(
nan_str
));
return
0
;
}
if
(
flag
&
1
)
{
int
exp
=
1
+
floor
(
log10
(
d
));
...
...
dlls/msvcrt/tests/misc.c
View file @
1f273618
...
...
@@ -30,8 +30,11 @@ static inline BOOL almost_equal(double d1, double d2) {
return
FALSE
;
}
/* MS' "long double" is an 80 bit FP that takes 12 bytes*/
struct
uld
{
ULONG
lo
,
hi
,
exp
;
};
static
int
(
__cdecl
*
prand_s
)(
unsigned
int
*
);
static
int
(
__cdecl
*
pI10_OUTPUT
)(
long
double
,
int
,
int
,
void
*
);
static
int
(
__cdecl
*
pI10_OUTPUT
)(
struct
uld
,
int
,
int
,
void
*
);
static
int
(
__cdecl
*
pstrerror_s
)(
char
*
,
size_t
,
int
);
static
int
(
__cdecl
*
p_get_doserrno
)(
int
*
);
static
int
(
__cdecl
*
p_get_errno
)(
int
*
);
...
...
@@ -94,7 +97,7 @@ typedef struct _I10_OUTPUT_data {
}
I10_OUTPUT_data
;
typedef
struct
_I10_OUTPUT_test
{
long
double
d
;
struct
uld
d
;
int
size
;
int
flags
;
...
...
@@ -105,63 +108,62 @@ typedef struct _I10_OUTPUT_test {
static
const
I10_OUTPUT_test
I10_OUTPUT_tests
[]
=
{
/* arg3 = 0 */
{
0
.
0
,
10
,
0
,
{
0
,
' '
,
1
,
"0"
},
1
,
""
},
{
1
.
0
,
10
,
0
,
{
1
,
' '
,
1
,
"1"
},
1
,
"000000009"
},
{
-
1
.
0
,
10
,
0
,
{
1
,
'-'
,
1
,
"1"
},
1
,
"000000009"
},
{
1
.
23
,
10
,
0
,
{
1
,
' '
,
3
,
"123"
},
1
,
"0000009"
},
{
1e13
,
10
,
0
,
{
14
,
' '
,
1
,
"1"
},
1
,
"000000009"
},
{
1e30
,
30
,
0
,
{
31
,
' '
,
21
,
"100000000000000001988"
},
1
,
""
},
{
1e-13
,
10
,
0
,
{
-
12
,
' '
,
1
,
"1"
},
1
,
"000000000"
},
{
0
.
25
,
10
,
0
,
{
0
,
' '
,
2
,
"25"
},
1
,
"00000000"
},
{
1
.
0000001
,
10
,
0
,
{
1
,
' '
,
8
,
"10000001"
},
1
,
"00"
},
{
{
0x00000000
,
0x00000000
,
0x0000
/* 0.0 */
},
10
,
0
,
{
0
,
' '
,
1
,
"0"
},
1
,
""
},
{
{
0x00000000
,
0x80000000
,
0x3fff
/* 1.0 */
},
10
,
0
,
{
1
,
' '
,
1
,
"1"
},
1
,
"000000009"
},
{
{
0x00000000
,
0x80000000
,
0xbfff
/* -1.0 */
},
10
,
0
,
{
1
,
'-'
,
1
,
"1"
},
1
,
"000000009"
},
{
{
0x0a3d7000
,
0x9d70a3d7
,
0x3fff
/* 1.23 */
},
10
,
0
,
{
1
,
' '
,
3
,
"123"
},
1
,
"0000009"
},
{
{
0x00000000
,
0x9184e72a
,
0x402a
/* 1e13 */
},
10
,
0
,
{
14
,
' '
,
1
,
"1"
},
1
,
"000000009"
},
{
{
0x04675000
,
0xc9f2c9cd
,
0x4062
/* 1e30 */
},
30
,
0
,
{
31
,
' '
,
21
,
"100000000000000001988"
},
1
,
""
},
{
{
0x4bb41000
,
0xe12e1342
,
0x3fd3
/* 1e-13 */
},
10
,
0
,
{
-
12
,
' '
,
1
,
"1"
},
1
,
"000000000"
},
{
{
0x00000000
,
0x80000000
,
0x3ffd
/* 0.25 */
},
10
,
0
,
{
0
,
' '
,
2
,
"25"
},
1
,
"00000000"
},
{
{
0xbf94d800
,
0x800000d6
,
0x3fff
/* 1.0000001 */
},
10
,
0
,
{
1
,
' '
,
8
,
"10000001"
},
1
,
"00"
},
{
{
0x00000000
,
0x80000000
,
0x7fff
/* +inf */
},
10
,
0
,
{
1
,
' '
,
5
,
"1#INF"
},
0
,
""
},
{
{
0x00000000
,
0x80000000
,
0xffff
/* -inf */
},
10
,
0
,
{
1
,
'-'
,
5
,
"1#INF"
},
0
,
""
},
{
{
0x00000001
,
0x80000000
,
0x7fff
/* snan */
},
10
,
0
,
{
1
,
' '
,
6
,
"1#SNAN"
},
0
,
""
},
{
{
0x00000001
,
0x80000000
,
0xffff
/* snan */
},
10
,
0
,
{
1
,
'-'
,
6
,
"1#SNAN"
},
0
,
""
},
{
{
0x00000000
,
0xc0000000
,
0x7fff
/* qnan */
},
10
,
0
,
{
1
,
' '
,
6
,
"1#QNAN"
},
0
,
""
},
{
{
0x00000000
,
0x40000000
,
0xffff
/* qnan */
},
10
,
0
,
{
1
,
'-'
,
6
,
"1#QNAN"
},
0
,
""
},
/* arg3 = 1 */
{
0
.
0
,
10
,
1
,
{
0
,
' '
,
1
,
"0"
},
1
,
""
},
{
1
.
0
,
10
,
1
,
{
1
,
' '
,
1
,
"1"
},
1
,
"0000000009"
},
{
-
1
.
0
,
10
,
1
,
{
1
,
'-'
,
1
,
"1"
},
1
,
"0000000009"
},
{
1
.
23
,
10
,
1
,
{
1
,
' '
,
3
,
"123"
},
1
,
"00000009"
},
{
1e13
,
10
,
1
,
{
14
,
' '
,
1
,
"1"
},
1
,
"00000000000000000009"
},
{
1e30
,
30
,
1
,
{
31
,
' '
,
21
,
"100000000000000001988"
},
1
,
""
},
{
1e-13
,
10
,
1
,
{
0
,
' '
,
1
,
"0"
},
1
,
""
},
{
1e-7
,
10
,
1
,
{
-
6
,
' '
,
1
,
"1"
},
1
,
"09"
},
{
0
.
25
,
10
,
1
,
{
0
,
' '
,
2
,
"25"
},
1
,
"00000000"
},
{
1
.
0000001
,
10
,
1
,
{
1
,
' '
,
8
,
"10000001"
},
1
,
"000"
},
{
{
0x00000000
,
0x00000000
,
0x0000
/* 0 */
},
10
,
1
,
{
0
,
' '
,
1
,
"0"
},
1
,
""
},
{
{
0x00000000
,
0x80000000
,
0x3fff
/* 1 */
},
10
,
1
,
{
1
,
' '
,
1
,
"1"
},
1
,
"0000000009"
},
{
{
0x00000000
,
0x80000000
,
0xbfff
/* -1 */
},
10
,
1
,
{
1
,
'-'
,
1
,
"1"
},
1
,
"0000000009"
},
{
{
0x0a3d7000
,
0x9d70a3d7
,
0x3fff
/* 1.23 */
},
10
,
1
,
{
1
,
' '
,
3
,
"123"
},
1
,
"00000009"
},
{
{
0x00000000
,
0x9184e72a
,
0x402a
/* 1e13 */
},
10
,
1
,
{
14
,
' '
,
1
,
"1"
},
1
,
"00000000000000000009"
},
{
{
0x04675000
,
0xc9f2c9cd
,
0x4062
/* 1e30 */
},
30
,
1
,
{
31
,
' '
,
21
,
"100000000000000001988"
},
1
,
""
},
{
{
0x4bb41000
,
0xe12e1342
,
0x3fd3
/* 1e-13 */
},
10
,
1
,
{
0
,
' '
,
1
,
"0"
},
1
,
""
},
{
{
0xe57a4000
,
0xd6bf94d5
,
0x3fe7
/* 1e-7 */
},
10
,
1
,
{
-
6
,
' '
,
1
,
"1"
},
1
,
"09"
},
{
{
0x00000000
,
0x80000000
,
0x3ffd
/* 0.25 */
},
10
,
1
,
{
0
,
' '
,
2
,
"25"
},
1
,
"00000000"
},
{
{
0xbf94d800
,
0x800000d6
,
0x3fff
/* 1.0000001 */
},
10
,
1
,
{
1
,
' '
,
8
,
"10000001"
},
1
,
"000"
},
{
{
0x00000000
,
0x80000000
,
0x7fff
/* +inf */
},
10
,
1
,
{
1
,
' '
,
5
,
"1#INF"
},
0
,
""
},
{
{
0x00000000
,
0x80000000
,
0xffff
/* -inf */
},
10
,
1
,
{
1
,
'-'
,
5
,
"1#INF"
},
0
,
""
},
{
{
0x00000001
,
0x80000000
,
0x7fff
/* snan */
},
10
,
1
,
{
1
,
' '
,
6
,
"1#SNAN"
},
0
,
""
},
{
{
0x00000000
,
0xc0000000
,
0x7fff
/* qnan */
},
10
,
1
,
{
1
,
' '
,
6
,
"1#QNAN"
},
0
,
""
},
{
{
0x00000000
,
0x40000000
,
0x7fff
/* qnan */
},
10
,
1
,
{
1
,
' '
,
6
,
"1#QNAN"
},
0
,
""
},
/* too small buffer */
{
0
.
0
,
0
,
0
,
{
0
,
' '
,
1
,
"0"
},
1
,
""
},
{
0
.
0
,
0
,
1
,
{
0
,
' '
,
1
,
"0"
},
1
,
""
},
{
123
.
0
,
2
,
0
,
{
3
,
' '
,
2
,
"12"
},
1
,
""
},
{
123
.
0
,
0
,
0
,
{
0
,
' '
,
1
,
"0"
},
1
,
""
},
{
123
.
0
,
2
,
1
,
{
3
,
' '
,
3
,
"123"
},
1
,
"09"
},
{
0
.
99
,
1
,
0
,
{
1
,
' '
,
1
,
"1"
},
1
,
""
},
{
1264567
.
0
,
2
,
0
,
{
7
,
' '
,
2
,
"13"
},
1
,
""
},
{
1264567
.
0
,
2
,
1
,
{
7
,
' '
,
7
,
"1264567"
},
1
,
"00"
},
{
1234567891
.
0
,
2
,
1
,
{
10
,
' '
,
10
,
"1234567891"
},
1
,
"09"
}
{
{
0x00000000
,
0x00000000
,
0x0000
/* 0 */
}
,
0
,
0
,
{
0
,
' '
,
1
,
"0"
},
1
,
""
},
{
{
0x00000000
,
0x00000000
,
0x0000
/* 0 */
}
,
0
,
1
,
{
0
,
' '
,
1
,
"0"
},
1
,
""
},
{
{
0x00000000
,
0xf6000000
,
0x4005
/* 123 */
}
,
2
,
0
,
{
3
,
' '
,
2
,
"12"
},
1
,
""
},
{
{
0x00000000
,
0xf6000000
,
0x4005
/* 123 */
}
,
0
,
0
,
{
0
,
' '
,
1
,
"0"
},
1
,
""
},
{
{
0x00000000
,
0xf6000000
,
0x4005
/* 123 */
}
,
2
,
1
,
{
3
,
' '
,
3
,
"123"
},
1
,
"09"
},
{
{
0x0a3d7000
,
0xfd70a3d7
,
0x3ffe
/* 0.99 */
}
,
1
,
0
,
{
1
,
' '
,
1
,
"1"
},
1
,
""
},
{
{
0x00000000
,
0x9a5db800
,
0x4013
/* 1264567.0 */
}
,
2
,
0
,
{
7
,
' '
,
2
,
"13"
},
1
,
""
},
{
{
0x00000000
,
0x9a5db800
,
0x4013
/* 1264567.0 */
}
,
2
,
1
,
{
7
,
' '
,
7
,
"1264567"
},
1
,
"00"
},
{
{
0x00000000
,
0x932c05a6
,
0x401d
/* 1234567891.0 */
}
,
2
,
1
,
{
10
,
' '
,
10
,
"1234567891"
},
1
,
"09"
}
};
static
void
test_I10_OUTPUT
(
void
)
{
I10_OUTPUT_data
out
;
int
i
,
j
=
sizeof
(
long
double
)
,
ret
;
int
i
,
j
,
ret
;
if
(
!
pI10_OUTPUT
)
{
win_skip
(
"I10_OUTPUT not available
\n
"
);
return
;
}
if
(
j
!=
12
)
trace
(
"sizeof(long double) = %d on this machine
\n
"
,
j
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
I10_OUTPUT_tests
);
i
++
)
{
memset
(
out
.
str
,
'#'
,
sizeof
(
out
.
str
));
if
(
sizeof
(
long
double
)
==
12
)
ret
=
pI10_OUTPUT
(
I10_OUTPUT_tests
[
i
].
d
,
I10_OUTPUT_tests
[
i
].
size
,
I10_OUTPUT_tests
[
i
].
flags
,
&
out
);
else
{
/* MS' "long double" is an 80 bit FP that takes 12 bytes*/
typedef
struct
{
ULONG
x80
[
3
];
}
uld
;
/* same calling convention */
union
{
long
double
ld
;
uld
ld12
;
}
fp80
;
int
(
__cdecl
*
pI10_OUTPUT12
)(
uld
,
int
,
int
,
void
*
)
=
(
void
*
)
pI10_OUTPUT
;
fp80
.
ld
=
I10_OUTPUT_tests
[
i
].
d
;
ret
=
pI10_OUTPUT12
(
fp80
.
ld12
,
I10_OUTPUT_tests
[
i
].
size
,
I10_OUTPUT_tests
[
i
].
flags
,
&
out
);
}
ret
=
pI10_OUTPUT
(
I10_OUTPUT_tests
[
i
].
d
,
I10_OUTPUT_tests
[
i
].
size
,
I10_OUTPUT_tests
[
i
].
flags
,
&
out
);
ok
(
ret
==
I10_OUTPUT_tests
[
i
].
ret
,
"%d: ret = %d
\n
"
,
i
,
ret
);
ok
(
out
.
pos
==
I10_OUTPUT_tests
[
i
].
out
.
pos
,
"%d: out.pos = %hd
\n
"
,
i
,
out
.
pos
);
ok
(
out
.
sign
==
I10_OUTPUT_tests
[
i
].
out
.
sign
,
"%d: out.size = %c
\n
"
,
i
,
out
.
sign
);
...
...
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