PATCH: VarInt, VarPow, VarAdd, VarSub
Marcus Meissner
marcus at jet.franken.de
Sat Dec 13 12:41:29 CST 2003
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();
}
More information about the wine-patches
mailing list