diff --git a/dlls/oleaut32/tests/vartype.c b/dlls/oleaut32/tests/vartype.c index a4d05afece5..9beaa35ba5a 100644 --- a/dlls/oleaut32/tests/vartype.c +++ b/dlls/oleaut32/tests/vartype.c @@ -68,6 +68,22 @@ static HMODULE hOleaut32; #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 @@ -501,6 +517,8 @@ static HRESULT (WINAPI *pVarBstrFromR4)(FLOAT,LCID,ULONG,BSTR*); static HRESULT (WINAPI *pVarBstrFromDate)(DATE,LCID,ULONG,BSTR*); static HRESULT (WINAPI *pVarBstrFromDec)(DECIMAL*,LCID,ULONG,BSTR*); +static HRESULT (WINAPI *pVarCmp)(LPVARIANT,LPVARIANT,LCID,ULONG); + static INT (WINAPI *pSystemTimeToVariantTime)(LPSYSTEMTIME,double*); static void (WINAPI *pClearCustData)(LPCUSTDATA); @@ -4698,6 +4716,62 @@ static void test_VarBoolChangeTypeEx(void) } } +#undef EXPECT_LT +#undef EXPECT_GT +#undef EXPECT_EQ +#undef EXPECT_NULL +#undef EXPECTRES +#define EXPECTRES(res) ok(hres == res, "expected " #res ", got hres=0x%08lx\n", hres) +#define EXPECT_LT EXPECTRES(VARCMP_LT) +#define EXPECT_GT EXPECTRES(VARCMP_GT) +#define EXPECT_EQ EXPECTRES(VARCMP_EQ) +#define EXPECT_NULL EXPECTRES(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, _I2, 100, &right, _BSTR, bzval100, lcid, 0); EXPECT_LT; + VARCMP(&left, _BSTR, (BSTR)100, &right, _I2, 100, lcid, 0); EXPECT_GT; + SysFreeString(szval101); + SysFreeString(szval100); + SysFreeString(szvalNULL); +} + /* * BSTR */ @@ -5889,6 +5963,8 @@ START_TEST(vartype) test_VarBoolCopy(); test_VarBoolChangeTypeEx(); + test_VarCmp(); + test_VarBstrFromR4(); test_VarBstrFromDate(); test_VarBstrFromDec(); diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c index e60880439bf..953595ba8d9 100644 --- a/dlls/oleaut32/variant.c +++ b/dlls/oleaut32/variant.c @@ -2512,11 +2512,14 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags) { 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); @@ -2581,6 +2584,8 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags) 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; } @@ -2596,6 +2601,8 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags) 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; } @@ -2608,7 +2615,47 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags) 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) { @@ -2642,7 +2689,9 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags) 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; }