oleaut32 2/3: [RESEND] Updates variant:VarAnd to pass all failures exposed from conformance test

Benjamin Arai me at benjaminarai.com
Tue Aug 29 19:50:05 CDT 2006


Hi,

I attached the correct patch this time.

ChangeLog:
 - Removes all todo_wine's in VarAnd conformance test
 - Fixes VarAnd to pass all tests in Windows XP SP2 and Wine

---
 dlls/oleaut32/tests/vartest.c |   78 ----------
 dlls/oleaut32/variant.c       |  327 +++++++++++++++++++++++++++++++++--------
 2 files changed, 269 insertions(+), 136 deletions(-)

Copyright: Google
License: LGPL
-- 
Benjamin Arai
http://www.benjaminarai.com
-------------- next part --------------

diff --git a/dlls/oleaut32/tests/vartest.c b/dlls/oleaut32/tests/vartest.c
index b738199..7e0bf78 100644
--- a/dlls/oleaut32/tests/vartest.c
+++ b/dlls/oleaut32/tests/vartest.c
@@ -5325,7 +5325,6 @@ static void test_VarAnd(void)
      * that good type combinations produce the desired value.
      * FIXME: Test VT_DECIMAL/VT_DISPATCH
      */
-    todo_wine {
     VARAND(EMPTY,0,EMPTY,0,I2,0);
     VARAND(EMPTY,1,EMPTY,0,I2,0);
     VARAND(EMPTY,1,EMPTY,1,I2,0);
@@ -5350,19 +5349,15 @@ static void test_VarAnd(void)
     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)
     {
-        todo_wine {
         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);
-        }
     }
-    todo_wine {
     VARAND(EMPTY,0,INT,0,I4,0);
     VARAND(EMPTY,0,INT,1,I4,0);
     VARAND(EMPTY,1,INT,1,I4,0);
@@ -5381,10 +5376,8 @@ static void test_VarAnd(void)
     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 */
-    todo_wine {
     VARAND(NULL,0,NULL,0,NULL,0);
     VARAND(NULL,1,NULL,0,NULL,0);
     VARAND(NULL,0,I1,0,I4,0);
@@ -5399,17 +5392,13 @@ static void test_VarAnd(void)
     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)
     {
-        todo_wine {
         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);
-        }
     }
-    todo_wine {
     VARAND(NULL,0,INT,0,I4,0);
     VARAND(NULL,0,INT,1,NULL,0);
     VARAND(NULL,0,UINT,0,I4,0);
@@ -5424,7 +5413,7 @@ static void test_VarAnd(void)
     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);
@@ -5434,14 +5423,12 @@ static void test_VarAnd(void)
     VARAND(BOOL,VARIANT_TRUE,I1,-1,I4,-1);
     VARAND(BOOL,VARIANT_TRUE,I1,0,I4,0);
     VARAND(BOOL,VARIANT_FALSE,I1,0,I4,0);
-    todo_wine {
     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);
@@ -5451,7 +5438,6 @@ static void test_VarAnd(void)
     VARAND(BOOL,VARIANT_TRUE,UI4,0xffffffff,I4,-1);
     VARAND(BOOL,VARIANT_TRUE,UI4,0,I4,0);
     VARAND(BOOL,VARIANT_FALSE,UI4,0,I4,0);
-    todo_wine {
     VARAND(BOOL,VARIANT_TRUE,R4,-1,I4,-1);
     VARAND(BOOL,VARIANT_TRUE,R4,0,I4,0);
     VARAND(BOOL,VARIANT_FALSE,R4,0,I4,0);
@@ -5461,16 +5447,13 @@ static void test_VarAnd(void)
     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)
     {
-        todo_wine {
         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);
@@ -5478,7 +5461,6 @@ static void test_VarAnd(void)
     VARAND(BOOL,VARIANT_TRUE,UINT,0xffffffff,I4,-1);
     VARAND(BOOL,VARIANT_TRUE,UINT,0,I4,0);
     VARAND(BOOL,VARIANT_FALSE,UINT,0,I4,0);
-    todo_wine {
     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);
@@ -5486,7 +5468,7 @@ static void test_VarAnd(void)
     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);
@@ -5505,7 +5487,6 @@ static void test_VarAnd(void)
     VARAND(I1,-1,UI4,0xffffffff,I4,-1);
     VARAND(I1,-1,UI4,0,I4,0);
     VARAND(I1,0,UI4,0,I4,0);
-    todo_wine {
     VARAND(I1,-1,R4,-1,I4,-1);
     VARAND(I1,-1,R4,0,I4,0);
     VARAND(I1,0,R4,0,I4,0);
@@ -5515,16 +5496,13 @@ static void test_VarAnd(void)
     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)
     {
-        todo_wine {
         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);
@@ -5532,7 +5510,6 @@ static void test_VarAnd(void)
     VARAND(I1,-1,UINT,0xffffffff,I4,-1);
     VARAND(I1,-1,UINT,0,I4,0);
     VARAND(I1,0,UINT,0,I4,0);
-    todo_wine {
     VARAND(I1,0,BSTR,false_str,I4,0);
     VARAND(I1,-1,BSTR,false_str,I4,0);
     VARAND(I1,0,BSTR,true_str,I4,0);
@@ -5547,7 +5524,6 @@ static void test_VarAnd(void)
     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);
@@ -5557,7 +5533,6 @@ static void test_VarAnd(void)
     VARAND(UI1,255,UI4,0xffffffff,I4,255);
     VARAND(UI1,255,UI4,0,I4,0);
     VARAND(UI1,0,UI4,0,I4,0);
-    todo_wine {
     VARAND(UI1,255,R4,-1,I4,255);
     VARAND(UI1,255,R4,0,I4,0);
     VARAND(UI1,0,R4,0,I4,0);
@@ -5567,16 +5542,13 @@ static void test_VarAnd(void)
     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)
     {
-        todo_wine {
         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);
@@ -5584,7 +5556,6 @@ static void test_VarAnd(void)
     VARAND(UI1,255,UINT,0xffffffff,I4,255);
     VARAND(UI1,255,UINT,0,I4,0);
     VARAND(UI1,0,UINT,0,I4,0);
-    todo_wine {
     VARAND(UI1,0,BSTR,false_str,I2,0);
     VARAND(UI1,255,BSTR,false_str,I2,0);
     VARAND(UI1,0,BSTR,true_str,I2,0);
@@ -5592,7 +5563,6 @@ static void test_VarAnd(void)
     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);
@@ -5606,7 +5576,6 @@ static void test_VarAnd(void)
     VARAND(I2,-1,UI4,0xffffffff,I4,-1);
     VARAND(I2,-1,UI4,0,I4,0);
     VARAND(I2,0,UI4,0,I4,0);
-    todo_wine {
     VARAND(I2,-1,R4,-1,I4,-1);
     VARAND(I2,-1,R4,0,I4,0);
     VARAND(I2,0,R4,0,I4,0);
@@ -5616,16 +5585,13 @@ static void test_VarAnd(void)
     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)
     {
-        todo_wine {
         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);
@@ -5633,7 +5599,6 @@ static void test_VarAnd(void)
     VARAND(I2,-1,UINT,0xffffffff,I4,-1);
     VARAND(I2,-1,UINT,0,I4,0);
     VARAND(I2,0,UINT,0,I4,0);
-    todo_wine {
     VARAND(I2,0,BSTR,false_str,I2,0);
     VARAND(I2,-1,BSTR,false_str,I2,0);
     VARAND(I2,0,BSTR,true_str,I2,0);
@@ -5641,7 +5606,6 @@ static void test_VarAnd(void)
     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);
@@ -5652,7 +5616,6 @@ static void test_VarAnd(void)
     VARAND(UI2,65535,UI4,0xffffffff,I4,65535);
     VARAND(UI2,65535,UI4,0,I4,0);
     VARAND(UI2,0,UI4,0,I4,0);
-    todo_wine {
     VARAND(UI2,65535,R4,-1,I4,65535);
     VARAND(UI2,65535,R4,0,I4,0);
     VARAND(UI2,0,R4,0,I4,0);
@@ -5662,16 +5625,13 @@ static void test_VarAnd(void)
     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)
     {
-        todo_wine {
         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);
@@ -5679,7 +5639,6 @@ static void test_VarAnd(void)
     VARAND(UI2,65535,UINT,0xffffffff,I4,65535);
     VARAND(UI2,65535,UINT,0,I4,0);
     VARAND(UI2,0,UINT,0,I4,0);
-    todo_wine {
     VARAND(UI2,0,BSTR,false_str,I4,0);
     VARAND(UI2,65535,BSTR,false_str,I4,0);
     VARAND(UI2,0,BSTR,true_str,I4,0);
@@ -5687,7 +5646,6 @@ static void test_VarAnd(void)
     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);
@@ -5695,7 +5653,6 @@ static void test_VarAnd(void)
     VARAND(I4,-1,UI4,0xffffffff,I4,-1);
     VARAND(I4,-1,UI4,0,I4,0);
     VARAND(I4,0,UI4,0,I4,0);
-    todo_wine {
     VARAND(I4,-1,R4,-1,I4,-1);
     VARAND(I4,-1,R4,0,I4,0);
     VARAND(I4,0,R4,0,I4,0);
@@ -5705,16 +5662,13 @@ static void test_VarAnd(void)
     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)
     {
-        todo_wine {
         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);
@@ -5722,7 +5676,6 @@ static void test_VarAnd(void)
     VARAND(I4,-1,UINT,0xffffffff,I4,-1);
     VARAND(I4,-1,UINT,0,I4,0);
     VARAND(I4,0,UINT,0,I4,0);
-    todo_wine {
     VARAND(I4,0,BSTR,false_str,I4,0);
     VARAND(I4,-1,BSTR,false_str,I4,0);
     VARAND(I4,0,BSTR,true_str,I4,0);
@@ -5730,12 +5683,10 @@ static void test_VarAnd(void)
     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);
-    todo_wine {
     VARAND(UI4,0xffffffff,R4,-1,I4,-1);
     VARAND(UI4,0xffffffff,R4,0,I4,0);
     VARAND(UI4,0,R4,0,I4,0);
@@ -5745,15 +5696,12 @@ static void test_VarAnd(void)
     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)
     {
-        todo_wine {
         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);
@@ -5761,7 +5709,6 @@ static void test_VarAnd(void)
     VARAND(UI4,0xffffffff,UINT,0xffffffff,I4,-1);
     VARAND(UI4,0xffffffff,UINT,0,I4,0);
     VARAND(UI4,0,UINT,0,I4,0);
-    todo_wine {
     VARAND(UI4,0,BSTR,false_str,I4,0);
     VARAND(UI4,0xffffffff,BSTR,false_str,I4,0);
     VARAND(UI4,0,BSTR,true_str,I4,0);
@@ -5779,18 +5726,14 @@ static void test_VarAnd(void)
     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)
     {
-        todo_wine {
         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);
-        }
     }
-    todo_wine {
     VARAND(R4,-1,INT,-1,I4,-1);
     VARAND(R4,-1,INT,0,I4,0);
     VARAND(R4,0,INT,0,I4,0);
@@ -5811,18 +5754,14 @@ static void test_VarAnd(void)
     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)
     {
-        todo_wine {
         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);
-        }
     }
-    todo_wine {
     VARAND(R8,-1,INT,-1,I4,-1);
     VARAND(R8,-1,INT,0,I4,0);
     VARAND(R8,0,INT,0,I4,0);
@@ -5836,24 +5775,18 @@ static void test_VarAnd(void)
     VARANDCY(R8,-1,10000,I4,1);
     VARANDCY(R8,-1,0,I4,0);
     VARANDCY(R8,0,0,I4,0);
-    }
 
-    todo_wine {
     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)
     {
-        todo_wine {
         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);
-        }
     }
-    todo_wine {
     VARAND(DATE,-1,INT,-1,I4,-1);
     VARAND(DATE,-1,INT,0,I4,0);
     VARAND(DATE,0,INT,0,I4,0);
@@ -5867,11 +5800,9 @@ static void test_VarAnd(void)
     VARANDCY(DATE,-1,10000,I4,1);
     VARANDCY(DATE,-1,0,I4,0);
     VARANDCY(DATE,0,0,I4,0);
-    }
 
     if (HAVE_OLEAUT32_I8)
     {
-        todo_wine {
         VARAND(I8,-1,I8,-1,I8,-1);
         VARAND(I8,-1,I8,0,I8,0);
         VARAND(I8,0,I8,0,I8,0);
@@ -5903,7 +5834,6 @@ static void test_VarAnd(void)
         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);
@@ -5912,7 +5842,6 @@ static void test_VarAnd(void)
     VARAND(INT,-1,UINT,0xffff,I4,65535);
     VARAND(INT,-1,UINT,0,I4,0);
     VARAND(INT,0,UINT,0,I4,0);
-    todo_wine {
     VARAND(INT,0,BSTR,false_str,I4,0);
     VARAND(INT,-1,BSTR,false_str,I4,0);
     VARAND(INT,0,BSTR,true_str,I4,0);
@@ -5920,12 +5849,10 @@ static void test_VarAnd(void)
     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);
-    todo_wine {
     VARAND(UINT,0,BSTR,false_str,I4,0);
     VARAND(UINT,0xffff,BSTR, false_str,I4,0);
     VARAND(UINT,0,BSTR,true_str,I4,0);
@@ -5939,7 +5866,6 @@ static void test_VarAnd(void)
     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);
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