Implement A->W call for GetNamedSecurityInfo.
[wine] / dlls / oleaut32 / tests / vartest.c
1 /*
2  * VARIANT test program
3  *
4  * Copyright 1998 Jean-Claude Cote
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <math.h>
25 #include <float.h>
26 #include <time.h>
27
28 #define NONAMELESSUNION
29 #define NONAMELESSSTRUCT
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winsock.h"
33 #include "wine/test.h"
34 #include "winuser.h"
35 #include "wingdi.h"
36 #include "winnls.h"
37 #include "winerror.h"
38 #include "winnt.h"
39
40 #include "wtypes.h"
41 #include "oleauto.h"
42
43 static HMODULE hOleaut32;
44
45 static HRESULT (WINAPI *pVarUdateFromDate)(DATE,ULONG,UDATE*);
46 static HRESULT (WINAPI *pVarDateFromUdate)(UDATE*,ULONG,DATE*);
47 static INT (WINAPI *pSystemTimeToVariantTime)(LPSYSTEMTIME,double*);
48 static INT (WINAPI *pVariantTimeToSystemTime)(double,LPSYSTEMTIME);
49 static INT (WINAPI *pDosDateTimeToVariantTime)(USHORT,USHORT,double*);
50 static INT (WINAPI *pVariantTimeToDosDateTime)(double,USHORT*,USHORT *);
51 static HRESULT (WINAPI *pVarFormatNumber)(LPVARIANT,int,int,int,int,ULONG,BSTR*);
52 static HRESULT (WINAPI *pVarFormat)(LPVARIANT,LPOLESTR,int,int,ULONG,BSTR*);
53
54 /* Get a conversion function ptr, return if function not available */
55 #define CHECKPTR(func) p##func = (void*)GetProcAddress(hOleaut32, #func); \
56   if (!p##func) { trace("function " # func " not available, not testing it\n"); return; }
57
58   /* Is a given function exported from oleaut32? */
59 #define HAVE_FUNC(func) ((void*)GetProcAddress(hOleaut32, #func) != NULL)
60
61 /* Have IRecordInfo data type? */
62 #define HAVE_OLEAUT32_RECORD  HAVE_FUNC(SafeArraySetRecordInfo)
63 /* Have CY data type? */
64 #define HAVE_OLEAUT32_CY      HAVE_FUNC(VarCyAdd)
65 /* Have I8/UI8 data type? */
66 #define HAVE_OLEAUT32_I8      HAVE_FUNC(VarI8FromI1)
67 /* Is this an ancient version with support for only I2/I4/R4/R8/DATE? */
68 #define IS_ANCIENT (!HAVE_FUNC(VarI1FromI2))
69 /* Is vt a type unavailable to ancient versions? */
70 #define IS_MODERN_VTYPE(vt) (vt==VT_VARIANT||vt==VT_DECIMAL|| \
71     vt==VT_I1||vt==VT_UI2||vt==VT_UI4||vt == VT_INT||vt == VT_UINT)
72
73 /* When comparing floating point values we cannot expect an exact match
74  * because the rounding errors depend on the exact algorithm.
75  */
76 #define EQ_DOUBLE(a,b)     (fabs((a)-(b))<1e-14)
77
78 #define SKIPTESTS(a)  if((a > VT_CLSID+10) && (a < VT_BSTR_BLOB-10)) continue;
79
80 /* Allow our test macros to work for VT_NULL and VT_EMPTY too */
81 #define V_EMPTY(v) V_I4(v)
82 #define V_NULL(v) V_I4(v)
83
84 static inline int strcmpW( const WCHAR *str1, const WCHAR *str2 )
85 {
86     while (*str1 && (*str1 == *str2)) { str1++; str2++; }
87     return *str1 - *str2;
88 }
89
90 /* return the string text of a given variant type */
91 char *vtstr(int x)
92 {
93         switch(x) {
94         case 0:
95                 return "VT_EMPTY";
96         case 1:
97                 return "VT_NULL";
98         case 2:
99                 return "VT_I2";
100         case 3:
101                 return "VT_I4";
102         case 4:
103                 return "VT_R4";
104         case 5:
105                 return "VT_R8";
106         case 6:
107                 return "VT_CY";
108         case 7:
109                 return "VT_DATE";
110         case 8:
111                 return "VT_BSTR";
112         case 9:
113                 return "VT_DISPATCH";
114         case 10:
115                 return "VT_ERROR";
116         case 11:
117                 return "VT_BOOL";
118         case 12:
119                 return "VT_VARIANT";
120         case 13:
121                 return "VT_UNKNOWN";
122         case 14:
123                 return "VT_DECIMAL";
124         case 15:
125                 return "notdefined";
126         case 16:
127                 return "VT_I1";
128         case 17:
129                 return "VT_UI1";
130         case 18:
131                 return "VT_UI2";
132         case 19:
133                 return "VT_UI4";
134         case 20:
135                 return "VT_I8";
136         case 21:
137                 return "VT_UI8";
138         case 22:
139                 return "VT_INT";
140         case 23:
141                 return "VT_UINT";
142         case 24:
143                 return "VT_VOID";
144         case 25:
145                 return "VT_HRESULT";
146         case 26:
147                 return "VT_PTR";
148         case 27:
149                 return "VT_SAFEARRAY";
150         case 28:
151                 return "VT_CARRAY";
152         case 29:
153                 return "VT_USERDEFINED";
154         case 30:
155                 return "VT_LPSTR";
156         case 31:
157                 return "VT_LPWSTR";
158         case 36:
159                 return "VT_RECORD";
160         case 64:
161                 return "VT_FILETIME";
162         case 65:
163                 return "VT_BLOB";
164         case 66:
165                 return "VT_STREAM";
166         case 67:
167                 return "VT_STORAGE";
168         case 68:
169                 return "VT_STREAMED_OBJECT";
170         case 69:
171                 return "VT_STORED_OBJECT";
172         case 70:
173                 return "VT_BLOB_OBJECT";
174         case 71:
175                 return "VT_CF";
176         case 72:
177                 return "VT_CLSID";
178         case 0xFFF:
179                 return "VT_BSTR_BLOB/VT_ILLEGALMASKED/VT_TYPEMASK";
180         case 0x1000:
181                 return "VT_VECTOR";
182         case 0x2000:
183                 return "VT_ARRAY";
184         case 0x4000:
185                 return "VT_BYREF";
186         case 0x8000:
187                 return "VT_BYREF";
188         case 0xFFFF:
189                 return "VT_ILLEGAL";
190
191         default:
192                 return "defineme";
193         }
194 }
195
196 static void test_VariantInit(void)
197 {
198   VARIANTARG v1, v2;
199
200   /* Test that VariantInit() only sets the type */
201   memset(&v1, -1, sizeof(v1));
202   v2 = v1;
203   V_VT(&v2) = VT_EMPTY;
204   VariantInit(&v1);
205   ok(!memcmp(&v1, &v2, sizeof(v1)), "VariantInit() set extra fields\n");
206 }
207
208 /* All possible combinations of extra V_VT() flags */
209 static const VARTYPE ExtraFlags[16] =
210 {
211   0,
212   VT_VECTOR,
213   VT_ARRAY,
214   VT_BYREF,
215   VT_RESERVED,
216   VT_VECTOR|VT_ARRAY,
217   VT_VECTOR|VT_BYREF,
218   VT_VECTOR|VT_RESERVED,
219   VT_VECTOR|VT_ARRAY|VT_BYREF,
220   VT_VECTOR|VT_ARRAY|VT_RESERVED,
221   VT_VECTOR|VT_BYREF|VT_RESERVED,
222   VT_VECTOR|VT_ARRAY|VT_BYREF|VT_RESERVED,
223   VT_ARRAY|VT_BYREF,
224   VT_ARRAY|VT_RESERVED,
225   VT_ARRAY|VT_BYREF|VT_RESERVED,
226   VT_BYREF|VT_RESERVED,
227 };
228
229 /* Determine if a vt is valid for VariantClear() */
230 static int IsValidVariantClearVT(VARTYPE vt, VARTYPE extraFlags)
231 {
232   int ret = 0;
233
234   /* Only the following flags/types are valid */
235   if ((vt <= VT_LPWSTR || vt == VT_RECORD || vt == VT_CLSID) &&
236       vt != (VARTYPE)15 &&
237       (vt < (VARTYPE)24 || vt > (VARTYPE)31) &&
238       (!(extraFlags & (VT_BYREF|VT_ARRAY)) || vt > VT_NULL) &&
239       (extraFlags == 0 || extraFlags == VT_BYREF || extraFlags == VT_ARRAY ||
240        extraFlags == (VT_ARRAY|VT_BYREF)))
241     ret = 1; /* ok */
242
243   if ((vt == VT_RECORD && !HAVE_OLEAUT32_RECORD) ||
244       ((vt == VT_I8 || vt == VT_UI8) && !HAVE_OLEAUT32_I8))
245     ret = 0; /* Old versions of oleaut32 */
246   return ret;
247 }
248
249 static void test_VariantClear(void)
250 {
251   HRESULT hres;
252   VARIANTARG v;
253   size_t i;
254
255 #if 0
256   /* Crashes: Native does not test input for NULL, so neither does Wine */
257   hres = VariantClear(NULL);
258 #endif
259
260   /* Only the type field is set, to VT_EMPTY */
261   V_VT(&v) = VT_UI4;
262   V_UI4(&v) = ~0u;
263   hres = VariantClear(&v);
264   ok((hres == S_OK && V_VT(&v) == VT_EMPTY) ||
265      (IS_ANCIENT && hres == DISP_E_BADVARTYPE && V_VT(&v) == VT_UI4),
266      "VariantClear: Type set to %d, res %08lx\n", V_VT(&v), hres);
267   ok(V_UI4(&v) == ~0u, "VariantClear: Overwrote value\n");
268
269   /* Test all possible V_VT values.
270    * Also demonstrates that null pointers in 'v' are not dereferenced.
271    * Individual variant tests should test VariantClear() with non-NULL values.
272    */
273   for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]) && !IS_ANCIENT; i++)
274   {
275     VARTYPE vt;
276
277     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
278     {
279       HRESULT hExpected = DISP_E_BADVARTYPE;
280
281       SKIPTESTS(vt);
282
283       memset(&v, 0, sizeof(v));
284       V_VT(&v) = vt | ExtraFlags[i];
285
286       hres = VariantClear(&v);
287
288       if (IsValidVariantClearVT(vt, ExtraFlags[i]))
289         hExpected = S_OK;
290
291       ok(hres == hExpected, "VariantClear: expected 0x%lX, got 0x%lX for vt %d | 0x%X\n",
292          hExpected, hres, vt, ExtraFlags[i]);
293     }
294   }
295 }
296
297 static void test_VariantCopy(void)
298 {
299   VARIANTARG vSrc, vDst;
300   VARTYPE vt;
301   size_t i;
302   HRESULT hres, hExpected;
303
304   /* Establish that the failure/other cases are dealt with. Individual tests
305    * for each type should verify that data is copied correctly, references
306    * are updated, etc.
307    */
308
309   /* vSrc == vDst */
310   for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]) && !IS_ANCIENT; i++)
311   {
312     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
313     {
314       SKIPTESTS(vt);
315
316       memset(&vSrc, 0, sizeof(vSrc));
317       V_VT(&vSrc) = vt | ExtraFlags[i];
318
319       hExpected = DISP_E_BADVARTYPE;
320       /* src is allowed to be a VT_CLSID */
321       if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
322         hExpected = S_OK;
323
324       hres = VariantCopy(&vSrc, &vSrc);
325
326       ok(hres == hExpected,
327          "Copy(src==dst): expected 0x%lX, got 0x%lX for src==dest vt %d|0x%X\n",
328          hExpected, hres, vt, ExtraFlags[i]);
329     }
330   }
331
332   /* Test that if VariantClear() fails on dest, the function fails. This also
333    * shows that dest is in fact cleared and not just overwritten
334    */
335   memset(&vSrc, 0, sizeof(vSrc));
336   V_VT(&vSrc) = VT_UI1;
337
338   for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]) && !IS_ANCIENT; i++)
339   {
340     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
341     {
342       SKIPTESTS(vt);
343
344       hExpected = DISP_E_BADVARTYPE;
345
346       memset(&vDst, 0, sizeof(vDst));
347       V_VT(&vDst) = vt | ExtraFlags[i];
348
349       if (IsValidVariantClearVT(vt, ExtraFlags[i]))
350         hExpected = S_OK;
351
352       hres = VariantCopy(&vDst, &vSrc);
353
354       ok(hres == hExpected,
355          "Copy(bad dst): expected 0x%lX, got 0x%lX for dest vt %d|0x%X\n",
356          hExpected, hres, vt, ExtraFlags[i]);
357       if (hres == S_OK)
358         ok(V_VT(&vDst) == VT_UI1,
359            "Copy(bad dst): expected vt = VT_UI1, got %d\n", V_VT(&vDst));
360     }
361   }
362
363   /* Test that VariantClear() checks vSrc for validity before copying */
364   for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]) && !IS_ANCIENT; i++)
365   {
366     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
367     {
368       SKIPTESTS(vt);
369
370       hExpected = DISP_E_BADVARTYPE;
371
372       memset(&vDst, 0, sizeof(vDst));
373       V_VT(&vDst) = VT_EMPTY;
374
375       memset(&vSrc, 0, sizeof(vSrc));
376       V_VT(&vSrc) = vt | ExtraFlags[i];
377
378       /* src is allowed to be a VT_CLSID */
379       if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
380         hExpected = S_OK;
381
382       hres = VariantCopy(&vDst, &vSrc);
383
384       ok(hres == hExpected,
385          "Copy(bad src): expected 0x%lX, got 0x%lX for src vt %d|0x%X\n",
386          hExpected, hres, vt, ExtraFlags[i]);
387       if (hres == S_OK)
388         ok(V_VT(&vDst) == (vt|ExtraFlags[i]),
389            "Copy(bad src): expected vt = %d, got %d\n",
390            vt | ExtraFlags[i], V_VT(&vDst));
391     }
392   }
393 }
394
395 /* Determine if a vt is valid for VariantCopyInd() */
396 static int IsValidVariantCopyIndVT(VARTYPE vt, VARTYPE extraFlags)
397 {
398   int ret = 0;
399
400   if ((extraFlags & VT_ARRAY) ||
401      (vt > VT_NULL && vt != (VARTYPE)15 && vt < VT_VOID &&
402      !(extraFlags & (VT_VECTOR|VT_RESERVED))))
403   {
404     ret = 1; /* ok */
405   }
406   return ret;
407 }
408
409 static void test_VariantCopyInd(void)
410 {
411   VARIANTARG vSrc, vDst, vRef, vRef2;
412   VARTYPE vt;
413   size_t i;
414   BYTE buffer[64];
415   HRESULT hres, hExpected;
416
417   memset(buffer, 0, sizeof(buffer));
418
419   /* vSrc == vDst */
420   for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]) && !IS_ANCIENT; i++)
421   {
422     if (ExtraFlags[i] & VT_ARRAY)
423       continue; /* Native crashes on NULL safearray */
424
425     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
426     {
427       SKIPTESTS(vt);
428
429       memset(&vSrc, 0, sizeof(vSrc));
430       V_VT(&vSrc) = vt | ExtraFlags[i];
431
432       hExpected = DISP_E_BADVARTYPE;
433       if (!(ExtraFlags[i] & VT_BYREF))
434       {
435         /* if src is not by-reference, acts as VariantCopy() */
436         if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
437           hExpected = S_OK;
438       }
439       else
440       {
441         if (vt == VT_SAFEARRAY || vt == VT_BSTR || vt == VT_UNKNOWN ||
442             vt == VT_DISPATCH || vt == VT_RECORD)
443           continue; /* Need valid ptrs for deep copies */
444
445         V_BYREF(&vSrc) = &buffer;
446         hExpected = E_INVALIDARG;
447
448         if ((vt == VT_I8 || vt == VT_UI8) &&
449             ExtraFlags[i] == VT_BYREF)
450         {
451           if (HAVE_OLEAUT32_I8)
452             hExpected = S_OK; /* Only valid if I8 is a known type */
453         }
454         else if (IsValidVariantCopyIndVT(vt, ExtraFlags[i]))
455           hExpected = S_OK;
456       }
457
458       hres = VariantCopyInd(&vSrc, &vSrc);
459
460       ok(hres == hExpected,
461          "CopyInd(src==dst): expected 0x%lX, got 0x%lX for src==dst vt %d|0x%X\n",
462          hExpected, hres, vt, ExtraFlags[i]);
463     }
464   }
465
466   /* Bad dest */
467   memset(&vSrc, 0, sizeof(vSrc));
468   V_VT(&vSrc) = VT_UI1|VT_BYREF;
469   V_BYREF(&vSrc) = &buffer;
470
471   for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]) && !IS_ANCIENT; i++)
472   {
473     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
474     {
475       SKIPTESTS(vt);
476
477       memset(&vDst, 0, sizeof(vDst));
478       V_VT(&vDst) = vt | ExtraFlags[i];
479
480       hExpected = DISP_E_BADVARTYPE;
481
482       if (IsValidVariantClearVT(vt, ExtraFlags[i]))
483         hExpected = S_OK;
484
485       hres = VariantCopyInd(&vDst, &vSrc);
486
487       ok(hres == hExpected,
488          "CopyInd(bad dst): expected 0x%lX, got 0x%lX for dst vt %d|0x%X\n",
489          hExpected, hres, vt, ExtraFlags[i]);
490       if (hres == S_OK)
491         ok(V_VT(&vDst) == VT_UI1,
492            "CopyInd(bad dst): expected vt = VT_UI1, got %d\n", V_VT(&vDst));
493     }
494   }
495
496   /* bad src */
497   for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]) && !IS_ANCIENT; i++)
498   {
499     if (ExtraFlags[i] & VT_ARRAY)
500       continue; /* Native crashes on NULL safearray */
501
502     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
503     {
504       SKIPTESTS(vt);
505
506       memset(&vDst, 0, sizeof(vDst));
507       V_VT(&vDst) = VT_EMPTY;
508
509       memset(&vSrc, 0, sizeof(vSrc));
510       V_VT(&vSrc) = vt | ExtraFlags[i];
511
512       hExpected = DISP_E_BADVARTYPE;
513       if (!(ExtraFlags[i] & VT_BYREF))
514       {
515         /* if src is not by-reference, acts as VariantCopy() */
516         if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
517           hExpected = S_OK;
518       }
519       else
520       {
521         if (vt == VT_SAFEARRAY || vt == VT_BSTR || vt == VT_UNKNOWN ||
522             vt == VT_DISPATCH || vt == VT_RECORD)
523           continue; /* Need valid ptrs for deep copies, see vartype.c */
524
525         V_BYREF(&vSrc) = &buffer;
526
527         hExpected = E_INVALIDARG;
528
529         if ((vt == VT_I8 || vt == VT_UI8) &&
530             ExtraFlags[i] == VT_BYREF)
531         {
532           if (HAVE_OLEAUT32_I8)
533             hExpected = S_OK; /* Only valid if I8 is a known type */
534         }
535         else if (IsValidVariantCopyIndVT(vt, ExtraFlags[i]))
536           hExpected = S_OK;
537       }
538
539       hres = VariantCopyInd(&vDst, &vSrc);
540
541       ok(hres == hExpected,
542          "CopyInd(bad src): expected 0x%lX, got 0x%lX for src vt %d|0x%X\n",
543          hExpected, hres, vt, ExtraFlags[i]);
544       if (hres == S_OK)
545       {
546         if (vt == VT_VARIANT && ExtraFlags[i] == VT_BYREF)
547         {
548           /* Type of vDst should be the type of the referenced variant.
549            * Since we set the buffer to all zeros, its type should be
550            * VT_EMPTY.
551            */
552           ok(V_VT(&vDst) == VT_EMPTY,
553              "CopyInd(bad src): expected dst vt = VT_EMPTY, got %d|0x%X\n",
554              V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK);
555         }
556         else
557         {
558           ok(V_VT(&vDst) == (vt|(ExtraFlags[i] & ~VT_BYREF)),
559              "CopyInd(bad src): expected dst vt = %d|0x%X, got %d|0x%X\n",
560              vt, ExtraFlags[i] & ~VT_BYREF,
561              V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK);
562         }
563       }
564     }
565   }
566
567   /* By-reference variants are dereferenced */
568   V_VT(&vRef) = VT_UI1;
569   V_UI1(&vRef) = 0x77;
570   V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
571   V_VARIANTREF(&vSrc) = &vRef;
572   VariantInit(&vDst);
573
574   hres = VariantCopyInd(&vDst, &vSrc);
575   ok(V_VT(&vDst) == VT_UI1 && V_UI1(&vDst) == 0x77,
576      "CopyInd(deref): expected dst vt = VT_UI1, val 0x77, got %d|0x%X, 0x%2X\n",
577       V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK, V_UI1(&vDst));
578
579   /* By-reference variant to a by-reference type succeeds */
580   V_VT(&vRef) = VT_UI1|VT_BYREF;
581   V_UI1REF(&vRef) = buffer; buffer[0] = 0x88;
582   V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
583   V_VARIANTREF(&vSrc) = &vRef;
584   VariantInit(&vDst);
585
586   hres = VariantCopyInd(&vDst, &vSrc);
587   ok(V_VT(&vDst) == VT_UI1 && V_UI1(&vDst) == 0x88,
588      "CopyInd(deref): expected dst vt = VT_UI1, val 0x77, got %d|0x%X, 0x%2X\n",
589       V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK, V_UI1(&vDst));
590
591   /* But a by-reference variant to a by-reference variant fails */
592   V_VT(&vRef2) = VT_UI1;
593   V_UI1(&vRef2) = 0x77;
594   V_VT(&vRef) = VT_VARIANT|VT_BYREF;
595   V_VARIANTREF(&vRef) = &vRef2;
596   V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
597   V_VARIANTREF(&vSrc) = &vRef;
598   VariantInit(&vDst);
599
600   hres = VariantCopyInd(&vDst, &vSrc);
601   ok(hres == E_INVALIDARG,
602      "CopyInd(ref->ref): expected E_INVALIDARG, got 0x%08lx\n", hres);
603 }
604
605 static HRESULT (WINAPI *pVarParseNumFromStr)(OLECHAR*,LCID,ULONG,NUMPARSE*,BYTE*);
606
607 /* Macros for converting and testing the result of VarParseNumFromStr */
608 #define FAILDIG 255
609 #define CONVERTN(str,dig,flags) MultiByteToWideChar(CP_ACP,0,str,-1,buff,sizeof(buff)); \
610   memset(rgb, FAILDIG, sizeof(rgb)); memset(&np,-1,sizeof(np)); np.cDig = dig; np.dwInFlags = flags; \
611   hres = pVarParseNumFromStr(buff,lcid,LOCALE_NOUSEROVERRIDE,&np,rgb)
612 #define CONVERT(str,flags) CONVERTN(str,sizeof(rgb),flags)
613 #define EXPECT(a,b,c,d,e,f) ok(hres == (HRESULT)S_OK, "Call failed, hres = %08lx\n", hres); \
614   if (hres == (HRESULT)S_OK) { \
615     ok(np.cDig == (a), "Expected cDig = %d, got %d\n", (a), np.cDig); \
616     ok(np.dwInFlags == (b), "Expected dwInFlags = 0x%lx, got 0x%lx\n", (ULONG)(b), np.dwInFlags); \
617     ok(np.dwOutFlags == (c), "Expected dwOutFlags = 0x%lx, got 0x%lx\n", (ULONG)(c), np.dwOutFlags); \
618     ok(np.cchUsed == (d), "Expected cchUsed = %d, got %d\n", (d), np.cchUsed); \
619     ok(np.nBaseShift == (e), "Expected nBaseShift = %d, got %d\n", (e), np.nBaseShift); \
620     ok(np.nPwr10 == (f), "Expected nPwr10 = %d, got %d\n", (f), np.nPwr10); \
621   }
622 #define EXPECTRGB(a,b) ok(rgb[a] == b, "Digit[%d], expected %d, got %d\n", a, b, rgb[a])
623 #define EXPECTFAIL ok(hres == (HRESULT)DISP_E_TYPEMISMATCH, "Call succeeded, hres = %08lx\n", hres)
624 #define EXPECT2(a,b) EXPECTRGB(0,a); EXPECTRGB(1,b)
625
626 static void test_VarParseNumFromStr(void)
627 {
628   HRESULT hres;
629   OLECHAR buff[128];
630   /* Ensure all tests are using the same locale characters for '$', ',' etc */
631   LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
632   NUMPARSE np;
633   BYTE rgb[128];
634
635   /** No flags **/
636
637   CHECKPTR(VarParseNumFromStr);
638
639   /* Consume a single digit */
640   CONVERT("7", 0);
641   EXPECT(1,0,0,1,0,0);
642   EXPECT2(7,FAILDIG);
643
644   /* cDig is not literal digits - zeros are suppressed and nPwr10 is increased */
645   CONVERT("10", 0);
646   EXPECT(1,0,0,2,0,1);
647   /* Note: Win32 writes the trailing zeros if they are within cDig's limits,
648    * but then excludes them from the returned cDig count.
649    * In our implementation we don't bother writing them at all.
650    */
651   EXPECTRGB(0, 1);
652
653   /* if cDig is too small and numbers follow, sets INEXACT */
654   CONVERTN("11",1, 0);
655   EXPECT(1,0,NUMPRS_INEXACT,2,0,1);
656   EXPECT2(1,FAILDIG);
657
658   /* Strips leading zeros */
659   CONVERT("01", 0);
660   EXPECT(1,0,0,2,0,0);
661   EXPECT2(1,FAILDIG);
662
663   /* Strips leading zeros */
664   CONVERTN("01",1, 0);
665   EXPECT(1,0,0,2,0,0);
666   EXPECT2(1,FAILDIG);
667
668
669   /* Fails on non digits */
670   CONVERT("a", 0);
671   EXPECTFAIL;
672   EXPECTRGB(0,FAILDIG);
673
674   /** NUMPRS_LEADING_WHITE/NUMPRS_TRAILING_WHITE **/
675
676   /* Without flag, fails on whitespace */
677   CONVERT(" 0", 0);
678   EXPECTFAIL;
679   EXPECTRGB(0,FAILDIG);
680
681
682   /* With flag, consumes whitespace */
683   CONVERT(" 0", NUMPRS_LEADING_WHITE);
684   EXPECT(1,NUMPRS_LEADING_WHITE,NUMPRS_LEADING_WHITE,2,0,0);
685   EXPECT2(0,FAILDIG);
686
687   /* Test TAB once, then assume it acts as space for all cases */
688   CONVERT("\t0", NUMPRS_LEADING_WHITE);
689   EXPECT(1,NUMPRS_LEADING_WHITE,NUMPRS_LEADING_WHITE,2,0,0);
690   EXPECT2(0,FAILDIG);
691
692
693   /* Doesn't pick up trailing whitespace without flag */
694   CONVERT("0 ", 0);
695   EXPECT(1,0,0,1,0,0);
696   EXPECT2(0,FAILDIG);
697
698   /* With flag, consumes trailing whitespace */
699   CONVERT("0 ", NUMPRS_TRAILING_WHITE);
700   EXPECT(1,NUMPRS_TRAILING_WHITE,NUMPRS_TRAILING_WHITE,2,0,0);
701   EXPECT2(0,FAILDIG);
702
703   /* Leading flag only consumes leading */
704   CONVERT(" 0 ", NUMPRS_LEADING_WHITE);
705   EXPECT(1,NUMPRS_LEADING_WHITE,NUMPRS_LEADING_WHITE,2,0,0);
706   EXPECT2(0,FAILDIG);
707
708   /* Both flags consumes both */
709   CONVERT(" 0 ", NUMPRS_LEADING_WHITE|NUMPRS_TRAILING_WHITE);
710   EXPECT(1,NUMPRS_LEADING_WHITE|NUMPRS_TRAILING_WHITE,NUMPRS_LEADING_WHITE|NUMPRS_TRAILING_WHITE,3,0,0);
711   EXPECT2(0,FAILDIG);
712
713   /** NUMPRS_LEADING_PLUS/NUMPRS_TRAILING_PLUS **/
714
715   /* Without flag, fails on + */
716   CONVERT("+0", 0);
717   EXPECTFAIL;
718   EXPECTRGB(0,FAILDIG);
719
720   /* With flag, consumes + */
721   CONVERT("+0", NUMPRS_LEADING_PLUS);
722   EXPECT(1,NUMPRS_LEADING_PLUS,NUMPRS_LEADING_PLUS,2,0,0);
723   EXPECT2(0,FAILDIG);
724
725   /* Without flag, doesn't consume trailing + */
726   CONVERT("0+", 0);
727   EXPECT(1,0,0,1,0,0);
728   EXPECT2(0,FAILDIG);
729
730   /* With flag, consumes trailing + */
731   CONVERT("0+", NUMPRS_TRAILING_PLUS);
732   EXPECT(1,NUMPRS_TRAILING_PLUS,NUMPRS_TRAILING_PLUS,2,0,0);
733   EXPECT2(0,FAILDIG);
734
735   /* With leading flag, doesn't consume trailing + */
736   CONVERT("+0+", NUMPRS_LEADING_PLUS);
737   EXPECT(1,NUMPRS_LEADING_PLUS,NUMPRS_LEADING_PLUS,2,0,0);
738   EXPECT2(0,FAILDIG);
739
740   /* Trailing + doesn't get consumed if we specify both (unlike whitespace) */
741   CONVERT("+0+", NUMPRS_LEADING_PLUS|NUMPRS_TRAILING_PLUS);
742   EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_TRAILING_PLUS,NUMPRS_LEADING_PLUS,2,0,0);
743   EXPECT2(0,FAILDIG);
744
745   /** NUMPRS_LEADING_MINUS/NUMPRS_TRAILING_MINUS **/
746
747   /* Without flag, fails on - */
748   CONVERT("-0", 0);
749   EXPECTFAIL;
750   EXPECTRGB(0,FAILDIG);
751
752   /* With flag, consumes - */
753   CONVERT("-0", NUMPRS_LEADING_MINUS);
754   EXPECT(1,NUMPRS_LEADING_MINUS,NUMPRS_NEG|NUMPRS_LEADING_MINUS,2,0,0);
755   EXPECT2(0,FAILDIG);
756
757   /* Without flag, doesn't consume trailing - */
758   CONVERT("0-", 0);
759   EXPECT(1,0,0,1,0,0);
760   EXPECT2(0,FAILDIG);
761
762   /* With flag, consumes trailing - */
763   CONVERT("0-", NUMPRS_TRAILING_MINUS);
764   EXPECT(1,NUMPRS_TRAILING_MINUS,NUMPRS_NEG|NUMPRS_TRAILING_MINUS,2,0,0);
765   EXPECT2(0,FAILDIG);
766
767   /* With leading flag, doesn't consume trailing - */
768   CONVERT("-0-", NUMPRS_LEADING_MINUS);
769   EXPECT(1,NUMPRS_LEADING_MINUS,NUMPRS_NEG|NUMPRS_LEADING_MINUS,2,0,0);
770   EXPECT2(0,FAILDIG);
771
772   /* Trailing - doesn't get consumed if we specify both (unlike whitespace) */
773   CONVERT("-0-", NUMPRS_LEADING_MINUS|NUMPRS_TRAILING_MINUS);
774   EXPECT(1,NUMPRS_LEADING_MINUS|NUMPRS_TRAILING_MINUS,NUMPRS_NEG|NUMPRS_LEADING_MINUS,2,0,0);
775   EXPECT2(0,FAILDIG);
776
777   /** NUMPRS_HEX_OCT **/
778
779   /* Could be hex, octal or decimal - With flag reads as decimal */
780   CONVERT("0", NUMPRS_HEX_OCT);
781   EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
782   EXPECT2(0,FAILDIG);
783
784   /* Doesn't recognise hex in .asm sytax */
785   CONVERT("0h", NUMPRS_HEX_OCT);
786   EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
787   EXPECT2(0,FAILDIG);
788
789   /* Doesn't fail with valid leading string but no digits */
790   CONVERT("0x", NUMPRS_HEX_OCT);
791   EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
792   EXPECT2(0,FAILDIG);
793
794   /* Doesn't recognise hex format humbers at all! */
795   CONVERT("0x0", NUMPRS_HEX_OCT);
796   EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
797   EXPECT2(0,FAILDIG);
798
799   /* Doesn't recognise plain hex digits either */
800   CONVERT("FE", NUMPRS_HEX_OCT);
801   EXPECTFAIL;
802   EXPECTRGB(0,FAILDIG);
803
804   /* Octal */
805   CONVERT("0100", NUMPRS_HEX_OCT);
806   EXPECT(1,NUMPRS_HEX_OCT,0,4,0,2);
807   EXPECTRGB(0,1);
808   EXPECTRGB(1,0);
809   EXPECTRGB(2,0);
810   EXPECTRGB(3,FAILDIG);
811
812   /* VB hex */
813   CONVERT("&HF800", NUMPRS_HEX_OCT);
814   EXPECT(4,NUMPRS_HEX_OCT,0x40,6,4,0);
815   EXPECTRGB(0,15);
816   EXPECTRGB(1,8);
817   EXPECTRGB(2,0);
818   EXPECTRGB(3,0);
819   EXPECTRGB(4,FAILDIG);
820
821   /* VB hex lower case and leading zero */
822   CONVERT("&h0abcd", NUMPRS_HEX_OCT);
823   EXPECT(4,NUMPRS_HEX_OCT,0x40,7,4,0);
824   EXPECTRGB(0,10);
825   EXPECTRGB(1,11);
826   EXPECTRGB(2,12);
827   EXPECTRGB(3,13);
828   EXPECTRGB(4,FAILDIG);
829
830   /* VB oct */
831   CONVERT("&O300", NUMPRS_HEX_OCT);
832   EXPECT(3,NUMPRS_HEX_OCT,0x40,5,3,0);
833   EXPECTRGB(0,3);
834   EXPECTRGB(1,0);
835   EXPECTRGB(2,0);
836   EXPECTRGB(3,FAILDIG);
837
838   /* VB oct lower case and leading zero */
839   CONVERT("&o0777", NUMPRS_HEX_OCT);
840   EXPECT(3,NUMPRS_HEX_OCT,0x40,6,3,0);
841   EXPECTRGB(0,7);
842   EXPECTRGB(1,7);
843   EXPECTRGB(2,7);
844   EXPECTRGB(3,FAILDIG);
845
846   /* VB oct char bigger than 7 */
847   CONVERT("&o128", NUMPRS_HEX_OCT);
848 /*
849   Native versions 2.x of oleaut32 allow this to succeed: later versions and Wine don't
850   EXPECTFAIL;
851   EXPECTRGB(0,FAILDIG);
852 */
853   /** NUMPRS_PARENS **/
854
855   /* Empty parens = error */
856   CONVERT("()", NUMPRS_PARENS);
857   EXPECTFAIL;
858   EXPECTRGB(0,FAILDIG);
859
860   /* With flag, trailing parens not consumed */
861   CONVERT("0()", NUMPRS_PARENS);
862   EXPECT(1,NUMPRS_PARENS,0,1,0,0);
863   EXPECT2(0,FAILDIG);
864
865   /* With flag, Number in parens made negative and parens consumed */
866   CONVERT("(0)", NUMPRS_PARENS);
867   EXPECT(1,NUMPRS_PARENS,NUMPRS_NEG|NUMPRS_PARENS,3,0,0);
868   EXPECT2(0,FAILDIG);
869
870   /** NUMPRS_THOUSANDS **/
871
872   /* With flag, thousands sep. not needed */
873   CONVERT("0", NUMPRS_THOUSANDS);
874   EXPECT(1,NUMPRS_THOUSANDS,0,1,0,0);
875   EXPECT2(0,FAILDIG);
876
877   /* With flag, thousands sep. and following digits consumed */
878   CONVERT("1,000", NUMPRS_THOUSANDS);
879   EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,3);
880   EXPECTRGB(0,1);
881
882   /* With flag and decimal point, thousands sep. but not decimals consumed */
883   CONVERT("1,000.0", NUMPRS_THOUSANDS);
884   EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,3);
885   EXPECTRGB(0,1);
886
887   /** NUMPRS_CURRENCY **/
888
889   /* Without flag, chokes on currency sign */
890   CONVERT("$11", 0);
891   EXPECTFAIL;
892   EXPECTRGB(0,FAILDIG);
893
894   /* With flag, consumes currency sign */
895   CONVERT("$11", NUMPRS_CURRENCY);
896   EXPECT(2,NUMPRS_CURRENCY,NUMPRS_CURRENCY,3,0,0);
897   EXPECT2(1,1);
898   EXPECTRGB(2,FAILDIG);
899
900   /* With flag only, doesn't consume decimal point */
901   CONVERT("$11.1", NUMPRS_CURRENCY);
902   EXPECT(2,NUMPRS_CURRENCY,NUMPRS_CURRENCY,3,0,0);
903   EXPECT2(1,1);
904   EXPECTRGB(2,FAILDIG);
905
906   /* With flag and decimal flag, consumes decimal point and following digits */
907   CONVERT("$11.1", NUMPRS_CURRENCY|NUMPRS_DECIMAL);
908   EXPECT(3,NUMPRS_CURRENCY|NUMPRS_DECIMAL,NUMPRS_CURRENCY|NUMPRS_DECIMAL,5,0,-1);
909   EXPECT2(1,1);
910   EXPECTRGB(2,1);
911   EXPECTRGB(3,FAILDIG);
912
913   /* Thousands flag can only be used with currency */
914   CONVERT("$1,234", NUMPRS_CURRENCY|NUMPRS_THOUSANDS);
915   EXPECT(4,NUMPRS_CURRENCY|NUMPRS_THOUSANDS,NUMPRS_CURRENCY|NUMPRS_THOUSANDS,6,0,0);
916   EXPECT2(1,2);
917   EXPECTRGB(2,3);
918   EXPECTRGB(3,4);
919   EXPECTRGB(4,FAILDIG);
920
921   /** NUMPRS_DECIMAL **/
922
923   /* With flag, consumes decimal point */
924   CONVERT("1.1", NUMPRS_DECIMAL);
925   EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL,3,0,-1);
926   EXPECT2(1,1);
927   EXPECTRGB(2,FAILDIG);
928
929   /* With flag, consumes decimal point. Skipping the decimal part is not an error */
930   CONVERT("1.", NUMPRS_DECIMAL);
931   EXPECT(1,NUMPRS_DECIMAL,NUMPRS_DECIMAL,2,0,0);
932   EXPECT2(1,FAILDIG);
933
934   /* Consumes only one decimal point */
935   CONVERT("1.1.", NUMPRS_DECIMAL);
936   EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL,3,0,-1);
937   EXPECT2(1,1);
938   EXPECTRGB(2,FAILDIG);
939
940   /** NUMPRS_EXPONENT **/
941
942   /* Without flag, doesn't consume exponent */
943   CONVERT("1e1", 0);
944   EXPECT(1,0,0,1,0,0);
945   EXPECT2(1,FAILDIG);
946
947   /* With flag, consumes exponent */
948   CONVERT("1e1", NUMPRS_EXPONENT);
949   EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,3,0,1);
950   EXPECT2(1,FAILDIG);
951
952   /* Negative exponents are accepted without flags */
953   CONVERT("1e-1", NUMPRS_EXPONENT);
954   EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,4,0,-1);
955   EXPECT2(1,FAILDIG);
956
957   /* As are positive exponents and leading exponent 0's */
958   CONVERT("1e+01", NUMPRS_EXPONENT);
959   EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,5,0,1);
960   EXPECT2(1,FAILDIG);
961
962   /* Doesn't consume a real number exponent */
963   CONVERT("1e1.", NUMPRS_EXPONENT);
964   EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,3,0,1);
965   EXPECT2(1,FAILDIG);
966
967   /* Powers of 10 are calculated from the position of any decimal point */
968   CONVERT("1.5e20", NUMPRS_EXPONENT|NUMPRS_DECIMAL);
969   EXPECT(2,NUMPRS_EXPONENT|NUMPRS_DECIMAL,NUMPRS_EXPONENT|NUMPRS_DECIMAL,6,0,19);
970   EXPECT2(1,5);
971
972   CONVERT("1.5e-20", NUMPRS_EXPONENT|NUMPRS_DECIMAL);
973   EXPECT(2,NUMPRS_EXPONENT|NUMPRS_DECIMAL,NUMPRS_EXPONENT|NUMPRS_DECIMAL,7,0,-21);
974   EXPECT2(1,5);
975
976   /** NUMPRS_USE_ALL **/
977
978   /* Flag expects all digits */
979   CONVERT("0", NUMPRS_USE_ALL);
980   EXPECT(1,NUMPRS_USE_ALL,0,1,0,0);
981   EXPECT2(0,FAILDIG);
982
983   /* Rejects anything trailing */
984   CONVERT("0 ", NUMPRS_USE_ALL);
985   EXPECTFAIL;
986   EXPECT2(0,FAILDIG);
987
988   /* Unless consumed by trailing flag */
989   CONVERT("0 ", NUMPRS_USE_ALL|NUMPRS_TRAILING_WHITE);
990   EXPECT(1,NUMPRS_USE_ALL|NUMPRS_TRAILING_WHITE,NUMPRS_TRAILING_WHITE,2,0,0);
991   EXPECT2(0,FAILDIG);
992
993   /** Combinations **/
994
995   /* Leading whitepace and plus, doesn't consume trailing whitespace */
996   CONVERT("+ 0 ", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
997   EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,3,0,0);
998   EXPECT2(0,FAILDIG);
999
1000   /* Order of whitepace and plus is unimportant */
1001   CONVERT(" +0", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
1002   EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,3,0,0);
1003   EXPECT2(0,FAILDIG);
1004
1005   /* Leading whitespace can be repeated */
1006   CONVERT(" + 0", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
1007   EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,4,0,0);
1008   EXPECT2(0,FAILDIG);
1009
1010   /* But plus/minus etc. cannot */
1011   CONVERT("+ +0", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
1012   EXPECTFAIL;
1013   EXPECTRGB(0,FAILDIG);
1014
1015   /* Inexact is not set if trailing zeros are removed */
1016   CONVERTN("10", 1, 0);
1017   EXPECT(1,0,0,2,0,1);
1018   EXPECT2(1,FAILDIG);
1019
1020   /* Make sure a leading 0 is stripped but decimals after it get read */
1021   CONVERT("-0.51", NUMPRS_STD);
1022   EXPECT(2,NUMPRS_STD,NUMPRS_NEG|NUMPRS_DECIMAL|NUMPRS_LEADING_MINUS,5,0,-2);
1023   EXPECT2(5,1);
1024 }
1025
1026 static HRESULT (WINAPI *pVarNumFromParseNum)(NUMPARSE*,BYTE*,ULONG,VARIANT*);
1027
1028 /* Macros for converting and testing the result of VarNumFromParseNum */
1029 #define SETRGB(indx,val) if (!indx) memset(rgb, FAILDIG, sizeof(rgb)); rgb[indx] = val
1030 #undef CONVERT
1031 #define CONVERT(a,b,c,d,e,f,bits) \
1032     np.cDig = (a); np.dwInFlags = (b); np.dwOutFlags = (c); np.cchUsed = (d); \
1033     np.nBaseShift = (e); np.nPwr10 = (f); hres = pVarNumFromParseNum(&np, rgb, bits, &vOut)
1034 static const char *szFailOverflow = "Expected overflow, hres = %08lx\n";
1035 #define EXPECT_OVERFLOW ok(hres == (HRESULT)DISP_E_OVERFLOW, szFailOverflow, hres)
1036 static const char *szFailOk = "Call failed, hres = %08lx\n";
1037 #define EXPECT_OK ok(hres == (HRESULT)S_OK, szFailOk, hres); \
1038   if (hres == (HRESULT)S_OK)
1039 #define EXPECT_TYPE(typ) ok(V_VT(&vOut) == typ,"Expected Type = " #typ ", got %d\n", V_VT(&vOut))
1040 #define EXPECT_I1(val) EXPECT_OK { EXPECT_TYPE(VT_I1); \
1041   ok(V_I1(&vOut) == val, "Expected i1 = %d, got %d\n", (signed char)val, V_I1(&vOut)); }
1042 #define EXPECT_UI1(val) EXPECT_OK { EXPECT_TYPE(VT_UI1); \
1043   ok(V_UI1(&vOut) == val, "Expected ui1 = %d, got %d\n", (BYTE)val, V_UI1(&vOut)); }
1044 #define EXPECT_I2(val) EXPECT_OK { EXPECT_TYPE(VT_I2); \
1045   ok(V_I2(&vOut) == val, "Expected i2 = %d, got %d\n", (SHORT)val, V_I2(&vOut)); }
1046 #define EXPECT_UI2(val) EXPECT_OK { EXPECT_TYPE(VT_UI2); \
1047   ok(V_UI2(&vOut) == val, "Expected ui2 = %d, got %d\n", (USHORT)val, V_UI2(&vOut)); }
1048 #define EXPECT_I4(val) EXPECT_OK { EXPECT_TYPE(VT_I4); \
1049   ok(V_I4(&vOut) == val, "Expected i4 = %ld, got %ld\n", (LONG)val, V_I4(&vOut)); }
1050 #define EXPECT_UI4(val) EXPECT_OK { EXPECT_TYPE(VT_UI4); \
1051   ok(V_UI4(&vOut) == val, "Expected ui4 = %ld, got %ld\n", (ULONG)val, V_UI4(&vOut)); }
1052 #define EXPECT_I8(val) EXPECT_OK { EXPECT_TYPE(VT_I8); \
1053   ok(V_I8(&vOut) == val, "Expected i8 = %lld, got %lld\n", (LONG64)val, V_I8(&vOut)); }
1054 #define EXPECT_UI8(val) EXPECT_OK { EXPECT_TYPE(VT_UI8); \
1055   ok(V_UI8(&vOut) == val, "Expected ui8 = %lld, got %lld\n", (ULONG64)val, V_UI8(&vOut)); }
1056 #define EXPECT_R4(val) EXPECT_OK { EXPECT_TYPE(VT_R4); \
1057   ok(V_R4(&vOut) == val, "Expected r4 = %f, got %f\n", val, V_R4(&vOut)); }
1058 #define EXPECT_R8(val) EXPECT_OK { EXPECT_TYPE(VT_R8); \
1059   ok(V_R8(&vOut) == val, "Expected r8 = %g, got %g\n", val, V_R8(&vOut)); }
1060 #define CY_MULTIPLIER 10000
1061 #define EXPECT_CY(val) EXPECT_OK { EXPECT_TYPE(VT_CY); \
1062   ok(V_CY(&vOut).int64 == (LONG64)(val * CY_MULTIPLIER), "Expected r8 = %lld, got %lld\n", (LONG64)val, V_CY(&vOut).int64); }
1063
1064 static void test_VarNumFromParseNum(void)
1065 {
1066   HRESULT hres;
1067   NUMPARSE np;
1068   BYTE rgb[128];
1069   VARIANT vOut;
1070
1071   CHECKPTR(VarNumFromParseNum);
1072     
1073   /* Convert the number 1 to different types */
1074   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I1); EXPECT_I1(1);
1075   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_UI1); EXPECT_UI1(1);
1076   /* Prefers a signed type to unsigned of the same size */
1077   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I1|VTBIT_UI1); EXPECT_I1(1);
1078   /* But takes the smaller size if possible */
1079   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I2|VTBIT_UI1); EXPECT_UI1(1);
1080
1081   /* Try different integer sizes */
1082 #define INTEGER_VTBITS (VTBIT_I1|VTBIT_UI1|VTBIT_I2|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|VTBIT_I8|VTBIT_UI8)
1083
1084   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, INTEGER_VTBITS); EXPECT_I1(1);
1085   /* 127 */
1086   SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 7);
1087   CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_I1(127);
1088   /* 128 */
1089   SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 8);
1090   CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_UI1(128);
1091   /* 255 */
1092   SETRGB(0, 2); SETRGB(1, 5); SETRGB(2, 5);
1093   CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_UI1(255);
1094   /* 256 */
1095   SETRGB(0, 2); SETRGB(1, 5); SETRGB(2, 6);
1096   CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_I2(256);
1097   /* 32767 */
1098   SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 7);
1099   CONVERT(5,0,0,5,0,0, INTEGER_VTBITS); EXPECT_I2(32767);
1100   /* 32768 */
1101   SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 8);
1102   CONVERT(5,0,0,5,0,0, INTEGER_VTBITS); EXPECT_UI2(32768);
1103
1104   /* Assume the above pattern holds for remaining positive integers; test negative */
1105
1106   /* -128 */
1107   SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 8);
1108   CONVERT(3,0,NUMPRS_NEG,3,0,0, INTEGER_VTBITS); EXPECT_I1(-128);
1109   /* -129 */
1110   SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 9);
1111   CONVERT(3,0,NUMPRS_NEG,3,0,0, INTEGER_VTBITS); EXPECT_I2(-129);
1112   /* -32768 */
1113   SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 8);
1114   CONVERT(5,0,NUMPRS_NEG,5,0,0, INTEGER_VTBITS); EXPECT_I2(-32768);
1115   /* -32768 */
1116   SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 9);
1117   CONVERT(5,0,NUMPRS_NEG,5,0,0, INTEGER_VTBITS); EXPECT_I4(-32769);
1118
1119   /* Assume the above pattern holds for remaining negative integers */
1120
1121   /* Negative numbers overflow if we have only unsigned outputs */
1122   /* -1 */
1123   SETRGB(0, 1); CONVERT(1,0,NUMPRS_NEG,1,0,0, VTBIT_UI1); EXPECT_OVERFLOW;
1124   /* -0.6 */
1125   SETRGB(0, 6); CONVERT(1,0,NUMPRS_NEG,1,0,~0u, VTBIT_UI1); EXPECT_OVERFLOW;
1126
1127   /* Except that rounding is done first, so -0.5 to 0 are accepted as 0 */
1128   /* -0.5 */
1129   SETRGB(0, 5); CONVERT(1,0,NUMPRS_NEG,1,0,~0u, VTBIT_UI1); EXPECT_UI1(0);
1130
1131   /* Float is acceptable for an integer input value */
1132   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R4); EXPECT_R4(1.0f);
1133   /* As is double */
1134   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R8); EXPECT_R8(1.0);
1135   /* As is currency */
1136   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_CY); EXPECT_CY(1);
1137
1138   /* Float is preferred over double */
1139   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R4|VTBIT_R8); EXPECT_R4(1.0f);
1140
1141   /* Double is preferred over currency */
1142   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R8|VTBIT_CY); EXPECT_R8(1.0);
1143
1144   /* Currency is preferred over decimal */
1145   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_CY|VTBIT_DECIMAL); EXPECT_CY(1);
1146 }
1147
1148 static const char* szUdateFromDateFail = "%.16g expected %lx, %d,%d,%d,%d,%d,%d,%d  %d %d"
1149                                          ", got %lx, %d,%d,%d,%d,%d,%d,%d  %d %d\n";
1150 #define DT2UD(dt,flags,r,d,m,y,h,mn,s,ms,dw,dy) \
1151   memset(&ud, 0, sizeof(ud)); \
1152   res = pVarUdateFromDate(dt, flags, &ud); \
1153   ok(r == res && (FAILED(r) || (ud.st.wYear == y && ud.st.wMonth == m && ud.st.wDay == d && \
1154      ud.st.wHour == h && ud.st.wMinute == mn && ud.st.wSecond == s && \
1155      ud.st.wMilliseconds == ms && ud.st.wDayOfWeek == dw && ud.wDayOfYear == dy)), \
1156      szUdateFromDateFail, dt, r, d, m, y, h, mn, s, ms, dw, dy, res, ud.st.wDay, ud.st.wMonth, \
1157      ud.st.wYear, ud.st.wHour, ud.st.wMinute, ud.st.wSecond, \
1158      ud.st.wMilliseconds, ud.st.wDayOfWeek, ud.wDayOfYear)
1159
1160 static void test_VarUdateFromDate(void)
1161 {
1162   UDATE ud;
1163   HRESULT res;
1164
1165   CHECKPTR(VarUdateFromDate);
1166   DT2UD(29221.0,0,S_OK,1,1,1980,0,0,0,0,2,1);        /* 1 Jan 1980 */
1167   DT2UD(29222.0,0,S_OK,2,1,1980,0,0,0,0,3,2);        /* 2 Jan 1980 */
1168   DT2UD(33238.0,0,S_OK,31,12,1990,0,0,0,0,1,365);    /* 31 Dec 1990 */
1169   DT2UD(0.0,0,S_OK,30,12,1899,0,0,0,0,6,364);        /* 30 Dec 1899 - VT_DATE 0.0 */
1170   DT2UD(-657434.0,0,S_OK,1,1,100,0,0,0,0,5,1);       /* 1 Jan 100 - Min */
1171   DT2UD(-657435.0,0,E_INVALIDARG,0,0,0,0,0,0,0,0,0); /* < 1 Jan 100 => err */
1172   DT2UD(2958465.0,0,S_OK,31,12,9999,0,0,0,0,5,365);  /* 31 Dec 9999 - Max */
1173   DT2UD(2958466.0,0,E_INVALIDARG,0,0,0,0,0,0,0,0,0); /* > 31 Dec 9999 => err  */
1174
1175   /* VAR_VALIDDATE doesn't prevent upper and lower bounds being checked */
1176   DT2UD(-657435.0,VAR_VALIDDATE,E_INVALIDARG,0,0,0,0,0,0,0,0,0);
1177   DT2UD(2958466.0,VAR_VALIDDATE,E_INVALIDARG,0,0,0,0,0,0,0,0,0);
1178
1179   /* Times */
1180   DT2UD(29221.25,0,S_OK,1,1,1980,6,0,0,0,2,1);           /* 6 AM */
1181   DT2UD(29221.33333333,0,S_OK,1,1,1980,8,0,0,0,2,1);     /* 8 AM */
1182   DT2UD(29221.5,0,S_OK,1,1,1980,12,0,0,0,2,1);           /* 12 AM */
1183   DT2UD(29221.9888884444,0,S_OK,1,1,1980,23,44,0,0,2,1); /* 11:44 PM */
1184   DT2UD(29221.7508765432,0,S_OK,1,1,1980,18,1,16,0,2,1); /* 6:18:02 PM */
1185 }
1186
1187 #define UD2T(d,m,y,h,mn,s,ms,dw,dy,flags,r,dt) \
1188   ud.st.wYear = (y); ud.st.wMonth = (m); ud.st.wDay = (d); ud.st.wHour = (h); \
1189   ud.st.wMinute = (mn); ud.st.wSecond = (s); ud.st.wMilliseconds = (ms); \
1190   ud.st.wDayOfWeek = (dw); ud.wDayOfYear = (dy); \
1191   res = pVarDateFromUdate(&ud, (flags), &out); \
1192   ok((r) == res && (FAILED(r) || fabs(out-(dt)) < 1.0e-11), \
1193      "expected %lx, %.16g, got %lx, %.16g\n", r, dt, res, out)
1194
1195 static void test_VarDateFromUdate(void)
1196 {
1197   UDATE ud;
1198   double out;
1199   HRESULT res;
1200
1201   CHECKPTR(VarDateFromUdate);
1202   UD2T(1,1,1980,0,0,0,0,2,1,0,S_OK,29221.0);      /* 1 Jan 1980 */
1203   UD2T(2,1,1980,0,0,0,0,3,2,0,S_OK,29222.0);      /* 2 Jan 1980 */
1204   UD2T(31,12,1990,0,0,0,0,0,0,0,S_OK,33238.0);    /* 31 Dec 1990 */
1205   UD2T(31,12,90,0,0,0,0,0,0,0,S_OK,33238.0);      /* year < 100 is 1900+year! */
1206   UD2T(30,12,1899,0,0,0,0,6,364,0,S_OK,0.0);      /* 30 Dec 1899 - VT_DATE 0.0 */
1207   UD2T(1,1,100,0,0,0,0,0,0,0,S_OK,-657434.0);     /* 1 Jan 100 - Min */
1208   UD2T(31,12,9999,0,0,0,0,0,0,0,S_OK,2958465.0);  /* 31 Dec 9999 - Max */
1209   UD2T(1,1,10000,0,0,0,0,0,0,0,E_INVALIDARG,0.0); /* > 31 Dec 9999 => err  */
1210
1211   UD2T(1,1,1980,18,1,16,0,2,1,0,S_OK,29221.75087962963); /* 6:18:02 PM */
1212
1213   UD2T(0,1,1980,0,0,0,0,2,1,0,S_OK,29220.0);      /* Rolls back to 31 Dec 1899 */
1214   UD2T(1,13,1980,0,0,0,0,2,1,0,S_OK,29587.0);     /* Rolls fwd to 1/1/1981 */
1215 }
1216
1217 #define ST2DT(d,m,y,h,mn,s,ms,r,dt) \
1218   st.wYear = y; st.wMonth = m; st.wDay = d; st.wHour = h; st.wMinute = mn; \
1219   st.wSecond = s; st.wMilliseconds = ms; st.wDayOfWeek = 0; \
1220   res = pSystemTimeToVariantTime(&st, &out); \
1221   ok(r == res && (!r || fabs(out-dt) < 1.0e-11), \
1222      "expected %d, %.16g, got %d, %.16g\n", r, dt, res, out)
1223
1224 static void test_SystemTimeToVariantTime(void)
1225 {
1226   SYSTEMTIME st;
1227   double out;
1228   int res;
1229
1230   CHECKPTR(SystemTimeToVariantTime);
1231   ST2DT(1,1,1980,0,0,0,0,TRUE,29221.0);
1232   ST2DT(2,1,1980,0,0,0,0,TRUE,29222.0);
1233   ST2DT(0,1,1980,0,0,0,0,TRUE,29220.0);   /* Rolls back to 31 Dec 1899 */
1234   ST2DT(1,13,1980,0,0,0,0,FALSE,29587.0); /* Fails on invalid month */
1235   ST2DT(31,12,90,0,0,0,0,TRUE,33238.0);   /* year < 100 is 1900+year! */
1236 }
1237
1238 #define DT2ST(dt,r,d,m,y,h,mn,s,ms) \
1239   memset(&st, 0, sizeof(st)); \
1240   res = pVariantTimeToSystemTime(dt, &st); \
1241   ok(r == res && (!r || (st.wYear == y && st.wMonth == m && st.wDay == d && \
1242      st.wHour == h && st.wMinute == mn && st.wSecond == s && \
1243      st.wMilliseconds == ms)), \
1244      "%.16g expected %d, %d,%d,%d,%d,%d,%d,%d, got %d, %d,%d,%d,%d,%d,%d,%d\n", \
1245      dt, r, d, m, y, h, mn, s, ms, res, st.wDay, st.wMonth, st.wYear, \
1246      st.wHour, st.wMinute, st.wSecond, st.wMilliseconds)
1247
1248 static void test_VariantTimeToSystemTime(void)
1249 {
1250   SYSTEMTIME st;
1251   int res;
1252
1253   CHECKPTR(VariantTimeToSystemTime);
1254   DT2ST(29221.0,1,1,1,1980,0,0,0,0);
1255   DT2ST(29222.0,1,2,1,1980,0,0,0,0);
1256 }
1257
1258 #define MKDOSDATE(d,m,y) ((d & 0x1f) | ((m & 0xf) << 5) | (((y-1980) & 0x7f) << 9))
1259 #define MKDOSTIME(h,m,s) (((s>>1) & 0x1f) | ((m & 0x3f) << 5) | ((h & 0x1f) << 11))
1260
1261 static const char *szDosDateToVarTimeFail = "expected %d, %.16g, got %d, %.16g\n";
1262 #define DOS2DT(d,m,y,h,mn,s,r,dt) out = 0.0; \
1263   dosDate = MKDOSDATE(d,m,y); \
1264   dosTime = MKDOSTIME(h,mn,s); \
1265   res = pDosDateTimeToVariantTime(dosDate, dosTime, &out); \
1266   ok(r == res && (!r || fabs(out-dt) < 1.0e-11), \
1267      szDosDateToVarTimeFail, r, dt, res, out)
1268
1269 static void test_DosDateTimeToVariantTime(void)
1270 {
1271   USHORT dosDate, dosTime;
1272   double out;
1273   INT res;
1274
1275   CHECKPTR(DosDateTimeToVariantTime);
1276
1277   /* Date */
1278   DOS2DT(1,1,1980,0,0,0,1,29221.0); /* 1/1/1980 */
1279   DOS2DT(31,12,2099,0,0,0,1,73050.0); /* 31/12/2099 */
1280   /* Dates are limited to the dos date max of 31/12/2099 */
1281   DOS2DT(31,12,2100,0,0,0,0,0.0); /* 31/12/2100 */
1282   /* Days and months of 0 cause date to roll back 1 day or month */
1283   DOS2DT(0,1,1980,0,0,0,1,29220.0); /* 0 Day => 31/12/1979 */
1284   DOS2DT(1,0,1980,0,0,0,1,29190.0); /* 0 Mth =>  1/12/1979 */
1285   DOS2DT(0,0,1980,0,0,0,1,29189.0); /* 0 D/M => 30/11/1979 */
1286   /* Days > days in the month cause date to roll forward 1 month */
1287   DOS2DT(29,2,1981,0,0,0,1,29646.0); /* 29/2/1981 -> 3/1/1980 */
1288   DOS2DT(30,2,1981,0,0,0,1,29647.0); /* 30/2/1981 -> 4/1/1980 */
1289   /* Takes leap years into account when rolling forward */
1290   DOS2DT(29,2,1980,0,0,0,1,29280.0); /* 2/29/1980 */
1291   /* Months > 12 cause an error */
1292   DOS2DT(2,13,1980,0,0,0,0,0.0);
1293
1294   /* Time */
1295   DOS2DT(1,1,1980,0,0,29,1,29221.00032407407); /* 1/1/1980 12:00:28 AM */
1296   DOS2DT(1,1,1980,0,0,31,1,29221.00034722222); /* 1/1/1980 12:00:30 AM */
1297   DOS2DT(1,1,1980,0,59,0,1,29221.04097222222); /* 1/1/1980 12:59:00 AM */
1298   DOS2DT(1,1,1980,0,60,0,0,0.0);               /* Invalid seconds */
1299   DOS2DT(1,1,1980,23,0,0,1,29221.95833333333); /* 1/1/1980 11:00:00 PM */
1300   DOS2DT(1,1,1980,24,0,0,0,0.0);               /* Invalid hours */
1301 }
1302
1303 #define DT2DOS(dt,r,d,m,y,h,mn,s) dosTime = dosDate = 0; \
1304   expDosDate = MKDOSDATE(d,m,y); \
1305   expDosTime = MKDOSTIME(h,mn,s); \
1306   res = pVariantTimeToDosDateTime(dt, &dosDate, &dosTime); \
1307   ok(r == res && (!r || (dosTime == expDosTime && dosDate == expDosDate)), \
1308      "%g: expected %d,%d(%d/%d/%d),%d(%d:%d:%d) got %d,%d(%d/%d/%d),%d(%d:%d:%d)\n", \
1309      dt, r, expDosDate, expDosDate & 0x1f, (expDosDate >> 5) & 0xf, 1980 + (expDosDate >> 9), \
1310      expDosTime, expDosTime >> 11, (expDosTime >> 5) & 0x3f, (expDosTime & 0x1f), \
1311      res, dosDate, dosDate & 0x1f, (dosDate >> 5) & 0xf, 1980 + (dosDate >> 9), \
1312      dosTime, dosTime >> 11, (dosTime >> 5) & 0x3f, (dosTime & 0x1f))
1313
1314 static void test_VariantTimeToDosDateTime(void)
1315 {
1316   USHORT dosDate, dosTime, expDosDate, expDosTime;
1317   INT res;
1318
1319   CHECKPTR(VariantTimeToDosDateTime);
1320
1321   /* Date */
1322   DT2DOS(29221.0,1,1,1,1980,0,0,0);   /* 1/1/1980 */
1323   DT2DOS(73050.0,1,31,12,2099,0,0,0); /* 31/12/2099 */
1324   DT2DOS(29220.0,0,0,0,0,0,0,0);      /* 31/12/1979 - out of range */
1325   DT2DOS(73415.0,0,0,0,0,0,0,0);      /* 31/12/2100 - out of range */
1326
1327   /* Time */
1328   DT2DOS(29221.00032407407,1,1,1,1980,0,0,29); /* 1/1/1980 12:00:28 AM */
1329   DT2DOS(29221.00034722222,1,1,1,1980,0,0,31); /* 1/1/1980 12:00:30 AM */
1330   DT2DOS(29221.04097222222,1,1,1,1980,0,59,0); /* 1/1/1980 12:59:00 AM */
1331   DT2DOS(29221.95833333333,1,1,1,1980,23,0,0); /* 1/1/1980 11:00:00 PM */
1332 }
1333
1334 #define FMT_NUMBER(vt,val) \
1335   VariantInit(&v); V_VT(&v) = vt; val(&v) = 1; \
1336   hres = pVarFormatNumber(&v,2,0,0,0,0,&str); \
1337   ok(hres == S_OK, "VarFormatNumber (vt %d): returned %8lx\n", vt, hres); \
1338   if (hres == S_OK) \
1339     ok(str && strcmpW(str,szResult1) == 0, \
1340        "VarFormatNumber (vt %d): string different\n", vt)
1341
1342 static void test_VarFormatNumber(void)
1343 {
1344   static const WCHAR szSrc1[] = { '1','\0' };
1345   static const WCHAR szResult1[] = { '1','.','0','0','\0' };
1346   static const WCHAR szSrc2[] = { '-','1','\0' };
1347   static const WCHAR szResult2[] = { '(','1','.','0','0',')','\0' };
1348   char buff[8];
1349   HRESULT hres;
1350   VARIANT v;
1351   BSTR str = NULL;
1352
1353   CHECKPTR(VarFormatNumber);
1354
1355   GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, sizeof(buff)/sizeof(char));
1356   if (buff[0] != '.' || buff[1])
1357   {
1358     trace("Skipping VarFormatNumber tests as decimal separator is '%s'\n", buff);
1359     return;
1360   }
1361
1362   FMT_NUMBER(VT_I1, V_I1);
1363   FMT_NUMBER(VT_UI1, V_UI1);
1364   FMT_NUMBER(VT_I2, V_I2);
1365   FMT_NUMBER(VT_UI2, V_UI2);
1366   FMT_NUMBER(VT_I4, V_I4);
1367   FMT_NUMBER(VT_UI4, V_UI4);
1368   if (HAVE_OLEAUT32_I8)
1369   {
1370     FMT_NUMBER(VT_I8, V_I8);
1371     FMT_NUMBER(VT_UI8, V_UI8);
1372   }
1373   FMT_NUMBER(VT_R4, V_R4);
1374   FMT_NUMBER(VT_R8, V_R8);
1375   FMT_NUMBER(VT_BOOL, V_BOOL);
1376
1377   V_VT(&v) = VT_BSTR;
1378   V_BSTR(&v) = SysAllocString(szSrc1);
1379
1380   hres = pVarFormatNumber(&v,2,0,0,0,0,&str);
1381   ok(hres == S_OK, "VarFormatNumber (bstr): returned %8lx\n", hres);
1382   if (hres == S_OK)
1383     ok(str && strcmpW(str, szResult1) == 0, "VarFormatNumber (bstr): string different\n");
1384   SysFreeString(V_BSTR(&v));
1385   SysFreeString(str);
1386
1387   V_BSTR(&v) = SysAllocString(szSrc2);
1388   hres = pVarFormatNumber(&v,2,0,-1,0,0,&str);
1389   ok(hres == S_OK, "VarFormatNumber (bstr): returned %8lx\n", hres);
1390   if (hres == S_OK)
1391     ok(str && strcmpW(str, szResult2) == 0, "VarFormatNumber (-bstr): string different\n");
1392   SysFreeString(V_BSTR(&v));
1393   SysFreeString(str);
1394 }
1395
1396 #define SIGNED_VTBITS (VTBIT_I1|VTBIT_I2|VTBIT_I4|VTBIT_I8|VTBIT_R4|VTBIT_R8)
1397
1398 static const char *szVarFmtFail = "VT %d|0x%04x Format %s: expected 0x%08lx, '%s', got 0x%08lx, '%s'\n";
1399 #define VARFMT(vt,v,val,fmt,ret,str) do { \
1400   if (out) SysFreeString(out); out = NULL; \
1401   V_VT(&in) = (vt); v(&in) = val; \
1402   if (fmt) MultiByteToWideChar(CP_ACP, 0, fmt, -1, buffW, sizeof(buffW)/sizeof(WCHAR)); \
1403   hres = pVarFormat(&in,fmt ? buffW : NULL,fd,fw,flags,&out); \
1404   if (SUCCEEDED(hres)) WideCharToMultiByte(CP_ACP, 0, out, -1, buff, sizeof(buff),0,0); \
1405   else buff[0] = '\0'; \
1406   ok(hres == ret && (FAILED(ret) || !strcmp(buff, str)), \
1407      szVarFmtFail, \
1408      (vt)&VT_TYPEMASK,(vt)&~VT_TYPEMASK,fmt?fmt:"<null>",ret,str,hres,buff); \
1409   } while(0)
1410
1411 typedef struct tagFMTRES
1412 {
1413   LPCSTR fmt;
1414   LPCSTR one_res;
1415   LPCSTR zero_res;
1416 } FMTRES;
1417
1418 static const FMTRES VarFormat_results[] =
1419 {
1420   { NULL, "1", "0" },
1421   { "", "1", "0" },
1422   { "General Number", "1", "0" },
1423   { "Percent", "100.00%", "0.00%" },
1424   { "Standard", "1.00", "0.00" },
1425   { "Scientific","1.00E+00", "0.00E+00" },
1426   { "True/False", "True", "False" },
1427   { "On/Off", "On", "Off" },
1428   { "Yes/No", "Yes", "No" },
1429   { "#", "1", "" },
1430   { "##", "1", "" },
1431   { "#.#", "1.", "." },
1432   { "0", "1", "0" },
1433   { "00", "01", "00" },
1434   { "0.0", "1.0", "0.0" },
1435   { "00\\c\\o\\p\\y", "01copy","00copy" },
1436   { "\"pos\";\"neg\"", "pos", "pos" },
1437   { "\"pos\";\"neg\";\"zero\"","pos", "zero" }
1438 };
1439
1440 typedef struct tagFMTDATERES
1441 {
1442   DATE   val;
1443   LPCSTR fmt;
1444   LPCSTR res;
1445 } FMTDATERES;
1446
1447 static const FMTDATERES VarFormat_date_results[] =
1448 {
1449   { 0.0, "w", "7" },
1450   { 0.0, "w", "6" },
1451   { 0.0, "w", "5" },
1452   { 0.0, "w", "4" },
1453   { 0.0, "w", "3" },
1454   { 0.0, "w", "2" },
1455   { 0.0, "w", "1" }, /* First 7 entries must remain in this order! */
1456   { 2.525, "am/pm", "pm" },
1457   { 2.525, "AM/PM", "PM" },
1458   { 2.525, "A/P", "P" },
1459   { 2.525, "a/p", "p" },
1460   { 2.525, "q", "1" },
1461   { 2.525, "d", "1" },
1462   { 2.525, "dd", "01" },
1463   { 2.525, "ddd", "Mon" },
1464   { 2.525, "dddd", "Monday" },
1465   { 2.525, "mmm", "Jan" },
1466   { 2.525, "mmmm", "January" },
1467   { 2.525, "y", "1" },
1468   { 2.525, "yy", "00" },
1469   { 2.525, "yyy", "001" },
1470   { 2.525, "yyyy", "1900" },
1471   { 2.525, "dd mm yyyy hh:mm:ss", "01 01 1900 12:36:00" },
1472   { 2.525, "dd mm yyyy mm", "01 01 1900 01" },
1473   { 2.525, "dd mm yyyy :mm", "01 01 1900 :01" },
1474   { 2.525, "dd mm yyyy hh:mm", "01 01 1900 12:36" },
1475   { 2.525, "mm mm", "01 01" },
1476   { 2.525, "mm :mm:ss", "01 :01:00" },
1477   { 2.525, "mm :ss:mm", "01 :00:01" },
1478   { 2.525, "hh:mm :ss:mm", "12:36 :00:01" },
1479   { 2.525, "hh:dd :mm:mm", "12:01 :01:01" },
1480   { 2.525, "dd:hh :mm:mm", "01:12 :36:01" },
1481   { 2.525, "hh :mm:mm", "12 :36:01" },
1482   { 2.525, "dd :mm:mm", "01 :01:01" },
1483   { 2.525, "dd :mm:nn", "01 :01:36" },
1484   { 2.725, "hh:nn:ss A/P", "05:24:00 P" }
1485 };
1486
1487 #define VNUMFMT(vt,v) \
1488   for (i = 0; i < sizeof(VarFormat_results)/sizeof(FMTRES); i++) \
1489   { \
1490     VARFMT(vt,v,1,VarFormat_results[i].fmt,S_OK,VarFormat_results[i].one_res); \
1491     VARFMT(vt,v,0,VarFormat_results[i].fmt,S_OK,VarFormat_results[i].zero_res); \
1492   } \
1493   if ((1 << vt) & SIGNED_VTBITS) \
1494   { \
1495     VARFMT(vt,v,-1,"\"pos\";\"neg\"",S_OK,"neg"); \
1496     VARFMT(vt,v,-1,"\"pos\";\"neg\";\"zero\"",S_OK,"neg"); \
1497   }
1498
1499 static void test_VarFormat(void)
1500 {
1501   static const WCHAR szTesting[] = { 't','e','s','t','i','n','g','\0' };
1502   size_t i;
1503   WCHAR buffW[256];
1504   char buff[256];
1505   VARIANT in;
1506   VARIANT_BOOL bTrue = VARIANT_TRUE, bFalse = VARIANT_FALSE;
1507   int fd = 0, fw = 0;
1508   ULONG flags = 0;
1509   BSTR bstrin, out = NULL;
1510   HRESULT hres;
1511
1512   CHECKPTR(VarFormat);
1513
1514   if (PRIMARYLANGID(LANGIDFROMLCID(GetUserDefaultLCID())) != LANG_ENGLISH)
1515   {
1516     trace("Skipping VarFormat tests for non english language\n");
1517     return;
1518   }
1519   GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, sizeof(buff)/sizeof(char));
1520   if (buff[0] != '.' || buff[1])
1521   {
1522     trace("Skipping VarFormat tests as decimal separator is '%s'\n", buff);
1523     return;
1524   }
1525   GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDIGITS, buff, sizeof(buff)/sizeof(char));
1526   if (buff[0] != '2' || buff[1])
1527   {
1528     trace("Skipping VarFormat tests as decimal places is '%s'\n", buff);
1529     return;
1530   }
1531
1532   VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"True/False",S_OK,"True");
1533   VARFMT(VT_BOOL,V_BOOL,VARIANT_FALSE,"True/False",S_OK,"False");
1534
1535   VNUMFMT(VT_I1,V_I1);
1536   VNUMFMT(VT_I2,V_I2);
1537   VNUMFMT(VT_I4,V_I4);
1538   if (HAVE_OLEAUT32_I8)
1539   {
1540     VNUMFMT(VT_I8,V_I8);
1541   }
1542   VNUMFMT(VT_INT,V_INT);
1543   VNUMFMT(VT_UI1,V_UI1);
1544   VNUMFMT(VT_UI2,V_UI2);
1545   VNUMFMT(VT_UI4,V_UI4);
1546   if (HAVE_OLEAUT32_I8)
1547   {
1548     VNUMFMT(VT_UI8,V_UI8);
1549   }
1550   VNUMFMT(VT_UINT,V_UINT);
1551   VNUMFMT(VT_R4,V_R4);
1552   VNUMFMT(VT_R8,V_R8);
1553
1554   /* Reference types are dereferenced */
1555   VARFMT(VT_BOOL|VT_BYREF,V_BOOLREF,&bTrue,"True/False",S_OK,"True");
1556   VARFMT(VT_BOOL|VT_BYREF,V_BOOLREF,&bFalse,"True/False",S_OK,"False");
1557
1558   /* Dates */
1559   for (i = 0; i < sizeof(VarFormat_date_results)/sizeof(FMTDATERES); i++)
1560   {
1561     if (i < 7)
1562       fd = i + 1; /* Test first day */
1563     else
1564       fd = 0;
1565     VARFMT(VT_DATE,V_DATE,VarFormat_date_results[i].val,
1566            VarFormat_date_results[i].fmt,S_OK,
1567            VarFormat_date_results[i].res);
1568   }
1569
1570   /* Strings */
1571   bstrin = SysAllocString(szTesting);
1572   VARFMT(VT_BSTR,V_BSTR,bstrin,"",S_OK,"testing");
1573   VARFMT(VT_BSTR,V_BSTR,bstrin,"@",S_OK,"testing");
1574   VARFMT(VT_BSTR,V_BSTR,bstrin,"&",S_OK,"testing");
1575   VARFMT(VT_BSTR,V_BSTR,bstrin,"\\x@\\x@",S_OK,"xtxesting");
1576   VARFMT(VT_BSTR,V_BSTR,bstrin,"\\x&\\x&",S_OK,"xtxesting");
1577   VARFMT(VT_BSTR,V_BSTR,bstrin,"@\\x",S_OK,"txesting");
1578   VARFMT(VT_BSTR,V_BSTR,bstrin,"@@@@@@@@",S_OK," testing");
1579   VARFMT(VT_BSTR,V_BSTR,bstrin,"@\\x@@@@@@@",S_OK," xtesting");
1580   VARFMT(VT_BSTR,V_BSTR,bstrin,"&&&&&&&&",S_OK,"testing");
1581   VARFMT(VT_BSTR,V_BSTR,bstrin,"!&&&&&&&",S_OK,"testing");
1582   VARFMT(VT_BSTR,V_BSTR,bstrin,"&&&&&&&!",S_OK,"testing");
1583   VARFMT(VT_BSTR,V_BSTR,bstrin,">&&",S_OK,"TESTING");
1584   VARFMT(VT_BSTR,V_BSTR,bstrin,"<&&",S_OK,"testing");
1585   VARFMT(VT_BSTR,V_BSTR,bstrin,"<&>&",S_OK,"testing");
1586   SysFreeString(bstrin);
1587   /* Numeric values are converted to strings then output */
1588   VARFMT(VT_I1,V_I1,1,"<&>&",S_OK,"1");
1589
1590   /* 'out' is not cleared */
1591   out = (BSTR)0x1;
1592   pVarFormat(&in,NULL,fd,fw,flags,&out); /* Would crash if out is cleared */
1593   out = NULL;
1594
1595   /* Invalid args */
1596   hres = pVarFormat(&in,NULL,fd,fw,flags,NULL);
1597   ok(hres == E_INVALIDARG, "Null out: expected E_INVALIDARG, got 0x%08lx\n", hres);
1598   hres = pVarFormat(NULL,NULL,fd,fw,flags,&out);
1599   ok(hres == E_INVALIDARG, "Null in: expected E_INVALIDARG, got 0x%08lx\n", hres);
1600   fd = -1;
1601   VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,"");
1602   fd = 8;
1603   VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,"");
1604   fd = 0; fw = -1;
1605   VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,"");
1606   fw = 4;
1607   VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,"");
1608 }
1609
1610 static HRESULT (WINAPI *pVarAbs)(LPVARIANT,LPVARIANT);
1611
1612 static const char *szVarAbsFail = "VarAbs: expected 0x0,%d,%d, got 0x%lX,%d,%d\n";
1613 #define VARABS(vt,val,rvt,rval) V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
1614         memset(&vDst,0,sizeof(vDst)); hres = pVarAbs(&v,&vDst); \
1615         ok(hres == S_OK && V_VT(&vDst) == VT_##rvt && V_##rvt(&vDst) == (rval), \
1616            szVarAbsFail, VT_##rvt, (int)(rval), \
1617            hres, V_VT(&vDst), (int)V_##rvt(&vDst))
1618
1619 static void test_VarAbs(void)
1620 {
1621     static const WCHAR szNum[] = {'-','1','.','1','\0' };
1622     char buff[8];
1623     HRESULT hres;
1624     VARIANT v, vDst;
1625     size_t i;
1626
1627     CHECKPTR(VarAbs);
1628
1629     /* Test all possible V_VT values.
1630      */
1631     for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
1632     {
1633         VARTYPE vt;
1634
1635         for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
1636         {
1637             HRESULT hExpected = DISP_E_BADVARTYPE;
1638
1639             SKIPTESTS(vt);
1640
1641             memset(&v, 0, sizeof(v));
1642             V_VT(&v) = vt | ExtraFlags[i];
1643             V_VT(&vDst) = VT_EMPTY;
1644
1645             hres = pVarAbs(&v,&vDst);
1646             if (ExtraFlags[i] & (VT_ARRAY|VT_ARRAY) ||
1647                 (!ExtraFlags[i] && (vt == VT_UNKNOWN || vt == VT_BSTR ||
1648                  vt == VT_DISPATCH || vt == VT_ERROR || vt == VT_RECORD)))
1649             {
1650                 hExpected = DISP_E_TYPEMISMATCH;
1651             }
1652             else if (ExtraFlags[i] || vt >= VT_CLSID || vt == VT_VARIANT)
1653             {
1654                 hExpected = DISP_E_BADVARTYPE;
1655             }
1656             else if (IsValidVariantClearVT(vt, ExtraFlags[i]))
1657                 hExpected = S_OK;
1658
1659             /* Native always fails on some vartypes that should be valid. don't
1660              * check that Wine does the same; these are bugs in native.
1661              */
1662             if (vt == VT_I8 || vt == VT_UI8 || vt == VT_INT || vt == VT_UINT ||
1663                 vt == VT_I1 || vt == VT_UI2 || vt == VT_UI4)
1664                 continue;
1665             ok(hres == hExpected, "VarAbs: expected 0x%lX, got 0x%lX for vt %d | 0x%X\n",
1666                hExpected, hres, vt, ExtraFlags[i]);
1667         }
1668     }
1669
1670     /* BOOL->I2, BSTR->R8, all others remain the same */
1671     VARABS(BOOL,VARIANT_TRUE,I2,-VARIANT_TRUE);
1672     VARABS(BOOL,VARIANT_FALSE,I2,VARIANT_FALSE);
1673     VARABS(EMPTY,0,I2,0);
1674     VARABS(EMPTY,1,I2,0);
1675     VARABS(NULL,0,NULL,0);
1676     VARABS(NULL,1,NULL,0);
1677     VARABS(I2,1,I2,1);
1678     VARABS(I2,-1,I2,1);
1679     VARABS(I4,1,I4,1);
1680     VARABS(I4,-1,I4,1);
1681     VARABS(UI1,1,UI1,1);
1682     VARABS(R4,1,R4,1);
1683     VARABS(R4,-1,R4,1);
1684     VARABS(R8,1,R8,1);
1685     VARABS(R8,-1,R8,1);
1686     VARABS(DATE,1,DATE,1);
1687     VARABS(DATE,-1,DATE,1);
1688     V_VT(&v) = VT_CY;
1689     V_CY(&v).int64 = -10000;
1690     memset(&vDst,0,sizeof(vDst));
1691     hres = pVarAbs(&v,&vDst);
1692     ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == 10000,
1693        "VarAbs(CY): expected 0x0 got 0x%lX\n", hres);
1694     GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, sizeof(buff)/sizeof(char));
1695     if (buff[0] != '.' || buff[1])
1696     {
1697         trace("Skipping VarAbs(BSTR) as decimal separator is '%s'\n", buff);
1698         return;
1699     }
1700     V_VT(&v) = VT_BSTR;
1701     V_BSTR(&v) = (BSTR)szNum;
1702     memset(&vDst,0,sizeof(vDst));
1703     hres = pVarAbs(&v,&vDst);
1704     ok(hres == S_OK && V_VT(&vDst) == VT_R8 && V_R8(&vDst) == 1.1,
1705        "VarAbs: expected 0x0,%d,%g, got 0x%lX,%d,%g\n", VT_R8, 1.1, hres, V_VT(&vDst), V_R8(&vDst));
1706 }
1707
1708 static HRESULT (WINAPI *pVarNot)(LPVARIANT,LPVARIANT);
1709
1710 static const char *szVarNotFail = "VarNot: expected 0x0,%d,%d, got 0x%lX,%d,%d\n";
1711 #define VARNOT(vt,val,rvt,rval) V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
1712         memset(&vDst,0,sizeof(vDst)); hres = pVarNot(&v,&vDst); \
1713         ok(hres == S_OK && V_VT(&vDst) == VT_##rvt && V_##rvt(&vDst) == (rval), \
1714         szVarNotFail, VT_##rvt, (int)(rval), \
1715         hres, V_VT(&vDst), (int)V_##rvt(&vDst))
1716
1717 static void test_VarNot(void)
1718 {
1719     static const WCHAR szNum0[] = {'0','\0' };
1720     static const WCHAR szNum1[] = {'1','\0' };
1721     HRESULT hres;
1722     VARIANT v, vDst;
1723     DECIMAL *pdec = &V_DECIMAL(&v);
1724     CY *pcy = &V_CY(&v);
1725     size_t i;
1726
1727     CHECKPTR(VarNot);
1728
1729     /* Test all possible V_VT values */
1730     for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
1731     {
1732         VARTYPE vt;
1733
1734         for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
1735         {
1736             HRESULT hExpected = DISP_E_BADVARTYPE;
1737
1738             SKIPTESTS(vt);
1739
1740             memset(&v, 0, sizeof(v));
1741             V_VT(&v) = vt | ExtraFlags[i];
1742             V_VT(&vDst) = VT_EMPTY;
1743
1744             switch (V_VT(&v))
1745             {
1746             case VT_I1:  case VT_UI1: case VT_I2:  case VT_UI2:
1747             case VT_INT: case VT_UINT: case VT_I4:  case VT_UI4:
1748             case VT_R4:  case VT_R8:
1749             case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
1750             case VT_DATE: case VT_CY:
1751                 hExpected = S_OK;
1752                 break;
1753             case VT_I8: case VT_UI8:
1754                 if (HAVE_OLEAUT32_I8)
1755                     hExpected = S_OK;
1756                 break;
1757             case VT_RECORD:
1758                 if (HAVE_OLEAUT32_RECORD)
1759                     hExpected = DISP_E_TYPEMISMATCH;
1760                 break;
1761             case VT_UNKNOWN: case VT_BSTR: case VT_DISPATCH: case VT_ERROR:
1762                 hExpected = DISP_E_TYPEMISMATCH;
1763                 break;
1764             default:
1765                 if (IsValidVariantClearVT(vt, ExtraFlags[i]) && vt != VT_CLSID)
1766                    hExpected = DISP_E_TYPEMISMATCH;
1767                 break;
1768             }
1769
1770             hres = pVarNot(&v,&vDst);
1771             ok(hres == hExpected, "VarNot: expected 0x%lX, got 0x%lX vt %d|0x%X\n",
1772                hExpected, hres, vt, ExtraFlags[i]);
1773         }
1774     }
1775     /* Test the values returned by all cases that can succeed */
1776     VARNOT(EMPTY,0,I2,-1);
1777     VARNOT(EMPTY,1,I2,-1);
1778     VARNOT(NULL,0,NULL,0);
1779     VARNOT(NULL,1,NULL,0);
1780     VARNOT(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE);
1781     VARNOT(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE);
1782     VARNOT(I1,-1,I4,0);
1783     VARNOT(I1,0,I4,-1);
1784     VARNOT(I2,-1,I2,0);
1785     VARNOT(I2,0,I2,-1);
1786     VARNOT(I2,1,I2,-2);
1787     VARNOT(I4,1,I4,-2);
1788     VARNOT(I4,0,I4,-1);
1789     VARNOT(UI1,1,UI1,254);
1790     VARNOT(UI1,0,UI1,255);
1791     VARNOT(UI2,0,I4,-1);
1792     VARNOT(UI2,1,I4,-2);
1793     VARNOT(UI4,0,I4,-1);
1794     VARNOT(UI4,1,I4,-2);
1795     VARNOT(INT,0,I4,-1);
1796     VARNOT(INT,1,I4,-2);
1797     VARNOT(UINT,0,I4,-1);
1798     VARNOT(UINT,1,I4,-2);
1799     if (HAVE_OLEAUT32_I8)
1800     {
1801         VARNOT(I8,1,I8,-2);
1802         VARNOT(I8,0,I8,-1);
1803         VARNOT(UI8,0,I4,-1);
1804         VARNOT(UI8,1,I4,-2);
1805     }
1806     VARNOT(R4,1,I4,-2);
1807     VARNOT(R4,0,I4,-1);
1808     VARNOT(R8,1,I4,-2);
1809     VARNOT(R8,0,I4,-1);
1810     VARNOT(DATE,1,I4,-2);
1811     VARNOT(DATE,0,I4,-1);
1812     VARNOT(BSTR,(BSTR)szNum0,I4,-1);
1813     ok(V_VT(&v) == VT_BSTR && V_BSTR(&v) == szNum0, "VarNot(0): changed input\n");
1814     VARNOT(BSTR,(BSTR)szNum1,I4,-2);
1815     ok(V_VT(&v) == VT_BSTR && V_BSTR(&v) == szNum1, "VarNot(1): changed input\n");
1816
1817     V_VT(&v) = VT_DECIMAL;
1818     pdec->u.s.sign = DECIMAL_NEG;
1819     pdec->u.s.scale = 0;
1820     pdec->Hi32 = 0;
1821     pdec->u1.s1.Mid32 = 0;
1822     pdec->u1.s1.Lo32 = 1;
1823     VARNOT(DECIMAL,*pdec,I4,0);
1824
1825     pcy->int64 = 10000;
1826     VARNOT(CY,*pcy,I4,-2);
1827
1828     pcy->int64 = 0;
1829     VARNOT(CY,*pcy,I4,-1);
1830
1831     pcy->int64 = -1;
1832     VARNOT(CY,*pcy,I4,-1);
1833 }
1834 static HRESULT (WINAPI *pVarSub)(LPVARIANT,LPVARIANT,LPVARIANT);
1835
1836 static void test_VarSub(void)
1837 {
1838     VARIANT va, vb, vc;
1839     HRESULT hr;
1840
1841     CHECKPTR(VarSub);
1842
1843     V_VT(&va) = VT_DATE;
1844     V_DATE(&va) = 200000.0;
1845     V_VT(&vb) = VT_DATE;
1846     V_DATE(&vb) = 100000.0;
1847
1848     hr = pVarSub(&va, &vb, &vc);
1849     ok(hr == S_OK,"VarSub of VT_DATE - VT_DATE failed with %lx\n", hr);
1850     ok(V_VT(&vc) == VT_R8,"VarSub of VT_DATE - VT_DATE returned vt 0x%x\n", V_VT(&vc));
1851     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));
1852     /* fprintf(stderr,"VarSub of 10000-20000 returned: %g\n", V_R8(&vc)); */
1853 }
1854
1855 static const char *szVarModFail = "VarMod: expected 0x%lx,%d(%s),%d, got 0x%lX,%d(%s),%d\n";
1856 #define VARMOD(vt1,vt2,val1,val2,rvt,rval,hexpected) V_VT(&v1) = VT_##vt1; V_##vt1(&v1) = val1; \
1857         V_VT(&v2) = VT_##vt2; V_##vt2(&v2) = val2;                  \
1858         memset(&vDst,0,sizeof(vDst)); hres = pVarMod(&v1,&v2,&vDst);                    \
1859         ok(hres == hexpected && V_VT(&vDst) == VT_##rvt && V_##rvt(&vDst) == (rval), \
1860         szVarModFail, hexpected, VT_##rvt, vtstr(VT_##rvt), (int)(rval), \
1861         hres, V_VT(&vDst), vtstr(V_VT(&vDst)), (int)V_##rvt(&vDst))
1862
1863 static const char *szVarMod2Fail = "VarMod: expected 0x%lx,%d(%s),%d, got 0x%lX,%d(%s),%d\n";
1864 #define VARMOD2(vt1,vt2,val1,val2,rvt,rval,hexpected) V_VT(&v1) = VT_##vt1; V_I4(&v1) = val1; \
1865         V_VT(&v2) = VT_##vt2; V_I4(&v2) = val2;                                \
1866         memset(&vDst,0,sizeof(vDst)); hres = pVarMod(&v1,&v2,&vDst);                     \
1867         ok(hres == hexpected && V_VT(&vDst) == VT_##rvt && V_I4(&vDst) == (rval), \
1868         szVarMod2Fail, hexpected, VT_##rvt, vtstr(VT_##rvt), (int)(rval), \
1869         hres, V_VT(&vDst), vtstr(V_VT(&vDst)), (int)V_I4(&vDst))
1870
1871 static HRESULT (WINAPI *pVarMod)(LPVARIANT,LPVARIANT,LPVARIANT);
1872
1873 static void test_VarMod(void)
1874 {
1875   VARIANT v1, v2, vDst;
1876   HRESULT hres;
1877   HRESULT hexpected = 0;
1878   static const WCHAR szNum0[] = {'1','2','5','\0'};
1879   static const WCHAR szNum1[] = {'1','0','\0'};
1880   int l, r;
1881   BOOL lFound, rFound;
1882   BOOL lValid, rValid;
1883   BSTR strNum0, strNum1;
1884
1885   CHECKPTR(VarMod);
1886
1887   VARMOD(I1,BOOL,100,10,I4,0,S_OK);
1888   VARMOD(I1,I1,100,10,I4,0,S_OK);
1889   VARMOD(I1,UI1,100,10,I4,0,S_OK);
1890   VARMOD(I1,I2,100,10,I4,0,S_OK);
1891   VARMOD(I1,UI2,100,10,I4,0,S_OK);
1892   VARMOD(I1,I4,100,10,I4,0,S_OK);
1893   VARMOD(I1,UI4,100,10,I4,0,S_OK);
1894   VARMOD(I1,R4,100,10,I4,0,S_OK);
1895   VARMOD(I1,R8,100,10,I4,0,S_OK);
1896   VARMOD(I1,I8,100,10,I8,0,S_OK);
1897
1898   VARMOD(UI1,BOOL,100,10,I2,0,S_OK);
1899   VARMOD(UI1,I1,100,10,I4,0,S_OK);
1900   VARMOD(UI1,UI1,100,10,UI1,0,S_OK);
1901   VARMOD(UI1,I2,100,10,I2,0,S_OK);
1902   VARMOD(UI1,UI2,100,10,I4,0,S_OK);
1903   VARMOD(UI1,I4,100,10,I4,0,S_OK);
1904   VARMOD(UI1,UI4,100,10,I4,0,S_OK);
1905   VARMOD(UI1,R4,100,10,I4,0,S_OK);
1906   VARMOD(UI1,R8,100,10,I4,0,S_OK);
1907   VARMOD(UI1,I8,100,10,I8,0,S_OK);
1908
1909   VARMOD(I2,BOOL,100,10,I2,0,S_OK);
1910   VARMOD(I2,I1,100,10,I4,0,S_OK);
1911   VARMOD(I2,UI1,100,10,I2,0,S_OK);
1912   VARMOD(I2,I2,100,10,I2,0,S_OK);
1913   VARMOD(I2,UI2,100,10,I4,0,S_OK);
1914   VARMOD(I2,I4,100,10,I4,0,S_OK);
1915   VARMOD(I2,UI4,100,10,I4,0,S_OK);
1916   VARMOD(I2,R4,100,10,I4,0,S_OK);
1917   VARMOD(I2,R8,100,10,I4,0,S_OK);
1918   VARMOD(I2,I8,100,10,I8,0,S_OK);
1919
1920   VARMOD(I4,BOOL,100,10,I4,0,S_OK);
1921   VARMOD(I4,I1,100,10,I4,0,S_OK);
1922   VARMOD(I4,UI1,100,10,I4,0,S_OK);
1923   VARMOD(I4,I2,100,10,I4,0,S_OK);
1924   VARMOD(I4,UI2,100,10,I4,0,S_OK);
1925   VARMOD(I4,I4,100,10,I4,0,S_OK);
1926   VARMOD(I4,UI4,100,10,I4,0,S_OK);
1927   VARMOD(I4,R4,100,10,I4,0,S_OK);
1928   VARMOD(I4,R8,100,10,I4,0,S_OK);
1929   VARMOD(I4,I8,100,10,I8,0,S_OK);
1930
1931   VARMOD(UI4,BOOL,100,10,I4,0,S_OK);
1932   VARMOD(UI4,I1,100,10,I4,0,S_OK);
1933   VARMOD(UI4,UI1,100,10,I4,0,S_OK);
1934   VARMOD(UI4,I2,100,10,I4,0,S_OK);
1935   VARMOD(UI4,UI2,100,10,I4,0,S_OK);
1936   VARMOD(UI4,I4,100,10,I4,0,S_OK);
1937   VARMOD(UI4,UI4,100,10,I4,0,S_OK);
1938   VARMOD(UI4,R4,100,10,I4,0,S_OK);
1939   VARMOD(UI4,R8,100,10,I4,0,S_OK);
1940   VARMOD(UI4,I8,100,10,I8,0,S_OK);
1941
1942   VARMOD(R4,BOOL,100,10,I4,0,S_OK);
1943   VARMOD(R4,I1,100,10,I4,0,S_OK);
1944   VARMOD(R4,UI1,100,10,I4,0,S_OK);
1945   VARMOD(R4,I2,100,10,I4,0,S_OK);
1946   VARMOD(R4,UI2,100,10,I4,0,S_OK);
1947   VARMOD(R4,I4,100,10,I4,0,S_OK);
1948   VARMOD(R4,UI4,100,10,I4,0,S_OK);
1949   VARMOD(R4,R4,100,10,I4,0,S_OK);
1950   VARMOD(R4,R8,100,10,I4,0,S_OK);
1951   VARMOD(R4,I8,100,10,I8,0,S_OK);
1952
1953   VARMOD(R8,BOOL,100,10,I4,0,S_OK);
1954   VARMOD(R8,I1,100,10,I4,0,S_OK);
1955   VARMOD(R8,UI1,100,10,I4,0,S_OK);
1956   VARMOD(R8,I2,100,10,I4,0,S_OK);
1957   VARMOD(R8,UI2,100,10,I4,0,S_OK);
1958   VARMOD(R8,I4,100,10,I4,0,S_OK);
1959   VARMOD(R8,UI4,100,10,I4,0,S_OK);
1960   VARMOD(R8,R4,100,10,I4,0,S_OK);
1961   VARMOD(R8,R8,100,10,I4,0,S_OK);
1962   VARMOD(R8,I8,100,10,I8,0,S_OK);
1963
1964   VARMOD(I8,BOOL,100,10,I8,0,S_OK);
1965   VARMOD(I8,I1,100,10,I8,0,S_OK);
1966   VARMOD(I8,UI1,100,10,I8,0,S_OK);
1967   VARMOD(I8,I2,100,10,I8,0,S_OK);
1968   VARMOD(I8,UI2,100,10,I8,0,S_OK);
1969   VARMOD(I8,I4,100,10,I8,0,S_OK);
1970   VARMOD(I8,UI4,100,10,I8,0,S_OK);
1971   VARMOD(I8,R4,100,10,I8,0,S_OK);
1972   VARMOD(I8,R8,100,10,I8,0,S_OK);
1973   VARMOD(I8,I8,100,10,I8,0,S_OK);
1974
1975   VARMOD(INT,INT,100,10,I4,0,S_OK);
1976   VARMOD(INT,UINT,100,10,I4,0,S_OK);
1977
1978   VARMOD(BOOL,BOOL,100,10,I2,0,S_OK);
1979   VARMOD(BOOL,I1,100,10,I4,0,S_OK);
1980   VARMOD(BOOL,UI1,100,10,I2,0,S_OK);
1981   VARMOD(BOOL,I2,100,10,I2,0,S_OK);
1982   VARMOD(BOOL,UI2,100,10,I4,0,S_OK);
1983   VARMOD(BOOL,I4,100,10,I4,0,S_OK);
1984   VARMOD(BOOL,UI4,100,10,I4,0,S_OK);
1985   VARMOD(BOOL,R4,100,10,I4,0,S_OK);
1986   VARMOD(BOOL,R8,100,10,I4,0,S_OK);
1987   VARMOD(BOOL,I8,100,10,I8,0,S_OK);
1988   VARMOD(BOOL,DATE,100,10,I4,0,S_OK);
1989
1990   VARMOD(DATE,BOOL,100,10,I4,0,S_OK);
1991   VARMOD(DATE,I1,100,10,I4,0,S_OK);
1992   VARMOD(DATE,UI1,100,10,I4,0,S_OK);
1993   VARMOD(DATE,I2,100,10,I4,0,S_OK);
1994   VARMOD(DATE,UI2,100,10,I4,0,S_OK);
1995   VARMOD(DATE,I4,100,10,I4,0,S_OK);
1996   VARMOD(DATE,UI4,100,10,I4,0,S_OK);
1997   VARMOD(DATE,R4,100,10,I4,0,S_OK);
1998   VARMOD(DATE,R8,100,10,I4,0,S_OK);
1999   VARMOD(DATE,I8,100,10,I8,0,S_OK);
2000   VARMOD(DATE,DATE,100,10,I4,0,S_OK);
2001
2002   strNum0 = SysAllocString(szNum0);
2003   strNum1 = SysAllocString(szNum1);
2004   VARMOD(BSTR,BSTR,strNum0,strNum1,I4,5,S_OK);
2005   VARMOD(BSTR,I1,strNum0,10,I4,5,S_OK);
2006   VARMOD(BSTR,I2,strNum0,10,I4,5,S_OK);
2007   VARMOD(BSTR,I4,strNum0,10,I4,5,S_OK);
2008   VARMOD(BSTR,R4,strNum0,10,I4,5,S_OK);
2009   VARMOD(BSTR,R8,strNum0,10,I4,5,S_OK);
2010   VARMOD(BSTR,I8,strNum0,10,I8,5,S_OK);
2011   VARMOD(I4,BSTR,125,strNum1,I4,5,S_OK);
2012
2013   /* test all combinations of types */
2014   for(l = 0; l < VT_BSTR_BLOB; l++)
2015   {
2016     SKIPTESTS(l);
2017
2018     for(r = 0; r < VT_BSTR_BLOB; r++)
2019     {
2020       SKIPTESTS(r);
2021         
2022       if(l == VT_BSTR) continue;
2023       if(l == VT_DISPATCH) continue;
2024       if(r == VT_BSTR) continue;
2025       if(r == VT_DISPATCH) continue;
2026
2027       lFound = TRUE;
2028       lValid = TRUE;
2029       switch(l)
2030         {
2031         case VT_EMPTY:
2032         case VT_NULL:
2033         case VT_I1:
2034         case VT_UI1:
2035         case VT_I2:
2036         case VT_UI2:
2037         case VT_I4:
2038         case VT_I8:
2039         case VT_UI4:
2040         case VT_UI8:
2041         case VT_INT:
2042         case VT_UINT:
2043         case VT_R4:
2044         case VT_R8:
2045         case VT_BOOL:
2046         case VT_DATE:
2047         case VT_CY:
2048           hexpected = S_OK;
2049           break;
2050         case VT_ERROR:
2051         case VT_VARIANT:
2052         case VT_UNKNOWN:
2053         case VT_DECIMAL:
2054         case VT_RECORD:
2055           lValid = FALSE;
2056           break;
2057         default:
2058           lFound = FALSE;
2059           hexpected = DISP_E_BADVARTYPE;
2060           break;
2061         }
2062
2063       rFound = TRUE;
2064       rValid = TRUE;
2065       switch(r)
2066         {
2067         case VT_EMPTY:
2068         case VT_NULL:
2069         case VT_I1:
2070         case VT_UI1:
2071         case VT_I2:
2072         case VT_UI2:
2073         case VT_I4:
2074         case VT_I8:
2075         case VT_UI4:
2076         case VT_UI8:
2077         case VT_INT:
2078         case VT_UINT:
2079         case VT_R4:
2080         case VT_R8:
2081         case VT_BOOL:
2082         case VT_DATE:
2083         case VT_CY:
2084           hexpected = S_OK;
2085           break;
2086         case VT_ERROR:
2087         case VT_VARIANT:
2088         case VT_UNKNOWN:
2089         case VT_DECIMAL:
2090         case VT_RECORD:
2091           rValid = FALSE;
2092           break;
2093         default:
2094           rFound = FALSE;
2095           break;
2096         }
2097
2098       if(((l == VT_I8) && (r == VT_INT)) || ((l == VT_INT) && (r == VT_I8)))
2099       {
2100         hexpected = DISP_E_TYPEMISMATCH;
2101       } else if((l == VT_EMPTY) && (r == VT_NULL))
2102       {
2103         hexpected = S_OK;
2104       } else if((l == VT_NULL) && (r == VT_EMPTY))
2105       {
2106         hexpected = S_OK;
2107       } else if((l == VT_EMPTY) && (r == VT_CY))
2108       {
2109         hexpected = S_OK;
2110       } else if((l == VT_EMPTY) && (r == VT_RECORD))
2111       {
2112         hexpected = DISP_E_TYPEMISMATCH;
2113       } else if((r == VT_EMPTY) && lFound && lValid)
2114       {
2115         hexpected = DISP_E_DIVBYZERO;
2116       } else if((l == VT_ERROR) || ((r == VT_ERROR) && lFound && lValid))
2117       {
2118         hexpected = DISP_E_TYPEMISMATCH;
2119       } else if((l == VT_NULL) && (r == VT_NULL))
2120       {
2121         hexpected = S_OK;
2122       } else if((l == VT_VARIANT) || ((r == VT_VARIANT) && lFound && lValid))
2123       {
2124         hexpected = DISP_E_TYPEMISMATCH;
2125       } else if((l == VT_NULL) && (r == VT_RECORD))
2126       {
2127         hexpected = DISP_E_TYPEMISMATCH;
2128       } else if((l == VT_NULL) && (r == VT_DECIMAL))
2129       {
2130         hexpected = E_INVALIDARG;
2131       } else if((l == VT_UNKNOWN) || ((r == VT_UNKNOWN) && lFound && lValid))
2132       {
2133         hexpected = DISP_E_TYPEMISMATCH;
2134       } else if((l == VT_NULL) && rFound)
2135       {
2136         hexpected = S_OK;
2137       } else if((l == VT_DECIMAL) || ((r == VT_DECIMAL) && lFound && lValid))
2138       {
2139         hexpected = E_INVALIDARG;
2140       } else if(l == VT_RECORD)
2141       {
2142         hexpected = DISP_E_TYPEMISMATCH;
2143       } else if((r == VT_RECORD) && lValid && lFound)
2144       {
2145         hexpected = DISP_E_TYPEMISMATCH;
2146       } else if((l == VT_EMPTY) && (r == VT_EMPTY))
2147       {
2148         hexpected = DISP_E_DIVBYZERO;
2149       } else if((l == VT_CY) && !rFound)
2150       {
2151         hexpected = DISP_E_BADVARTYPE;
2152       } else if(lFound && !rFound)
2153       {
2154         hexpected = DISP_E_BADVARTYPE;
2155       } else if(!lFound && rFound)
2156       {
2157         hexpected = DISP_E_BADVARTYPE;
2158       } else if((r == VT_NULL) && lFound && lValid)
2159       {
2160         hexpected = S_OK;
2161       } else if((l == VT_NULL) || (r == VT_NULL))
2162       {
2163         hexpected = DISP_E_BADVARTYPE;
2164       } else if((l == VT_VARIANT) || (r == VT_VARIANT))
2165       {
2166         hexpected = DISP_E_BADVARTYPE;
2167       } else if(lFound && !rFound)
2168       {
2169         hexpected = DISP_E_BADVARTYPE;
2170       } else if(!lFound && !rFound)
2171       {
2172         hexpected = DISP_E_BADVARTYPE;
2173       }
2174
2175       V_VT(&v1) = l;
2176       V_VT(&v2) = r;
2177
2178       if(l == VT_CY)
2179         V_CY(&v1).int64 = 1000000;
2180       else if(l == VT_R4)
2181         V_R4(&v1) = 100;
2182       else if(l == VT_R8)
2183         V_R8(&v1) = 100;
2184       else if(l == VT_UI8)
2185         V_UI8(&v1) = 100;
2186       else if(l == VT_DATE)
2187         V_DATE(&v1) = 1000;
2188       else
2189         V_I4(&v1) = 10000;
2190
2191       if(r == VT_CY)
2192         V_CY(&v2).int64 = 10000;
2193       else if(r == VT_R4)
2194         V_R4(&v2) = 100;
2195       else if(r == VT_R8)
2196         V_R8(&v2) = 100;
2197       else if(r == VT_UI8)
2198         V_UI8(&v2) = 100;
2199       else if(r == VT_DATE)
2200         V_DATE(&v2) = 1000;
2201       else
2202         V_I4(&v2) = 10000;
2203
2204       hres = pVarMod(&v1,&v2,&vDst);
2205       ok(hres == hexpected,
2206          "VarMod: expected 0x%lx, got 0x%lX for l type of %d, r type of %d,\n", hexpected, hres, l, r);
2207     }
2208   }
2209
2210
2211   /****************************/
2212   /* test some bad parameters */
2213   VARMOD(I4,I4,-1,-1,I4,0,S_OK);
2214
2215   /* test modulus with zero */
2216   VARMOD2(I4,I4,100,0,EMPTY,0,DISP_E_DIVBYZERO);
2217
2218   VARMOD(I4,I4,0,10,I4,0,S_OK); /* test 0 mod 10 */
2219
2220   /* right parameter is type empty */
2221   VARMOD2(I4,EMPTY,100,10,EMPTY,0,DISP_E_DIVBYZERO);
2222
2223   /* left parameter is type empty */
2224   VARMOD2(EMPTY,I4,100,10,I4,0,S_OK);
2225
2226   /* mod with a null left value */
2227   VARMOD2(NULL,I4,125,10,NULL,0,S_OK);
2228
2229   /* mod with a null right value */
2230   VARMOD2(I4,NULL,100,10,NULL,0,S_OK);
2231
2232   /* void left value */
2233   VARMOD2(VOID,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2234
2235   /* void right value */
2236   VARMOD2(I4,VOID,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2237
2238   /* null left value, void right value */
2239   VARMOD2(NULL,VOID,100,10,EMPTY, 0, DISP_E_BADVARTYPE);
2240
2241   /* void left value, null right value */
2242   VARMOD2(VOID,NULL,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2243
2244   /* some currencies */
2245   V_VT(&v1) = VT_CY;
2246   V_VT(&v2) = VT_CY;
2247   V_CY(&v1).int64 = 100000;
2248   V_CY(&v2).int64 = 100000;
2249   hres = pVarMod(&v1,&v2,&vDst);
2250   ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == 0,
2251      "VarMod: expected 0x%lx,%d,%d, got 0x%lX,%d,%ld\n", S_OK, VT_I4, 0, hres, V_VT(&vDst), V_I4(&vDst));
2252
2253   V_VT(&v1) = VT_I4;
2254   V_VT(&v2) = VT_CY;
2255   V_I4(&v1) = 100;
2256   V_CY(&v2).int64 = 100000;
2257   hres = pVarMod(&v1,&v2,&vDst);
2258   ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == 0,
2259      "VarMod: expected 0x%lx,%d,%d, got 0x%lX,%d,%ld\n", S_OK, VT_I4, 0, hres, V_VT(&vDst), V_I4(&vDst));
2260
2261   VARMOD2(UINT,I4,100,10,I4,0,S_OK);
2262
2263   /* test that an error results in the type of the result changing but not its value */
2264   V_VT(&v1) = VT_UNKNOWN;
2265   V_VT(&v2) = VT_EMPTY;
2266   V_I4(&v1) = 100;
2267   V_CY(&v2).int64 = 100000;
2268   V_VT(&vDst) = VT_I4;
2269   V_I4(&vDst) = 1231;
2270   hres = pVarMod(&v1,&v2,&vDst);
2271   ok(hres == DISP_E_TYPEMISMATCH && V_VT(&vDst) == VT_EMPTY && V_I4(&vDst) == 1231,
2272      "VarMod: expected 0x%lx,%d,%d, got 0x%lX,%d,%ld\n", DISP_E_TYPEMISMATCH, VT_EMPTY, 1231, hres, V_VT(&vDst), V_I4(&vDst));
2273
2274
2275   /* test some invalid types */
2276   /*TODO: not testing VT_DISPATCH */
2277   VARMOD2(I8,INT,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
2278   VARMOD2(ERROR,I4,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
2279   VARMOD2(VARIANT,I4,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
2280   VARMOD2(UNKNOWN,I4,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
2281   VARMOD2(DECIMAL,I4,100,10,EMPTY,0,E_INVALIDARG);
2282   VARMOD2(VOID,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2283   VARMOD2(HRESULT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2284   VARMOD2(PTR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2285   VARMOD2(SAFEARRAY,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2286   VARMOD2(CARRAY,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2287   VARMOD2(USERDEFINED,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2288   VARMOD2(LPSTR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2289   VARMOD2(LPWSTR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2290   VARMOD2(RECORD,I4,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
2291   VARMOD2(FILETIME,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2292   VARMOD2(BLOB,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2293   VARMOD2(STREAM,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2294   VARMOD2(STORAGE,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2295   VARMOD2(STREAMED_OBJECT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2296   VARMOD2(STORED_OBJECT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2297   VARMOD2(BLOB_OBJECT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2298   VARMOD2(CF,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2299   VARMOD2(CLSID,CLSID,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2300   VARMOD2(VECTOR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2301   VARMOD2(ARRAY,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2302   VARMOD2(BYREF,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
2303
2304   /* test some more invalid types */
2305   V_VT(&v1) = 456;
2306   V_VT(&v2) = 234;
2307   V_I4(&v1) = 100;
2308   V_I4(&v2)=  10;
2309   hres = pVarMod(&v1,&v2,&vDst);
2310   ok(hres == DISP_E_BADVARTYPE && V_VT(&vDst) == VT_EMPTY && V_I4(&vDst) == 0,
2311      "VarMod: expected 0x%lx,%d,%d, got 0x%lX,%d,%ld\n", DISP_E_BADVARTYPE, VT_EMPTY, 0, hres, V_VT(&vDst), V_I4(&vDst));
2312 }
2313
2314 static HRESULT (WINAPI *pVarFix)(LPVARIANT,LPVARIANT);
2315
2316 static const char *szVarFixFail = "VarFix: expected 0x0,%d,%d, got 0x%lX,%d,%d\n";
2317 #define VARFIX(vt,val,rvt,rval) V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
2318         memset(&vDst,0,sizeof(vDst)); hres = pVarFix(&v,&vDst); \
2319         ok(hres == S_OK && V_VT(&vDst) == VT_##rvt && V_##rvt(&vDst) == (rval), \
2320         szVarFixFail, VT_##rvt, (int)(rval), \
2321         hres, V_VT(&vDst), (int)V_##rvt(&vDst))
2322
2323 static void test_VarFix(void)
2324 {
2325     static const WCHAR szNumMinus1[] = {'-','1','\0' };
2326     HRESULT hres;
2327     VARIANT v, vDst;
2328     DECIMAL *pdec = &V_DECIMAL(&v);
2329     CY *pcy = &V_CY(&v);
2330     size_t i;
2331
2332     CHECKPTR(VarFix);
2333
2334     /* Test all possible V_VT values */
2335     for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
2336     {
2337         VARTYPE vt;
2338
2339         for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
2340         {
2341             HRESULT bFail = TRUE;
2342
2343             SKIPTESTS(vt);
2344
2345             memset(&v, 0, sizeof(v));
2346             V_VT(&v) = vt | ExtraFlags[i];
2347             V_VT(&vDst) = VT_EMPTY;
2348
2349             switch (V_VT(&v))
2350             {
2351               case VT_UI1: case VT_I2: case VT_I4: case VT_R4:  case VT_R8:
2352               case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
2353               case VT_DATE: case VT_CY:
2354                 bFail = FALSE;
2355                 break;
2356               case VT_I8:
2357                 if (HAVE_OLEAUT32_I8)
2358                   bFail = FALSE;
2359                 break;
2360             }
2361
2362             hres = pVarFix(&v,&vDst);
2363             if (bFail)
2364               ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
2365                  "VarFix: expected failure, got 0x%lX vt %d|0x%X\n",
2366                  hres, vt, ExtraFlags[i]);
2367             else
2368                  ok(hres == S_OK, "VarFix: expected S_OK, got 0x%lX vt %d|0x%X\n",
2369                     hres, vt, ExtraFlags[i]);
2370         }
2371     }
2372
2373     VARFIX(BOOL,VARIANT_TRUE,I2,VARIANT_TRUE);
2374     VARFIX(BOOL,VARIANT_FALSE,I2,0);
2375     VARFIX(BOOL,1,I2,1);
2376     VARFIX(UI1,1,UI1,1);
2377     VARFIX(I2,-1,I2,-1);
2378     VARFIX(I4,-1,I4,-1);
2379     if (HAVE_OLEAUT32_I8)
2380     {
2381         VARFIX(I8,-1,I8,-1);
2382     }
2383     VARFIX(R4,1.4,R4,1);
2384     VARFIX(R4,1.5,R4,1);
2385     VARFIX(R4,1.6,R4,1);
2386     VARFIX(R4,-1.4,R4,-1);
2387     VARFIX(R4,-1.5,R4,-1);
2388     VARFIX(R4,-1.6,R4,-1);
2389     /* DATE & R8 round as for R4 */
2390     VARFIX(DATE,-1,DATE,-1);
2391     VARFIX(R8,-1,R8,-1);
2392     VARFIX(BSTR,(BSTR)szNumMinus1,R8,-1);
2393
2394     V_VT(&v) = VT_EMPTY;
2395     hres = pVarFix(&v,&vDst);
2396     ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
2397        "VarFix: expected 0x0,%d,0 got 0x%lX,%d,%d\n", VT_EMPTY,
2398        hres, V_VT(&vDst), V_I2(&vDst));
2399
2400     V_VT(&v) = VT_NULL;
2401     hres = pVarFix(&v,&vDst);
2402     ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
2403        "VarFix: expected 0x0,%d got 0x%lX,%d\n", VT_NULL, hres, V_VT(&vDst));
2404
2405     V_VT(&v) = VT_DECIMAL;
2406     pdec->u.s.sign = DECIMAL_NEG;
2407     pdec->u.s.scale = 0;
2408     pdec->Hi32 = 0;
2409     pdec->u1.s1.Mid32 = 0;
2410     pdec->u1.s1.Lo32 = 1;
2411     hres = pVarFix(&v,&vDst);
2412     ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL && !memcmp(&v, &vDst, sizeof(v)),
2413        "VarFix: expected 0x0,%d,identical, got 0x%lX,%d\n", VT_DECIMAL,
2414        hres, V_VT(&vDst));
2415
2416     /* FIXME: Test some fractional decimals when VarDecFix is implemented */
2417
2418     V_VT(&v) = VT_CY;
2419     pcy->int64 = -10000;
2420     hres = pVarFix(&v,&vDst);
2421     ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
2422        "VarFix: VT_CY wrong, hres=0x%lX\n", hres);
2423
2424     V_VT(&v) = VT_CY;
2425     pcy->int64 = -16000;
2426     hres = pVarFix(&v,&vDst);
2427     ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
2428        "VarFix: VT_CY wrong, hres=0x%lX\n", hres);
2429 }
2430
2431 static HRESULT (WINAPI *pVarInt)(LPVARIANT,LPVARIANT);
2432
2433 static const char *szVarIntFail = "VarInt: expected 0x0,%d,%d, got 0x%lX,%d,%d\n";
2434 #define VARINT(vt,val,rvt,rval) V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
2435         memset(&vDst,0,sizeof(vDst)); hres = pVarInt(&v,&vDst); \
2436         ok(hres == S_OK && V_VT(&vDst) == VT_##rvt && V_##rvt(&vDst) == (rval), \
2437         szVarIntFail, VT_##rvt, (int)(rval), \
2438         hres, V_VT(&vDst), (int)V_##rvt(&vDst))
2439
2440 static void test_VarInt(void)
2441 {
2442     static const WCHAR szNumMinus1[] = {'-','1','\0' };
2443     HRESULT hres;
2444     VARIANT v, vDst;
2445     DECIMAL *pdec = &V_DECIMAL(&v);
2446     CY *pcy = &V_CY(&v);
2447     size_t i;
2448
2449     CHECKPTR(VarInt);
2450
2451     /* Test all possible V_VT values */
2452     for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
2453     {
2454         VARTYPE vt;
2455
2456         for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
2457         {
2458             HRESULT bFail = TRUE;
2459
2460             SKIPTESTS(vt);
2461
2462             memset(&v, 0, sizeof(v));
2463             V_VT(&v) = vt | ExtraFlags[i];
2464             V_VT(&vDst) = VT_EMPTY;
2465
2466             switch (V_VT(&v))
2467             {
2468               case VT_UI1: case VT_I2: case VT_I4: case VT_R4:  case VT_R8:
2469               case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
2470               case VT_DATE: case VT_CY:
2471                 bFail = FALSE;
2472                 break;
2473               case VT_I8:
2474                 if (HAVE_OLEAUT32_I8)
2475                   bFail = FALSE;
2476                 break;
2477             }
2478
2479             hres = pVarInt(&v,&vDst);
2480             if (bFail)
2481               ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
2482                  "VarInt: expected failure, got 0x%lX vt %d|0x%X\n",
2483                  hres, vt, ExtraFlags[i]);
2484             else
2485                  ok(hres == S_OK, "VarInt: expected S_OK, got 0x%lX vt %d|0x%X\n",
2486                     hres, vt, ExtraFlags[i]);
2487         }
2488     }
2489
2490     VARINT(BOOL,VARIANT_TRUE,I2,VARIANT_TRUE);
2491     VARINT(BOOL,VARIANT_FALSE,I2,0);
2492     VARINT(BOOL,1,I2,1);
2493     VARINT(UI1,1,UI1,1);
2494     VARINT(I2,-1,I2,-1);
2495     VARINT(I4,-1,I4,-1);
2496     if (HAVE_OLEAUT32_I8)
2497     {
2498         VARINT(I8,-1,I8,-1);
2499     }
2500     VARINT(R4,1.4,R4,1);
2501     VARINT(R4,1.5,R4,1);
2502     VARINT(R4,1.6,R4,1);
2503     VARINT(R4,-1.4,R4,-2); /* Note these 3 are different from VarFix */
2504     VARINT(R4,-1.5,R4,-2);
2505     VARINT(R4,-1.6,R4,-2);
2506     /* DATE & R8 round as for R4 */
2507     VARINT(DATE,-1,DATE,-1);
2508     VARINT(R8,-1,R8,-1);
2509     VARINT(BSTR,(BSTR)szNumMinus1,R8,-1);
2510
2511     V_VT(&v) = VT_EMPTY;
2512     hres = pVarInt(&v,&vDst);
2513     ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
2514        "VarInt: expected 0x0,%d,0 got 0x%lX,%d,%d\n", VT_EMPTY,
2515        hres, V_VT(&vDst), V_I2(&vDst));
2516
2517     V_VT(&v) = VT_NULL;
2518     hres = pVarInt(&v,&vDst);
2519     ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
2520        "VarInt: expected 0x0,%d got 0x%lX,%d\n", VT_NULL, hres, V_VT(&vDst));
2521
2522     V_VT(&v) = VT_DECIMAL;
2523     pdec->u.s.sign = DECIMAL_NEG;
2524     pdec->u.s.scale = 0;
2525     pdec->Hi32 = 0;
2526     pdec->u1.s1.Mid32 = 0;
2527     pdec->u1.s1.Lo32 = 1;
2528     hres = pVarInt(&v,&vDst);
2529     ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL && !memcmp(&v, &vDst, sizeof(v)),
2530        "VarInt: expected 0x0,%d,identical, got 0x%lX,%d\n", VT_DECIMAL,
2531        hres, V_VT(&vDst));
2532
2533     /* FIXME: Test some fractional decimals when VarDecInt is implemented */
2534
2535     V_VT(&v) = VT_CY;
2536     pcy->int64 = -10000;
2537     hres = pVarInt(&v,&vDst);
2538     ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
2539        "VarInt: VT_CY wrong, hres=0x%lX\n", hres);
2540
2541     V_VT(&v) = VT_CY;
2542     pcy->int64 = -11000;
2543     hres = pVarInt(&v,&vDst);
2544     ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -20000,
2545        "VarInt: VT_CY wrong, hres=0x%lX %lld\n", hres,V_CY(&vDst).int64);
2546 }
2547
2548 static HRESULT (WINAPI *pVarNeg)(LPVARIANT,LPVARIANT);
2549
2550 static const char *szVarNegFail = "VarNeg: expected 0x0,%d,%d, got 0x%lX,%d,%d\n";
2551 #define VARNEG(vt,val,rvt,rval) V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
2552         memset(&vDst,0,sizeof(vDst)); hres = pVarNeg(&v,&vDst); \
2553         ok(hres == S_OK && V_VT(&vDst) == VT_##rvt && V_##rvt(&vDst) == (rval), \
2554         szVarNegFail, VT_##rvt, (int)(rval), \
2555         hres, V_VT(&vDst), (int)V_##rvt(&vDst))
2556
2557 static void test_VarNeg(void)
2558 {
2559     static const WCHAR szNumMinus1[] = {'-','1','\0' };
2560     static const WCHAR szNum1[] = {'1','\0' };
2561     HRESULT hres;
2562     VARIANT v, vDst;
2563     DECIMAL *pdec = &V_DECIMAL(&v);
2564     CY *pcy = &V_CY(&v);
2565     size_t i;
2566
2567     CHECKPTR(VarNeg);
2568
2569     /* Test all possible V_VT values. But don't test the exact return values
2570      * except for success/failure, since M$ made a hash of them in the
2571      * native version. This at least ensures (as with all tests here) that
2572      * we will notice if/when new vtypes/flags are added in native.
2573      */
2574     for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
2575     {
2576         VARTYPE vt;
2577
2578         for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
2579         {
2580             HRESULT bFail = TRUE;
2581
2582             SKIPTESTS(vt);
2583
2584             memset(&v, 0, sizeof(v));
2585             V_VT(&v) = vt | ExtraFlags[i];
2586             V_VT(&vDst) = VT_EMPTY;
2587
2588             switch (V_VT(&v))
2589             {
2590             case VT_UI1: case VT_I2: case VT_I4:
2591             case VT_R4:  case VT_R8:
2592             case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
2593             case VT_DATE: case VT_CY:
2594                 bFail = FALSE;
2595                 break;
2596             case VT_I8:
2597                 if (HAVE_OLEAUT32_I8)
2598                     bFail = FALSE;
2599             }
2600
2601             hres = pVarNeg(&v,&vDst);
2602             if (bFail)
2603                 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
2604                    "VarNeg: expected failure, got 0x%lX vt %d|0x%X\n",
2605                    hres, vt, ExtraFlags[i]);
2606             else
2607                 ok(hres == S_OK, "VarNeg: expected S_OK, got 0x%lX vt %d|0x%X\n",
2608                     hres, vt, ExtraFlags[i]);
2609         }
2610     }
2611
2612     VARNEG(BOOL,VARIANT_TRUE,I2,1);
2613     VARNEG(BOOL,VARIANT_FALSE,I2,0);
2614     VARNEG(BOOL,1,I2,-1);
2615     VARNEG(UI1,1,I2,-1);
2616     VARNEG(UI1,254,I2,-254);
2617     VARNEG(I2,-32768,I4,32768);
2618     VARNEG(I2,-1,I2,1);
2619     VARNEG(I2,1,I2,-1);
2620     VARNEG(I4,-((int)(~0u >> 1)) - 1,R8,-2147483648u);
2621     VARNEG(I4,-1,I4,1);
2622     VARNEG(I4,1,I4,-1);
2623     if (HAVE_OLEAUT32_I8)
2624     {
2625         VARNEG(I8,1,I8,-1);
2626         VARNEG(I8,-1,I8,1);
2627     }
2628     VARNEG(R4,1,R4,-1);
2629     VARNEG(R4,-1,R4,1);
2630     VARNEG(DATE,1,DATE,-1);
2631     VARNEG(DATE,-1,DATE,1);
2632     VARNEG(R8,1,R8,-1);
2633     VARNEG(R8,-1,R8,1);
2634     VARNEG(BSTR,(BSTR)szNumMinus1,R8,1);
2635     VARNEG(BSTR,(BSTR)szNum1,R8,-1);
2636
2637     V_VT(&v) = VT_EMPTY;
2638     hres = pVarNeg(&v,&vDst);
2639     ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
2640        "VarNeg: expected 0x0,%d,0 got 0x%lX,%d,%d\n", VT_EMPTY,
2641        hres, V_VT(&vDst), V_I2(&vDst));
2642
2643     V_VT(&v) = VT_NULL;
2644     hres = pVarNeg(&v,&vDst);
2645     ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
2646        "VarNeg: expected 0x0,%d got 0x%lX,%d\n", VT_NULL, hres, V_VT(&vDst));
2647
2648     V_VT(&v) = VT_DECIMAL;
2649     pdec->u.s.sign = DECIMAL_NEG;
2650     pdec->u.s.scale = 0;
2651     pdec->Hi32 = 0;
2652     pdec->u1.s1.Mid32 = 0;
2653     pdec->u1.s1.Lo32 = 1;
2654     hres = pVarNeg(&v,&vDst);
2655     ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
2656        V_DECIMAL(&vDst).u.s.sign == 0,
2657        "VarNeg: expected 0x0,%d,0x00, got 0x%lX,%d,%02x\n", VT_DECIMAL,
2658        hres, V_VT(&vDst), V_DECIMAL(&vDst).u.s.sign);
2659
2660     pdec->u.s.sign = 0;
2661     hres = pVarNeg(&v,&vDst);
2662     ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
2663        V_DECIMAL(&vDst).u.s.sign == DECIMAL_NEG,
2664        "VarNeg: expected 0x0,%d,0x7f, got 0x%lX,%d,%02x\n", VT_DECIMAL,
2665        hres, V_VT(&vDst), V_DECIMAL(&vDst).u.s.sign);
2666
2667     V_VT(&v) = VT_CY;
2668     pcy->int64 = -10000;
2669     hres = pVarNeg(&v,&vDst);
2670     ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == 10000,
2671        "VarNeg: VT_CY wrong, hres=0x%lX\n", hres);
2672 }
2673
2674 static HRESULT (WINAPI *pVarRound)(LPVARIANT,int,LPVARIANT);
2675
2676 #define VARROUND(vt,val,deci,rvt,rval) V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
2677         memset(&vDst,0,sizeof(vDst)); hres = pVarRound(&v,deci,&vDst); \
2678         ok(hres == S_OK && V_VT(&vDst) == VT_##rvt && V_##rvt(&vDst) == (rval), \
2679         "VarRound: expected 0x0,%d,%d, got 0x%lX,%d,%d\n", VT_##rvt, (int)(rval), \
2680         hres, V_VT(&vDst), (int)V_##rvt(&vDst))
2681
2682 #define VARROUNDF(vt,val,deci,rvt,rval) V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
2683         memset(&vDst,0,sizeof(vDst)); hres = pVarRound(&v,deci,&vDst); \
2684         ok(hres == S_OK && V_VT(&vDst) == VT_##rvt && V_##rvt(&vDst) == (rval), \
2685         "VarRound: expected 0x0,%d,%f, got 0x%lX,%d,%f\n", VT_##rvt, rval, \
2686         hres, V_VT(&vDst), V_##rvt(&vDst))
2687
2688 static void test_VarRound(void)
2689 {
2690     /* static const WCHAR szNumMin[] = {'-','1','.','4','5','\0' };
2691        static const WCHAR szNum[] = {'1','.','4','5','\0' }; */
2692     HRESULT hres;
2693     VARIANT v, vDst;
2694     CY *pcy = &V_CY(&v);
2695
2696     CHECKPTR(VarRound);
2697
2698     /* first check valid integer types */
2699     VARROUND(BOOL,VARIANT_TRUE,0,I2,-1);
2700     VARROUND(BOOL,VARIANT_FALSE,0,I2,0);
2701     VARROUND(BOOL,1,0,I2,1);
2702     VARROUND(UI1,1,0,UI1,1);
2703     VARROUND(UI1,254,0,UI1,254);
2704     VARROUND(I2,-32768,0,I2,-32768);
2705     VARROUND(I2,-1,0,I2,-1);
2706     VARROUND(I2,1,0,I2,1);
2707     VARROUND(I4,-((int)(~0u >> 1)) - 1,0,I4,-((int)(~0u >> 1)) - 1);
2708     VARROUND(I4,-1,0,I4,-1);
2709     VARROUND(I4,1,0,I4,1);
2710
2711
2712     /* MSDN states that rounding of R4/R8 is dependent on the underlying
2713      * bit pattern of the number and so is architecture dependent. In this
2714      * case Wine returns .2 (which is more correct) and Native returns .3
2715      */
2716
2717     VARROUNDF(R4,1.0,0,R4,1.0);
2718     VARROUNDF(R4,-1.0,0,R4,-1.0);
2719     VARROUNDF(R8,1.0,0,R8,1.0);
2720     VARROUNDF(R8,-1.0,0,R8,-1.0);
2721
2722     /* floating point numbers aren't exactly equal and we can't just
2723      * compare the first few digits.
2724     todo_wine {
2725         VARROUNDF(DATE,1.451,1,DATE,1.5);
2726         VARROUNDF(DATE,-1.45,1,DATE,-1.4);
2727         VARROUNDF(BSTR,(BSTR)szNumMin,1,R8,-1.40);
2728         VARROUNDF(BSTR,(BSTR)szNum,1,R8,1.50);
2729
2730         VARROUNDF(R4,1.23456,0,R4,1.0);
2731         VARROUNDF(R4,1.23456,1,R4,1.2);
2732         VARROUNDF(R4,1.23456,2,R4,1.23);
2733         VARROUNDF(R4,1.23456,3,R4,1.235);
2734         VARROUNDF(R4,1.23456,4,R4,1.2346);
2735         VARROUNDF(R4,-1.23456,0,R4,-1.0);
2736         VARROUNDF(R4,-1.23456,1,R4,-1.2);
2737         VARROUNDF(R4,-1.23456,2,R4,-1.23);
2738         VARROUNDF(R4,-1.23456,3,R4,-1.235);
2739         VARROUNDF(R4,-1.23456,4,R4,-1.2346);
2740
2741         VARROUNDF(R8,1.23456,0,R8,1.0);
2742         VARROUNDF(R8,1.23456,1,R8,1.2);
2743         VARROUNDF(R8,1.23456,2,R8,1.23);
2744         VARROUNDF(R8,1.23456,3,R8,1.235);
2745         VARROUNDF(R8,1.23456,4,R8,1.2346);
2746         VARROUNDF(R8,-1.23456,0,R8,-1.0);
2747         VARROUNDF(R8,-1.23456,1,R8,-1.2);
2748         VARROUNDF(R8,-1.23456,2,R8,-1.23);
2749         VARROUNDF(R8,-1.23456,3,R8,-1.235);
2750         VARROUNDF(R8,-1.23456,4,R8,-1.2346);
2751     }
2752     */
2753
2754     V_VT(&v) = VT_EMPTY;
2755     hres = pVarRound(&v,0,&vDst);
2756     ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
2757         "VarRound: expected 0x0,%d,0 got 0x%lX,%d,%d\n", VT_EMPTY,
2758         hres, V_VT(&vDst), V_I2(&vDst));
2759
2760     V_VT(&v) = VT_NULL;
2761     hres = pVarRound(&v,0,&vDst);
2762     ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
2763         "VarRound: expected 0x0,%d got 0x%lX,%d\n", VT_NULL, hres, V_VT(&vDst));
2764
2765     /* not yet implemented so no use testing yet
2766     todo_wine {
2767         DECIMAL *pdec = &V_DECIMAL(&v);
2768         V_VT(&v) = VT_DECIMAL;
2769         pdec->u.s.sign = DECIMAL_NEG;
2770         pdec->u.s.scale = 0;
2771         pdec->Hi32 = 0;
2772         pdec->u1.s1.Mid32 = 0;
2773         pdec->u1.s1.Lo32 = 1;
2774         hres = pVarRound(&v,0,&vDst);
2775         ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
2776             V_DECIMAL(&vDst).u.s.sign == 0,
2777             "VarRound: expected 0x0,%d,0x00, got 0x%lX,%d,%02x\n", VT_DECIMAL,
2778             hres, V_VT(&vDst), V_DECIMAL(&vDst).u.s.sign);
2779
2780         pdec->u.s.sign = 0;
2781         hres = pVarRound(&v,0,&vDst);
2782         ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
2783             V_DECIMAL(&vDst).u.s.sign == DECIMAL_NEG,
2784             "VarRound: expected 0x0,%d,0x7f, got 0x%lX,%d,%02x\n", VT_DECIMAL,
2785             hres, V_VT(&vDst), V_DECIMAL(&vDst).u.s.sign);
2786     }
2787     */
2788
2789     V_VT(&v) = VT_CY;
2790     pcy->int64 = 10000;
2791     hres = pVarRound(&v,0,&vDst);
2792     ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == 10000,
2793         "VarRound: VT_CY wrong, hres=0x%lX\n", hres);
2794
2795 }
2796
2797 static HRESULT (WINAPI *pVarXor)(LPVARIANT,LPVARIANT,LPVARIANT);
2798
2799 static const char *szVarXorFail = "VarXor(%d,%d): expected 0x0,%d,%d, got 0x%lX,%d,%d\n";
2800 #define VARXOR(vt1,val1,vt2,val2,rvt,rval) \
2801         V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
2802         V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
2803         memset(&result,0,sizeof(result)); hres = pVarXor(&left,&right,&result); \
2804         ok(hres == S_OK && V_VT(&result) == VT_##rvt && V_##rvt(&result) == (rval), \
2805         szVarXorFail, VT_##vt1, VT_##vt2, \
2806         VT_##rvt, (int)(rval), hres, V_VT(&result), (int)V_##rvt(&result)); \
2807         ok(V_VT(&left) == VT_##vt1 && V_##vt1(&left) == val1 && \
2808            V_VT(&right) == VT_##vt2 && V_##vt2(&right) == val2, \
2809            "VarXor(%d,%d): Modified input arguments\n",VT_##vt1,VT_##vt2)
2810 #define VARXORCY(vt1,val1,val2,rvt,rval) \
2811         V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
2812         V_VT(&right) = VT_CY; V_CY(&right).int64 = val2; \
2813         memset(&result,0,sizeof(result)); hres = pVarXor(&left,&right,&result); \
2814         ok(hres == S_OK && V_VT(&result) == VT_##rvt && V_##rvt(&result) == (rval), \
2815         "VarXor(%d,%d): expected 0x0,%d,%d, got 0x%lX,%d,%d\n", VT_##vt1, VT_CY, \
2816         VT_##rvt, (int)(rval), hres, V_VT(&result), (int)V_##rvt(&result)); \
2817         ok(V_VT(&left) == VT_##vt1 && V_##vt1(&left) == val1 && \
2818            V_VT(&right) == VT_CY && V_CY(&right).int64 == val2, \
2819            "VarXor(%d,%d): Modified input arguments\n",VT_##vt1,VT_CY)
2820
2821 static void test_VarXor(void)
2822 {
2823     static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
2824     static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
2825     VARIANT left, right, result;
2826     BSTR lbstr, rbstr;
2827     VARTYPE i;
2828     HRESULT hres;
2829
2830     CHECKPTR(VarXor);
2831
2832     /* Test all possible flag/vt combinations & the resulting vt type */
2833     for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
2834     {
2835         VARTYPE leftvt, rightvt, resvt;
2836
2837         for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
2838         {
2839
2840             SKIPTESTS(leftvt);
2841                     
2842             for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
2843             {
2844                 BOOL bFail = FALSE;
2845
2846                 SKIPTESTS(rightvt);
2847                 
2848                 if (leftvt == VT_BSTR || rightvt == VT_BSTR ||
2849                     leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
2850                     leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN)
2851                     continue;
2852
2853                 memset(&left, 0, sizeof(left));
2854                 memset(&right, 0, sizeof(right));
2855                 V_VT(&left) = leftvt | ExtraFlags[i];
2856                 V_VT(&right) = rightvt | ExtraFlags[i];
2857                 V_VT(&result) = VT_EMPTY;
2858                 resvt = VT_I4;
2859
2860                 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
2861                     !IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
2862                     !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
2863                     leftvt == VT_CLSID || rightvt == VT_CLSID ||
2864                     leftvt == VT_RECORD || rightvt == VT_RECORD ||
2865                     leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
2866                     leftvt == VT_ERROR || rightvt == VT_ERROR)
2867                 {
2868                     bFail = TRUE;
2869                 }
2870                 if (leftvt == VT_EMPTY || rightvt == VT_EMPTY)
2871                 {
2872                     if (leftvt == rightvt ||
2873                         leftvt == VT_I2 || rightvt == VT_I2 ||
2874                         leftvt == VT_UI1 || rightvt == VT_UI1 ||
2875                         leftvt == VT_BOOL || rightvt == VT_BOOL)
2876                         resvt = VT_I2;
2877                     else if (leftvt == VT_NULL || rightvt == VT_NULL)
2878                         resvt = VT_NULL;
2879                     else if (leftvt == VT_I8 || rightvt == VT_I8)
2880                         resvt = VT_I8;
2881                 }
2882                 else if (leftvt == VT_NULL || rightvt == VT_NULL)
2883                 {
2884                     resvt = VT_NULL;
2885                 }
2886                 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
2887                 {
2888                     if (leftvt == rightvt)
2889                         resvt = VT_UI1;
2890                     else if (leftvt == rightvt ||
2891                         leftvt == VT_I2 || rightvt == VT_I2 ||
2892                         leftvt == VT_BOOL || rightvt == VT_BOOL)
2893                     {
2894                         resvt = VT_I2;
2895                     }
2896                     else if (leftvt == VT_I8 || rightvt == VT_I8)
2897                         resvt = VT_I8;
2898                 }
2899                 else if (leftvt == VT_I2 || rightvt == VT_I2)
2900                 {
2901                     if (leftvt == rightvt ||
2902                         leftvt == VT_BOOL || rightvt == VT_BOOL)
2903                         resvt = VT_I2;
2904                     else if (leftvt == VT_I8 || rightvt == VT_I8)
2905                         resvt = VT_I8;
2906                 }
2907                 else if (leftvt == VT_BOOL && rightvt == VT_BOOL)
2908                 {
2909                     resvt = VT_BOOL;
2910                 }
2911                 else if (leftvt == VT_I8 || rightvt == VT_I8)
2912                 {
2913                     if (leftvt == VT_INT || rightvt == VT_INT)
2914                         bFail = TRUE;
2915                     else
2916                         resvt = VT_I8;
2917                 }
2918                 hres = pVarXor(&left, &right, &result);
2919                 if (bFail)
2920                     ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
2921                        "VarXor: %d|0x%X, %d|0x%X: Expected failure, got 0x%lX vt %d\n",
2922                        leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres,
2923                        V_VT(&result));
2924                 else
2925                     ok(hres == S_OK && V_VT(&result) == resvt,
2926                        "VarXor: %d|0x%X, %d|0x%X: expected S_OK, vt %d, got 0x%lX vt %d\n",
2927                        leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], resvt, hres,
2928                        V_VT(&result));
2929             }
2930         }
2931     }
2932
2933     /* Test returned values
2934      * FIXME: Test VT_DECIMAL/VT_DISPATCH
2935      */
2936     VARXOR(EMPTY,0,EMPTY,0,I2,0);
2937     VARXOR(EMPTY,1,EMPTY,0,I2,0);
2938     VARXOR(EMPTY,0,NULL,0,NULL,0);
2939     VARXOR(EMPTY,0,I1,0,I4,0);
2940     VARXOR(EMPTY,0,I1,1,I4,1);
2941     VARXOR(EMPTY,0,UI1,0,I2,0);
2942     VARXOR(EMPTY,0,UI1,1,I2,1);
2943     VARXOR(EMPTY,0,I2,0,I2,0);
2944     VARXOR(EMPTY,0,I2,1,I2,1);
2945     VARXOR(EMPTY,0,UI2,0,I4,0);
2946     VARXOR(EMPTY,0,UI2,1,I4,1);
2947     VARXOR(EMPTY,0,I4,0,I4,0);
2948     VARXOR(EMPTY,0,I4,1,I4,1);
2949     VARXOR(EMPTY,0,UI4,0,I4,0);
2950     VARXOR(EMPTY,0,UI4,1,I4,1);
2951     if (HAVE_OLEAUT32_I8)
2952     {
2953         VARXOR(EMPTY,0,I8,0,I8,0);
2954         VARXOR(EMPTY,0,I8,1,I8,1);
2955         VARXOR(EMPTY,0,UI8,0,I4,0);
2956         VARXOR(EMPTY,0,UI8,1,I4,1);
2957     }
2958     VARXOR(EMPTY,0,INT,0,I4,0);
2959     VARXOR(EMPTY,0,INT,1,I4,1);
2960     VARXOR(EMPTY,0,UINT,0,I4,0);
2961     VARXOR(EMPTY,0,UINT,1,I4,1);
2962     VARXOR(EMPTY,0,BOOL,0,I2,0);
2963     VARXOR(EMPTY,0,BOOL,1,I2,1);
2964     VARXOR(EMPTY,0,R4,0,I4,0);
2965     VARXOR(EMPTY,0,R4,1,I4,1);
2966     VARXOR(EMPTY,0,R8,0,I4,0);
2967     VARXOR(EMPTY,0,R8,1,I4,1);
2968     rbstr = SysAllocString(szFalse);
2969     VARXOR(EMPTY,0,BSTR,rbstr,I2,0);
2970     rbstr = SysAllocString(szTrue);
2971     VARXOR(EMPTY,0,BSTR,rbstr,I2,-1);
2972     VARXORCY(EMPTY,0,10000,I4,1);
2973
2974     /* NULL OR 0 = NULL. NULL OR n = n */
2975     VARXOR(NULL,0,NULL,0,NULL,0);
2976     VARXOR(NULL,1,NULL,0,NULL,0);
2977     VARXOR(NULL,0,I1,0,NULL,0);
2978     VARXOR(NULL,0,I1,1,NULL,0);
2979     VARXOR(NULL,0,UI1,0,NULL,0);
2980     VARXOR(NULL,0,UI1,1,NULL,0);
2981     VARXOR(NULL,0,I2,0,NULL,0);
2982     VARXOR(NULL,0,I2,1,NULL,0);
2983     VARXOR(NULL,0,UI2,0,NULL,0);
2984     VARXOR(NULL,0,UI2,1,NULL,0);
2985     VARXOR(NULL,0,I4,0,NULL,0);
2986     VARXOR(NULL,0,I4,1,NULL,0);
2987     VARXOR(NULL,0,UI4,0,NULL,0);
2988     VARXOR(NULL,0,UI4,1,NULL,0);
2989     if (HAVE_OLEAUT32_I8)
2990     {
2991         VARXOR(NULL,0,I8,0,NULL,0);
2992         VARXOR(NULL,0,I8,1,NULL,0);
2993         VARXOR(NULL,0,UI8,0,NULL,0);
2994         VARXOR(NULL,0,UI8,1,NULL,0);
2995     }
2996     VARXOR(NULL,0,INT,0,NULL,0);
2997     VARXOR(NULL,0,INT,1,NULL,0);
2998     VARXOR(NULL,0,UINT,0,NULL,0);
2999     VARXOR(NULL,0,UINT,1,NULL,0);
3000     VARXOR(NULL,0,BOOL,0,NULL,0);
3001     VARXOR(NULL,0,BOOL,1,NULL,0);
3002     VARXOR(NULL,0,R4,0,NULL,0);
3003     VARXOR(NULL,0,R4,1,NULL,0);
3004     VARXOR(NULL,0,R8,0,NULL,0);
3005     VARXOR(NULL,0,R8,1,NULL,0);
3006     rbstr = SysAllocString(szFalse);
3007     VARXOR(NULL,0,BSTR,rbstr,NULL,0);
3008     rbstr = SysAllocString(szTrue);
3009     VARXOR(NULL,0,BSTR,rbstr,NULL,0);
3010     VARXORCY(NULL,0,10000,NULL,0);
3011     VARXORCY(NULL,0,0,NULL,0);
3012
3013     VARXOR(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE);
3014     VARXOR(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE);
3015     VARXOR(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
3016     VARXOR(BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE);
3017     /* Assume x,y & y,x are the same from now on to reduce the number of tests */
3018     VARXOR(BOOL,VARIANT_TRUE,I1,-1,I4,0);
3019     VARXOR(BOOL,VARIANT_TRUE,I1,0,I4,-1);
3020     VARXOR(BOOL,VARIANT_FALSE,I1,0,I4,0);
3021     VARXOR(BOOL,VARIANT_TRUE,UI1,255,I2,-256);
3022     VARXOR(BOOL,VARIANT_TRUE,UI1,0,I2,-1);
3023     VARXOR(BOOL,VARIANT_FALSE,UI1,0,I2,0);
3024     VARXOR(BOOL,VARIANT_TRUE,I2,-1,I2,0);
3025     VARXOR(BOOL,VARIANT_TRUE,I2,0,I2,-1);
3026     VARXOR(BOOL,VARIANT_FALSE,I2,0,I2,0);
3027     VARXOR(BOOL,VARIANT_TRUE,UI2,65535,I4,-65536);
3028     VARXOR(BOOL,VARIANT_TRUE,UI2,0,I4,-1);
3029     VARXOR(BOOL,VARIANT_FALSE,UI2,0,I4,0);
3030     VARXOR(BOOL,VARIANT_TRUE,I4,-1,I4,0);
3031     VARXOR(BOOL,VARIANT_TRUE,I4,0,I4,-1);
3032     VARXOR(BOOL,VARIANT_FALSE,I4,0,I4,0);
3033     VARXOR(BOOL,VARIANT_TRUE,UI4,0xffffffff,I4,0);
3034     VARXOR(BOOL,VARIANT_TRUE,UI4,0,I4,-1);
3035     VARXOR(BOOL,VARIANT_FALSE,UI4,0,I4,0);
3036     VARXOR(BOOL,VARIANT_TRUE,R4,-1,I4,0);
3037     VARXOR(BOOL,VARIANT_TRUE,R4,0,I4,-1);
3038     VARXOR(BOOL,VARIANT_FALSE,R4,0,I4,0);
3039     VARXOR(BOOL,VARIANT_TRUE,R8,-1,I4,0);
3040     VARXOR(BOOL,VARIANT_TRUE,R8,0,I4,-1);
3041     VARXOR(BOOL,VARIANT_FALSE,R8,0,I4,0);
3042     VARXOR(BOOL,VARIANT_TRUE,DATE,-1,I4,0);
3043     VARXOR(BOOL,VARIANT_TRUE,DATE,0,I4,-1);
3044     VARXOR(BOOL,VARIANT_FALSE,DATE,0,I4,0);
3045     if (HAVE_OLEAUT32_I8)
3046     {
3047         VARXOR(BOOL,VARIANT_TRUE,I8,-1,I8,0);
3048         VARXOR(BOOL,VARIANT_TRUE,I8,0,I8,-1);
3049         VARXOR(BOOL,VARIANT_FALSE,I8,0,I8,0);
3050         /* This returns DISP_E_OVERFLOW which indicates that a conversion
3051          * to I4 is performed.
3052          */
3053         /* VARXOR(BOOL,VARIANT_TRUE,UI8,-1,I4,-1); */
3054         VARXOR(BOOL,VARIANT_TRUE,UI8,0,I4,-1);
3055         VARXOR(BOOL,VARIANT_FALSE,UI8,0,I4,0);
3056     }
3057     VARXOR(BOOL,VARIANT_TRUE,INT,-1,I4,0);
3058     VARXOR(BOOL,VARIANT_TRUE,INT,0,I4,-1);
3059     VARXOR(BOOL,VARIANT_FALSE,INT,0,I4,0);
3060     VARXOR(BOOL,VARIANT_TRUE,UINT,0xffffffff,I4,0);
3061     VARXOR(BOOL,VARIANT_TRUE,UINT,0,I4,-1);
3062     VARXOR(BOOL,VARIANT_FALSE,UINT,0,I4,0);
3063     rbstr = SysAllocString(szFalse);
3064     VARXOR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_FALSE);
3065     VARXOR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_TRUE);
3066     rbstr = SysAllocString(szTrue);
3067     VARXOR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_TRUE);
3068     VARXOR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_FALSE);
3069     VARXORCY(BOOL,VARIANT_TRUE,10000,I4,-2);
3070     VARXORCY(BOOL,VARIANT_TRUE,0,I4,-1);
3071     VARXORCY(BOOL,VARIANT_FALSE,0,I4,0);
3072
3073     VARXOR(I1,-1,I1,-1,I4,0);
3074     VARXOR(I1,-1,I1,0,I4,-1);
3075     VARXOR(I1,0,I1,0,I4,0);
3076     VARXOR(I1,-1,UI1,255,I4,-256);
3077     VARXOR(I1,-1,UI1,0,I4,-1);
3078     VARXOR(I1,0,UI1,0,I4,0);
3079     VARXOR(I1,-1,I2,-1,I4,0);
3080     VARXOR(I1,-1,I2,0,I4,-1);
3081     VARXOR(I1,0,I2,0,I4,0);
3082     VARXOR(I1,-1,UI2,65535,I4,-65536);
3083     VARXOR(I1,-1,UI2,0,I4,-1);
3084     VARXOR(I1,0,UI2,0,I4,0);
3085     VARXOR(I1,-1,I4,-1,I4,0);
3086     VARXOR(I1,-1,I4,0,I4,-1);
3087     VARXOR(I1,0,I4,0,I4,0);
3088     VARXOR(I1,-1,UI4,0xffffffff,I4,0);
3089     VARXOR(I1,-1,UI4,0,I4,-1);
3090     VARXOR(I1,0,UI4,0,I4,0);
3091     VARXOR(I1,-1,R4,-1,I4,0);
3092     VARXOR(I1,-1,R4,0,I4,-1);
3093     VARXOR(I1,0,R4,0,I4,0);
3094     VARXOR(I1,-1,R8,-1,I4,0);
3095     VARXOR(I1,-1,R8,0,I4,-1);
3096     VARXOR(I1,0,R8,0,I4,0);
3097     VARXOR(I1,-1,DATE,-1,I4,0);
3098     VARXOR(I1,-1,DATE,0,I4,-1);
3099     VARXOR(I1,0,DATE,0,I4,0);
3100     if (HAVE_OLEAUT32_I8)
3101     {
3102         VARXOR(I1,-1,I8,-1,I8,0);
3103         VARXOR(I1,-1,I8,0,I8,-1);
3104         VARXOR(I1,0,I8,0,I8,0);
3105         VARXOR(I1,-1,UI8,0,I4,-1);
3106         VARXOR(I1,0,UI8,0,I4,0);
3107     }
3108     VARXOR(I1,-1,INT,-1,I4,0);
3109     VARXOR(I1,-1,INT,0,I4,-1);
3110     VARXOR(I1,0,INT,0,I4,0);
3111     VARXOR(I1,-1,UINT,0xffffffff,I4,0);
3112     VARXOR(I1,-1,UINT,0,I4,-1);
3113     VARXOR(I1,0,UINT,0,I4,0);
3114     rbstr = SysAllocString(szFalse);
3115     VARXOR(I1,0,BSTR,rbstr,I4,0);
3116     VARXOR(I1,-1,BSTR,rbstr,I4,-1);
3117     rbstr = SysAllocString(szTrue);
3118     VARXOR(I1,0,BSTR,rbstr,I4,-1);
3119     VARXOR(I1,-1,BSTR,rbstr,I4,0);
3120     VARXORCY(I1,-1,10000,I4,-2);
3121     VARXORCY(I1,-1,0,I4,-1);
3122     VARXORCY(I1,0,0,I4,0);
3123
3124     VARXOR(UI1,255,UI1,255,UI1,0);
3125     VARXOR(UI1,255,UI1,0,UI1,255);
3126     VARXOR(UI1,0,UI1,0,UI1,0);
3127     VARXOR(UI1,255,I2,-1,I2,-256);
3128     VARXOR(UI1,255,I2,0,I2,255);
3129     VARXOR(UI1,0,I2,0,I2,0);
3130     VARXOR(UI1,255,UI2,65535,I4,65280);
3131     VARXOR(UI1,255,UI2,0,I4,255);
3132     VARXOR(UI1,0,UI2,0,I4,0);
3133     VARXOR(UI1,255,I4,-1,I4,-256);
3134     VARXOR(UI1,255,I4,0,I4,255);
3135     VARXOR(UI1,0,I4,0,I4,0);
3136     VARXOR(UI1,255,UI4,0xffffffff,I4,-256);
3137     VARXOR(UI1,255,UI4,0,I4,255);
3138     VARXOR(UI1,0,UI4,0,I4,0);
3139     VARXOR(UI1,255,R4,-1,I4,-256);
3140     VARXOR(UI1,255,R4,0,I4,255);
3141     VARXOR(UI1,0,R4,0,I4,0);
3142     VARXOR(UI1,255,R8,-1,I4,-256);
3143     VARXOR(UI1,255,R8,0,I4,255);
3144     VARXOR(UI1,0,R8,0,I4,0);
3145     VARXOR(UI1,255,DATE,-1,I4,-256);
3146     VARXOR(UI1,255,DATE,0,I4,255);
3147     VARXOR(UI1,0,DATE,0,I4,0);
3148     if (HAVE_OLEAUT32_I8)
3149     {
3150         VARXOR(UI1,255,I8,-1,I8,-256);
3151         VARXOR(UI1,255,I8,0,I8,255);
3152         VARXOR(UI1,0,I8,0,I8,0);
3153         VARXOR(UI1,255,UI8,0,I4,255);
3154         VARXOR(UI1,0,UI8,0,I4,0);
3155     }
3156     VARXOR(UI1,255,INT,-1,I4,-256);
3157     VARXOR(UI1,255,INT,0,I4,255);
3158     VARXOR(UI1,0,INT,0,I4,0);
3159     VARXOR(UI1,255,UINT,0xffffffff,I4,-256);
3160     VARXOR(UI1,255,UINT,0,I4,255);
3161     VARXOR(UI1,0,UINT,0,I4,0);
3162     rbstr = SysAllocString(szFalse);
3163     VARXOR(UI1,0,BSTR,rbstr,I2,0);
3164     VARXOR(UI1,255,BSTR,rbstr,I2,255);
3165     rbstr = SysAllocString(szTrue);
3166     VARXOR(UI1,0,BSTR,rbstr,I2,-1);
3167     VARXOR(UI1,255,BSTR,rbstr,I2,-256);
3168     VARXORCY(UI1,255,10000,I4,254);
3169     VARXORCY(UI1,255,0,I4,255);
3170     VARXORCY(UI1,0,0,I4,0);
3171
3172     VARXOR(I2,-1,I2,-1,I2,0);
3173     VARXOR(I2,-1,I2,0,I2,-1);
3174     VARXOR(I2,0,I2,0,I2,0);
3175     VARXOR(I2,-1,UI2,65535,I4,-65536);
3176     VARXOR(I2,-1,UI2,0,I4,-1);
3177     VARXOR(I2,0,UI2,0,I4,0);
3178     VARXOR(I2,-1,I4,-1,I4,0);
3179     VARXOR(I2,-1,I4,0,I4,-1);
3180     VARXOR(I2,0,I4,0,I4,0);
3181     VARXOR(I2,-1,UI4,0xffffffff,I4,0);
3182     VARXOR(I2,-1,UI4,0,I4,-1);
3183     VARXOR(I2,0,UI4,0,I4,0);
3184     VARXOR(I2,-1,R4,-1,I4,0);
3185     VARXOR(I2,-1,R4,0,I4,-1);
3186     VARXOR(I2,0,R4,0,I4,0);
3187     VARXOR(I2,-1,R8,-1,I4,0);
3188     VARXOR(I2,-1,R8,0,I4,-1);
3189     VARXOR(I2,0,R8,0,I4,0);
3190     VARXOR(I2,-1,DATE,-1,I4,0);
3191     VARXOR(I2,-1,DATE,0,I4,-1);
3192     VARXOR(I2,0,DATE,0,I4,0);
3193     if (HAVE_OLEAUT32_I8)
3194     {
3195         VARXOR(I2,-1,I8,-1,I8,0);
3196         VARXOR(I2,-1,I8,0,I8,-1);
3197         VARXOR(I2,0,I8,0,I8,0);
3198         VARXOR(I2,-1,UI8,0,I4,-1);
3199         VARXOR(I2,0,UI8,0,I4,0);
3200     }
3201     VARXOR(I2,-1,INT,-1,I4,0);
3202     VARXOR(I2,-1,INT,0,I4,-1);
3203     VARXOR(I2,0,INT,0,I4,0);
3204     VARXOR(I2,-1,UINT,0xffffffff,I4,0);
3205     VARXOR(I2,-1,UINT,0,I4,-1);
3206     VARXOR(I2,0,UINT,0,I4,0);
3207     rbstr = SysAllocString(szFalse);
3208     VARXOR(I2,0,BSTR,rbstr,I2,0);
3209     VARXOR(I2,-1,BSTR,rbstr,I2,-1);
3210     rbstr = SysAllocString(szTrue);
3211     VARXOR(I2,0,BSTR,rbstr,I2,-1);
3212     VARXOR(I2,-1,BSTR,rbstr,I2,0);
3213     VARXORCY(I2,-1,10000,I4,-2);
3214     VARXORCY(I2,-1,0,I4,-1);
3215     VARXORCY(I2,0,0,I4,0);
3216
3217     VARXOR(UI2,65535,UI2,65535,I4,0);
3218     VARXOR(UI2,65535,UI2,0,I4,65535);
3219     VARXOR(UI2,0,UI2,0,I4,0);
3220     VARXOR(UI2,65535,I4,-1,I4,-65536);
3221     VARXOR(UI2,65535,I4,0,I4,65535);
3222     VARXOR(UI2,0,I4,0,I4,0);
3223     VARXOR(UI2,65535,UI4,0xffffffff,I4,-65536);
3224     VARXOR(UI2,65535,UI4,0,I4,65535);
3225     VARXOR(UI2,0,UI4,0,I4,0);
3226     VARXOR(UI2,65535,R4,-1,I4,-65536);
3227     VARXOR(UI2,65535,R4,0,I4,65535);
3228     VARXOR(UI2,0,R4,0,I4,0);
3229     VARXOR(UI2,65535,R8,-1,I4,-65536);
3230     VARXOR(UI2,65535,R8,0,I4,65535);
3231     VARXOR(UI2,0,R8,0,I4,0);
3232     VARXOR(UI2,65535,DATE,-1,I4,-65536);
3233     VARXOR(UI2,65535,DATE,0,I4,65535);
3234     VARXOR(UI2,0,DATE,0,I4,0);
3235     if (HAVE_OLEAUT32_I8)
3236     {
3237         VARXOR(UI2,65535,I8,-1,I8,-65536);
3238         VARXOR(UI2,65535,I8,0,I8,65535);
3239         VARXOR(UI2,0,I8,0,I8,0);
3240         VARXOR(UI2,65535,UI8,0,I4,65535);
3241         VARXOR(UI2,0,UI8,0,I4,0);
3242     }
3243     VARXOR(UI2,65535,INT,-1,I4,-65536);
3244     VARXOR(UI2,65535,INT,0,I4,65535);
3245     VARXOR(UI2,0,INT,0,I4,0);
3246     VARXOR(UI2,65535,UINT,0xffffffff,I4,-65536);
3247     VARXOR(UI2,65535,UINT,0,I4,65535);
3248     VARXOR(UI2,0,UINT,0,I4,0);
3249     rbstr = SysAllocString(szFalse);
3250     VARXOR(UI2,0,BSTR,rbstr,I4,0);
3251     VARXOR(UI2,65535,BSTR,rbstr,I4,65535);
3252     rbstr = SysAllocString(szTrue);
3253     VARXOR(UI2,0,BSTR,rbstr,I4,-1);
3254     VARXOR(UI2,65535,BSTR,rbstr,I4,-65536);
3255     VARXORCY(UI2,65535,10000,I4,65534);
3256     VARXORCY(UI2,65535,0,I4,65535);
3257     VARXORCY(UI2,0,0,I4,0);
3258
3259     VARXOR(I4,-1,I4,-1,I4,0);
3260     VARXOR(I4,-1,I4,0,I4,-1);
3261     VARXOR(I4,0,I4,0,I4,0);
3262     VARXOR(I4,-1,UI4,0xffffffff,I4,0);
3263     VARXOR(I4,-1,UI4,0,I4,-1);
3264     VARXOR(I4,0,UI4,0,I4,0);
3265     VARXOR(I4,-1,R4,-1,I4,0);
3266     VARXOR(I4,-1,R4,0,I4,-1);
3267     VARXOR(I4,0,R4,0,I4,0);
3268     VARXOR(I4,-1,R8,-1,I4,0);
3269     VARXOR(I4,-1,R8,0,I4,-1);
3270     VARXOR(I4,0,R8,0,I4,0);
3271     VARXOR(I4,-1,DATE,-1,I4,0);
3272     VARXOR(I4,-1,DATE,0,I4,-1);
3273     VARXOR(I4,0,DATE,0,I4,0);
3274     if (HAVE_OLEAUT32_I8)
3275     {
3276         VARXOR(I4,-1,I8,-1,I8,0);
3277         VARXOR(I4,-1,I8,0,I8,-1);
3278         VARXOR(I4,0,I8,0,I8,0);
3279         VARXOR(I4,-1,UI8,0,I4,-1);
3280         VARXOR(I4,0,UI8,0,I4,0);
3281     }
3282     VARXOR(I4,-1,INT,-1,I4,0);
3283     VARXOR(I4,-1,INT,0,I4,-1);
3284     VARXOR(I4,0,INT,0,I4,0);
3285     VARXOR(I4,-1,UINT,0xffffffff,I4,0);
3286     VARXOR(I4,-1,UINT,0,I4,-1);
3287     VARXOR(I4,0,UINT,0,I4,0);
3288     rbstr = SysAllocString(szFalse);
3289     VARXOR(I4,0,BSTR,rbstr,I4,0);
3290     VARXOR(I4,-1,BSTR,rbstr,I4,-1);
3291     rbstr = SysAllocString(szTrue);
3292     VARXOR(I4,0,BSTR,rbstr,I4,-1);
3293     VARXOR(I4,-1,BSTR,rbstr,I4,0);
3294     VARXORCY(I4,-1,10000,I4,-2);
3295     VARXORCY(I4,-1,0,I4,-1);
3296     VARXORCY(I4,0,0,I4,0);
3297
3298     VARXOR(UI4,0xffffffff,UI4,0xffffffff,I4,0);
3299     VARXOR(UI4,0xffffffff,UI4,0,I4,-1);
3300     VARXOR(UI4,0,UI4,0,I4,0);
3301     VARXOR(UI4,0xffffffff,R4,-1,I4,0);
3302     VARXOR(UI4,0xffffffff,R4,0,I4,-1);
3303     VARXOR(UI4,0,R4,0,I4,0);
3304     VARXOR(UI4,0xffffffff,R8,-1,I4,0);
3305     VARXOR(UI4,0xffffffff,R8,0,I4,-1);
3306     VARXOR(UI4,0,R8,0,I4,0);
3307     VARXOR(UI4,0xffffffff,DATE,-1,I4,0);
3308     VARXOR(UI4,0xffffffff,DATE,0,I4,-1);
3309     VARXOR(UI4,0,DATE,0,I4,0);
3310     if (HAVE_OLEAUT32_I8)
3311     {
3312         VARXOR(UI4,0xffffffff,I8,0,I8,0xffffffff);
3313         VARXOR(UI4,VARIANT_FALSE,I8,VARIANT_FALSE,I8,0);
3314         VARXOR(UI4,0,I8,0,I8,0);
3315         VARXOR(UI4,0xffffffff,UI8,0,I4,-1);
3316         VARXOR(UI4,0,UI8,0,I4,0);
3317     }
3318     VARXOR(UI4,0xffffffff,INT,-1,I4,0);
3319     VARXOR(UI4,0xffffffff,INT,0,I4,-1);
3320     VARXOR(UI4,0,INT,0,I4,0);
3321     VARXOR(UI4,0xffffffff,UINT,0xffffffff,I4,0);
3322     VARXOR(UI4,0xffffffff,UINT,0,I4,-1);
3323     VARXOR(UI4,0,UINT,0,I4,0);
3324     rbstr = SysAllocString(szFalse);
3325     VARXOR(UI4,0,BSTR,rbstr,I4,0);
3326     VARXOR(UI4,0xffffffff,BSTR,rbstr,I4,-1);
3327     rbstr = SysAllocString(szTrue);
3328     VARXOR(UI4,0,BSTR,rbstr,I4,-1);
3329     VARXOR(UI4,0xffffffff,BSTR,rbstr,I4,0);
3330     VARXORCY(UI4,0xffffffff,10000,I4,-2);
3331     VARXORCY(UI4,0xffffffff,0,I4,-1);
3332     VARXORCY(UI4,0,0,I4,0);
3333
3334     VARXOR(R4,-1,R4,-1,I4,0);
3335     VARXOR(R4,-1,R4,0,I4,-1);
3336     VARXOR(R4,0,R4,0,I4,0);
3337     VARXOR(R4,-1,R8,-1,I4,0);
3338     VARXOR(R4,-1,R8,0,I4,-1);
3339     VARXOR(R4,0,R8,0,I4,0);
3340     VARXOR(R4,-1,DATE,-1,I4,0);
3341     VARXOR(R4,-1,DATE,0,I4,-1);
3342     VARXOR(R4,0,DATE,0,I4,0);
3343     if (HAVE_OLEAUT32_I8)
3344     {
3345         VARXOR(R4,-1,I8,-1,I8,0);
3346         VARXOR(R4,-1,I8,0,I8,-1);
3347         VARXOR(R4,0,I8,0,I8,0);
3348         VARXOR(R4,-1,UI8,0,I4,-1);
3349         VARXOR(R4,0,UI8,0,I4,0);
3350     }
3351     VARXOR(R4,-1,INT,-1,I4,0);
3352     VARXOR(R4,-1,INT,0,I4,-1);
3353     VARXOR(R4,0,INT,0,I4,0);
3354     VARXOR(R4,-1,UINT,0xffffffff,I4,0);
3355     VARXOR(R4,-1,UINT,0,I4,-1);
3356     VARXOR(R4,0,UINT,0,I4,0);
3357     rbstr = SysAllocString(szFalse);
3358     VARXOR(R4,0,BSTR,rbstr,I4,0);
3359     VARXOR(R4,-1,BSTR,rbstr,I4,-1);
3360     rbstr = SysAllocString(szTrue);
3361     VARXOR(R4,0,BSTR,rbstr,I4,-1);
3362     VARXOR(R4,-1,BSTR,rbstr,I4,0);
3363     VARXORCY(R4,-1,10000,I4,-2);
3364     VARXORCY(R4,-1,0,I4,-1);
3365     VARXORCY(R4,0,0,I4,0);
3366
3367     VARXOR(R8,-1,R8,-1,I4,0);
3368     VARXOR(R8,-1,R8,0,I4,-1);
3369     VARXOR(R8,0,R8,0,I4,0);
3370     VARXOR(R8,-1,DATE,-1,I4,0);
3371     VARXOR(R8,-1,DATE,0,I4,-1);
3372     VARXOR(R8,0,DATE,0,I4,0);
3373     if (HAVE_OLEAUT32_I8)
3374     {
3375         VARXOR(R8,-1,I8,-1,I8,0);
3376         VARXOR(R8,-1,I8,0,I8,-1);
3377         VARXOR(R8,0,I8,0,I8,0);
3378         VARXOR(R8,-1,UI8,0,I4,-1);
3379         VARXOR(R8,0,UI8,0,I4,0);
3380     }
3381     VARXOR(R8,-1,INT,-1,I4,0);
3382     VARXOR(R8,-1,INT,0,I4,-1);
3383     VARXOR(R8,0,INT,0,I4,0);
3384     VARXOR(R8,-1,UINT,0xffffffff,I4,0);
3385     VARXOR(R8,-1,UINT,0,I4,-1);
3386     VARXOR(R8,0,UINT,0,I4,0);
3387     rbstr = SysAllocString(szFalse);
3388     VARXOR(R8,0,BSTR,rbstr,I4,0);
3389     VARXOR(R8,-1,BSTR,rbstr,I4,-1);
3390     rbstr = SysAllocString(szTrue);
3391     VARXOR(R8,0,BSTR,rbstr,I4,-1);
3392     VARXOR(R8,-1,BSTR,rbstr,I4,0);
3393     VARXORCY(R8,-1,10000,I4,-2);
3394     VARXORCY(R8,-1,0,I4,-1);
3395     VARXORCY(R8,0,0,I4,0);
3396
3397     VARXOR(DATE,-1,DATE,-1,I4,0);
3398     VARXOR(DATE,-1,DATE,0,I4,-1);
3399     VARXOR(DATE,0,DATE,0,I4,0);
3400     if (HAVE_OLEAUT32_I8)
3401     {
3402         VARXOR(DATE,-1,I8,-1,I8,0);
3403         VARXOR(DATE,-1,I8,0,I8,-1);
3404         VARXOR(DATE,0,I8,0,I8,0);
3405         VARXOR(DATE,-1,UI8,0,I4,-1);
3406         VARXOR(DATE,0,UI8,0,I4,0);
3407     }
3408     VARXOR(DATE,-1,INT,-1,I4,0);
3409     VARXOR(DATE,-1,INT,0,I4,-1);
3410     VARXOR(DATE,0,INT,0,I4,0);
3411     VARXOR(DATE,-1,UINT,0xffffffff,I4,0);
3412     VARXOR(DATE,-1,UINT,0,I4,-1);
3413     VARXOR(DATE,0,UINT,0,I4,0);
3414     rbstr = SysAllocString(szFalse);
3415     VARXOR(DATE,0,BSTR,rbstr,I4,0);
3416     VARXOR(DATE,-1,BSTR,rbstr,I4,-1);
3417     rbstr = SysAllocString(szTrue);
3418     VARXOR(DATE,0,BSTR,rbstr,I4,-1);
3419     VARXOR(DATE,-1,BSTR,rbstr,I4,0);
3420     VARXORCY(DATE,-1,10000,I4,-2);
3421     VARXORCY(DATE,-1,0,I4,-1);
3422     VARXORCY(DATE,0,0,I4,0);
3423
3424     if (HAVE_OLEAUT32_I8)
3425     {
3426         VARXOR(I8,-1,I8,-1,I8,0);
3427         VARXOR(I8,-1,I8,0,I8,-1);
3428         VARXOR(I8,0,I8,0,I8,0);
3429         VARXOR(I8,-1,UI8,0,I8,-1);
3430         VARXOR(I8,0,UI8,0,I8,0);
3431         VARXOR(I8,-1,UINT,0,I8,-1);
3432         VARXOR(I8,0,UINT,0,I8,0);
3433         rbstr = SysAllocString(szFalse);
3434         VARXOR(I8,0,BSTR,rbstr,I8,0);
3435         VARXOR(I8,-1,BSTR,rbstr,I8,-1);
3436         rbstr = SysAllocString(szTrue);
3437         VARXOR(I8,0,BSTR,rbstr,I8,-1);
3438         VARXOR(I8,-1,BSTR,rbstr,I8,0);
3439         VARXORCY(I8,-1,10000,I8,-2);
3440         VARXORCY(I8,-1,0,I8,-1);
3441         VARXORCY(I8,0,0,I8,0);
3442
3443         VARXOR(UI8,0xffff,UI8,0xffff,I4,0);
3444         VARXOR(UI8,0xffff,UI8,0,I4,0xffff);
3445         VARXOR(UI8,0,UI8,0,I4,0);
3446         VARXOR(UI8,0xffff,INT,-1,I4,-65536);
3447         VARXOR(UI8,0xffff,INT,0,I4,0xffff);
3448         VARXOR(UI8,0,INT,0,I4,0);
3449         VARXOR(UI8,0xffff,UINT,0xffff,I4,0);
3450         VARXOR(UI8,0xffff,UINT,0,I4,0xffff);
3451         VARXOR(UI8,0,UINT,0,I4,0);
3452         rbstr = SysAllocString(szFalse);
3453         VARXOR(UI8,0,BSTR,rbstr,I4,0);
3454         VARXOR(UI8,0xffff,BSTR,rbstr,I4,0xffff);
3455         rbstr = SysAllocString(szTrue);
3456         VARXOR(UI8,0,BSTR,rbstr,I4,-1);
3457         VARXOR(UI8,0xffff,BSTR,rbstr,I4,-65536);
3458         VARXORCY(UI8,0xffff,10000,I4,65534);
3459         VARXORCY(UI8,0xffff,0,I4,0xffff);
3460         VARXORCY(UI8,0,0,I4,0);
3461     }
3462
3463     VARXOR(INT,-1,INT,-1,I4,0);
3464     VARXOR(INT,-1,INT,0,I4,-1);
3465     VARXOR(INT,0,INT,0,I4,0);
3466     VARXOR(INT,-1,UINT,0xffff,I4,-65536);
3467     VARXOR(INT,-1,UINT,0,I4,-1);
3468     VARXOR(INT,0,UINT,0,I4,0);
3469     rbstr = SysAllocString(szFalse);
3470     VARXOR(INT,0,BSTR,rbstr,I4,0);
3471     VARXOR(INT,-1,BSTR,rbstr,I4,-1);
3472     rbstr = SysAllocString(szTrue);
3473     VARXOR(INT,0,BSTR,rbstr,I4,-1);
3474     VARXOR(INT,-1,BSTR,rbstr,I4,0);
3475     VARXORCY(INT,-1,10000,I4,-2);
3476     VARXORCY(INT,-1,0,I4,-1);
3477     VARXORCY(INT,0,0,I4,0);
3478
3479     VARXOR(UINT,0xffff,UINT,0xffff,I4,0);
3480     VARXOR(UINT,0xffff,UINT,0,I4,0xffff);
3481     VARXOR(UINT,0,UINT,0,I4,0);
3482     rbstr = SysAllocString(szFalse);
3483     VARXOR(UINT,0,BSTR,rbstr,I4,0);
3484     VARXOR(UINT,0xffff,BSTR,rbstr,I4,0xffff);
3485     rbstr = SysAllocString(szTrue);
3486     VARXOR(UINT,0,BSTR,rbstr,I4,-1);
3487     VARXOR(UINT,0xffff,BSTR,rbstr,I4,-65536);
3488     VARXORCY(UINT,0xffff,10000,I4,65534);
3489     VARXORCY(UINT,0xffff,0,I4,0xffff);
3490     VARXORCY(UINT,0,0,I4,0);
3491
3492     lbstr = SysAllocString(szFalse);
3493     rbstr = SysAllocString(szFalse);
3494     VARXOR(BSTR,lbstr,BSTR,rbstr,BOOL,0);
3495     rbstr = SysAllocString(szTrue);
3496     VARXOR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_TRUE);
3497     lbstr = SysAllocString(szTrue);
3498     VARXOR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_FALSE);
3499     VARXORCY(BSTR,lbstr,10000,I4,-2);
3500     lbstr = SysAllocString(szFalse);
3501     VARXORCY(BSTR,lbstr,10000,I4,1);
3502 }
3503
3504 static HRESULT (WINAPI *pVarOr)(LPVARIANT,LPVARIANT,LPVARIANT);
3505
3506 static const char *szVarOrFail = "VarOr(%d,%d): expected 0x0,%d,%d, got 0x%lX,%d,%d\n";
3507 static const char *szVarOrChanged = "VarOr(%d,%d): Modified input arguments\n";
3508 #define VAROR(vt1,val1,vt2,val2,rvt,rval) \
3509         V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
3510         V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
3511         memset(&result,0,sizeof(result)); hres = pVarOr(&left,&right,&result); \
3512         ok(hres == S_OK && V_VT(&result) == VT_##rvt && V_##rvt(&result) == (rval), \
3513         szVarOrFail, VT_##vt1, VT_##vt2, \
3514         VT_##rvt, (int)(rval), hres, V_VT(&result), (int)V_##rvt(&result)); \
3515         ok(V_VT(&left) == VT_##vt1 && V_##vt1(&left) == val1 && \
3516            V_VT(&right) == VT_##vt2 && V_##vt2(&right) == val2, \
3517            szVarOrChanged,VT_##vt1,VT_##vt2)
3518 #define VARORCY(vt1,val1,val2,rvt,rval) \
3519         V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
3520         V_VT(&right) = VT_CY; V_CY(&right).int64 = val2; \
3521         memset(&result,0,sizeof(result)); hres = pVarOr(&left,&right,&result); \
3522         ok(hres == S_OK && V_VT(&result) == VT_##rvt && V_##rvt(&result) == (rval), \
3523         "VarOr(%d,%d): expected 0x0,%d,%d, got 0x%lX,%d,%d\n", VT_##vt1, VT_CY, \
3524         VT_##rvt, (int)(rval), hres, V_VT(&result), (int)V_##rvt(&result)); \
3525         ok(V_VT(&left) == VT_##vt1 && V_##vt1(&left) == val1 && \
3526            V_VT(&right) == VT_CY && V_CY(&right).int64 == val2, \
3527            "VarOr(%d,%d): Modified input arguments\n",VT_##vt1,VT_CY)
3528
3529 static void test_VarOr(void)
3530 {
3531     static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
3532     static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
3533     VARIANT left, right, result;
3534     BSTR lbstr, rbstr;
3535     VARTYPE i;
3536     HRESULT hres;
3537
3538     CHECKPTR(VarOr);
3539
3540     /* Test all possible flag/vt combinations & the resulting vt type */
3541     for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
3542     {
3543         VARTYPE leftvt, rightvt, resvt;
3544
3545         for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
3546         {
3547         
3548             SKIPTESTS(leftvt);
3549         
3550             for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
3551             {
3552                 BOOL bFail = FALSE;
3553
3554                 SKIPTESTS(rightvt);
3555                 
3556                 if (leftvt == VT_BSTR || rightvt == VT_BSTR ||
3557                     leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
3558                     leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN)
3559                     continue;
3560
3561                 memset(&left, 0, sizeof(left));
3562                 memset(&right, 0, sizeof(right));
3563                 V_VT(&left) = leftvt | ExtraFlags[i];
3564                 V_VT(&right) = rightvt | ExtraFlags[i];
3565                 V_VT(&result) = VT_EMPTY;
3566                 resvt = VT_I4;
3567
3568                 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
3569                     !IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
3570                     !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
3571                     leftvt == VT_CLSID || rightvt == VT_CLSID ||
3572                     leftvt == VT_RECORD || rightvt == VT_RECORD ||
3573                     leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
3574                     leftvt == VT_ERROR || rightvt == VT_ERROR)
3575                 {
3576                     bFail = TRUE;
3577                 }
3578                 if (leftvt == VT_EMPTY || rightvt == VT_EMPTY)
3579                 {
3580                     if (leftvt == rightvt ||
3581                         leftvt == VT_I2 || rightvt == VT_I2 ||
3582                         leftvt == VT_UI1 || rightvt == VT_UI1 ||
3583                         leftvt == VT_BOOL || rightvt == VT_BOOL)
3584                         resvt = VT_I2;
3585                     else if (leftvt == VT_NULL || rightvt == VT_NULL)
3586                         resvt = VT_NULL;
3587                     else if (leftvt == VT_I8 || rightvt == VT_I8)
3588                         resvt = VT_I8;
3589                 }
3590                 else if (leftvt == VT_NULL || rightvt == VT_NULL)
3591                 {
3592                     resvt = VT_NULL;
3593                 }
3594                 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
3595                 {
3596                     if (leftvt == rightvt)
3597                         resvt = VT_UI1;
3598                     else if (leftvt == rightvt ||
3599                         leftvt == VT_I2 || rightvt == VT_I2 ||
3600                         leftvt == VT_BOOL || rightvt == VT_BOOL)
3601                     {
3602                         resvt = VT_I2;
3603                     }
3604                     else if (leftvt == VT_I8 || rightvt == VT_I8)
3605                         resvt = VT_I8;
3606                 }
3607                 else if (leftvt == VT_I2 || rightvt == VT_I2)
3608                 {
3609                     if (leftvt == rightvt ||
3610                         leftvt == VT_BOOL || rightvt == VT_BOOL)
3611                         resvt = VT_I2;
3612                     else if (leftvt == VT_I8 || rightvt == VT_I8)
3613                         resvt = VT_I8;
3614                 }
3615                 else if (leftvt == VT_BOOL && rightvt == VT_BOOL)
3616                 {
3617                     resvt = VT_BOOL;
3618                 }
3619                 else if (leftvt == VT_I8 || rightvt == VT_I8)
3620                 {
3621                     if (leftvt == VT_INT || rightvt == VT_INT)
3622                         bFail = TRUE;
3623                     else
3624                         resvt = VT_I8;
3625                 }
3626                 hres = pVarOr(&left, &right, &result);
3627                 if (bFail)
3628                     ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
3629                        "VarOr: %d|0x%X, %d|0x%X: Expected failure, got 0x%lX vt %d\n",
3630                        leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres,
3631                        V_VT(&result));
3632                 else
3633                     ok(hres == S_OK && V_VT(&result) == resvt,
3634                        "VarOr: %d|0x%X, %d|0x%X: expected S_OK, vt %d, got 0x%lX vt %d\n",
3635                        leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], resvt, hres,
3636                        V_VT(&result));
3637             }
3638         }
3639     }
3640
3641     /* Test returned values. Since we know the returned type is correct
3642      * and that we handle all combinations of invalid types, just check
3643      * that good type combinations produce the desired value.
3644      * FIXME: Test VT_DECIMAL/VT_DISPATCH
3645      */
3646     VAROR(EMPTY,0,EMPTY,0,I2,0);
3647     VAROR(EMPTY,1,EMPTY,0,I2,0);
3648     VAROR(EMPTY,0,NULL,0,NULL,0);
3649     VAROR(EMPTY,0,I1,0,I4,0);
3650     VAROR(EMPTY,0,I1,1,I4,1);
3651     VAROR(EMPTY,0,UI1,0,I2,0);
3652     VAROR(EMPTY,0,UI1,1,I2,1);
3653     VAROR(EMPTY,0,I2,0,I2,0);
3654     VAROR(EMPTY,0,I2,1,I2,1);
3655     VAROR(EMPTY,0,UI2,0,I4,0);
3656     VAROR(EMPTY,0,UI2,1,I4,1);
3657     VAROR(EMPTY,0,I4,0,I4,0);
3658     VAROR(EMPTY,0,I4,1,I4,1);
3659     VAROR(EMPTY,0,UI4,0,I4,0);
3660     VAROR(EMPTY,0,UI4,1,I4,1);
3661     if (HAVE_OLEAUT32_I8)
3662     {
3663         VAROR(EMPTY,0,I8,0,I8,0);
3664         VAROR(EMPTY,0,I8,1,I8,1);
3665         VAROR(EMPTY,0,UI8,0,I4,0);
3666         VAROR(EMPTY,0,UI8,1,I4,1);
3667     }
3668     VAROR(EMPTY,0,INT,0,I4,0);
3669     VAROR(EMPTY,0,INT,1,I4,1);
3670     VAROR(EMPTY,0,UINT,0,I4,0);
3671     VAROR(EMPTY,0,UINT,1,I4,1);
3672     VAROR(EMPTY,0,BOOL,0,I2,0);
3673     VAROR(EMPTY,0,BOOL,1,I2,1);
3674     VAROR(EMPTY,0,R4,0,I4,0);
3675     VAROR(EMPTY,0,R4,1,I4,1);
3676     VAROR(EMPTY,0,R8,0,I4,0);
3677     VAROR(EMPTY,0,R8,1,I4,1);
3678     rbstr = SysAllocString(szFalse);
3679     VAROR(EMPTY,0,BSTR,rbstr,I2,0);
3680     rbstr = SysAllocString(szTrue);
3681     VAROR(EMPTY,0,BSTR,rbstr,I2,-1);
3682     VARORCY(EMPTY,0,10000,I4,1);
3683
3684     /* NULL OR 0 = NULL. NULL OR n = n */
3685     VAROR(NULL,0,NULL,0,NULL,0);
3686     VAROR(NULL,1,NULL,0,NULL,0);
3687     VAROR(NULL,0,I1,0,NULL,0);
3688     VAROR(NULL,0,I1,1,I4,1);
3689     VAROR(NULL,0,UI1,0,NULL,0);
3690     VAROR(NULL,0,UI1,1,UI1,1);
3691     VAROR(NULL,0,I2,0,NULL,0);
3692     VAROR(NULL,0,I2,1,I2,1);
3693     VAROR(NULL,0,UI2,0,NULL,0);
3694     VAROR(NULL,0,UI2,1,I4,1);
3695     VAROR(NULL,0,I4,0,NULL,0);
3696     VAROR(NULL,0,I4,1,I4,1);
3697     VAROR(NULL,0,UI4,0,NULL,0);
3698     VAROR(NULL,0,UI4,1,I4,1);
3699     if (HAVE_OLEAUT32_I8)
3700     {
3701         VAROR(NULL,0,I8,0,NULL,0);
3702         VAROR(NULL,0,I8,1,I8,1);
3703         VAROR(NULL,0,UI8,0,NULL,0);
3704         VAROR(NULL,0,UI8,1,I4,1);
3705     }
3706     VAROR(NULL,0,INT,0,NULL,0);
3707     VAROR(NULL,0,INT,1,I4,1);
3708     VAROR(NULL,0,UINT,0,NULL,0);
3709     VAROR(NULL,0,UINT,1,I4,1);
3710     VAROR(NULL,0,BOOL,0,NULL,0);
3711     VAROR(NULL,0,BOOL,1,BOOL,1);
3712     VAROR(NULL,0,R4,0,NULL,0);
3713     VAROR(NULL,0,R4,1,I4,1);
3714     VAROR(NULL,0,R8,0,NULL,0);
3715     VAROR(NULL,0,R8,1,I4,1);
3716     rbstr = SysAllocString(szFalse);
3717     VAROR(NULL,0,BSTR,rbstr,NULL,0);
3718     rbstr = SysAllocString(szTrue);
3719     VAROR(NULL,0,BSTR,rbstr,BOOL,VARIANT_TRUE);
3720     VARORCY(NULL,0,10000,I4,1);
3721     VARORCY(NULL,0,0,NULL,0);
3722
3723     VAROR(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
3724     VAROR(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE);
3725     VAROR(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
3726     VAROR(BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE);
3727     /* Assume x,y & y,x are the same from now on to reduce the number of tests */
3728     VAROR(BOOL,VARIANT_TRUE,I1,-1,I4,-1);
3729     VAROR(BOOL,VARIANT_TRUE,I1,0,I4,-1);
3730     VAROR(BOOL,VARIANT_FALSE,I1,0,I4,0);
3731     VAROR(BOOL,VARIANT_TRUE,UI1,255,I2,-1);
3732     VAROR(BOOL,VARIANT_TRUE,UI1,0,I2,-1);
3733     VAROR(BOOL,VARIANT_FALSE,UI1,0,I2,0);
3734     VAROR(BOOL,VARIANT_TRUE,I2,-1,I2,-1);
3735     VAROR(BOOL,VARIANT_TRUE,I2,0,I2,-1);
3736     VAROR(BOOL,VARIANT_FALSE,I2,0,I2,0);
3737     VAROR(BOOL,VARIANT_TRUE,UI2,65535,I4,-1);
3738     VAROR(BOOL,VARIANT_TRUE,UI2,0,I4,-1);
3739     VAROR(BOOL,VARIANT_FALSE,UI2,0,I4,0);
3740     VAROR(BOOL,VARIANT_TRUE,I4,-1,I4,-1);
3741     VAROR(BOOL,VARIANT_TRUE,I4,0,I4,-1);
3742     VAROR(BOOL,VARIANT_FALSE,I4,0,I4,0);
3743     VAROR(BOOL,VARIANT_TRUE,UI4,0xffffffff,I4,-1);
3744     VAROR(BOOL,VARIANT_TRUE,UI4,0,I4,-1);
3745     VAROR(BOOL,VARIANT_FALSE,UI4,0,I4,0);
3746     VAROR(BOOL,VARIANT_TRUE,R4,-1,I4,-1);
3747     VAROR(BOOL,VARIANT_TRUE,R4,0,I4,-1);
3748     VAROR(BOOL,VARIANT_FALSE,R4,0,I4,0);
3749     VAROR(BOOL,VARIANT_TRUE,R8,-1,I4,-1);
3750     VAROR(BOOL,VARIANT_TRUE,R8,0,I4,-1);
3751     VAROR(BOOL,VARIANT_FALSE,R8,0,I4,0);
3752     VAROR(BOOL,VARIANT_TRUE,DATE,-1,I4,-1);
3753     VAROR(BOOL,VARIANT_TRUE,DATE,0,I4,-1);
3754     VAROR(BOOL,VARIANT_FALSE,DATE,0,I4,0);
3755     if (HAVE_OLEAUT32_I8)
3756     {
3757         VAROR(BOOL,VARIANT_TRUE,I8,-1,I8,-1);
3758         VAROR(BOOL,VARIANT_TRUE,I8,0,I8,-1);
3759         VAROR(BOOL,VARIANT_FALSE,I8,0,I8,0);
3760         /* This returns DISP_E_OVERFLOW which indicates that a conversion
3761          * to I4 is performed.
3762          */
3763         /* VAROR(BOOL,VARIANT_TRUE,UI8,-1,I4,-1); */
3764         VAROR(BOOL,VARIANT_TRUE,UI8,0,I4,-1);
3765         VAROR(BOOL,VARIANT_FALSE,UI8,0,I4,0);
3766     }
3767     VAROR(BOOL,VARIANT_TRUE,INT,-1,I4,-1);
3768     VAROR(BOOL,VARIANT_TRUE,INT,0,I4,-1);
3769     VAROR(BOOL,VARIANT_FALSE,INT,0,I4,0);
3770     VAROR(BOOL,VARIANT_TRUE,UINT,0xffffffff,I4,-1);
3771     VAROR(BOOL,VARIANT_TRUE,UINT,0,I4,-1);
3772     VAROR(BOOL,VARIANT_FALSE,UINT,0,I4,0);
3773     rbstr = SysAllocString(szFalse);
3774     VAROR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_FALSE);
3775     VAROR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_TRUE);
3776     rbstr = SysAllocString(szTrue);
3777     VAROR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_TRUE);
3778     VAROR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_TRUE);
3779     VARORCY(BOOL,VARIANT_TRUE,10000,I4,-1);
3780     VARORCY(BOOL,VARIANT_TRUE,0,I4,-1);
3781     VARORCY(BOOL,VARIANT_FALSE,0,I4,0);
3782
3783     VAROR(I1,-1,I1,-1,I4,-1);
3784     VAROR(I1,-1,I1,0,I4,-1);
3785     VAROR(I1,0,I1,0,I4,0);
3786     VAROR(I1,-1,UI1,255,I4,-1);
3787     VAROR(I1,-1,UI1,0,I4,-1);
3788     VAROR(I1,0,UI1,0,I4,0);
3789     VAROR(I1,-1,I2,-1,I4,-1);
3790     VAROR(I1,-1,I2,0,I4,-1);
3791     VAROR(I1,0,I2,0,I4,0);
3792     VAROR(I1,-1,UI2,65535,I4,-1);
3793     VAROR(I1,-1,UI2,0,I4,-1);
3794     VAROR(I1,0,UI2,0,I4,0);
3795     VAROR(I1,-1,I4,-1,I4,-1);
3796     VAROR(I1,-1,I4,0,I4,-1);
3797     VAROR(I1,0,I4,0,I4,0);
3798     VAROR(I1,-1,UI4,0xffffffff,I4,-1);
3799     VAROR(I1,-1,UI4,0,I4,-1);
3800     VAROR(I1,0,UI4,0,I4,0);
3801     VAROR(I1,-1,R4,-1,I4,-1);
3802     VAROR(I1,-1,R4,0,I4,-1);
3803     VAROR(I1,0,R4,0,I4,0);
3804     VAROR(I1,-1,R8,-1,I4,-1);
3805     VAROR(I1,-1,R8,0,I4,-1);
3806     VAROR(I1,0,R8,0,I4,0);
3807     VAROR(I1,-1,DATE,-1,I4,-1);
3808     VAROR(I1,-1,DATE,0,I4,-1);
3809     VAROR(I1,0,DATE,0,I4,0);
3810     if (HAVE_OLEAUT32_I8)
3811     {
3812         VAROR(I1,-1,I8,-1,I8,-1);
3813         VAROR(I1,-1,I8,0,I8,-1);
3814         VAROR(I1,0,I8,0,I8,0);
3815         VAROR(I1,-1,UI8,0,I4,-1);
3816         VAROR(I1,0,UI8,0,I4,0);
3817     }
3818     VAROR(I1,-1,INT,-1,I4,-1);
3819     VAROR(I1,-1,INT,0,I4,-1);
3820     VAROR(I1,0,INT,0,I4,0);
3821     VAROR(I1,-1,UINT,0xffffffff,I4,-1);
3822     VAROR(I1,-1,UINT,0,I4,-1);
3823     VAROR(I1,0,UINT,0,I4,0);
3824     rbstr = SysAllocString(szFalse);
3825     VAROR(I1,0,BSTR,rbstr,I4,0);
3826     VAROR(I1,-1,BSTR,rbstr,I4,-1);
3827     rbstr = SysAllocString(szTrue);
3828     VAROR(I1,0,BSTR,rbstr,I4,-1);
3829     VAROR(I1,-1,BSTR,rbstr,I4,-1);
3830     VARORCY(I1,-1,10000,I4,-1);
3831     VARORCY(I1,-1,0,I4,-1);
3832     VARORCY(I1,0,0,I4,0);
3833
3834     VAROR(UI1,255,UI1,255,UI1,255);
3835     VAROR(UI1,255,UI1,0,UI1,255);
3836     VAROR(UI1,0,UI1,0,UI1,0);
3837     VAROR(UI1,255,I2,-1,I2,-1);
3838     VAROR(UI1,255,I2,0,I2,255);
3839     VAROR(UI1,0,I2,0,I2,0);
3840     VAROR(UI1,255,UI2,65535,I4,65535);
3841     VAROR(UI1,255,UI2,0,I4,255);
3842     VAROR(UI1,0,UI2,0,I4,0);
3843     VAROR(UI1,255,I4,-1,I4,-1);
3844     VAROR(UI1,255,I4,0,I4,255);
3845     VAROR(UI1,0,I4,0,I4,0);
3846     VAROR(UI1,255,UI4,0xffffffff,I4,-1);
3847     VAROR(UI1,255,UI4,0,I4,255);
3848     VAROR(UI1,0,UI4,0,I4,0);
3849     VAROR(UI1,255,R4,-1,I4,-1);
3850     VAROR(UI1,255,R4,0,I4,255);
3851     VAROR(UI1,0,R4,0,I4,0);
3852     VAROR(UI1,255,R8,-1,I4,-1);
3853     VAROR(UI1,255,R8,0,I4,255);
3854     VAROR(UI1,0,R8,0,I4,0);
3855     VAROR(UI1,255,DATE,-1,I4,-1);
3856     VAROR(UI1,255,DATE,0,I4,255);
3857     VAROR(UI1,0,DATE,0,I4,0);
3858     if (HAVE_OLEAUT32_I8)
3859     {
3860         VAROR(UI1,255,I8,-1,I8,-1);
3861         VAROR(UI1,255,I8,0,I8,255);
3862         VAROR(UI1,0,I8,0,I8,0);
3863         VAROR(UI1,255,UI8,0,I4,255);
3864         VAROR(UI1,0,UI8,0,I4,0);
3865     }
3866     VAROR(UI1,255,INT,-1,I4,-1);
3867     VAROR(UI1,255,INT,0,I4,255);
3868     VAROR(UI1,0,INT,0,I4,0);
3869     VAROR(UI1,255,UINT,0xffffffff,I4,-1);
3870     VAROR(UI1,255,UINT,0,I4,255);
3871     VAROR(UI1,0,UINT,0,I4,0);
3872     rbstr = SysAllocString(szFalse);
3873     VAROR(UI1,0,BSTR,rbstr,I2,0);
3874     VAROR(UI1,255,BSTR,rbstr,I2,255);
3875     rbstr = SysAllocString(szTrue);
3876     VAROR(UI1,0,BSTR,rbstr,I2,-1);
3877     VAROR(UI1,255,BSTR,rbstr,I2,-1);
3878     VARORCY(UI1,255,10000,I4,255);
3879     VARORCY(UI1,255,0,I4,255);
3880     VARORCY(UI1,0,0,I4,0);
3881
3882     VAROR(I2,-1,I2,-1,I2,-1);
3883     VAROR(I2,-1,I2,0,I2,-1);
3884     VAROR(I2,0,I2,0,I2,0);
3885     VAROR(I2,-1,UI2,65535,I4,-1);
3886     VAROR(I2,-1,UI2,0,I4,-1);
3887     VAROR(I2,0,UI2,0,I4,0);
3888     VAROR(I2,-1,I4,-1,I4,-1);
3889     VAROR(I2,-1,I4,0,I4,-1);
3890     VAROR(I2,0,I4,0,I4,0);
3891     VAROR(I2,-1,UI4,0xffffffff,I4,-1);
3892     VAROR(I2,-1,UI4,0,I4,-1);
3893     VAROR(I2,0,UI4,0,I4,0);
3894     VAROR(I2,-1,R4,-1,I4,-1);
3895     VAROR(I2,-1,R4,0,I4,-1);
3896     VAROR(I2,0,R4,0,I4,0);
3897     VAROR(I2,-1,R8,-1,I4,-1);
3898     VAROR(I2,-1,R8,0,I4,-1);
3899     VAROR(I2,0,R8,0,I4,0);
3900     VAROR(I2,-1,DATE,-1,I4,-1);
3901     VAROR(I2,-1,DATE,0,I4,-1);
3902     VAROR(I2,0,DATE,0,I4,0);
3903     if (HAVE_OLEAUT32_I8)
3904     {
3905         VAROR(I2,-1,I8,-1,I8,-1);
3906         VAROR(I2,-1,I8,0,I8,-1);
3907         VAROR(I2,0,I8,0,I8,0);
3908         VAROR(I2,-1,UI8,0,I4,-1);
3909         VAROR(I2,0,UI8,0,I4,0);
3910     }
3911     VAROR(I2,-1,INT,-1,I4,-1);
3912     VAROR(I2,-1,INT,0,I4,-1);
3913     VAROR(I2,0,INT,0,I4,0);
3914     VAROR(I2,-1,UINT,0xffffffff,I4,-1);
3915     VAROR(I2,-1,UINT,0,I4,-1);
3916     VAROR(I2,0,UINT,0,I4,0);
3917     rbstr = SysAllocString(szFalse);
3918     VAROR(I2,0,BSTR,rbstr,I2,0);
3919     VAROR(I2,-1,BSTR,rbstr,I2,-1);
3920     rbstr = SysAllocString(szTrue);
3921     VAROR(I2,0,BSTR,rbstr,I2,-1);
3922     VAROR(I2,-1,BSTR,rbstr,I2,-1);
3923     VARORCY(I2,-1,10000,I4,-1);
3924     VARORCY(I2,-1,0,I4,-1);
3925     VARORCY(I2,0,0,I4,0);
3926
3927     VAROR(UI2,65535,UI2,65535,I4,65535);
3928     VAROR(UI2,65535,UI2,0,I4,65535);
3929     VAROR(UI2,0,UI2,0,I4,0);
3930     VAROR(UI2,65535,I4,-1,I4,-1);
3931     VAROR(UI2,65535,I4,0,I4,65535);
3932     VAROR(UI2,0,I4,0,I4,0);
3933     VAROR(UI2,65535,UI4,0xffffffff,I4,-1);
3934     VAROR(UI2,65535,UI4,0,I4,65535);
3935     VAROR(UI2,0,UI4,0,I4,0);
3936     VAROR(UI2,65535,R4,-1,I4,-1);
3937     VAROR(UI2,65535,R4,0,I4,65535);
3938     VAROR(UI2,0,R4,0,I4,0);
3939     VAROR(UI2,65535,R8,-1,I4,-1);
3940     VAROR(UI2,65535,R8,0,I4,65535);
3941     VAROR(UI2,0,R8,0,I4,0);
3942     VAROR(UI2,65535,DATE,-1,I4,-1);
3943     VAROR(UI2,65535,DATE,0,I4,65535);
3944     VAROR(UI2,0,DATE,0,I4,0);
3945     if (HAVE_OLEAUT32_I8)
3946     {
3947         VAROR(UI2,65535,I8,-1,I8,-1);
3948         VAROR(UI2,65535,I8,0,I8,65535);
3949         VAROR(UI2,0,I8,0,I8,0);
3950         VAROR(UI2,65535,UI8,0,I4,65535);
3951         VAROR(UI2,0,UI8,0,I4,0);
3952     }
3953     VAROR(UI2,65535,INT,-1,I4,-1);
3954     VAROR(UI2,65535,INT,0,I4,65535);
3955     VAROR(UI2,0,INT,0,I4,0);
3956     VAROR(UI2,65535,UINT,0xffffffff,I4,-1);
3957     VAROR(UI2,65535,UINT,0,I4,65535);
3958     VAROR(UI2,0,UINT,0,I4,0);
3959     rbstr = SysAllocString(szFalse);
3960     VAROR(UI2,0,BSTR,rbstr,I4,0);
3961     VAROR(UI2,65535,BSTR,rbstr,I4,65535);
3962     rbstr = SysAllocString(szTrue);
3963     VAROR(UI2,0,BSTR,rbstr,I4,-1);
3964     VAROR(UI2,65535,BSTR,rbstr,I4,-1);
3965     VARORCY(UI2,65535,10000,I4,65535);
3966     VARORCY(UI2,65535,0,I4,65535);
3967     VARORCY(UI2,0,0,I4,0);
3968
3969     VAROR(I4,-1,I4,-1,I4,-1);
3970     VAROR(I4,-1,I4,0,I4,-1);
3971     VAROR(I4,0,I4,0,I4,0);
3972     VAROR(I4,-1,UI4,0xffffffff,I4,-1);
3973     VAROR(I4,-1,UI4,0,I4,-1);
3974     VAROR(I4,0,UI4,0,I4,0);
3975     VAROR(I4,-1,R4,-1,I4,-1);
3976     VAROR(I4,-1,R4,0,I4,-1);
3977     VAROR(I4,0,R4,0,I4,0);
3978     VAROR(I4,-1,R8,-1,I4,-1);
3979     VAROR(I4,-1,R8,0,I4,-1);
3980     VAROR(I4,0,R8,0,I4,0);
3981     VAROR(I4,-1,DATE,-1,I4,-1);
3982     VAROR(I4,-1,DATE,0,I4,-1);
3983     VAROR(I4,0,DATE,0,I4,0);
3984     if (HAVE_OLEAUT32_I8)
3985     {
3986         VAROR(I4,-1,I8,-1,I8,-1);
3987         VAROR(I4,-1,I8,0,I8,-1);
3988         VAROR(I4,0,I8,0,I8,0);
3989         VAROR(I4,-1,UI8,0,I4,-1);
3990         VAROR(I4,0,UI8,0,I4,0);
3991     }
3992     VAROR(I4,-1,INT,-1,I4,-1);
3993     VAROR(I4,-1,INT,0,I4,-1);
3994     VAROR(I4,0,INT,0,I4,0);
3995     VAROR(I4,-1,UINT,0xffffffff,I4,-1);
3996     VAROR(I4,-1,UINT,0,I4,-1);
3997     VAROR(I4,0,UINT,0,I4,0);
3998     rbstr = SysAllocString(szFalse);
3999     VAROR(I4,0,BSTR,rbstr,I4,0);
4000     VAROR(I4,-1,BSTR,rbstr,I4,-1);
4001     rbstr = SysAllocString(szTrue);
4002     VAROR(I4,0,BSTR,rbstr,I4,-1);
4003     VAROR(I4,-1,BSTR,rbstr,I4,-1);
4004     VARORCY(I4,-1,10000,I4,-1);
4005     VARORCY(I4,-1,0,I4,-1);
4006     VARORCY(I4,0,0,I4,0);
4007
4008     VAROR(UI4,0xffffffff,UI4,0xffffffff,I4,-1);
4009     VAROR(UI4,0xffffffff,UI4,0,I4,-1);
4010     VAROR(UI4,0,UI4,0,I4,0);
4011     VAROR(UI4,0xffffffff,R4,-1,I4,-1);
4012     VAROR(UI4,0xffffffff,R4,0,I4,-1);
4013     VAROR(UI4,0,R4,0,I4,0);
4014     VAROR(UI4,0xffffffff,R8,-1,I4,-1);
4015     VAROR(UI4,0xffffffff,R8,0,I4,-1);
4016     VAROR(UI4,0,R8,0,I4,0);
4017     VAROR(UI4,0xffffffff,DATE,-1,I4,-1);
4018     VAROR(UI4,0xffffffff,DATE,0,I4,-1);
4019     VAROR(UI4,0,DATE,0,I4,0);
4020     if (HAVE_OLEAUT32_I8)
4021     {
4022         VAROR(UI4,0xffffffff,I8,-1,I8,-1);
4023         VAROR(UI4,0xffffffff,I8,0,I8,0xffffffff);
4024         VAROR(UI4,0,I8,0,I8,0);
4025         VAROR(UI4,0xffffffff,UI8,0,I4,-1);
4026         VAROR(UI4,0,UI8,0,I4,0);
4027     }
4028     VAROR(UI4,0xffffffff,INT,-1,I4,-1);
4029     VAROR(UI4,0xffffffff,INT,0,I4,-1);
4030     VAROR(UI4,0,INT,0,I4,0);
4031     VAROR(UI4,0xffffffff,UINT,0xffffffff,I4,-1);
4032     VAROR(UI4,0xffffffff,UINT,0,I4,-1);
4033     VAROR(UI4,0,UINT,0,I4,0);
4034     rbstr = SysAllocString(szFalse);
4035     VAROR(UI4,0,BSTR,rbstr,I4,0);
4036     VAROR(UI4,0xffffffff,BSTR,rbstr,I4,-1);
4037     rbstr = SysAllocString(szTrue);
4038     VAROR(UI4,0,BSTR,rbstr,I4,-1);
4039     VAROR(UI4,0xffffffff,BSTR,rbstr,I4,-1);
4040     VARORCY(UI4,0xffffffff,10000,I4,-1);
4041     VARORCY(UI4,0xffffffff,0,I4,-1);
4042     VARORCY(UI4,0,0,I4,0);
4043
4044     VAROR(R4,-1,R4,-1,I4,-1);
4045     VAROR(R4,-1,R4,0,I4,-1);
4046     VAROR(R4,0,R4,0,I4,0);
4047     VAROR(R4,-1,R8,-1,I4,-1);
4048     VAROR(R4,-1,R8,0,I4,-1);
4049     VAROR(R4,0,R8,0,I4,0);
4050     VAROR(R4,-1,DATE,-1,I4,-1);
4051     VAROR(R4,-1,DATE,0,I4,-1);
4052     VAROR(R4,0,DATE,0,I4,0);
4053     if (HAVE_OLEAUT32_I8)
4054     {
4055         VAROR(R4,-1,I8,-1,I8,-1);
4056         VAROR(R4,-1,I8,0,I8,-1);
4057         VAROR(R4,0,I8,0,I8,0);
4058         VAROR(R4,-1,UI8,0,I4,-1);
4059         VAROR(R4,0,UI8,0,I4,0);
4060     }
4061     VAROR(R4,-1,INT,-1,I4,-1);
4062     VAROR(R4,-1,INT,0,I4,-1);
4063     VAROR(R4,0,INT,0,I4,0);
4064     VAROR(R4,-1,UINT,0xffffffff,I4,-1);
4065     VAROR(R4,-1,UINT,0,I4,-1);
4066     VAROR(R4,0,UINT,0,I4,0);
4067     rbstr = SysAllocString(szFalse);
4068     VAROR(R4,0,BSTR,rbstr,I4,0);
4069     VAROR(R4,-1,BSTR,rbstr,I4,-1);
4070     rbstr = SysAllocString(szTrue);
4071     VAROR(R4,0,BSTR,rbstr,I4,-1);
4072     VAROR(R4,-1,BSTR,rbstr,I4,-1);
4073     VARORCY(R4,-1,10000,I4,-1);
4074     VARORCY(R4,-1,0,I4,-1);
4075     VARORCY(R4,0,0,I4,0);
4076
4077     VAROR(R8,-1,R8,-1,I4,-1);
4078     VAROR(R8,-1,R8,0,I4,-1);
4079     VAROR(R8,0,R8,0,I4,0);
4080     VAROR(R8,-1,DATE,-1,I4,-1);
4081     VAROR(R8,-1,DATE,0,I4,-1);
4082     VAROR(R8,0,DATE,0,I4,0);
4083     if (HAVE_OLEAUT32_I8)
4084     {
4085         VAROR(R8,-1,I8,-1,I8,-1);
4086         VAROR(R8,-1,I8,0,I8,-1);
4087         VAROR(R8,0,I8,0,I8,0);
4088         VAROR(R8,-1,UI8,0,I4,-1);
4089         VAROR(R8,0,UI8,0,I4,0);
4090     }
4091     VAROR(R8,-1,INT,-1,I4,-1);
4092     VAROR(R8,-1,INT,0,I4,-1);
4093     VAROR(R8,0,INT,0,I4,0);
4094     VAROR(R8,-1,UINT,0xffffffff,I4,-1);
4095     VAROR(R8,-1,UINT,0,I4,-1);
4096     VAROR(R8,0,UINT,0,I4,0);
4097     rbstr = SysAllocString(szFalse);
4098     VAROR(R8,0,BSTR,rbstr,I4,0);
4099     VAROR(R8,-1,BSTR,rbstr,I4,-1);
4100     rbstr = SysAllocString(szTrue);
4101     VAROR(R8,0,BSTR,rbstr,I4,-1);
4102     VAROR(R8,-1,BSTR,rbstr,I4,-1);
4103     VARORCY(R8,-1,10000,I4,-1);
4104     VARORCY(R8,-1,0,I4,-1);
4105     VARORCY(R8,0,0,I4,0);
4106
4107     VAROR(DATE,-1,DATE,-1,I4,-1);
4108     VAROR(DATE,-1,DATE,0,I4,-1);
4109     VAROR(DATE,0,DATE,0,I4,0);
4110     if (HAVE_OLEAUT32_I8)
4111     {
4112         VAROR(DATE,-1,I8,-1,I8,-1);
4113         VAROR(DATE,-1,I8,0,I8,-1);
4114         VAROR(DATE,0,I8,0,I8,0);
4115         VAROR(DATE,-1,UI8,0,I4,-1);
4116         VAROR(DATE,0,UI8,0,I4,0);
4117     }
4118     VAROR(DATE,-1,INT,-1,I4,-1);
4119     VAROR(DATE,-1,INT,0,I4,-1);
4120     VAROR(DATE,0,INT,0,I4,0);
4121     VAROR(DATE,-1,UINT,0xffffffff,I4,-1);
4122     VAROR(DATE,-1,UINT,0,I4,-1);
4123     VAROR(DATE,0,UINT,0,I4,0);
4124     rbstr = SysAllocString(szFalse);
4125     VAROR(DATE,0,BSTR,rbstr,I4,0);
4126     VAROR(DATE,-1,BSTR,rbstr,I4,-1);
4127     rbstr = SysAllocString(szTrue);
4128     VAROR(DATE,0,BSTR,rbstr,I4,-1);
4129     VAROR(DATE,-1,BSTR,rbstr,I4,-1);
4130     VARORCY(DATE,-1,10000,I4,-1);
4131     VARORCY(DATE,-1,0,I4,-1);
4132     VARORCY(DATE,0,0,I4,0);
4133
4134     if (HAVE_OLEAUT32_I8)
4135     {
4136         VAROR(I8,-1,I8,-1,I8,-1);
4137         VAROR(I8,-1,I8,0,I8,-1);
4138         VAROR(I8,0,I8,0,I8,0);
4139         VAROR(I8,-1,UI8,0,I8,-1);
4140         VAROR(I8,0,UI8,0,I8,0);
4141         /* These overflow under native and Wine
4142         VAROR(I8,-1,INT,-1,I4,-1);
4143         VAROR(I8,-1,INT,0,I4,-1);
4144         VAROR(I8,0,INT,0,I4,0); */
4145         VAROR(I8,-1,UINT,0xffffffff,I8,-1);
4146         VAROR(I8,-1,UINT,0,I8,-1);
4147         VAROR(I8,0,UINT,0,I8,0);
4148         rbstr = SysAllocString(szFalse);
4149         VAROR(I8,0,BSTR,rbstr,I8,0);
4150         VAROR(I8,-1,BSTR,rbstr,I8,-1);
4151         rbstr = SysAllocString(szTrue);
4152         VAROR(I8,0,BSTR,rbstr,I8,-1);
4153         VAROR(I8,-1,BSTR,rbstr,I8,-1);
4154         VARORCY(I8,-1,10000,I8,-1);
4155         VARORCY(I8,-1,0,I8,-1);
4156         VARORCY(I8,0,0,I8,0);
4157
4158         VAROR(UI8,0xffff,UI8,0xffff,I4,0xffff);
4159         VAROR(UI8,0xffff,UI8,0,I4,0xffff);
4160         VAROR(UI8,0,UI8,0,I4,0);
4161         VAROR(UI8,0xffff,INT,-1,I4,-1);
4162         VAROR(UI8,0xffff,INT,0,I4,0xffff);
4163         VAROR(UI8,0,INT,0,I4,0);
4164         VAROR(UI8,0xffff,UINT,0xffff,I4,0xffff);
4165         VAROR(UI8,0xffff,UINT,0,I4,0xffff);
4166         VAROR(UI8,0,UINT,0,I4,0);
4167         rbstr = SysAllocString(szFalse);
4168         VAROR(UI8,0,BSTR,rbstr,I4,0);
4169         VAROR(UI8,0xffff,BSTR,rbstr,I4,0xffff);
4170         rbstr = SysAllocString(szTrue);
4171         VAROR(UI8,0,BSTR,rbstr,I4,-1);
4172         VAROR(UI8,0xffff,BSTR,rbstr,I4,-1);
4173         VARORCY(UI8,0xffff,10000,I4,0xffff);
4174         VARORCY(UI8,0xffff,0,I4,0xffff);
4175         VARORCY(UI8,0,0,I4,0);
4176     }
4177
4178     VAROR(INT,-1,INT,-1,I4,-1);
4179     VAROR(INT,-1,INT,0,I4,-1);
4180     VAROR(INT,0,INT,0,I4,0);
4181     VAROR(INT,-1,UINT,0xffff,I4,-1);
4182     VAROR(INT,-1,UINT,0,I4,-1);
4183     VAROR(INT,0,UINT,0,I4,0);
4184     rbstr = SysAllocString(szFalse);
4185     VAROR(INT,0,BSTR,rbstr,I4,0);
4186     VAROR(INT,-1,BSTR,rbstr,I4,-1);
4187     rbstr = SysAllocString(szTrue);
4188     VAROR(INT,0,BSTR,rbstr,I4,-1);
4189     VAROR(INT,-1,BSTR,rbstr,I4,-1);
4190     VARORCY(INT,-1,10000,I4,-1);
4191     VARORCY(INT,-1,0,I4,-1);
4192     VARORCY(INT,0,0,I4,0);
4193
4194     VAROR(UINT,0xffff,UINT,0xffff,I4,0xffff);
4195     VAROR(UINT,0xffff,UINT,0,I4,0xffff);
4196     VAROR(UINT,0,UINT,0,I4,0);
4197     rbstr = SysAllocString(szFalse);
4198     VAROR(UINT,0,BSTR,rbstr,I4,0);
4199     VAROR(UINT,0xffff,BSTR,rbstr,I4,0xffff);
4200     rbstr = SysAllocString(szTrue);
4201     VAROR(UINT,0,BSTR,rbstr,I4,-1);
4202     VAROR(UINT,0xffff,BSTR,rbstr,I4,-1);
4203     VARORCY(UINT,0xffff,10000,I4,0xffff);
4204     VARORCY(UINT,0xffff,0,I4,0xffff);
4205     VARORCY(UINT,0,0,I4,0);
4206
4207     lbstr = SysAllocString(szFalse);
4208     rbstr = SysAllocString(szFalse);
4209     VAROR(BSTR,lbstr,BSTR,rbstr,BOOL,0);
4210     rbstr = SysAllocString(szTrue);
4211     VAROR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_TRUE);
4212     lbstr = SysAllocString(szTrue);
4213     VAROR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_TRUE);
4214     VARORCY(BSTR,lbstr,10000,I4,-1);
4215     lbstr = SysAllocString(szFalse);
4216     VARORCY(BSTR,lbstr,10000,I4,1);
4217 }
4218
4219 static HRESULT (WINAPI *pVarEqv)(LPVARIANT,LPVARIANT,LPVARIANT);
4220
4221 static const char *szVarEqvFail = "VarEqv(%d,%d): expected 0x0,%d,%d, got 0x%lX,%d,%d\n";
4222 #define VAREQV(vt1,val1,vt2,val2,rvt,rval) \
4223         V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
4224         V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
4225         memset(&result,0,sizeof(result)); hres = pVarEqv(&left,&right,&result); \
4226         ok(hres == S_OK && V_VT(&result) == VT_##rvt && V_##rvt(&result) == (rval), \
4227         szVarEqvFail, VT_##vt1, VT_##vt2, \
4228         VT_##rvt, (int)(rval), hres, V_VT(&result), (int)V_##rvt(&result))
4229
4230 static void test_VarEqv(void)
4231 {
4232     VARIANT left, right, result;
4233     VARTYPE i;
4234     HRESULT hres;
4235
4236     CHECKPTR(VarEqv);
4237
4238     /* Test all possible flag/vt combinations & the resulting vt type */
4239     for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
4240     {
4241         VARTYPE leftvt, rightvt, resvt;
4242
4243         for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
4244         {
4245             SKIPTESTS(leftvt);
4246
4247             for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
4248             {
4249                 BOOL bFail = FALSE;
4250
4251                 SKIPTESTS(rightvt);
4252
4253                 if (leftvt == VT_BSTR || rightvt == VT_BSTR ||
4254                     leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
4255                     leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN)
4256                     continue;
4257
4258                 memset(&left, 0, sizeof(left));
4259                 memset(&right, 0, sizeof(right));
4260                 V_VT(&left) = leftvt | ExtraFlags[i];
4261                 V_VT(&right) = rightvt | ExtraFlags[i];
4262                 V_VT(&result) = VT_EMPTY;
4263                 resvt = VT_I4;
4264
4265                 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
4266                     !IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
4267                     !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
4268                     leftvt == VT_CLSID || rightvt == VT_CLSID ||
4269                     leftvt == VT_RECORD || rightvt == VT_RECORD ||
4270                     leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
4271                     leftvt == VT_ERROR || rightvt == VT_ERROR)
4272                 {
4273                     bFail = TRUE;
4274                 }
4275                 if (leftvt == VT_EMPTY || rightvt == VT_EMPTY)
4276                 {
4277                     if (leftvt == rightvt ||
4278                         leftvt == VT_I2 || rightvt == VT_I2 ||
4279                         leftvt == VT_UI1 || rightvt == VT_UI1 ||
4280                         leftvt == VT_BOOL || rightvt == VT_BOOL)
4281                         resvt = VT_I2;
4282                     else if (leftvt == VT_NULL || rightvt == VT_NULL)
4283                         resvt = VT_NULL;
4284                     else if (leftvt == VT_I8 || rightvt == VT_I8)
4285                         resvt = VT_I8;
4286                 }
4287                 else if (leftvt == VT_NULL || rightvt == VT_NULL)
4288                 {
4289                     resvt = VT_NULL;
4290                 }
4291                 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
4292                 {
4293                     if (leftvt == rightvt)
4294                         resvt = VT_UI1;
4295                     else if (leftvt == rightvt ||
4296                         leftvt == VT_I2 || rightvt == VT_I2 ||
4297                         leftvt == VT_BOOL || rightvt == VT_BOOL)
4298                     {
4299                         resvt = VT_I2;
4300                     }
4301                     else if (leftvt == VT_I8 || rightvt == VT_I8)
4302                         resvt = VT_I8;
4303                 }
4304                 else if (leftvt == VT_I2 || rightvt == VT_I2)
4305                 {
4306                     if (leftvt == rightvt ||
4307                         leftvt == VT_BOOL || rightvt == VT_BOOL)
4308                         resvt = VT_I2;
4309                     else if (leftvt == VT_I8 || rightvt == VT_I8)
4310                         resvt = VT_I8;
4311                 }
4312                 else if (leftvt == VT_BOOL && rightvt == VT_BOOL)
4313                 {
4314                     resvt = VT_BOOL;
4315                 }
4316                 else if (leftvt == VT_I8 || rightvt == VT_I8)
4317                 {
4318                     if (leftvt == VT_INT || rightvt == VT_INT)
4319                         bFail = TRUE;
4320                     else
4321                         resvt = VT_I8;
4322                 }
4323                 hres = pVarEqv(&left, &right, &result);
4324                 if (bFail)
4325                     ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
4326                        "VarEqv: %d|0x%X, %d|0x%X: Expected failure, got 0x%lX vt %d\n",
4327                        leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres,
4328                        V_VT(&result));
4329                 else
4330                     ok(hres == S_OK && V_VT(&result) == resvt,
4331                        "VarEqv: %d|0x%X, %d|0x%X: expected S_OK, vt %d, got 0x%lX vt %d\n",
4332                        leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], resvt, hres,
4333                        V_VT(&result));
4334             }
4335         }
4336     }
4337
4338     /* Test returned values */
4339     VAREQV(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
4340     VAREQV(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE);
4341     VAREQV(BOOL,TRUE,BOOL,TRUE,BOOL,VARIANT_TRUE);
4342     VAREQV(BOOL,FALSE,BOOL,FALSE,BOOL,VARIANT_TRUE);
4343     VAREQV(BOOL,TRUE,BOOL,FALSE,BOOL,-2);
4344     VAREQV(BOOL,FALSE,BOOL,TRUE,BOOL,-2);
4345     VAREQV(BOOL,6,BOOL,7,BOOL,-2);
4346     VAREQV(BOOL,6,BOOL,6,BOOL,VARIANT_TRUE);
4347     VAREQV(BOOL,VARIANT_TRUE,I2,VARIANT_TRUE,I2,VARIANT_TRUE);
4348     VAREQV(BOOL,VARIANT_TRUE,I2,VARIANT_FALSE,I2,VARIANT_FALSE);
4349     VAREQV(BOOL,6,I2,7,I2,-2);
4350     VAREQV(UI1,1,UI1,1,UI1,255);
4351     VAREQV(UI1,1,UI1,0,UI1,254);
4352     VAREQV(UI1,0,UI1,1,UI1,254);
4353     if (HAVE_OLEAUT32_I8)
4354     {
4355         VAREQV(UI4,VARIANT_FALSE,I8,VARIANT_FALSE,I8,-1);
4356         VAREQV(UI4,5,I8,19,I8,-23);
4357         VAREQV(UI4,VARIANT_FALSE,UI8,VARIANT_FALSE,I4,-1);
4358     }
4359 }
4360
4361 START_TEST(vartest)
4362 {
4363   hOleaut32 = LoadLibraryA("oleaut32.dll");
4364
4365   test_VariantInit();
4366   test_VariantClear();
4367   test_VariantCopy();
4368   test_VariantCopyInd();
4369   test_VarParseNumFromStr();
4370   test_VarNumFromParseNum();
4371   test_VarUdateFromDate();
4372   test_VarDateFromUdate();
4373   test_SystemTimeToVariantTime();
4374   test_VariantTimeToSystemTime();
4375   test_DosDateTimeToVariantTime();
4376   test_VariantTimeToDosDateTime();
4377   test_VarFormatNumber();
4378   test_VarFormat();
4379   test_VarAbs();
4380   test_VarNot();
4381   test_VarSub();
4382   test_VarMod();
4383   test_VarFix();
4384   test_VarInt();
4385   test_VarNeg();
4386   test_VarRound();
4387   test_VarXor();
4388   test_VarOr();
4389   test_VarEqv();
4390 }