Hi, Just found another new missing functionality in VarSub for VT_DATE. Ciao, Marcus Changelog: Implemented VarInt, VarPow. Added R4 (float) support to VarAdd. Added DATE support to VarSub. Index: dlls/oleaut32/variant.c =================================================================== RCS file: /home/wine/wine/dlls/oleaut32/variant.c,v retrieving revision 1.80 diff -u -r1.80 variant.c --- dlls/oleaut32/variant.c 11 Dec 2003 05:25:59 -0000 1.80 +++ dlls/oleaut32/variant.c 13 Dec 2003 18:40:20 -0000 @@ -30,6 +30,7 @@ #ifdef HAVE_STDLIB_H # include <stdlib.h> #endif +#include <math.h> #include <stdarg.h> #define NONAMELESSUNION @@ -2612,6 +2613,7 @@ 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 @@ 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 @@ 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; } @@ -3176,4 +3230,58 @@ { 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; } Index: dlls/oleaut32/oleaut32.spec =================================================================== RCS file: /home/wine/wine/dlls/oleaut32/oleaut32.spec,v retrieving revision 1.60 diff -u -r1.60 oleaut32.spec --- dlls/oleaut32/oleaut32.spec 11 Dec 2003 04:28:20 -0000 1.60 +++ dlls/oleaut32/oleaut32.spec 13 Dec 2003 18:40:20 -0000 @@ -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) Index: dlls/oleaut32/tests/vartest.c =================================================================== RCS file: /home/wine/wine/dlls/oleaut32/tests/vartest.c,v retrieving revision 1.18 diff -u -r1.18 vartest.c --- dlls/oleaut32/tests/vartest.c 11 Dec 2003 04:28:20 -0000 1.18 +++ dlls/oleaut32/tests/vartest.c 13 Dec 2003 18:40:21 -0000 @@ -4227,6 +4227,23 @@ } } +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 @@ test_VarFormat(); test_VarAbs(); test_VarNot(); + test_VarSub(); }