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