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