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