Implemented VarInt, VarPow.

Added R4 (float) support to VarAdd.
Added DATE support to VarSub.
This commit is contained in:
Marcus Meissner 2003-12-15 20:14:32 +00:00 committed by Alexandre Julliard
parent 48f97983d7
commit cf50f9a04e
3 changed files with 129 additions and 3 deletions

View File

@ -153,7 +153,7 @@
155 stdcall VarMod(ptr ptr ptr)
156 stdcall VarMul(ptr ptr ptr)
157 stdcall VarOr(ptr ptr ptr)
158 stub VarPow # stdcall (ptr ptr ptr)
158 stdcall VarPow(ptr ptr ptr)
159 stdcall VarSub(ptr ptr ptr)
160 stdcall CreateTypeLib(long wstr ptr)
161 stdcall LoadTypeLib (wstr ptr)
@ -167,7 +167,7 @@
169 stub VarFix # stdcall (ptr ptr)
170 stdcall OaBuildVersion()
171 stub ClearCustData
172 stub VarInt # stdcall (ptr ptr)
172 stdcall VarInt(ptr ptr)
173 stub VarNeg # stdcall (ptr ptr)
174 stdcall VarNot(ptr ptr)
175 stub VarRound # stdcall (ptr long ptr)

View File

@ -4227,6 +4227,23 @@ static void test_VarNot(void)
}
}
static void test_VarSub(void)
{
VARIANT va, vb, vc;
HRESULT hr;
V_VT(&va) = VT_DATE;
V_DATE(&va) = 200000.0;
V_VT(&vb) = VT_DATE;
V_DATE(&vb) = 100000.0;
hr = VarSub(&va, &vb, &vc);
ok(hr == S_OK,"VarSub of VT_DATE - VT_DATE failed with %lx\n", hr);
ok(V_VT(&vc) == VT_R8,"VarSub of VT_DATE - VT_DATE returned vt 0x%x\n", V_VT(&vc));
ok(((V_R8(&vc) > 99999.9) && (V_R8(&vc) < 100000.1)),"VarSub of VT_DATE - VT_DATE should return 100000.0, but returned %g\n", V_R8(&vc));
/* fprintf(stderr,"VarSub of 10000-20000 returned: %g\n", V_R8(&vc)); */
}
START_TEST(vartest)
{
hOleaut32 = LoadLibraryA("oleaut32.dll");
@ -4248,4 +4265,5 @@ START_TEST(vartest)
test_VarFormat();
test_VarAbs();
test_VarNot();
test_VarSub();
}

View File

@ -30,6 +30,7 @@
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#include <math.h>
#include <stdarg.h>
#define NONAMELESSUNION
@ -2612,6 +2613,7 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
if ((V_VT(right)&VT_TYPEMASK) == VT_EMPTY)
return VariantCopy(result,left);
/* check if we add doubles */
if (((V_VT(left)&VT_TYPEMASK) == VT_R8) || ((V_VT(right)&VT_TYPEMASK) == VT_R8)) {
BOOL lOk = TRUE;
BOOL rOk = TRUE;
@ -2665,6 +2667,58 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
return rc;
}
/* now check if we add floats. VT_R8 can no longer happen here! */
if (((V_VT(left)&VT_TYPEMASK) == VT_R4) || ((V_VT(right)&VT_TYPEMASK) == VT_R4)) {
BOOL lOk = TRUE;
BOOL rOk = TRUE;
float lVal = -1;
float rVal = -1;
float res = -1;
lOk = TRUE;
switch (V_VT(left)&VT_TYPEMASK) {
case VT_I1 : lVal = V_UNION(left,cVal); break;
case VT_I2 : lVal = V_UNION(left,iVal); break;
case VT_I4 : lVal = V_UNION(left,lVal); break;
case VT_INT : lVal = V_UNION(left,lVal); break;
case VT_UI1 : lVal = V_UNION(left,bVal); break;
case VT_UI2 : lVal = V_UNION(left,uiVal); break;
case VT_UI4 : lVal = V_UNION(left,ulVal); break;
case VT_UINT : lVal = V_UNION(left,ulVal); break;
case VT_R4 : lVal = V_UNION(left,fltVal); break;
case VT_NULL : lVal = 0.0; break;
default: lOk = FALSE;
}
rOk = TRUE;
switch (V_VT(right)&VT_TYPEMASK) {
case VT_I1 : rVal = V_UNION(right,cVal); break;
case VT_I2 : rVal = V_UNION(right,iVal); break;
case VT_I4 : rVal = V_UNION(right,lVal); break;
case VT_INT : rVal = V_UNION(right,lVal); break;
case VT_UI1 : rVal = V_UNION(right,bVal); break;
case VT_UI2 : rVal = V_UNION(right,uiVal); break;
case VT_UI4 : rVal = V_UNION(right,ulVal); break;
case VT_UINT : rVal = V_UNION(right,ulVal); break;
case VT_R4 : rVal = V_UNION(right,fltVal);break;
case VT_NULL : rVal = 0.0; break;
default: rOk = FALSE;
}
if (lOk && rOk) {
res = (lVal + rVal);
V_VT(result) = VT_R4;
V_UNION(result,fltVal) = res;
rc = S_OK;
} else {
FIXME("Unhandled type pair %d / %d in float addition.\n",
(V_VT(left)&VT_TYPEMASK),
(V_VT(right)&VT_TYPEMASK)
);
}
return rc;
}
/* Handle strings as concat */
if ((V_VT(left)&VT_TYPEMASK) == VT_BSTR &&
(V_VT(right)&VT_TYPEMASK) == VT_BSTR) {
@ -2863,7 +2917,7 @@ HRESULT WINAPI VarSub(LPVARIANT left, LPVARIANT right, LPVARIANT result)
lvt = V_VT(left)&VT_TYPEMASK;
rvt = V_VT(right)&VT_TYPEMASK;
found = FALSE;resvt = VT_VOID;
if (((1<<lvt) | (1<<rvt)) & ((1<<VT_R4)|(1<<VT_R8))) {
if (((1<<lvt) | (1<<rvt)) & ((1<<VT_DATE)|(1<<VT_R4)|(1<<VT_R8))) {
found = TRUE;
resvt = VT_R8;
}
@ -3177,3 +3231,57 @@ HRESULT WINAPI VarMod(LPVARIANT left, LPVARIANT right, LPVARIANT result)
FIXME("%p %p %p\n", left, right, result);
return E_FAIL;
}
/**********************************************************************
* VarPow [OLEAUT32.158]
*
*/
HRESULT WINAPI VarPow(LPVARIANT left, LPVARIANT right, LPVARIANT result)
{
HRESULT hr;
VARIANT dl,dr;
TRACE("(%p,%p,%p)\n", left, right, result);
TRACE("left var:\n"); dump_Variant(left);
TRACE("right var:\n"); dump_Variant(right);
hr = VariantChangeType(&dl,left,0,VT_R8);
if (!SUCCEEDED(hr)) {
ERR("Could not change passed left argument to VT_R8, handle it differently.\n");
return E_FAIL;
}
hr = VariantChangeType(&dr,right,0,VT_R8);
if (!SUCCEEDED(hr)) {
ERR("Could not change passed right argument to VT_R8, handle it differently.\n");
return E_FAIL;
}
V_VT(result) = VT_R8;
V_R8(result) = pow(V_R8(&dl),V_R8(&dr));
return S_OK;
}
/**********************************************************************
* VarInt [OLEAUT32.172]
*
*/
HRESULT WINAPI VarInt(LPVARIANT var, LPVARIANT result)
{
TRACE("(%p,%p)\n",var,result);
TRACE("Var:\n");
dump_Variant(var);
switch(V_VT(var)) {
case VT_R4:
V_VT(result) = VT_I4;
V_I4(result) = floor(V_R4(var));
break;
case VT_R8:
V_VT(result) = VT_I4;
V_I4(result) = floor(V_R8(var));
break;
default:
FIXME("Unhandled variant type 0x%x\n", V_VT(var));
return DISP_E_TYPEMISMATCH;
}
return S_OK;
}