kernel: Add some more tests for FindFirstChangeNotification.
[wine] / dlls / oleaut32 / tests / vartype.c
1 /*
2  * Low level variant tests
3  *
4  * Copyright 2003 Jon Griffiths
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 "wine/test.h"
22 #include "wine/unicode.h"
23 #include "oleauto.h"
24 #include <math.h>
25
26 /* Some Visual C++ versions choke on __uint64 to float conversions.
27  * To fix this you need either VC++ 6.0 plus the processor pack
28  * or Visual C++ >=7.0.
29  */
30 #ifndef _MSC_VER
31 #  define HAS_UINT64_TO_FLOAT
32 #else
33 #  if _MSC_VER >= 1300
34 #    define HAS_UINT64_TO_FLOAT
35 #  else
36 #    include <malloc.h>
37 #    if defined(_mm_free)
38 /*     _mm_free is defined if the Processor Pack has been installed */
39 #      define HAS_UINT64_TO_FLOAT
40 #    endif
41
42 #  endif
43 #endif
44
45 static HMODULE hOleaut32;
46
47 /* Get a conversion function ptr, return if function not available */
48 #define CHECKPTR(func) p##func = (void*)GetProcAddress(hOleaut32, #func); \
49   if (!p##func) { \
50     trace("function " # func " not available, not testing it\n"); return; }
51
52 /* Is a given function exported from oleaut32? */
53 #define HAVE_FUNC(func) ((void*)GetProcAddress(hOleaut32, #func) != NULL)
54
55 /* Have IRecordInfo data type? */
56 #define HAVE_OLEAUT32_RECORD  HAVE_FUNC(SafeArraySetRecordInfo)
57 /* Have DECIMAL data type with new error checking? */
58 #define HAVE_OLEAUT32_DECIMAL HAVE_FUNC(VarDecAdd)
59 /* Have CY data type? */
60 #define HAVE_OLEAUT32_CY      HAVE_FUNC(VarCyAdd)
61 /* Have I8/UI8 data type? */
62 #define HAVE_OLEAUT32_I8      HAVE_FUNC(VarI8FromI1)
63 /* Have proper locale conversions? */
64 #define HAVE_OLEAUT32_LOCALES (HAVE_FUNC(GetVarConversionLocaleSetting) && HAVE_OLEAUT32_I8)
65 /* Is this an ancient version with support for only I2/I4/R4/R8/DATE? */
66 #define IS_ANCIENT (!HAVE_FUNC(VarI1FromI2))
67 /* Is vt a type unavailable to ancient versions? */
68 #define IS_MODERN_VTYPE(vt) (vt==VT_VARIANT||vt==VT_DECIMAL|| \
69     vt==VT_I1||vt==VT_UI2||vt==VT_UI4||vt == VT_INT||vt == VT_UINT)
70
71 /* Macro for setting typ and initializing */
72 /* First some dummy definitions*/
73 int val_empty, val_null; 
74
75 #define V_EMPTY(x) val_empty
76 #define V_NULL(x) val_null
77
78 #define VARINIT( A, type, value)  V_VT(A) = VT##type; V##type(A) = value
79
80 /* Macros for converting and testing results */
81 #define CONVVARS(typ) HRESULT hres; CONV_TYPE out; typ in
82
83 #define _EXPECTRES(res, x, fs) \
84   ok((hres == S_OK && out == (CONV_TYPE)(x)) || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
85      "expected " #x ", got " fs "; hres=0x%08lx\n", out, hres)
86 #define EXPECT(x)       EXPECTRES(S_OK, (x))
87 #define EXPECT_OVERFLOW EXPECTRES(DISP_E_OVERFLOW, DISP_E_OVERFLOW)
88 #define EXPECT_MISMATCH EXPECTRES(DISP_E_TYPEMISMATCH,DISP_E_TYPEMISMATCH)
89 #define EXPECT_BADVAR   EXPECTRES(DISP_E_BADVARTYPE, DISP_E_BADVARTYPE)
90 #define EXPECT_INVALID  EXPECTRES(E_INVALIDARG, E_INVALIDARG)
91 #define EXPECT_LT       EXPECTRES(VARCMP_LT, VARCMP_LT)
92 #define EXPECT_GT       EXPECTRES(VARCMP_GT, VARCMP_GT)
93 #define EXPECT_EQ       EXPECTRES(VARCMP_EQ, VARCMP_EQ)
94 #define EXPECT_DBL(x)   \
95   ok(hres == S_OK && fabs(out-(x))<1e-14, "expected " #x ", got %16.16g; hres=0x%08lx\n", out, hres)
96
97 #define CONVERT(func, val) in = val; hres = p##func(in, &out)
98 #define CONVERTRANGE(func,start,end) for (i = start; i < end; i+=1) { CONVERT(func, i); EXPECT(i); };
99 #define OVERFLOWRANGE(func,start,end) for (i = start; i < end; i+=1) { CONVERT(func, i); EXPECT_OVERFLOW; };
100
101 #define CY_MULTIPLIER   10000
102
103 #define DATE_MIN -657434
104 #define DATE_MAX 2958465
105
106 #define CONVERT_I8(func,hi,lo) in = hi; in = (in << 32) | lo; hres = p##func(in, &out)
107
108 #define CONVERT_CY(func,val) in.int64 = (LONGLONG)(val * CY_MULTIPLIER); hres = p##func(in, &out)
109
110 #define CONVERT_CY64(func,hi,lo) S(in).Hi = hi; S(in).Lo = lo; in.int64 *= CY_MULTIPLIER; hres = p##func(in, &out)
111
112 #define SETDEC(dec, scl, sgn, hi, lo) S(U(dec)).scale = (BYTE)scl; S(U(dec)).sign = (BYTE)sgn; \
113   dec.Hi32 = (ULONG)hi; U1(dec).Lo64 = (ULONG64)lo
114
115 #define SETDEC64(dec, scl, sgn, hi, mid, lo) S(U(dec)).scale = (BYTE)scl; S(U(dec)).sign = (BYTE)sgn; \
116   dec.Hi32 = (ULONG)hi; S1(U1(dec)).Mid32 = mid; S1(U1(dec)).Lo32 = lo;
117
118 #define CONVERT_DEC(func,scl,sgn,hi,lo) SETDEC(in,scl,sgn,hi,lo); hres = p##func(&in, &out)
119
120 #define CONVERT_DEC64(func,scl,sgn,hi,mid,lo) SETDEC64(in,scl,sgn,hi,mid,lo); hres = p##func(&in, &out)
121
122 #define CONVERT_BADDEC(func) \
123   if (HAVE_OLEAUT32_DECIMAL) \
124   { \
125     CONVERT_DEC(func,29,0,0,0);   EXPECT_INVALID; \
126     CONVERT_DEC(func,0,0x1,0,0);  EXPECT_INVALID; \
127     CONVERT_DEC(func,0,0x40,0,0); EXPECT_INVALID; \
128     CONVERT_DEC(func,0,0x7f,0,0); EXPECT_INVALID; \
129   }
130
131 #define CONVERT_STR(func,str,flags) \
132   SetLastError(0); \
133   if (str) MultiByteToWideChar(CP_ACP,0,str,-1,buff,sizeof(buff)/sizeof(WCHAR)); \
134   hres = p##func(str ? buff : NULL,in,flags,&out)
135
136 #define COPYTEST(val, vt, srcval, dstval, srcref, dstref, fs) do { \
137   HRESULT hres; VARIANTARG vSrc, vDst; CONV_TYPE in = val; \
138   VariantInit(&vSrc); VariantInit(&vDst); \
139   V_VT(&vSrc) = vt; srcval = in; \
140   hres = VariantCopy(&vDst, &vSrc); \
141   ok(hres == S_OK && V_VT(&vDst) == vt && dstval == in, \
142      "copy hres 0x%lX, type %d, value (" fs ") " fs "\n", hres, V_VT(&vDst), val, dstval); \
143   V_VT(&vSrc) = vt|VT_BYREF; srcref = &in; \
144   hres = VariantCopy(&vDst, &vSrc); \
145   ok(hres == S_OK && V_VT(&vDst) == (vt|VT_BYREF) && dstref == &in, \
146      "ref hres 0x%lX, type %d, ref (%p) %p\n", hres, V_VT(&vDst), &in, dstref); \
147   hres = VariantCopyInd(&vDst, &vSrc); \
148   ok(hres == S_OK && V_VT(&vDst) == vt && dstval == in, \
149      "ind hres 0x%lX, type %d, value (" fs ") " fs "\n", hres, V_VT(&vDst), val, dstval); \
150   } while(0)
151
152 #define CHANGETYPEEX(typ) hres = VariantChangeTypeEx(&vDst, &vSrc, 0, 0, typ)
153
154 #define TYPETEST(typ,res,fs) CHANGETYPEEX(typ); \
155   ok(hres == S_OK && V_VT(&vDst) == typ && (CONV_TYPE)res == in, \
156      "hres=0x%lX, type=%d (should be %d(" #typ ")), value=" fs " (should be " fs ")\n", \
157       hres, V_VT(&vDst), typ, (CONV_TYPE)res, in);
158 #define TYPETESTI8(typ,res) CHANGETYPEEX(typ); \
159   ok(hres == S_OK && V_VT(&vDst) == typ && (CONV_TYPE)res == in, \
160      "hres=0x%lX, type=%d (should be %d(" #typ ")), value=%d (should be 1)\n", \
161       hres, V_VT(&vDst), typ, (int)res);
162 #define BADVAR(typ)   CHANGETYPEEX(typ); out = (CONV_TYPE)hres; EXPECT_BADVAR
163 #define MISMATCH(typ) CHANGETYPEEX(typ); out = (CONV_TYPE)hres; EXPECT_MISMATCH
164
165 #define INITIAL_TYPETEST(vt, val, fs) \
166   VariantInit(&vSrc); \
167   VariantInit(&vDst); \
168   V_VT(&vSrc) = vt; \
169   (val(&vSrc)) = in; \
170   if (!IS_ANCIENT) { \
171     TYPETEST(VT_I1, V_I1(&vDst), fs); \
172     TYPETEST(VT_UI2, V_UI2(&vDst), fs); \
173     TYPETEST(VT_UI4, V_UI4(&vDst), fs); \
174     TYPETEST(VT_INT, V_INT(&vDst), fs); \
175     TYPETEST(VT_UINT, V_UINT(&vDst), fs); \
176   } else {  \
177     BADVAR(VT_I1); BADVAR(VT_UI2); BADVAR(VT_UI4); \
178     BADVAR(VT_INT); BADVAR(VT_UINT); \
179   } \
180   TYPETEST(VT_UI1, V_UI1(&vDst), fs); \
181   TYPETEST(VT_I2, V_I2(&vDst), fs); \
182   TYPETEST(VT_I4, V_I4(&vDst), fs); \
183   TYPETEST(VT_R4, V_R4(&vDst), fs); \
184   TYPETEST(VT_R8, V_R8(&vDst), fs); \
185   TYPETEST(VT_DATE, V_DATE(&vDst), fs); \
186   if (HAVE_OLEAUT32_I8) \
187   { \
188     TYPETEST(VT_I8, V_I8(&vDst), fs); \
189     TYPETEST(VT_UI8, V_UI8(&vDst), fs); \
190   }
191 #define NEGATIVE_TYPETEST(vt, val, fs, vtneg, valneg) \
192   in = -in; \
193   VariantInit(&vSrc); \
194   VariantInit(&vDst); \
195   V_VT(&vSrc) = vt; \
196   (val(&vSrc)) = in; \
197   if (!IS_ANCIENT) { \
198     TYPETEST(vtneg, valneg(&vDst), fs); \
199   }
200
201 #define INITIAL_TYPETESTI8(vt, val) \
202   VariantInit(&vSrc); \
203   VariantInit(&vDst); \
204   V_VT(&vSrc) = vt; \
205   (val(&vSrc)) = in; \
206   TYPETESTI8(VT_I1, V_I1(&vDst)); \
207   TYPETESTI8(VT_UI1, V_UI1(&vDst)); \
208   TYPETESTI8(VT_I2, V_I2(&vDst)); \
209   TYPETESTI8(VT_UI2, V_UI2(&vDst)); \
210   TYPETESTI8(VT_I4, V_I4(&vDst)); \
211   TYPETESTI8(VT_UI4, V_UI4(&vDst)); \
212   TYPETESTI8(VT_INT, V_INT(&vDst)); \
213   TYPETESTI8(VT_UINT, V_UINT(&vDst)); \
214   TYPETESTI8(VT_R4, V_R4(&vDst)); \
215   TYPETESTI8(VT_R8, V_R8(&vDst)); \
216   TYPETESTI8(VT_DATE, V_DATE(&vDst)); \
217   TYPETESTI8(VT_I8, V_I8(&vDst)); \
218   TYPETESTI8(VT_UI8, V_UI8(&vDst))
219
220 #define COMMON_TYPETEST \
221   hres = VariantChangeTypeEx(&vDst, &vSrc, 0, 0, VT_BOOL); \
222   ok(hres == S_OK && V_VT(&vDst) == VT_BOOL && \
223      (V_BOOL(&vDst) == VARIANT_TRUE || (V_VT(&vSrc) == VT_BOOL && V_BOOL(&vDst) == 1)), \
224      "->VT_BOOL hres=0x%lX, type=%d (should be VT_BOOL), value %d (should be VARIANT_TRUE)\n", \
225      hres, V_VT(&vDst), V_BOOL(&vDst)); \
226   if (HAVE_OLEAUT32_CY) \
227   { \
228     hres = VariantChangeTypeEx(&vDst, &vSrc, 0, 0, VT_CY); \
229     ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == CY_MULTIPLIER, \
230        "->VT_CY hres=0x%lX, type=%d (should be VT_CY), value (%08lx,%08lx) (should be CY_MULTIPLIER)\n", \
231        hres, V_VT(&vDst), S(V_CY(&vDst)).Hi, S(V_CY(&vDst)).Lo); \
232   } \
233   if (V_VT(&vSrc) != VT_DATE) \
234   { \
235     hres = VariantChangeTypeEx(&vDst, &vSrc, 0, 0, VT_BSTR); \
236     ok(hres == S_OK && V_VT(&vDst) == VT_BSTR && \
237        V_BSTR(&vDst) && V_BSTR(&vDst)[0] == '1' && V_BSTR(&vDst)[1] == '\0', \
238        "->VT_BSTR hres=0x%lX, type=%d (should be VT_BSTR), *bstr='%c'\n", \
239        hres, V_VT(&vDst), V_BSTR(&vDst) ? *V_BSTR(&vDst) : '?'); \
240   } \
241   if (HAVE_OLEAUT32_DECIMAL) \
242   { \
243     hres = VariantChangeTypeEx(&vDst, &vSrc, 0, 0, VT_DECIMAL); \
244     ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL && \
245        S(U(V_DECIMAL(&vDst))).sign == 0 && S(U(V_DECIMAL(&vDst))).scale == 0 && \
246        V_DECIMAL(&vDst).Hi32 == 0 && U1(V_DECIMAL(&vDst)).Lo64 == (ULONGLONG)in, \
247        "->VT_DECIMAL hres=0x%lX, type=%d (should be VT_DECIMAL), sign=%d, scale=%d, hi=%lu, lo=(%8lx %8lx),\n", \
248        hres, V_VT(&vDst), S(U(V_DECIMAL(&vDst))).sign, S(U(V_DECIMAL(&vDst))).scale, \
249        V_DECIMAL(&vDst).Hi32, S1(U1(V_DECIMAL(&vDst))).Mid32, S1(U1(V_DECIMAL(&vDst))).Lo32); \
250   } \
251   hres = VariantChangeTypeEx(&vDst, &vSrc, 0, 0, VT_EMPTY); \
252   ok(hres == S_OK && V_VT(&vDst) == VT_EMPTY, "->VT_EMPTY hres=0x%lX, type=%d (should be VT_EMPTY)\n", hres, V_VT(&vDst)); \
253   hres = VariantChangeTypeEx(&vDst, &vSrc, 0, 0, VT_NULL); \
254   ok(hres == S_OK && V_VT(&vDst) == VT_NULL, "->VT_NULL hres=0x%lX, type=%d (should be VT_NULL)\n", hres, V_VT(&vDst)); \
255   MISMATCH(VT_DISPATCH); \
256   MISMATCH(VT_ERROR); \
257   MISMATCH(VT_UNKNOWN); \
258   if (!IS_ANCIENT) { MISMATCH(VT_VARIANT); } else { BADVAR(VT_VARIANT); } \
259   if (HAVE_OLEAUT32_RECORD) \
260   { \
261     MISMATCH(VT_RECORD); \
262   } \
263   BADVAR(VT_VOID); \
264   BADVAR(VT_HRESULT); \
265   BADVAR(VT_SAFEARRAY); \
266   BADVAR(VT_CARRAY); \
267   BADVAR(VT_USERDEFINED); \
268   BADVAR(VT_LPSTR); \
269   BADVAR(VT_LPWSTR); \
270   BADVAR(VT_PTR); \
271   BADVAR(VT_INT_PTR); \
272   BADVAR(VT_UINT_PTR); \
273   BADVAR(VT_FILETIME); \
274   BADVAR(VT_BLOB); \
275   BADVAR(VT_STREAM); \
276   BADVAR(VT_STORAGE); \
277   BADVAR(VT_STREAMED_OBJECT); \
278   BADVAR(VT_STORED_OBJECT); \
279   BADVAR(VT_BLOB_OBJECT); \
280   BADVAR(VT_CF); \
281   BADVAR(VT_CLSID); \
282   BADVAR(VT_BSTR_BLOB)
283
284 /* Early versions of oleaut32 are missing many functions */
285 static HRESULT (WINAPI *pVarI1FromUI1)(BYTE,signed char*);
286 static HRESULT (WINAPI *pVarI1FromI2)(SHORT,signed char*);
287 static HRESULT (WINAPI *pVarI1FromI4)(LONG,signed char*);
288 static HRESULT (WINAPI *pVarI1FromR4)(FLOAT,signed char*);
289 static HRESULT (WINAPI *pVarI1FromR8)(double,signed char*);
290 static HRESULT (WINAPI *pVarI1FromDate)(DATE,signed char*);
291 static HRESULT (WINAPI *pVarI1FromCy)(CY,signed char*);
292 static HRESULT (WINAPI *pVarI1FromStr)(OLECHAR*,LCID,ULONG,signed char*);
293 static HRESULT (WINAPI *pVarI1FromBool)(VARIANT_BOOL,signed char*);
294 static HRESULT (WINAPI *pVarI1FromUI2)(USHORT,signed char*);
295 static HRESULT (WINAPI *pVarI1FromUI4)(ULONG,signed char*);
296 static HRESULT (WINAPI *pVarI1FromDec)(DECIMAL*,signed char*);
297 static HRESULT (WINAPI *pVarI1FromI8)(LONG64,signed char*);
298 static HRESULT (WINAPI *pVarI1FromUI8)(ULONG64,signed char*);
299 static HRESULT (WINAPI *pVarUI1FromI2)(SHORT,BYTE*);
300 static HRESULT (WINAPI *pVarUI1FromI4)(LONG,BYTE*);
301 static HRESULT (WINAPI *pVarUI1FromR4)(FLOAT,BYTE*);
302 static HRESULT (WINAPI *pVarUI1FromR8)(double,BYTE*);
303 static HRESULT (WINAPI *pVarUI1FromCy)(CY,BYTE*);
304 static HRESULT (WINAPI *pVarUI1FromDate)(DATE,BYTE*);
305 static HRESULT (WINAPI *pVarUI1FromStr)(OLECHAR*,LCID,ULONG,BYTE*);
306 static HRESULT (WINAPI *pVarUI1FromBool)(VARIANT_BOOL,BYTE*);
307 static HRESULT (WINAPI *pVarUI1FromI1)(signed char,BYTE*);
308 static HRESULT (WINAPI *pVarUI1FromUI2)(USHORT,BYTE*);
309 static HRESULT (WINAPI *pVarUI1FromUI4)(ULONG,BYTE*);
310 static HRESULT (WINAPI *pVarUI1FromDec)(DECIMAL*,BYTE*);
311 static HRESULT (WINAPI *pVarUI1FromI8)(LONG64,BYTE*);
312 static HRESULT (WINAPI *pVarUI1FromUI8)(ULONG64,BYTE*);
313 static HRESULT (WINAPI *pVarUI1FromDisp)(IDispatch*,LCID,BYTE*);
314
315 static HRESULT (WINAPI *pVarI2FromUI1)(BYTE,SHORT*);
316 static HRESULT (WINAPI *pVarI2FromI4)(LONG,SHORT*);
317 static HRESULT (WINAPI *pVarI2FromR4)(FLOAT,SHORT*);
318 static HRESULT (WINAPI *pVarI2FromR8)(double,SHORT*);
319 static HRESULT (WINAPI *pVarI2FromCy)(CY,SHORT*);
320 static HRESULT (WINAPI *pVarI2FromDate)(DATE,SHORT*);
321 static HRESULT (WINAPI *pVarI2FromStr)(OLECHAR*,LCID,ULONG,SHORT*);
322 static HRESULT (WINAPI *pVarI2FromBool)(VARIANT_BOOL,SHORT*);
323 static HRESULT (WINAPI *pVarI2FromI1)(signed char,SHORT*);
324 static HRESULT (WINAPI *pVarI2FromUI2)(USHORT,SHORT*);
325 static HRESULT (WINAPI *pVarI2FromUI4)(ULONG,SHORT*);
326 static HRESULT (WINAPI *pVarI2FromDec)(DECIMAL*,SHORT*);
327 static HRESULT (WINAPI *pVarI2FromI8)(LONG64,SHORT*);
328 static HRESULT (WINAPI *pVarI2FromUI8)(ULONG64,SHORT*);
329 static HRESULT (WINAPI *pVarUI2FromUI1)(BYTE,USHORT*);
330 static HRESULT (WINAPI *pVarUI2FromI2)(SHORT,USHORT*);
331 static HRESULT (WINAPI *pVarUI2FromI4)(LONG,USHORT*);
332 static HRESULT (WINAPI *pVarUI2FromR4)(FLOAT,USHORT*);
333 static HRESULT (WINAPI *pVarUI2FromR8)(double,USHORT*);
334 static HRESULT (WINAPI *pVarUI2FromDate)(DATE,USHORT*);
335 static HRESULT (WINAPI *pVarUI2FromCy)(CY,USHORT*);
336 static HRESULT (WINAPI *pVarUI2FromStr)(OLECHAR*,LCID,ULONG,USHORT*);
337 static HRESULT (WINAPI *pVarUI2FromBool)(VARIANT_BOOL,USHORT*);
338 static HRESULT (WINAPI *pVarUI2FromI1)(signed char,USHORT*);
339 static HRESULT (WINAPI *pVarUI2FromUI4)(ULONG,USHORT*);
340 static HRESULT (WINAPI *pVarUI2FromDec)(DECIMAL*,USHORT*);
341 static HRESULT (WINAPI *pVarUI2FromI8)(LONG64,USHORT*);
342 static HRESULT (WINAPI *pVarUI2FromUI8)(ULONG64,USHORT*);
343
344 static HRESULT (WINAPI *pVarI4FromUI1)(BYTE,LONG*);
345 static HRESULT (WINAPI *pVarI4FromI2)(SHORT,LONG*);
346 static HRESULT (WINAPI *pVarI4FromR4)(FLOAT,LONG*);
347 static HRESULT (WINAPI *pVarI4FromR8)(DOUBLE,LONG*);
348 static HRESULT (WINAPI *pVarI4FromCy)(CY,LONG*);
349 static HRESULT (WINAPI *pVarI4FromDate)(DATE,LONG*);
350 static HRESULT (WINAPI *pVarI4FromStr)(OLECHAR*,LCID,ULONG,LONG*);
351 static HRESULT (WINAPI *pVarI4FromBool)(VARIANT_BOOL,LONG*);
352 static HRESULT (WINAPI *pVarI4FromI1)(signed char,LONG*);
353 static HRESULT (WINAPI *pVarI4FromUI2)(USHORT,LONG*);
354 static HRESULT (WINAPI *pVarI4FromUI4)(ULONG,LONG*);
355 static HRESULT (WINAPI *pVarI4FromDec)(DECIMAL*,LONG*);
356 static HRESULT (WINAPI *pVarI4FromI8)(LONG64,LONG*);
357 static HRESULT (WINAPI *pVarI4FromUI8)(ULONG64,LONG*);
358 static HRESULT (WINAPI *pVarUI4FromUI1)(BYTE,ULONG*);
359 static HRESULT (WINAPI *pVarUI4FromI2)(SHORT,ULONG*);
360 static HRESULT (WINAPI *pVarUI4FromI4)(LONG,ULONG*);
361 static HRESULT (WINAPI *pVarUI4FromR4)(FLOAT,ULONG*);
362 static HRESULT (WINAPI *pVarUI4FromR8)(DOUBLE,ULONG*);
363 static HRESULT (WINAPI *pVarUI4FromDate)(DATE,ULONG*);
364 static HRESULT (WINAPI *pVarUI4FromCy)(CY,ULONG*);
365 static HRESULT (WINAPI *pVarUI4FromStr)(OLECHAR*,LCID,ULONG,ULONG*);
366 static HRESULT (WINAPI *pVarUI4FromBool)(VARIANT_BOOL,ULONG*);
367 static HRESULT (WINAPI *pVarUI4FromI1)(signed char,ULONG*);
368 static HRESULT (WINAPI *pVarUI4FromUI2)(USHORT,ULONG*);
369 static HRESULT (WINAPI *pVarUI4FromDec)(DECIMAL*,ULONG*);
370 static HRESULT (WINAPI *pVarUI4FromI8)(LONG64,ULONG*);
371 static HRESULT (WINAPI *pVarUI4FromUI8)(ULONG64,ULONG*);
372
373 static HRESULT (WINAPI *pVarI8FromUI1)(BYTE,LONG64*);
374 static HRESULT (WINAPI *pVarI8FromI2)(SHORT,LONG64*);
375 static HRESULT (WINAPI *pVarI8FromR4)(FLOAT,LONG64*);
376 static HRESULT (WINAPI *pVarI8FromR8)(double,LONG64*);
377 static HRESULT (WINAPI *pVarI8FromCy)(CY,LONG64*);
378 static HRESULT (WINAPI *pVarI8FromDate)(DATE,LONG64*);
379 static HRESULT (WINAPI *pVarI8FromStr)(OLECHAR*,LCID,ULONG,LONG64*);
380 static HRESULT (WINAPI *pVarI8FromBool)(VARIANT_BOOL,LONG64*);
381 static HRESULT (WINAPI *pVarI8FromI1)(signed char,LONG64*);
382 static HRESULT (WINAPI *pVarI8FromUI2)(USHORT,LONG64*);
383 static HRESULT (WINAPI *pVarI8FromUI4)(ULONG,LONG64*);
384 static HRESULT (WINAPI *pVarI8FromDec)(DECIMAL*,LONG64*);
385 static HRESULT (WINAPI *pVarI8FromUI8)(ULONG64,LONG64*);
386 static HRESULT (WINAPI *pVarUI8FromI8)(LONG64,ULONG64*);
387 static HRESULT (WINAPI *pVarUI8FromUI1)(BYTE,ULONG64*);
388 static HRESULT (WINAPI *pVarUI8FromI2)(SHORT,ULONG64*);
389 static HRESULT (WINAPI *pVarUI8FromR4)(FLOAT,ULONG64*);
390 static HRESULT (WINAPI *pVarUI8FromR8)(double,ULONG64*);
391 static HRESULT (WINAPI *pVarUI8FromCy)(CY,ULONG64*);
392 static HRESULT (WINAPI *pVarUI8FromDate)(DATE,ULONG64*);
393 static HRESULT (WINAPI *pVarUI8FromStr)(OLECHAR*,LCID,ULONG,ULONG64*);
394 static HRESULT (WINAPI *pVarUI8FromBool)(VARIANT_BOOL,ULONG64*);
395 static HRESULT (WINAPI *pVarUI8FromI1)(signed char,ULONG64*);
396 static HRESULT (WINAPI *pVarUI8FromUI2)(USHORT,ULONG64*);
397 static HRESULT (WINAPI *pVarUI8FromUI4)(ULONG,ULONG64*);
398 static HRESULT (WINAPI *pVarUI8FromDec)(DECIMAL*,ULONG64*);
399
400 static HRESULT (WINAPI *pVarR4FromUI1)(BYTE,float*);
401 static HRESULT (WINAPI *pVarR4FromI2)(SHORT,float*);
402 static HRESULT (WINAPI *pVarR4FromI4)(LONG,float*);
403 static HRESULT (WINAPI *pVarR4FromR8)(double,float*);
404 static HRESULT (WINAPI *pVarR4FromCy)(CY,float*);
405 static HRESULT (WINAPI *pVarR4FromDate)(DATE,float*);
406 static HRESULT (WINAPI *pVarR4FromStr)(OLECHAR*,LCID,ULONG,float*);
407 static HRESULT (WINAPI *pVarR4FromBool)(VARIANT_BOOL,float*);
408 static HRESULT (WINAPI *pVarR4FromI1)(signed char,float*);
409 static HRESULT (WINAPI *pVarR4FromUI2)(USHORT,float*);
410 static HRESULT (WINAPI *pVarR4FromUI4)(ULONG,float*);
411 static HRESULT (WINAPI *pVarR4FromDec)(DECIMAL*,float*);
412 static HRESULT (WINAPI *pVarR4FromI8)(LONG64,float*);
413 static HRESULT (WINAPI *pVarR4FromUI8)(ULONG64,float*);
414
415 static HRESULT (WINAPI *pVarR8FromUI1)(BYTE,double*);
416 static HRESULT (WINAPI *pVarR8FromI2)(SHORT,double*);
417 static HRESULT (WINAPI *pVarR8FromI4)(LONG,double*);
418 static HRESULT (WINAPI *pVarR8FromR4)(FLOAT,double*);
419 static HRESULT (WINAPI *pVarR8FromCy)(CY,double*);
420 static HRESULT (WINAPI *pVarR8FromDate)(DATE,double*);
421 static HRESULT (WINAPI *pVarR8FromStr)(OLECHAR*,LCID,ULONG,double*);
422 static HRESULT (WINAPI *pVarR8FromBool)(VARIANT_BOOL,double*);
423 static HRESULT (WINAPI *pVarR8FromI1)(signed char,double*);
424 static HRESULT (WINAPI *pVarR8FromUI2)(USHORT,double*);
425 static HRESULT (WINAPI *pVarR8FromUI4)(ULONG,double*);
426 static HRESULT (WINAPI *pVarR8FromDec)(DECIMAL*,double*);
427 static HRESULT (WINAPI *pVarR8FromI8)(LONG64,double*);
428 static HRESULT (WINAPI *pVarR8FromUI8)(ULONG64,double*);
429 static HRESULT (WINAPI *pVarR8Round)(double,int,double*);
430
431 static HRESULT (WINAPI *pVarDateFromUI1)(BYTE,DATE*);
432 static HRESULT (WINAPI *pVarDateFromI2)(SHORT,DATE*);
433 static HRESULT (WINAPI *pVarDateFromI4)(LONG,DATE*);
434 static HRESULT (WINAPI *pVarDateFromR4)(FLOAT,DATE*);
435 static HRESULT (WINAPI *pVarDateFromCy)(CY,DATE*);
436 static HRESULT (WINAPI *pVarDateFromR8)(double,DATE*);
437 static HRESULT (WINAPI *pVarDateFromStr)(OLECHAR*,LCID,ULONG,DATE*);
438 static HRESULT (WINAPI *pVarDateFromBool)(VARIANT_BOOL,DATE*);
439 static HRESULT (WINAPI *pVarDateFromI1)(signed char,DATE*);
440 static HRESULT (WINAPI *pVarDateFromUI2)(USHORT,DATE*);
441 static HRESULT (WINAPI *pVarDateFromUI4)(ULONG,DATE*);
442 static HRESULT (WINAPI *pVarDateFromDec)(DECIMAL*,DATE*);
443 static HRESULT (WINAPI *pVarDateFromI8)(LONG64,DATE*);
444 static HRESULT (WINAPI *pVarDateFromUI8)(ULONG64,DATE*);
445
446 static HRESULT (WINAPI *pVarCyFromUI1)(BYTE,CY*);
447 static HRESULT (WINAPI *pVarCyFromI2)(SHORT,CY*);
448 static HRESULT (WINAPI *pVarCyFromI4)(LONG,CY*);
449 static HRESULT (WINAPI *pVarCyFromR4)(FLOAT,CY*);
450 static HRESULT (WINAPI *pVarCyFromR8)(double,CY*);
451 static HRESULT (WINAPI *pVarCyFromDate)(DATE,CY*);
452 static HRESULT (WINAPI *pVarCyFromBool)(VARIANT_BOOL,CY*);
453 static HRESULT (WINAPI *pVarCyFromI1)(signed char,CY*);
454 static HRESULT (WINAPI *pVarCyFromUI2)(USHORT,CY*);
455 static HRESULT (WINAPI *pVarCyFromUI4)(ULONG,CY*);
456 static HRESULT (WINAPI *pVarCyFromDec)(DECIMAL*,CY*);
457 static HRESULT (WINAPI *pVarCyFromI8)(LONG64,CY*);
458 static HRESULT (WINAPI *pVarCyFromUI8)(ULONG64,CY*);
459 static HRESULT (WINAPI *pVarCyAdd)(const CY,const CY,CY*);
460 static HRESULT (WINAPI *pVarCyMul)(const CY,const CY,CY*);
461 static HRESULT (WINAPI *pVarCyMulI4)(const CY,LONG,CY*);
462 static HRESULT (WINAPI *pVarCySub)(const CY,const CY,CY*);
463 static HRESULT (WINAPI *pVarCyAbs)(const CY,CY*);
464 static HRESULT (WINAPI *pVarCyFix)(const CY,CY*);
465 static HRESULT (WINAPI *pVarCyInt)(const CY,CY*);
466 static HRESULT (WINAPI *pVarCyNeg)(const CY,CY*);
467 static HRESULT (WINAPI *pVarCyRound)(const CY,int,CY*);
468 static HRESULT (WINAPI *pVarCyCmp)(const CY,const CY);
469 static HRESULT (WINAPI *pVarCyCmpR8)(const CY,double);
470 static HRESULT (WINAPI *pVarCyMulI8)(const CY,LONG64,CY*);
471
472 static HRESULT (WINAPI *pVarDecFromUI1)(BYTE,DECIMAL*);
473 static HRESULT (WINAPI *pVarDecFromI2)(SHORT,DECIMAL*);
474 static HRESULT (WINAPI *pVarDecFromI4)(LONG,DECIMAL*);
475 static HRESULT (WINAPI *pVarDecFromI8)(LONG64,DECIMAL*);
476 static HRESULT (WINAPI *pVarDecFromR4)(FLOAT,DECIMAL*);
477 static HRESULT (WINAPI *pVarDecFromR8)(DOUBLE,DECIMAL*);
478 static HRESULT (WINAPI *pVarDecFromDate)(DATE,DECIMAL*);
479 static HRESULT (WINAPI *pVarDecFromStr)(OLECHAR*,LCID,ULONG,DECIMAL*);
480 static HRESULT (WINAPI *pVarDecFromBool)(VARIANT_BOOL,DECIMAL*);
481 static HRESULT (WINAPI *pVarDecFromI1)(signed char,DECIMAL*);
482 static HRESULT (WINAPI *pVarDecFromUI2)(USHORT,DECIMAL*);
483 static HRESULT (WINAPI *pVarDecFromUI4)(ULONG,DECIMAL*);
484 static HRESULT (WINAPI *pVarDecFromUI8)(ULONG64,DECIMAL*);
485 static HRESULT (WINAPI *pVarDecFromCy)(CY,DECIMAL*);
486 static HRESULT (WINAPI *pVarDecAbs)(const DECIMAL*,DECIMAL*);
487 static HRESULT (WINAPI *pVarDecAdd)(const DECIMAL*,const DECIMAL*,DECIMAL*);
488 static HRESULT (WINAPI *pVarDecSub)(const DECIMAL*,const DECIMAL*,DECIMAL*);
489 static HRESULT (WINAPI *pVarDecMul)(const DECIMAL*,const DECIMAL*,DECIMAL*);
490 static HRESULT (WINAPI *pVarDecDiv)(const DECIMAL*,const DECIMAL*,DECIMAL*);
491 static HRESULT (WINAPI *pVarDecCmp)(const DECIMAL*,const DECIMAL*);
492 static HRESULT (WINAPI *pVarDecNeg)(const DECIMAL*,DECIMAL*);
493
494 static HRESULT (WINAPI *pVarBoolFromUI1)(BYTE,VARIANT_BOOL*);
495 static HRESULT (WINAPI *pVarBoolFromI2)(SHORT,VARIANT_BOOL*);
496 static HRESULT (WINAPI *pVarBoolFromI4)(LONG,VARIANT_BOOL*);
497 static HRESULT (WINAPI *pVarBoolFromR4)(FLOAT,VARIANT_BOOL*);
498 static HRESULT (WINAPI *pVarBoolFromR8)(DOUBLE,VARIANT_BOOL*);
499 static HRESULT (WINAPI *pVarBoolFromDate)(DATE,VARIANT_BOOL*);
500 static HRESULT (WINAPI *pVarBoolFromCy)(CY,VARIANT_BOOL*);
501 static HRESULT (WINAPI *pVarBoolFromStr)(OLECHAR*,LCID,ULONG,VARIANT_BOOL*);
502 static HRESULT (WINAPI *pVarBoolFromI1)(signed char,VARIANT_BOOL*);
503 static HRESULT (WINAPI *pVarBoolFromUI2)(USHORT,VARIANT_BOOL*);
504 static HRESULT (WINAPI *pVarBoolFromUI4)(ULONG,VARIANT_BOOL*);
505 static HRESULT (WINAPI *pVarBoolFromDec)(DECIMAL*,VARIANT_BOOL*);
506 static HRESULT (WINAPI *pVarBoolFromI8)(LONG64,VARIANT_BOOL*);
507 static HRESULT (WINAPI *pVarBoolFromUI8)(ULONG64,VARIANT_BOOL*);
508
509 static HRESULT (WINAPI *pVarBstrFromR4)(FLOAT,LCID,ULONG,BSTR*);
510 static HRESULT (WINAPI *pVarBstrFromDate)(DATE,LCID,ULONG,BSTR*);
511 static HRESULT (WINAPI *pVarBstrFromDec)(DECIMAL*,LCID,ULONG,BSTR*);
512 static HRESULT (WINAPI *pVarBstrCmp)(BSTR,BSTR,LCID,ULONG);
513
514 static INT (WINAPI *pSystemTimeToVariantTime)(LPSYSTEMTIME,double*);
515 static void (WINAPI *pClearCustData)(LPCUSTDATA);
516
517 /* Internal representation of a BSTR */
518 typedef struct tagINTERNAL_BSTR
519 {
520   DWORD   dwLen;
521   OLECHAR szString[1];
522 } INTERNAL_BSTR, *LPINTERNAL_BSTR;
523
524 typedef struct
525 {
526   const IDispatchVtbl *lpVtbl;
527   LONG ref;
528   VARTYPE vt;
529   BOOL bFailInvoke;
530 } DummyDispatch;
531
532 static DummyDispatch dispatch;
533
534 static ULONG WINAPI DummyDispatch_AddRef(LPDISPATCH iface)
535 {
536   trace("AddRef(%p)\n", iface);
537   return InterlockedIncrement(&((DummyDispatch*)iface)->ref);
538 }
539
540 static ULONG WINAPI DummyDispatch_Release(LPDISPATCH iface)
541 {
542   trace("Release(%p)\n", iface);
543   return InterlockedDecrement(&((DummyDispatch*)iface)->ref);
544 }
545
546 static HRESULT WINAPI DummyDispatch_QueryInterface(LPDISPATCH iface,
547                                                    REFIID riid,
548                                                    void** ppvObject)
549 {
550   trace("QueryInterface(%p)\n", iface);
551   if (ppvObject)
552   {
553     *ppvObject = NULL;
554     if (IsEqualIID(riid, &IID_IDispatch))
555     {
556       trace("Asked for IID_IDispatch\n");
557       *ppvObject = iface;
558     }
559     else if (IsEqualIID(riid, &IID_IUnknown))
560     {
561       trace("Asked for IID_IUnknown\n");
562       *ppvObject = iface;
563     }
564     if (*ppvObject)
565     {
566       DummyDispatch_AddRef((IDispatch*)*ppvObject);
567       return S_OK;
568     }
569   }
570   return E_NOINTERFACE;
571 }
572
573 static HRESULT WINAPI DummyDispatch_Invoke(LPDISPATCH iface,
574                                            DISPID dispIdMember, REFIID riid,
575                                            LCID lcid, WORD wFlags,
576                                            DISPPARAMS *pDispParams,
577                                            VARIANT *pVarResult,
578                                            EXCEPINFO *pExcepInfo,
579                                            UINT *puArgErr)
580 {
581   trace("Invoke(%p)\n", iface);
582   ok(wFlags == DISPATCH_PROPERTYGET, "Flags wrong\n");
583   ok(pDispParams->cArgs == 0, "Property get has args\n");
584
585   if (dispatch.bFailInvoke)
586     return E_OUTOFMEMORY;
587
588   memset(pVarResult, 0, sizeof(*pVarResult));
589   V_VT(pVarResult) = dispatch.vt;
590   return S_OK;
591 }
592
593 static const IDispatchVtbl DummyDispatch_VTable =
594 {
595   DummyDispatch_QueryInterface,
596   DummyDispatch_AddRef,
597   DummyDispatch_Release,
598   NULL,
599   NULL,
600   NULL,
601   DummyDispatch_Invoke
602 };
603
604 static DummyDispatch dispatch = { &DummyDispatch_VTable, 1, 0, 0 };
605
606 /*
607  * VT_I1/VT_UI1
608  */
609
610 #undef CONV_TYPE
611 #define CONV_TYPE signed char
612 #undef EXPECTRES
613 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%d")
614
615 static void test_VarI1FromI2(void)
616 {
617   CONVVARS(SHORT);
618   int i;
619
620   CHECKPTR(VarI1FromI2);
621   OVERFLOWRANGE(VarI1FromI2, -32768, -128);
622   CONVERTRANGE(VarI1FromI2, -128, 128);
623   OVERFLOWRANGE(VarI1FromI2, 129, 32768);
624 }
625
626 static void test_VarI1FromI4(void)
627 {
628   CONVVARS(LONG);
629   int i;
630
631   CHECKPTR(VarI1FromI4);
632   CONVERT(VarI1FromI4, -129); EXPECT_OVERFLOW;
633   CONVERTRANGE(VarI1FromI4, -128, 128);
634   CONVERT(VarI1FromI4, 128);  EXPECT_OVERFLOW;
635 }
636
637 static void test_VarI1FromI8(void)
638 {
639   CONVVARS(LONG64);
640   int i;
641
642   CHECKPTR(VarI1FromI8);
643   CONVERT(VarI1FromI8, -129);   EXPECT_OVERFLOW;
644   CONVERTRANGE(VarI1FromI8, -127, 128);
645   CONVERT(VarI1FromI8, 128);    EXPECT_OVERFLOW;
646 }
647
648 static void test_VarI1FromUI1(void)
649 {
650   CONVVARS(BYTE);
651   int i;
652
653   CHECKPTR(VarI1FromUI1);
654   CONVERTRANGE(VarI1FromUI1, 0, 127);
655   OVERFLOWRANGE(VarI1FromUI1, 128, 255);
656 }
657
658 static void test_VarI1FromUI2(void)
659 {
660   CONVVARS(USHORT);
661   int i;
662
663   CHECKPTR(VarI1FromUI2);
664   CONVERTRANGE(VarI1FromUI2, 0, 127);
665   OVERFLOWRANGE(VarI1FromUI2, 128, 32768);
666 }
667
668 static void test_VarI1FromUI4(void)
669 {
670   CONVVARS(ULONG);
671   int i;
672
673   CHECKPTR(VarI1FromUI4);
674   CONVERTRANGE(VarI1FromUI4, 0, 127);
675   CONVERT(VarI1FromUI4, 128); EXPECT_OVERFLOW;
676 }
677
678 static void test_VarI1FromUI8(void)
679 {
680   CONVVARS(ULONG64);
681   int i;
682
683   CHECKPTR(VarI1FromUI8);
684   CONVERTRANGE(VarI1FromUI8, 0, 127);
685   CONVERT(VarI1FromUI8, 128); EXPECT_OVERFLOW;
686 }
687
688 static void test_VarI1FromBool(void)
689 {
690   CONVVARS(VARIANT_BOOL);
691   int i;
692
693   CHECKPTR(VarI1FromBool);
694   /* Note that conversions from bool wrap around! */
695   CONVERT(VarI1FromBool, -129);  EXPECT(127);
696   CONVERTRANGE(VarI1FromBool, -128, 128);
697   CONVERT(VarI1FromBool, 128); EXPECT(-128);
698 }
699
700 static void test_VarI1FromR4(void)
701 {
702   CONVVARS(FLOAT);
703
704   CHECKPTR(VarI1FromR4);
705   CONVERT(VarI1FromR4, -129.0f); EXPECT_OVERFLOW;
706   CONVERT(VarI1FromR4, -128.0f); EXPECT(-128);
707   CONVERT(VarI1FromR4, -1.0f);   EXPECT(-1);
708   CONVERT(VarI1FromR4, 0.0f);    EXPECT(0);
709   CONVERT(VarI1FromR4, 1.0f);    EXPECT(1);
710   CONVERT(VarI1FromR4, 127.0f);  EXPECT(127);
711   CONVERT(VarI1FromR4, 128.0f);  EXPECT_OVERFLOW;
712
713   CONVERT(VarI1FromR4, -1.5f); EXPECT(-2);
714   CONVERT(VarI1FromR4, -0.6f); EXPECT(-1);
715   CONVERT(VarI1FromR4, -0.5f); EXPECT(0);
716   CONVERT(VarI1FromR4, -0.4f); EXPECT(0);
717   CONVERT(VarI1FromR4, 0.4f);  EXPECT(0);
718   CONVERT(VarI1FromR4, 0.5f);  EXPECT(0);
719   CONVERT(VarI1FromR4, 0.6f);  EXPECT(1);
720   CONVERT(VarI1FromR4, 1.5f);  EXPECT(2);
721 }
722
723 static void test_VarI1FromR8(void)
724 {
725   CONVVARS(DOUBLE);
726
727   CHECKPTR(VarI1FromR8);
728   CONVERT(VarI1FromR8, -129.0); EXPECT_OVERFLOW;
729   CONVERT(VarI1FromR8, -128.0); EXPECT(-128);
730   CONVERT(VarI1FromR8, -1.0);   EXPECT(-1);
731   CONVERT(VarI1FromR8, 0.0);    EXPECT(0);
732   CONVERT(VarI1FromR8, 1.0);    EXPECT(1);
733   CONVERT(VarI1FromR8, 127.0);  EXPECT(127);
734   CONVERT(VarI1FromR8, 128.0);  EXPECT_OVERFLOW;
735
736   CONVERT(VarI1FromR8, -1.5); EXPECT(-2);
737   CONVERT(VarI1FromR8, -0.6); EXPECT(-1);
738   CONVERT(VarI1FromR8, -0.5); EXPECT(0);
739   CONVERT(VarI1FromR8, -0.4); EXPECT(0);
740   CONVERT(VarI1FromR8, 0.4);  EXPECT(0);
741   CONVERT(VarI1FromR8, 0.5);  EXPECT(0);
742   CONVERT(VarI1FromR8, 0.6);  EXPECT(1);
743   CONVERT(VarI1FromR8, 1.5);  EXPECT(2);
744 }
745
746 static void test_VarI1FromDate(void)
747 {
748   CONVVARS(DATE);
749
750   CHECKPTR(VarI1FromDate);
751   CONVERT(VarI1FromDate, -129.0); EXPECT_OVERFLOW;
752   CONVERT(VarI1FromDate, -128.0); EXPECT(-128);
753   CONVERT(VarI1FromDate, -1.0);   EXPECT(-1);
754   CONVERT(VarI1FromDate, 0.0);    EXPECT(0);
755   CONVERT(VarI1FromDate, 1.0);    EXPECT(1);
756   CONVERT(VarI1FromDate, 127.0);  EXPECT(127);
757   CONVERT(VarI1FromDate, 128.0);  EXPECT_OVERFLOW;
758
759   CONVERT(VarI1FromDate, -1.5); EXPECT(-2);
760   CONVERT(VarI1FromDate, -0.6); EXPECT(-1);
761   CONVERT(VarI1FromDate, -0.5); EXPECT(0);
762   CONVERT(VarI1FromDate, -0.4); EXPECT(0);
763   CONVERT(VarI1FromDate, 0.4);  EXPECT(0);
764   CONVERT(VarI1FromDate, 0.5);  EXPECT(0);
765   CONVERT(VarI1FromDate, 0.6);  EXPECT(1);
766   CONVERT(VarI1FromDate, 1.5);  EXPECT(2);
767 }
768
769 static void test_VarI1FromCy(void)
770 {
771   CONVVARS(CY);
772
773   CHECKPTR(VarI1FromCy);
774   CONVERT_CY(VarI1FromCy,-129); EXPECT_OVERFLOW;
775   CONVERT_CY(VarI1FromCy,-128); EXPECT(128);
776   CONVERT_CY(VarI1FromCy,-1);   EXPECT(-1);
777   CONVERT_CY(VarI1FromCy,0);    EXPECT(0);
778   CONVERT_CY(VarI1FromCy,1);    EXPECT(1);
779   CONVERT_CY(VarI1FromCy,127);  EXPECT(127);
780   CONVERT_CY(VarI1FromCy,128);  EXPECT_OVERFLOW;
781
782   CONVERT_CY(VarI1FromCy,-1.5); EXPECT(-2);
783   CONVERT_CY(VarI1FromCy,-0.6); EXPECT(-1);
784   CONVERT_CY(VarI1FromCy,-0.5); EXPECT(0);
785   CONVERT_CY(VarI1FromCy,-0.4); EXPECT(0);
786   CONVERT_CY(VarI1FromCy,0.4);  EXPECT(0);
787   CONVERT_CY(VarI1FromCy,0.5);  EXPECT(0);
788   CONVERT_CY(VarI1FromCy,0.6);  EXPECT(1);
789   CONVERT_CY(VarI1FromCy,1.5);  EXPECT(2);
790 }
791
792 static void test_VarI1FromDec(void)
793 {
794   CONVVARS(DECIMAL);
795
796   CHECKPTR(VarI1FromDec);
797
798   CONVERT_BADDEC(VarI1FromDec);
799
800   CONVERT_DEC(VarI1FromDec,0,0x80,0,129); EXPECT_OVERFLOW;
801   CONVERT_DEC(VarI1FromDec,0,0x80,0,128); EXPECT(-128);
802   CONVERT_DEC(VarI1FromDec,0,0x80,0,1);   EXPECT(-1);
803   CONVERT_DEC(VarI1FromDec,0,0,0,0);      EXPECT(0);
804   CONVERT_DEC(VarI1FromDec,0,0,0,1);      EXPECT(1);
805   CONVERT_DEC(VarI1FromDec,0,0,0,127);    EXPECT(127);
806   CONVERT_DEC(VarI1FromDec,0,0,0,128);    EXPECT_OVERFLOW;
807
808   CONVERT_DEC(VarI1FromDec,2,0x80,0,12800); EXPECT(-128);
809   CONVERT_DEC(VarI1FromDec,2,0,0,12700);    EXPECT(127);
810 }
811
812 static void test_VarI1FromStr(void)
813 {
814   CONVVARS(LCID);
815   OLECHAR buff[128];
816
817   in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
818
819   CHECKPTR(VarI1FromStr);
820
821   CONVERT_STR(VarI1FromStr,NULL, 0);   EXPECT_MISMATCH;
822   CONVERT_STR(VarI1FromStr,"0", 0);    EXPECT(0);
823   CONVERT_STR(VarI1FromStr,"-129", 0); EXPECT_OVERFLOW;
824   CONVERT_STR(VarI1FromStr,"-128", 0); EXPECT(-128);
825   CONVERT_STR(VarI1FromStr,"127", 0);  EXPECT(127);
826   CONVERT_STR(VarI1FromStr,"128", 0);  EXPECT_OVERFLOW;
827
828   CONVERT_STR(VarI1FromStr,"-1.5", 0); EXPECT(-2);
829   CONVERT_STR(VarI1FromStr,"-0.6", 0); EXPECT(-1);
830   CONVERT_STR(VarI1FromStr,"-0.5", 0); EXPECT(0);
831   CONVERT_STR(VarI1FromStr,"-0.4", 0); EXPECT(0);
832   CONVERT_STR(VarI1FromStr,"0.4", 0);  EXPECT(0);
833   CONVERT_STR(VarI1FromStr,"0.5", 0);  EXPECT(0);
834   CONVERT_STR(VarI1FromStr,"0.6", 0);  EXPECT(1);
835   CONVERT_STR(VarI1FromStr,"1.5", 0);  EXPECT(2);
836 }
837
838 static void test_VarI1Copy(void)
839 {
840   if (!IS_ANCIENT)
841   {
842       COPYTEST(1, VT_I1, V_I1(&vSrc), V_I1(&vDst), V_I1REF(&vSrc), V_I1REF(&vDst), "%d");
843   }
844 }
845
846 static void test_VarI1ChangeTypeEx(void)
847 {
848   CONVVARS(CONV_TYPE);
849   VARIANTARG vSrc, vDst;
850
851   in = 1;
852
853   if (!IS_ANCIENT)
854   {
855       INITIAL_TYPETEST(VT_I1, V_I1, "%d");
856       COMMON_TYPETEST;
857       NEGATIVE_TYPETEST(VT_I1, V_I1, "%d", VT_UI1, V_UI1);
858   }
859 }
860
861 #undef CONV_TYPE
862 #define CONV_TYPE BYTE
863
864 static void test_VarUI1FromI1(void)
865 {
866   CONVVARS(signed char);
867   int i;
868
869   CHECKPTR(VarUI1FromI1);
870   OVERFLOWRANGE(VarUI1FromI1, -128, 0);
871   CONVERTRANGE(VarUI1FromI1, 0, 128);
872 }
873
874 static void test_VarUI1FromI2(void)
875 {
876   CONVVARS(SHORT);
877   int i;
878
879   CHECKPTR(VarUI1FromI2);
880   OVERFLOWRANGE(VarUI1FromI2, -32768, 0);
881   CONVERTRANGE(VarUI1FromI2, 0, 256);
882   OVERFLOWRANGE(VarUI1FromI2, 256, 32768);
883 }
884
885 static void test_VarUI1FromI4(void)
886 {
887   CONVVARS(LONG);
888   int i;
889
890   CHECKPTR(VarUI1FromI4);
891   CONVERT(VarUI1FromI4, -1);  EXPECT_OVERFLOW;
892   CONVERTRANGE(VarUI1FromI4, 0, 256);
893   CONVERT(VarUI1FromI4, 256); EXPECT_OVERFLOW;
894 }
895
896 static void test_VarUI1FromI8(void)
897 {
898   CONVVARS(LONG64);
899   int i;
900
901   CHECKPTR(VarUI1FromI8);
902   CONVERT(VarUI1FromI8, -1);  EXPECT_OVERFLOW;
903   CONVERTRANGE(VarUI1FromI8, 0, 256);
904   CONVERT(VarUI1FromI8, 256); EXPECT_OVERFLOW;
905 }
906
907 static void test_VarUI1FromUI2(void)
908 {
909   CONVVARS(USHORT);
910   int i;
911
912   CHECKPTR(VarUI1FromUI2);
913   CONVERTRANGE(VarUI1FromUI2, 0, 256);
914   OVERFLOWRANGE(VarUI1FromUI2, 256, 65536);
915 }
916
917 static void test_VarUI1FromUI4(void)
918 {
919   CONVVARS(ULONG);
920   int i;
921
922   CHECKPTR(VarUI1FromUI4);
923   CONVERTRANGE(VarUI1FromUI4, 0, 256);
924   CONVERT(VarUI1FromUI4, 256); EXPECT_OVERFLOW;
925 }
926
927 static void test_VarUI1FromUI8(void)
928 {
929   CONVVARS(ULONG64);
930   int i;
931
932   CHECKPTR(VarUI1FromUI8);
933   CONVERTRANGE(VarUI1FromUI8, 0, 256);
934   CONVERT(VarUI1FromUI8, 256); EXPECT_OVERFLOW;
935 }
936
937 static void test_VarUI1FromBool(void)
938 {
939   CONVVARS(VARIANT_BOOL);
940   int i;
941
942   CHECKPTR(VarUI1FromBool);
943   /* Note that conversions from bool overflow! */
944   CONVERT(VarUI1FromBool, -1); EXPECT(255);
945   CONVERTRANGE(VarUI1FromBool, 0, 256);
946   CONVERT(VarUI1FromBool, 256); EXPECT(0);
947 }
948
949 static void test_VarUI1FromR4(void)
950 {
951   CONVVARS(FLOAT);
952
953   CHECKPTR(VarUI1FromR4);
954   CONVERT(VarUI1FromR4, -1.0f);  EXPECT_OVERFLOW;
955   CONVERT(VarUI1FromR4, 0.0f);   EXPECT(0);
956   CONVERT(VarUI1FromR4, 1.0f);   EXPECT(1);
957   CONVERT(VarUI1FromR4, 255.0f); EXPECT(255);
958   CONVERT(VarUI1FromR4, 256.0f); EXPECT_OVERFLOW;
959
960   /* Rounding */
961   CONVERT(VarUI1FromR4, -1.5f); EXPECT_OVERFLOW;
962   CONVERT(VarUI1FromR4, -0.6f); EXPECT_OVERFLOW;
963   CONVERT(VarUI1FromR4, -0.5f); EXPECT(0);
964   CONVERT(VarUI1FromR4, -0.4f); EXPECT(0);
965   CONVERT(VarUI1FromR4, 0.4f);  EXPECT(0);
966   CONVERT(VarUI1FromR4, 0.5f);  EXPECT(0);
967   CONVERT(VarUI1FromR4, 0.6f);  EXPECT(1);
968   CONVERT(VarUI1FromR4, 1.5f);  EXPECT(2);
969 }
970
971 static void test_VarUI1FromR8(void)
972 {
973   CONVVARS(DOUBLE);
974
975   CHECKPTR(VarUI1FromR8);
976   CONVERT(VarUI1FromR8, -1.0);  EXPECT_OVERFLOW;
977   CONVERT(VarUI1FromR8, 0.0);   EXPECT(0);
978   CONVERT(VarUI1FromR8, 1.0);   EXPECT(1);
979   CONVERT(VarUI1FromR8, 255.0); EXPECT(255);
980   CONVERT(VarUI1FromR8, 256.0); EXPECT_OVERFLOW;
981
982   /* Rounding */
983   CONVERT(VarUI1FromR8, -1.5); EXPECT_OVERFLOW;
984   CONVERT(VarUI1FromR8, -0.6); EXPECT_OVERFLOW;
985   CONVERT(VarUI1FromR8, -0.5); EXPECT(0);
986   CONVERT(VarUI1FromR8, -0.4); EXPECT(0);
987   CONVERT(VarUI1FromR8, 0.4);  EXPECT(0);
988   CONVERT(VarUI1FromR8, 0.5);  EXPECT(0);
989   CONVERT(VarUI1FromR8, 0.6);  EXPECT(1);
990   CONVERT(VarUI1FromR8, 1.5);  EXPECT(2);
991 }
992
993 static void test_VarUI1FromDate(void)
994 {
995   CONVVARS(DATE);
996
997   CHECKPTR(VarUI1FromDate);
998   CONVERT(VarUI1FromDate, -1.0);  EXPECT_OVERFLOW;
999   CONVERT(VarUI1FromDate, 0.0);   EXPECT(0);
1000   CONVERT(VarUI1FromDate, 1.0);   EXPECT(1);
1001   CONVERT(VarUI1FromDate, 255.0); EXPECT(255);
1002   CONVERT(VarUI1FromDate, 256.0); EXPECT_OVERFLOW;
1003
1004   /* Rounding */
1005   CONVERT(VarUI1FromDate, -1.5); EXPECT_OVERFLOW;
1006   CONVERT(VarUI1FromDate, -0.6); EXPECT_OVERFLOW;
1007   CONVERT(VarUI1FromDate, -0.5); EXPECT(0);
1008   CONVERT(VarUI1FromDate, -0.4); EXPECT(0);
1009   CONVERT(VarUI1FromDate, 0.4);  EXPECT(0);
1010   CONVERT(VarUI1FromDate, 0.5);  EXPECT(0);
1011   CONVERT(VarUI1FromDate, 0.6);  EXPECT(1);
1012   CONVERT(VarUI1FromDate, 1.5);  EXPECT(2);
1013 }
1014
1015 static void test_VarUI1FromCy(void)
1016 {
1017   CONVVARS(CY);
1018
1019   CHECKPTR(VarUI1FromCy);
1020   CONVERT_CY(VarUI1FromCy,-1);  EXPECT_OVERFLOW;
1021   CONVERT_CY(VarUI1FromCy,0);   EXPECT(0);
1022   CONVERT_CY(VarUI1FromCy,1);   EXPECT(1);
1023   CONVERT_CY(VarUI1FromCy,255); EXPECT(255);
1024   CONVERT_CY(VarUI1FromCy,256); EXPECT_OVERFLOW;
1025
1026   /* Rounding */
1027   CONVERT_CY(VarUI1FromCy,-1.5); EXPECT_OVERFLOW;
1028   CONVERT_CY(VarUI1FromCy,-0.6); EXPECT_OVERFLOW;
1029   CONVERT_CY(VarUI1FromCy,-0.5); EXPECT(0);
1030   CONVERT_CY(VarUI1FromCy,-0.4); EXPECT(0);
1031   CONVERT_CY(VarUI1FromCy,0.4);  EXPECT(0);
1032   CONVERT_CY(VarUI1FromCy,0.5);  EXPECT(0);
1033   CONVERT_CY(VarUI1FromCy,0.6);  EXPECT(1);
1034   CONVERT_CY(VarUI1FromCy,1.5);  EXPECT(2);
1035 }
1036
1037 static void test_VarUI1FromDec(void)
1038 {
1039   CONVVARS(DECIMAL);
1040
1041   CHECKPTR(VarUI1FromDec);
1042
1043   CONVERT_BADDEC(VarUI1FromDec);
1044
1045   CONVERT_DEC(VarUI1FromDec,0,0x80,0,1); EXPECT_OVERFLOW;
1046   CONVERT_DEC(VarUI1FromDec,0,0,0,0);    EXPECT(0);
1047   CONVERT_DEC(VarUI1FromDec,0,0,0,1);    EXPECT(1);
1048   CONVERT_DEC(VarUI1FromDec,0,0,0,255);  EXPECT(255);
1049   CONVERT_DEC(VarUI1FromDec,0,0,0,256);  EXPECT_OVERFLOW;
1050
1051   CONVERT_DEC(VarUI1FromDec,2,0x80,0,100); EXPECT_OVERFLOW;
1052   CONVERT_DEC(VarUI1FromDec,2,0,0,25500);  EXPECT(255);
1053 }
1054
1055 static void test_VarUI1FromStr(void)
1056 {
1057   CONVVARS(LCID);
1058   OLECHAR buff[128];
1059
1060   in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
1061
1062   CHECKPTR(VarUI1FromStr);
1063
1064   CONVERT_STR(VarUI1FromStr,NULL, 0);   EXPECT_MISMATCH;
1065   CONVERT_STR(VarUI1FromStr,"0", 0);    EXPECT(0);
1066   CONVERT_STR(VarUI1FromStr,"-1", 0);   EXPECT_OVERFLOW;
1067   CONVERT_STR(VarUI1FromStr,"255", 0);  EXPECT(255);
1068   CONVERT_STR(VarUI1FromStr,"256", 0);  EXPECT_OVERFLOW;
1069
1070   /* Rounding */
1071   CONVERT_STR(VarUI1FromStr,"-1.5", 0); EXPECT_OVERFLOW;
1072   CONVERT_STR(VarUI1FromStr,"-0.6", 0); EXPECT_OVERFLOW;
1073   CONVERT_STR(VarUI1FromStr,"-0.5", 0); EXPECT(0);
1074   CONVERT_STR(VarUI1FromStr,"-0.4", 0); EXPECT(0);
1075   CONVERT_STR(VarUI1FromStr,"0.4", 0);  EXPECT(0);
1076   CONVERT_STR(VarUI1FromStr,"0.5", 0);  EXPECT(0);
1077   CONVERT_STR(VarUI1FromStr,"0.6", 0);  EXPECT(1);
1078   CONVERT_STR(VarUI1FromStr,"1.5", 0);  EXPECT(2);
1079 }
1080
1081 static void test_VarUI1FromDisp(void)
1082 {
1083   CONVVARS(LCID);
1084   VARIANTARG vSrc, vDst;
1085
1086   CHECKPTR(VarUI1FromDisp);
1087
1088   /* FIXME
1089    * Conversions from IDispatch should get the default 'value' property
1090    * from the IDispatch pointer and return it. The following tests this.
1091    * However, I can't get these tests to return a valid value under native
1092    * oleaut32, regardless of the value returned in response to the Invoke()
1093    * call (early versions of oleaut32 call AddRef/Release, but not Invoke.
1094    * I'm obviously missing something, as these conversions work fine
1095    * when called through VBA on an object to get its default value property.
1096    *
1097    * Should this test be corrected so that it works under native it should be
1098    * generalised and the remaining types checked as well.
1099    */
1100   in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
1101
1102   VariantInit(&vSrc);
1103   VariantInit(&vDst);
1104
1105   V_VT(&vSrc) = VT_DISPATCH;
1106   V_DISPATCH(&vSrc) = (IDispatch*)&dispatch;
1107   dispatch.vt = VT_UI1;
1108   dispatch.bFailInvoke = FALSE;
1109
1110   hres = VarUI1FromDisp((IDispatch*)&dispatch, in, &out);
1111   trace("0x%08lx\n", hres);
1112
1113   hres = VariantChangeTypeEx(&vDst, &vSrc, in, 0, VT_UI1);
1114   trace("0x%08lx\n", hres);
1115
1116   dispatch.bFailInvoke = TRUE;
1117
1118   hres = VarUI1FromDisp((IDispatch*)&dispatch, in, &out);
1119   trace("0x%08lx\n", hres);
1120
1121   hres = VariantChangeTypeEx(&vDst, &vSrc, in, 0, VT_UI1);
1122   trace("0x%08lx\n", hres);
1123 }
1124
1125 static void test_VarUI1Copy(void)
1126 {
1127   COPYTEST(1, VT_UI1, V_UI1(&vSrc), V_UI1(&vDst), V_UI1REF(&vSrc), V_UI1REF(&vDst), "%d");
1128 }
1129
1130 static void test_VarUI1ChangeTypeEx(void)
1131 {
1132   CONVVARS(CONV_TYPE);
1133   VARIANTARG vSrc, vDst;
1134
1135   in = 1;
1136
1137   INITIAL_TYPETEST(VT_UI1, V_UI1, "%d");
1138   COMMON_TYPETEST;
1139   NEGATIVE_TYPETEST(VT_UI1, V_UI1, "%d", VT_I1, V_I1);
1140 }
1141
1142 /*
1143  * VT_I2/VT_UI2
1144  */
1145
1146 #undef CONV_TYPE
1147 #define CONV_TYPE SHORT
1148 #undef EXPECTRES
1149 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%d")
1150
1151 static void test_VarI2FromI1(void)
1152 {
1153   CONVVARS(signed char);
1154   int i;
1155
1156   CHECKPTR(VarI2FromI1);
1157   CONVERTRANGE(VarI2FromI1, -128, 128);
1158 }
1159
1160 static void test_VarI2FromI4(void)
1161 {
1162   CONVVARS(LONG);
1163   int i;
1164
1165   CHECKPTR(VarI2FromI4);
1166   CONVERT(VarI2FromI4, -32769); EXPECT_OVERFLOW;
1167   CONVERTRANGE(VarI2FromI4, -32768, 32768);
1168   CONVERT(VarI2FromI4, 32768);  EXPECT_OVERFLOW;
1169 }
1170
1171 static void test_VarI2FromI8(void)
1172 {
1173   CONVVARS(LONG64);
1174
1175   CHECKPTR(VarI2FromI8);
1176   CONVERT(VarI2FromI8, -32769); EXPECT_OVERFLOW;
1177   CONVERT(VarI2FromI8, -32768); EXPECT(-32768);
1178   CONVERT(VarI2FromI8, 32767);  EXPECT(32767);
1179   CONVERT(VarI2FromI8, 32768);  EXPECT_OVERFLOW;
1180 }
1181
1182 static void test_VarI2FromUI1(void)
1183 {
1184   CONVVARS(BYTE);
1185   int i;
1186
1187   CHECKPTR(VarI2FromUI1);
1188   CONVERTRANGE(VarI2FromUI1, 0, 256);
1189 }
1190
1191 static void test_VarI2FromUI2(void)
1192 {
1193   CONVVARS(USHORT);
1194   int i;
1195
1196   CHECKPTR(VarI2FromUI2);
1197   CONVERTRANGE(VarI2FromUI2, 0, 32768);
1198   CONVERT(VarI2FromUI2, 32768); EXPECT_OVERFLOW;
1199 }
1200
1201 static void test_VarI2FromUI4(void)
1202 {
1203   CONVVARS(ULONG);
1204   int i;
1205
1206   CHECKPTR(VarI2FromUI4);
1207   CONVERTRANGE(VarI2FromUI4, 0, 32768);
1208   CONVERT(VarI2FromUI4, 32768); EXPECT_OVERFLOW;
1209 }
1210
1211 static void test_VarI2FromUI8(void)
1212 {
1213   CONVVARS(ULONG64);
1214   int i;
1215
1216   CHECKPTR(VarI2FromUI8);
1217   CONVERTRANGE(VarI2FromUI8, 0, 32768);
1218   CONVERT(VarI2FromUI8, 32768); EXPECT_OVERFLOW;
1219 }
1220
1221 static void test_VarI2FromBool(void)
1222 {
1223   CONVVARS(VARIANT_BOOL);
1224   int i;
1225
1226   CHECKPTR(VarI2FromBool);
1227   CONVERTRANGE(VarI2FromBool, -32768, 32768);
1228 }
1229
1230 static void test_VarI2FromR4(void)
1231 {
1232   CONVVARS(FLOAT);
1233
1234   CHECKPTR(VarI2FromR4);
1235   CONVERT(VarI2FromR4, -32769.0f); EXPECT_OVERFLOW;
1236   CONVERT(VarI2FromR4, -32768.0f); EXPECT(-32768);
1237   CONVERT(VarI2FromR4, -1.0f);     EXPECT(-1);
1238   CONVERT(VarI2FromR4, 0.0f);      EXPECT(0);
1239   CONVERT(VarI2FromR4, 1.0f);      EXPECT(1);
1240   CONVERT(VarI2FromR4, 32767.0f);  EXPECT(32767);
1241   CONVERT(VarI2FromR4, 32768.0f);  EXPECT_OVERFLOW;
1242
1243   /* Rounding */
1244   CONVERT(VarI2FromR4, -1.5f); EXPECT(-2);
1245   CONVERT(VarI2FromR4, -0.6f); EXPECT(-1);
1246   CONVERT(VarI2FromR4, -0.5f); EXPECT(0);
1247   CONVERT(VarI2FromR4, -0.4f); EXPECT(0);
1248   CONVERT(VarI2FromR4, 0.4f);  EXPECT(0);
1249   CONVERT(VarI2FromR4, 0.5f);  EXPECT(0);
1250   CONVERT(VarI2FromR4, 0.6f);  EXPECT(1);
1251   CONVERT(VarI2FromR4, 1.5f);  EXPECT(2);
1252 }
1253
1254 static void test_VarI2FromR8(void)
1255 {
1256   CONVVARS(DOUBLE);
1257
1258   CHECKPTR(VarI2FromR8);
1259   CONVERT(VarI2FromR8, -32769.0); EXPECT_OVERFLOW;
1260   CONVERT(VarI2FromR8, -32768.0); EXPECT(-32768);
1261   CONVERT(VarI2FromR8, -1.0);     EXPECT(-1);
1262   CONVERT(VarI2FromR8, 0.0);      EXPECT(0);
1263   CONVERT(VarI2FromR8, 1.0);      EXPECT(1);
1264   CONVERT(VarI2FromR8, 32767.0);  EXPECT(32767);
1265   CONVERT(VarI2FromR8, 32768.0);  EXPECT_OVERFLOW;
1266
1267   /* Rounding */
1268   CONVERT(VarI2FromR8, -1.5); EXPECT(-2);
1269   CONVERT(VarI2FromR8, -0.6); EXPECT(-1);
1270   CONVERT(VarI2FromR8, -0.5); EXPECT(0);
1271   CONVERT(VarI2FromR8, -0.4); EXPECT(0);
1272   CONVERT(VarI2FromR8, 0.4);  EXPECT(0);
1273   CONVERT(VarI2FromR8, 0.5);  EXPECT(0);
1274   CONVERT(VarI2FromR8, 0.6);  EXPECT(1);
1275   CONVERT(VarI2FromR8, 1.5);  EXPECT(2);
1276 }
1277
1278 static void test_VarI2FromDate(void)
1279 {
1280   CONVVARS(DATE);
1281
1282   CHECKPTR(VarI2FromDate);
1283   CONVERT(VarI2FromDate, -32769.0); EXPECT_OVERFLOW;
1284   CONVERT(VarI2FromDate, -32768.0); EXPECT(-32768);
1285   CONVERT(VarI2FromDate, -1.0);   EXPECT(-1);
1286   CONVERT(VarI2FromDate, 0.0);    EXPECT(0);
1287   CONVERT(VarI2FromDate, 1.0);    EXPECT(1);
1288   CONVERT(VarI2FromDate, 32767.0);  EXPECT(32767);
1289   CONVERT(VarI2FromDate, 32768.0);  EXPECT_OVERFLOW;
1290
1291   /* Rounding */
1292   CONVERT(VarI2FromDate, -1.5); EXPECT(-2);
1293   CONVERT(VarI2FromDate, -0.6); EXPECT(-1);
1294   CONVERT(VarI2FromDate, -0.5); EXPECT(0);
1295   CONVERT(VarI2FromDate, -0.4); EXPECT(0);
1296   CONVERT(VarI2FromDate, 0.4);  EXPECT(0);
1297   CONVERT(VarI2FromDate, 0.5);  EXPECT(0);
1298   CONVERT(VarI2FromDate, 0.6);  EXPECT(1);
1299   CONVERT(VarI2FromDate, 1.5);  EXPECT(2);
1300 }
1301
1302 static void test_VarI2FromCy(void)
1303 {
1304   CONVVARS(CY);
1305
1306   CHECKPTR(VarI2FromCy);
1307   CONVERT_CY(VarI2FromCy,-32769); EXPECT_OVERFLOW;
1308   CONVERT_CY(VarI2FromCy,-32768); EXPECT(32768);
1309   CONVERT_CY(VarI2FromCy,-1);     EXPECT(-1);
1310   CONVERT_CY(VarI2FromCy,0);      EXPECT(0);
1311   CONVERT_CY(VarI2FromCy,1);      EXPECT(1);
1312   CONVERT_CY(VarI2FromCy,32767);  EXPECT(32767);
1313   CONVERT_CY(VarI2FromCy,32768);  EXPECT_OVERFLOW;
1314
1315   /* Rounding */
1316   CONVERT_CY(VarI2FromCy,-1.5); EXPECT(-2);
1317   CONVERT_CY(VarI2FromCy,-0.6); EXPECT(-1);
1318   CONVERT_CY(VarI2FromCy,-0.5); EXPECT(0);
1319   CONVERT_CY(VarI2FromCy,-0.4); EXPECT(0);
1320   CONVERT_CY(VarI2FromCy,0.4);  EXPECT(0);
1321   CONVERT_CY(VarI2FromCy,0.5);  EXPECT(0);
1322   CONVERT_CY(VarI2FromCy,0.6);  EXPECT(1);
1323   CONVERT_CY(VarI2FromCy,1.5);  EXPECT(2);
1324 }
1325
1326 static void test_VarI2FromDec(void)
1327 {
1328   CONVVARS(DECIMAL);
1329
1330   CHECKPTR(VarI2FromDec);
1331
1332   CONVERT_BADDEC(VarI2FromDec);
1333
1334   CONVERT_DEC(VarI2FromDec,0,0x80,0,32769); EXPECT_OVERFLOW;
1335   CONVERT_DEC(VarI2FromDec,0,0x80,0,32768); EXPECT(-32768);
1336   CONVERT_DEC(VarI2FromDec,0,0x80,0,1);     EXPECT(-1);
1337   CONVERT_DEC(VarI2FromDec,0,0,0,0);        EXPECT(0);
1338   CONVERT_DEC(VarI2FromDec,0,0,0,1);        EXPECT(1);
1339   CONVERT_DEC(VarI2FromDec,0,0,0,32767);    EXPECT(32767);
1340   CONVERT_DEC(VarI2FromDec,0,0,0,32768);    EXPECT_OVERFLOW;
1341
1342   CONVERT_DEC(VarI2FromDec,2,0x80,0,3276800); EXPECT(-32768);
1343   CONVERT_DEC(VarI2FromDec,2,0,0,3276700);    EXPECT(32767);
1344   CONVERT_DEC(VarI2FromDec,2,0,0,3276800);    EXPECT_OVERFLOW;
1345 }
1346
1347 static void test_VarI2FromStr(void)
1348 {
1349   CONVVARS(LCID);
1350   OLECHAR buff[128];
1351
1352   in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
1353
1354   CHECKPTR(VarI2FromStr);
1355
1356   CONVERT_STR(VarI2FromStr,NULL, 0);     EXPECT_MISMATCH;
1357   CONVERT_STR(VarI2FromStr,"0", 0);      EXPECT(0);
1358   CONVERT_STR(VarI2FromStr,"-32769", 0); EXPECT_OVERFLOW;
1359   CONVERT_STR(VarI2FromStr,"-32768", 0); EXPECT(-32768);
1360   CONVERT_STR(VarI2FromStr,"32767", 0);  EXPECT(32767);
1361   CONVERT_STR(VarI2FromStr,"32768", 0);  EXPECT_OVERFLOW;
1362
1363   /* Rounding */
1364   CONVERT_STR(VarI2FromStr,"-1.5", 0); EXPECT(-2);
1365   CONVERT_STR(VarI2FromStr,"-0.6", 0); EXPECT(-1);
1366   CONVERT_STR(VarI2FromStr,"-0.5", 0); EXPECT(0);
1367   CONVERT_STR(VarI2FromStr,"-0.4", 0); EXPECT(0);
1368   CONVERT_STR(VarI2FromStr,"0.4", 0);  EXPECT(0);
1369   CONVERT_STR(VarI2FromStr,"0.5", 0);  EXPECT(0);
1370   CONVERT_STR(VarI2FromStr,"0.6", 0);  EXPECT(1);
1371   CONVERT_STR(VarI2FromStr,"1.5", 0);  EXPECT(2);
1372 }
1373
1374 static void test_VarI2Copy(void)
1375 {
1376   COPYTEST(1, VT_I2, V_I2(&vSrc), V_I2(&vDst), V_I2REF(&vSrc), V_I2REF(&vDst), "%d");
1377 }
1378
1379 static void test_VarI2ChangeTypeEx(void)
1380 {
1381   CONVVARS(CONV_TYPE);
1382   VARIANTARG vSrc, vDst;
1383
1384   in = 1;
1385
1386   INITIAL_TYPETEST(VT_I2, V_I2, "%d");
1387   COMMON_TYPETEST;
1388   NEGATIVE_TYPETEST(VT_I2, V_I2, "%d", VT_UI2, V_UI2);
1389 }
1390
1391 #undef CONV_TYPE
1392 #define CONV_TYPE USHORT
1393
1394 static void test_VarUI2FromI1(void)
1395 {
1396   CONVVARS(signed char);
1397   int i;
1398
1399   CHECKPTR(VarUI2FromI1);
1400   OVERFLOWRANGE(VarUI2FromI1, -128, 0);
1401   CONVERTRANGE(VarUI2FromI1, 0, 128);
1402 }
1403
1404 static void test_VarUI2FromI2(void)
1405 {
1406   CONVVARS(SHORT);
1407   int i;
1408
1409   CHECKPTR(VarUI2FromI2);
1410   OVERFLOWRANGE(VarUI2FromI2, -32768, 0);
1411   CONVERTRANGE(VarUI2FromI2, 0, 32768);
1412 }
1413
1414 static void test_VarUI2FromI4(void)
1415 {
1416   CONVVARS(LONG);
1417   int i;
1418
1419   CHECKPTR(VarUI2FromI4);
1420   OVERFLOWRANGE(VarUI2FromI4, -32768, 0);
1421   CONVERT(VarUI2FromI4, 0);     EXPECT(0);
1422   CONVERT(VarUI2FromI4, 65535); EXPECT(65535);
1423   CONVERT(VarUI2FromI4, 65536); EXPECT_OVERFLOW;
1424 }
1425
1426 static void test_VarUI2FromI8(void)
1427 {
1428   CONVVARS(LONG64);
1429   int i;
1430
1431   CHECKPTR(VarUI2FromI8);
1432   OVERFLOWRANGE(VarUI2FromI8, -32768, 0);
1433   CONVERT(VarUI2FromI8, 0);     EXPECT(0);
1434   CONVERT(VarUI2FromI8, 65535); EXPECT(65535);
1435   CONVERT(VarUI2FromI8, 65536); EXPECT_OVERFLOW;
1436 }
1437
1438 static void test_VarUI2FromUI1(void)
1439 {
1440   CONVVARS(BYTE);
1441   int i;
1442
1443   CHECKPTR(VarUI2FromUI1);
1444   CONVERTRANGE(VarUI2FromUI1, 0, 256);
1445 }
1446
1447 static void test_VarUI2FromUI4(void)
1448 {
1449   CONVVARS(ULONG);
1450
1451   CHECKPTR(VarUI2FromUI4);
1452   CONVERT(VarUI2FromUI4, 0);     EXPECT(0);
1453   CONVERT(VarUI2FromUI4, 65535); EXPECT(65535);
1454   CONVERT(VarUI2FromUI4, 65536); EXPECT_OVERFLOW;
1455 }
1456
1457 static void test_VarUI2FromUI8(void)
1458 {
1459   CONVVARS(ULONG64);
1460
1461   CHECKPTR(VarUI2FromUI8);
1462   CONVERT(VarUI2FromUI8, 0);     EXPECT(0);
1463   CONVERT(VarUI2FromUI8, 65535); EXPECT(65535);
1464   CONVERT(VarUI2FromUI8, 65536); EXPECT_OVERFLOW;
1465 }
1466
1467 static void test_VarUI2FromBool(void)
1468 {
1469   CONVVARS(VARIANT_BOOL);
1470   int i;
1471
1472   CHECKPTR(VarUI2FromBool);
1473   CONVERT(VarUI2FromBool, -1); EXPECT(65535); /* Wraps! */
1474   CONVERTRANGE(VarUI2FromBool, 0, 32768);
1475 }
1476
1477 static void test_VarUI2FromR4(void)
1478 {
1479   CONVVARS(FLOAT);
1480
1481   CHECKPTR(VarUI2FromR4);
1482   CONVERT(VarUI2FromR4, -1.0f);    EXPECT_OVERFLOW;
1483   CONVERT(VarUI2FromR4, 0.0f);     EXPECT(0);
1484   CONVERT(VarUI2FromR4, 1.0f);     EXPECT(1);
1485   CONVERT(VarUI2FromR4, 65535.0f); EXPECT(65535);
1486   CONVERT(VarUI2FromR4, 65536.0f); EXPECT_OVERFLOW;
1487
1488   /* Rounding */
1489   CONVERT(VarUI2FromR4, -1.5f); EXPECT_OVERFLOW;
1490   CONVERT(VarUI2FromR4, -0.6f); EXPECT_OVERFLOW;
1491   CONVERT(VarUI2FromR4, -0.5f); EXPECT(0);
1492   CONVERT(VarUI2FromR4, -0.4f); EXPECT(0);
1493   CONVERT(VarUI2FromR4, 0.4f);  EXPECT(0);
1494   CONVERT(VarUI2FromR4, 0.5f);  EXPECT(0);
1495   CONVERT(VarUI2FromR4, 0.6f);  EXPECT(1);
1496   CONVERT(VarUI2FromR4, 1.5f);  EXPECT(2);
1497 }
1498
1499 static void test_VarUI2FromR8(void)
1500 {
1501   CONVVARS(DOUBLE);
1502
1503   CHECKPTR(VarUI2FromR8);
1504   CONVERT(VarUI2FromR8, -1.0);    EXPECT_OVERFLOW;
1505   CONVERT(VarUI2FromR8, 0.0);     EXPECT(0);
1506   CONVERT(VarUI2FromR8, 1.0);     EXPECT(1);
1507   CONVERT(VarUI2FromR8, 65535.0); EXPECT(65535);
1508   CONVERT(VarUI2FromR8, 65536.0); EXPECT_OVERFLOW;
1509
1510   /* Rounding */
1511   CONVERT(VarUI2FromR8, -1.5); EXPECT_OVERFLOW;
1512   CONVERT(VarUI2FromR8, -0.6); EXPECT_OVERFLOW;
1513   CONVERT(VarUI2FromR8, -0.5); EXPECT(0);
1514   CONVERT(VarUI2FromR8, -0.4); EXPECT(0);
1515   CONVERT(VarUI2FromR8, 0.4);  EXPECT(0);
1516   CONVERT(VarUI2FromR8, 0.5);  EXPECT(0);
1517   CONVERT(VarUI2FromR8, 0.6);  EXPECT(1);
1518   CONVERT(VarUI2FromR8, 1.5);  EXPECT(2);
1519 }
1520
1521 static void test_VarUI2FromDate(void)
1522 {
1523   CONVVARS(DATE);
1524
1525   CHECKPTR(VarUI2FromDate);
1526   CONVERT(VarUI2FromDate, -1.0);    EXPECT_OVERFLOW;
1527   CONVERT(VarUI2FromDate, 0.0);     EXPECT(0);
1528   CONVERT(VarUI2FromDate, 1.0);     EXPECT(1);
1529   CONVERT(VarUI2FromDate, 65535.0); EXPECT(65535);
1530   CONVERT(VarUI2FromDate, 65536.0); EXPECT_OVERFLOW;
1531
1532   /* Rounding */
1533   CONVERT(VarUI2FromDate, -1.5); EXPECT_OVERFLOW;
1534   CONVERT(VarUI2FromDate, -0.6); EXPECT_OVERFLOW;
1535   CONVERT(VarUI2FromDate, -0.5); EXPECT(0);
1536   CONVERT(VarUI2FromDate, -0.4); EXPECT(0);
1537   CONVERT(VarUI2FromDate, 0.4);  EXPECT(0);
1538   CONVERT(VarUI2FromDate, 0.5);  EXPECT(0);
1539   CONVERT(VarUI2FromDate, 0.6);  EXPECT(1);
1540   CONVERT(VarUI2FromDate, 1.5);  EXPECT(2);
1541 }
1542
1543 static void test_VarUI2FromCy(void)
1544 {
1545   CONVVARS(CY);
1546
1547   CHECKPTR(VarUI2FromCy);
1548   CONVERT_CY(VarUI2FromCy,-1);    EXPECT_OVERFLOW;
1549   CONVERT_CY(VarUI2FromCy,0);     EXPECT(0);
1550   CONVERT_CY(VarUI2FromCy,1);     EXPECT(1);
1551   CONVERT_CY(VarUI2FromCy,65535); EXPECT(65535);
1552   CONVERT_CY(VarUI2FromCy,65536); EXPECT_OVERFLOW;
1553
1554   /* Rounding */
1555   CONVERT_CY(VarUI2FromCy,-1.5); EXPECT_OVERFLOW;
1556   CONVERT_CY(VarUI2FromCy,-0.6); EXPECT_OVERFLOW;
1557   CONVERT_CY(VarUI2FromCy,-0.5); EXPECT(0);
1558   CONVERT_CY(VarUI2FromCy,-0.4); EXPECT(0);
1559   CONVERT_CY(VarUI2FromCy,0.4);  EXPECT(0);
1560   CONVERT_CY(VarUI2FromCy,0.5);  EXPECT(0);
1561   CONVERT_CY(VarUI2FromCy,0.6);  EXPECT(1);
1562   CONVERT_CY(VarUI2FromCy,1.5);  EXPECT(2);
1563 }
1564
1565 static void test_VarUI2FromDec(void)
1566 {
1567   CONVVARS(DECIMAL);
1568
1569   CHECKPTR(VarUI2FromDec);
1570
1571   CONVERT_BADDEC(VarUI2FromDec);
1572
1573   CONVERT_DEC(VarUI2FromDec,0,0x80,0,1);  EXPECT_OVERFLOW;
1574   CONVERT_DEC(VarUI2FromDec,0,0,0,0);     EXPECT(0);
1575   CONVERT_DEC(VarUI2FromDec,0,0,0,1);     EXPECT(1);
1576   CONVERT_DEC(VarUI2FromDec,0,0,0,65535); EXPECT(65535);
1577   CONVERT_DEC(VarUI2FromDec,0,0,0,65536); EXPECT_OVERFLOW;
1578
1579   CONVERT_DEC(VarUI2FromDec,2,0x80,0,100);  EXPECT_OVERFLOW;
1580   CONVERT_DEC(VarUI2FromDec,2,0,0,6553500); EXPECT(65535);
1581   CONVERT_DEC(VarUI2FromDec,2,0,0,6553600); EXPECT_OVERFLOW;
1582 }
1583
1584 static void test_VarUI2FromStr(void)
1585 {
1586   CONVVARS(LCID);
1587   OLECHAR buff[128];
1588
1589   in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
1590
1591   CHECKPTR(VarUI2FromStr);
1592
1593   CONVERT_STR(VarUI2FromStr,NULL, 0);    EXPECT_MISMATCH;
1594   CONVERT_STR(VarUI2FromStr,"0", 0);     EXPECT(0);
1595   CONVERT_STR(VarUI2FromStr,"-1", 0);    EXPECT_OVERFLOW;
1596   CONVERT_STR(VarUI2FromStr,"65535", 0); EXPECT(65535);
1597   CONVERT_STR(VarUI2FromStr,"65536", 0); EXPECT_OVERFLOW;
1598
1599   /* Rounding */
1600   CONVERT_STR(VarUI2FromStr,"-1.5", 0); EXPECT_OVERFLOW;
1601   CONVERT_STR(VarUI2FromStr,"-0.6", 0); EXPECT_OVERFLOW;
1602   CONVERT_STR(VarUI2FromStr,"-0.5", 0); EXPECT(0);
1603   CONVERT_STR(VarUI2FromStr,"-0.4", 0); EXPECT(0);
1604   CONVERT_STR(VarUI2FromStr,"0.4", 0);  EXPECT(0);
1605   CONVERT_STR(VarUI2FromStr,"0.5", 0);  EXPECT(0);
1606   CONVERT_STR(VarUI2FromStr,"0.6", 0);  EXPECT(1);
1607   CONVERT_STR(VarUI2FromStr,"1.5", 0);  EXPECT(2);
1608 }
1609
1610 static void test_VarUI2Copy(void)
1611 {
1612   if (!IS_ANCIENT)
1613   {
1614       COPYTEST(1, VT_UI2, V_UI2(&vSrc), V_UI2(&vDst), V_UI2REF(&vSrc), V_UI2REF(&vDst), "%d");
1615   }
1616 }
1617
1618 static void test_VarUI2ChangeTypeEx(void)
1619 {
1620   CONVVARS(CONV_TYPE);
1621   VARIANTARG vSrc, vDst;
1622
1623   in = 1;
1624
1625   if (!IS_ANCIENT)
1626   {
1627     INITIAL_TYPETEST(VT_UI2, V_UI2, "%d");
1628     COMMON_TYPETEST;
1629     NEGATIVE_TYPETEST(VT_UI2, V_UI2, "%d", VT_I2, V_I2);
1630   }
1631 }
1632
1633 /*
1634  * VT_I4/VT_UI4
1635  */
1636
1637 #undef CONV_TYPE
1638 #define CONV_TYPE LONG
1639 #undef EXPECTRES
1640 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%ld")
1641
1642
1643 static void test_VarI4FromI1(void)
1644 {
1645   CONVVARS(signed char);
1646   int i;
1647
1648   CHECKPTR(VarI4FromI1);
1649   CONVERTRANGE(VarI4FromI1, -128, 128);
1650 }
1651
1652 static void test_VarI4FromI2(void)
1653 {
1654   CONVVARS(SHORT);
1655   int i;
1656
1657   CHECKPTR(VarI4FromI2);
1658   CONVERTRANGE(VarI4FromI2, -32768, 32768);
1659 }
1660
1661 static void test_VarI4FromI8(void)
1662 {
1663   CONVVARS(LONG64);
1664
1665   CHECKPTR(VarI4FromI8);
1666   CHECKPTR(VarI4FromDec);
1667
1668   CONVERT(VarI4FromI8, -1);                   EXPECT(-1);
1669   CONVERT(VarI4FromI8, 0);                    EXPECT(0);
1670   CONVERT(VarI4FromI8, 1);                    EXPECT(1);
1671
1672   CONVERT_I8(VarI4FromI8, -1, 2147483647ul); EXPECT_OVERFLOW;
1673   CONVERT_I8(VarI4FromI8, -1, 2147483648ul); EXPECT(-2147483647 - 1);
1674   CONVERT_I8(VarI4FromI8, 0, 2147483647ul);  EXPECT(2147483647);
1675   CONVERT_I8(VarI4FromI8, 0, 2147483648ul);  EXPECT_OVERFLOW;
1676 }
1677
1678 static void test_VarI4FromUI1(void)
1679 {
1680   CONVVARS(BYTE);
1681   int i;
1682
1683   CHECKPTR(VarI4FromUI1);
1684   CONVERTRANGE(VarI4FromUI1, 0, 256);
1685 }
1686
1687 static void test_VarI4FromUI2(void)
1688 {
1689   CONVVARS(USHORT);
1690   int i;
1691
1692   CHECKPTR(VarI4FromUI2);
1693   CONVERTRANGE(VarI4FromUI2, 0, 65536);
1694 }
1695
1696 static void test_VarI4FromUI4(void)
1697 {
1698   CONVVARS(ULONG);
1699
1700   CHECKPTR(VarI4FromUI4);
1701   CONVERT(VarI4FromUI4, 0);            EXPECT(0);
1702   CONVERT(VarI4FromUI4, 1);            EXPECT(1);
1703   CONVERT(VarI4FromUI4, 2147483647);   EXPECT(2147483647);
1704   CONVERT(VarI4FromUI4, 2147483648ul); EXPECT_OVERFLOW;
1705 }
1706
1707 static void test_VarI4FromUI8(void)
1708 {
1709   CONVVARS(ULONG64);
1710
1711   CHECKPTR(VarI4FromUI8);
1712   CONVERT(VarI4FromUI8, 0);             EXPECT(0);
1713   CONVERT(VarI4FromUI8, 1);             EXPECT(1);
1714   CONVERT(VarI4FromUI8, 2147483647);    EXPECT(2147483647);
1715   CONVERT(VarI4FromUI8, 2147483648ul);  EXPECT_OVERFLOW;
1716 }
1717
1718 static void test_VarI4FromBool(void)
1719 {
1720   CONVVARS(VARIANT_BOOL);
1721   int i;
1722
1723   CHECKPTR(VarI4FromBool);
1724   CONVERTRANGE(VarI4FromBool, -32768, 32768);
1725 }
1726
1727 static void test_VarI4FromR4(void)
1728 {
1729   CONVVARS(FLOAT);
1730
1731   CHECKPTR(VarI4FromR4);
1732
1733   /* min/max values are not exactly representable in a float */
1734   CONVERT(VarI4FromR4, -1.0f); EXPECT(-1);
1735   CONVERT(VarI4FromR4, 0.0f);  EXPECT(0);
1736   CONVERT(VarI4FromR4, 1.0f);  EXPECT(1);
1737
1738   CONVERT(VarI4FromR4, -1.5f); EXPECT(-2);
1739   CONVERT(VarI4FromR4, -0.6f); EXPECT(-1);
1740   CONVERT(VarI4FromR4, -0.5f); EXPECT(0);
1741   CONVERT(VarI4FromR4, -0.4f); EXPECT(0);
1742   CONVERT(VarI4FromR4, 0.4f);  EXPECT(0);
1743   CONVERT(VarI4FromR4, 0.5f);  EXPECT(0);
1744   CONVERT(VarI4FromR4, 0.6f);  EXPECT(1);
1745   CONVERT(VarI4FromR4, 1.5f);  EXPECT(2);
1746 }
1747
1748 static void test_VarI4FromR8(void)
1749 {
1750   CONVVARS(DOUBLE);
1751
1752   CHECKPTR(VarI4FromR8);
1753   CONVERT(VarI4FromR8, -2147483649.0); EXPECT_OVERFLOW;
1754   CONVERT(VarI4FromR8, -2147483648.0); EXPECT(-2147483647 - 1);
1755   CONVERT(VarI4FromR8, -1.0);          EXPECT(-1);
1756   CONVERT(VarI4FromR8, 0.0);           EXPECT(0);
1757   CONVERT(VarI4FromR8, 1.0);           EXPECT(1);
1758   CONVERT(VarI4FromR8, 2147483647.0);  EXPECT(2147483647);
1759   CONVERT(VarI4FromR8, 2147483648.0);  EXPECT_OVERFLOW;
1760
1761   CONVERT(VarI4FromR8, -1.5); EXPECT(-2);
1762   CONVERT(VarI4FromR8, -0.6); EXPECT(-1);
1763   CONVERT(VarI4FromR8, -0.5); EXPECT(0);
1764   CONVERT(VarI4FromR8, -0.4); EXPECT(0);
1765   CONVERT(VarI4FromR8, 0.4);  EXPECT(0);
1766   CONVERT(VarI4FromR8, 0.5);  EXPECT(0);
1767   CONVERT(VarI4FromR8, 0.6);  EXPECT(1);
1768   CONVERT(VarI4FromR8, 1.5);  EXPECT(2);
1769 }
1770
1771 static void test_VarI4FromDate(void)
1772 {
1773   CONVVARS(DATE);
1774
1775   CHECKPTR(VarI4FromDate);
1776   CONVERT(VarI4FromDate, -2147483649.0); EXPECT_OVERFLOW;
1777   CONVERT(VarI4FromDate, -2147483648.0); EXPECT(-2147483647 - 1);
1778   CONVERT(VarI4FromDate, -1.0);          EXPECT(-1);
1779   CONVERT(VarI4FromDate, 0.0);           EXPECT(0);
1780   CONVERT(VarI4FromDate, 1.0);           EXPECT(1);
1781   CONVERT(VarI4FromDate, 2147483647.0);  EXPECT(2147483647);
1782   CONVERT(VarI4FromDate, 2147483648.0);  EXPECT_OVERFLOW;
1783
1784   CONVERT(VarI4FromDate, -1.5); EXPECT(-2);
1785   CONVERT(VarI4FromDate, -0.6); EXPECT(-1);
1786   CONVERT(VarI4FromDate, -0.5); EXPECT(0);
1787   CONVERT(VarI4FromDate, -0.4); EXPECT(0);
1788   CONVERT(VarI4FromDate, 0.4);  EXPECT(0);
1789   CONVERT(VarI4FromDate, 0.5);  EXPECT(0);
1790   CONVERT(VarI4FromDate, 0.6);  EXPECT(1);
1791   CONVERT(VarI4FromDate, 1.5);  EXPECT(2);
1792 }
1793
1794 static void test_VarI4FromCy(void)
1795 {
1796   CONVVARS(CY);
1797
1798   CHECKPTR(VarI4FromCy);
1799   CONVERT_CY(VarI4FromCy,-1); EXPECT(-1);
1800   CONVERT_CY(VarI4FromCy,0);  EXPECT(0);
1801   CONVERT_CY(VarI4FromCy,1);  EXPECT(1);
1802
1803   CONVERT_CY64(VarI4FromCy,-1,2147483647ul); EXPECT_OVERFLOW;
1804   CONVERT_CY64(VarI4FromCy,-1,2147483648ul); EXPECT(-2147483647 - 1);
1805   CONVERT_CY64(VarI4FromCy,0,2147483647ul);  EXPECT(2147483647ul);
1806   CONVERT_CY64(VarI4FromCy,0,2147483648ul);  EXPECT_OVERFLOW;
1807
1808   CONVERT_CY(VarI4FromCy,-1.5); EXPECT(-2);
1809   CONVERT_CY(VarI4FromCy,-0.6); EXPECT(-1);
1810   CONVERT_CY(VarI4FromCy,-0.5); EXPECT(0);
1811   CONVERT_CY(VarI4FromCy,-0.4); EXPECT(0);
1812   CONVERT_CY(VarI4FromCy,0.4);  EXPECT(0);
1813   CONVERT_CY(VarI4FromCy,0.5);  EXPECT(0);
1814   CONVERT_CY(VarI4FromCy,0.6);  EXPECT(1);
1815   CONVERT_CY(VarI4FromCy,1.5);  EXPECT(2);
1816 }
1817
1818 static void test_VarI4FromDec(void)
1819 {
1820   CONVVARS(DECIMAL);
1821
1822   CHECKPTR(VarI4FromDec);
1823
1824   CONVERT_BADDEC(VarI4FromDec);
1825
1826   CONVERT_DEC(VarI4FromDec,0,0x80,0,1); EXPECT(-1);
1827   CONVERT_DEC(VarI4FromDec,0,0,0,0);    EXPECT(0);
1828   CONVERT_DEC(VarI4FromDec,0,0,0,1);    EXPECT(1);
1829
1830   CONVERT_DEC64(VarI4FromDec,0,0x80,0,0,2147483649ul);  EXPECT_OVERFLOW;
1831   CONVERT_DEC64(VarI4FromDec,0,0x80,0,0,2147483648ul);  EXPECT(-2147483647 - 1);
1832   CONVERT_DEC64(VarI4FromDec,0,0,0,0,2147483647ul);     EXPECT(2147483647ul);
1833   CONVERT_DEC64(VarI4FromDec,0,0,0,0,2147483648ul);     EXPECT_OVERFLOW;
1834
1835   CONVERT_DEC64(VarI4FromDec,2,0x80,0,50,100);       EXPECT_OVERFLOW;
1836   CONVERT_DEC64(VarI4FromDec,2,0x80,0,50,0);         EXPECT(-2147483647 - 1);
1837   CONVERT_DEC64(VarI4FromDec,2,0,0,49,4294967196ul); EXPECT(2147483647);
1838   CONVERT_DEC64(VarI4FromDec,2,0,0,50,0);            EXPECT_OVERFLOW;
1839 }
1840
1841 static void test_VarI4FromStr(void)
1842 {
1843   CONVVARS(LCID);
1844   OLECHAR buff[128];
1845
1846   in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
1847
1848   CHECKPTR(VarI4FromStr);
1849
1850   CONVERT_STR(VarI4FromStr,NULL,0);          EXPECT_MISMATCH;
1851   CONVERT_STR(VarI4FromStr,"0",0);           EXPECT(0);
1852   CONVERT_STR(VarI4FromStr,"-2147483649",0); EXPECT_OVERFLOW;
1853   CONVERT_STR(VarI4FromStr,"-2147483648",0); EXPECT(-2147483647 -1);
1854   CONVERT_STR(VarI4FromStr,"2147483647",0);  EXPECT(2147483647);
1855   CONVERT_STR(VarI4FromStr,"2147483648",0);  EXPECT_OVERFLOW;
1856
1857   /* Rounding */
1858   CONVERT_STR(VarI4FromStr,"-1.5",0); EXPECT(-2);
1859   CONVERT_STR(VarI4FromStr,"-0.6",0); EXPECT(-1);
1860   CONVERT_STR(VarI4FromStr,"-0.5",0); EXPECT(0);
1861   CONVERT_STR(VarI4FromStr,"-0.4",0); EXPECT(0);
1862   CONVERT_STR(VarI4FromStr,"0.4",0);  EXPECT(0);
1863   CONVERT_STR(VarI4FromStr,"0.5",0);  EXPECT(0);
1864   CONVERT_STR(VarI4FromStr,"0.6",0);  EXPECT(1);
1865   CONVERT_STR(VarI4FromStr,"1.5",0);  EXPECT(2);
1866 }
1867
1868 static void test_VarI4Copy(void)
1869 {
1870   COPYTEST(1l, VT_I4, V_I4(&vSrc), V_I4(&vDst), V_I4REF(&vSrc), V_I4REF(&vDst), "%ld");
1871 }
1872
1873 static void test_VarI4ChangeTypeEx(void)
1874 {
1875   CONVVARS(CONV_TYPE);
1876   VARIANTARG vSrc, vDst;
1877
1878   in = 1;
1879
1880   INITIAL_TYPETEST(VT_I4, V_I4, "%ld");
1881   COMMON_TYPETEST;
1882   NEGATIVE_TYPETEST(VT_I4, V_I4, "%ld", VT_UI4, V_UI4);
1883 }
1884
1885 #undef CONV_TYPE
1886 #define CONV_TYPE ULONG
1887 #undef EXPECTRES
1888 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%lu")
1889
1890 static void test_VarUI4FromI1(void)
1891 {
1892   CONVVARS(signed char);
1893   int i;
1894
1895   CHECKPTR(VarUI4FromI1);
1896   OVERFLOWRANGE(VarUI4FromI1, -127, 0);
1897   CONVERTRANGE(VarUI4FromI1, 0, 128);
1898 }
1899
1900 static void test_VarUI4FromI2(void)
1901 {
1902   CONVVARS(SHORT);
1903   int i;
1904
1905   CHECKPTR(VarUI4FromI2);
1906   OVERFLOWRANGE(VarUI4FromI2, -32768, 0);
1907   CONVERTRANGE(VarUI4FromI2, 0, 32768);
1908 }
1909
1910 static void test_VarUI4FromUI2(void)
1911 {
1912   CONVVARS(USHORT);
1913   int i;
1914
1915   CHECKPTR(VarUI4FromUI2);
1916   CONVERTRANGE(VarUI4FromUI2, 0, 65536);
1917 }
1918
1919 static void test_VarUI4FromI8(void)
1920 {
1921   CONVVARS(LONG64);
1922
1923   CHECKPTR(VarUI4FromI8);
1924   CONVERT(VarUI4FromI8, -1);           EXPECT_OVERFLOW;
1925   CONVERT(VarUI4FromI8, 0);            EXPECT(0);
1926   CONVERT(VarUI4FromI8, 1);            EXPECT(1);
1927   CONVERT(VarUI4FromI8, 4294967295ul); EXPECT(4294967295ul);
1928   CONVERT_I8(VarUI4FromI8, 1, 0);      EXPECT_OVERFLOW;
1929 }
1930
1931 static void test_VarUI4FromUI1(void)
1932 {
1933   CONVVARS(BYTE);
1934   int i;
1935
1936   CHECKPTR(VarUI4FromUI1);
1937   CONVERTRANGE(VarUI4FromUI1, 0, 256);
1938 }
1939
1940 static void test_VarUI4FromI4(void)
1941 {
1942   CONVVARS(int);
1943
1944   CHECKPTR(VarUI4FromI4);
1945   CONVERT(VarUI4FromI4, -1);         EXPECT_OVERFLOW;
1946   CONVERT(VarUI4FromI4, 0);          EXPECT(0);
1947   CONVERT(VarUI4FromI4, 1);          EXPECT(1);
1948   CONVERT(VarUI4FromI4, 2147483647); EXPECT(2147483647);
1949 }
1950
1951 static void test_VarUI4FromUI8(void)
1952 {
1953   CONVVARS(ULONG64);
1954
1955   CHECKPTR(VarUI4FromUI8);
1956   CONVERT(VarUI4FromUI8, 0);           EXPECT(0);
1957   CONVERT(VarUI4FromUI8, 1);           EXPECT(1);
1958   CONVERT(VarUI4FromI8, 4294967295ul); EXPECT(4294967295ul);
1959   CONVERT_I8(VarUI4FromI8, 1, 0);      EXPECT_OVERFLOW;
1960 }
1961
1962 static void test_VarUI4FromBool(void)
1963 {
1964   CONVVARS(VARIANT_BOOL);
1965   int i;
1966
1967   CHECKPTR(VarUI4FromBool);
1968   CONVERTRANGE(VarUI4FromBool, -32768, 32768);
1969 }
1970
1971 static void test_VarUI4FromR4(void)
1972 {
1973   CONVVARS(FLOAT);
1974
1975   CHECKPTR(VarUI4FromR4);
1976   /* We can't test max values as they are not exactly representable in a float */
1977   CONVERT(VarUI4FromR4, -1.0f); EXPECT_OVERFLOW;
1978   CONVERT(VarUI4FromR4, 0.0f);  EXPECT(0);
1979   CONVERT(VarUI4FromR4, 1.0f);  EXPECT(1);
1980
1981   CONVERT(VarUI4FromR4, -1.5f); EXPECT_OVERFLOW;
1982   CONVERT(VarUI4FromR4, -0.6f); EXPECT_OVERFLOW;
1983   CONVERT(VarUI4FromR4, -0.5f); EXPECT(0);
1984   CONVERT(VarUI4FromR4, -0.4f); EXPECT(0);
1985   CONVERT(VarUI4FromR4, 0.4f);  EXPECT(0);
1986   CONVERT(VarUI4FromR4, 0.5f);  EXPECT(0);
1987   CONVERT(VarUI4FromR4, 0.6f);  EXPECT(1);
1988   CONVERT(VarUI4FromR4, 1.5f);  EXPECT(2);
1989
1990 }
1991
1992 static void test_VarUI4FromR8(void)
1993 {
1994   CONVVARS(DOUBLE);
1995
1996   CHECKPTR(VarUI4FromR8);
1997   CONVERT(VarUI4FromR8, -1.0);         EXPECT_OVERFLOW;
1998   CONVERT(VarUI4FromR8, 0.0);          EXPECT(0);
1999   CONVERT(VarUI4FromR8, 1.0);          EXPECT(1);
2000   CONVERT(VarUI4FromR8, 4294967295.0); EXPECT(4294967295ul);
2001   CONVERT(VarUI4FromR8, 4294967296.0); EXPECT_OVERFLOW;
2002
2003   CONVERT(VarUI4FromR8, -1.5); EXPECT_OVERFLOW;
2004   CONVERT(VarUI4FromR8, -0.6); EXPECT_OVERFLOW;
2005   CONVERT(VarUI4FromR8, -0.5); EXPECT(0);
2006   CONVERT(VarUI4FromR8, -0.4); EXPECT(0);
2007   CONVERT(VarUI4FromR8, 0.4);  EXPECT(0);
2008   CONVERT(VarUI4FromR8, 0.5);  EXPECT(0);
2009   CONVERT(VarUI4FromR8, 0.6);  EXPECT(1);
2010   CONVERT(VarUI4FromR8, 1.5);  EXPECT(2);
2011 }
2012
2013 static void test_VarUI4FromDate(void)
2014 {
2015   CONVVARS(DOUBLE);
2016
2017   CHECKPTR(VarUI4FromDate);
2018   CONVERT(VarUI4FromDate, -1.0);         EXPECT_OVERFLOW;
2019   CONVERT(VarUI4FromDate, 0.0);          EXPECT(0);
2020   CONVERT(VarUI4FromDate, 1.0);          EXPECT(1);
2021   CONVERT(VarUI4FromDate, 4294967295.0); EXPECT(4294967295ul);
2022   CONVERT(VarUI4FromDate, 4294967296.0); EXPECT_OVERFLOW;
2023
2024   CONVERT(VarUI4FromDate, -1.5); EXPECT_OVERFLOW;
2025   CONVERT(VarUI4FromDate, -0.6); EXPECT_OVERFLOW;
2026   CONVERT(VarUI4FromDate, -0.5); EXPECT(0);
2027   CONVERT(VarUI4FromDate, -0.4); EXPECT(0);
2028   CONVERT(VarUI4FromDate, 0.4);  EXPECT(0);
2029   CONVERT(VarUI4FromDate, 0.5);  EXPECT(0);
2030   CONVERT(VarUI4FromDate, 0.6);  EXPECT(1);
2031   CONVERT(VarUI4FromDate, 1.5);  EXPECT(2);
2032 }
2033
2034 static void test_VarUI4FromCy(void)
2035 {
2036   CONVVARS(CY);
2037
2038   CHECKPTR(VarUI4FromCy);
2039   CONVERT_CY(VarUI4FromCy,-1);               EXPECT_OVERFLOW;
2040   CONVERT_CY(VarUI4FromCy,0);                EXPECT(0);
2041   CONVERT_CY(VarUI4FromCy,1);                EXPECT(1);
2042   CONVERT_CY64(VarUI4FromCy,0,4294967295ul); EXPECT(4294967295ul);
2043   CONVERT_CY64(VarUI4FromCy,1,0);            EXPECT_OVERFLOW;
2044
2045   CONVERT_CY(VarUI4FromCy,-1.5); EXPECT_OVERFLOW;
2046   CONVERT_CY(VarUI4FromCy,-0.6); EXPECT_OVERFLOW;
2047   CONVERT_CY(VarUI4FromCy,-0.5); EXPECT(0);
2048   CONVERT_CY(VarUI4FromCy,-0.4); EXPECT(0);
2049   CONVERT_CY(VarUI4FromCy,0.4);  EXPECT(0);
2050   CONVERT_CY(VarUI4FromCy,0.5);  EXPECT(0);
2051   CONVERT_CY(VarUI4FromCy,0.6);  EXPECT(1);
2052   CONVERT_CY(VarUI4FromCy,1.5);  EXPECT(2);
2053 }
2054
2055 static void test_VarUI4FromDec(void)
2056 {
2057   CONVVARS(DECIMAL);
2058
2059   CHECKPTR(VarUI4FromDec);
2060
2061   CONVERT_BADDEC(VarUI4FromDec);
2062
2063   CONVERT_DEC(VarUI4FromDec,0,0x80,0,1);              EXPECT_OVERFLOW;
2064   CONVERT_DEC(VarUI4FromDec,0,0,0,0);                 EXPECT(0);
2065   CONVERT_DEC(VarUI4FromDec,0,0,0,1);                 EXPECT(1);
2066   CONVERT_DEC64(VarUI4FromDec,0,0,0,0,4294967295ul);  EXPECT(4294967295ul);
2067   CONVERT_DEC64(VarUI4FromDec,0,0,0,1,0);             EXPECT_OVERFLOW;
2068
2069   CONVERT_DEC64(VarUI4FromDec,2,0,0,99,4294967196ul); EXPECT(4294967295ul);
2070   CONVERT_DEC64(VarUI4FromDec,2,0,0,100,0);           EXPECT_OVERFLOW;
2071 }
2072
2073 static void test_VarUI4FromStr(void)
2074 {
2075   CONVVARS(LCID);
2076   OLECHAR buff[128];
2077
2078   in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
2079
2080   CHECKPTR(VarUI4FromStr);
2081
2082   CONVERT_STR(VarUI4FromStr,NULL,0);         EXPECT_MISMATCH;
2083   CONVERT_STR(VarUI4FromStr,"-1",0);         EXPECT_OVERFLOW;
2084   CONVERT_STR(VarUI4FromStr,"0",0);          EXPECT(0);
2085   CONVERT_STR(VarUI4FromStr,"4294967295",0); EXPECT(4294967295ul);
2086   CONVERT_STR(VarUI4FromStr,"4294967296",0); EXPECT_OVERFLOW;
2087
2088   /* Rounding */
2089   CONVERT_STR(VarUI4FromStr,"-1.5",0); EXPECT_OVERFLOW;
2090   CONVERT_STR(VarUI4FromStr,"-0.6",0); EXPECT_OVERFLOW;
2091   CONVERT_STR(VarUI4FromStr,"-0.5",0); EXPECT(0);
2092   CONVERT_STR(VarUI4FromStr,"-0.4",0); EXPECT(0);
2093   CONVERT_STR(VarUI4FromStr,"0.4",0);  EXPECT(0);
2094   CONVERT_STR(VarUI4FromStr,"0.5",0);  EXPECT(0);
2095   CONVERT_STR(VarUI4FromStr,"0.6",0);  EXPECT(1);
2096   CONVERT_STR(VarUI4FromStr,"1.5",0);  EXPECT(2);
2097 }
2098
2099 static void test_VarUI4Copy(void)
2100 {
2101   if (!IS_ANCIENT)
2102   {
2103       COPYTEST(1ul, VT_UI4, V_UI4(&vSrc), V_UI4(&vDst), V_UI4REF(&vSrc), V_UI4REF(&vDst), "%lu");
2104   }
2105 }
2106
2107 static void test_VarUI4ChangeTypeEx(void)
2108 {
2109   CONVVARS(CONV_TYPE);
2110   VARIANTARG vSrc, vDst;
2111
2112   in = 1;
2113
2114   if (!IS_ANCIENT)
2115   {
2116     INITIAL_TYPETEST(VT_UI4, V_UI4, "%lu");
2117     COMMON_TYPETEST;
2118     NEGATIVE_TYPETEST(VT_UI4, V_UI4, "%lu", VT_I4, V_I4);
2119   }
2120 }
2121
2122 /*
2123  * VT_I8/VT_UI8
2124  */
2125
2126 #undef CONV_TYPE
2127 #define CONV_TYPE LONG64
2128 #undef EXPECTRES
2129 #define EXPECTRES(res, x) \
2130   ok(hres == S_OK || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
2131      "expected hres " #x ", got hres=0x%08lx\n", hres)
2132
2133 #define EXPECTI8(x) \
2134   ok((hres == S_OK && out == (CONV_TYPE)(x)), \
2135      "expected " #x "(%lu,%lu), got (%lu,%lu); hres=0x%08lx\n", \
2136       (ULONG)((LONG64)(x) >> 32), (ULONG)((x) & 0xffffffff), \
2137       (ULONG)(out >> 32), (ULONG)(out & 0xffffffff), hres)
2138
2139 #define EXPECTI864(x,y) \
2140   ok(hres == S_OK && (out >> 32) == (CONV_TYPE)(x) && (out & 0xffffffff) == (CONV_TYPE)(y), \
2141      "expected " #x "(%lu,%lu), got (%lu,%lu); hres=0x%08lx\n", \
2142       (ULONG)(x), (ULONG)(y), \
2143       (ULONG)(out >> 32), (ULONG)(out & 0xffffffff), hres)
2144
2145 static void test_VarI8FromI1(void)
2146 {
2147   CONVVARS(signed char);
2148   int i;
2149
2150   CHECKPTR(VarI8FromI1);
2151   for (i = -128; i < 128; i++)
2152   {
2153     CONVERT(VarI8FromI1,i); EXPECTI8(i);
2154   }
2155 }
2156
2157 static void test_VarI8FromUI1(void)
2158 {
2159   CONVVARS(BYTE);
2160   int i;
2161
2162   CHECKPTR(VarI8FromUI1);
2163   for (i = 0; i < 256; i++)
2164   {
2165     CONVERT(VarI8FromUI1,i); EXPECTI8(i);
2166   }
2167 }
2168
2169 static void test_VarI8FromI2(void)
2170 {
2171   CONVVARS(SHORT);
2172   int i;
2173
2174   CHECKPTR(VarI8FromI2);
2175   for (i = -32768; i < 32768; i++)
2176   {
2177     CONVERT(VarI8FromI2,i); EXPECTI8(i);
2178   }
2179 }
2180
2181 static void test_VarI8FromUI2(void)
2182 {
2183   CONVVARS(USHORT);
2184   int i;
2185
2186   CHECKPTR(VarI8FromUI2);
2187   for (i = -0; i < 65535; i++)
2188   {
2189     CONVERT(VarI8FromUI2,i); EXPECTI8(i);
2190   }
2191 }
2192
2193 static void test_VarI8FromUI4(void)
2194 {
2195   CONVVARS(ULONG);
2196
2197   CHECKPTR(VarI8FromUI4);
2198   CONVERT(VarI8FromUI4, 0);            EXPECTI8(0);
2199   CONVERT(VarI8FromUI4, 1);            EXPECTI8(1);
2200   CONVERT(VarI8FromUI4, 4294967295ul); EXPECTI8(4294967295ul);
2201 }
2202
2203 static void test_VarI8FromR4(void)
2204 {
2205   CONVVARS(FLOAT);
2206
2207   CHECKPTR(VarI8FromR4);
2208
2209   CONVERT(VarI8FromR4, -128.0f); EXPECTI8(-128);
2210   CONVERT(VarI8FromR4, -1.0f);   EXPECTI8(-1);
2211   CONVERT(VarI8FromR4, 0.0f);    EXPECTI8(0);
2212   CONVERT(VarI8FromR4, 1.0f);    EXPECTI8(1);
2213   CONVERT(VarI8FromR4, 127.0f);  EXPECTI8(127);
2214
2215   CONVERT(VarI8FromR4, -1.5f); EXPECTI8(-2);
2216   CONVERT(VarI8FromR4, -0.6f); EXPECTI8(-1);
2217   CONVERT(VarI8FromR4, -0.5f); EXPECTI8(0);
2218   CONVERT(VarI8FromR4, -0.4f); EXPECTI8(0);
2219   CONVERT(VarI8FromR4, 0.4f);  EXPECTI8(0);
2220   CONVERT(VarI8FromR4, 0.5f);  EXPECTI8(0);
2221   CONVERT(VarI8FromR4, 0.6f);  EXPECTI8(1);
2222   CONVERT(VarI8FromR4, 1.5f);  EXPECTI8(2);
2223 }
2224
2225 static void test_VarI8FromR8(void)
2226 {
2227   CONVVARS(DOUBLE);
2228
2229   CHECKPTR(VarI8FromR8);
2230   CONVERT(VarI8FromR8, -128.0); EXPECTI8(-128);
2231   CONVERT(VarI8FromR8, -1.0);   EXPECTI8(-1);
2232   CONVERT(VarI8FromR8, 0.0);    EXPECTI8(0);
2233   CONVERT(VarI8FromR8, 1.0);    EXPECTI8(1);
2234   CONVERT(VarI8FromR8, 127.0);  EXPECTI8(127);
2235
2236   CONVERT(VarI8FromR8, -1.5); EXPECTI8(-2);
2237   CONVERT(VarI8FromR8, -0.6); EXPECTI8(-1);
2238   CONVERT(VarI8FromR8, -0.5); EXPECTI8(0);
2239   CONVERT(VarI8FromR8, -0.4); EXPECTI8(0);
2240   CONVERT(VarI8FromR8, 0.4);  EXPECTI8(0);
2241   CONVERT(VarI8FromR8, 0.5);  EXPECTI8(0);
2242   CONVERT(VarI8FromR8, 0.6);  EXPECTI8(1);
2243   CONVERT(VarI8FromR8, 1.5);  EXPECTI8(2);
2244 }
2245
2246 static void test_VarI8FromDate(void)
2247 {
2248   CONVVARS(DATE);
2249
2250   CHECKPTR(VarI8FromDate);
2251   CONVERT(VarI8FromDate, -128.0); EXPECTI8(-128);
2252   CONVERT(VarI8FromDate, -1.0);   EXPECTI8(-1);
2253   CONVERT(VarI8FromDate, 0.0);    EXPECTI8(0);
2254   CONVERT(VarI8FromDate, 1.0);    EXPECTI8(1);
2255   CONVERT(VarI8FromDate, 127.0);  EXPECTI8(127);
2256
2257   CONVERT(VarI8FromDate, -1.5); EXPECTI8(-2);
2258   CONVERT(VarI8FromDate, -0.6); EXPECTI8(-1);
2259   CONVERT(VarI8FromDate, -0.5); EXPECTI8(0);
2260   CONVERT(VarI8FromDate, -0.4); EXPECTI8(0);
2261   CONVERT(VarI8FromDate, 0.4);  EXPECTI8(0);
2262   CONVERT(VarI8FromDate, 0.5);  EXPECTI8(0);
2263   CONVERT(VarI8FromDate, 0.6);  EXPECTI8(1);
2264   CONVERT(VarI8FromDate, 1.5);  EXPECTI8(2);
2265 }
2266
2267 static void test_VarI8FromBool(void)
2268 {
2269   CONVVARS(VARIANT_BOOL);
2270   int i;
2271
2272   CHECKPTR(VarI8FromBool);
2273   for (i = -32768; i < 32768; i++)
2274   {
2275     CONVERT(VarI8FromBool,i); EXPECTI8(i);
2276   }
2277 }
2278
2279 static void test_VarI8FromUI8(void)
2280 {
2281   CONVVARS(ULONG64);
2282
2283   CHECKPTR(VarI8FromUI8);
2284   CONVERT(VarI8FromUI8, 0); EXPECTI8(0);
2285   CONVERT(VarI8FromUI8, 1); EXPECTI8(1);
2286   CONVERT_I8(VarI8FromUI8, 0x7fffffff, 0xffffffff); EXPECTI864(0x7fffffff, 0xffffffff);
2287   CONVERT_I8(VarI8FromUI8, 0x80000000, 0);          EXPECT_OVERFLOW;
2288 }
2289
2290 static void test_VarI8FromCy(void)
2291 {
2292   CONVVARS(CY);
2293
2294   CHECKPTR(VarI8FromCy);
2295   CONVERT_CY(VarI8FromCy,-128); EXPECTI8(-129);
2296   CONVERT_CY(VarI8FromCy,-1);   EXPECTI8(-2);
2297   CONVERT_CY(VarI8FromCy,0);    EXPECTI8(0);
2298   CONVERT_CY(VarI8FromCy,1);    EXPECTI8(1);
2299   CONVERT_CY(VarI8FromCy,127);  EXPECTI8(127);
2300
2301   CONVERT_CY(VarI8FromCy,-1.5); EXPECTI8(-2);
2302   CONVERT_CY(VarI8FromCy,-0.6); EXPECTI8(-1);
2303   CONVERT_CY(VarI8FromCy,-0.5); EXPECTI8(-1);
2304   CONVERT_CY(VarI8FromCy,-0.4); EXPECTI8(-1);
2305   CONVERT_CY(VarI8FromCy,0.4);  EXPECTI8(0);
2306   CONVERT_CY(VarI8FromCy,0.5);  EXPECTI8(0);
2307   CONVERT_CY(VarI8FromCy,0.6);  EXPECTI8(1);
2308   CONVERT_CY(VarI8FromCy,1.5);  EXPECTI8(2);
2309 }
2310
2311 static void test_VarI8FromDec(void)
2312 {
2313   CONVVARS(DECIMAL);
2314
2315   CHECKPTR(VarI8FromDec);
2316
2317   CONVERT_BADDEC(VarI8FromDec);
2318
2319   CONVERT_DEC(VarI8FromDec,0,0x80,0,128); EXPECTI8(-128);
2320   CONVERT_DEC(VarI8FromDec,0,0x80,0,1);   EXPECTI8(-1);
2321   CONVERT_DEC(VarI8FromDec,0,0,0,0);      EXPECTI8(0);
2322   CONVERT_DEC(VarI8FromDec,0,0,0,1);      EXPECTI8(1);
2323   CONVERT_DEC(VarI8FromDec,0,0,0,127);    EXPECTI8(127);
2324
2325   CONVERT_DEC(VarI8FromDec,2,0x80,0,12700); EXPECTI8(-127);
2326   CONVERT_DEC(VarI8FromDec,2,0,0,12700);    EXPECTI8(127);
2327 }
2328
2329 static void test_VarI8FromStr(void)
2330 {
2331   CONVVARS(LCID);
2332   OLECHAR buff[128];
2333
2334   in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
2335
2336   CHECKPTR(VarI8FromStr);
2337
2338   CONVERT_STR(VarI8FromStr,NULL,0);         EXPECT_MISMATCH;
2339   CONVERT_STR(VarI8FromStr,"0",0);          EXPECTI8(0);
2340   CONVERT_STR(VarI8FromStr,"-1",0);         EXPECTI8(-1);
2341   CONVERT_STR(VarI8FromStr,"2147483647",0); EXPECTI8(2147483647);
2342
2343   CONVERT_STR(VarI8FromStr,"-1.5",0); EXPECTI8(-2);
2344   CONVERT_STR(VarI8FromStr,"-0.6",0); EXPECTI8(-1);
2345   CONVERT_STR(VarI8FromStr,"-0.5",0); EXPECTI8(0);
2346   CONVERT_STR(VarI8FromStr,"-0.4",0); EXPECTI8(0);
2347   CONVERT_STR(VarI8FromStr,"0.4",0);  EXPECTI8(0);
2348   CONVERT_STR(VarI8FromStr,"0.5",0);  EXPECTI8(0);
2349   CONVERT_STR(VarI8FromStr,"0.6",0);  EXPECTI8(1);
2350   CONVERT_STR(VarI8FromStr,"1.5",0);  EXPECTI8(2);
2351 }
2352
2353 static void test_VarI8Copy(void)
2354 {
2355   HRESULT hres;
2356   VARIANTARG vSrc, vDst;
2357   LONGLONG in = 1;
2358
2359   if (!HAVE_OLEAUT32_I8)
2360     return;
2361
2362   VariantInit(&vSrc);
2363   VariantInit(&vDst);
2364   V_VT(&vSrc) = VT_I8;
2365   V_I8(&vSrc) = in;
2366   hres = VariantCopy(&vDst, &vSrc);
2367   ok(hres == S_OK && V_VT(&vDst) == VT_I8 && V_I8(&vDst) == in,
2368      "copy hres 0x%lX, type %d, value (%x%08x) %x%08x\n",
2369      hres, V_VT(&vDst), (UINT)(in >> 32), (UINT)in, (UINT)(V_I8(&vDst) >> 32), (UINT)V_I8(&vDst) );
2370   V_VT(&vSrc) = VT_I8|VT_BYREF;
2371   V_I8REF(&vSrc) = &in;
2372   hres = VariantCopy(&vDst, &vSrc);
2373   ok(hres == S_OK && V_VT(&vDst) == (VT_I8|VT_BYREF) && V_I8REF(&vDst) == &in,
2374      "ref hres 0x%lX, type %d, ref (%p) %p\n", hres, V_VT(&vDst), &in, V_I8REF(&vDst));
2375   hres = VariantCopyInd(&vDst, &vSrc);
2376   ok(hres == S_OK && V_VT(&vDst) == VT_I8 && V_I8(&vDst) == in,
2377      "copy hres 0x%lX, type %d, value (%x%08x) %x%08x\n",
2378      hres, V_VT(&vDst), (UINT)(in >> 32), (UINT)in, (UINT)(V_I8(&vDst) >> 32), (UINT)V_I8(&vDst) );
2379 }
2380
2381 static void test_VarI8ChangeTypeEx(void)
2382 {
2383   CONVVARS(CONV_TYPE);
2384   VARIANTARG vSrc, vDst;
2385
2386   if (!HAVE_OLEAUT32_I8)
2387     return;
2388
2389   in = 1;
2390
2391   INITIAL_TYPETESTI8(VT_I8, V_I8);
2392   COMMON_TYPETEST;
2393 }
2394
2395 /* Adapt the test macros to UI8 */
2396 #undef CONV_TYPE
2397 #define CONV_TYPE ULONG64
2398
2399 static void test_VarUI8FromI1(void)
2400 {
2401   CONVVARS(signed char);
2402   int i;
2403
2404   CHECKPTR(VarUI8FromI1);
2405   for (i = -128; i < 128; i++)
2406   {
2407     CONVERT(VarUI8FromI1,i);
2408     if (i < 0)
2409       EXPECT_OVERFLOW;
2410     else
2411       EXPECTI8(i);
2412   }
2413 }
2414
2415 static void test_VarUI8FromUI1(void)
2416 {
2417   CONVVARS(BYTE);
2418   int i;
2419
2420   CHECKPTR(VarUI8FromUI1);
2421   for (i = 0; i < 256; i++)
2422   {
2423     CONVERT(VarUI8FromUI1,i); EXPECTI8(i);
2424   }
2425 }
2426
2427 static void test_VarUI8FromI2(void)
2428 {
2429   CONVVARS(SHORT);
2430   int i;
2431
2432   CHECKPTR(VarUI8FromI2);
2433   for (i = -32768; i < 32768; i++)
2434   {
2435     CONVERT(VarUI8FromI2,i);
2436     if (i < 0)
2437       EXPECT_OVERFLOW;
2438     else
2439       EXPECTI8(i);
2440   }
2441 }
2442
2443 static void test_VarUI8FromUI2(void)
2444 {
2445   CONVVARS(USHORT);
2446   int i;
2447
2448   CHECKPTR(VarUI8FromUI2);
2449   for (i = 0; i < 65535; i++)
2450   {
2451     CONVERT(VarUI8FromUI2,i); EXPECTI8(i);
2452   }
2453 }
2454
2455 static void test_VarUI8FromUI4(void)
2456 {
2457   CONVVARS(ULONG);
2458
2459   CHECKPTR(VarUI8FromUI4);
2460   CONVERT(VarUI8FromUI4, 0); EXPECTI8(0);
2461   CONVERT(VarUI8FromUI4, 0xffffffff); EXPECTI8(0xffffffff);
2462 }
2463
2464 static void test_VarUI8FromR4(void)
2465 {
2466   CONVVARS(FLOAT);
2467
2468   CHECKPTR(VarUI8FromR4);
2469   CONVERT(VarUI8FromR4, -1.0f);  EXPECT_OVERFLOW;
2470   CONVERT(VarUI8FromR4, 0.0f);   EXPECTI8(0);
2471   CONVERT(VarUI8FromR4, 1.0f);   EXPECTI8(1);
2472   CONVERT(VarUI8FromR4, 255.0f); EXPECTI8(255);
2473
2474   CONVERT(VarUI8FromR4, -1.5f); EXPECT_OVERFLOW;
2475   CONVERT(VarUI8FromR4, -0.6f); EXPECT_OVERFLOW;
2476   CONVERT(VarUI8FromR4, -0.5f); EXPECTI8(0);
2477   CONVERT(VarUI8FromR4, -0.4f); EXPECTI8(0);
2478   CONVERT(VarUI8FromR4, 0.4f);  EXPECTI8(0);
2479   CONVERT(VarUI8FromR4, 0.5f);  EXPECTI8(0);
2480   CONVERT(VarUI8FromR4, 0.6f);  EXPECTI8(1);
2481   CONVERT(VarUI8FromR4, 1.5f);  EXPECTI8(2);
2482 }
2483
2484 static void test_VarUI8FromR8(void)
2485 {
2486   CONVVARS(DOUBLE);
2487
2488   CHECKPTR(VarUI8FromR8);
2489   CONVERT(VarUI8FromR8, -1.0);  EXPECT_OVERFLOW;
2490   CONVERT(VarUI8FromR8, 0.0);   EXPECTI8(0);
2491   CONVERT(VarUI8FromR8, 1.0);   EXPECTI8(1);
2492   CONVERT(VarUI8FromR8, 255.0); EXPECTI8(255);
2493
2494   CONVERT(VarUI8FromR8, -1.5); EXPECT_OVERFLOW;
2495   CONVERT(VarUI8FromR8, -0.6); EXPECT_OVERFLOW;
2496   CONVERT(VarUI8FromR8, -0.5); EXPECTI8(0);
2497   CONVERT(VarUI8FromR8, -0.4); EXPECTI8(0);
2498   CONVERT(VarUI8FromR8, 0.4);  EXPECTI8(0);
2499   CONVERT(VarUI8FromR8, 0.5);  EXPECTI8(0);
2500   CONVERT(VarUI8FromR8, 0.6);  EXPECTI8(1);
2501   CONVERT(VarUI8FromR8, 1.5);  EXPECTI8(2);
2502 }
2503
2504 static void test_VarUI8FromDate(void)
2505 {
2506   CONVVARS(DATE);
2507
2508   CHECKPTR(VarUI8FromDate);
2509   CONVERT(VarUI8FromDate, -1.0);  EXPECT_OVERFLOW;
2510   CONVERT(VarUI8FromDate, 0.0);   EXPECTI8(0);
2511   CONVERT(VarUI8FromDate, 1.0);   EXPECTI8(1);
2512   CONVERT(VarUI8FromDate, 255.0); EXPECTI8(255);
2513
2514   CONVERT(VarUI8FromDate, -1.5); EXPECT_OVERFLOW;
2515   CONVERT(VarUI8FromDate, -0.6); EXPECT_OVERFLOW;
2516   CONVERT(VarUI8FromDate, -0.5); EXPECTI8(0);
2517   CONVERT(VarUI8FromDate, -0.4); EXPECTI8(0);
2518   CONVERT(VarUI8FromDate, 0.4);  EXPECTI8(0);
2519   CONVERT(VarUI8FromDate, 0.5);  EXPECTI8(0);
2520   CONVERT(VarUI8FromDate, 0.6);  EXPECTI8(1);
2521   CONVERT(VarUI8FromDate, 1.5);  EXPECTI8(2);
2522 }
2523
2524 static void test_VarUI8FromBool(void)
2525 {
2526   CONVVARS(VARIANT_BOOL);
2527   int i;
2528
2529   CHECKPTR(VarUI8FromBool);
2530   CONVERTRANGE(VarUI8FromBool, -32768, 32768);
2531 }
2532
2533 static void test_VarUI8FromI8(void)
2534 {
2535   CONVVARS(LONG64);
2536
2537   CHECKPTR(VarUI8FromI8);
2538   CONVERT(VarUI8FromI8, -1); EXPECT_OVERFLOW;
2539   CONVERT(VarUI8FromI8, 0);  EXPECTI8(0);
2540   CONVERT(VarUI8FromI8, 1);  EXPECTI8(1);
2541 }
2542
2543 static void test_VarUI8FromCy(void)
2544 {
2545   CONVVARS(CY);
2546
2547   CHECKPTR(VarUI8FromCy);
2548   CONVERT_CY(VarUI8FromCy,-1);  EXPECT_OVERFLOW;
2549   CONVERT_CY(VarUI8FromCy,0);   EXPECTI8(0);
2550   CONVERT_CY(VarUI8FromCy,1);   EXPECTI8(1);
2551   CONVERT_CY(VarUI8FromCy,255); EXPECTI8(255);
2552
2553   CONVERT_CY(VarUI8FromCy,-1.5); EXPECT_OVERFLOW;
2554   CONVERT_CY(VarUI8FromCy,-0.6); EXPECT_OVERFLOW;
2555   CONVERT_CY(VarUI8FromCy,-0.5); EXPECTI8(0);
2556   CONVERT_CY(VarUI8FromCy,-0.4); EXPECTI8(0);
2557   CONVERT_CY(VarUI8FromCy,0.4);  EXPECTI8(0);
2558   CONVERT_CY(VarUI8FromCy,0.5);  EXPECTI8(0);
2559   CONVERT_CY(VarUI8FromCy,0.6);  EXPECTI8(1);
2560   CONVERT_CY(VarUI8FromCy,1.5);  EXPECTI8(2);
2561 }
2562
2563 static void test_VarUI8FromDec(void)
2564 {
2565   CONVVARS(DECIMAL);
2566
2567   CHECKPTR(VarUI8FromDec);
2568
2569   CONVERT_BADDEC(VarUI8FromDec);
2570
2571 #if 0
2572   /* This returns 1 under native; Wine fixes this bug and returns overflow */
2573   CONVERT_DEC(VarUI8FromDec,0,0x80,0,1);
2574 #endif
2575   CONVERT_DEC(VarUI8FromDec,0,0,0,0);   EXPECTI8(0);
2576   CONVERT_DEC(VarUI8FromDec,0,0,0,1);   EXPECTI8(1);
2577   CONVERT_DEC(VarUI8FromDec,0,0,0,255); EXPECTI8(255);
2578
2579   CONVERT_DEC(VarUI8FromDec,2,0x80,0,100); EXPECT_OVERFLOW;
2580   CONVERT_DEC(VarUI8FromDec,2,0,0,25500);  EXPECTI8(255);
2581 }
2582
2583 static void test_VarUI8FromStr(void)
2584 {
2585   CONVVARS(LCID);
2586   OLECHAR buff[128];
2587
2588   in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
2589
2590   CHECKPTR(VarUI8FromStr);
2591
2592   CONVERT_STR(VarUI8FromStr,NULL,0);         EXPECT_MISMATCH;
2593   CONVERT_STR(VarUI8FromStr,"0",0);          EXPECTI8(0);
2594   CONVERT_STR(VarUI8FromStr,"-1",0);         EXPECT_OVERFLOW;
2595   CONVERT_STR(VarUI8FromStr,"2147483647",0); EXPECTI8(2147483647);
2596
2597   CONVERT_STR(VarUI8FromStr,"-1.5",0); EXPECT_OVERFLOW;
2598   CONVERT_STR(VarUI8FromStr,"-0.6",0); EXPECT_OVERFLOW;
2599   CONVERT_STR(VarUI8FromStr,"-0.5",0); EXPECTI8(0);
2600   CONVERT_STR(VarUI8FromStr,"-0.4",0); EXPECTI8(0);
2601   CONVERT_STR(VarUI8FromStr,"0.4",0);  EXPECTI8(0);
2602   CONVERT_STR(VarUI8FromStr,"0.5",0);  EXPECTI8(0);
2603   CONVERT_STR(VarUI8FromStr,"0.6",0);  EXPECTI8(1);
2604   CONVERT_STR(VarUI8FromStr,"1.5",0);  EXPECTI8(2);
2605 }
2606
2607 static void test_VarUI8Copy(void)
2608 {
2609   HRESULT hres;
2610   VARIANTARG vSrc, vDst;
2611   ULONGLONG in = 1;
2612
2613   if (!HAVE_OLEAUT32_I8)
2614     return;
2615
2616   VariantInit(&vSrc);
2617   VariantInit(&vDst);
2618   V_VT(&vSrc) = VT_UI8;
2619   V_UI8(&vSrc) = in;
2620   hres = VariantCopy(&vDst, &vSrc);
2621   ok(hres == S_OK && V_VT(&vDst) == VT_UI8 && V_UI8(&vDst) == in,
2622      "copy hres 0x%lX, type %d, value (%x%08x) %x%08x\n",
2623      hres, V_VT(&vDst), (UINT)(in >> 32), (UINT)in, (UINT)(V_UI8(&vDst) >> 32), (UINT)V_UI8(&vDst) );
2624   V_VT(&vSrc) = VT_UI8|VT_BYREF;
2625   V_UI8REF(&vSrc) = &in;
2626   hres = VariantCopy(&vDst, &vSrc);
2627   ok(hres == S_OK && V_VT(&vDst) == (VT_UI8|VT_BYREF) && V_UI8REF(&vDst) == &in,
2628      "ref hres 0x%lX, type %d, ref (%p) %p\n", hres, V_VT(&vDst), &in, V_UI8REF(&vDst));
2629   hres = VariantCopyInd(&vDst, &vSrc);
2630   ok(hres == S_OK && V_VT(&vDst) == VT_UI8 && V_UI8(&vDst) == in,
2631      "copy hres 0x%lX, type %d, value (%x%08x) %x%08x\n",
2632      hres, V_VT(&vDst), (UINT)(in >> 32), (UINT)in, (UINT)(V_UI8(&vDst) >> 32), (UINT)V_UI8(&vDst) );
2633 }
2634
2635 static void test_VarUI8ChangeTypeEx(void)
2636 {
2637   CONVVARS(CONV_TYPE);
2638   VARIANTARG vSrc, vDst;
2639
2640   if (!HAVE_OLEAUT32_I8)
2641     return;
2642
2643   in = 1;
2644
2645   INITIAL_TYPETESTI8(VT_UI8, V_UI8);
2646   COMMON_TYPETEST;
2647 }
2648
2649 /*
2650  * VT_R4
2651  */
2652
2653 #undef CONV_TYPE
2654 #define CONV_TYPE float
2655 #undef EXPECTRES
2656 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%15.15f")
2657
2658 static void test_VarR4FromI1(void)
2659 {
2660   CONVVARS(signed char);
2661   int i;
2662
2663   CHECKPTR(VarR4FromI1);
2664   CONVERTRANGE(VarR4FromI1, -128, 128);
2665 }
2666
2667 static void test_VarR4FromUI1(void)
2668 {
2669   CONVVARS(BYTE);
2670   int i;
2671
2672   CHECKPTR(VarR4FromUI1);
2673   CONVERTRANGE(VarR4FromUI1, 0, 256);
2674 }
2675
2676 static void test_VarR4FromI2(void)
2677 {
2678   CONVVARS(SHORT);
2679   int i;
2680
2681   CHECKPTR(VarR4FromI2);
2682   CONVERTRANGE(VarR4FromI2, -32768, 32768);
2683 }
2684
2685 static void test_VarR4FromUI2(void)
2686 {
2687   CONVVARS(USHORT);
2688   int i;
2689
2690   CHECKPTR(VarR4FromUI2);
2691   CONVERTRANGE(VarR4FromUI2, 0, 65536);
2692 }
2693
2694 static void test_VarR4FromI4(void)
2695 {
2696   CONVVARS(int);
2697
2698   CHECKPTR(VarR4FromI4);
2699   CONVERT(VarR4FromI4, -2147483647-1); EXPECT(-2147483648.0f);
2700   CONVERT(VarR4FromI4, -1);            EXPECT(-1.0f);
2701   CONVERT(VarR4FromI4, 0);             EXPECT(0.0f);
2702   CONVERT(VarR4FromI4, 1);             EXPECT(1.0f);
2703   CONVERT(VarR4FromI4, 2147483647);    EXPECT(2147483647.0f);
2704 }
2705
2706 static void test_VarR4FromUI4(void)
2707 {
2708   CONVVARS(unsigned int);
2709
2710   CHECKPTR(VarR4FromUI4);
2711   CONVERT(VarR4FromUI4, 0);          EXPECT(0.0f);
2712   CONVERT(VarR4FromUI4, 1);          EXPECT(1.0f);
2713 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
2714   CONVERT(VarR4FromUI4, 0xffffffff); EXPECT(4294967296.0f);
2715 #endif
2716 }
2717
2718 static void test_VarR4FromR8(void)
2719 {
2720   CONVVARS(FLOAT);
2721
2722   CHECKPTR(VarR4FromR8);
2723   CONVERT(VarR4FromR8, -1.0); EXPECT(-1.0f);
2724   CONVERT(VarR4FromR8, 0.0); EXPECT(0.0f);
2725   CONVERT(VarR4FromR8, 1.0); EXPECT(1.0f);
2726   CONVERT(VarR4FromR8, 1.5); EXPECT(1.5f);
2727
2728   /* Skip rounding tests - no rounding is done */
2729 }
2730
2731 static void test_VarR4FromBool(void)
2732 {
2733   CONVVARS(VARIANT_BOOL);
2734
2735   CHECKPTR(VarR4FromBool);
2736   CONVERT(VarR4FromBool, VARIANT_TRUE);  EXPECT(VARIANT_TRUE * 1.0f);
2737   CONVERT(VarR4FromBool, VARIANT_FALSE); EXPECT(VARIANT_FALSE * 1.0f);
2738 }
2739
2740 static void test_VarR4FromCy(void)
2741 {
2742   CONVVARS(CY);
2743
2744   CHECKPTR(VarR4FromCy);
2745   CONVERT_CY(VarR4FromCy,-32768); EXPECT(-32768.0f);
2746   CONVERT_CY(VarR4FromCy,-1);     EXPECT(-1.0f);
2747   CONVERT_CY(VarR4FromCy,0);      EXPECT(0.0f);
2748   CONVERT_CY(VarR4FromCy,1);      EXPECT(1.0f);
2749   CONVERT_CY(VarR4FromCy,32768);  EXPECT(32768.0f);
2750
2751   CONVERT_CY(VarR4FromCy,-1.5); EXPECT(-1.5f);
2752   CONVERT_CY(VarR4FromCy,-0.6); EXPECT(-0.6f);
2753   CONVERT_CY(VarR4FromCy,-0.5); EXPECT(-0.5f);
2754   CONVERT_CY(VarR4FromCy,-0.4); EXPECT(-0.4f);
2755   CONVERT_CY(VarR4FromCy,0.4);  EXPECT(0.4f);
2756   CONVERT_CY(VarR4FromCy,0.5);  EXPECT(0.5f);
2757   CONVERT_CY(VarR4FromCy,0.6);  EXPECT(0.6f);
2758   CONVERT_CY(VarR4FromCy,1.5);  EXPECT(1.5f);
2759 }
2760
2761 static void test_VarR4FromI8(void)
2762 {
2763   CONVVARS(LONG64);
2764
2765   CHECKPTR(VarR4FromI8);
2766   CONVERT(VarR4FromI8, -1); EXPECT(-1.0f);
2767   CONVERT(VarR4FromI8, 0);  EXPECT(0.0f);
2768   CONVERT(VarR4FromI8, 1);  EXPECT(1.0f);
2769 }
2770
2771 static void test_VarR4FromUI8(void)
2772 {
2773   CONVVARS(ULONG64);
2774
2775   CHECKPTR(VarR4FromUI8);
2776   CONVERT(VarR4FromUI8, 0); EXPECT(0.0f);
2777   CONVERT(VarR4FromUI8, 1); EXPECT(1.0f);
2778 }
2779
2780 static void test_VarR4FromDec(void)
2781 {
2782   CONVVARS(DECIMAL);
2783
2784   CHECKPTR(VarR4FromDec);
2785
2786   CONVERT_BADDEC(VarR4FromDec);
2787
2788   CONVERT_DEC(VarR4FromDec,0,0x80,0,32768); EXPECT(-32768.0f);
2789   CONVERT_DEC(VarR4FromDec,0,0x80,0,1);     EXPECT(-1.0f);
2790   CONVERT_DEC(VarR4FromDec,0,0,0,0);        EXPECT(0.0f);
2791   CONVERT_DEC(VarR4FromDec,0,0,0,1);        EXPECT(1.0f);
2792   CONVERT_DEC(VarR4FromDec,0,0,0,32767);    EXPECT(32767.0f);
2793
2794   CONVERT_DEC(VarR4FromDec,2,0x80,0,3276800); EXPECT(-32768.0f);
2795   CONVERT_DEC(VarR4FromDec,2,0,0,3276700);    EXPECT(32767.0f);
2796   
2797   CONVERT_DEC(VarR4FromDec,0,0,1,0);        EXPECT(18446744073709551616.0f);
2798 }
2799
2800 static void test_VarR4FromDate(void)
2801 {
2802   CONVVARS(DATE);
2803
2804   CHECKPTR(VarR4FromDate);
2805   CONVERT(VarR4FromDate, -1.0); EXPECT(-1.0f);
2806   CONVERT(VarR4FromDate, 0.0);  EXPECT(0.0f);
2807   CONVERT(VarR4FromDate, 1.0);  EXPECT(1.0f);
2808 }
2809
2810 static void test_VarR4FromStr(void)
2811 {
2812   CONVVARS(LCID);
2813   OLECHAR buff[128];
2814
2815   in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
2816
2817   CHECKPTR(VarR4FromStr);
2818
2819   CONVERT_STR(VarR4FromStr,NULL,0);    EXPECT_MISMATCH;
2820   CONVERT_STR(VarR4FromStr,"-1", 0);   EXPECT(-1.0f);
2821   CONVERT_STR(VarR4FromStr,"0", 0);    EXPECT(0.0f);
2822   CONVERT_STR(VarR4FromStr,"1", 0);    EXPECT(1.0f);
2823
2824   CONVERT_STR(VarR4FromStr,"-1.5",0); EXPECT(-1.5f);
2825   CONVERT_STR(VarR4FromStr,"-0.6",0); EXPECT(-0.6f);
2826   CONVERT_STR(VarR4FromStr,"-0.5",0); EXPECT(-0.5f);
2827   CONVERT_STR(VarR4FromStr,"-0.4",0); EXPECT(-0.4f);
2828   CONVERT_STR(VarR4FromStr,"0.4",0);  EXPECT(0.4f);
2829   CONVERT_STR(VarR4FromStr,"0.5",0);  EXPECT(0.5f);
2830   CONVERT_STR(VarR4FromStr,"0.6",0);  EXPECT(0.6f);
2831   CONVERT_STR(VarR4FromStr,"1.5",0);  EXPECT(1.5f);
2832 }
2833
2834 static void test_VarR4Copy(void)
2835 {
2836   COPYTEST(77665544.0f, VT_R4, V_R4(&vSrc), V_R4(&vDst), V_R4REF(&vSrc),V_R4REF(&vDst), "%15.15f");
2837 }
2838
2839 static void test_VarR4ChangeTypeEx(void)
2840 {
2841 #ifdef HAS_UINT64_TO_FLOAT
2842   CONVVARS(CONV_TYPE);
2843   VARIANTARG vSrc, vDst;
2844
2845   in = 1.0f;
2846
2847   INITIAL_TYPETEST(VT_R4, V_R4, "%f");
2848   COMMON_TYPETEST;
2849 #endif
2850 }
2851
2852 /*
2853  * VT_R8
2854  */
2855
2856 #undef CONV_TYPE
2857 #define CONV_TYPE double
2858 #undef EXPECTRES
2859 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%15.15f")
2860
2861 static void test_VarR8FromI1(void)
2862 {
2863   CONVVARS(signed char);
2864   int i;
2865
2866   CHECKPTR(VarR8FromI1);
2867   CONVERTRANGE(VarR8FromI1, -128, 128);
2868 }
2869
2870 static void test_VarR8FromUI1(void)
2871 {
2872   CONVVARS(BYTE);
2873   int i;
2874
2875   CHECKPTR(VarR8FromUI1);
2876   CONVERTRANGE(VarR8FromUI1, 0, 256);
2877 }
2878
2879 static void test_VarR8FromI2(void)
2880 {
2881   CONVVARS(SHORT);
2882   int i;
2883
2884   CHECKPTR(VarR8FromI2);
2885   CONVERTRANGE(VarR8FromI2, -32768, 32768);
2886 }
2887
2888 static void test_VarR8FromUI2(void)
2889 {
2890   CONVVARS(USHORT);
2891   int i;
2892
2893   CHECKPTR(VarR8FromUI2);
2894   CONVERTRANGE(VarR8FromUI2, 0, 65536);
2895 }
2896
2897 static void test_VarR8FromI4(void)
2898 {
2899   CONVVARS(int);
2900
2901   CHECKPTR(VarR8FromI4);
2902   CONVERT(VarR8FromI4, -2147483647-1); EXPECT(-2147483648.0);
2903   CONVERT(VarR8FromI4, -1);            EXPECT(-1.0);
2904   CONVERT(VarR8FromI4, 0);             EXPECT(0.0);
2905   CONVERT(VarR8FromI4, 1);             EXPECT(1.0);
2906   CONVERT(VarR8FromI4, 0x7fffffff);    EXPECT(2147483647.0);
2907 }
2908
2909 static void test_VarR8FromUI4(void)
2910 {
2911   CONVVARS(unsigned int);
2912
2913   CHECKPTR(VarR8FromUI4);
2914   CONVERT(VarR8FromUI4, 0);          EXPECT(0.0);
2915   CONVERT(VarR8FromUI4, 1);          EXPECT(1.0);
2916   CONVERT(VarR8FromUI4, 0xffffffff); EXPECT(4294967295.0);
2917 }
2918
2919 static void test_VarR8FromR4(void)
2920 {
2921   CONVVARS(FLOAT);
2922
2923   CHECKPTR(VarR8FromR4);
2924   CONVERT(VarR8FromR4, -1.0f); EXPECT(-1.0);
2925   CONVERT(VarR8FromR4, 0.0f);  EXPECT(0.0);
2926   CONVERT(VarR8FromR4, 1.0f);  EXPECT(1.0);
2927   CONVERT(VarR8FromR4, 1.5f);  EXPECT(1.5);
2928
2929   /* Skip rounding tests - no rounding is done */
2930 }
2931
2932 static void test_VarR8FromBool(void)
2933 {
2934   CONVVARS(VARIANT_BOOL);
2935
2936   CHECKPTR(VarR8FromBool);
2937   CONVERT(VarR8FromBool, VARIANT_TRUE);  EXPECT(VARIANT_TRUE * 1.0);
2938   CONVERT(VarR8FromBool, VARIANT_FALSE); EXPECT(VARIANT_FALSE * 1.0);
2939 }
2940
2941 static void test_VarR8FromCy(void)
2942 {
2943   CONVVARS(CY);
2944
2945   CHECKPTR(VarR8FromCy);
2946   CONVERT_CY(VarR8FromCy,-32769); EXPECT(-32769.0);
2947   CONVERT_CY(VarR8FromCy,-32768); EXPECT(-32768.0);
2948   CONVERT_CY(VarR8FromCy,-1);     EXPECT(-1.0);
2949   CONVERT_CY(VarR8FromCy,0);      EXPECT(0.0);
2950   CONVERT_CY(VarR8FromCy,1);      EXPECT(1.0);
2951   CONVERT_CY(VarR8FromCy,32767);  EXPECT(32767.0);
2952   CONVERT_CY(VarR8FromCy,32768);  EXPECT(32768.0);
2953
2954   CONVERT_CY(VarR8FromCy,-1.5); EXPECT(-1.5);
2955   CONVERT_CY(VarR8FromCy,-0.6); EXPECT(-0.6);
2956   CONVERT_CY(VarR8FromCy,-0.5); EXPECT(-0.5);
2957   CONVERT_CY(VarR8FromCy,-0.4); EXPECT(-0.4);
2958   CONVERT_CY(VarR8FromCy,0.4);  EXPECT(0.4);
2959   CONVERT_CY(VarR8FromCy,0.5);  EXPECT(0.5);
2960   CONVERT_CY(VarR8FromCy,0.6);  EXPECT(0.6);
2961   CONVERT_CY(VarR8FromCy,1.5);  EXPECT(1.5);
2962 }
2963
2964 static void test_VarR8FromI8(void)
2965 {
2966   CONVVARS(LONG64);
2967
2968   CHECKPTR(VarR8FromI8);
2969   CONVERT(VarR8FromI8, -1); EXPECT(-1.0);
2970   CONVERT(VarR8FromI8, 0);  EXPECT(0.0);
2971   CONVERT(VarR8FromI8, 1);  EXPECT(1.0);
2972 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
2973   CONVERT_I8(VarR8FromI8, 0x7fffffff,0xffffffff); EXPECT(9223372036854775808.0);
2974 #endif
2975 }
2976
2977 static void test_VarR8FromUI8(void)
2978 {
2979   CONVVARS(ULONG64);
2980
2981   CHECKPTR(VarR8FromUI8);
2982   CONVERT(VarR8FromUI8, 0); EXPECT(0.0);
2983   CONVERT(VarR8FromUI8, 1); EXPECT(1.0);
2984 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
2985   CONVERT_I8(VarR8FromUI8, 0x80000000,0); EXPECT(9223372036854775808.0);
2986 #endif
2987 }
2988
2989 static void test_VarR8FromDec(void)
2990 {
2991   CONVVARS(DECIMAL);
2992
2993   CHECKPTR(VarR8FromDec);
2994
2995   CONVERT_BADDEC(VarR8FromDec);
2996
2997   CONVERT_DEC(VarR8FromDec,0,0x80,0,32768); EXPECT(-32768.0);
2998   CONVERT_DEC(VarR8FromDec,0,0x80,0,1);     EXPECT(-1.0);
2999   CONVERT_DEC(VarR8FromDec,0,0,0,0);        EXPECT(0.0);
3000   CONVERT_DEC(VarR8FromDec,0,0,0,1);        EXPECT(1.0);
3001   CONVERT_DEC(VarR8FromDec,0,0,0,32767);    EXPECT(32767.0);
3002
3003   CONVERT_DEC(VarR8FromDec,2,0x80,0,3276800); EXPECT(-32768.0);
3004   CONVERT_DEC(VarR8FromDec,2,0,0,3276700);    EXPECT(32767.0);
3005
3006   CONVERT_DEC(VarR8FromDec,0,0,1,0);        EXPECT(18446744073709551616.0);
3007 }
3008
3009 static void test_VarR8FromDate(void)
3010 {
3011   CONVVARS(DATE);
3012
3013   CHECKPTR(VarR8FromDate);
3014   CONVERT(VarR8FromDate, -1.0); EXPECT(-1.0);
3015   CONVERT(VarR8FromDate, -0.0); EXPECT(0.0);
3016   CONVERT(VarR8FromDate, 1.0);  EXPECT(1.0);
3017 }
3018
3019 static void test_VarR8FromStr(void)
3020 {
3021   CONVVARS(LCID);
3022   OLECHAR buff[128];
3023
3024   in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3025
3026   CHECKPTR(VarR8FromStr);
3027
3028   CONVERT_STR(VarR8FromStr,NULL,0);   EXPECT_MISMATCH;
3029   CONVERT_STR(VarR8FromStr,"",0);     EXPECT_MISMATCH;
3030   CONVERT_STR(VarR8FromStr," ",0);    EXPECT_MISMATCH;
3031
3032   CONVERT_STR(VarR8FromStr,"0",0);    EXPECT(0.0);
3033   CONVERT_STR(VarR8FromStr,"-1.5",0); EXPECT(-1.5);
3034   CONVERT_STR(VarR8FromStr,"-0.6",0); EXPECT(-0.6);
3035   CONVERT_STR(VarR8FromStr,"-0.5",0); EXPECT(-0.5);
3036   CONVERT_STR(VarR8FromStr,"-0.4",0); EXPECT(-0.4);
3037   CONVERT_STR(VarR8FromStr,"0.4",0);  EXPECT(0.4);
3038   CONVERT_STR(VarR8FromStr,"0.5",0);  EXPECT(0.5);
3039   CONVERT_STR(VarR8FromStr,"0.6",0);  EXPECT(0.6);
3040   CONVERT_STR(VarR8FromStr,"1.5",0);  EXPECT(1.5);
3041
3042   /* We already have exhaustive tests for number parsing, so skip those tests here */
3043 }
3044
3045 static void test_VarR8Copy(void)
3046 {
3047   COPYTEST(77665544.0, VT_R8, V_R8(&vSrc), V_R8(&vDst), V_R8REF(&vSrc),V_R8REF(&vDst), "%16.16g");
3048 }
3049
3050 static void test_VarR8ChangeTypeEx(void)
3051 {
3052 #ifdef HAS_UINT64_TO_FLOAT
3053   CONVVARS(CONV_TYPE);
3054   VARIANTARG vSrc, vDst;
3055
3056   in = 1.0;
3057
3058   INITIAL_TYPETEST(VT_R8, V_R8, "%g");
3059   COMMON_TYPETEST;
3060 #endif
3061 }
3062
3063 #define MATHRND(l, r) left = l; right = r; hres = pVarR8Round(left, right, &out)
3064
3065 static void test_VarR8Round(void)
3066 {
3067   HRESULT hres;
3068   double left = 0.0, out;
3069   int right;
3070
3071   CHECKPTR(VarR8Round);
3072   MATHRND(0.5432, 5);  EXPECT(0.5432);
3073   MATHRND(0.5432, 4);  EXPECT(0.5432);
3074   MATHRND(0.5432, 3);  EXPECT(0.543);
3075   MATHRND(0.5432, 2);  EXPECT(0.54);
3076   MATHRND(0.5432, 1);  EXPECT(0.5);
3077   MATHRND(0.5532, 0);  EXPECT(1);
3078   MATHRND(0.5532, -1); EXPECT_INVALID;
3079
3080   MATHRND(0.5568, 5);  EXPECT(0.5568);
3081   MATHRND(0.5568, 4);  EXPECT(0.5568);
3082   MATHRND(0.5568, 3);  EXPECT(0.557);
3083   MATHRND(0.5568, 2);  EXPECT(0.56);
3084   MATHRND(0.5568, 1);  EXPECT(0.6);
3085   MATHRND(0.5568, 0);  EXPECT(1);
3086   MATHRND(0.5568, -1); EXPECT_INVALID;
3087
3088   MATHRND(0.4999, 0); EXPECT(0);
3089   MATHRND(0.5000, 0); EXPECT(0);
3090   MATHRND(0.5001, 0); EXPECT(1);
3091   MATHRND(1.4999, 0); EXPECT(1);
3092   MATHRND(1.5000, 0); EXPECT(2);
3093   MATHRND(1.5001, 0); EXPECT(2);
3094 }
3095
3096 /*
3097  * VT_DATE
3098  */
3099
3100 #undef CONV_TYPE
3101 #define CONV_TYPE DATE
3102
3103 static void test_VarDateFromI1(void)
3104 {
3105   CONVVARS(signed char);
3106   int i;
3107
3108   CHECKPTR(VarDateFromI1);
3109   CONVERTRANGE(VarDateFromI1, -128, 128);
3110 }
3111
3112 static void test_VarDateFromUI1(void)
3113 {
3114   CONVVARS(BYTE);
3115   int i;
3116
3117   CHECKPTR(VarDateFromUI1);
3118   CONVERTRANGE(VarDateFromUI1, 0, 256);
3119 }
3120
3121 static void test_VarDateFromI2(void)
3122 {
3123   CONVVARS(SHORT);
3124   int i;
3125
3126   CHECKPTR(VarDateFromI2);
3127   CONVERTRANGE(VarDateFromI2, -32768, 32768);
3128 }
3129
3130 static void test_VarDateFromUI2(void)
3131 {
3132   CONVVARS(USHORT);
3133   int i;
3134
3135   CHECKPTR(VarDateFromUI2);
3136   CONVERTRANGE(VarDateFromUI2, 0, 65536);
3137 }
3138
3139 static void test_VarDateFromI4(void)
3140 {
3141   CONVVARS(int);
3142
3143   CHECKPTR(VarDateFromI4);
3144   CONVERT(VarDateFromI4, DATE_MIN-1);
3145   if (hres != DISP_E_TYPEMISMATCH) /* Early versions return this, incorrectly */
3146     EXPECT_OVERFLOW;
3147   CONVERT(VarDateFromI4, DATE_MIN);   EXPECT(DATE_MIN);
3148   CONVERT(VarDateFromI4, -1);         EXPECT(-1.0);
3149   CONVERT(VarDateFromI4, 0);          EXPECT(0.0);
3150   CONVERT(VarDateFromI4, 1);          EXPECT(1.0);
3151   CONVERT(VarDateFromI4, DATE_MAX);   EXPECT(DATE_MAX);
3152   CONVERT(VarDateFromI4, DATE_MAX+1);
3153   if (hres != DISP_E_TYPEMISMATCH) /* Early versions return this, incorrectly */
3154     EXPECT_OVERFLOW;
3155 }
3156
3157 static void test_VarDateFromUI4(void)
3158 {
3159   CONVVARS(unsigned int);
3160
3161   CHECKPTR(VarDateFromUI4);
3162   CONVERT(VarDateFromUI4, 0);          EXPECT(0.0);
3163   CONVERT(VarDateFromUI4, 1);          EXPECT(1.0);
3164   CONVERT(VarDateFromUI4, DATE_MAX);   EXPECT(DATE_MAX);
3165   CONVERT(VarDateFromUI4, DATE_MAX+1);
3166   if (hres != DISP_E_TYPEMISMATCH) /* Early versions return this, incorrectly */
3167     EXPECT_OVERFLOW;
3168 }
3169
3170 static void test_VarDateFromR4(void)
3171 {
3172   CONVVARS(FLOAT);
3173
3174   CHECKPTR(VarDateFromR4);
3175   CONVERT(VarDateFromR4, -1.0f); EXPECT(-1.0);
3176   CONVERT(VarDateFromR4, 0.0f);  EXPECT(0.0);
3177   CONVERT(VarDateFromR4, 1.0f);  EXPECT(1.0);
3178   CONVERT(VarDateFromR4, 1.5f);  EXPECT(1.5);
3179 }
3180
3181 static void test_VarDateFromR8(void)
3182 {
3183   CONVVARS(double);
3184
3185   CHECKPTR(VarDateFromR8);
3186   CONVERT(VarDateFromR8, -1.0f); EXPECT(-1.0);
3187   CONVERT(VarDateFromR8, 0.0f);  EXPECT(0.0);
3188   CONVERT(VarDateFromR8, 1.0f);  EXPECT(1.0);
3189   CONVERT(VarDateFromR8, 1.5f);  EXPECT(1.5);
3190 }
3191
3192 static void test_VarDateFromBool(void)
3193 {
3194   CONVVARS(VARIANT_BOOL);
3195
3196   CHECKPTR(VarDateFromBool);
3197   CONVERT(VarDateFromBool, VARIANT_TRUE);  EXPECT(VARIANT_TRUE * 1.0);
3198   CONVERT(VarDateFromBool, VARIANT_FALSE); EXPECT(VARIANT_FALSE * 1.0);
3199 }
3200
3201 static void test_VarDateFromCy(void)
3202 {
3203   CONVVARS(CY);
3204
3205   CHECKPTR(VarDateFromCy);
3206   CONVERT_CY(VarDateFromCy,-32769); EXPECT(-32769.0);
3207   CONVERT_CY(VarDateFromCy,-32768); EXPECT(-32768.0);
3208   CONVERT_CY(VarDateFromCy,-1);     EXPECT(-1.0);
3209   CONVERT_CY(VarDateFromCy,0);      EXPECT(0.0);
3210   CONVERT_CY(VarDateFromCy,1);      EXPECT(1.0);
3211   CONVERT_CY(VarDateFromCy,32767);  EXPECT(32767.0);
3212   CONVERT_CY(VarDateFromCy,32768);  EXPECT(32768.0);
3213
3214   CONVERT_CY(VarDateFromCy,-1.5); EXPECT(-1.5);
3215   CONVERT_CY(VarDateFromCy,-0.6); EXPECT(-0.6);
3216   CONVERT_CY(VarDateFromCy,-0.5); EXPECT(-0.5);
3217   CONVERT_CY(VarDateFromCy,-0.4); EXPECT(-0.4);
3218   CONVERT_CY(VarDateFromCy,0.4);  EXPECT(0.4);
3219   CONVERT_CY(VarDateFromCy,0.5);  EXPECT(0.5);
3220   CONVERT_CY(VarDateFromCy,0.6);  EXPECT(0.6);
3221   CONVERT_CY(VarDateFromCy,1.5);  EXPECT(1.5);
3222 }
3223
3224 static void test_VarDateFromI8(void)
3225 {
3226   CONVVARS(LONG64);
3227
3228   CHECKPTR(VarDateFromI8);
3229   CONVERT(VarDateFromI8, DATE_MIN-1); EXPECT_OVERFLOW;
3230   CONVERT(VarDateFromI8, DATE_MIN);   EXPECT(DATE_MIN);
3231   CONVERT(VarDateFromI8, -1);         EXPECT(-1.0);
3232   CONVERT(VarDateFromI8, 0);          EXPECT(0.0);
3233   CONVERT(VarDateFromI8, 1);          EXPECT(1.0);
3234   CONVERT(VarDateFromI8, DATE_MAX);   EXPECT(DATE_MAX);
3235   CONVERT(VarDateFromI8, DATE_MAX+1); EXPECT_OVERFLOW;
3236 }
3237
3238 static void test_VarDateFromUI8(void)
3239 {
3240   CONVVARS(ULONG64);
3241
3242   CHECKPTR(VarDateFromUI8);
3243   CONVERT(VarDateFromUI8, 0);          EXPECT(0.0);
3244   CONVERT(VarDateFromUI8, 1);          EXPECT(1.0);
3245   CONVERT(VarDateFromUI8, DATE_MAX);   EXPECT(DATE_MAX);
3246   CONVERT(VarDateFromUI8, DATE_MAX+1); EXPECT_OVERFLOW;
3247 }
3248
3249 static void test_VarDateFromDec(void)
3250 {
3251   CONVVARS(DECIMAL);
3252
3253   CHECKPTR(VarDateFromDec);
3254
3255   CONVERT_BADDEC(VarDateFromDec);
3256
3257   CONVERT_DEC(VarDateFromDec,0,0x80,0,32768); EXPECT(-32768.0);
3258   CONVERT_DEC(VarDateFromDec,0,0x80,0,1);     EXPECT(-1.0);
3259   CONVERT_DEC(VarDateFromDec,0,0,0,0);        EXPECT(0.0);
3260   CONVERT_DEC(VarDateFromDec,0,0,0,1);        EXPECT(1.0);
3261   CONVERT_DEC(VarDateFromDec,0,0,0,32767);    EXPECT(32767.0);
3262
3263   CONVERT_DEC(VarDateFromDec,2,0x80,0,3276800); EXPECT(-32768.0);
3264   CONVERT_DEC(VarDateFromDec,2,0,0,3276700);    EXPECT(32767.0);
3265 }
3266
3267 #define DFS(str) \
3268   buff[0] = '\0'; out = 0.0; \
3269   if (str) MultiByteToWideChar(CP_ACP,0,str,-1,buff,sizeof(buff)/sizeof(WCHAR)); \
3270   hres = pVarDateFromStr(str ? buff : NULL,lcid,LOCALE_NOUSEROVERRIDE,&out)
3271
3272 #define MKRELDATE(day,mth) st.wMonth = mth; st.wDay = day; \
3273   pSystemTimeToVariantTime(&st,&relative)
3274
3275 static const char *BadDateStrings[] =
3276 {
3277   "True", "False", /* Plain text */
3278   "0.", ".0", "-1.1", "1.1-", /* Partial specifications */
3279   "1;2;3", "1*2*3", "1@2@3", "1#2#3", "(1:2)","<1:2>","1|2|3", /* Bad chars */
3280   "0", "1", /* 1 element */
3281   "0.60", "24.00", "0:60", "24:00", "1 2 am", "1 am 2", /* 2 elements */
3282   "1.5 2", "1 5.2", "2 32 3", "1 2 am 3", /* 3 elements */
3283   "1 2.3 4", "1.2.3 4", "1 2.3.4", "1.2 3.4", "1.2.3.4", "1 2 3 4",
3284   "1 am 2 3.4", "1 2 am 3.4", "1.2 3 am 4", "1.2 3 4 am", /* 4 elements */
3285   "1.2.3.4.5", "1.2.3.4 5", "1.2.3 4.5", "1.2 3.4.5", "1.2 3.4 5", "1.2 3 4.5",
3286   "1 2.3.4.5", "1 2.3.4 5", "1 2.3 4.5", "1 2.3 4 5", "1 2 3.4 5", "1 2 3 4 5",
3287   "1.2.3 4 am 5", "1.2.3 4 5 am", "1.2 3 am 4 5",
3288   "1.2 3 4 am 5", "1.2 3 4 5 am", "1 am 2 3.4.5", "1 2 am 3.4.5",
3289   "1 am 2 3 4.5", "1 2 am 3 4.5", "1 2 3 am 4.5", /* 5 elements */
3290   /* 6 elements */
3291   "1.2.3.4.5.6", "1.2.3.4.5 6", "1.2.3.4 5.6", "1.2.3.4 5 6", "1.2.3 4.5.6",
3292   "1.2.3 4.5 6", "1.2.3 4 5.6", "1.2 3.4.5.6", "1.2 3.4.5 6", "1.2 3.4 5.6",
3293   "1.2 3.4 5 6", "1.2 3 4.5.6", "1.2 3 4.5 6", "1.2 3 4 5.6", "1.2 3 4 5 6",
3294   "1 2.3.4.5.6", "1 2.3.4.5 6", "1 2.3.4 5.6", "1 2.3.4 5 6", "1 2.3 4.5.6",
3295 #if 0
3296   /* following throws an exception on winME */
3297   "1 2.3 4.5 6", "1 2.3 4 5.6", "1 2.3 4 5 6", "1 2 3.4.5.6", "1 2 3.4.5 6",
3298 #endif
3299   "1 2 3.4 5.6", "1 2 3.4 5 6", "1 2 3 4.5 6", "1 2 3 4 5.6", "1 2 3 4 5 6",
3300 #if 0
3301   /* following throws an exception on winME */
3302   "1.2.3 4 am 5 6", "1.2.3 4 5 am 6", "1.2.3 4 5 6 am", "1 am 2 3 4.5.6",
3303 #endif
3304   "1 2 am 3 4.5.6", "1 2 3 am 4.5.6"
3305 };
3306
3307 static void test_VarDateFromStr(void)
3308 {
3309   LCID lcid;
3310   DATE out, relative;
3311   HRESULT hres;
3312   SYSTEMTIME st;
3313   OLECHAR buff[128];
3314   size_t i;
3315
3316   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3317
3318   CHECKPTR(VarDateFromStr);
3319   CHECKPTR(SystemTimeToVariantTime);
3320
3321   /* Some date formats are relative, so we need to find the cuurent year */
3322   GetSystemTime(&st);
3323   st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0;
3324   DFS(NULL); EXPECT_MISMATCH;
3325
3326   /* Floating point number are not recognised */
3327   DFS("0.0");
3328   if (hres == S_OK)
3329     EXPECT_DBL(0.0); /* Very old versions accept this string */
3330   else
3331     EXPECT_MISMATCH;
3332
3333   /* 1 element - can only be a time, and only if it has am/pm */
3334   DFS("1 am"); EXPECT_DBL(0.04166666666666666);
3335   /* 2 elements */
3336   /* A decimal point is treated as a time separator.
3337    * The following are converted as hours/minutes.
3338    */
3339   DFS("0.1");  EXPECT_DBL(0.0006944444444444445);
3340   DFS("0.40"); EXPECT_DBL(0.02777777777777778);
3341   DFS("2.5");  EXPECT_DBL(0.08680555555555555);
3342   /* A colon acts as a decimal point */
3343   DFS("0:1");  EXPECT_DBL(0.0006944444444444445);
3344   DFS("0:20"); EXPECT_DBL(0.01388888888888889);
3345   DFS("0:40"); EXPECT_DBL(0.02777777777777778);
3346   DFS("3:5");  EXPECT_DBL(0.1284722222222222);
3347   /* Check the am/pm limits */
3348   DFS("00:00 AM"); EXPECT_DBL(0.0);
3349   DFS("00:00 a");  EXPECT_DBL(0.0);
3350   DFS("12:59 AM"); EXPECT_DBL(0.04097222222222222);
3351   DFS("12:59 A");  EXPECT_DBL(0.04097222222222222);
3352   DFS("00:00 pm"); EXPECT_DBL(0.5);
3353   DFS("00:00 p");  EXPECT_DBL(0.5);
3354   DFS("12:59 pm"); EXPECT_DBL(0.5409722222222222);
3355   DFS("12:59 p");  EXPECT_DBL(0.5409722222222222);
3356   /* AM/PM is ignored if hours > 12 */
3357   DFS("13:00 AM"); EXPECT_DBL(0.5416666666666666);
3358   DFS("13:00 PM"); EXPECT_DBL(0.5416666666666666);
3359
3360   /* Space, dash and slash all indicate a date format. */
3361   /* If both numbers are valid month values => month/day of current year */
3362   DFS("1 2"); MKRELDATE(2,1); EXPECT_DBL(relative);
3363   DFS("2 1"); MKRELDATE(1,2); EXPECT_DBL(relative);
3364   /* one number not valid month, is a valid day, other number valid month:
3365    * that number becomes the day.
3366    */
3367   DFS("14 1");   MKRELDATE(14,1); EXPECT_DBL(relative);
3368   DFS("1 14");   EXPECT_DBL(relative);
3369   /* If the numbers can't be day/month, they are assumed to be year/month */
3370   DFS("30 2");   EXPECT_DBL(10990.0);
3371   DFS("2 30");   EXPECT_DBL(10990.0);
3372   DFS("32 49");  EXPECT_MISMATCH; /* Can't be any format */
3373   DFS("0 49");   EXPECT_MISMATCH; /* Can't be any format */
3374   /* If a month name is given the other number is the day */
3375   DFS("Jan 2");  MKRELDATE(2,1); EXPECT_DBL(relative);
3376   DFS("2 Jan");  EXPECT_DBL(relative);
3377   /* Unless it can't be, in which case it becomes the year */
3378   DFS("Jan 35"); EXPECT_DBL(12785.0);
3379   DFS("35 Jan"); EXPECT_DBL(12785.0);
3380   DFS("Jan-35"); EXPECT_DBL(12785.0);
3381   DFS("35-Jan"); EXPECT_DBL(12785.0);
3382   DFS("Jan/35"); EXPECT_DBL(12785.0);
3383   DFS("35/Jan"); EXPECT_DBL(12785.0);
3384   /* 3 elements */
3385   /* 3 numbers and time separator => h:m:s */
3386   DFS("0.1.0");  EXPECT_DBL(0.0006944444444444445);
3387   DFS("1.5.2");  EXPECT_DBL(0.04516203703703704);
3388   /* 3 numbers => picks date giving preference to lcid format */
3389   DFS("1 2 3");  EXPECT_DBL(37623.0);
3390   DFS("14 2 3"); EXPECT_DBL(41673.0);
3391   DFS("2 14 3"); EXPECT_DBL(37666.0);
3392   DFS("2 3 14"); EXPECT_DBL(41673.0);
3393   DFS("32 2 3"); EXPECT_DBL(11722.0);
3394   DFS("2 3 32"); EXPECT_DBL(11722.0);
3395   DFS("1 2 29"); EXPECT_DBL(47120.0);
3396   /* After 30, two digit dates are expected to be in the 1900's */
3397   DFS("1 2 30"); EXPECT_DBL(10960.0);
3398   DFS("1 2 31"); EXPECT_DBL(11325.0);
3399   DFS("3 am 1 2"); MKRELDATE(2,1); relative += 0.125; EXPECT_DBL(relative);
3400   DFS("1 2 3 am"); EXPECT_DBL(relative);
3401
3402   /* 4 elements -interpreted as 2 digit date & time */
3403   DFS("1.2 3 4");   MKRELDATE(4,3); relative += 0.04305555556; EXPECT_DBL(relative);
3404   DFS("3 4 1.2");   EXPECT_DBL(relative);
3405   /* 5 elements - interpreted as 2 & 3 digit date/times */
3406   DFS("1.2.3 4 5"); MKRELDATE(5,4); relative += 0.04309027778; EXPECT_DBL(relative);
3407   DFS("1.2 3 4 5"); EXPECT_DBL(38415.04305555556);
3408 #if 0
3409   /* following throws an exception on winME */
3410   DFS("1 2 3.4.5"); MKRELDATE(2,1); relative += 0.12783564815; EXPECT_DBL(relative);
3411 #endif
3412   DFS("1 2 3 4.5"); EXPECT_DBL(37623.17013888889);
3413   /* 6 elements - interpreted as 3 digit date/times */
3414   DFS("1.2.3 4 5 6"); EXPECT_DBL(38812.04309027778);
3415   DFS("1 2 3 4.5.6"); EXPECT_DBL(37623.17020833334);
3416
3417   for (i = 0; i < sizeof(BadDateStrings)/sizeof(char*); i++)
3418   {
3419     DFS(BadDateStrings[i]); EXPECT_MISMATCH;
3420   }
3421
3422   /* Some normal-ish strings */
3423   DFS("2 January, 1970"); EXPECT_DBL(25570.0);
3424   DFS("2 January 1970");  EXPECT_DBL(25570.0);
3425   DFS("2 Jan 1970");      EXPECT_DBL(25570.0);
3426   DFS("2/Jan/1970");      EXPECT_DBL(25570.0);
3427   DFS("2-Jan-1970");      EXPECT_DBL(25570.0);
3428   DFS("1 2 1970");        EXPECT_DBL(25570.0);
3429   DFS("1/2/1970");        EXPECT_DBL(25570.0);
3430   DFS("1-2-1970");        EXPECT_DBL(25570.0);
3431   /* Native fails "1999 January 3, 9AM". I consider that a bug in native */
3432 }
3433
3434 static void test_VarDateCopy(void)
3435 {
3436   COPYTEST(77665544.0, VT_DATE, V_DATE(&vSrc), V_DATE(&vDst), V_DATEREF(&vSrc),
3437            V_DATEREF(&vDst), "%16.16g");
3438 }
3439
3440 static const char* wtoascii(LPWSTR lpszIn)
3441 {
3442     static char buff[256];
3443     WideCharToMultiByte(CP_ACP, 0, lpszIn, -1, buff, sizeof(buff), NULL, NULL);
3444     return buff;
3445 }
3446
3447 static void test_VarDateChangeTypeEx(void)
3448 {
3449   static const WCHAR sz25570[] = {
3450     '1','/','2','/','1','9','7','0','\0' };
3451   static const WCHAR sz25570_2[] = {
3452           '1','/','2','/','7','0','\0' };
3453   static const WCHAR sz25570Nls[] = {
3454     '1','/','2','/','1','9','7','0',' ','1','2',':','0','0',':','0','0',' ','A','M','\0' };
3455   CONVVARS(CONV_TYPE);
3456   VARIANTARG vSrc, vDst;
3457   LCID lcid;
3458
3459   in = 1.0;
3460
3461 #ifdef HAS_UINT64_TO_FLOAT
3462   INITIAL_TYPETEST(VT_DATE, V_DATE, "%g");
3463   COMMON_TYPETEST;
3464 #endif
3465
3466   V_VT(&vDst) = VT_EMPTY;
3467   V_VT(&vSrc) = VT_DATE;
3468   V_DATE(&vSrc) = 25570.0;
3469   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3470
3471   hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, VARIANT_NOUSEROVERRIDE, VT_BSTR); 
3472   ok(hres == S_OK && V_VT(&vDst) == VT_BSTR && V_BSTR(&vDst) &&
3473           (!strcmpW(V_BSTR(&vDst), sz25570) || !strcmpW(V_BSTR(&vDst), sz25570_2)),
3474           "hres=0x%lX, type=%d (should be VT_BSTR), *bstr=%s\n", 
3475           hres, V_VT(&vDst), V_BSTR(&vDst) ? wtoascii(V_BSTR(&vDst)) : "?");
3476
3477   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3478   if (HAVE_OLEAUT32_LOCALES)
3479   {
3480     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, VARIANT_NOUSEROVERRIDE|VARIANT_USE_NLS, VT_BSTR);
3481     ok(hres == S_OK && V_VT(&vDst) == VT_BSTR && V_BSTR(&vDst) && !strcmpW(V_BSTR(&vDst), sz25570Nls), 
3482             "hres=0x%lX, type=%d (should be VT_BSTR), *bstr=%s\n", 
3483             hres, V_VT(&vDst), V_BSTR(&vDst) ? wtoascii(V_BSTR(&vDst)) : "?");
3484   }
3485 }
3486
3487 /*
3488  * VT_CY
3489  */
3490
3491 #undef CONV_TYPE
3492 #define CONV_TYPE CY
3493 #undef EXPECTRES
3494 #define EXPECTRES(res, x) \
3495   ok(hres == S_OK || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
3496      "expected hres " #x ", got hres=0x%08lx\n", hres)
3497
3498 #define EXPECTCY(x) \
3499   ok((hres == S_OK && out.int64 == (LONGLONG)(x*CY_MULTIPLIER)), \
3500      "expected " #x "*CY_MULTIPLIER, got (%8lx %8lx); hres=0x%08lx\n", S(out).Hi, S(out).Lo, hres)
3501
3502 #define EXPECTCY64(x,y) \
3503   ok(hres == S_OK && S(out).Hi == (long)x && S(out).Lo == y, \
3504      "expected " #x #y "(%lu,%lu), got (%lu,%lu); hres=0x%08lx\n", \
3505       (ULONG)(x), (ULONG)(y), S(out).Hi, S(out).Lo, hres)
3506
3507 static void test_VarCyFromI1(void)
3508 {
3509   CONVVARS(signed char);
3510   int i;
3511
3512   CHECKPTR(VarCyFromI1);
3513   for (i = -128; i < 128; i++)
3514   {
3515     CONVERT(VarCyFromI1,i); EXPECTCY(i);
3516   }
3517 }
3518
3519 static void test_VarCyFromUI1(void)
3520 {
3521   CONVVARS(BYTE);
3522   int i;
3523
3524   CHECKPTR(VarCyFromUI1);
3525   for (i = 0; i < 256; i++)
3526   {
3527     CONVERT(VarCyFromUI1,i); EXPECTCY(i);
3528   }
3529 }
3530
3531 static void test_VarCyFromI2(void)
3532 {
3533   CONVVARS(SHORT);
3534   int i;
3535
3536   CHECKPTR(VarCyFromI2);
3537   for (i = -16384; i < 16384; i++)
3538   {
3539     CONVERT(VarCyFromI2,i); EXPECTCY(i);
3540   }
3541 }
3542
3543 static void test_VarCyFromUI2(void)
3544 {
3545   CONVVARS(int);
3546   int i;
3547
3548   CHECKPTR(VarCyFromUI2);
3549   for (i = 0; i < 32768; i++)
3550   {
3551     CONVERT(VarCyFromUI2,i); EXPECTCY(i);
3552   }
3553 }
3554
3555 static void test_VarCyFromI4(void)
3556 {
3557   CONVVARS(int);
3558
3559   CHECKPTR(VarCyFromI4);
3560   CONVERT(VarCyFromI4, -1);         EXPECTCY(-1);
3561   CONVERT(VarCyFromI4, 0);          EXPECTCY(0);
3562   CONVERT(VarCyFromI4, 1);          EXPECTCY(1);
3563   CONVERT(VarCyFromI4, 0x7fffffff); EXPECTCY64(0x1387, 0xffffd8f0);
3564   CONVERT(VarCyFromI4, 0x80000000); EXPECTCY64(0xffffec78, 0);
3565 }
3566
3567 static void test_VarCyFromUI4(void)
3568 {
3569   CONVVARS(unsigned int);
3570
3571   CHECKPTR(VarCyFromUI4);
3572   CONVERT(VarCyFromUI4, 0); EXPECTCY(0);
3573   CONVERT(VarCyFromUI4, 1); EXPECTCY(1);
3574   CONVERT(VarCyFromUI4, 0x80000000); EXPECTCY64(5000, 0);
3575 }
3576
3577 static void test_VarCyFromR4(void)
3578 {
3579   CONVVARS(FLOAT);
3580
3581   CHECKPTR(VarCyFromR4);
3582   CONVERT(VarCyFromR4, -1.0f); EXPECTCY(-1);
3583   CONVERT(VarCyFromR4, 0.0f);  EXPECTCY(0);
3584   CONVERT(VarCyFromR4, 1.0f);  EXPECTCY(1);
3585   CONVERT(VarCyFromR4, 1.5f);  EXPECTCY(1.5);
3586
3587   CONVERT(VarCyFromR4, -1.5f);     EXPECTCY(-1.5);
3588   CONVERT(VarCyFromR4, -0.6f);     EXPECTCY(-0.6);
3589   CONVERT(VarCyFromR4, -0.5f);     EXPECTCY(-0.5);
3590   CONVERT(VarCyFromR4, -0.4f);     EXPECTCY(-0.4);
3591   CONVERT(VarCyFromR4, 0.4f);      EXPECTCY(0.4);
3592   CONVERT(VarCyFromR4, 0.5f);      EXPECTCY(0.5);
3593   CONVERT(VarCyFromR4, 0.6f);      EXPECTCY(0.6);
3594   CONVERT(VarCyFromR4, 1.5f);      EXPECTCY(1.5);
3595   CONVERT(VarCyFromR4, 1.00009f);  EXPECTCY(1.0001);
3596   CONVERT(VarCyFromR4, -1.00001f); EXPECTCY(-1);
3597   CONVERT(VarCyFromR4, -1.00005f); EXPECTCY(-1);
3598   CONVERT(VarCyFromR4, -0.00009f); EXPECTCY(-0.0001);
3599   CONVERT(VarCyFromR4, -0.00005f); EXPECTCY(0);
3600   CONVERT(VarCyFromR4, -0.00001f); EXPECTCY(0);
3601   CONVERT(VarCyFromR4, 0.00001f);  EXPECTCY(0);
3602   CONVERT(VarCyFromR4, 0.00005f);  EXPECTCY(0);
3603   CONVERT(VarCyFromR4, 0.00009f);  EXPECTCY(0.0001);
3604   CONVERT(VarCyFromR4, -1.00001f); EXPECTCY(-1);
3605   CONVERT(VarCyFromR4, -1.00005f); EXPECTCY(-1);
3606   CONVERT(VarCyFromR4, -1.00009f); EXPECTCY(-1.0001);
3607 }
3608
3609 static void test_VarCyFromR8(void)
3610 {
3611   CONVVARS(DOUBLE);
3612
3613   CHECKPTR(VarCyFromR8);
3614
3615 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
3616   /* Test our rounding is exactly the same. This fails if the special x86
3617    * code is taken out of VarCyFromR8.
3618    */
3619   CONVERT(VarCyFromR8, -461168601842738.7904); EXPECTCY64(0xbfffffff, 0xffffff23);
3620 #endif
3621
3622   CONVERT(VarCyFromR8, -4611686018427388416.1); EXPECT_OVERFLOW;
3623   CONVERT(VarCyFromR8, -1.0);                   EXPECTCY(-1);
3624   CONVERT(VarCyFromR8, -0.0);                   EXPECTCY(0);
3625   CONVERT(VarCyFromR8, 1.0);                    EXPECTCY(1);
3626   CONVERT(VarCyFromR8, 4611686018427387648.0);  EXPECT_OVERFLOW;
3627
3628   /* Rounding */
3629   CONVERT(VarCyFromR8, -1.5f);     EXPECTCY(-1.5);
3630   CONVERT(VarCyFromR8, -0.6f);     EXPECTCY(-0.6);
3631   CONVERT(VarCyFromR8, -0.5f);     EXPECTCY(-0.5);
3632   CONVERT(VarCyFromR8, -0.4f);     EXPECTCY(-0.4);
3633   CONVERT(VarCyFromR8, 0.4f);      EXPECTCY(0.4);
3634   CONVERT(VarCyFromR8, 0.5f);      EXPECTCY(0.5);
3635   CONVERT(VarCyFromR8, 0.6f);      EXPECTCY(0.6);
3636   CONVERT(VarCyFromR8, 1.5f);      EXPECTCY(1.5);
3637   CONVERT(VarCyFromR8, 1.00009f);  EXPECTCY(1.0001);
3638   CONVERT(VarCyFromR8, -1.00001f); EXPECTCY(-1);
3639   CONVERT(VarCyFromR8, -1.00005f); EXPECTCY(-1);
3640   CONVERT(VarCyFromR8, -0.00009f); EXPECTCY(-0.0001);
3641   CONVERT(VarCyFromR8, -0.00005f); EXPECTCY(0);
3642   CONVERT(VarCyFromR8, -0.00001f); EXPECTCY(0);
3643   CONVERT(VarCyFromR8, 0.00001f);  EXPECTCY(0);
3644   CONVERT(VarCyFromR8, 0.00005f);  EXPECTCY(0);
3645   CONVERT(VarCyFromR8, 0.00009f);  EXPECTCY(0.0001);
3646   CONVERT(VarCyFromR8, -1.00001f); EXPECTCY(-1);
3647   CONVERT(VarCyFromR8, -1.00005f); EXPECTCY(-1);
3648   CONVERT(VarCyFromR8, -1.00009f); EXPECTCY(-1.0001);
3649 }
3650
3651 static void test_VarCyFromBool(void)
3652 {
3653   CONVVARS(VARIANT_BOOL);
3654   int i;
3655
3656   CHECKPTR(VarCyFromBool);
3657   for (i = -32768; i < 32768; i++)
3658   {
3659     CONVERT(VarCyFromBool, i);  EXPECTCY(i);
3660   }
3661 }
3662
3663 static void test_VarCyFromI8(void)
3664 {
3665   CONVVARS(LONG64);
3666
3667   CHECKPTR(VarCyFromI8);
3668   CONVERT_I8(VarCyFromI8, -214749, 2728163227ul);   EXPECT_OVERFLOW;
3669   CONVERT_I8(VarCyFromI8, -214749, 2728163228ul);   EXPECTCY64(2147483648ul,15808);
3670   CONVERT(VarCyFromI8, -1); EXPECTCY(-1);
3671   CONVERT(VarCyFromI8, 0);  EXPECTCY(0);
3672   CONVERT(VarCyFromI8, 1);  EXPECTCY(1);
3673   CONVERT_I8(VarCyFromI8, 214748, 1566804068); EXPECTCY64(2147483647ul, 4294951488ul);
3674   CONVERT_I8(VarCyFromI8, 214748, 1566804069); EXPECT_OVERFLOW;
3675 }
3676
3677 static void test_VarCyFromUI8(void)
3678 {
3679   CONVVARS(ULONG64);
3680
3681   CHECKPTR(VarCyFromUI8);
3682   CONVERT(VarCyFromUI8, 0); EXPECTCY(0);
3683   CONVERT(VarCyFromUI8, 1); EXPECTCY(1);
3684   CONVERT_I8(VarCyFromUI8, 214748, 1566804068); EXPECTCY64(2147483647ul, 4294951488ul);
3685   CONVERT_I8(VarCyFromUI8, 214748, 1566804069); EXPECT_OVERFLOW;
3686 }
3687
3688 static void test_VarCyFromDec(void)
3689 {
3690   CONVVARS(DECIMAL);
3691
3692   CHECKPTR(VarCyFromDec);
3693
3694   CONVERT_BADDEC(VarCyFromDec);
3695
3696   CONVERT_DEC(VarCyFromDec,0,0x80,0,1); EXPECTCY(-1);
3697   CONVERT_DEC(VarCyFromDec,0,0,0,0);    EXPECTCY(0);
3698   CONVERT_DEC(VarCyFromDec,0,0,0,1);    EXPECTCY(1);
3699
3700   CONVERT_DEC64(VarCyFromDec,0,0,0,214748, 1566804068); EXPECTCY64(2147483647ul, 4294951488ul);
3701   CONVERT_DEC64(VarCyFromDec,0,0,0,214748, 1566804069); EXPECT_OVERFLOW;
3702
3703   CONVERT_DEC(VarCyFromDec,2,0,0,100);     EXPECTCY(1);
3704   CONVERT_DEC(VarCyFromDec,2,0x80,0,100);  EXPECTCY(-1);
3705   CONVERT_DEC(VarCyFromDec,2,0x80,0,1);    EXPECTCY(-0.01);
3706   CONVERT_DEC(VarCyFromDec,2,0,0,1);       EXPECTCY(0.01);
3707   CONVERT_DEC(VarCyFromDec,2,0x80,0,1);    EXPECTCY(-0.01);
3708   CONVERT_DEC(VarCyFromDec,2,0,0,999);     EXPECTCY(9.99);
3709   CONVERT_DEC(VarCyFromDec,2,0x80,0,999);  EXPECTCY(-9.99);
3710   CONVERT_DEC(VarCyFromDec,2,0,0,1500);    EXPECTCY(15);
3711   CONVERT_DEC(VarCyFromDec,2,0x80,0,1500); EXPECTCY(-15);
3712 }
3713
3714 static void test_VarCyFromDate(void)
3715 {
3716   CONVVARS(DATE);
3717
3718   CHECKPTR(VarCyFromDate);
3719
3720 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
3721   CONVERT(VarCyFromR8, -461168601842738.7904); EXPECTCY64(0xbfffffff, 0xffffff23);
3722 #endif
3723
3724   CONVERT(VarCyFromDate, -1.0); EXPECTCY(-1);
3725   CONVERT(VarCyFromDate, -0.0); EXPECTCY(0);
3726   CONVERT(VarCyFromDate, 1.0);  EXPECTCY(1);
3727   CONVERT(VarCyFromDate, -4611686018427388416.1); EXPECT_OVERFLOW;
3728   CONVERT(VarCyFromDate, 4611686018427387648.0);  EXPECT_OVERFLOW;
3729
3730   /* Rounding */
3731   CONVERT(VarCyFromDate, -1.5f);     EXPECTCY(-1.5);
3732   CONVERT(VarCyFromDate, -0.6f);     EXPECTCY(-0.6);
3733   CONVERT(VarCyFromDate, -0.5f);     EXPECTCY(-0.5);
3734   CONVERT(VarCyFromDate, -0.4f);     EXPECTCY(-0.4);
3735   CONVERT(VarCyFromDate, 0.4f);      EXPECTCY(0.4);
3736   CONVERT(VarCyFromDate, 0.5f);      EXPECTCY(0.5);
3737   CONVERT(VarCyFromDate, 0.6f);      EXPECTCY(0.6);
3738   CONVERT(VarCyFromDate, 1.5f);      EXPECTCY(1.5);
3739   CONVERT(VarCyFromDate, 1.00009f);  EXPECTCY(1.0001);
3740   CONVERT(VarCyFromDate, -1.00001f); EXPECTCY(-1);
3741   CONVERT(VarCyFromDate, -1.00005f); EXPECTCY(-1);
3742   CONVERT(VarCyFromDate, -0.00009f); EXPECTCY(-0.0001);
3743   CONVERT(VarCyFromDate, -0.00005f); EXPECTCY(0);
3744   CONVERT(VarCyFromDate, -0.00001f); EXPECTCY(0);
3745   CONVERT(VarCyFromDate, 0.00001f);  EXPECTCY(0);
3746   CONVERT(VarCyFromDate, 0.00005f);  EXPECTCY(0);
3747   CONVERT(VarCyFromDate, 0.00009f);  EXPECTCY(0.0001);
3748   CONVERT(VarCyFromDate, -1.00001f); EXPECTCY(-1);
3749   CONVERT(VarCyFromDate, -1.00005f); EXPECTCY(-1);
3750   CONVERT(VarCyFromDate, -1.00009f); EXPECTCY(-1.0001);
3751 }
3752
3753 #define MATHVARS1 HRESULT hres; double left = 0.0; CY cyLeft, out
3754 #define MATHVARS2 MATHVARS1; double right = 0.0; CY cyRight
3755 #define MATH1(func, l) left = (double)l; pVarCyFromR8(left, &cyLeft); hres = p##func(cyLeft, &out)
3756 #define MATH2(func, l, r) left = (double)l; right = (double)r; \
3757   pVarCyFromR8(left, &cyLeft); pVarCyFromR8(right, &cyRight); \
3758   hres = p##func(cyLeft, cyRight, &out)
3759
3760 static void test_VarCyAdd(void)
3761 {
3762   MATHVARS2;
3763
3764   CHECKPTR(VarCyAdd);
3765   MATH2(VarCyAdd, 0.5, 0.5);   EXPECTCY(1);
3766   MATH2(VarCyAdd, 0.5, -0.4);  EXPECTCY(0.1);
3767   MATH2(VarCyAdd, 0.5, -0.6);  EXPECTCY(-0.1);
3768   MATH2(VarCyAdd, -0.5, -0.5); EXPECTCY(-1);
3769   MATH2(VarCyAdd, -922337203685476.0, -922337203685476.0); EXPECT_OVERFLOW;
3770   MATH2(VarCyAdd, -922337203685476.0, 922337203685476.0);  EXPECTCY(0);
3771   MATH2(VarCyAdd, 922337203685476.0, -922337203685476.0);  EXPECTCY(0);
3772   MATH2(VarCyAdd, 922337203685476.0, 922337203685476.0);   EXPECT_OVERFLOW;
3773 }
3774
3775 static void test_VarCyMul(void)
3776 {
3777   MATHVARS2;
3778
3779   CHECKPTR(VarCyMul);
3780   MATH2(VarCyMul, 534443.0, 0.0); EXPECTCY(0);
3781   MATH2(VarCyMul, 0.5, 0.5);      EXPECTCY(0.25);
3782   MATH2(VarCyMul, 0.5, -0.4);     EXPECTCY(-0.2);
3783   MATH2(VarCyMul, 0.5, -0.6);     EXPECTCY(-0.3);
3784   MATH2(VarCyMul, -0.5, -0.5);    EXPECTCY(0.25);
3785   MATH2(VarCyMul, 922337203685476.0, 20000); EXPECT_OVERFLOW;
3786 }
3787
3788 static void test_VarCySub(void)
3789 {
3790   MATHVARS2;
3791
3792   CHECKPTR(VarCySub);
3793   MATH2(VarCySub, 0.5, 0.5);   EXPECTCY(0);
3794   MATH2(VarCySub, 0.5, -0.4);  EXPECTCY(0.9);
3795   MATH2(VarCySub, 0.5, -0.6);  EXPECTCY(1.1);
3796   MATH2(VarCySub, -0.5, -0.5); EXPECTCY(0);
3797   MATH2(VarCySub, -922337203685476.0, -922337203685476.0); EXPECTCY(0);
3798   MATH2(VarCySub, -922337203685476.0, 922337203685476.0);  EXPECT_OVERFLOW;
3799   MATH2(VarCySub, 922337203685476.0, -922337203685476.0);  EXPECT_OVERFLOW;
3800   MATH2(VarCySub, 922337203685476.0, 922337203685476.0);   EXPECTCY(0);
3801 }
3802
3803 static void test_VarCyAbs(void)
3804 {
3805   MATHVARS1;
3806
3807   CHECKPTR(VarCyAbs);
3808   MATH1(VarCyAbs, 0.5);  EXPECTCY(0.5);
3809   MATH1(VarCyAbs, -0.5); EXPECTCY(0.5);
3810   MATH1(VarCyAbs, 922337203685476.0);  EXPECTCY64(2147483647ul,4294951488ul);
3811   MATH1(VarCyAbs, -922337203685476.0); EXPECTCY64(2147483647ul,4294951488ul);
3812 }
3813
3814 static void test_VarCyNeg(void)
3815 {
3816   MATHVARS1;
3817
3818   CHECKPTR(VarCyNeg);
3819   MATH1(VarCyNeg, 0.5); EXPECTCY(-0.5);
3820   MATH1(VarCyNeg, -0.5); EXPECTCY(0.5);
3821   MATH1(VarCyNeg, 922337203685476.0);  EXPECTCY64(2147483648ul,15808);
3822   MATH1(VarCyNeg, -922337203685476.0); EXPECTCY64(2147483647ul,4294951488ul);
3823 }
3824
3825 #define MATHMULI4(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
3826   hres = pVarCyMulI4(cyLeft, right, &out)
3827
3828 static void test_VarCyMulI4(void)
3829 {
3830   MATHVARS1;
3831   LONG right;
3832
3833   CHECKPTR(VarCyMulI4);
3834   MATHMULI4(534443.0, 0); EXPECTCY(0);
3835   MATHMULI4(0.5, 1);      EXPECTCY(0.5);
3836   MATHMULI4(0.5, 2);      EXPECTCY(1);
3837   MATHMULI4(922337203685476.0, 1); EXPECTCY64(2147483647ul,4294951488ul);
3838   MATHMULI4(922337203685476.0, 2); EXPECT_OVERFLOW;
3839 }
3840
3841 #define MATHMULI8(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
3842   hres = pVarCyMulI8(cyLeft, right, &out)
3843
3844 static void test_VarCyMulI8(void)
3845 {
3846   MATHVARS1;
3847   LONG64 right;
3848
3849   CHECKPTR(VarCyMulI8);
3850   MATHMULI8(534443.0, 0); EXPECTCY(0);
3851   MATHMULI8(0.5, 1);      EXPECTCY(0.5);
3852   MATHMULI8(0.5, 2);      EXPECTCY(1);
3853   MATHMULI8(922337203685476.0, 1); EXPECTCY64(2147483647ul,4294951488ul);
3854   MATHMULI8(922337203685476.0, 2); EXPECT_OVERFLOW;
3855 }
3856
3857 #define MATHCMP(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); pVarCyFromR8(right, &cyRight); \
3858   hres = pVarCyCmp(cyLeft, cyRight); out.int64 = hres
3859
3860 static void test_VarCyCmp(void)
3861 {
3862   MATHVARS2;
3863
3864   CHECKPTR(VarCyCmp);
3865   MATHCMP(-1.0, -1.0); EXPECT_EQ;
3866   MATHCMP(-1.0, 0.0);  EXPECT_LT;
3867   MATHCMP(-1.0, 1.0);  EXPECT_LT;
3868   MATHCMP(-1.0, 2.0);  EXPECT_LT;
3869   MATHCMP(0.0, 1.0);   EXPECT_LT;
3870   MATHCMP(0.0, 0.0);   EXPECT_EQ;
3871   MATHCMP(0.0, -1.0);  EXPECT_GT;
3872   MATHCMP(1.0, -1.0);  EXPECT_GT;
3873   MATHCMP(1.0, 0.0);   EXPECT_GT;
3874   MATHCMP(1.0, 1.0);   EXPECT_EQ;
3875   MATHCMP(1.0, 2.0);   EXPECT_LT;
3876 }
3877
3878 #define MATHCMPR8(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
3879   hres = pVarCyCmpR8(cyLeft, right); out.int64 = hres
3880
3881 static void test_VarCyCmpR8(void)
3882 {
3883   MATHVARS1;
3884   double right;
3885
3886   CHECKPTR(VarCyCmpR8);
3887   MATHCMPR8(-1.0, -1.0); EXPECT_EQ;
3888   MATHCMPR8(-1.0, 0.0);  EXPECT_LT;
3889   MATHCMPR8(-1.0, 1.0);  EXPECT_LT;
3890   MATHCMPR8(-1.0, 2.0);  EXPECT_LT;
3891   MATHCMPR8(0.0, 1.0);   EXPECT_LT;
3892   MATHCMPR8(0.0, 0.0);   EXPECT_EQ;
3893   MATHCMPR8(0.0, -1.0);  EXPECT_GT;
3894   MATHCMPR8(1.0, -1.0);  EXPECT_GT;
3895   MATHCMPR8(1.0, 0.0);   EXPECT_GT;
3896   MATHCMPR8(1.0, 1.0);   EXPECT_EQ;
3897   MATHCMPR8(1.0, 2.0);   EXPECT_LT;
3898 }
3899
3900 #undef MATHRND
3901 #define MATHRND(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
3902   hres = pVarCyRound(cyLeft, right, &out)
3903
3904 static void test_VarCyRound(void)
3905 {
3906   MATHVARS1;
3907   int right;
3908
3909   CHECKPTR(VarCyRound);
3910   MATHRND(0.5432, 5);  EXPECTCY(0.5432);
3911   MATHRND(0.5432, 4);  EXPECTCY(0.5432);
3912   MATHRND(0.5432, 3);  EXPECTCY(0.543);
3913   MATHRND(0.5432, 2);  EXPECTCY(0.54);
3914   MATHRND(0.5432, 1);  EXPECTCY(0.5);
3915   MATHRND(0.5532, 0);  EXPECTCY(1);
3916   MATHRND(0.5532, -1); EXPECT_INVALID;
3917
3918   MATHRND(0.5568, 5);  EXPECTCY(0.5568);
3919   MATHRND(0.5568, 4);  EXPECTCY(0.5568);
3920   MATHRND(0.5568, 3);  EXPECTCY(0.557);
3921   MATHRND(0.5568, 2);  EXPECTCY(0.56);
3922   MATHRND(0.5568, 1);  EXPECTCY(0.6);
3923   MATHRND(0.5568, 0);  EXPECTCY(1);
3924   MATHRND(0.5568, -1); EXPECT_INVALID;
3925
3926   MATHRND(0.4999, 0); EXPECTCY(0);
3927   MATHRND(0.5000, 0); EXPECTCY(0);
3928   MATHRND(0.5001, 0); EXPECTCY(1);
3929   MATHRND(1.4999, 0); EXPECTCY(1);
3930   MATHRND(1.5000, 0); EXPECTCY(2);
3931   MATHRND(1.5001, 0); EXPECTCY(2);
3932 }
3933
3934 #define MATHFIX(l) left = l; pVarCyFromR8(left, &cyLeft); \
3935   hres = pVarCyFix(cyLeft, &out)
3936
3937 static void test_VarCyFix(void)
3938 {
3939   MATHVARS1;
3940
3941   CHECKPTR(VarCyFix);
3942   MATHFIX(-1.0001); EXPECTCY(-1);
3943   MATHFIX(-1.4999); EXPECTCY(-1);
3944   MATHFIX(-1.5001); EXPECTCY(-1);
3945   MATHFIX(-1.9999); EXPECTCY(-1);
3946   MATHFIX(-0.0001); EXPECTCY(0);
3947   MATHFIX(-0.4999); EXPECTCY(0);
3948   MATHFIX(-0.5001); EXPECTCY(0);
3949   MATHFIX(-0.9999); EXPECTCY(0);
3950   MATHFIX(0.0001);  EXPECTCY(0);
3951   MATHFIX(0.4999);  EXPECTCY(0);
3952   MATHFIX(0.5001);  EXPECTCY(0);
3953   MATHFIX(0.9999);  EXPECTCY(0);
3954   MATHFIX(1.0001);  EXPECTCY(1);
3955   MATHFIX(1.4999);  EXPECTCY(1);
3956   MATHFIX(1.5001);  EXPECTCY(1);
3957   MATHFIX(1.9999);  EXPECTCY(1);
3958 }
3959
3960 #define MATHINT(l) left = l; pVarCyFromR8(left, &cyLeft); \
3961   hres = pVarCyInt(cyLeft, &out)
3962
3963 static void test_VarCyInt(void)
3964 {
3965   MATHVARS1;
3966
3967   CHECKPTR(VarCyInt);
3968   MATHINT(-1.0001); EXPECTCY(-2);
3969   MATHINT(-1.4999); EXPECTCY(-2);
3970   MATHINT(-1.5001); EXPECTCY(-2);
3971   MATHINT(-1.9999); EXPECTCY(-2);
3972   MATHINT(-0.0001); EXPECTCY(-1);
3973   MATHINT(-0.4999); EXPECTCY(-1);
3974   MATHINT(-0.5001); EXPECTCY(-1);
3975   MATHINT(-0.9999); EXPECTCY(-1);
3976   MATHINT(0.0001);  EXPECTCY(0);
3977   MATHINT(0.4999);  EXPECTCY(0);
3978   MATHINT(0.5001);  EXPECTCY(0);
3979   MATHINT(0.9999);  EXPECTCY(0);
3980   MATHINT(1.0001);  EXPECTCY(1);
3981   MATHINT(1.4999);  EXPECTCY(1);
3982   MATHINT(1.5001);  EXPECTCY(1);
3983   MATHINT(1.9999);  EXPECTCY(1);
3984 }
3985
3986 /*
3987  * VT_DECIMAL
3988  */
3989
3990 #undef CONV_TYPE
3991 #define CONV_TYPE DECIMAL
3992 #undef EXPECTRES
3993 #define EXPECTRES(res, x) \
3994   ok(hres == S_OK || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
3995      "expected hres " #x ", got hres=0x%08lx\n", hres)
3996
3997 #define EXPECTDEC(scl, sgn, hi, lo) ok(hres == S_OK && \
3998   S(U(out)).scale == (BYTE)(scl) && S(U(out)).sign == (BYTE)(sgn) && \
3999   out.Hi32 == (ULONG)(hi) && U1(out).Lo64 == (ULONG64)(lo), \
4000   "expected (%d,%d,%d,(%lx %lx)), got (%d,%d,%ld,(%lx %lx)) hres 0x%08lx\n", \
4001   scl, sgn, hi, (LONG)((LONG64)(lo) >> 32), (LONG)((lo) & 0xffffffff), S(U(out)).scale, \
4002   S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres)
4003
4004 #define EXPECTDEC64(scl, sgn, hi, mid, lo) ok(hres == S_OK && \
4005   S(U(out)).scale == (BYTE)(scl) && S(U(out)).sign == (BYTE)(sgn) && \
4006   out.Hi32 == (ULONG)(hi) && S1(U1(out)).Mid32 == (ULONG)(mid) && \
4007   S1(U1(out)).Lo32 == (ULONG)(lo), \
4008   "expected (%d,%d,%d,(%lx %lx)), got (%d,%d,%ld,(%lx %lx)) hres 0x%08lx\n", \
4009   scl, sgn, hi, (LONG)(mid), (LONG)(lo), S(U(out)).scale, \
4010   S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres)
4011
4012 #define EXPECTDECI if (i < 0) EXPECTDEC(0, 0x80, 0, -i); else EXPECTDEC(0, 0, 0, i)
4013
4014 static void test_VarDecFromI1(void)
4015 {
4016   CONVVARS(signed char);
4017   int i;
4018
4019   CHECKPTR(VarDecFromI1);
4020   for (i = -128; i < 128; i++)
4021   {
4022     CONVERT(VarDecFromI1,i); EXPECTDECI;
4023   }
4024 }
4025
4026 static void test_VarDecFromI2(void)
4027 {
4028   CONVVARS(SHORT);
4029   int i;
4030
4031   CHECKPTR(VarDecFromI2);
4032   for (i = -32768; i < 32768; i++)
4033   {
4034     CONVERT(VarDecFromI2,i); EXPECTDECI;
4035   }
4036 }
4037
4038 static void test_VarDecFromI4(void)
4039 {
4040   CONVVARS(LONG);
4041   int i;
4042
4043   CHECKPTR(VarDecFromI4);
4044   for (i = -32768; i < 32768; i++)
4045   {
4046     CONVERT(VarDecFromI4,i); EXPECTDECI;
4047   }
4048 }
4049
4050 static void test_VarDecFromI8(void)
4051 {
4052   CONVVARS(LONG64);
4053   int i;
4054
4055   CHECKPTR(VarDecFromI8);
4056   for (i = -32768; i < 32768; i++)
4057   {
4058     CONVERT(VarDecFromI8,i); EXPECTDECI;
4059   }
4060 }
4061
4062 static void test_VarDecFromUI1(void)
4063 {
4064   CONVVARS(BYTE);
4065   int i;
4066
4067   CHECKPTR(VarDecFromUI1);
4068   for (i = 0; i < 256; i++)
4069   {
4070     CONVERT(VarDecFromUI1,i); EXPECTDECI;
4071   }
4072 }
4073
4074 static void test_VarDecFromUI2(void)
4075 {
4076   CONVVARS(USHORT);
4077   int i;
4078
4079   CHECKPTR(VarDecFromUI2);
4080   for (i = 0; i < 65536; i++)
4081   {
4082     CONVERT(VarDecFromUI2,i); EXPECTDECI;
4083   }
4084 }
4085
4086 static void test_VarDecFromUI4(void)
4087 {
4088   CONVVARS(ULONG);
4089   int i;
4090
4091   CHECKPTR(VarDecFromUI4);
4092   for (i = 0; i < 65536; i++)
4093   {
4094     CONVERT(VarDecFromUI4,i); EXPECTDECI;
4095   }
4096 }
4097
4098 static void test_VarDecFromUI8(void)
4099 {
4100   CONVVARS(ULONG64);
4101   int i;
4102
4103   CHECKPTR(VarDecFromUI8);
4104   for (i = 0; i < 65536; i++)
4105   {
4106     CONVERT(VarDecFromUI8,i); EXPECTDECI;
4107   }
4108 }
4109
4110 static void test_VarDecFromBool(void)
4111 {
4112   CONVVARS(SHORT);
4113   int i;
4114
4115   CHECKPTR(VarDecFromBool);
4116   /* Test all possible type values. Note that the result is reduced to 0 or -1 */
4117   for (i = -32768; i < 0; i++)
4118   {
4119     CONVERT(VarDecFromBool,i);
4120     if (i)
4121       EXPECTDEC(0,0x80,0,1);
4122     else
4123       EXPECTDEC(0,0,0,0);
4124   }
4125 }
4126
4127 static void test_VarDecFromR4(void)
4128 {
4129   CONVVARS(float);
4130
4131   CHECKPTR(VarDecFromR4);
4132
4133   CONVERT(VarDecFromR4,-0.6f); EXPECTDEC(1,0x80,0,6);
4134   CONVERT(VarDecFromR4,-0.5f); EXPECTDEC(1,0x80,0,5);
4135   CONVERT(VarDecFromR4,-0.4f); EXPECTDEC(1,0x80,0,4);
4136   CONVERT(VarDecFromR4,0.0f);  EXPECTDEC(0,0,0,0);
4137   CONVERT(VarDecFromR4,0.4f);  EXPECTDEC(1,0,0,4);
4138   CONVERT(VarDecFromR4,0.5f);  EXPECTDEC(1,0,0,5);
4139   CONVERT(VarDecFromR4,0.6f);  EXPECTDEC(1,0,0,6);
4140 }
4141
4142 static void test_VarDecFromR8(void)
4143 {
4144   CONVVARS(double);
4145
4146   CHECKPTR(VarDecFromR8);
4147
4148   CONVERT(VarDecFromR8,-0.6); EXPECTDEC(1,0x80,0,6);
4149   CONVERT(VarDecFromR8,-0.5); EXPECTDEC(1,0x80,0,5);
4150   CONVERT(VarDecFromR8,-0.4); EXPECTDEC(1,0x80,0,4);
4151   CONVERT(VarDecFromR8,0.0);  EXPECTDEC(0,0,0,0);
4152   CONVERT(VarDecFromR8,0.4);  EXPECTDEC(1,0,0,4);
4153   CONVERT(VarDecFromR8,0.5);  EXPECTDEC(1,0,0,5);
4154   CONVERT(VarDecFromR8,0.6);  EXPECTDEC(1,0,0,6);
4155 }
4156
4157 static void test_VarDecFromDate(void)
4158 {
4159   CONVVARS(DATE);
4160
4161   CHECKPTR(VarDecFromDate);
4162
4163   CONVERT(VarDecFromDate,-0.6); EXPECTDEC(1,0x80,0,6);
4164   CONVERT(VarDecFromDate,-0.5); EXPECTDEC(1,0x80,0,5);
4165   CONVERT(VarDecFromDate,-0.4); EXPECTDEC(1,0x80,0,4);
4166   CONVERT(VarDecFromDate,0.0);  EXPECTDEC(0,0,0,0);
4167   CONVERT(VarDecFromDate,0.4);  EXPECTDEC(1,0,0,4);
4168   CONVERT(VarDecFromDate,0.5);  EXPECTDEC(1,0,0,5);
4169   CONVERT(VarDecFromDate,0.6);  EXPECTDEC(1,0,0,6);
4170 }
4171
4172 static void test_VarDecFromStr(void)
4173 {
4174   CONVVARS(LCID);
4175   OLECHAR buff[128];
4176
4177   CHECKPTR(VarDecFromStr);
4178
4179   in = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4180
4181   CONVERT_STR(VarDecFromStr,NULL,0);                       EXPECT_MISMATCH;
4182   CONVERT_STR(VarDecFromStr,"-1",  LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0x80,0,1);
4183   CONVERT_STR(VarDecFromStr,"0",   LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,0,0);
4184   CONVERT_STR(VarDecFromStr,"1",   LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,0,1);
4185   CONVERT_STR(VarDecFromStr,"0.5", LOCALE_NOUSEROVERRIDE); EXPECTDEC(1,0,0,5);
4186   CONVERT_STR(VarDecFromStr,"4294967296", LOCALE_NOUSEROVERRIDE); EXPECTDEC64(0,0,0,1,0);
4187   CONVERT_STR(VarDecFromStr,"18446744073709551616", LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,1,0);
4188   CONVERT_STR(VarDecFromStr,"4294967296.0", LOCALE_NOUSEROVERRIDE); EXPECTDEC64(0,0,0,1,0);
4189   CONVERT_STR(VarDecFromStr,"18446744073709551616.0", LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,1,0);
4190 }
4191
4192 static void test_VarDecFromCy(void)
4193 {
4194   CONVVARS(CY);
4195
4196   CHECKPTR(VarDecFromCy);
4197
4198   CONVERT_CY(VarDecFromCy, -1);  EXPECTDEC(4,0x80,0,10000);
4199   CONVERT_CY(VarDecFromCy, 0);   EXPECTDEC(4,0,0,0);
4200   CONVERT_CY(VarDecFromCy, 1);   EXPECTDEC(4,0,0,10000);
4201   CONVERT_CY(VarDecFromCy, 0.5); EXPECTDEC(4,0,0,5000);
4202 }
4203
4204 #undef MATHVARS1
4205 #define MATHVARS1 HRESULT hres; DECIMAL l, out
4206 #undef MATHVARS2
4207 #define MATHVARS2 MATHVARS1; DECIMAL r
4208 #undef MATH1
4209 #define MATH1(func) hres = p##func(&l, &out)
4210 #undef MATH2
4211 #define MATH2(func) hres = p##func(&l, &r, &out)
4212
4213 static void test_VarDecAbs(void)
4214 {
4215   MATHVARS1;
4216
4217   CHECKPTR(VarDecAbs);
4218   SETDEC(l,0,0x80,0,1);  MATH1(VarDecAbs); EXPECTDEC(0,0,0,1);
4219   SETDEC(l,0,0,0,0);     MATH1(VarDecAbs); EXPECTDEC(0,0,0,0);
4220   SETDEC(l,0,0x80,0,0);  MATH1(VarDecAbs); EXPECTDEC(0,0,0,0);
4221   SETDEC(l,0,0,0,1);     MATH1(VarDecAbs); EXPECTDEC(0,0,0,1);
4222
4223   /* Doesn't check for invalid input */
4224   SETDEC(l,0,0x7f,0,1);  MATH1(VarDecAbs); EXPECTDEC(0,0x7f,0,1);
4225   SETDEC(l,0,0x80,29,1); MATH1(VarDecAbs); EXPECTDEC(0,0,29,1);
4226 }
4227
4228 static void test_VarDecNeg(void)
4229 {
4230   MATHVARS1;
4231
4232   CHECKPTR(VarDecNeg);
4233   SETDEC(l,0,0x80,0,1); MATH1(VarDecNeg); EXPECTDEC(0,0,0,1);
4234   SETDEC(l,0,0,0,0);    MATH1(VarDecNeg); EXPECTDEC(0,0x80,0,0); /* '-0'! */
4235   SETDEC(l,0,0x80,0,0); MATH1(VarDecNeg); EXPECTDEC(0,0,0,0);
4236   SETDEC(l,0,0,0,1);    MATH1(VarDecNeg); EXPECTDEC(0,0x80,0,1);
4237
4238   /* Doesn't check for invalid input */
4239   SETDEC(l,0,0x7f,0,1);  MATH1(VarDecNeg); EXPECTDEC(0,0xff,0,1);
4240   SETDEC(l,0,0x80,29,1); MATH1(VarDecNeg); EXPECTDEC(0,0,29,1);
4241   SETDEC(l,0,0,29,1);    MATH1(VarDecNeg); EXPECTDEC(0,0x80,29,1);
4242 }
4243
4244 static void test_VarDecAdd(void)
4245 {
4246   MATHVARS2;
4247
4248   CHECKPTR(VarDecAdd);
4249   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,0);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,0);
4250   SETDEC(l,0,0,0,0);    SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,1);
4251   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4252
4253   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,0);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4254   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,2);
4255   SETDEC(l,0,0,0,1);    SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,0); /* '-0'! */
4256   SETDEC(l,0,0,0,1);    SETDEC(r,0,0x80,0,2); MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,1);
4257
4258   SETDEC(l,0,0x80,0,0); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4259   SETDEC(l,0,0x80,0,1); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,0);
4260   SETDEC(l,0,0x80,0,1); SETDEC(r,0,0,0,2);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4261   SETDEC(l,0,0x80,0,1); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,2);
4262   SETDEC(l,0,0x80,0,2); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,1);
4263
4264   SETDEC(l,0,0,0,0xffffffff); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0,0,0xfffffffe);
4265   SETDEC(l,0,0,0,0xffffffff); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,(ULONG64)1 << 32);
4266   SETDEC(l,0,0,0,0xffffffff); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,(ULONG64)1 << 32);
4267
4268   SETDEC64(l,0,0,0,0xffffffff,0); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC64(0,0,0,0xffffffff,1);
4269   SETDEC64(l,0,0,0,0xffffffff,0); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4270   EXPECTDEC64(0,0,0,0xfffffffe,0xffffffff);
4271
4272   SETDEC64(l,0,0,0,0xffffffff,0xffffffff); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,1,0);
4273   SETDEC64(l,0,0,0,0xffffffff,0xffffffff); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4274   EXPECTDEC64(0,0,0,0xffffffff,0xfffffffe);
4275
4276   SETDEC(l,0,0,0xffffffff,0); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0xffffffff,1);
4277   SETDEC(l,0,0,0xffffffff,0); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4278   EXPECTDEC64(0,0,0xfffffffe,0xffffffff,0xffffffff);
4279
4280   SETDEC64(l,0,0,0xffffffff,0xffffffff,0xffffffff);SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4281   EXPECTDEC64(0,0,0xffffffff,0xffffffff,0xfffffffe);
4282   SETDEC64(l,0,0,0xffffffff,0xffffffff,0xffffffff);SETDEC(r,0,0,0,1); MATH2(VarDecAdd);
4283   ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%ld,(%8lx,%8lx)x) hres 0x%08lx\n",
4284      S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4285
4286   /* Promotes to the highest scale, so here the results are in the scale of 2 */
4287   SETDEC(l,2,0,0,0);   SETDEC(r,0,0,0,0); MATH2(VarDecAdd); EXPECTDEC(2,0,0,0);
4288   SETDEC(l,2,0,0,100); SETDEC(r,0,0,0,1); MATH2(VarDecAdd); EXPECTDEC(2,0,0,200);
4289 }
4290
4291 static void test_VarDecSub(void)
4292 {
4293   MATHVARS2;
4294
4295   CHECKPTR(VarDecSub);
4296   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,0);    MATH2(VarDecSub); EXPECTDEC(0,0x80,0,0);
4297   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,1);    MATH2(VarDecSub); EXPECTDEC(0,0x80,0,1);
4298   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,1);    MATH2(VarDecSub); EXPECTDEC(0,0x80,0,0);
4299   SETDEC(l,0,0,0,1);    SETDEC(r,0,0x80,0,1); MATH2(VarDecSub); EXPECTDEC(0,0,0,2);
4300 }
4301
4302 static void test_VarDecMul(void)
4303 {
4304   MATHVARS2;
4305   
4306   CHECKPTR(VarDecMul);
4307   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,0);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,0);
4308   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,0);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,0);
4309   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,1);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,0);
4310   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,1);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,1);
4311   SETDEC(l,0,0,0,45000);SETDEC(r,0,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,90000);
4312   SETDEC(l,0,0,0,2);    SETDEC(r,0,0,0,45000);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,90000);
4313
4314   SETDEC(l,0,0x80,0,2); SETDEC(r,0,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(0,0x80,0,4);
4315   SETDEC(l,0,0,0,2);    SETDEC(r,0,0x80,0,2);  MATH2(VarDecMul);   EXPECTDEC(0,0x80,0,4);
4316   SETDEC(l,0,0x80,0,2); SETDEC(r,0,0x80,0,2);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,4);
4317
4318   SETDEC(l,4,0,0,2);    SETDEC(r,0,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(4,0,0,4);
4319   SETDEC(l,0,0,0,2);    SETDEC(r,3,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(3,0,0,4);
4320   SETDEC(l,4,0,0,2);    SETDEC(r,3,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(7,0,0,4);
4321   /* this last one shows that native oleaut32 does *not* gratuitously seize opportunities
4322      to reduce the scale if possible - the canonical result for the expected value is (6,0,0,1)
4323    */
4324   SETDEC(l,4,0,0,5);    SETDEC(r,3,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(7,0,0,10);
4325   
4326   SETDEC64(l,0,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC(r,0,0,0,2);  MATH2(VarDecMul);   EXPECTDEC64(0,0,1,0xFFFFFFFF,0xFFFFFFFE);
4327   SETDEC(l,0,0,0,2);    SETDEC64(r,0,0,0,0xFFFFFFFF,0xFFFFFFFF);  MATH2(VarDecMul);   EXPECTDEC64(0,0,1,0xFFFFFFFF,0xFFFFFFFE);
4328   SETDEC(l,0,0,1,1);    SETDEC(r,0,0,0,0x80000000);  MATH2(VarDecMul);   EXPECTDEC(0,0,0x80000000,0x80000000);
4329   SETDEC(l,0,0,0,0x80000000);    SETDEC(r,0,0,1,1);  MATH2(VarDecMul);   EXPECTDEC(0,0,0x80000000,0x80000000);
4330   
4331   /* near-overflow, used as a reference */
4332   SETDEC64(l,0,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC(r,0,0,0,2000000000);  MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4333   /* actual overflow - right operand is 10 times the previous value */
4334   SETDEC64(l,0,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC64(r,0,0,0,4,0xA817C800);  MATH2(VarDecMul);
4335   ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%ld,(%8lx,%8lx)x) hres 0x%08lx\n",
4336      S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4337   /* here, native oleaut32 has an opportunity to avert the overflow, by reducing the scale of the result  */
4338   SETDEC64(l,1,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC64(r,0,0,0,4,0xA817C800);  MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4339
4340   /* near-overflow, used as a reference */
4341   SETDEC64(l,0,0,1,0xFFFFFFFF,0xFFFFFFFE);    SETDEC(r,0,0,0,1000000000);  MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4342   /* actual overflow - right operand is 10 times the previous value */
4343   SETDEC64(l,0,0,1,0xFFFFFFFF,0xFFFFFFFE);    SETDEC64(r,0,0,0,2,0x540BE400);  MATH2(VarDecMul);
4344   ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%ld,(%8lx,%8lx)x) hres 0x%08lx\n",
4345      S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4346   /* here, native oleaut32 has an opportunity to avert the overflow, by reducing the scale of the result  */
4347   SETDEC64(l,1,0,1,0xFFFFFFFF,0xFFFFFFFE);    SETDEC64(r,0,0,0,2,0x540BE400);  MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4348   
4349   /* this one shows that native oleaut32 is willing to lose significant digits in order to avert an overflow */
4350   SETDEC64(l,2,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC64(r,0,0,0,9,0x502F9001);  MATH2(VarDecMul);EXPECTDEC64(1,0,0xee6b2800,0x19999998,0xab2e719a);
4351 }
4352
4353 static void test_VarDecDiv(void)
4354 {
4355   MATHVARS2;
4356   
4357   CHECKPTR(VarDecDiv);
4358   /* identity divisions */
4359   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,1);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,0);
4360   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,1);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,1);
4361   SETDEC(l,1,0,0,1);    SETDEC(r,0,0,0,1);  MATH2(VarDecDiv);   EXPECTDEC(1,0,0,1);
4362
4363   /* exact divisions */  
4364   SETDEC(l,0,0,0,45);    SETDEC(r,0,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,5);
4365   SETDEC(l,1,0,0,45);    SETDEC(r,0,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(1,0,0,5);
4366   SETDEC(l,0,0,0,45);    SETDEC(r,1,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,50);
4367   SETDEC(l,1,0,0,45);    SETDEC(r,2,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,50);
4368   /* these last three results suggest that native oleaut32 scales both operands down to zero
4369      before the division, but does *not* try to scale the result, even if it is possible - 
4370      analogous to multiplication behavior
4371    */
4372   SETDEC(l,1,0,0,45);    SETDEC(r,1,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,5);
4373   SETDEC(l,2,0,0,450);    SETDEC(r,1,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(1,0,0,50);
4374   
4375   /* inexact divisions */
4376   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,180700362,0x14b700cb,0x05555555);
4377   SETDEC(l,1,0,0,1);    SETDEC(r,0,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,18070036,0x35458014,0x4d555555);
4378   SETDEC(l,0,0,0,1);    SETDEC(r,1,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,1807003620,0xcf2607ee,0x35555555);
4379   SETDEC(l,1,0,0,1);    SETDEC(r,2,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,1807003620,0xcf2607ee,0x35555555);
4380   SETDEC(l,1,0,0,1);    SETDEC(r,1,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,180700362,0x14b700cb,0x05555555);
4381   SETDEC(l,2,0,0,10);    SETDEC(r,1,0,0,3);  MATH2(VarDecDiv);  EXPECTDEC64(28,0,180700362,0x14b700cb,0x05555555);
4382
4383   /* this one shows that native oleaut32 rounds up the result */
4384   SETDEC(l,0,0,0,2);    SETDEC(r,0,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,361400724,0x296e0196,0x0aaaaaab);
4385   
4386   /* sign tests */
4387   SETDEC(l,0,0x80,0,45);    SETDEC(r,0,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0x80,0,5);
4388   SETDEC(l,0,0,0,45);       SETDEC(r,0,0x80,0,9);  MATH2(VarDecDiv);EXPECTDEC(0,0x80,0,5);
4389   SETDEC(l,0,0x80,0,45);    SETDEC(r,0,0x80,0,9);  MATH2(VarDecDiv);EXPECTDEC(0,0,0,5);
4390   
4391   /* oddballs */
4392   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,0);  MATH2(VarDecDiv);/* indeterminate */
4393   ok(hres == DISP_E_DIVBYZERO,"Expected division-by-zero, got (%d,%d,%ld,(%8lx,%8lx)x) hres 0x%08lx\n",
4394      S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4395   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,0);  MATH2(VarDecDiv);/* division by zero */
4396   ok(hres == DISP_E_DIVBYZERO,"Expected division-by-zero, got (%d,%d,%ld,(%8lx,%8lx)x) hres 0x%08lx\n",
4397      S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4398   
4399 }
4400
4401 static void test_VarDecCmp(void)
4402 {
4403   MATHVARS1;
4404
4405   CHECKPTR(VarDecCmp);
4406   SETDEC(l,0,0,0,1); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_EQ;
4407   SETDEC(l,0,0,0,1); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_GT;
4408   SETDEC(l,0,0,0,0); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4409 }
4410
4411 /*
4412  * VT_BOOL
4413  */
4414
4415 #undef CONV_TYPE
4416 #define CONV_TYPE VARIANT_BOOL
4417 #undef _EXPECTRES
4418 #define _EXPECTRES(res, x, fs) \
4419   ok((hres == S_OK && out == (CONV_TYPE)(x)) || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
4420      "expected " #x ", got " fs "; hres=0x%08lx\n", out, hres)
4421 #undef EXPECTRES
4422 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%d")
4423 #undef CONVERTRANGE
4424 #define CONVERTRANGE(func,start,end) for (i = start; i < end; i++) { \
4425   CONVERT(func, i); if (i) { EXPECT(VARIANT_TRUE); } else { EXPECT(VARIANT_FALSE); } }
4426
4427 static void test_VarBoolFromI1(void)
4428 {
4429   CONVVARS(signed char);
4430   int i;
4431
4432   CHECKPTR(VarBoolFromI1);
4433   CONVERTRANGE(VarBoolFromI1, -128, 128);
4434 }
4435
4436 static void test_VarBoolFromUI1(void)
4437 {
4438   CONVVARS(BYTE);
4439   int i;
4440
4441   CHECKPTR(VarBoolFromUI1);
4442   CONVERTRANGE(VarBoolFromUI1, 0, 256);
4443 }
4444
4445 static void test_VarBoolFromI2(void)
4446 {
4447   CONVVARS(SHORT);
4448   int i;
4449
4450   CHECKPTR(VarBoolFromI2);
4451   CONVERTRANGE(VarBoolFromI2, -32768, 32768);
4452 }
4453
4454 static void test_VarBoolFromUI2(void)
4455 {
4456   CONVVARS(USHORT);
4457   int i;
4458
4459   CHECKPTR(VarBoolFromUI2);
4460   CONVERTRANGE(VarBoolFromUI2, 0, 65536);
4461 }
4462
4463 static void test_VarBoolFromI4(void)
4464 {
4465   CONVVARS(int);
4466
4467   CHECKPTR(VarBoolFromI4);
4468   CONVERT(VarBoolFromI4, 0x80000000); EXPECT(VARIANT_TRUE);
4469   CONVERT(VarBoolFromI4, -1);         EXPECT(VARIANT_TRUE);
4470   CONVERT(VarBoolFromI4, 0);          EXPECT(VARIANT_FALSE);
4471   CONVERT(VarBoolFromI4, 1);          EXPECT(VARIANT_TRUE);
4472   CONVERT(VarBoolFromI4, 0x7fffffff); EXPECT(VARIANT_TRUE);
4473 }
4474
4475 static void test_VarBoolFromUI4(void)
4476 {
4477   CONVVARS(ULONG);
4478
4479   CHECKPTR(VarBoolFromUI4);
4480   CONVERT(VarBoolFromI4, 0);          EXPECT(VARIANT_FALSE);
4481   CONVERT(VarBoolFromI4, 1);          EXPECT(VARIANT_TRUE);
4482   CONVERT(VarBoolFromI4, 0x80000000); EXPECT(VARIANT_TRUE);
4483 }
4484
4485 static void test_VarBoolFromR4(void)
4486 {
4487   CONVVARS(FLOAT);
4488
4489   CHECKPTR(VarBoolFromR4);
4490   CONVERT(VarBoolFromR4, -1.0f); EXPECT(VARIANT_TRUE);
4491   CONVERT(VarBoolFromR4, 0.0f);  EXPECT(VARIANT_FALSE);
4492   CONVERT(VarBoolFromR4, 1.0f);  EXPECT(VARIANT_TRUE);
4493   CONVERT(VarBoolFromR4, 1.5f);  EXPECT(VARIANT_TRUE);
4494
4495   /* Rounding */
4496   CONVERT(VarBoolFromR4, -1.5f); EXPECT(VARIANT_TRUE);
4497   CONVERT(VarBoolFromR4, -0.6f); EXPECT(VARIANT_TRUE);
4498   CONVERT(VarBoolFromR4, -0.5f); EXPECT(VARIANT_TRUE);
4499   CONVERT(VarBoolFromR4, -0.4f); EXPECT(VARIANT_TRUE);
4500   CONVERT(VarBoolFromR4, 0.4f);  EXPECT(VARIANT_TRUE);
4501   CONVERT(VarBoolFromR4, 0.5f);  EXPECT(VARIANT_TRUE);
4502   CONVERT(VarBoolFromR4, 0.6f);  EXPECT(VARIANT_TRUE);
4503   CONVERT(VarBoolFromR4, 1.5f);  EXPECT(VARIANT_TRUE);
4504 }
4505
4506 static void test_VarBoolFromR8(void)
4507 {
4508   CONVVARS(DOUBLE);
4509
4510   /* Hopefully we made the point with R4 above that rounding is
4511    * irrelevant, so we'll skip that for R8 and Date
4512    */
4513   CHECKPTR(VarBoolFromR8);
4514   CONVERT(VarBoolFromR8, -1.0); EXPECT(VARIANT_TRUE);
4515   CONVERT(VarBoolFromR8, -0.0); EXPECT(VARIANT_FALSE);
4516   CONVERT(VarBoolFromR8, 1.0);  EXPECT(VARIANT_TRUE);
4517 }
4518
4519 static void test_VarBoolFromCy(void)
4520 {
4521   CONVVARS(CY);
4522
4523   CHECKPTR(VarBoolFromCy);
4524   CONVERT_CY(VarBoolFromCy, -32769); EXPECT(VARIANT_TRUE);
4525   CONVERT_CY(VarBoolFromCy, -32768); EXPECT(VARIANT_TRUE);
4526   CONVERT_CY(VarBoolFromCy, -1);     EXPECT(VARIANT_TRUE);
4527   CONVERT_CY(VarBoolFromCy, 0);      EXPECT(VARIANT_FALSE);
4528   CONVERT_CY(VarBoolFromCy, 1);      EXPECT(VARIANT_TRUE);
4529   CONVERT_CY(VarBoolFromCy, 32767);  EXPECT(VARIANT_TRUE);
4530   CONVERT_CY(VarBoolFromCy, 32768);  EXPECT(VARIANT_TRUE);
4531 }
4532
4533 static void test_VarBoolFromI8(void)
4534 {
4535   CONVVARS(LONG64);
4536
4537   CHECKPTR(VarBoolFromI8);
4538   CONVERT(VarBoolFromI8, -1); EXPECT(VARIANT_TRUE);
4539   CONVERT(VarBoolFromI8, 0);  EXPECT(VARIANT_FALSE);
4540   CONVERT(VarBoolFromI8, 1);  EXPECT(VARIANT_TRUE);
4541 }
4542
4543 static void test_VarBoolFromUI8(void)
4544 {
4545   CONVVARS(ULONG64);
4546
4547   CHECKPTR(VarBoolFromUI8);
4548   CONVERT(VarBoolFromUI8, 0); EXPECT(VARIANT_FALSE);
4549   CONVERT(VarBoolFromUI8, 1); EXPECT(VARIANT_TRUE);
4550 }
4551
4552 static void test_VarBoolFromDec(void)
4553 {
4554   CONVVARS(DECIMAL);
4555
4556   CHECKPTR(VarBoolFromDec);
4557   CONVERT_BADDEC(VarBoolFromDec);
4558
4559   if (HAVE_OLEAUT32_DECIMAL)
4560   {
4561     /* Early versions of oleaut32 don't catch these errors */
4562     CONVERT_DEC(VarBoolFromDec,29,0,0,0);   EXPECT_INVALID;
4563     CONVERT_DEC(VarBoolFromDec,0,0x1,0,0);  EXPECT_INVALID;
4564     CONVERT_DEC(VarBoolFromDec,0,0x40,0,0); EXPECT_INVALID;
4565     CONVERT_DEC(VarBoolFromDec,0,0x7f,0,0); EXPECT_INVALID;
4566   }
4567
4568   CONVERT_DEC(VarBoolFromDec,0,0x80,0,1); EXPECT(VARIANT_TRUE);
4569   CONVERT_DEC(VarBoolFromDec,0,0,0,0);    EXPECT(VARIANT_FALSE);
4570   CONVERT_DEC(VarBoolFromDec,0,0,0,1);    EXPECT(VARIANT_TRUE);
4571   CONVERT_DEC(VarBoolFromDec,0,0,1,0);    EXPECT(VARIANT_TRUE);
4572
4573   CONVERT_DEC(VarBoolFromDec,2,0,0,CY_MULTIPLIER);    EXPECT(VARIANT_TRUE);
4574   CONVERT_DEC(VarBoolFromDec,2,0x80,0,CY_MULTIPLIER); EXPECT(VARIANT_TRUE);
4575 }
4576
4577 static void test_VarBoolFromDate(void)
4578 {
4579   CONVVARS(DATE);
4580
4581   CHECKPTR(VarBoolFromDate);
4582   CONVERT(VarBoolFromDate, -1.0); EXPECT(VARIANT_TRUE);
4583   CONVERT(VarBoolFromDate, -0.0); EXPECT(VARIANT_FALSE);
4584   CONVERT(VarBoolFromDate, 1.0);  EXPECT(VARIANT_TRUE);
4585 }
4586
4587 static void test_VarBoolFromStr(void)
4588 {
4589   CONVVARS(LCID);
4590   OLECHAR buff[128];
4591
4592   CHECKPTR(VarBoolFromStr);
4593
4594   in = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4595
4596   CONVERT_STR(VarBoolFromStr,NULL,0);
4597   if (hres != E_INVALIDARG)
4598     EXPECT_MISMATCH;
4599
4600   /* #FALSE# and #TRUE# Are always accepted */
4601   CONVERT_STR(VarBoolFromStr,"#FALSE#",0); EXPECT(VARIANT_FALSE);
4602   CONVERT_STR(VarBoolFromStr,"#TRUE#",0);  EXPECT(VARIANT_TRUE);
4603
4604   /* Match of #FALSE# and #TRUE# is case sensitive */
4605   CONVERT_STR(VarBoolFromStr,"#False#",0); EXPECT_MISMATCH;
4606   /* But match against English is not */
4607   CONVERT_STR(VarBoolFromStr,"false",0);   EXPECT(VARIANT_FALSE);
4608   CONVERT_STR(VarBoolFromStr,"False",0);   EXPECT(VARIANT_FALSE);
4609   /* On/Off and yes/no are not acceptable inputs, with any flags set */
4610   CONVERT_STR(VarBoolFromStr,"On",0xffffffff);  EXPECT_MISMATCH;
4611   CONVERT_STR(VarBoolFromStr,"Yes",0xffffffff); EXPECT_MISMATCH;
4612
4613   /* Change the LCID. This doesn't make any difference for text,unless we ask
4614    * to check local boolean text with the VARIANT_LOCALBOOL flag. */
4615   in = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT);
4616
4617   /* #FALSE# and #TRUE# are accepted in all locales */
4618   CONVERT_STR(VarBoolFromStr,"#FALSE#",0); EXPECT(VARIANT_FALSE);
4619   CONVERT_STR(VarBoolFromStr,"#TRUE#",0);  EXPECT(VARIANT_TRUE);
4620   CONVERT_STR(VarBoolFromStr,"#FALSE#",VARIANT_LOCALBOOL); EXPECT(VARIANT_FALSE);
4621   CONVERT_STR(VarBoolFromStr,"#TRUE#",VARIANT_LOCALBOOL);  EXPECT(VARIANT_TRUE);
4622
4623   /* English is accepted regardless of the locale */
4624   CONVERT_STR(VarBoolFromStr,"false",0); EXPECT(VARIANT_FALSE);
4625   /* And is still not case sensitive */
4626   CONVERT_STR(VarBoolFromStr,"False",0); EXPECT(VARIANT_FALSE);
4627
4628   if (HAVE_OLEAUT32_LOCALES)
4629   {
4630     /* French is rejected without VARIANT_LOCALBOOL */
4631     CONVERT_STR(VarBoolFromStr,"faux",0); EXPECT_MISMATCH;
4632     /* But accepted if this flag is given */
4633     CONVERT_STR(VarBoolFromStr,"faux",VARIANT_LOCALBOOL); EXPECT(VARIANT_FALSE);
4634     /* Regardless of case - from this we assume locale text comparisons ignore case */
4635     CONVERT_STR(VarBoolFromStr,"Faux",VARIANT_LOCALBOOL); EXPECT(VARIANT_FALSE);
4636
4637     /* Changing the locale prevents the localised text from being compared -
4638      * this demonstrates that only the indicated LCID and English are searched */
4639     in = MAKELCID(MAKELANGID(LANG_POLISH, SUBLANG_DEFAULT), SORT_DEFAULT);
4640     CONVERT_STR(VarBoolFromStr,"faux",VARIANT_LOCALBOOL); EXPECT_MISMATCH;
4641   }
4642
4643   /* Numeric strings are read as 0 or non-0 */
4644   CONVERT_STR(VarBoolFromStr,"0",0);  EXPECT(VARIANT_FALSE);
4645   CONVERT_STR(VarBoolFromStr,"-1",0); EXPECT(VARIANT_TRUE);
4646   CONVERT_STR(VarBoolFromStr,"+1",0); EXPECT(VARIANT_TRUE);
4647
4648   if (HAVE_OLEAUT32_LOCALES)
4649   {
4650     /* Numeric strings are read as floating point numbers. The line below fails
4651      * because '.' is not a valid decimal separator for Polish numbers */
4652     CONVERT_STR(VarBoolFromStr,"0.1",0); EXPECT_MISMATCH;
4653   }
4654
4655   /* Changing the lcid back to US English reads the r8 correctly */
4656   in = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4657   CONVERT_STR(VarBoolFromStr,"0.1",0); EXPECT(VARIANT_TRUE);
4658 }
4659
4660 static void test_VarBoolCopy(void)
4661 {
4662   COPYTEST(1, VT_BOOL, V_BOOL(&vSrc), V_BOOL(&vDst), V_BOOLREF(&vSrc), V_BOOLREF(&vDst), "%d");
4663 }
4664
4665 #define BOOL_STR(flags, str) hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, flags, VT_BSTR); \
4666   ok(hres == S_OK && V_VT(&vDst) == VT_BSTR && \
4667      V_BSTR(&vDst) && !memcmp(V_BSTR(&vDst), str, sizeof(str)), \
4668      "hres=0x%lX, type=%d (should be VT_BSTR), *bstr='%c'\n", \
4669      hres, V_VT(&vDst), V_BSTR(&vDst) ? *V_BSTR(&vDst) : '?')
4670
4671 static void test_VarBoolChangeTypeEx(void)
4672 {
4673   static const WCHAR szTrue[] = { 'T','r','u','e','\0' };
4674   static const WCHAR szFalse[] = { 'F','a','l','s','e','\0' };
4675   static const WCHAR szFaux[] = { 'F','a','u','x','\0' };
4676   CONVVARS(CONV_TYPE);
4677   VARIANTARG vSrc, vDst;
4678   LCID lcid;
4679
4680   in = 1;
4681
4682   INITIAL_TYPETEST(VT_BOOL, V_BOOL, "%d");
4683   COMMON_TYPETEST;
4684
4685   /* The common tests convert to a number. Try the different flags */
4686   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4687
4688   V_VT(&vSrc) = VT_BOOL;
4689   V_BOOL(&vSrc) = 1;
4690
4691   if (!IS_ANCIENT)
4692   {
4693       BOOL_STR(VARIANT_ALPHABOOL, szTrue);
4694       V_BOOL(&vSrc) = 0;
4695       BOOL_STR(VARIANT_ALPHABOOL, szFalse);
4696   }
4697
4698   if (HAVE_OLEAUT32_LOCALES)
4699   {
4700     lcid = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT);
4701
4702     /* VARIANT_ALPHABOOL is always English */
4703     BOOL_STR(VARIANT_ALPHABOOL, szFalse);
4704     /* VARIANT_LOCALBOOL uses the localised text */
4705     BOOL_STR(VARIANT_LOCALBOOL, szFaux);
4706     /* Both flags together acts as VARIANT_LOCALBOOL */
4707     BOOL_STR(VARIANT_ALPHABOOL|VARIANT_LOCALBOOL, szFaux);
4708   }
4709 }
4710
4711 /*
4712  * BSTR
4713  */
4714
4715 static void test_VarBstrFromR4(void)
4716 {
4717   static const WCHAR szNative[] = { '6','5','4','3','2','2','.','3','\0' };
4718   static const WCHAR szZero[] = {'0', '\0'};
4719   static const WCHAR szOneHalf_English[] = { '0','.','5','\0' };    /* uses period */
4720   static const WCHAR szOneHalf_Spanish[] = { '0',',','5','\0' };    /* uses comma */
4721   LCID lcid;
4722   LCID lcid_spanish;
4723   HRESULT hres;
4724   BSTR bstr = NULL;
4725
4726   float f;
4727
4728   CHECKPTR(VarBstrFromR4);
4729
4730   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4731   lcid_spanish = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), SORT_DEFAULT);
4732   f = 654322.23456f;
4733   hres = pVarBstrFromR4(f, lcid, 0, &bstr);
4734   ok(hres == S_OK, "got hres 0x%08lx\n", hres);
4735   if (bstr)
4736   {
4737     todo_wine {
4738     /* MSDN states that rounding of R4/R8 is dependent on the underlying
4739      * bit pattern of the number and so is architecture dependent. In this
4740      * case Wine returns .2 (which is more correct) and Native returns .3
4741      */
4742     ok(memcmp(bstr, szNative, sizeof(szNative)) == 0, "string different\n");
4743     }
4744   }
4745
4746   f = -1e-400;    /* deliberately cause underflow */
4747   hres = pVarBstrFromR4(f, lcid, 0, &bstr);
4748   ok(hres == S_OK, "got hres 0x%08lx\n", hres);
4749   if (bstr)
4750   {
4751     ok(memcmp(bstr, szZero, sizeof(szZero)) == 0, "negative zero (got %s)\n", wtoascii(bstr));
4752   }
4753   
4754   /* The following tests that lcid is used for decimal separator even without LOCALE_USE_NLS */
4755   f = 0.5;
4756   hres = pVarBstrFromR4(f, lcid, 0, &bstr);
4757   ok(hres == S_OK, "got hres 0x%08lx\n", hres);
4758   if (bstr)
4759   {
4760     ok(memcmp(bstr, szOneHalf_English, sizeof(szOneHalf_English)) == 0, "English locale failed (got %s)\n", wtoascii(bstr));
4761   }
4762   f = 0.5;
4763   hres = pVarBstrFromR4(f, lcid_spanish, 0, &bstr);
4764   ok(hres == S_OK, "got hres 0x%08lx\n", hres);
4765   if (bstr)
4766   {
4767     ok(memcmp(bstr, szOneHalf_Spanish, sizeof(szOneHalf_Spanish)) == 0, "Spanish locale failed (got %s)\n", wtoascii(bstr));
4768   }
4769 }
4770
4771 #define BSTR_DATE(dt,str) SysFreeString(bstr); bstr = NULL; \
4772   hres = pVarBstrFromDate(dt,lcid,LOCALE_NOUSEROVERRIDE,&bstr); \
4773   if (bstr) WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0); \
4774   else buff[0] = 0; \
4775   ok(hres == S_OK && !strcmp(str,buff), "Expected '%s', got '%s', hres = 0x%08lx\n", \
4776      str, buff, hres)
4777
4778 static void test_VarBstrFromDate(void)
4779 {
4780   char buff[256];
4781   LCID lcid;
4782   HRESULT hres;
4783   BSTR bstr = NULL;
4784
4785   CHECKPTR(VarBstrFromDate);
4786   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
4787
4788   BSTR_DATE(0.0, "12:00:00 AM");
4789   BSTR_DATE(3.34, "1/2/1900 8:09:36 AM");
4790   BSTR_DATE(3339.34, "2/20/1909 8:09:36 AM");
4791   BSTR_DATE(365.00, "12/30/1900");
4792   BSTR_DATE(365.25, "12/30/1900 6:00:00 AM");
4793   BSTR_DATE(1461.0, "12/31/1903");
4794   BSTR_DATE(1461.5, "12/31/1903 12:00:00 PM");
4795 }
4796
4797 #define BSTR_DEC(l, a, b, c, d, e) \
4798   SETDEC(l, a,b,c,d);\
4799   hres = VarBstrFromDec(&l, lcid, 0, &bstr);\
4800   ok(hres == S_OK, "got hres 0x%08lx\n", hres);\
4801   if (hres== S_OK && bstr)\
4802   {\
4803     ok(lstrcmpW(bstr, e) == 0, "invalid number (got %s)\n", wtoascii(bstr));\
4804   }
4805
4806 #define BSTR_DEC64(l, a, b, c, x, d, e) \
4807   SETDEC64(l, a,b,c,x,d);\
4808   hres = VarBstrFromDec(&l, lcid, 0, &bstr);\
4809   ok(hres == S_OK, "got hres 0x%08lx\n", hres);\
4810   if (hres== S_OK && bstr)\
4811   {\
4812     ok(lstrcmpW(bstr, e) == 0, "invalid number (got %s)\n", wtoascii(bstr));\
4813   }
4814
4815 static void test_VarBstrFromDec(void)
4816 {
4817   LCID lcid;
4818   HRESULT hres;
4819   BSTR bstr = NULL;
4820   DECIMAL l;
4821
4822   static const WCHAR szZero[] = {'0', '\0'};
4823   static const WCHAR szOne[] = {'1', '\0'};
4824   static const WCHAR szOnePointFive[] = {'1','.','5','\0'};
4825   static const WCHAR szMinusOnePointFive[] = {'-','1','.','5','\0'};
4826   static const WCHAR szBigNum1[] = {'4','2','9','4','9','6','7','2','9','5','\0'};    /* (1 << 32) - 1 */
4827   static const WCHAR szBigNum2[] = {'4','2','9','4','9','6','7','2','9','6','\0'};    /* (1 << 32) */
4828   static const WCHAR szBigNum3[] = {'1','8','4','4','6','7','4','4','0','7','3','7','0','9','5','5','1','6','1','5','\0'};    /* (1 << 64) - 1 */
4829   static const WCHAR szBigNum4[] = {'1','8','4','4','6','7','4','4','0','7','3','7','0','9','5','5','1','6','1','6','\0'};    /* (1 << 64) */
4830   static const WCHAR szBigNum5[] = {'7','9','2','2','8','1','6','2','5','1','4','2','6','4','3','3','7','5','9','3','5','4','3','9','5','0','3','3','5','\0'};    /* (1 << 96) - 1 */
4831   static const WCHAR szBigScale1[] = {'0','.','0','0','0','0','0','0','0','0','0','1','\0'};    /* 1 * 10^-10 */
4832   static const WCHAR szBigScale2[] = {'7','9','2','2','8','1','6','2','5','1','4','2','6','4','3','3','7','5','9','.','3','5','4','3','9','5','0','3','3','5','\0'};    /* ((1 << 96) - 1) * 10^-10 */
4833   static const WCHAR szBigScale3[] = {'7','.','9','2','2','8','1','6','2','5','1','4','2','6','4','3','3','7','5','9','3','5','4','3','9','5','0','3','3','5','\0'};    /* ((1 << 96) - 1) * 10^-28 */
4834
4835   static const WCHAR szSmallNumber_English[] = {'0','.','0','0','0','9','\0'};
4836   static const WCHAR szSmallNumber_Spanish[] = {'0',',','0','0','0','9','\0'};
4837
4838   CHECKPTR(VarBstrFromDec);
4839   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
4840
4841   /* check zero */
4842   BSTR_DEC(l, 0,0,0,0, szZero);
4843   
4844   /* check one */
4845   BSTR_DEC(l, 0,0,0,1, szOne);
4846   BSTR_DEC(l, 1,0,0,10,szOne);
4847   BSTR_DEC(l, 2,0,0,100,szOne);
4848   BSTR_DEC(l, 3,0,0,1000,szOne);
4849
4850   /* check one point five */
4851   BSTR_DEC(l, 1,0,0,15, szOnePointFive);
4852   BSTR_DEC(l, 2,0,0,150, szOnePointFive);
4853   BSTR_DEC(l, 3,0,0,1500, szOnePointFive);
4854
4855   /* check minus one point five */
4856   BSTR_DEC(l, 1,0x80,0,15, szMinusOnePointFive);
4857
4858   /* check bignum (1) */
4859   BSTR_DEC(l, 0,0,0,0xffffffff, szBigNum1);
4860
4861   /* check bignum (2) */
4862   BSTR_DEC64(l, 0,0,0,1,0, szBigNum2);
4863
4864   /* check bignum (3) */
4865   BSTR_DEC64(l, 0,0,0,0xffffffff,0xffffffff, szBigNum3);
4866
4867   /* check bignum (4) */
4868   BSTR_DEC(l, 0,0,1,0, szBigNum4);
4869
4870   /* check bignum (5) */
4871   BSTR_DEC64(l, 0,0,0xffffffff,0xffffffff,0xffffffff, szBigNum5);
4872
4873   /* check bigscale (1) */
4874   BSTR_DEC(l, 10,0,0,1, szBigScale1);
4875
4876   /* check bigscale (2) */
4877   BSTR_DEC64(l, 10,0,0xffffffffUL,0xffffffff,0xffffffff, szBigScale2);
4878
4879   /* check bigscale (3) */
4880   BSTR_DEC64(l, 28,0,0xffffffffUL,0xffffffff,0xffffffff, szBigScale3);
4881
4882   /* check leading zeros and decimal sep. for English locale */
4883   BSTR_DEC(l, 4,0,0,9, szSmallNumber_English);
4884   BSTR_DEC(l, 5,0,0,90, szSmallNumber_English);
4885   BSTR_DEC(l, 6,0,0,900, szSmallNumber_English);
4886   BSTR_DEC(l, 7,0,0,9000, szSmallNumber_English);
4887   
4888   lcid = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
4889   
4890   /* check leading zeros and decimal sep. for Spanish locale */
4891   BSTR_DEC(l, 4,0,0,9, szSmallNumber_Spanish);
4892   BSTR_DEC(l, 5,0,0,90, szSmallNumber_Spanish);
4893   BSTR_DEC(l, 6,0,0,900, szSmallNumber_Spanish);
4894   BSTR_DEC(l, 7,0,0,9000, szSmallNumber_Spanish);
4895 }
4896 #undef BSTR_DEC
4897 #undef BSTR_DEC64
4898
4899 #define _VARBSTRCMP(left,right,lcid,flags,result) \
4900         hres = pVarBstrCmp(left,right,lcid,flags); \
4901         ok(hres == result, "VarBstrCmp: expected " #result ", got hres=0x%lx\n", hres)
4902 #define VARBSTRCMP(left,right,result) \
4903         _VARBSTRCMP(left,right,lcid,0,result)
4904
4905 static void test_VarBstrCmp(void)
4906 {
4907     LCID lcid;
4908     HRESULT hres;
4909     static const WCHAR sz[] = {'W','u','r','s','c','h','t','\0'};
4910     static const WCHAR szempty[] = {'\0'};
4911     BSTR bstr, bstrempty;
4912
4913     CHECKPTR(VarBstrCmp);
4914     
4915     lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
4916     bstr = SysAllocString(sz);
4917     bstrempty = SysAllocString(szempty);
4918     
4919     /* NULL handling. Yepp, MSDN is totaly wrong here */
4920     VARBSTRCMP(NULL,NULL,VARCMP_EQ);
4921     VARBSTRCMP(bstr,NULL,VARCMP_GT);
4922     VARBSTRCMP(NULL,bstr,VARCMP_LT);
4923
4924     /* NULL and empty string comparisions */
4925     VARBSTRCMP(bstrempty,NULL,VARCMP_EQ);
4926     VARBSTRCMP(NULL,bstrempty,VARCMP_EQ);
4927 }
4928
4929 /* Get the internal representation of a BSTR */
4930 static inline LPINTERNAL_BSTR Get(const BSTR lpszString)
4931 {
4932   return lpszString ? (LPINTERNAL_BSTR)((char*)lpszString - sizeof(DWORD)) : NULL;
4933 }
4934
4935 static inline BSTR GetBSTR(const LPINTERNAL_BSTR bstr)
4936 {
4937   return (BSTR)bstr->szString;
4938 }
4939
4940 static void test_SysStringLen(void)
4941 {
4942   INTERNAL_BSTR bstr;
4943   BSTR str = GetBSTR(&bstr);
4944
4945   bstr.dwLen = 0;
4946   ok (SysStringLen(str) == 0, "Expected dwLen 0, got %d\n", SysStringLen(str));
4947   bstr.dwLen = 2;
4948   ok (SysStringLen(str) == 1, "Expected dwLen 1, got %d\n", SysStringLen(str));
4949 }
4950
4951 static void test_SysStringByteLen(void)
4952 {
4953   INTERNAL_BSTR bstr;
4954   BSTR str = GetBSTR(&bstr);
4955
4956   bstr.dwLen = 0;
4957   ok (SysStringByteLen(str) == 0, "Expected dwLen 0, got %d\n", SysStringLen(str));
4958   bstr.dwLen = 2;
4959   ok (SysStringByteLen(str) == 2, "Expected dwLen 2, got %d\n", SysStringByteLen(str));
4960 }
4961
4962 static void test_SysAllocString(void)
4963 {
4964   const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
4965   BSTR str;
4966
4967   str = SysAllocString(NULL);
4968   ok (str == NULL, "Expected NULL, got %p\n", str);
4969
4970   str = SysAllocString(szTest);
4971   ok (str != NULL, "Expected non-NULL\n");
4972   if (str)
4973   {
4974     LPINTERNAL_BSTR bstr = Get(str);
4975
4976     ok (bstr->dwLen == 8, "Expected 8, got %ld\n", bstr->dwLen);
4977     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
4978     SysFreeString(str);
4979   }
4980 }
4981
4982 static void test_SysAllocStringLen(void)
4983 {
4984   const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
4985   BSTR str;
4986
4987   /* Very early native dlls do not limit the size of strings, so skip this test */
4988 #if 0
4989   str = SysAllocStringLen(szTest, 0x80000000);
4990   todo_wine {
4991   ok (str == NULL, "Expected NULL, got %p\n", str);
4992   }
4993 #endif
4994   
4995   str = SysAllocStringLen(NULL, 0);
4996   ok (str != NULL, "Expected non-NULL\n");
4997   if (str)
4998   {
4999     LPINTERNAL_BSTR bstr = Get(str);
5000
5001     ok (bstr->dwLen == 0, "Expected 0, got %ld\n", bstr->dwLen);
5002     ok (!bstr->szString[0], "String not empty\n");
5003     SysFreeString(str);
5004   }
5005
5006   str = SysAllocStringLen(szTest, 4);
5007   ok (str != NULL, "Expected non-NULL\n");
5008   if (str)
5009   {
5010     LPINTERNAL_BSTR bstr = Get(str);
5011
5012     ok (bstr->dwLen == 8, "Expected 8, got %ld\n", bstr->dwLen);
5013     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5014     SysFreeString(str);
5015   }
5016 }
5017
5018 static void test_SysAllocStringByteLen(void)
5019 {
5020   const OLECHAR szTest[10] = { 'T','e','s','t','\0' };
5021   const CHAR szTestA[6] = { 'T','e','s','t','\0','?' };
5022   BSTR str;
5023
5024   str = SysAllocStringByteLen(szTestA, 0x80000000);
5025   ok (str == NULL, "Expected NULL, got %p\n", str);
5026
5027   str = SysAllocStringByteLen(NULL, 0);
5028   ok (str != NULL, "Expected non-NULL\n");
5029   if (str)
5030   {
5031     LPINTERNAL_BSTR bstr = Get(str);
5032
5033     ok (bstr->dwLen == 0, "Expected 0, got %ld\n", bstr->dwLen);
5034     ok (!bstr->szString[0], "String not empty\n");
5035     SysFreeString(str);
5036   }
5037
5038   str = SysAllocStringByteLen(szTestA, 4);
5039   ok (str != NULL, "Expected non-NULL\n");
5040   if (str)
5041   {
5042     LPINTERNAL_BSTR bstr = Get(str);
5043
5044     ok (bstr->dwLen == 4, "Expected 4, got %ld\n", bstr->dwLen);
5045     ok (!lstrcmpA((LPCSTR)bstr->szString, szTestA), "String different\n");
5046     SysFreeString(str);
5047   }
5048
5049   /* Odd lengths are allocated rounded up, but truncated at the right position */
5050   str = SysAllocStringByteLen(szTestA, 3);
5051   ok (str != NULL, "Expected non-NULL\n");
5052   if (str)
5053   {
5054     const CHAR szTestTruncA[4] = { 'T','e','s','\0' };
5055     LPINTERNAL_BSTR bstr = Get(str);
5056
5057     ok (bstr->dwLen == 3, "Expected 3, got %ld\n", bstr->dwLen);
5058     ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n");
5059     SysFreeString(str);
5060   }
5061
5062   str = SysAllocStringByteLen((LPCSTR)szTest, 8);
5063   ok (str != NULL, "Expected non-NULL\n");
5064   if (str)
5065   {
5066     LPINTERNAL_BSTR bstr = Get(str);
5067
5068     ok (bstr->dwLen == 8, "Expected 8, got %ld\n", bstr->dwLen);
5069     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5070     SysFreeString(str);
5071   }
5072 }
5073
5074 static void test_SysReAllocString(void)
5075 {
5076   const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
5077   const OLECHAR szSmaller[2] = { 'x','\0' };
5078   const OLECHAR szLarger[7] = { 'L','a','r','g','e','r','\0' };
5079   BSTR str;
5080
5081   str = SysAllocStringLen(szTest, 4);
5082   ok (str != NULL, "Expected non-NULL\n");
5083   if (str)
5084   {
5085     LPINTERNAL_BSTR bstr;
5086     BSTR oldstr = str;
5087     int changed;
5088
5089     bstr = Get(str);
5090     ok (bstr->dwLen == 8, "Expected 8, got %ld\n", bstr->dwLen);
5091     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5092
5093     changed = SysReAllocString(&str, szSmaller);
5094     ok (changed == 1, "Expected 1, got %d\n", changed);
5095     ok (str == oldstr, "Created new string\n");
5096     bstr = Get(str);
5097     ok (bstr->dwLen == 2, "Expected 2, got %ld\n", bstr->dwLen);
5098     ok (!lstrcmpW(bstr->szString, szSmaller), "String different\n");
5099
5100     oldstr = str;
5101     changed = SysReAllocString(&str, szLarger);
5102     ok (changed == 1, "Expected 1, got %d\n", changed);
5103     /* Early versions always make new strings rather than resizing */
5104     /* ok (str == oldstr, "Created new string\n"); */
5105     bstr = Get(str);
5106     ok (bstr->dwLen == 12, "Expected 12, got %ld\n", bstr->dwLen);
5107     ok (!lstrcmpW(bstr->szString, szLarger), "String different\n");
5108
5109     SysFreeString(str);
5110   }
5111 }
5112
5113 static void test_SysReAllocStringLen(void)
5114 {
5115   const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
5116   const OLECHAR szSmaller[2] = { 'x','\0' };
5117   const OLECHAR szLarger[7] = { 'L','a','r','g','e','r','\0' };
5118   BSTR str;
5119
5120   str = SysAllocStringLen(szTest, 4);
5121   ok (str != NULL, "Expected non-NULL\n");
5122   if (str)
5123   {
5124     LPINTERNAL_BSTR bstr;
5125     BSTR oldstr = str;
5126     int changed;
5127
5128     bstr = Get(str);
5129     ok (bstr->dwLen == 8, "Expected 8, got %ld\n", bstr->dwLen);
5130     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5131
5132     changed = SysReAllocStringLen(&str, szSmaller, 1);
5133     ok (changed == 1, "Expected 1, got %d\n", changed);
5134     ok (str == oldstr, "Created new string\n");
5135     bstr = Get(str);
5136     ok (bstr->dwLen == 2, "Expected 2, got %ld\n", bstr->dwLen);
5137     ok (!lstrcmpW(bstr->szString, szSmaller), "String different\n");
5138
5139     oldstr = str;
5140     changed = SysReAllocStringLen(&str, szLarger, 6);
5141     ok (changed == 1, "Expected 1, got %d\n", changed);
5142     /* Early versions always make new strings rather than resizing */
5143     /* ok (str == oldstr, "Created new string\n"); */
5144     bstr = Get(str);
5145     ok (bstr->dwLen == 12, "Expected 12, got %ld\n", bstr->dwLen);
5146     ok (!lstrcmpW(bstr->szString, szLarger), "String different\n");
5147
5148     changed = SysReAllocStringLen(&str, str, 6);
5149     ok (changed == 1, "Expected 1, got %d\n", changed);
5150
5151     SysFreeString(str);
5152   }
5153 }
5154
5155 static void test_BstrCopy(void)
5156 {
5157   const CHAR szTestA[6] = { 'T','e','s','t','\0','?' };
5158   const CHAR szTestTruncA[4] = { 'T','e','s','\0' };
5159   LPINTERNAL_BSTR bstr;
5160   BSTR str;
5161   HRESULT hres;
5162   VARIANT vt1, vt2;
5163
5164   str = SysAllocStringByteLen(szTestA, 3);
5165   ok (str != NULL, "Expected non-NULL\n");
5166   if (str)
5167   {
5168     V_VT(&vt1) = VT_BSTR;
5169     V_BSTR(&vt1) = str;
5170     V_VT(&vt2) = VT_EMPTY;
5171     hres = VariantCopy(&vt2, &vt1);
5172     ok (hres == S_OK,"Failed to copy binary bstring with hres 0x%08lx\n", hres);
5173     bstr = Get(V_BSTR(&vt2));
5174     ok (bstr->dwLen == 3, "Expected 3, got %ld\n", bstr->dwLen);
5175     ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n");
5176   }
5177 }
5178
5179 /* IUnknown */
5180
5181 static void test_IUnknownClear(void)
5182 {
5183   HRESULT hres;
5184   VARIANTARG v;
5185   DummyDispatch u = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
5186   IUnknown* pu = (IUnknown*)&u;
5187
5188   /* Test that IUnknown_Release is called on by-value */
5189   V_VT(&v) = VT_UNKNOWN;
5190   V_UNKNOWN(&v) = (IUnknown*)&u;
5191   hres = VariantClear(&v);
5192   ok(hres == S_OK && u.ref == 0 && V_VT(&v) == VT_EMPTY,
5193      "clear unknown: expected 0x%08lx, %d, %d, got 0x%08lx, %ld, %d\n",
5194      S_OK, 0, VT_EMPTY, hres, u.ref, V_VT(&v));
5195
5196   /* But not when clearing a by-reference*/
5197   u.ref = 1;
5198   V_VT(&v) = VT_UNKNOWN|VT_BYREF;
5199   V_UNKNOWNREF(&v) = &pu;
5200   hres = VariantClear(&v);
5201   ok(hres == S_OK && u.ref == 1 && V_VT(&v) == VT_EMPTY,
5202      "clear dispatch: expected 0x%08lx, %d, %d, got 0x%08lx, %ld, %d\n",
5203      S_OK, 1, VT_EMPTY, hres, u.ref, V_VT(&v));
5204 }
5205
5206 static void test_IUnknownCopy(void)
5207 {
5208   HRESULT hres;
5209   VARIANTARG vSrc, vDst;
5210   DummyDispatch u = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
5211   IUnknown* pu = (IUnknown*)&u;
5212
5213   /* AddRef is called on by-value copy */
5214   VariantInit(&vDst);
5215   V_VT(&vSrc) = VT_UNKNOWN;
5216   V_UNKNOWN(&vSrc) = pu;
5217   hres = VariantCopy(&vDst, &vSrc);
5218   ok(hres == S_OK && u.ref == 2 && V_VT(&vDst) == VT_UNKNOWN,
5219      "copy unknown: expected 0x%08lx, %d, %d, got 0x%08lx, %ld, %d\n",
5220      S_OK, 2, VT_EMPTY, hres, u.ref, V_VT(&vDst));
5221
5222   /* AddRef is skipped on copy of by-reference IDispatch */
5223   VariantInit(&vDst);
5224   u.ref = 1;
5225   V_VT(&vSrc) = VT_UNKNOWN|VT_BYREF;
5226   V_UNKNOWNREF(&vSrc) = &pu;
5227   hres = VariantCopy(&vDst, &vSrc);
5228   ok(hres == S_OK && u.ref == 1 && V_VT(&vDst) == (VT_UNKNOWN|VT_BYREF),
5229      "copy unknown: expected 0x%08lx, %d, %d, got 0x%08lx, %ld, %d\n",
5230      S_OK, 1, VT_DISPATCH, hres, u.ref, V_VT(&vDst));
5231
5232   /* AddRef is called copying by-reference IDispatch with indirection */
5233   VariantInit(&vDst);
5234   u.ref = 1;
5235   V_VT(&vSrc) = VT_UNKNOWN|VT_BYREF;
5236   V_UNKNOWNREF(&vSrc) = &pu;
5237   hres = VariantCopyInd(&vDst, &vSrc);
5238   ok(hres == S_OK && u.ref == 2 && V_VT(&vDst) == VT_UNKNOWN,
5239      "copy unknown: expected 0x%08lx, %d, %d, got 0x%08lx, %ld, %d\n",
5240      S_OK, 2, VT_DISPATCH, hres, u.ref, V_VT(&vDst));
5241
5242   /* Indirection in place also calls AddRef */
5243   u.ref = 1;
5244   V_VT(&vSrc) = VT_UNKNOWN|VT_BYREF;
5245   V_UNKNOWNREF(&vSrc) = &pu;
5246   hres = VariantCopyInd(&vSrc, &vSrc);
5247   ok(hres == S_OK && u.ref == 2 && V_VT(&vSrc) == VT_UNKNOWN,
5248      "copy unknown: expected 0x%08lx, %d, %d, got 0x%08lx, %ld, %d\n",
5249      S_OK, 2, VT_DISPATCH, hres, u.ref, V_VT(&vSrc));
5250 }
5251
5252 static void test_IUnknownChangeTypeEx(void)
5253 {
5254   HRESULT hres;
5255   VARIANTARG vSrc, vDst;
5256   LCID lcid;
5257   VARTYPE vt;
5258   DummyDispatch u = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
5259   IUnknown* pu = (IUnknown*)&u;
5260
5261   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5262
5263   V_VT(&vSrc) = VT_UNKNOWN;
5264   V_UNKNOWN(&vSrc) = pu;
5265
5266   /* =>IDispatch in place */
5267   hres = VariantChangeTypeEx(&vSrc, &vSrc, lcid, 0, VT_DISPATCH);
5268   ok(hres == S_OK && u.ref == 1 &&
5269      V_VT(&vSrc) == VT_DISPATCH && V_DISPATCH(&vSrc) == (IDispatch*)pu,
5270      "change unk(src=src): expected 0x%08lx,%d,%d,%p, got 0x%08lx,%ld,%d,%p\n",
5271      S_OK, 1, VT_DISPATCH, pu, hres, u.ref, V_VT(&vSrc), V_DISPATCH(&vSrc));
5272
5273   /* =>IDispatch */
5274   u.ref = 1;
5275   V_VT(&vSrc) = VT_UNKNOWN;
5276   V_UNKNOWN(&vSrc) = (IUnknown*)pu;
5277   VariantInit(&vDst);
5278   hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, VT_UNKNOWN);
5279   /* Note vSrc is not cleared, as final refcount is 2 */
5280   ok(hres == S_OK && u.ref == 2 &&
5281      V_VT(&vDst) == VT_UNKNOWN && V_UNKNOWN(&vDst) == (IUnknown*)pu,
5282      "change unk(src,dst): expected 0x%08lx,%d,%d,%p, got 0x%08lx,%ld,%d,%p\n",
5283      S_OK, 2, VT_UNKNOWN, pu, hres, u.ref, V_VT(&vDst), V_UNKNOWN(&vDst));
5284
5285   /* Can't change unknown to anything else */
5286   for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
5287   {
5288     HRESULT hExpected = DISP_E_BADVARTYPE;
5289
5290     V_VT(&vSrc) = VT_UNKNOWN;
5291     V_UNKNOWN(&vSrc) = (IUnknown*)pu;
5292     VariantInit(&vDst);
5293
5294     if (vt == VT_UNKNOWN || vt == VT_DISPATCH || vt == VT_EMPTY || vt == VT_NULL)
5295       hExpected = S_OK;
5296     else
5297     {
5298       if (vt == VT_I8 || vt == VT_UI8)
5299       {
5300         if (HAVE_OLEAUT32_I8)
5301           hExpected = DISP_E_TYPEMISMATCH;
5302       }
5303       else if (vt == VT_RECORD)
5304       {
5305         if (HAVE_OLEAUT32_RECORD)
5306           hExpected = DISP_E_TYPEMISMATCH;
5307       }
5308       else if (vt  >= VT_I2 && vt <= VT_UINT && vt != (VARTYPE)15)
5309         hExpected = DISP_E_TYPEMISMATCH;
5310     }
5311     if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
5312         hExpected = DISP_E_BADVARTYPE;
5313
5314     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
5315     ok(hres == hExpected,
5316        "change unk(badvar): vt %d expected 0x%08lx, got 0x%08lx\n",
5317        vt, hExpected, hres);
5318   }
5319 }
5320
5321 /* IDispatch */
5322 static void test_IDispatchClear(void)
5323 {
5324   HRESULT hres;
5325   VARIANTARG v;
5326   DummyDispatch d = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
5327   IDispatch* pd = (IDispatch*)&d;
5328
5329   /* As per IUnknown */
5330
5331   V_VT(&v) = VT_DISPATCH;
5332   V_DISPATCH(&v) = pd;
5333   hres = VariantClear(&v);
5334   ok(hres == S_OK && d.ref == 0 && V_VT(&v) == VT_EMPTY,
5335      "clear dispatch: expected 0x%08lx, %d, %d, got 0x%08lx, %ld, %d\n",
5336      S_OK, 0, VT_EMPTY, hres, d.ref, V_VT(&v));
5337
5338   d.ref = 1;
5339   V_VT(&v) = VT_DISPATCH|VT_BYREF;
5340   V_DISPATCHREF(&v) = &pd;
5341   hres = VariantClear(&v);
5342   ok(hres == S_OK && d.ref == 1 && V_VT(&v) == VT_EMPTY,
5343      "clear dispatch: expected 0x%08lx, %d, %d, got 0x%08lx, %ld, %d\n",
5344      S_OK, 1, VT_EMPTY, hres, d.ref, V_VT(&v));
5345 }
5346
5347 static void test_IDispatchCopy(void)
5348 {
5349   HRESULT hres;
5350   VARIANTARG vSrc, vDst;
5351   DummyDispatch d = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
5352   IDispatch* pd = (IDispatch*)&d;
5353
5354   /* As per IUnknown */
5355
5356   VariantInit(&vDst);
5357   V_VT(&vSrc) = VT_DISPATCH;
5358   V_DISPATCH(&vSrc) = pd;
5359   hres = VariantCopy(&vDst, &vSrc);
5360   ok(hres == S_OK && d.ref == 2 && V_VT(&vDst) == VT_DISPATCH,
5361      "copy dispatch: expected 0x%08lx, %d, %d, got 0x%08lx, %ld, %d\n",
5362      S_OK, 2, VT_EMPTY, hres, d.ref, V_VT(&vDst));
5363
5364   VariantInit(&vDst);
5365   d.ref = 1;
5366   V_VT(&vSrc) = VT_DISPATCH|VT_BYREF;
5367   V_DISPATCHREF(&vSrc) = &pd;
5368   hres = VariantCopy(&vDst, &vSrc);
5369   ok(hres == S_OK && d.ref == 1 && V_VT(&vDst) == (VT_DISPATCH|VT_BYREF),
5370      "copy dispatch: expected 0x%08lx, %d, %d, got 0x%08lx, %ld, %d\n",
5371      S_OK, 1, VT_DISPATCH, hres, d.ref, V_VT(&vDst));
5372
5373   VariantInit(&vDst);
5374   d.ref = 1;
5375   V_VT(&vSrc) = VT_DISPATCH|VT_BYREF;
5376   V_DISPATCHREF(&vSrc) = &pd;
5377   hres = VariantCopyInd(&vDst, &vSrc);
5378   ok(hres == S_OK && d.ref == 2 && V_VT(&vDst) == VT_DISPATCH,
5379      "copy dispatch: expected 0x%08lx, %d, %d, got 0x%08lx, %ld, %d\n",
5380      S_OK, 2, VT_DISPATCH, hres, d.ref, V_VT(&vDst));
5381
5382   d.ref = 1;
5383   V_VT(&vSrc) = VT_DISPATCH|VT_BYREF;
5384   V_DISPATCHREF(&vSrc) = &pd;
5385   hres = VariantCopyInd(&vSrc, &vSrc);
5386   ok(hres == S_OK && d.ref == 2 && V_VT(&vSrc) == VT_DISPATCH,
5387      "copy dispatch: expected 0x%08lx, %d, %d, got 0x%08lx, %ld, %d\n",
5388      S_OK, 2, VT_DISPATCH, hres, d.ref, V_VT(&vSrc));
5389 }
5390
5391 static void test_IDispatchChangeTypeEx(void)
5392 {
5393   HRESULT hres;
5394   VARIANTARG vSrc, vDst;
5395   LCID lcid;
5396   DummyDispatch d = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
5397   IDispatch* pd = (IDispatch*)&d;
5398
5399   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5400
5401   V_VT(&vSrc) = VT_DISPATCH;
5402   V_DISPATCH(&vSrc) = pd;
5403
5404   /* =>IUnknown in place */
5405   hres = VariantChangeTypeEx(&vSrc, &vSrc, lcid, 0, VT_UNKNOWN);
5406   ok(hres == S_OK && d.ref == 1 &&
5407      V_VT(&vSrc) == VT_UNKNOWN && V_UNKNOWN(&vSrc) == (IUnknown*)pd,
5408      "change disp(src=src): expected 0x%08lx,%d,%d,%p, got 0x%08lx,%ld,%d,%p\n",
5409      S_OK, 1, VT_UNKNOWN, pd, hres, d.ref, V_VT(&vSrc), V_UNKNOWN(&vSrc));
5410
5411   /* =>IUnknown */
5412   d.ref = 1;
5413   V_VT(&vSrc) = VT_DISPATCH;
5414   V_DISPATCH(&vSrc) = pd;
5415   VariantInit(&vDst);
5416   hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, VT_UNKNOWN);
5417   /* Note vSrc is not cleared, as final refcount is 2 */
5418   ok(hres == S_OK && d.ref == 2 &&
5419      V_VT(&vDst) == VT_UNKNOWN && V_UNKNOWN(&vDst) == (IUnknown*)pd,
5420      "change disp(src,dst): expected 0x%08lx,%d,%d,%p, got 0x%08lx,%ld,%d,%p\n",
5421      S_OK, 2, VT_UNKNOWN, pd, hres, d.ref, V_VT(&vDst), V_UNKNOWN(&vDst));
5422
5423   /* FIXME: Verify that VARIANT_NOVALUEPROP prevents conversion to integral
5424    *        types. this requires that the xxxFromDisp tests work first.
5425    */
5426 }
5427
5428 /* VT_ERROR */
5429 static void test_ErrorChangeTypeEx(void)
5430 {
5431   HRESULT hres;
5432   VARIANTARG vSrc, vDst;
5433   VARTYPE vt;
5434   LCID lcid;
5435
5436   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5437
5438   for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
5439   {
5440     HRESULT hExpected = DISP_E_BADVARTYPE;
5441
5442     V_VT(&vSrc) = VT_ERROR;
5443     V_ERROR(&vSrc) = 1;
5444     VariantInit(&vDst);
5445     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
5446
5447     if (vt == VT_ERROR)
5448       hExpected = S_OK;
5449     else
5450     {
5451       if (vt == VT_I8 || vt == VT_UI8)
5452       {
5453         if (HAVE_OLEAUT32_I8)
5454           hExpected = DISP_E_TYPEMISMATCH;
5455       }
5456       else if (vt == VT_RECORD)
5457       {
5458         if (HAVE_OLEAUT32_RECORD)
5459           hExpected = DISP_E_TYPEMISMATCH;
5460       }
5461       else if (vt <= VT_UINT && vt != (VARTYPE)15)
5462         hExpected = DISP_E_TYPEMISMATCH;
5463     }
5464     if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
5465         hExpected = DISP_E_BADVARTYPE;
5466
5467     ok(hres == hExpected,
5468      "change err: vt %d expected 0x%08lx, got 0x%08lx\n", vt, hExpected, hres);
5469   }
5470 }
5471
5472 /* VT_EMPTY */
5473 static void test_EmptyChangeTypeEx(void)
5474 {
5475   HRESULT hres;
5476   VARIANTARG vSrc, vDst;
5477   VARTYPE vt;
5478   LCID lcid;
5479
5480   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5481
5482   for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
5483   {
5484     HRESULT hExpected = DISP_E_BADVARTYPE;
5485
5486     VariantInit(&vSrc);
5487     memset(&vDst, 0, sizeof(vDst));
5488     V_VT(&vDst) = VT_EMPTY;
5489
5490     if (vt == VT_I8 || vt == VT_UI8)
5491     {
5492       if (HAVE_OLEAUT32_I8)
5493         hExpected = S_OK;
5494     }
5495     else if (vt == VT_RECORD)
5496     {
5497       if (HAVE_OLEAUT32_RECORD)
5498         hExpected = DISP_E_TYPEMISMATCH;
5499     }
5500     else if (vt == VT_VARIANT || vt == VT_DISPATCH ||
5501               vt == VT_UNKNOWN || vt == VT_ERROR)
5502     {
5503       hExpected = DISP_E_TYPEMISMATCH;
5504     }
5505     else if (vt <= VT_UINT && vt != (VARTYPE)15)
5506       hExpected = S_OK;
5507
5508     if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
5509         hExpected = DISP_E_BADVARTYPE;
5510
5511     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
5512
5513     ok(hres == hExpected && (hres != S_OK || V_VT(&vDst) == vt),
5514        "change empty: vt %d expected 0x%08lx, got 0x%08lx, vt %d\n",
5515        vt, hExpected, hres, V_VT(&vDst));
5516   }
5517 }
5518
5519 /* VT_NULL */
5520 static void test_NullChangeTypeEx(void)
5521 {
5522   HRESULT hres;
5523   VARIANTARG vSrc, vDst;
5524   VARTYPE vt;
5525   LCID lcid;
5526
5527   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5528
5529   for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
5530   {
5531     HRESULT hExpected = DISP_E_BADVARTYPE;
5532
5533     VariantInit(&vSrc);
5534     V_VT(&vSrc) = VT_NULL;
5535     memset(&vDst, 0, sizeof(vDst));
5536     V_VT(&vDst) = VT_EMPTY;
5537
5538     if (vt == VT_I8 || vt == VT_UI8)
5539     {
5540       if (HAVE_OLEAUT32_I8)
5541         hExpected = DISP_E_TYPEMISMATCH;
5542     }
5543     else if (vt == VT_RECORD)
5544     {
5545       if (HAVE_OLEAUT32_RECORD)
5546         hExpected = DISP_E_TYPEMISMATCH;
5547     }
5548     else if (vt == VT_NULL)
5549     {
5550       hExpected = S_OK;
5551     }
5552     else if (vt == VT_VARIANT || vt == VT_DISPATCH ||
5553               vt == VT_UNKNOWN || vt == VT_ERROR ||
5554               (vt <= VT_UINT && vt != (VARTYPE)15))
5555       hExpected = DISP_E_TYPEMISMATCH;
5556
5557     if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
5558         hExpected = DISP_E_BADVARTYPE;
5559
5560     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
5561
5562     ok(hres == hExpected && (hres != S_OK || V_VT(&vDst) == vt),
5563        "change null: vt %d expected 0x%08lx, got 0x%08lx, vt %d\n",
5564        vt, hExpected, hres, V_VT(&vDst));
5565   }
5566 }
5567
5568  
5569 /* VT_UINT */
5570 static void test_UintChangeTypeEx(void)
5571 {
5572   HRESULT hres;
5573   VARIANTARG vSrc, vDst;
5574   LCID lcid;
5575
5576   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5577
5578   /* Converting a VT_UINT to a VT_INT does not check for overflow */
5579   V_VT(&vDst) = VT_EMPTY;
5580   V_VT(&vSrc) = VT_UINT;
5581   V_UI4(&vSrc) = -1;
5582   hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, VT_I4);
5583   ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == -1,
5584      "change uint: Expected %d,0x%08lx,%d got %d,0x%08lx,%ld\n",
5585      VT_I4, S_OK, -1, V_VT(&vDst), hres, V_I4(&vDst));
5586 }
5587
5588 #define NUM_CUST_ITEMS 16
5589
5590 static void test_ClearCustData(void)
5591 {
5592   WCHAR buff[sizeof(CUSTDATAITEM) * NUM_CUST_ITEMS / sizeof(WCHAR)];
5593   CUSTDATA ci;
5594   unsigned i;
5595
5596   CHECKPTR(ClearCustData);
5597
5598   memset(buff, 0, sizeof(buff));
5599
5600   ci.cCustData = NUM_CUST_ITEMS;
5601   /* This is a bit tricky. We use SysAllocStringByteLen to allocate the
5602    * array, since native uses an internal IMalloc interface for allocating
5603    * its memory, while Wine uses HeapAlloc(). Doing this ensures we allocate
5604    * using the correct function whether with native or builtin.
5605    */
5606   ci.prgCustData = (LPCUSTDATAITEM)SysAllocStringByteLen((LPCSTR)buff, sizeof(buff));
5607   for (i = 0; i < NUM_CUST_ITEMS; i++)
5608     VariantInit(&ci.prgCustData[i].varValue);
5609   pClearCustData(&ci);
5610   ok(!ci.cCustData && !ci.prgCustData, "ClearCustData didn't clear fields!\n");
5611 }
5612
5613 static void test_NullByRef(void)
5614 {
5615   VARIANT v1, v2;
5616   HRESULT hRes;
5617
5618   VariantClear(&v1);
5619   VariantClear(&v2);
5620   V_VT(&v1) = VT_BYREF|VT_VARIANT;
5621   V_BYREF(&v1) = 0;
5622
5623   hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_I4);
5624   ok(hRes == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx should return DISP_E_TYPEMISMATCH\n");
5625
5626   VariantClear(&v1);
5627   V_VT(&v1) = VT_BYREF|VT_VARIANT;
5628   V_BYREF(&v1) = 0;
5629   V_VT(&v2) = VT_I4;
5630   V_I4(&v2) = 123;
5631
5632   hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_VARIANT);
5633   ok(hRes == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx should return DISP_E_TYPEMISMATCH\n");
5634   ok(V_VT(&v2) == VT_I4 && V_I4(&v2) == 123, "VariantChangeTypeEx shouldn't change pvargDest\n");
5635
5636   hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_BYREF|VT_I4);
5637   ok(hRes == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx should return DISP_E_TYPEMISMATCH\n");
5638
5639   hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, 0x3847);
5640   ok(hRes == DISP_E_BADVARTYPE, "VariantChangeTypeEx should return DISP_E_BADVARTYPE\n");
5641 }
5642
5643 /* Dst Variant should remain unchanged if VariantChangeType cannot convert */
5644 static void test_ChangeType_keep_dst(void)
5645 {
5646      VARIANT v1, v2;
5647      BSTR bstr;
5648      WCHAR testW[] = {'t','e','s','t',0};
5649      HRESULT hres;
5650
5651      bstr = SysAllocString(testW);
5652      VariantClear(&v1);
5653      VariantClear(&v2);
5654      V_VT(&v1) = VT_BSTR;
5655      V_BSTR(&v1) = bstr;
5656      hres = VariantChangeTypeEx(&v1, &v1, 0, 0, VT_INT);
5657      ok(hres == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx returns %08lx\n", hres);
5658      ok(V_VT(&v1) == VT_BSTR && V_BSTR(&v1) == bstr, "VariantChangeTypeEx changed dst variant\n");
5659      V_VT(&v2) = VT_INT;
5660      V_INT(&v2) = 4;
5661      hres = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_INT);
5662      ok(hres == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx returns %08lx\n", hres);
5663      ok(V_VT(&v2) == VT_INT && V_INT(&v2) == 4, "VariantChangeTypeEx changed dst variant\n");     
5664      SysFreeString(bstr);
5665 }
5666
5667 START_TEST(vartype)
5668 {
5669   hOleaut32 = LoadLibraryA("oleaut32.dll");
5670   ok(hOleaut32 != 0, "Failed to load oleaut32.dll\n");
5671   if (!hOleaut32)
5672     return;
5673
5674   trace("LCID's: System=0x%08lx, User=0x%08lx\n", GetSystemDefaultLCID(),
5675         GetUserDefaultLCID());
5676
5677   test_VarI1FromI2();
5678   test_VarI1FromI4();
5679   test_VarI1FromI8();
5680   test_VarI1FromUI1();
5681   test_VarI1FromUI2();
5682   test_VarI1FromUI4();
5683   test_VarI1FromUI8();
5684   test_VarI1FromBool();
5685   test_VarI1FromR4();
5686   test_VarI1FromR8();
5687   test_VarI1FromDate();
5688   test_VarI1FromCy();
5689   test_VarI1FromDec();
5690   test_VarI1FromStr();
5691   test_VarUI1FromDisp();
5692   test_VarI1Copy();
5693   test_VarI1ChangeTypeEx();
5694
5695   test_VarUI1FromI1();
5696   test_VarUI1FromI2();
5697   test_VarUI1FromI4();
5698   test_VarUI1FromI8();
5699   test_VarUI1FromUI2();
5700   test_VarUI1FromUI4();
5701   test_VarUI1FromUI8();
5702   test_VarUI1FromBool();
5703   test_VarUI1FromR4();
5704   test_VarUI1FromR8();
5705   test_VarUI1FromDate();
5706   test_VarUI1FromCy();
5707   test_VarUI1FromDec();
5708   test_VarUI1FromStr();
5709   test_VarUI1Copy();
5710   test_VarUI1ChangeTypeEx();
5711
5712   test_VarI2FromI1();
5713   test_VarI2FromI4();
5714   test_VarI2FromI8();
5715   test_VarI2FromUI1();
5716   test_VarI2FromUI2();
5717   test_VarI2FromUI4();
5718   test_VarI2FromUI8();
5719   test_VarI2FromBool();
5720   test_VarI2FromR4();
5721   test_VarI2FromR8();
5722   test_VarI2FromDate();
5723   test_VarI2FromCy();
5724   test_VarI2FromDec();
5725   test_VarI2FromStr();
5726   test_VarI2Copy();
5727   test_VarI2ChangeTypeEx();
5728
5729   test_VarUI2FromI1();
5730   test_VarUI2FromI2();
5731   test_VarUI2FromI4();
5732   test_VarUI2FromI8();
5733   test_VarUI2FromUI1();
5734   test_VarUI2FromUI4();
5735   test_VarUI2FromUI8();
5736   test_VarUI2FromBool();
5737   test_VarUI2FromR4();
5738   test_VarUI2FromR8();
5739   test_VarUI2FromDate();
5740   test_VarUI2FromCy();
5741   test_VarUI2FromDec();
5742   test_VarUI2FromStr();
5743   test_VarUI2Copy();
5744   test_VarUI2ChangeTypeEx();
5745
5746   test_VarI4FromI1();
5747   test_VarI4FromI2();
5748   test_VarI4FromI8();
5749   test_VarI4FromUI1();
5750   test_VarI4FromUI2();
5751   test_VarI4FromUI4();
5752   test_VarI4FromUI8();
5753   test_VarI4FromBool();
5754   test_VarI4FromR4();
5755   test_VarI4FromR8();
5756   test_VarI4FromDate();
5757   test_VarI4FromCy();
5758   test_VarI4FromDec();
5759   test_VarI4FromStr();
5760   test_VarI4Copy();
5761   test_VarI4ChangeTypeEx();
5762
5763   test_VarUI4FromI1();
5764   test_VarUI4FromI2();
5765   test_VarUI4FromUI2();
5766   test_VarUI4FromI8();
5767   test_VarUI4FromUI1();
5768   test_VarUI4FromI4();
5769   test_VarUI4FromUI8();
5770   test_VarUI4FromBool();
5771   test_VarUI4FromR4();
5772   test_VarUI4FromR8();
5773   test_VarUI4FromDate();
5774   test_VarUI4FromCy();
5775   test_VarUI4FromDec();
5776   test_VarUI4FromStr();
5777   test_VarUI4Copy();
5778   test_VarUI4ChangeTypeEx();
5779
5780   test_VarI8FromI1();
5781   test_VarI8FromUI1();
5782   test_VarI8FromI2();
5783   test_VarI8FromUI2();
5784   test_VarI8FromUI4();
5785   test_VarI8FromR4();
5786   test_VarI8FromR8();
5787   test_VarI8FromBool();
5788   test_VarI8FromUI8();
5789   test_VarI8FromCy();
5790   test_VarI8FromDec();
5791   test_VarI8FromDate();
5792   test_VarI8FromStr();
5793   test_VarI8Copy();
5794   test_VarI8ChangeTypeEx();
5795
5796   test_VarUI8FromI1();
5797   test_VarUI8FromUI1();
5798   test_VarUI8FromI2();
5799   test_VarUI8FromUI2();
5800   test_VarUI8FromUI4();
5801   test_VarUI8FromR4();
5802   test_VarUI8FromR8();
5803   test_VarUI8FromBool();
5804   test_VarUI8FromI8();
5805   test_VarUI8FromCy();
5806   test_VarUI8FromDec();
5807   test_VarUI8FromDate();
5808   test_VarUI8FromStr();
5809   test_VarUI8Copy();
5810   test_VarUI8ChangeTypeEx();
5811
5812   test_VarR4FromI1();
5813   test_VarR4FromUI1();
5814   test_VarR4FromI2();
5815   test_VarR4FromUI2();
5816   test_VarR4FromI4();
5817   test_VarR4FromUI4();
5818   test_VarR4FromR8();
5819   test_VarR4FromBool();
5820   test_VarR4FromCy();
5821   test_VarR4FromI8();
5822   test_VarR4FromUI8();
5823   test_VarR4FromDec();
5824   test_VarR4FromDate();
5825   test_VarR4FromStr();
5826   test_VarR4Copy();
5827   test_VarR4ChangeTypeEx();
5828
5829   test_VarR8FromI1();
5830   test_VarR8FromUI1();
5831   test_VarR8FromI2();
5832   test_VarR8FromUI2();
5833   test_VarR8FromI4();
5834   test_VarR8FromUI4();
5835   test_VarR8FromR4();
5836   test_VarR8FromBool();
5837   test_VarR8FromCy();
5838   test_VarR8FromI8();
5839   test_VarR8FromUI8();
5840   test_VarR8FromDec();
5841   test_VarR8FromDate();
5842   test_VarR8FromStr();
5843   test_VarR8Copy();
5844   test_VarR8ChangeTypeEx();
5845   test_VarR8Round();
5846
5847   test_VarDateFromI1();
5848   test_VarDateFromUI1();
5849   test_VarDateFromI2();
5850   test_VarDateFromUI2();
5851   test_VarDateFromI4();
5852   test_VarDateFromUI4();
5853   test_VarDateFromR4();
5854   test_VarDateFromR8();
5855   test_VarDateFromBool();
5856   test_VarDateFromCy();
5857   test_VarDateFromI8();
5858   test_VarDateFromUI8();
5859   test_VarDateFromDec();
5860   test_VarDateFromStr();
5861   test_VarDateCopy();
5862   test_VarDateChangeTypeEx();
5863
5864   test_VarCyFromI1();
5865   test_VarCyFromUI1();
5866   test_VarCyFromI2();
5867   test_VarCyFromUI2();
5868   test_VarCyFromI4();
5869   test_VarCyFromUI4();
5870   test_VarCyFromR4();
5871   test_VarCyFromR8();
5872   test_VarCyFromBool();
5873   test_VarCyFromI8();
5874   test_VarCyFromUI8();
5875   test_VarCyFromDec();
5876   test_VarCyFromDate();
5877
5878   test_VarCyAdd();
5879   test_VarCyMul();
5880   test_VarCySub();
5881   test_VarCyAbs();
5882   test_VarCyNeg();
5883   test_VarCyMulI4();
5884   test_VarCyMulI8();
5885   test_VarCyCmp();
5886   test_VarCyCmpR8();
5887   test_VarCyRound();
5888   test_VarCyFix();
5889   test_VarCyInt();
5890
5891   test_VarDecFromI1();
5892   test_VarDecFromI2();
5893   test_VarDecFromI4();
5894   test_VarDecFromI8();
5895   test_VarDecFromUI1();
5896   test_VarDecFromUI2();
5897   test_VarDecFromUI4();
5898   test_VarDecFromUI8();
5899   test_VarDecFromR4();
5900   test_VarDecFromR8();
5901   test_VarDecFromDate();
5902   test_VarDecFromStr();
5903   test_VarDecFromCy();
5904   test_VarDecFromDate();
5905   test_VarDecFromBool();
5906
5907   test_VarDecAbs();
5908   test_VarDecNeg();
5909   test_VarDecAdd();
5910   test_VarDecSub();
5911   test_VarDecCmp();
5912   test_VarDecMul();
5913   test_VarDecDiv();
5914
5915   test_VarBoolFromI1();
5916   test_VarBoolFromUI1();
5917   test_VarBoolFromI2();
5918   test_VarBoolFromUI2();
5919   test_VarBoolFromI4();
5920   test_VarBoolFromUI4();
5921   test_VarBoolFromR4();
5922   test_VarBoolFromR8();
5923   test_VarBoolFromCy();
5924   test_VarBoolFromI8();
5925   test_VarBoolFromUI8();
5926   test_VarBoolFromDec();
5927   test_VarBoolFromDate();
5928   test_VarBoolFromStr();
5929   test_VarBoolCopy();
5930   test_VarBoolChangeTypeEx();
5931
5932   test_VarBstrFromR4();
5933   test_VarBstrFromDate();
5934   test_VarBstrFromDec();
5935   test_VarBstrCmp();
5936   test_SysStringLen();
5937   test_SysStringByteLen();
5938   test_SysAllocString();
5939   test_SysAllocStringLen();
5940   test_SysAllocStringByteLen();
5941   test_SysReAllocString();
5942   test_SysReAllocStringLen();
5943   test_BstrCopy();
5944
5945   test_IUnknownClear();
5946   test_IUnknownCopy();
5947   test_IUnknownChangeTypeEx();
5948
5949   test_IDispatchClear();
5950   test_IDispatchCopy();
5951   test_IDispatchChangeTypeEx();
5952
5953   test_ErrorChangeTypeEx();
5954   test_EmptyChangeTypeEx();
5955   test_NullChangeTypeEx();
5956   test_UintChangeTypeEx();
5957
5958   test_ClearCustData();
5959
5960   test_NullByRef();
5961   test_ChangeType_keep_dst();
5962 }