oleaut32: Conformance test with fixes for variant:VarAnd
Benjamin Arai
me at benjaminarai.com
Thu Aug 24 20:45:59 CDT 2006
Hi,
ChangeLog:
- Adds conformance test for VarAnd
- Fixes for VarAnd to pass all conformance tests
---
dlls/oleaut32/tests/vartest.c | 748 +++++++++++++++++++++++++++++++++++++++++
dlls/oleaut32/variant.c | 327 +++++++++++++++---
2 files changed, 1015 insertions(+), 60 deletions(-)
--
Benjamin Arai
http://www.benjaminarai.com
-------------- next part --------------
diff --git a/dlls/oleaut32/tests/vartest.c b/dlls/oleaut32/tests/vartest.c
index cfcf1f0..d6197d9 100644
--- a/dlls/oleaut32/tests/vartest.c
+++ b/dlls/oleaut32/tests/vartest.c
@@ -5287,6 +5287,753 @@ static void test_VarCat(void)
VariantClear(&expected);
}
+static HRESULT (WINAPI *pVarAnd)(LPVARIANT,LPVARIANT,LPVARIANT);
+
+static const char *szVarAndFail = "VarAnd(%s,%s): expected 0x0,%s,%d, got 0x%lX,%s,%d\n";
+static const char *szVarAndChanged = "VarAnd(%s,%s): Modified input arguments\n";
+
+#define VARAND(vt1,val1,vt2,val2,rvt,rval) \
+ V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
+ V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
+ memset(&result,0,sizeof(result)); hres = pVarAnd(&left,&right,&result); \
+ ok(hres == S_OK && V_VT(&result) == VT_##rvt && V_##rvt(&result) == (rval), \
+ szVarAndFail, vtstr(VT_##vt1), vtstr(VT_##vt2), \
+ vtstr(VT_##rvt), (int)(rval), hres, vtstr(V_VT(&result)), (int)V_##rvt(&result)); \
+ ok(V_VT(&left) == VT_##vt1 && V_##vt1(&left) == val1 && \
+ V_VT(&right) == VT_##vt2 && V_##vt2(&right) == val2, \
+ szVarAndChanged,vtstr(VT_##vt1),vtstr(VT_##vt2))
+#define VARANDCY(vt1,val1,val2,rvt,rval) \
+ V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
+ V_VT(&right) = VT_CY; V_CY(&right).int64 = val2; \
+ memset(&result,0,sizeof(result)); hres = pVarAnd(&left,&right,&result); \
+ ok(hres == S_OK && V_VT(&result) == VT_##rvt && V_##rvt(&result) == (rval), \
+ szVarAndFail, vtstr(VT_##vt1), vtstr(VT_CY), \
+ vtstr(VT_##rvt), (int)(rval), hres, vtstr(V_VT(&result)), (int)V_##rvt(&result)); \
+ ok(V_VT(&left) == VT_##vt1 && V_##vt1(&left) == val1 && \
+ V_VT(&right) == VT_CY && V_CY(&right).int64 == val2, \
+ szVarAndChanged,vtstr(VT_##vt1),vtstr(VT_CY))
+
+static void test_VarAnd(void)
+{
+ static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
+ static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
+ VARIANT left, right, result;
+ BSTR false_str, true_str;
+ VARTYPE i;
+ HRESULT hres, expectedhres;
+
+ true_str = SysAllocString(szTrue);
+ false_str = SysAllocString(szFalse);
+
+ CHECKPTR(VarAnd);
+
+ /* Test all possible flag/vt combinations & the resulting vt type */
+ for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
+ {
+ VARTYPE leftvt, rightvt, resvt;
+
+ for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
+ {
+ SKIPTESTS(leftvt);
+
+ for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
+ {
+ SKIPTESTS(rightvt);
+
+ if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
+ leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN)
+ continue;
+
+ memset(&left, 0, sizeof(left));
+ memset(&right, 0, sizeof(right));
+ V_VT(&left) = leftvt | ExtraFlags[i];
+ V_VT(&right) = rightvt | ExtraFlags[i];
+ V_VT(&result) = VT_EMPTY;
+ resvt = VT_EMPTY;
+ if (leftvt == VT_BSTR)
+ V_BSTR(&left) = true_str;
+ if (rightvt == VT_BSTR)
+ V_BSTR(&right) = true_str;
+ expectedhres = S_OK;
+
+ /* All extra flags produce errors */
+ if (ExtraFlags[i] == (VT_ARRAY|VT_BYREF) ||
+ ExtraFlags[i] == (VT_BYREF) ||
+ ExtraFlags[i] == (VT_ARRAY))
+ {
+ if ((leftvt >= VT_I2 && leftvt <= VT_DATE) ||
+ (leftvt >= VT_ERROR && leftvt <= VT_VARIANT) ||
+ leftvt == VT_DECIMAL || leftvt == VT_RECORD ||
+ (leftvt >= VT_I1 && leftvt <= VT_UI4) ||
+ leftvt == VT_INT || leftvt == VT_UINT ||
+ leftvt == VT_I8 || leftvt == VT_UI8 ||
+ leftvt == VT_BSTR)
+ expectedhres = DISP_E_TYPEMISMATCH;
+ else
+ expectedhres = DISP_E_BADVARTYPE;
+ }
+ else if (ExtraFlags[i])
+ expectedhres = DISP_E_BADVARTYPE;
+ else if (leftvt == VT_ERROR || leftvt == VT_RECORD ||
+ leftvt == VT_VARIANT)
+ expectedhres = DISP_E_TYPEMISMATCH;
+ else if (rightvt == VT_RECORD || rightvt == VT_VARIANT ||
+ rightvt == VT_ERROR)
+ {
+ if (leftvt == VT_EMPTY || leftvt == VT_NULL ||
+ leftvt == VT_I2 || leftvt == VT_I4 ||
+ leftvt == VT_R4 || leftvt == VT_R8 ||
+ leftvt == VT_CY || leftvt == VT_DATE ||
+ leftvt == VT_BOOL || leftvt == VT_DECIMAL ||
+ (leftvt >= VT_I1 && leftvt <= VT_UI4) ||
+ leftvt == VT_INT || leftvt == VT_UINT ||
+ leftvt == VT_I8 || leftvt == VT_UI8 ||
+ leftvt == VT_BSTR)
+ expectedhres = DISP_E_TYPEMISMATCH;
+ else
+ expectedhres = DISP_E_BADVARTYPE;
+ }
+ else if (leftvt == VT_CLSID || rightvt == VT_CLSID)
+ expectedhres = DISP_E_BADVARTYPE;
+ /* The following flags/types are invalid for left variant */
+ else if (!((leftvt <= VT_LPWSTR) && leftvt != (VARTYPE)15 &&
+ (leftvt < VT_VOID || leftvt > VT_LPWSTR)))
+ expectedhres = DISP_E_BADVARTYPE;
+ /* The following flags/types are invalid for right variant */
+ else if (!((rightvt <= VT_LPWSTR) && rightvt != (VARTYPE)15 &&
+ (rightvt < VT_VOID || rightvt > VT_LPWSTR)))
+ expectedhres = DISP_E_BADVARTYPE;
+ else if (leftvt == VT_I8 || rightvt == VT_I8)
+ {
+ if (rightvt == VT_INT || leftvt == VT_INT)
+ expectedhres = DISP_E_TYPEMISMATCH;
+ else
+ resvt = VT_I8;
+ }
+ else if (leftvt == VT_EMPTY || rightvt == VT_EMPTY)
+ {
+ if (leftvt == rightvt ||
+ leftvt == VT_I2 || rightvt == VT_I2 ||
+ leftvt == VT_UI1 || rightvt == VT_UI1 ||
+ leftvt == VT_BOOL || rightvt == VT_BOOL ||
+ leftvt == VT_NULL || rightvt == VT_NULL ||
+ leftvt == VT_BSTR || rightvt == VT_BSTR)
+ resvt = VT_I2;
+ else if (leftvt == VT_NULL || rightvt == VT_NULL)
+ resvt = VT_NULL;
+ else
+ resvt = VT_I4;
+ }
+ else if (leftvt == VT_NULL || rightvt == VT_NULL)
+ {
+ if (leftvt == rightvt || leftvt == VT_BSTR ||
+ rightvt == VT_BSTR)
+ resvt = VT_NULL;
+ else if (leftvt == VT_I2 || rightvt == VT_I2)
+ resvt = VT_I2;
+ else if (leftvt == VT_BOOL || rightvt == VT_BOOL)
+ resvt = VT_BOOL;
+ else if (leftvt == VT_UI1 || rightvt == VT_UI1)
+ resvt = VT_UI1;
+ else
+ resvt = VT_I4;
+ }
+ else if (leftvt == VT_UI1 || rightvt == VT_UI1)
+ {
+ if (leftvt == rightvt)
+ resvt = VT_UI1;
+ else if (leftvt == VT_I2 || rightvt == VT_I2 ||
+ leftvt == VT_BOOL || rightvt == VT_BOOL ||
+ leftvt == VT_BSTR || rightvt == VT_BSTR)
+ resvt = VT_I2;
+ else
+ resvt = VT_I4;
+ }
+ else if (leftvt == VT_I2 || rightvt == VT_I2)
+ {
+ if (leftvt == rightvt || leftvt == VT_BOOL ||
+ rightvt == VT_BOOL || leftvt == VT_BSTR ||
+ rightvt == VT_BSTR)
+ resvt = VT_I2;
+ else
+ resvt = VT_I4;
+ }
+ else if (leftvt == VT_BSTR || rightvt == VT_BSTR)
+ {
+ if (leftvt == rightvt || leftvt == VT_BOOL ||
+ rightvt == VT_BOOL)
+ resvt = VT_BOOL;
+ else
+ resvt = VT_I4;
+ }
+ else if (leftvt == VT_BOOL && rightvt == VT_BOOL)
+ resvt = VT_BOOL;
+ else
+ resvt = VT_I4;
+
+ hres = pVarAnd(&left, &right, &result);
+
+ /* Check if the expected HRESULT and result variant type is correct */
+ ok(hres == expectedhres && resvt == V_VT(&result),
+ "VarAnd: %s|0x%X, %s|0x%X: expected vt %s hr 0x%lX, got vt %s hr 0x%lX\n",
+ vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i], vtstr(resvt),
+ expectedhres, vtstr(V_VT(&result)), hres);
+ }
+ }
+ }
+
+ /*
+ * Test returned values. Since we know the returned type is correct
+ * and that we handle all combinations of invalid types, just check
+ * that good type combinations produce the desired value.
+ * FIXME: Test VT_DECIMAL/VT_DISPATCH
+ */
+ VARAND(EMPTY,0,EMPTY,0,I2,0);
+ VARAND(EMPTY,1,EMPTY,0,I2,0);
+ VARAND(EMPTY,1,EMPTY,1,I2,0);
+ VARAND(EMPTY,0,NULL,0,I2,0);
+ VARAND(EMPTY,1,NULL,0,I2,0);
+ VARAND(EMPTY,1,NULL,1,I2,0);
+ VARAND(EMPTY,0,I1,0,I4,0);
+ VARAND(EMPTY,0,I1,1,I4,0);
+ VARAND(EMPTY,1,I1,1,I4,0);
+ VARAND(EMPTY,0,UI1,0,I2,0);
+ VARAND(EMPTY,0,UI1,1,I2,0);
+ VARAND(EMPTY,1,UI1,1,I2,0);
+ VARAND(EMPTY,0,I2,0,I2,0);
+ VARAND(EMPTY,0,I2,1,I2,0);
+ VARAND(EMPTY,1,I2,1,I2,0);
+ VARAND(EMPTY,0,UI2,0,I4,0);
+ VARAND(EMPTY,0,UI2,1,I4,0);
+ VARAND(EMPTY,1,UI2,1,I4,0);
+ VARAND(EMPTY,0,I4,0,I4,0);
+ VARAND(EMPTY,0,I4,1,I4,0);
+ VARAND(EMPTY,1,I4,1,I4,0);
+ VARAND(EMPTY,0,UI4,0,I4,0);
+ VARAND(EMPTY,0,UI4,1,I4,0);
+ VARAND(EMPTY,1,UI4,1,I4,0);
+ if (HAVE_OLEAUT32_I8)
+ {
+ VARAND(EMPTY,0,I8,0,I8,0);
+ VARAND(EMPTY,0,I8,1,I8,0);
+ VARAND(EMPTY,1,I8,1,I8,0);
+ VARAND(EMPTY,0,UI8,0,I4,0);
+ VARAND(EMPTY,0,UI8,1,I4,0);
+ VARAND(EMPTY,1,UI8,1,I4,0);
+ }
+ VARAND(EMPTY,0,INT,0,I4,0);
+ VARAND(EMPTY,0,INT,1,I4,0);
+ VARAND(EMPTY,1,INT,1,I4,0);
+ VARAND(EMPTY,0,UINT,0,I4,0);
+ VARAND(EMPTY,0,UINT,1,I4,0);
+ VARAND(EMPTY,1,UINT,1,I4,0);
+ VARAND(EMPTY,0,BOOL,0,I2,0);
+ VARAND(EMPTY,0,BOOL,1,I2,0);
+ VARAND(EMPTY,1,BOOL,1,I2,0);
+ VARAND(EMPTY,0,R4,0,I4,0);
+ VARAND(EMPTY,0,R4,1,I4,0);
+ VARAND(EMPTY,1,R4,1,I4,0);
+ VARAND(EMPTY,0,R8,0,I4,0);
+ VARAND(EMPTY,0,R8,1,I4,0);
+ VARAND(EMPTY,1,R8,1,I4,0);
+ VARAND(EMPTY,0,BSTR,false_str,I2,0);
+ VARAND(EMPTY,0,BSTR,true_str,I2,0);
+ VARANDCY(EMPTY,0,10000,I4,0);
+
+ /* NULL OR 0 = NULL. NULL OR n = n */
+ VARAND(NULL,0,NULL,0,NULL,0);
+ VARAND(NULL,1,NULL,0,NULL,0);
+ VARAND(NULL,0,I1,0,I4,0);
+ VARAND(NULL,0,I1,1,NULL,0);
+ VARAND(NULL,0,UI1,0,UI1,0);
+ VARAND(NULL,0,UI1,1,NULL,0);
+ VARAND(NULL,0,I2,0,I2,0);
+ VARAND(NULL,0,I2,1,NULL,0);
+ VARAND(NULL,0,UI2,0,I4,0);
+ VARAND(NULL,0,UI2,1,NULL,0);
+ VARAND(NULL,0,I4,0,I4,0);
+ VARAND(NULL,0,I4,1,NULL,0);
+ VARAND(NULL,0,UI4,0,I4,0);
+ VARAND(NULL,0,UI4,1,NULL,0);
+ if (HAVE_OLEAUT32_I8)
+ {
+ VARAND(NULL,0,I8,0,I8,0);
+ VARAND(NULL,0,I8,1,NULL,0);
+ VARAND(NULL,0,UI8,0,I4,0);
+ VARAND(NULL,0,UI8,1,NULL,0);
+ }
+ VARAND(NULL,0,INT,0,I4,0);
+ VARAND(NULL,0,INT,1,NULL,0);
+ VARAND(NULL,0,UINT,0,I4,0);
+ VARAND(NULL,0,UINT,1,NULL,0);
+ VARAND(NULL,0,BOOL,0,BOOL,0);
+ VARAND(NULL,0,BOOL,1,NULL,0);
+ VARAND(NULL,0,R4,0,I4,0);
+ VARAND(NULL,0,R4,1,NULL,0);
+ VARAND(NULL,0,R8,0,I4,0);
+ VARAND(NULL,0,R8,1,NULL,0);
+ VARAND(NULL,0,BSTR,false_str,BOOL,0);
+ VARAND(NULL,0,BSTR,true_str,NULL,VARIANT_FALSE);
+ VARANDCY(NULL,0,10000,NULL,0);
+ VARANDCY(NULL,0,0,I4,0);
+
+ VARAND(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
+ VARAND(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE);
+ VARAND(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE);
+ VARAND(BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE);
+
+ /* Assume x,y & y,x are the same from now on to reduce the number of tests */
+ VARAND(BOOL,VARIANT_TRUE,I1,-1,I4,-1);
+ VARAND(BOOL,VARIANT_TRUE,I1,0,I4,0);
+ VARAND(BOOL,VARIANT_FALSE,I1,0,I4,0);
+ VARAND(BOOL,VARIANT_TRUE,UI1,255,I2,255);
+ VARAND(BOOL,VARIANT_TRUE,UI1,0,I2,0);
+ VARAND(BOOL,VARIANT_FALSE,UI1,0,I2,0);
+ VARAND(BOOL,VARIANT_TRUE,I2,-1,I2,-1);
+ VARAND(BOOL,VARIANT_TRUE,I2,0,I2,0);
+ VARAND(BOOL,VARIANT_FALSE,I2,0,I2,0);
+ VARAND(BOOL,VARIANT_TRUE,UI2,65535,I4,65535);
+ VARAND(BOOL,VARIANT_TRUE,UI2,0,I4,0);
+ VARAND(BOOL,VARIANT_FALSE,UI2,0,I4,0);
+ VARAND(BOOL,VARIANT_TRUE,I4,-1,I4,-1);
+ VARAND(BOOL,VARIANT_TRUE,I4,0,I4,0);
+ VARAND(BOOL,VARIANT_FALSE,I4,0,I4,0);
+ VARAND(BOOL,VARIANT_TRUE,UI4,0xffffffff,I4,-1);
+ VARAND(BOOL,VARIANT_TRUE,UI4,0,I4,0);
+ VARAND(BOOL,VARIANT_FALSE,UI4,0,I4,0);
+ VARAND(BOOL,VARIANT_TRUE,R4,-1,I4,-1);
+ VARAND(BOOL,VARIANT_TRUE,R4,0,I4,0);
+ VARAND(BOOL,VARIANT_FALSE,R4,0,I4,0);
+ VARAND(BOOL,VARIANT_TRUE,R8,-1,I4,-1);
+ VARAND(BOOL,VARIANT_TRUE,R8,0,I4,0);
+ VARAND(BOOL,VARIANT_FALSE,R8,0,I4,0);
+ VARAND(BOOL,VARIANT_TRUE,DATE,-1,I4,-1);
+ VARAND(BOOL,VARIANT_TRUE,DATE,0,I4,0);
+ VARAND(BOOL,VARIANT_FALSE,DATE,0,I4,0);
+ if (HAVE_OLEAUT32_I8)
+ {
+ VARAND(BOOL,VARIANT_TRUE,I8,-1,I8,-1);
+ VARAND(BOOL,VARIANT_TRUE,I8,0,I8,0);
+ VARAND(BOOL,VARIANT_FALSE,I8,0,I8,0);
+ VARAND(BOOL,VARIANT_TRUE,UI8,0,I4,0);
+ VARAND(BOOL,VARIANT_FALSE,UI8,0,I4,0);
+ }
+ VARAND(BOOL,VARIANT_TRUE,INT,-1,I4,-1);
+ VARAND(BOOL,VARIANT_TRUE,INT,0,I4,0);
+ VARAND(BOOL,VARIANT_FALSE,INT,0,I4,0);
+ VARAND(BOOL,VARIANT_TRUE,UINT,0xffffffff,I4,-1);
+ VARAND(BOOL,VARIANT_TRUE,UINT,0,I4,0);
+ VARAND(BOOL,VARIANT_FALSE,UINT,0,I4,0);
+ VARAND(BOOL,VARIANT_FALSE,BSTR,false_str,BOOL,VARIANT_FALSE);
+ VARAND(BOOL,VARIANT_TRUE,BSTR,false_str,BOOL,VARIANT_FALSE);
+ VARAND(BOOL,VARIANT_FALSE,BSTR,true_str,BOOL,VARIANT_FALSE);
+ VARAND(BOOL,VARIANT_TRUE,BSTR,true_str,BOOL,VARIANT_TRUE);
+ VARANDCY(BOOL,VARIANT_TRUE,10000,I4,1);
+ VARANDCY(BOOL,VARIANT_TRUE,0,I4,0);
+ VARANDCY(BOOL,VARIANT_FALSE,0,I4,0);
+
+ VARAND(I1,-1,I1,-1,I4,-1);
+ VARAND(I1,-1,I1,0,I4,0);
+ VARAND(I1,0,I1,0,I4,0);
+ VARAND(I1,-1,UI1,255,I4,255);
+ VARAND(I1,-1,UI1,0,I4,0);
+ VARAND(I1,0,UI1,0,I4,0);
+ VARAND(I1,-1,I2,-1,I4,-1);
+ VARAND(I1,-1,I2,0,I4,0);
+ VARAND(I1,0,I2,0,I4,0);
+ VARAND(I1,-1,UI2,65535,I4,65535);
+ VARAND(I1,-1,UI2,0,I4,0);
+ VARAND(I1,0,UI2,0,I4,0);
+ VARAND(I1,-1,I4,-1,I4,-1);
+ VARAND(I1,-1,I4,0,I4,0);
+ VARAND(I1,0,I4,0,I4,0);
+ VARAND(I1,-1,UI4,0xffffffff,I4,-1);
+ VARAND(I1,-1,UI4,0,I4,0);
+ VARAND(I1,0,UI4,0,I4,0);
+ VARAND(I1,-1,R4,-1,I4,-1);
+ VARAND(I1,-1,R4,0,I4,0);
+ VARAND(I1,0,R4,0,I4,0);
+ VARAND(I1,-1,R8,-1,I4,-1);
+ VARAND(I1,-1,R8,0,I4,0);
+ VARAND(I1,0,R8,0,I4,0);
+ VARAND(I1,-1,DATE,-1,I4,-1);
+ VARAND(I1,-1,DATE,0,I4,0);
+ VARAND(I1,0,DATE,0,I4,0);
+ if (HAVE_OLEAUT32_I8)
+ {
+ VARAND(I1,-1,I8,-1,I8,-1);
+ VARAND(I1,-1,I8,0,I8,0);
+ VARAND(I1,0,I8,0,I8,0);
+ VARAND(I1,-1,UI8,0,I4,0);
+ VARAND(I1,0,UI8,0,I4,0);
+ }
+ VARAND(I1,-1,INT,-1,I4,-1);
+ VARAND(I1,-1,INT,0,I4,0);
+ VARAND(I1,0,INT,0,I4,0);
+ VARAND(I1,-1,UINT,0xffffffff,I4,-1);
+ VARAND(I1,-1,UINT,0,I4,0);
+ VARAND(I1,0,UINT,0,I4,0);
+ VARAND(I1,0,BSTR,false_str,I4,0);
+ VARAND(I1,-1,BSTR,false_str,I4,0);
+ VARAND(I1,0,BSTR,true_str,I4,0);
+ VARAND(I1,-1,BSTR,true_str,I4,-1);
+ VARANDCY(I1,-1,10000,I4,1);
+ VARANDCY(I1,-1,0,I4,0);
+ VARANDCY(I1,0,0,I4,0);
+
+ VARAND(UI1,255,UI1,255,UI1,255);
+ VARAND(UI1,255,UI1,0,UI1,0);
+ VARAND(UI1,0,UI1,0,UI1,0);
+ VARAND(UI1,255,I2,-1,I2,255);
+ VARAND(UI1,255,I2,0,I2,0);
+ VARAND(UI1,0,I2,0,I2,0);
+ VARAND(UI1,255,UI2,65535,I4,255);
+ VARAND(UI1,255,UI2,0,I4,0);
+ VARAND(UI1,0,UI2,0,I4,0);
+ VARAND(UI1,255,I4,-1,I4,255);
+ VARAND(UI1,255,I4,0,I4,0);
+ VARAND(UI1,0,I4,0,I4,0);
+ VARAND(UI1,255,UI4,0xffffffff,I4,255);
+ VARAND(UI1,255,UI4,0,I4,0);
+ VARAND(UI1,0,UI4,0,I4,0);
+ VARAND(UI1,255,R4,-1,I4,255);
+ VARAND(UI1,255,R4,0,I4,0);
+ VARAND(UI1,0,R4,0,I4,0);
+ VARAND(UI1,255,R8,-1,I4,255);
+ VARAND(UI1,255,R8,0,I4,0);
+ VARAND(UI1,0,R8,0,I4,0);
+ VARAND(UI1,255,DATE,-1,I4,255);
+ VARAND(UI1,255,DATE,0,I4,0);
+ VARAND(UI1,0,DATE,0,I4,0);
+ if (HAVE_OLEAUT32_I8)
+ {
+ VARAND(UI1,255,I8,-1,I8,255);
+ VARAND(UI1,255,I8,0,I8,0);
+ VARAND(UI1,0,I8,0,I8,0);
+ VARAND(UI1,255,UI8,0,I4,0);
+ VARAND(UI1,0,UI8,0,I4,0);
+ }
+ VARAND(UI1,255,INT,-1,I4,255);
+ VARAND(UI1,255,INT,0,I4,0);
+ VARAND(UI1,0,INT,0,I4,0);
+ VARAND(UI1,255,UINT,0xffffffff,I4,255);
+ VARAND(UI1,255,UINT,0,I4,0);
+ VARAND(UI1,0,UINT,0,I4,0);
+ VARAND(UI1,0,BSTR,false_str,I2,0);
+ VARAND(UI1,255,BSTR,false_str,I2,0);
+ VARAND(UI1,0,BSTR,true_str,I2,0);
+ VARAND(UI1,255,BSTR,true_str,I2,255);
+ VARANDCY(UI1,255,10000,I4,1);
+ VARANDCY(UI1,255,0,I4,0);
+ VARANDCY(UI1,0,0,I4,0);
+
+ VARAND(I2,-1,I2,-1,I2,-1);
+ VARAND(I2,-1,I2,0,I2,0);
+ VARAND(I2,0,I2,0,I2,0);
+ VARAND(I2,-1,UI2,65535,I4,65535);
+ VARAND(I2,-1,UI2,0,I4,0);
+ VARAND(I2,0,UI2,0,I4,0);
+ VARAND(I2,-1,I4,-1,I4,-1);
+ VARAND(I2,-1,I4,0,I4,0);
+ VARAND(I2,0,I4,0,I4,0);
+ VARAND(I2,-1,UI4,0xffffffff,I4,-1);
+ VARAND(I2,-1,UI4,0,I4,0);
+ VARAND(I2,0,UI4,0,I4,0);
+ VARAND(I2,-1,R4,-1,I4,-1);
+ VARAND(I2,-1,R4,0,I4,0);
+ VARAND(I2,0,R4,0,I4,0);
+ VARAND(I2,-1,R8,-1,I4,-1);
+ VARAND(I2,-1,R8,0,I4,0);
+ VARAND(I2,0,R8,0,I4,0);
+ VARAND(I2,-1,DATE,-1,I4,-1);
+ VARAND(I2,-1,DATE,0,I4,0);
+ VARAND(I2,0,DATE,0,I4,0);
+ if (HAVE_OLEAUT32_I8)
+ {
+ VARAND(I2,-1,I8,-1,I8,-1);
+ VARAND(I2,-1,I8,0,I8,0);
+ VARAND(I2,0,I8,0,I8,0);
+ VARAND(I2,-1,UI8,0,I4,0);
+ VARAND(I2,0,UI8,0,I4,0);
+ }
+ VARAND(I2,-1,INT,-1,I4,-1);
+ VARAND(I2,-1,INT,0,I4,0);
+ VARAND(I2,0,INT,0,I4,0);
+ VARAND(I2,-1,UINT,0xffffffff,I4,-1);
+ VARAND(I2,-1,UINT,0,I4,0);
+ VARAND(I2,0,UINT,0,I4,0);
+ VARAND(I2,0,BSTR,false_str,I2,0);
+ VARAND(I2,-1,BSTR,false_str,I2,0);
+ VARAND(I2,0,BSTR,true_str,I2,0);
+ VARAND(I2,-1,BSTR,true_str,I2,-1);
+ VARANDCY(I2,-1,10000,I4,1);
+ VARANDCY(I2,-1,0,I4,0);
+ VARANDCY(I2,0,0,I4,0);
+
+ VARAND(UI2,65535,UI2,65535,I4,65535);
+ VARAND(UI2,65535,UI2,0,I4,0);
+ VARAND(UI2,0,UI2,0,I4,0);
+ VARAND(UI2,65535,I4,-1,I4,65535);
+ VARAND(UI2,65535,I4,0,I4,0);
+ VARAND(UI2,0,I4,0,I4,0);
+ VARAND(UI2,65535,UI4,0xffffffff,I4,65535);
+ VARAND(UI2,65535,UI4,0,I4,0);
+ VARAND(UI2,0,UI4,0,I4,0);
+ VARAND(UI2,65535,R4,-1,I4,65535);
+ VARAND(UI2,65535,R4,0,I4,0);
+ VARAND(UI2,0,R4,0,I4,0);
+ VARAND(UI2,65535,R8,-1,I4,65535);
+ VARAND(UI2,65535,R8,0,I4,0);
+ VARAND(UI2,0,R8,0,I4,0);
+ VARAND(UI2,65535,DATE,-1,I4,65535);
+ VARAND(UI2,65535,DATE,0,I4,0);
+ VARAND(UI2,0,DATE,0,I4,0);
+ if (HAVE_OLEAUT32_I8)
+ {
+ VARAND(UI2,65535,I8,-1,I8,65535);
+ VARAND(UI2,65535,I8,0,I8,0);
+ VARAND(UI2,0,I8,0,I8,0);
+ VARAND(UI2,65535,UI8,0,I4,0);
+ VARAND(UI2,0,UI8,0,I4,0);
+ }
+ VARAND(UI2,65535,INT,-1,I4,65535);
+ VARAND(UI2,65535,INT,0,I4,0);
+ VARAND(UI2,0,INT,0,I4,0);
+ VARAND(UI2,65535,UINT,0xffffffff,I4,65535);
+ VARAND(UI2,65535,UINT,0,I4,0);
+ VARAND(UI2,0,UINT,0,I4,0);
+ VARAND(UI2,0,BSTR,false_str,I4,0);
+ VARAND(UI2,65535,BSTR,false_str,I4,0);
+ VARAND(UI2,0,BSTR,true_str,I4,0);
+ VARAND(UI2,65535,BSTR,true_str,I4,65535);
+ VARANDCY(UI2,65535,10000,I4,1);
+ VARANDCY(UI2,65535,0,I4,0);
+ VARANDCY(UI2,0,0,I4,0);
+
+ VARAND(I4,-1,I4,-1,I4,-1);
+ VARAND(I4,-1,I4,0,I4,0);
+ VARAND(I4,0,I4,0,I4,0);
+ VARAND(I4,-1,UI4,0xffffffff,I4,-1);
+ VARAND(I4,-1,UI4,0,I4,0);
+ VARAND(I4,0,UI4,0,I4,0);
+ VARAND(I4,-1,R4,-1,I4,-1);
+ VARAND(I4,-1,R4,0,I4,0);
+ VARAND(I4,0,R4,0,I4,0);
+ VARAND(I4,-1,R8,-1,I4,-1);
+ VARAND(I4,-1,R8,0,I4,0);
+ VARAND(I4,0,R8,0,I4,0);
+ VARAND(I4,-1,DATE,-1,I4,-1);
+ VARAND(I4,-1,DATE,0,I4,0);
+ VARAND(I4,0,DATE,0,I4,0);
+ if (HAVE_OLEAUT32_I8)
+ {
+ VARAND(I4,-1,I8,-1,I8,-1);
+ VARAND(I4,-1,I8,0,I8,0);
+ VARAND(I4,0,I8,0,I8,0);
+ VARAND(I4,-1,UI8,0,I4,0);
+ VARAND(I4,0,UI8,0,I4,0);
+ }
+ VARAND(I4,-1,INT,-1,I4,-1);
+ VARAND(I4,-1,INT,0,I4,0);
+ VARAND(I4,0,INT,0,I4,0);
+ VARAND(I4,-1,UINT,0xffffffff,I4,-1);
+ VARAND(I4,-1,UINT,0,I4,0);
+ VARAND(I4,0,UINT,0,I4,0);
+ VARAND(I4,0,BSTR,false_str,I4,0);
+ VARAND(I4,-1,BSTR,false_str,I4,0);
+ VARAND(I4,0,BSTR,true_str,I4,0);
+ VARAND(I4,-1,BSTR,true_str,I4,-1);
+ VARANDCY(I4,-1,10000,I4,1);
+ VARANDCY(I4,-1,0,I4,0);
+ VARANDCY(I4,0,0,I4,0);
+
+ VARAND(UI4,0xffffffff,UI4,0xffffffff,I4,-1);
+ VARAND(UI4,0xffffffff,UI4,0,I4,0);
+ VARAND(UI4,0,UI4,0,I4,0);
+ VARAND(UI4,0xffffffff,R4,-1,I4,-1);
+ VARAND(UI4,0xffffffff,R4,0,I4,0);
+ VARAND(UI4,0,R4,0,I4,0);
+ VARAND(UI4,0xffffffff,R8,-1,I4,-1);
+ VARAND(UI4,0xffffffff,R8,0,I4,0);
+ VARAND(UI4,0,R8,0,I4,0);
+ VARAND(UI4,0xffffffff,DATE,-1,I4,-1);
+ VARAND(UI4,0xffffffff,DATE,0,I4,0);
+ VARAND(UI4,0,DATE,0,I4,0);
+ if (HAVE_OLEAUT32_I8)
+ {
+ VARAND(UI4,0xffffffff,I8,0,I8,0);
+ VARAND(UI4,0,I8,0,I8,0);
+ VARAND(UI4,0xffffffff,UI8,0,I4,0);
+ VARAND(UI4,0,UI8,0,I4,0);
+ }
+ VARAND(UI4,0xffffffff,INT,-1,I4,-1);
+ VARAND(UI4,0xffffffff,INT,0,I4,0);
+ VARAND(UI4,0,INT,0,I4,0);
+ VARAND(UI4,0xffffffff,UINT,0xffffffff,I4,-1);
+ VARAND(UI4,0xffffffff,UINT,0,I4,0);
+ VARAND(UI4,0,UINT,0,I4,0);
+ VARAND(UI4,0,BSTR,false_str,I4,0);
+ VARAND(UI4,0xffffffff,BSTR,false_str,I4,0);
+ VARAND(UI4,0,BSTR,true_str,I4,0);
+ VARAND(UI4,0xffffffff,BSTR,true_str,I4,-1);
+ VARANDCY(UI4,0xffffffff,10000,I4,1);
+ VARANDCY(UI4,0xffffffff,0,I4,0);
+ VARANDCY(UI4,0,0,I4,0);
+
+ VARAND(R4,-1,R4,-1,I4,-1);
+ VARAND(R4,-1,R4,0,I4,0);
+ VARAND(R4,0,R4,0,I4,0);
+ VARAND(R4,-1,R8,-1,I4,-1);
+ VARAND(R4,-1,R8,0,I4,0);
+ VARAND(R4,0,R8,0,I4,0);
+ VARAND(R4,-1,DATE,-1,I4,-1);
+ VARAND(R4,-1,DATE,0,I4,0);
+ VARAND(R4,0,DATE,0,I4,0);
+ if (HAVE_OLEAUT32_I8)
+ {
+ VARAND(R4,-1,I8,-1,I8,-1);
+ VARAND(R4,-1,I8,0,I8,0);
+ VARAND(R4,0,I8,0,I8,0);
+ VARAND(R4,-1,UI8,0,I4,0);
+ VARAND(R4,0,UI8,0,I4,0);
+ }
+ VARAND(R4,-1,INT,-1,I4,-1);
+ VARAND(R4,-1,INT,0,I4,0);
+ VARAND(R4,0,INT,0,I4,0);
+ VARAND(R4,-1,UINT,0xffffffff,I4,-1);
+ VARAND(R4,-1,UINT,0,I4,0);
+ VARAND(R4,0,UINT,0,I4,0);
+ VARAND(R4,0,BSTR,false_str,I4,0);
+ VARAND(R4,-1,BSTR,false_str,I4,0);
+ VARAND(R4,0,BSTR,true_str,I4,0);
+ VARAND(R4,-1,BSTR,true_str,I4,-1);
+ VARANDCY(R4,-1,10000,I4,1);
+ VARANDCY(R4,-1,0,I4,0);
+ VARANDCY(R4,0,0,I4,0);
+
+ VARAND(R8,-1,R8,-1,I4,-1);
+ VARAND(R8,-1,R8,0,I4,0);
+ VARAND(R8,0,R8,0,I4,0);
+ VARAND(R8,-1,DATE,-1,I4,-1);
+ VARAND(R8,-1,DATE,0,I4,0);
+ VARAND(R8,0,DATE,0,I4,0);
+ if (HAVE_OLEAUT32_I8)
+ {
+ VARAND(R8,-1,I8,-1,I8,-1);
+ VARAND(R8,-1,I8,0,I8,0);
+ VARAND(R8,0,I8,0,I8,0);
+ VARAND(R8,-1,UI8,0,I4,0);
+ VARAND(R8,0,UI8,0,I4,0);
+ }
+ VARAND(R8,-1,INT,-1,I4,-1);
+ VARAND(R8,-1,INT,0,I4,0);
+ VARAND(R8,0,INT,0,I4,0);
+ VARAND(R8,-1,UINT,0xffffffff,I4,-1);
+ VARAND(R8,-1,UINT,0,I4,0);
+ VARAND(R8,0,UINT,0,I4,0);
+ VARAND(R8,0,BSTR,false_str,I4,0);
+ VARAND(R8,-1,BSTR,false_str,I4,0);
+ VARAND(R8,0,BSTR,true_str,I4,0);
+ VARAND(R8,-1,BSTR,true_str,I4,-1);
+ VARANDCY(R8,-1,10000,I4,1);
+ VARANDCY(R8,-1,0,I4,0);
+ VARANDCY(R8,0,0,I4,0);
+
+ VARAND(DATE,-1,DATE,-1,I4,-1);
+ VARAND(DATE,-1,DATE,0,I4,0);
+ VARAND(DATE,0,DATE,0,I4,0);
+ if (HAVE_OLEAUT32_I8)
+ {
+ VARAND(DATE,-1,I8,-1,I8,-1);
+ VARAND(DATE,-1,I8,0,I8,0);
+ VARAND(DATE,0,I8,0,I8,0);
+ VARAND(DATE,-1,UI8,0,I4,0);
+ VARAND(DATE,0,UI8,0,I4,0);
+ }
+ VARAND(DATE,-1,INT,-1,I4,-1);
+ VARAND(DATE,-1,INT,0,I4,0);
+ VARAND(DATE,0,INT,0,I4,0);
+ VARAND(DATE,-1,UINT,0xffffffff,I4,-1);
+ VARAND(DATE,-1,UINT,0,I4,0);
+ VARAND(DATE,0,UINT,0,I4,0);
+ VARAND(DATE,0,BSTR,false_str,I4,0);
+ VARAND(DATE,-1,BSTR,false_str,I4,0);
+ VARAND(DATE,0,BSTR,true_str,I4,0);
+ VARAND(DATE,-1,BSTR,true_str,I4,-1);
+ VARANDCY(DATE,-1,10000,I4,1);
+ VARANDCY(DATE,-1,0,I4,0);
+ VARANDCY(DATE,0,0,I4,0);
+
+ if (HAVE_OLEAUT32_I8)
+ {
+ VARAND(I8,-1,I8,-1,I8,-1);
+ VARAND(I8,-1,I8,0,I8,0);
+ VARAND(I8,0,I8,0,I8,0);
+ VARAND(I8,-1,UI8,0,I8,0);
+ VARAND(I8,0,UI8,0,I8,0);
+ VARAND(I8,-1,UINT,0,I8,0);
+ VARAND(I8,0,UINT,0,I8,0);
+ VARAND(I8,0,BSTR,false_str,I8,0);
+ VARAND(I8,-1,BSTR,false_str,I8,0);
+ VARAND(I8,0,BSTR,true_str,I8,0);
+ VARAND(I8,-1,BSTR,true_str,I8,-1);
+ VARANDCY(I8,-1,10000,I8,1);
+ VARANDCY(I8,-1,0,I8,0);
+ VARANDCY(I8,0,0,I8,0);
+
+ VARAND(UI8,0xffff,UI8,0xffff,I4,0xffff);
+ VARAND(UI8,0xffff,UI8,0,I4,0);
+ VARAND(UI8,0,UI8,0,I4,0);
+ VARAND(UI8,0xffff,INT,-1,I4,65535);
+ VARAND(UI8,0xffff,INT,0,I4,0);
+ VARAND(UI8,0,INT,0,I4,0);
+ VARAND(UI8,0xffff,UINT,0xffff,I4,0xffff);
+ VARAND(UI8,0xffff,UINT,0,I4,0);
+ VARAND(UI8,0,UINT,0,I4,0);
+ VARAND(UI8,0,BSTR,false_str,I4,0);
+ VARAND(UI8,0xffff,BSTR,false_str,I4,0);
+ VARAND(UI8,0,BSTR,true_str,I4,0);
+ VARAND(UI8,0xffff,BSTR,true_str,I4,65535);
+ VARANDCY(UI8,0xffff,10000,I4,1);
+ VARANDCY(UI8,0xffff,0,I4,0);
+ VARANDCY(UI8,0,0,I4,0);
+ }
+
+ VARAND(INT,-1,INT,-1,I4,-1);
+ VARAND(INT,-1,INT,0,I4,0);
+ VARAND(INT,0,INT,0,I4,0);
+ VARAND(INT,-1,UINT,0xffff,I4,65535);
+ VARAND(INT,-1,UINT,0,I4,0);
+ VARAND(INT,0,UINT,0,I4,0);
+ VARAND(INT,0,BSTR,false_str,I4,0);
+ VARAND(INT,-1,BSTR,false_str,I4,0);
+ VARAND(INT,0,BSTR,true_str,I4,0);
+ VARAND(INT,-1,BSTR,true_str,I4,-1);
+ VARANDCY(INT,-1,10000,I4,1);
+ VARANDCY(INT,-1,0,I4,0);
+ VARANDCY(INT,0,0,I4,0);
+
+ VARAND(UINT,0xffff,UINT,0xffff,I4,0xffff);
+ VARAND(UINT,0xffff,UINT,0,I4,0);
+ VARAND(UINT,0,UINT,0,I4,0);
+ VARAND(UINT,0,BSTR,false_str,I4,0);
+ VARAND(UINT,0xffff,BSTR, false_str,I4,0);
+ VARAND(UINT,0,BSTR,true_str,I4,0);
+ VARAND(UINT,0xffff,BSTR,true_str,I4,65535);
+ VARANDCY(UINT,0xffff,10000,I4,1);
+ VARANDCY(UINT,0xffff,0,I4,0);
+ VARANDCY(UINT,0,0,I4,0);
+
+ VARAND(BSTR,false_str,BSTR,false_str,BOOL,0);
+ VARAND(BSTR,true_str,BSTR,false_str,BOOL,VARIANT_FALSE);
+ VARAND(BSTR,true_str,BSTR,true_str,BOOL,VARIANT_TRUE);
+ VARANDCY(BSTR,true_str,10000,I4,1);
+ VARANDCY(BSTR,false_str,10000,I4,0);
+
+ SysFreeString(true_str);
+ SysFreeString(false_str);
+}
+
static HRESULT (WINAPI *pVarCmp)(LPVARIANT,LPVARIANT,LCID,ULONG);
/* ERROR from wingdi.h is interfering here */
@@ -5581,4 +6328,5 @@ START_TEST(vartest)
test_VarAdd();
test_VarCat();
test_VarCmp();
+ test_VarAnd();
}
diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c
index 05fb764..b7114c9 100644
--- a/dlls/oleaut32/variant.c
+++ b/dlls/oleaut32/variant.c
@@ -2872,80 +2872,287 @@ #undef _VARCMP
*/
HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
{
- HRESULT rc = E_FAIL;
+ HRESULT hres = S_OK;
+ VARTYPE resvt = VT_EMPTY;
+ VARTYPE leftvt,rightvt;
+ VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
+ VARIANT varLeft, varRight;
+
+ VariantInit(&varLeft);
+ VariantInit(&varRight);
TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
- debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
+ debugstr_VF(left), right, debugstr_VT(right),
+ debugstr_VF(right), result);
- if ((V_VT(left)&VT_TYPEMASK) == VT_BOOL &&
- (V_VT(right)&VT_TYPEMASK) == VT_BOOL) {
+ leftvt = V_VT(left)&VT_TYPEMASK;
+ rightvt = V_VT(right)&VT_TYPEMASK;
+ leftExtraFlags = V_VT(left)&(~VT_TYPEMASK);
+ rightExtraFlags = V_VT(right)&(~VT_TYPEMASK);
- V_VT(result) = VT_BOOL;
- if (V_BOOL(left) && V_BOOL(right)) {
- V_BOOL(result) = VARIANT_TRUE;
- } else {
- V_BOOL(result) = VARIANT_FALSE;
- }
- rc = S_OK;
+ if (leftExtraFlags != rightExtraFlags)
+ return DISP_E_BADVARTYPE;
+ ExtraFlags = leftExtraFlags;
- } else {
- /* Integers */
- BOOL lOk = TRUE;
- BOOL rOk = TRUE;
- LONGLONG lVal = -1;
- LONGLONG rVal = -1;
- LONGLONG res = -1;
- int resT = 0; /* Testing has shown I2 & I2 == I2, all else
- becomes I4, even unsigned ints (incl. UI2) */
-
- lOk = TRUE;
- switch (V_VT(left)&VT_TYPEMASK) {
- case VT_I1 : lVal = V_I1(left); resT=VT_I4; break;
- case VT_I2 : lVal = V_I2(left); resT=VT_I2; break;
- case VT_I4 :
- case VT_INT : lVal = V_I4(left); resT=VT_I4; break;
- case VT_UI1 : lVal = V_UI1(left); resT=VT_I4; break;
- case VT_UI2 : lVal = V_UI2(left); resT=VT_I4; break;
- case VT_UI4 :
- case VT_UINT : lVal = V_UI4(left); resT=VT_I4; break;
- case VT_BOOL : rVal = V_BOOL(left); resT=VT_I4; break;
- default: lOk = FALSE;
+ /* All extra flags produce errors */
+ if (ExtraFlags == (VT_ARRAY|VT_BYREF) ||
+ ExtraFlags == (VT_BYREF) ||
+ ExtraFlags == (VT_ARRAY))
+ {
+ if ((leftvt >= VT_I2 && leftvt <= VT_DATE) ||
+ (leftvt >= VT_ERROR && leftvt <= VT_VARIANT) ||
+ leftvt == VT_DECIMAL || leftvt == VT_RECORD ||
+ (leftvt >= VT_I1 && leftvt <= VT_UI4) ||
+ leftvt == VT_INT || leftvt == VT_UINT ||
+ leftvt == VT_I8 || leftvt == VT_UI8 ||
+ leftvt == VT_BSTR)
+ hres = DISP_E_TYPEMISMATCH;
+ else
+ hres = DISP_E_BADVARTYPE;
+ }
+ else if (ExtraFlags)
+ hres = DISP_E_BADVARTYPE;
+ else if (leftvt == VT_ERROR || leftvt == VT_RECORD ||
+ leftvt == VT_VARIANT)
+ hres = DISP_E_TYPEMISMATCH;
+ else if (rightvt == VT_RECORD || rightvt == VT_VARIANT ||
+ rightvt == VT_ERROR)
+ {
+ if (leftvt == VT_EMPTY || leftvt == VT_NULL ||
+ leftvt == VT_I2 || leftvt == VT_I4 ||
+ leftvt == VT_R4 || leftvt == VT_R8 ||
+ leftvt == VT_CY || leftvt == VT_DATE ||
+ leftvt == VT_BOOL || leftvt == VT_DECIMAL ||
+ (leftvt >= VT_I1 && leftvt <= VT_UI4) ||
+ leftvt == VT_INT || leftvt == VT_UINT ||
+ leftvt == VT_I8 || leftvt == VT_UI8 ||
+ leftvt == VT_BSTR)
+ hres = DISP_E_TYPEMISMATCH;
+ else
+ hres = DISP_E_BADVARTYPE;
+ }
+ else if (leftvt == VT_CLSID || rightvt == VT_CLSID)
+ hres = DISP_E_BADVARTYPE;
+ /* The following types are invalid for left variant */
+ else if (!((leftvt <= VT_LPWSTR) && leftvt != (VARTYPE)15 &&
+ (leftvt < VT_VOID || leftvt > VT_LPWSTR)))
+ hres = DISP_E_BADVARTYPE;
+ /* The following types are invalid for right variant */
+ else if (!((rightvt <= VT_LPWSTR) && rightvt != (VARTYPE)15 &&
+ (rightvt < VT_VOID || rightvt > VT_LPWSTR)))
+ hres = DISP_E_BADVARTYPE;
+ else if (leftvt == VT_I8 || rightvt == VT_I8)
+ {
+ if (rightvt == VT_INT || leftvt == VT_INT)
+ hres = DISP_E_TYPEMISMATCH;
+ else
+ resvt = VT_I8;
+ }
+ else if (leftvt == VT_EMPTY || rightvt == VT_EMPTY)
+ {
+ if (leftvt == rightvt ||
+ leftvt == VT_I2 || rightvt == VT_I2 ||
+ leftvt == VT_UI1 || rightvt == VT_UI1 ||
+ leftvt == VT_BOOL || rightvt == VT_BOOL ||
+ leftvt == VT_NULL || rightvt == VT_NULL ||
+ leftvt == VT_BSTR || rightvt == VT_BSTR)
+ resvt = VT_I2;
+ else if (leftvt == VT_NULL || rightvt == VT_NULL)
+ resvt = VT_NULL;
+ else
+ resvt = VT_I4;
+ }
+ else if (leftvt == VT_NULL || rightvt == VT_NULL)
+ {
+ if (leftvt == rightvt || leftvt == VT_BSTR ||
+ rightvt == VT_BSTR)
+ resvt = VT_NULL;
+ else if (leftvt == VT_I2 || rightvt == VT_I2)
+ resvt = VT_I2;
+ else if (leftvt == VT_BOOL || rightvt == VT_BOOL)
+ resvt = VT_BOOL;
+ else if (leftvt == VT_UI1 || rightvt == VT_UI1)
+ resvt = VT_UI1;
+ else
+ resvt = VT_I4;
+ }
+ else if (leftvt == VT_UI1 || rightvt == VT_UI1)
+ {
+ if (leftvt == rightvt)
+ resvt = VT_UI1;
+ else if (leftvt == VT_I2 || rightvt == VT_I2 ||
+ leftvt == VT_BOOL || rightvt == VT_BOOL ||
+ leftvt == VT_BSTR || rightvt == VT_BSTR)
+ resvt = VT_I2;
+ else
+ resvt = VT_I4;
+ }
+ else if (leftvt == VT_I2 || rightvt == VT_I2)
+ {
+ if (leftvt == rightvt || leftvt == VT_BOOL ||
+ rightvt == VT_BOOL || leftvt == VT_BSTR ||
+ rightvt == VT_BSTR)
+ resvt = VT_I2;
+ else
+ resvt = VT_I4;
+ }
+ else if (leftvt == VT_BSTR || rightvt == VT_BSTR)
+ {
+ if (leftvt == rightvt || leftvt == VT_BOOL ||
+ rightvt == VT_BOOL)
+ resvt = VT_BOOL;
+ else
+ resvt = VT_I4;
+ }
+ else if (leftvt == VT_BOOL && rightvt == VT_BOOL)
+ resvt = VT_BOOL;
+ else
+ resvt = VT_I4;
+
+ /* no need to go further if returning an error */
+ if (hres != S_OK) {
+ V_VT(result) = resvt;
+ return hres;
+ }
+ else
+ {
+ if (leftvt == VT_BOOL && rightvt == VT_BOOL)
+ {
+ V_VT(result) = VT_BOOL;
+ if (V_BOOL(left) == VARIANT_TRUE &&
+ V_BOOL(right) == VARIANT_TRUE)
+ V_BOOL(result) = VARIANT_TRUE;
+ else
+ V_BOOL(result) = VARIANT_FALSE;
+ return S_OK;
}
- rOk = TRUE;
- switch (V_VT(right)&VT_TYPEMASK) {
- case VT_I1 : rVal = V_I1(right); resT=VT_I4; break;
- case VT_I2 : rVal = V_I2(right); resT=max(VT_I2, resT); break;
- case VT_I4 :
- case VT_INT : rVal = V_I4(right); resT=VT_I4; break;
- case VT_UI1 : rVal = V_UI1(right); resT=VT_I4; break;
- case VT_UI2 : rVal = V_UI2(right); resT=VT_I4; break;
- case VT_UI4 :
- case VT_UINT : rVal = V_UI4(right); resT=VT_I4; break;
- case VT_BOOL : rVal = V_BOOL(right); resT=VT_I4; break;
- default: rOk = FALSE;
+ if(leftvt == VT_EMPTY || rightvt == VT_EMPTY)
+ {
+ V_VT(result) = resvt;
+ return S_OK;
}
- if (lOk && rOk) {
- res = (lVal & rVal);
- V_VT(result) = resT;
- switch (resT) {
- case VT_I2 : V_I2(result) = res; break;
- case VT_I4 : V_I4(result) = res; break;
- default:
- FIXME("Unexpected result variant type %x\n", resT);
- V_I4(result) = res;
+ if (leftvt == VT_NULL || rightvt == VT_NULL)
+ {
+ /*
+ * Special cases for when left variant is VT_NULL
+ * (NULL & 0 = NULL, NULL & value = value)
+ */
+ if (leftvt == VT_NULL)
+ {
+ VARIANT_BOOL b;
+ switch(rightvt)
+ {
+ case VT_I1: if (V_I1(right)) resvt = VT_NULL; break;
+ case VT_UI1: if (V_UI1(right)) resvt = VT_NULL; break;
+ case VT_I2: if (V_I2(right)) resvt = VT_NULL; break;
+ case VT_UI2: if (V_UI2(right)) resvt = VT_NULL; break;
+ case VT_I4: if (V_I4(right)) resvt = VT_NULL; break;
+ case VT_UI4: if (V_UI4(right)) resvt = VT_NULL; break;
+ case VT_I8: if (V_I8(right)) resvt = VT_NULL; break;
+ case VT_UI8: if (V_UI8(right)) resvt = VT_NULL; break;
+ case VT_INT: if (V_INT(right)) resvt = VT_NULL; break;
+ case VT_UINT: if (V_UINT(right)) resvt = VT_NULL; break;
+ case VT_BOOL: if (V_BOOL(right)) resvt = VT_NULL; break;
+ case VT_R4: if (V_R4(right)) resvt = VT_NULL; break;
+ case VT_R8: if (V_R8(right)) resvt = VT_NULL; break;
+ case VT_CY:
+ if(V_CY(right).int64)
+ resvt = VT_NULL;
+ break;
+ case VT_DECIMAL:
+ if(DEC_HI32(&V_DECIMAL(right)) ||
+ DEC_LO64(&V_DECIMAL(right)))
+ resvt = VT_NULL;
+ break;
+ case VT_BSTR:
+ hres = VarBoolFromStr(V_BSTR(right),
+ LOCALE_USER_DEFAULT, VAR_LOCALBOOL, &b);
+ if (FAILED(hres))
+ return hres;
+ else if (b)
+ V_VT(result) = VT_NULL;
+ else
+ {
+ V_VT(result) = VT_BOOL;
+ V_BOOL(result) = b;
+ }
+ goto VarAnd_Exit;
+ }
}
- rc = S_OK;
+ V_VT(result) = resvt;
+ goto VarAnd_Exit;
+ }
- } else {
- FIXME("VarAnd stub\n");
+ hres = VariantCopy(&varLeft, left);
+ if (FAILED(hres)) goto VarAnd_Exit;
+
+ hres = VariantCopy(&varRight, right);
+ if (FAILED(hres)) goto VarAnd_Exit;
+
+ if (resvt == VT_I4 && V_VT(&varLeft) == VT_UI4)
+ V_VT(&varLeft) = VT_I4; /* Don't overflow */
+ else
+ {
+ double d;
+
+ if (V_VT(&varLeft) == VT_BSTR &&
+ FAILED(VarR8FromStr(V_BSTR(&varLeft),
+ LOCALE_USER_DEFAULT, 0, &d)))
+ hres = VariantChangeType(&varLeft,&varLeft,
+ VARIANT_LOCALBOOL, VT_BOOL);
+ if (SUCCEEDED(hres) && V_VT(&varLeft) != resvt)
+ hres = VariantChangeType(&varLeft,&varLeft,0,resvt);
+ if (FAILED(hres)) goto VarAnd_Exit;
+ }
+
+ if (resvt == VT_I4 && V_VT(&varRight) == VT_UI4)
+ V_VT(&varRight) = VT_I4; /* Don't overflow */
+ else
+ {
+ double d;
+
+ if (V_VT(&varRight) == VT_BSTR &&
+ FAILED(VarR8FromStr(V_BSTR(&varRight),
+ LOCALE_USER_DEFAULT, 0, &d)))
+ hres = VariantChangeType(&varRight, &varRight,
+ VARIANT_LOCALBOOL, VT_BOOL);
+ if (SUCCEEDED(hres) && V_VT(&varRight) != resvt)
+ hres = VariantChangeType(&varRight, &varRight, 0, resvt);
+ if (FAILED(hres)) goto VarAnd_Exit;
+ }
+
+ V_VT(result) = resvt;
+ switch(resvt)
+ {
+ case VT_I8:
+ V_I8(result) = V_I8(&varLeft) & V_I8(&varRight);
+ break;
+ case VT_I4:
+ V_I4(result) = V_I4(&varLeft) & V_I4(&varRight);
+ break;
+ case VT_I2:
+ V_I2(result) = V_I2(&varLeft) & V_I2(&varRight);
+ break;
+ case VT_UI1:
+ V_UI1(result) = V_UI1(&varLeft) & V_UI1(&varRight);
+ break;
+ case VT_BOOL:
+ V_BOOL(result) = V_BOOL(&varLeft) & V_BOOL(&varRight);
+ break;
+ default:
+ FIXME("Couldn't bitwise AND variant types %d,%d\n",
+ leftvt,rightvt);
}
}
- TRACE("returning 0x%8lx (%s%s),%ld\n", rc, debugstr_VT(result),
- debugstr_VF(result), V_VT(result) == VT_I4 ? V_I4(result) : V_I2(result));
- return rc;
+VarAnd_Exit:
+
+ VariantClear(&varLeft);
+ VariantClear(&varRight);
+
+ return hres;
}
/**********************************************************************
--
1.4.0
More information about the wine-patches
mailing list