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