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
87c459ab
Commit
87c459ab
authored
Sep 17, 2013
by
Andrew Eikum
Committed by
Alexandre Julliard
Sep 18, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
oleaut32: Implement VarDecRound.
parent
515af78f
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
98 additions
and
23 deletions
+98
-23
vartype.c
dlls/oleaut32/tests/vartype.c
+35
-0
vartype.c
dlls/oleaut32/vartype.c
+63
-23
No files found.
dlls/oleaut32/tests/vartype.c
View file @
87c459ab
...
...
@@ -455,6 +455,7 @@ static HRESULT (WINAPI *pVarDecDiv)(const DECIMAL*,const DECIMAL*,DECIMAL*);
static
HRESULT
(
WINAPI
*
pVarDecCmp
)(
const
DECIMAL
*
,
const
DECIMAL
*
);
static
HRESULT
(
WINAPI
*
pVarDecCmpR8
)(
const
DECIMAL
*
,
double
);
static
HRESULT
(
WINAPI
*
pVarDecNeg
)(
const
DECIMAL
*
,
DECIMAL
*
);
static
HRESULT
(
WINAPI
*
pVarDecRound
)(
const
DECIMAL
*
,
int
,
DECIMAL
*
);
static
HRESULT
(
WINAPI
*
pVarBoolFromUI1
)(
BYTE
,
VARIANT_BOOL
*
);
static
HRESULT
(
WINAPI
*
pVarBoolFromI2
)(
SHORT
,
VARIANT_BOOL
*
);
...
...
@@ -4545,6 +4546,39 @@ static void test_VarDecCmpR8(void)
SETDEC
(
l
,
0
,
DECIMAL_NEG
,
-
1
,
-
1
);
r
=
DECIMAL_NEG
;
MATH3
(
VarDecCmpR8
);
EXPECT_LT
;
}
#define CLEAR(x) memset(&(x), 0xBB, sizeof(x))
static
void
test_VarDecRound
(
void
)
{
HRESULT
hres
;
DECIMAL
l
,
out
;
CHECKPTR
(
VarDecRound
);
CLEAR
(
out
);
SETDEC
(
l
,
0
,
0
,
0
,
1
);
hres
=
pVarDecRound
(
&
l
,
3
,
&
out
);
EXPECTDEC
(
0
,
0
,
0
,
1
);
CLEAR
(
out
);
SETDEC
(
l
,
0
,
0
,
0
,
1
);
hres
=
pVarDecRound
(
&
l
,
0
,
&
out
);
EXPECTDEC
(
0
,
0
,
0
,
1
);
CLEAR
(
out
);
SETDEC
(
l
,
1
,
0
,
0
,
1
);
hres
=
pVarDecRound
(
&
l
,
0
,
&
out
);
EXPECTDEC
(
0
,
0
,
0
,
0
);
CLEAR
(
out
);
SETDEC
(
l
,
1
,
0
,
0
,
1
);
hres
=
pVarDecRound
(
&
l
,
1
,
&
out
);
EXPECTDEC
(
1
,
0
,
0
,
1
);
CLEAR
(
out
);
SETDEC
(
l
,
2
,
0
,
0
,
11
);
hres
=
pVarDecRound
(
&
l
,
1
,
&
out
);
EXPECTDEC
(
1
,
0
,
0
,
1
);
CLEAR
(
out
);
SETDEC
(
l
,
2
,
0
,
0
,
15
);
hres
=
pVarDecRound
(
&
l
,
1
,
&
out
);
EXPECTDEC
(
1
,
0
,
0
,
2
);
CLEAR
(
out
);
SETDEC
(
l
,
6
,
0
,
0
,
550001
);
hres
=
pVarDecRound
(
&
l
,
1
,
&
out
);
EXPECTDEC
(
1
,
0
,
0
,
6
);
CLEAR
(
out
);
SETDEC
(
l
,
0
,
DECIMAL_NEG
,
0
,
1
);
hres
=
pVarDecRound
(
&
l
,
0
,
&
out
);
EXPECTDEC
(
0
,
DECIMAL_NEG
,
0
,
1
);
CLEAR
(
out
);
SETDEC
(
l
,
1
,
DECIMAL_NEG
,
0
,
1
);
hres
=
pVarDecRound
(
&
l
,
0
,
&
out
);
EXPECTDEC
(
0
,
DECIMAL_NEG
,
0
,
0
);
CLEAR
(
out
);
SETDEC
(
l
,
1
,
DECIMAL_NEG
,
0
,
1
);
hres
=
pVarDecRound
(
&
l
,
1
,
&
out
);
EXPECTDEC
(
1
,
DECIMAL_NEG
,
0
,
1
);
CLEAR
(
out
);
SETDEC
(
l
,
2
,
DECIMAL_NEG
,
0
,
11
);
hres
=
pVarDecRound
(
&
l
,
1
,
&
out
);
EXPECTDEC
(
1
,
DECIMAL_NEG
,
0
,
1
);
CLEAR
(
out
);
SETDEC
(
l
,
2
,
DECIMAL_NEG
,
0
,
15
);
hres
=
pVarDecRound
(
&
l
,
1
,
&
out
);
EXPECTDEC
(
1
,
DECIMAL_NEG
,
0
,
2
);
CLEAR
(
out
);
SETDEC
(
l
,
6
,
DECIMAL_NEG
,
0
,
550001
);
hres
=
pVarDecRound
(
&
l
,
1
,
&
out
);
EXPECTDEC
(
1
,
DECIMAL_NEG
,
0
,
6
);
CLEAR
(
out
);
SETDEC64
(
l
,
0
,
0
,
0xffffffff
,
0xffffffff
,
0xffffffff
);
hres
=
pVarDecRound
(
&
l
,
0
,
&
out
);
EXPECTDEC64
(
0
,
0
,
0xffffffff
,
0xffffffff
,
0xffffffff
);
CLEAR
(
out
);
SETDEC64
(
l
,
28
,
0
,
0xffffffff
,
0xffffffff
,
0xffffffff
);
hres
=
pVarDecRound
(
&
l
,
0
,
&
out
);
EXPECTDEC64
(
0
,
0
,
0
,
0
,
8
);
CLEAR
(
out
);
SETDEC64
(
l
,
0
,
DECIMAL_NEG
,
0xffffffff
,
0xffffffff
,
0xffffffff
);
hres
=
pVarDecRound
(
&
l
,
0
,
&
out
);
EXPECTDEC64
(
0
,
DECIMAL_NEG
,
0xffffffff
,
0xffffffff
,
0xffffffff
);
CLEAR
(
out
);
SETDEC64
(
l
,
28
,
DECIMAL_NEG
,
0xffffffff
,
0xffffffff
,
0xffffffff
);
hres
=
pVarDecRound
(
&
l
,
0
,
&
out
);
EXPECTDEC64
(
0
,
DECIMAL_NEG
,
0
,
0
,
8
);
CLEAR
(
out
);
SETDEC
(
l
,
2
,
0
,
0
,
0
);
hres
=
pVarDecRound
(
&
l
,
1
,
&
out
);
EXPECTDEC
(
1
,
0
,
0
,
0
);
}
/*
* VT_BOOL
*/
...
...
@@ -6334,6 +6368,7 @@ START_TEST(vartype)
test_VarDecCmpR8
();
test_VarDecMul
();
test_VarDecDiv
();
test_VarDecRound
();
test_VarBoolFromI1
();
test_VarBoolFromUI1
();
...
...
dlls/oleaut32/vartype.c
View file @
87c459ab
...
...
@@ -5137,7 +5137,7 @@ static int VARIANT_int_addlossy(
in case of quotient overflow.
*/
static
HRESULT
VARIANT_DI_div
(
const
VARIANT_DI
*
dividend
,
const
VARIANT_DI
*
divisor
,
VARIANT_DI
*
quotient
)
VARIANT_DI
*
quotient
,
BOOL
round_remainder
)
{
HRESULT
r_overflow
=
S_OK
;
...
...
@@ -5180,8 +5180,21 @@ static HRESULT VARIANT_DI_div(const VARIANT_DI * dividend, const VARIANT_DI * di
underflow
=
VARIANT_int_addlossy
(
quotient
->
bitsnum
,
&
quotientscale
,
sizeof
(
quotient
->
bitsnum
)
/
sizeof
(
DWORD
),
remainderplusquotient
,
&
tempquotientscale
,
4
);
VARIANT_int_mulbychar
(
remainderplusquotient
+
4
,
4
,
10
);
memcpy
(
remainderplusquotient
,
remainderplusquotient
+
4
,
4
*
sizeof
(
DWORD
));
if
(
round_remainder
)
{
if
(
remainderplusquotient
[
4
]
>=
5
){
unsigned
int
i
;
unsigned
char
remainder
=
1
;
for
(
i
=
0
;
i
<
sizeof
(
quotient
->
bitsnum
)
/
sizeof
(
DWORD
)
&&
remainder
;
i
++
)
{
ULONGLONG
digit
=
quotient
->
bitsnum
[
i
]
+
1
;
remainder
=
(
digit
>
0xFFFFFFFF
)
?
1
:
0
;
quotient
->
bitsnum
[
i
]
=
digit
&
0xFFFFFFFF
;
}
}
memset
(
remainderplusquotient
,
0
,
sizeof
(
remainderplusquotient
));
}
else
{
VARIANT_int_mulbychar
(
remainderplusquotient
+
4
,
4
,
10
);
memcpy
(
remainderplusquotient
,
remainderplusquotient
+
4
,
4
*
sizeof
(
DWORD
));
}
tempquotientscale
=
++
remainderscale
;
}
while
(
!
underflow
&&
!
VARIANT_int_iszero
(
remainderplusquotient
+
4
,
4
));
...
...
@@ -5485,31 +5498,16 @@ static HRESULT VARIANT_DI_FromR8(double source, VARIANT_DI * dest)
return
hres
;
}
/************************************************************************
* VarDecDiv (OLEAUT32.178)
*
* Divide one DECIMAL by another.
*
* PARAMS
* pDecLeft [I] Source
* pDecRight [I] Value to divide by
* pDecOut [O] Destination
*
* RETURNS
* Success: S_OK.
* Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
*/
HRESULT
WINAPI
VarDecDiv
(
const
DECIMAL
*
pDecLeft
,
const
DECIMAL
*
pDecRight
,
DECIMAL
*
pDecOut
)
static
HRESULT
VARIANT_do_division
(
const
DECIMAL
*
pDecLeft
,
const
DECIMAL
*
pDecRight
,
DECIMAL
*
pDecOut
,
BOOL
round
)
{
HRESULT
hRet
=
S_OK
;
VARIANT_DI
di_left
,
di_right
,
di_result
;
HRESULT
divresult
;
if
(
!
pDecLeft
||
!
pDecRight
||
!
pDecOut
)
return
E_INVALIDARG
;
VARIANT_DIFromDec
(
pDecLeft
,
&
di_left
);
VARIANT_DIFromDec
(
pDecRight
,
&
di_right
);
divresult
=
VARIANT_DI_div
(
&
di_left
,
&
di_right
,
&
di_result
);
divresult
=
VARIANT_DI_div
(
&
di_left
,
&
di_right
,
&
di_result
,
round
);
if
(
divresult
!=
S_OK
)
{
/* division actually overflowed */
...
...
@@ -5557,6 +5555,27 @@ HRESULT WINAPI VarDecDiv(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECI
}
/************************************************************************
* VarDecDiv (OLEAUT32.178)
*
* Divide one DECIMAL by another.
*
* PARAMS
* pDecLeft [I] Source
* pDecRight [I] Value to divide by
* pDecOut [O] Destination
*
* RETURNS
* Success: S_OK.
* Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
*/
HRESULT
WINAPI
VarDecDiv
(
const
DECIMAL
*
pDecLeft
,
const
DECIMAL
*
pDecRight
,
DECIMAL
*
pDecOut
)
{
if
(
!
pDecLeft
||
!
pDecRight
||
!
pDecOut
)
return
E_INVALIDARG
;
return
VARIANT_do_division
(
pDecLeft
,
pDecRight
,
pDecOut
,
FALSE
);
}
/************************************************************************
* VarDecMul (OLEAUT32.179)
*
* Multiply one DECIMAL by another.
...
...
@@ -5765,6 +5784,10 @@ HRESULT WINAPI VarDecNeg(const DECIMAL* pDecIn, DECIMAL* pDecOut)
*/
HRESULT
WINAPI
VarDecRound
(
const
DECIMAL
*
pDecIn
,
int
cDecimals
,
DECIMAL
*
pDecOut
)
{
DECIMAL
divisor
,
tmp
;
HRESULT
hr
;
unsigned
int
i
;
if
(
cDecimals
<
0
||
(
DEC_SIGN
(
pDecIn
)
&
~
DECIMAL_NEG
)
||
DEC_SCALE
(
pDecIn
)
>
DEC_MAX_SCALE
)
return
E_INVALIDARG
;
...
...
@@ -5774,9 +5797,26 @@ HRESULT WINAPI VarDecRound(const DECIMAL* pDecIn, int cDecimals, DECIMAL* pDecOu
return
S_OK
;
}
FIXME
(
"semi-stub!
\n
"
);
/* truncate significant digits and rescale */
memset
(
&
divisor
,
0
,
sizeof
(
divisor
));
DEC_LO64
(
&
divisor
)
=
1
;
return
DISP_E_OVERFLOW
;
memset
(
&
tmp
,
0
,
sizeof
(
tmp
));
DEC_LO64
(
&
tmp
)
=
10
;
for
(
i
=
0
;
i
<
DEC_SCALE
(
pDecIn
)
-
cDecimals
;
++
i
)
{
hr
=
VarDecMul
(
&
divisor
,
&
tmp
,
&
divisor
);
if
(
FAILED
(
hr
))
return
hr
;
}
hr
=
VARIANT_do_division
(
pDecIn
,
&
divisor
,
pDecOut
,
TRUE
);
if
(
FAILED
(
hr
))
return
hr
;
DEC_SCALE
(
pDecOut
)
=
cDecimals
;
return
S_OK
;
}
/************************************************************************
...
...
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