Extend VarCmp() and add test cases(extended)

Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Sun Oct 23 17:26:17 CDT 2005


Subject: Extend VarCmp() and add test cases
Date: Sun, 23 Oct 2005 14:52:59 +0200

       Changelog:
       wine/dlls/oleaut32/variant.c: VarCmp()
       Extend VarCmp functionality
       wine/dlls/oleaut32/tests/vartype.c:
       Add tests for VarCmp()

Overrides the patch sent earlier. Now handles R4/R8 types.
It shouldn't collide with Michael Stefaniuc patch:
Re: oleaut32: handle VT_DECIMAL in VarCmp()

Together with the other oleaut32 fixes this makes TGEB.exe proceed run now.
-- 
Uwe Bonnes                bon at elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
Index: wine/dlls/oleaut32/tests/vartype.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/tests/vartype.c,v
retrieving revision 1.32
diff -u -r1.32 vartype.c
--- wine/dlls/oleaut32/tests/vartype.c	12 Sep 2005 22:07:53 -0000	1.32
+++ wine/dlls/oleaut32/tests/vartype.c	23 Oct 2005 22:22:34 -0000
@@ -68,6 +68,22 @@
 #define IS_MODERN_VTYPE(vt) (vt==VT_VARIANT||vt==VT_DECIMAL|| \
     vt==VT_I1||vt==VT_UI2||vt==VT_UI4||vt == VT_INT||vt == VT_UINT)
 
+/* Macro for setting typ and initializing */
+/* First some dummy definitions*/
+int val_empty, val_null; 
+
+#define V_EMPTY(x) val_empty
+#define V_NULL(x) val_null
+
+#define VARINIT( A, type, value)  V_VT(A) = VT##type; V##type(A) = value
+
+/* Macro for VarCmp*/
+
+#define VARCMP(left, ltype, lvalue, right, rtype, rvalue, lcid, flags) \
+  VARINIT(left, ltype, lvalue); \
+  VARINIT(right, rtype, rvalue); \
+  hres = pVarCmp(left, right, lcid, flags)
+
 /* Macros for converting and testing results */
 #define CONVVARS(typ) HRESULT hres; CONV_TYPE out; typ in
 
@@ -498,6 +514,8 @@
 static HRESULT (WINAPI *pVarBstrFromR4)(FLOAT,LCID,ULONG,BSTR*);
 static HRESULT (WINAPI *pVarBstrFromDate)(DATE,LCID,ULONG,BSTR*);
 
+static HRESULT (WINAPI *pVarCmp)(LPVARIANT,LPVARIANT,LCID,ULONG);
+
 static INT (WINAPI *pSystemTimeToVariantTime)(LPSYSTEMTIME,double*);
 static void (WINAPI *pClearCustData)(LPCUSTDATA);
 
@@ -4588,6 +4606,90 @@
   }
 }
 
+#undef EXPECT_LT 
+#undef EXPECT_GT 
+#undef EXPECT_EQ 
+#undef EXPECT_NULL
+#undef EXPECTRES
+#define EXPECTRES(res, x) ok(hres == res, "expected " #x ", got hres=0x%08lx\n", hres)
+#define EXPECT_LT       EXPECTRES(VARCMP_LT, VARCMP_LT)
+#define EXPECT_GT       EXPECTRES(VARCMP_GT, VARCMP_GT)
+#define EXPECT_EQ       EXPECTRES(VARCMP_EQ, VARCMP_EQ)
+#define EXPECT_NULL     EXPECTRES(VARCMP_NULL, VARCMP_NULL)
+
+static void test_VarCmp(void)
+{
+    HRESULT hres;
+    VARIANTARG left, right;
+    LCID lcid;
+    WCHAR szvalNULL[] = { '0',0 };
+    WCHAR szval100[] = { '1','0','0',0 };
+    WCHAR szval101[] = { '1','0','1',0 };
+    BSTR bzvalNULL, bzval100, bzval101;
+
+    lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
+    bzvalNULL=SysAllocString(szvalNULL);
+    bzval100=SysAllocString(szval100);
+    bzval101=SysAllocString(szval101);
+    CHECKPTR(VarCmp);
+    VARCMP(&left, _DATE,   25570.0, &right, _DATE,   25570.0, lcid, 0); EXPECT_EQ;
+    VARCMP(&left, _DATE,   25570.0, &right, _DATE,   25571.0, lcid, 0); EXPECT_LT;
+    VARCMP(&left, _DATE,   25571.0, &right, _DATE,   25570.0, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _DATE,   25570.0, &right, _EMPTY,        0, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _DATE,   25570.0, &right, _NULL,         0, lcid, 0); EXPECT_NULL;
+    VARCMP(&left, _I2,           2, &right, _I2,           2, lcid, 0); EXPECT_EQ;
+    VARCMP(&left, _I2,           1, &right, _I2,           2, lcid, 0); EXPECT_LT;
+    VARCMP(&left, _I2,           2, &right, _I2,           1, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _I2,           2, &right, _EMPTY,        1, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _I2,           2, &right, _NULL,          1, lcid, 0); EXPECT_NULL;
+    VARCMP(&left, _BSTR,      NULL, &right, _EMPTY,        0, lcid, 0); EXPECT_EQ;
+    VARCMP(&left, _EMPTY,        0, &right, _BSTR,      NULL, lcid, 0); EXPECT_EQ;
+    VARCMP(&left, _EMPTY,        0, &right, _BSTR,  bzval100, lcid, 0); EXPECT_LT;
+    VARCMP(&left, _BSTR, bzvalNULL, &right, _EMPTY,        0, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _BSTR, bzvalNULL, &right, _NULL,         0, lcid, 0); EXPECT_NULL;
+    VARCMP(&left, _BSTR, bzvalNULL, &right, _I2,           0, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _BSTR, bzvalNULL, &right, _NULL,         0, lcid, 0); EXPECT_NULL;
+    VARCMP(&left, _BSTR,  bzval100, &right, _BSTR,  bzval100, lcid, 0); EXPECT_EQ;
+    VARCMP(&left, _BSTR,  bzval100, &right, _BSTR,  bzval101, lcid, 0); EXPECT_LT;
+    VARCMP(&left, _BSTR,  bzval101, &right, _BSTR,  bzval100, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _BSTR,  bzval100, &right, _I2,         100, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _BSTR,  bzval100, &right, _I2,         101, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _BSTR,  bzval100, &right, _I2,         101, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _BSTR, (BSTR)100, &right, _I2,         100, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _I2,         100, &right, _BSTR,  bzval100, lcid, 0); EXPECT_LT;
+    VARCMP(&left, _R4,       100.0, &right, _R4,       100.0, lcid, 0); EXPECT_EQ;
+    VARCMP(&left, _R4,       100.1, &right, _R4,       100.0, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _R4,       100.0, &right, _R4,       100.1, lcid, 0); EXPECT_LT;
+    VARCMP(&left, _R8,       100.0, &right, _R8,       100.0, lcid, 0); EXPECT_EQ;
+    VARCMP(&left, _R8,       100.1, &right, _R8,       100.0, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _R8,       100.0, &right, _R8,       100.1, lcid, 0); EXPECT_LT;
+    VARCMP(&left, _R4,       100.0, &right, _R8,       100.0, lcid, 0); EXPECT_EQ;
+    VARCMP(&left, _R4,       100.1, &right, _R8,       100.0, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _R4,       100.0, &right, _R8,       100.1, lcid, 0); EXPECT_LT;
+    VARCMP(&left, _R8,       100.0, &right, _R4,       100.0, lcid, 0); EXPECT_EQ;
+    VARCMP(&left, _R8,       100.1, &right, _R4,       100.0, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _R8,       100.0, &right, _R4,       100.1, lcid, 0); EXPECT_LT;
+
+    VARCMP(&left, _R4,       100.0, &right, _I4,         100, lcid, 0); EXPECT_EQ;
+    VARCMP(&left, _R4,       100.1, &right, _I4,         100, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _R4,       100.0, &right, _I4,         101, lcid, 0); EXPECT_LT;
+    VARCMP(&left, _R8,       100.0, &right, _I4,         100, lcid, 0); EXPECT_EQ;
+    VARCMP(&left, _R8,       100.1, &right, _I4,         100, lcid, 0); EXPECT_GT;
+    VARCMP(&left, _R8,       100.0, &right, _I4,         101, lcid, 0); EXPECT_LT;
+
+    VARCMP(&left, _I4,         100, &right, _R4,       100.0, lcid, 0); EXPECT_EQ;
+    VARCMP(&left, _I4,         100, &right, _R4,       100.1, lcid, 0); EXPECT_LT;
+    VARCMP(&left, _I4,         101, &right, _R4,       100.0, lcid, 0); EXPECT_GT;
+
+    VARCMP(&left, _I4,         100, &right, _R8,       100.0, lcid, 0); EXPECT_EQ;
+    VARCMP(&left, _I4,         100, &right, _R8,       100.1, lcid, 0); EXPECT_LT;
+    VARCMP(&left, _I4,         101, &right, _R8,       100.0, lcid, 0); EXPECT_GT;
+
+    SysFreeString(szval101);
+    SysFreeString(szval100);
+    SysFreeString(szvalNULL);
+}
+
 /*
  * BSTR
  */
@@ -5672,6 +5774,8 @@
   test_VarBoolCopy();
   test_VarBoolChangeTypeEx();
 
+  test_VarCmp();
+
   test_VarBstrFromR4();
   test_VarBstrFromDate();
   test_SysStringLen();
Index: wine/dlls/oleaut32/variant.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/variant.c,v
retrieving revision 1.123
diff -u -r1.123 variant.c
--- wine/dlls/oleaut32/variant.c	22 Sep 2005 10:35:16 -0000	1.123
+++ wine/dlls/oleaut32/variant.c	23 Oct 2005 22:22:42 -0000
@@ -2512,11 +2512,14 @@
 {
     BOOL	lOk        = TRUE;
     BOOL	rOk        = TRUE;
+    BOOL	l_isR      = FALSE;
+    BOOL	r_isR      = FALSE;
     LONGLONG	lVal = -1;
     LONGLONG	rVal = -1;
     VARIANT	rv,lv;
     DWORD	xmask;
     HRESULT	rc;
+    double	lDouble =0.0,rDouble=0.0;
 
     TRACE("(%p->(%s%s),%p->(%s%s),0x%08lx,0x%08lx)\n", left, debugstr_VT(left),
           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), lcid, flags);
@@ -2537,29 +2540,6 @@
     }
 
     xmask = (1<<(V_VT(left)&VT_TYPEMASK))|(1<<(V_VT(right)&VT_TYPEMASK));
-    if (xmask & VTBIT_R8) {
-	rc = VariantChangeType(&lv,left,0,VT_R8);
-	if (FAILED(rc)) return rc;
-	rc = VariantChangeType(&rv,right,0,VT_R8);
-	if (FAILED(rc)) return rc;
-
-	if (V_R8(&lv) == V_R8(&rv)) return VARCMP_EQ;
-	if (V_R8(&lv) < V_R8(&rv)) return VARCMP_LT;
-	if (V_R8(&lv) > V_R8(&rv)) return VARCMP_GT;
-	return E_FAIL; /* can't get here */
-    }
-    if (xmask & VTBIT_R4) {
-	rc = VariantChangeType(&lv,left,0,VT_R4);
-	if (FAILED(rc)) return rc;
-	rc = VariantChangeType(&rv,right,0,VT_R4);
-	if (FAILED(rc)) return rc;
-
-	if (V_R4(&lv) == V_R4(&rv)) return VARCMP_EQ;
-	if (V_R4(&lv) < V_R4(&rv)) return VARCMP_LT;
-	if (V_R4(&lv) > V_R4(&rv)) return VARCMP_GT;
-	return E_FAIL; /* can't get here */
-    }
-
     /* Integers - Ideally like to use VarDecCmp, but no Dec support yet
            Use LONGLONG to maximize ranges                              */
     lOk = TRUE;
@@ -2574,6 +2554,8 @@
     case VT_UINT : lVal = V_UI4(left); break;
     case VT_BOOL : lVal = V_BOOL(left); break;
     case VT_EMPTY : lVal = 0; break;
+    case VT_R4 : lDouble = V_R4(left); lOk = FALSE; l_isR= TRUE; break;
+    case VT_R8 : lDouble = V_R8(left); lOk = FALSE; l_isR= TRUE; break;
     default: lOk = FALSE;
     }
 
@@ -2589,6 +2571,8 @@
     case VT_UINT : rVal = V_UI4(right); break;
     case VT_BOOL : rVal = V_BOOL(right); break;
     case VT_EMPTY : rVal = 0; break;
+    case VT_R4 : rDouble = V_R4(right); rOk = FALSE;r_isR= TRUE; break;
+    case VT_R8 : rDouble = V_R8(right); rOk = FALSE;r_isR= TRUE; break;
     default: rOk = FALSE;
     }
 
@@ -2601,7 +2585,47 @@
             return VARCMP_EQ;
         }
     }
-
+    else if (l_isR && r_isR) {
+        if (lDouble < rDouble) {
+            return VARCMP_LT;
+        } else if (lDouble > rDouble) {
+            return VARCMP_GT;
+        } else {
+            return VARCMP_EQ;
+        }
+    }
+    else if (lOk && r_isR) {
+        if (lVal < rDouble) {
+            return VARCMP_LT;
+        } else if (lVal > rDouble) {
+            return VARCMP_GT;
+        } else {
+            return VARCMP_EQ;
+        }
+    }
+    else if (l_isR && rOk) {
+        if (lDouble < rVal) {
+            return VARCMP_LT;
+        } else if (lDouble > rVal) {
+            return VARCMP_GT;
+        } else {
+            return VARCMP_EQ;
+        }
+    }
+    if ((V_VT(left)&VT_TYPEMASK) == VT_BSTR ) {
+	if(((V_VT(right)&VT_TYPEMASK) == VT_EMPTY ) && !(V_BSTR(left))) {
+	    return VARCMP_EQ;
+	} else {
+	    return VARCMP_GT;
+	}
+    }
+    if ((V_VT(right)&VT_TYPEMASK) == VT_BSTR ) {
+	if(((V_VT(left)&VT_TYPEMASK) == VT_EMPTY ) && !(V_BSTR(right))) {
+	    return VARCMP_EQ;
+	} else {
+	    return VARCMP_LT;
+	}
+    }
     /* Dates */
     if ((V_VT(left)&VT_TYPEMASK) == VT_DATE &&
         (V_VT(right)&VT_TYPEMASK) == VT_DATE) {
@@ -2635,7 +2659,9 @@
             return VARCMP_GT;
         }
     }
-    FIXME("VarCmp partial implementation, doesn't support vt 0x%x / 0x%x\n",V_VT(left), V_VT(right));
+    else if((V_VT(right)&VT_TYPEMASK) == VT_EMPTY)
+            return VARCMP_GT;
+    FIXME("VarCmp partial implementation, doesn't support %s / %s\n",wine_vtypes[V_VT(left)], wine_vtypes[V_VT(right)]);
     return E_FAIL;
 }
 



More information about the wine-patches mailing list