wined3d: Remove COM from the shader implementation.
[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("02.01.1970 00:00:00"); EXPECT_DBL(25570.0);
3462   lcid = MAKELCID(MAKELANGID(LANG_SPANISH,SUBLANG_SPANISH),SORT_DEFAULT);
3463   DFS("02.01.1970"); EXPECT_MISMATCH;
3464   DFS("02.01.1970 00:00:00"); EXPECT_MISMATCH;
3465 }
3466
3467 static void test_VarDateCopy(void)
3468 {
3469   COPYTEST(77665544.0, VT_DATE, V_DATE(&vSrc), V_DATE(&vDst), V_DATEREF(&vSrc),
3470            V_DATEREF(&vDst), "%16.16g");
3471 }
3472
3473 static const char* wtoascii(LPWSTR lpszIn)
3474 {
3475     static char buff[256];
3476     WideCharToMultiByte(CP_ACP, 0, lpszIn, -1, buff, sizeof(buff), NULL, NULL);
3477     return buff;
3478 }
3479
3480 static void test_VarDateChangeTypeEx(void)
3481 {
3482   static const WCHAR sz25570[] = {
3483     '1','/','2','/','1','9','7','0','\0' };
3484   static const WCHAR sz25570_2[] = {
3485           '1','/','2','/','7','0','\0' };
3486   static const WCHAR sz25570Nls[] = {
3487     '1','/','2','/','1','9','7','0',' ','1','2',':','0','0',':','0','0',' ','A','M','\0' };
3488   CONVVARS(CONV_TYPE);
3489   VARIANTARG vSrc, vDst;
3490   LCID lcid;
3491
3492   in = 1.0;
3493
3494 #ifdef HAS_UINT64_TO_FLOAT
3495   INITIAL_TYPETEST(VT_DATE, V_DATE, "%g");
3496   COMMON_TYPETEST;
3497 #endif
3498
3499   V_VT(&vDst) = VT_EMPTY;
3500   V_VT(&vSrc) = VT_DATE;
3501   V_DATE(&vSrc) = 25570.0;
3502   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3503
3504   hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, VARIANT_NOUSEROVERRIDE, VT_BSTR); 
3505   ok(hres == S_OK && V_VT(&vDst) == VT_BSTR && V_BSTR(&vDst) &&
3506           (!lstrcmpW(V_BSTR(&vDst), sz25570) || !lstrcmpW(V_BSTR(&vDst), sz25570_2)),
3507           "hres=0x%X, type=%d (should be VT_BSTR), *bstr=%s\n", 
3508           hres, V_VT(&vDst), V_BSTR(&vDst) ? wtoascii(V_BSTR(&vDst)) : "?");
3509   VariantClear(&vDst);
3510
3511   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3512   if (HAVE_OLEAUT32_LOCALES)
3513   {
3514     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, VARIANT_NOUSEROVERRIDE|VARIANT_USE_NLS, VT_BSTR);
3515     ok(hres == S_OK && V_VT(&vDst) == VT_BSTR && V_BSTR(&vDst) && !lstrcmpW(V_BSTR(&vDst), sz25570Nls), 
3516             "hres=0x%X, type=%d (should be VT_BSTR), *bstr=%s\n", 
3517             hres, V_VT(&vDst), V_BSTR(&vDst) ? wtoascii(V_BSTR(&vDst)) : "?");
3518     VariantClear(&vDst);
3519   }
3520 }
3521
3522 /*
3523  * VT_CY
3524  */
3525
3526 #undef CONV_TYPE
3527 #define CONV_TYPE CY
3528 #undef EXPECTRES
3529 #define EXPECTRES(res, x) \
3530   ok(hres == S_OK || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
3531      "expected hres " #x ", got hres=0x%08x\n", hres)
3532
3533 #define EXPECTCY(x) \
3534   ok((hres == S_OK && out.int64 == (LONGLONG)(x*CY_MULTIPLIER)), \
3535      "expected " #x "*CY_MULTIPLIER, got (%8x %8x); hres=0x%08x\n", S(out).Hi, S(out).Lo, hres)
3536
3537 #define EXPECTCY64(x,y) \
3538   ok(hres == S_OK && S(out).Hi == (LONG)x && S(out).Lo == y, \
3539      "expected " #x " " #y " (%u,%u), got (%u,%u); hres=0x%08x\n", \
3540       (ULONG)(x), (ULONG)(y), S(out).Hi, S(out).Lo, hres)
3541
3542 static void test_VarCyFromI1(void)
3543 {
3544   CONVVARS(signed char);
3545   int i;
3546
3547   CHECKPTR(VarCyFromI1);
3548   for (i = -128; i < 128; i++)
3549   {
3550     CONVERT(VarCyFromI1,i); EXPECTCY(i);
3551   }
3552 }
3553
3554 static void test_VarCyFromUI1(void)
3555 {
3556   CONVVARS(BYTE);
3557   int i;
3558
3559   CHECKPTR(VarCyFromUI1);
3560   for (i = 0; i < 256; i++)
3561   {
3562     CONVERT(VarCyFromUI1,i); EXPECTCY(i);
3563   }
3564 }
3565
3566 static void test_VarCyFromI2(void)
3567 {
3568   CONVVARS(SHORT);
3569   int i;
3570
3571   CHECKPTR(VarCyFromI2);
3572   for (i = -16384; i < 16384; i++)
3573   {
3574     CONVERT(VarCyFromI2,i); EXPECTCY(i);
3575   }
3576 }
3577
3578 static void test_VarCyFromUI2(void)
3579 {
3580   CONVVARS(int);
3581   int i;
3582
3583   CHECKPTR(VarCyFromUI2);
3584   for (i = 0; i < 32768; i++)
3585   {
3586     CONVERT(VarCyFromUI2,i); EXPECTCY(i);
3587   }
3588 }
3589
3590 static void test_VarCyFromI4(void)
3591 {
3592   CONVVARS(int);
3593
3594   CHECKPTR(VarCyFromI4);
3595   CONVERT(VarCyFromI4, -1);         EXPECTCY(-1);
3596   CONVERT(VarCyFromI4, 0);          EXPECTCY(0);
3597   CONVERT(VarCyFromI4, 1);          EXPECTCY(1);
3598   CONVERT(VarCyFromI4, 0x7fffffff); EXPECTCY64(0x1387, 0xffffd8f0);
3599   CONVERT(VarCyFromI4, 0x80000000); EXPECTCY64(0xffffec78, 0);
3600 }
3601
3602 static void test_VarCyFromUI4(void)
3603 {
3604   CONVVARS(unsigned int);
3605
3606   CHECKPTR(VarCyFromUI4);
3607   CONVERT(VarCyFromUI4, 0); EXPECTCY(0);
3608   CONVERT(VarCyFromUI4, 1); EXPECTCY(1);
3609   CONVERT(VarCyFromUI4, 0x80000000); EXPECTCY64(5000, 0);
3610 }
3611
3612 static void test_VarCyFromR4(void)
3613 {
3614   CONVVARS(FLOAT);
3615
3616   CHECKPTR(VarCyFromR4);
3617   CONVERT(VarCyFromR4, -1.0f); EXPECTCY(-1);
3618   CONVERT(VarCyFromR4, 0.0f);  EXPECTCY(0);
3619   CONVERT(VarCyFromR4, 1.0f);  EXPECTCY(1);
3620   CONVERT(VarCyFromR4, 1.5f);  EXPECTCY(1.5);
3621
3622   CONVERT(VarCyFromR4, -1.5f);     EXPECTCY(-1.5);
3623   CONVERT(VarCyFromR4, -0.6f);     EXPECTCY(-0.6);
3624   CONVERT(VarCyFromR4, -0.5f);     EXPECTCY(-0.5);
3625   CONVERT(VarCyFromR4, -0.4f);     EXPECTCY(-0.4);
3626   CONVERT(VarCyFromR4, 0.4f);      EXPECTCY(0.4);
3627   CONVERT(VarCyFromR4, 0.5f);      EXPECTCY(0.5);
3628   CONVERT(VarCyFromR4, 0.6f);      EXPECTCY(0.6);
3629   CONVERT(VarCyFromR4, 1.5f);      EXPECTCY(1.5);
3630   CONVERT(VarCyFromR4, 1.00009f);  EXPECTCY(1.0001);
3631   CONVERT(VarCyFromR4, -1.00001f); EXPECTCY(-1);
3632   CONVERT(VarCyFromR4, -1.00005f); EXPECTCY(-1);
3633   CONVERT(VarCyFromR4, -0.00009f); EXPECTCY(-0.0001);
3634   CONVERT(VarCyFromR4, -0.00005f); EXPECTCY(0);
3635   CONVERT(VarCyFromR4, -0.00001f); EXPECTCY(0);
3636   CONVERT(VarCyFromR4, 0.00001f);  EXPECTCY(0);
3637   CONVERT(VarCyFromR4, 0.00005f);  EXPECTCY(0);
3638   CONVERT(VarCyFromR4, 0.00009f);  EXPECTCY(0.0001);
3639   CONVERT(VarCyFromR4, -1.00001f); EXPECTCY(-1);
3640   CONVERT(VarCyFromR4, -1.00005f); EXPECTCY(-1);
3641   CONVERT(VarCyFromR4, -1.00009f); EXPECTCY(-1.0001);
3642 }
3643
3644 static void test_VarCyFromR8(void)
3645 {
3646   CONVVARS(DOUBLE);
3647
3648   CHECKPTR(VarCyFromR8);
3649
3650 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
3651   /* Test our rounding is exactly the same. This fails if the special x86
3652    * code is taken out of VarCyFromR8.
3653    */
3654   CONVERT(VarCyFromR8, -461168601842738.7904); EXPECTCY64(0xbfffffff, 0xffffff23);
3655 #endif
3656
3657   CONVERT(VarCyFromR8, -4611686018427388416.1); EXPECT_OVERFLOW;
3658   CONVERT(VarCyFromR8, -1.0);                   EXPECTCY(-1);
3659   CONVERT(VarCyFromR8, -0.0);                   EXPECTCY(0);
3660   CONVERT(VarCyFromR8, 1.0);                    EXPECTCY(1);
3661   CONVERT(VarCyFromR8, 4611686018427387648.0);  EXPECT_OVERFLOW;
3662
3663   /* Rounding */
3664   CONVERT(VarCyFromR8, -1.5f);     EXPECTCY(-1.5);
3665   CONVERT(VarCyFromR8, -0.6f);     EXPECTCY(-0.6);
3666   CONVERT(VarCyFromR8, -0.5f);     EXPECTCY(-0.5);
3667   CONVERT(VarCyFromR8, -0.4f);     EXPECTCY(-0.4);
3668   CONVERT(VarCyFromR8, 0.4f);      EXPECTCY(0.4);
3669   CONVERT(VarCyFromR8, 0.5f);      EXPECTCY(0.5);
3670   CONVERT(VarCyFromR8, 0.6f);      EXPECTCY(0.6);
3671   CONVERT(VarCyFromR8, 1.5f);      EXPECTCY(1.5);
3672   CONVERT(VarCyFromR8, 1.00009f);  EXPECTCY(1.0001);
3673   CONVERT(VarCyFromR8, -1.00001f); EXPECTCY(-1);
3674   CONVERT(VarCyFromR8, -1.00005f); EXPECTCY(-1);
3675   CONVERT(VarCyFromR8, -0.00009f); EXPECTCY(-0.0001);
3676   CONVERT(VarCyFromR8, -0.00005f); EXPECTCY(0);
3677   CONVERT(VarCyFromR8, -0.00001f); EXPECTCY(0);
3678   CONVERT(VarCyFromR8, 0.00001f);  EXPECTCY(0);
3679   CONVERT(VarCyFromR8, 0.00005f);  EXPECTCY(0);
3680   CONVERT(VarCyFromR8, 0.00009f);  EXPECTCY(0.0001);
3681   CONVERT(VarCyFromR8, -1.00001f); EXPECTCY(-1);
3682   CONVERT(VarCyFromR8, -1.00005f); EXPECTCY(-1);
3683   CONVERT(VarCyFromR8, -1.00009f); EXPECTCY(-1.0001);
3684 }
3685
3686 static void test_VarCyFromBool(void)
3687 {
3688   CONVVARS(VARIANT_BOOL);
3689   int i;
3690
3691   CHECKPTR(VarCyFromBool);
3692   for (i = -32768; i < 32768; i++)
3693   {
3694     CONVERT(VarCyFromBool, i);  EXPECTCY(i);
3695   }
3696 }
3697
3698 static void test_VarCyFromI8(void)
3699 {
3700   CONVVARS(LONG64);
3701
3702   CHECKPTR(VarCyFromI8);
3703   CONVERT_I8(VarCyFromI8, -214749, 2728163227ul);   EXPECT_OVERFLOW;
3704   CONVERT_I8(VarCyFromI8, -214749, 2728163228ul);   EXPECTCY64(2147483648ul,15808);
3705   CONVERT(VarCyFromI8, -1); EXPECTCY(-1);
3706   CONVERT(VarCyFromI8, 0);  EXPECTCY(0);
3707   CONVERT(VarCyFromI8, 1);  EXPECTCY(1);
3708   CONVERT_I8(VarCyFromI8, 214748, 1566804068); EXPECTCY64(2147483647ul, 4294951488ul);
3709   CONVERT_I8(VarCyFromI8, 214748, 1566804069); EXPECT_OVERFLOW;
3710 }
3711
3712 static void test_VarCyFromUI8(void)
3713 {
3714   CONVVARS(ULONG64);
3715
3716   CHECKPTR(VarCyFromUI8);
3717   CONVERT(VarCyFromUI8, 0); EXPECTCY(0);
3718   CONVERT(VarCyFromUI8, 1); EXPECTCY(1);
3719   CONVERT_I8(VarCyFromUI8, 214748, 1566804068); EXPECTCY64(2147483647ul, 4294951488ul);
3720   CONVERT_I8(VarCyFromUI8, 214748, 1566804069); EXPECT_OVERFLOW;
3721 }
3722
3723 static void test_VarCyFromDec(void)
3724 {
3725   CONVVARS(DECIMAL);
3726
3727   CHECKPTR(VarCyFromDec);
3728
3729   CONVERT_BADDEC(VarCyFromDec);
3730
3731   CONVERT_DEC(VarCyFromDec,0,0x80,0,1); EXPECTCY(-1);
3732   CONVERT_DEC(VarCyFromDec,0,0,0,0);    EXPECTCY(0);
3733   CONVERT_DEC(VarCyFromDec,0,0,0,1);    EXPECTCY(1);
3734
3735   CONVERT_DEC64(VarCyFromDec,0,0,0,214748, 1566804068); EXPECTCY64(2147483647ul, 4294951488ul);
3736   CONVERT_DEC64(VarCyFromDec,0,0,0,214748, 1566804069); EXPECT_OVERFLOW;
3737
3738   CONVERT_DEC(VarCyFromDec,2,0,0,100);     EXPECTCY(1);
3739   CONVERT_DEC(VarCyFromDec,2,0x80,0,100);  EXPECTCY(-1);
3740   CONVERT_DEC(VarCyFromDec,2,0x80,0,1);    EXPECTCY(-0.01);
3741   CONVERT_DEC(VarCyFromDec,2,0,0,1);       EXPECTCY(0.01);
3742   CONVERT_DEC(VarCyFromDec,2,0x80,0,1);    EXPECTCY(-0.01);
3743   CONVERT_DEC(VarCyFromDec,2,0,0,999);     EXPECTCY(9.99);
3744   CONVERT_DEC(VarCyFromDec,2,0x80,0,999);  EXPECTCY(-9.99);
3745   CONVERT_DEC(VarCyFromDec,2,0,0,1500);    EXPECTCY(15);
3746   CONVERT_DEC(VarCyFromDec,2,0x80,0,1500); EXPECTCY(-15);
3747 }
3748
3749 static void test_VarCyFromDate(void)
3750 {
3751   CONVVARS(DATE);
3752
3753   CHECKPTR(VarCyFromDate);
3754
3755 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
3756   CONVERT(VarCyFromR8, -461168601842738.7904); EXPECTCY64(0xbfffffff, 0xffffff23);
3757 #endif
3758
3759   CONVERT(VarCyFromDate, -1.0); EXPECTCY(-1);
3760   CONVERT(VarCyFromDate, -0.0); EXPECTCY(0);
3761   CONVERT(VarCyFromDate, 1.0);  EXPECTCY(1);
3762   CONVERT(VarCyFromDate, -4611686018427388416.1); EXPECT_OVERFLOW;
3763   CONVERT(VarCyFromDate, 4611686018427387648.0);  EXPECT_OVERFLOW;
3764
3765   /* Rounding */
3766   CONVERT(VarCyFromDate, -1.5f);     EXPECTCY(-1.5);
3767   CONVERT(VarCyFromDate, -0.6f);     EXPECTCY(-0.6);
3768   CONVERT(VarCyFromDate, -0.5f);     EXPECTCY(-0.5);
3769   CONVERT(VarCyFromDate, -0.4f);     EXPECTCY(-0.4);
3770   CONVERT(VarCyFromDate, 0.4f);      EXPECTCY(0.4);
3771   CONVERT(VarCyFromDate, 0.5f);      EXPECTCY(0.5);
3772   CONVERT(VarCyFromDate, 0.6f);      EXPECTCY(0.6);
3773   CONVERT(VarCyFromDate, 1.5f);      EXPECTCY(1.5);
3774   CONVERT(VarCyFromDate, 1.00009f);  EXPECTCY(1.0001);
3775   CONVERT(VarCyFromDate, -1.00001f); EXPECTCY(-1);
3776   CONVERT(VarCyFromDate, -1.00005f); EXPECTCY(-1);
3777   CONVERT(VarCyFromDate, -0.00009f); EXPECTCY(-0.0001);
3778   CONVERT(VarCyFromDate, -0.00005f); EXPECTCY(0);
3779   CONVERT(VarCyFromDate, -0.00001f); EXPECTCY(0);
3780   CONVERT(VarCyFromDate, 0.00001f);  EXPECTCY(0);
3781   CONVERT(VarCyFromDate, 0.00005f);  EXPECTCY(0);
3782   CONVERT(VarCyFromDate, 0.00009f);  EXPECTCY(0.0001);
3783   CONVERT(VarCyFromDate, -1.00001f); EXPECTCY(-1);
3784   CONVERT(VarCyFromDate, -1.00005f); EXPECTCY(-1);
3785   CONVERT(VarCyFromDate, -1.00009f); EXPECTCY(-1.0001);
3786 }
3787
3788 #define MATHVARS1 HRESULT hres; double left = 0.0; CY cyLeft, out
3789 #define MATHVARS2 MATHVARS1; double right = 0.0; CY cyRight
3790 #define MATH1(func, l) left = (double)l; pVarCyFromR8(left, &cyLeft); hres = p##func(cyLeft, &out)
3791 #define MATH2(func, l, r) left = (double)l; right = (double)r; \
3792   pVarCyFromR8(left, &cyLeft); pVarCyFromR8(right, &cyRight); \
3793   hres = p##func(cyLeft, cyRight, &out)
3794
3795 static void test_VarCyAdd(void)
3796 {
3797   MATHVARS2;
3798
3799   CHECKPTR(VarCyAdd);
3800   MATH2(VarCyAdd, 0.5, 0.5);   EXPECTCY(1);
3801   MATH2(VarCyAdd, 0.5, -0.4);  EXPECTCY(0.1);
3802   MATH2(VarCyAdd, 0.5, -0.6);  EXPECTCY(-0.1);
3803   MATH2(VarCyAdd, -0.5, -0.5); EXPECTCY(-1);
3804   MATH2(VarCyAdd, -922337203685476.0, -922337203685476.0); EXPECT_OVERFLOW;
3805   MATH2(VarCyAdd, -922337203685476.0, 922337203685476.0);  EXPECTCY(0);
3806   MATH2(VarCyAdd, 922337203685476.0, -922337203685476.0);  EXPECTCY(0);
3807   MATH2(VarCyAdd, 922337203685476.0, 922337203685476.0);   EXPECT_OVERFLOW;
3808 }
3809
3810 static void test_VarCyMul(void)
3811 {
3812   MATHVARS2;
3813
3814   CHECKPTR(VarCyMul);
3815   MATH2(VarCyMul, 534443.0, 0.0); EXPECTCY(0);
3816   MATH2(VarCyMul, 0.5, 0.5);      EXPECTCY(0.25);
3817   MATH2(VarCyMul, 0.5, -0.4);     EXPECTCY(-0.2);
3818   MATH2(VarCyMul, 0.5, -0.6);     EXPECTCY(-0.3);
3819   MATH2(VarCyMul, -0.5, -0.5);    EXPECTCY(0.25);
3820   MATH2(VarCyMul, 922337203685476.0, 20000); EXPECT_OVERFLOW;
3821 }
3822
3823 static void test_VarCySub(void)
3824 {
3825   MATHVARS2;
3826
3827   CHECKPTR(VarCySub);
3828   MATH2(VarCySub, 0.5, 0.5);   EXPECTCY(0);
3829   MATH2(VarCySub, 0.5, -0.4);  EXPECTCY(0.9);
3830   MATH2(VarCySub, 0.5, -0.6);  EXPECTCY(1.1);
3831   MATH2(VarCySub, -0.5, -0.5); EXPECTCY(0);
3832   MATH2(VarCySub, -922337203685476.0, -922337203685476.0); EXPECTCY(0);
3833   MATH2(VarCySub, -922337203685476.0, 922337203685476.0);  EXPECT_OVERFLOW;
3834   MATH2(VarCySub, 922337203685476.0, -922337203685476.0);  EXPECT_OVERFLOW;
3835   MATH2(VarCySub, 922337203685476.0, 922337203685476.0);   EXPECTCY(0);
3836 }
3837
3838 static void test_VarCyAbs(void)
3839 {
3840   MATHVARS1;
3841
3842   CHECKPTR(VarCyAbs);
3843   MATH1(VarCyAbs, 0.5);  EXPECTCY(0.5);
3844   MATH1(VarCyAbs, -0.5); EXPECTCY(0.5);
3845   MATH1(VarCyAbs, 922337203685476.0);  EXPECTCY64(2147483647ul,4294951488ul);
3846   MATH1(VarCyAbs, -922337203685476.0); EXPECTCY64(2147483647ul,4294951488ul);
3847 }
3848
3849 static void test_VarCyNeg(void)
3850 {
3851   MATHVARS1;
3852
3853   CHECKPTR(VarCyNeg);
3854   MATH1(VarCyNeg, 0.5); EXPECTCY(-0.5);
3855   MATH1(VarCyNeg, -0.5); EXPECTCY(0.5);
3856   MATH1(VarCyNeg, 922337203685476.0);  EXPECTCY64(2147483648ul,15808);
3857   MATH1(VarCyNeg, -922337203685476.0); EXPECTCY64(2147483647ul,4294951488ul);
3858 }
3859
3860 #define MATHMULI4(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
3861   hres = pVarCyMulI4(cyLeft, right, &out)
3862
3863 static void test_VarCyMulI4(void)
3864 {
3865   MATHVARS1;
3866   LONG right;
3867
3868   CHECKPTR(VarCyMulI4);
3869   MATHMULI4(534443.0, 0); EXPECTCY(0);
3870   MATHMULI4(0.5, 1);      EXPECTCY(0.5);
3871   MATHMULI4(0.5, 2);      EXPECTCY(1);
3872   MATHMULI4(922337203685476.0, 1); EXPECTCY64(2147483647ul,4294951488ul);
3873   MATHMULI4(922337203685476.0, 2); EXPECT_OVERFLOW;
3874 }
3875
3876 #define MATHMULI8(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
3877   hres = pVarCyMulI8(cyLeft, right, &out)
3878
3879 static void test_VarCyMulI8(void)
3880 {
3881   MATHVARS1;
3882   LONG64 right;
3883
3884   CHECKPTR(VarCyMulI8);
3885   MATHMULI8(534443.0, 0); EXPECTCY(0);
3886   MATHMULI8(0.5, 1);      EXPECTCY(0.5);
3887   MATHMULI8(0.5, 2);      EXPECTCY(1);
3888   MATHMULI8(922337203685476.0, 1); EXPECTCY64(2147483647ul,4294951488ul);
3889   MATHMULI8(922337203685476.0, 2); EXPECT_OVERFLOW;
3890 }
3891
3892 #define MATHCMP(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); pVarCyFromR8(right, &cyRight); \
3893   hres = pVarCyCmp(cyLeft, cyRight); out.int64 = hres
3894
3895 static void test_VarCyCmp(void)
3896 {
3897   MATHVARS2;
3898
3899   CHECKPTR(VarCyCmp);
3900   MATHCMP(-1.0, -1.0); EXPECT_EQ;
3901   MATHCMP(-1.0, 0.0);  EXPECT_LT;
3902   MATHCMP(-1.0, 1.0);  EXPECT_LT;
3903   MATHCMP(-1.0, 2.0);  EXPECT_LT;
3904   MATHCMP(0.0, 1.0);   EXPECT_LT;
3905   MATHCMP(0.0, 0.0);   EXPECT_EQ;
3906   MATHCMP(0.0, -1.0);  EXPECT_GT;
3907   MATHCMP(1.0, -1.0);  EXPECT_GT;
3908   MATHCMP(1.0, 0.0);   EXPECT_GT;
3909   MATHCMP(1.0, 1.0);   EXPECT_EQ;
3910   MATHCMP(1.0, 2.0);   EXPECT_LT;
3911 }
3912
3913 #define MATHCMPR8(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
3914   hres = pVarCyCmpR8(cyLeft, right); out.int64 = hres
3915
3916 static void test_VarCyCmpR8(void)
3917 {
3918   MATHVARS1;
3919   double right;
3920
3921   CHECKPTR(VarCyCmpR8);
3922   MATHCMPR8(-1.0, -1.0); EXPECT_EQ;
3923   MATHCMPR8(-1.0, 0.0);  EXPECT_LT;
3924   MATHCMPR8(-1.0, 1.0);  EXPECT_LT;
3925   MATHCMPR8(-1.0, 2.0);  EXPECT_LT;
3926   MATHCMPR8(0.0, 1.0);   EXPECT_LT;
3927   MATHCMPR8(0.0, 0.0);   EXPECT_EQ;
3928   MATHCMPR8(0.0, -1.0);  EXPECT_GT;
3929   MATHCMPR8(1.0, -1.0);  EXPECT_GT;
3930   MATHCMPR8(1.0, 0.0);   EXPECT_GT;
3931   MATHCMPR8(1.0, 1.0);   EXPECT_EQ;
3932   MATHCMPR8(1.0, 2.0);   EXPECT_LT;
3933 }
3934
3935 #undef MATHRND
3936 #define MATHRND(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
3937   hres = pVarCyRound(cyLeft, right, &out)
3938
3939 static void test_VarCyRound(void)
3940 {
3941   MATHVARS1;
3942   int right;
3943
3944   CHECKPTR(VarCyRound);
3945   MATHRND(0.5432, 5);  EXPECTCY(0.5432);
3946   MATHRND(0.5432, 4);  EXPECTCY(0.5432);
3947   MATHRND(0.5432, 3);  EXPECTCY(0.543);
3948   MATHRND(0.5432, 2);  EXPECTCY(0.54);
3949   MATHRND(0.5432, 1);  EXPECTCY(0.5);
3950   MATHRND(0.5532, 0);  EXPECTCY(1);
3951   MATHRND(0.5532, -1); EXPECT_INVALID;
3952
3953   MATHRND(0.5568, 5);  EXPECTCY(0.5568);
3954   MATHRND(0.5568, 4);  EXPECTCY(0.5568);
3955   MATHRND(0.5568, 3);  EXPECTCY(0.557);
3956   MATHRND(0.5568, 2);  EXPECTCY(0.56);
3957   MATHRND(0.5568, 1);  EXPECTCY(0.6);
3958   MATHRND(0.5568, 0);  EXPECTCY(1);
3959   MATHRND(0.5568, -1); EXPECT_INVALID;
3960
3961   MATHRND(0.4999, 0); EXPECTCY(0);
3962   MATHRND(0.5000, 0); EXPECTCY(0);
3963   MATHRND(0.5001, 0); EXPECTCY(1);
3964   MATHRND(1.4999, 0); EXPECTCY(1);
3965   MATHRND(1.5000, 0); EXPECTCY(2);
3966   MATHRND(1.5001, 0); EXPECTCY(2);
3967 }
3968
3969 #define MATHFIX(l) left = l; pVarCyFromR8(left, &cyLeft); \
3970   hres = pVarCyFix(cyLeft, &out)
3971
3972 static void test_VarCyFix(void)
3973 {
3974   MATHVARS1;
3975
3976   CHECKPTR(VarCyFix);
3977   MATHFIX(-1.0001); EXPECTCY(-1);
3978   MATHFIX(-1.4999); EXPECTCY(-1);
3979   MATHFIX(-1.5001); EXPECTCY(-1);
3980   MATHFIX(-1.9999); EXPECTCY(-1);
3981   MATHFIX(-0.0001); EXPECTCY(0);
3982   MATHFIX(-0.4999); EXPECTCY(0);
3983   MATHFIX(-0.5001); EXPECTCY(0);
3984   MATHFIX(-0.9999); EXPECTCY(0);
3985   MATHFIX(0.0001);  EXPECTCY(0);
3986   MATHFIX(0.4999);  EXPECTCY(0);
3987   MATHFIX(0.5001);  EXPECTCY(0);
3988   MATHFIX(0.9999);  EXPECTCY(0);
3989   MATHFIX(1.0001);  EXPECTCY(1);
3990   MATHFIX(1.4999);  EXPECTCY(1);
3991   MATHFIX(1.5001);  EXPECTCY(1);
3992   MATHFIX(1.9999);  EXPECTCY(1);
3993 }
3994
3995 #define MATHINT(l) left = l; pVarCyFromR8(left, &cyLeft); \
3996   hres = pVarCyInt(cyLeft, &out)
3997
3998 static void test_VarCyInt(void)
3999 {
4000   MATHVARS1;
4001
4002   CHECKPTR(VarCyInt);
4003   MATHINT(-1.0001); EXPECTCY(-2);
4004   MATHINT(-1.4999); EXPECTCY(-2);
4005   MATHINT(-1.5001); EXPECTCY(-2);
4006   MATHINT(-1.9999); EXPECTCY(-2);
4007   MATHINT(-0.0001); EXPECTCY(-1);
4008   MATHINT(-0.4999); EXPECTCY(-1);
4009   MATHINT(-0.5001); EXPECTCY(-1);
4010   MATHINT(-0.9999); EXPECTCY(-1);
4011   MATHINT(0.0001);  EXPECTCY(0);
4012   MATHINT(0.4999);  EXPECTCY(0);
4013   MATHINT(0.5001);  EXPECTCY(0);
4014   MATHINT(0.9999);  EXPECTCY(0);
4015   MATHINT(1.0001);  EXPECTCY(1);
4016   MATHINT(1.4999);  EXPECTCY(1);
4017   MATHINT(1.5001);  EXPECTCY(1);
4018   MATHINT(1.9999);  EXPECTCY(1);
4019 }
4020
4021 /*
4022  * VT_DECIMAL
4023  */
4024
4025 #undef CONV_TYPE
4026 #define CONV_TYPE DECIMAL
4027 #undef EXPECTRES
4028 #define EXPECTRES(res, x) \
4029   ok(hres == S_OK || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
4030      "expected hres " #x ", got hres=0x%08x\n", hres)
4031
4032 #define EXPECTDEC(scl, sgn, hi, lo) ok(hres == S_OK && \
4033   S(U(out)).scale == (BYTE)(scl) && S(U(out)).sign == (BYTE)(sgn) && \
4034   out.Hi32 == (ULONG)(hi) && U1(out).Lo64 == (ULONG64)(lo), \
4035   "expected (%d,%d,%d,(%x %x)), got (%d,%d,%d,(%x %x)) hres 0x%08x\n", \
4036   scl, sgn, hi, (LONG)((LONG64)(lo) >> 32), (LONG)((lo) & 0xffffffff), S(U(out)).scale, \
4037   S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres)
4038
4039 #define EXPECTDEC64(scl, sgn, hi, mid, lo) ok(hres == S_OK && \
4040   S(U(out)).scale == (BYTE)(scl) && S(U(out)).sign == (BYTE)(sgn) && \
4041   out.Hi32 == (ULONG)(hi) && S1(U1(out)).Mid32 == (ULONG)(mid) && \
4042   S1(U1(out)).Lo32 == (ULONG)(lo), \
4043   "expected (%d,%d,%d,(%x %x)), got (%d,%d,%d,(%x %x)) hres 0x%08x\n", \
4044   scl, sgn, hi, (LONG)(mid), (LONG)(lo), S(U(out)).scale, \
4045   S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres)
4046
4047 /* expect either a positive or negative zero */
4048 #define EXPECTDECZERO() ok(hres == S_OK && S(U(out)).scale == 0 && \
4049   (S(U(out)).sign == 0 || S(U(out)).sign == 0x80) && out.Hi32 == 0 && U1(out).Lo64 == 0, \
4050   "expected zero, got (%d,%d,%d,(%x %x)) hres 0x%08x\n", \
4051   S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres)
4052
4053 #define EXPECTDECI if (i < 0) EXPECTDEC(0, 0x80, 0, -i); else EXPECTDEC(0, 0, 0, i)
4054
4055 static void test_VarDecFromI1(void)
4056 {
4057   CONVVARS(signed char);
4058   int i;
4059
4060   CHECKPTR(VarDecFromI1);
4061   for (i = -128; i < 128; i++)
4062   {
4063     CONVERT(VarDecFromI1,i); EXPECTDECI;
4064   }
4065 }
4066
4067 static void test_VarDecFromI2(void)
4068 {
4069   CONVVARS(SHORT);
4070   int i;
4071
4072   CHECKPTR(VarDecFromI2);
4073   for (i = -32768; i < 32768; i++)
4074   {
4075     CONVERT(VarDecFromI2,i); EXPECTDECI;
4076   }
4077 }
4078
4079 static void test_VarDecFromI4(void)
4080 {
4081   CONVVARS(LONG);
4082   int i;
4083
4084   CHECKPTR(VarDecFromI4);
4085   for (i = -32768; i < 32768; i++)
4086   {
4087     CONVERT(VarDecFromI4,i); EXPECTDECI;
4088   }
4089 }
4090
4091 static void test_VarDecFromI8(void)
4092 {
4093   CONVVARS(LONG64);
4094   int i;
4095
4096   CHECKPTR(VarDecFromI8);
4097   for (i = -32768; i < 32768; i++)
4098   {
4099     CONVERT(VarDecFromI8,i); EXPECTDECI;
4100   }
4101 }
4102
4103 static void test_VarDecFromUI1(void)
4104 {
4105   CONVVARS(BYTE);
4106   int i;
4107
4108   CHECKPTR(VarDecFromUI1);
4109   for (i = 0; i < 256; i++)
4110   {
4111     CONVERT(VarDecFromUI1,i); EXPECTDECI;
4112   }
4113 }
4114
4115 static void test_VarDecFromUI2(void)
4116 {
4117   CONVVARS(USHORT);
4118   int i;
4119
4120   CHECKPTR(VarDecFromUI2);
4121   for (i = 0; i < 65536; i++)
4122   {
4123     CONVERT(VarDecFromUI2,i); EXPECTDECI;
4124   }
4125 }
4126
4127 static void test_VarDecFromUI4(void)
4128 {
4129   CONVVARS(ULONG);
4130   int i;
4131
4132   CHECKPTR(VarDecFromUI4);
4133   for (i = 0; i < 65536; i++)
4134   {
4135     CONVERT(VarDecFromUI4,i); EXPECTDECI;
4136   }
4137 }
4138
4139 static void test_VarDecFromUI8(void)
4140 {
4141   CONVVARS(ULONG64);
4142   int i;
4143
4144   CHECKPTR(VarDecFromUI8);
4145   for (i = 0; i < 65536; i++)
4146   {
4147     CONVERT(VarDecFromUI8,i); EXPECTDECI;
4148   }
4149 }
4150
4151 static void test_VarDecFromBool(void)
4152 {
4153   CONVVARS(SHORT);
4154   int i;
4155
4156   CHECKPTR(VarDecFromBool);
4157   /* Test all possible type values. Note that the result is reduced to 0 or -1 */
4158   for (i = -32768; i < 0; i++)
4159   {
4160     CONVERT(VarDecFromBool,i);
4161     if (i)
4162       EXPECTDEC(0,0x80,0,1);
4163     else
4164       EXPECTDEC(0,0,0,0);
4165   }
4166 }
4167
4168 static void test_VarDecFromR4(void)
4169 {
4170   CONVVARS(float);
4171
4172   CHECKPTR(VarDecFromR4);
4173
4174   CONVERT(VarDecFromR4,-0.6f); EXPECTDEC(1,0x80,0,6);
4175   CONVERT(VarDecFromR4,-0.5f); EXPECTDEC(1,0x80,0,5);
4176   CONVERT(VarDecFromR4,-0.4f); EXPECTDEC(1,0x80,0,4);
4177   CONVERT(VarDecFromR4,0.0f);  EXPECTDEC(0,0,0,0);
4178   CONVERT(VarDecFromR4,0.4f);  EXPECTDEC(1,0,0,4);
4179   CONVERT(VarDecFromR4,0.5f);  EXPECTDEC(1,0,0,5);
4180   CONVERT(VarDecFromR4,0.6f);  EXPECTDEC(1,0,0,6);
4181 }
4182
4183 static void test_VarDecFromR8(void)
4184 {
4185   CONVVARS(double);
4186
4187   CHECKPTR(VarDecFromR8);
4188
4189   CONVERT(VarDecFromR8,-0.6); EXPECTDEC(1,0x80,0,6);
4190   CONVERT(VarDecFromR8,-0.5); EXPECTDEC(1,0x80,0,5);
4191   CONVERT(VarDecFromR8,-0.4); EXPECTDEC(1,0x80,0,4);
4192   CONVERT(VarDecFromR8,0.0);  EXPECTDEC(0,0,0,0);
4193   CONVERT(VarDecFromR8,0.4);  EXPECTDEC(1,0,0,4);
4194   CONVERT(VarDecFromR8,0.5);  EXPECTDEC(1,0,0,5);
4195   CONVERT(VarDecFromR8,0.6);  EXPECTDEC(1,0,0,6);
4196 }
4197
4198 static void test_VarDecFromDate(void)
4199 {
4200   CONVVARS(DATE);
4201
4202   CHECKPTR(VarDecFromDate);
4203
4204   CONVERT(VarDecFromDate,-0.6); EXPECTDEC(1,0x80,0,6);
4205   CONVERT(VarDecFromDate,-0.5); EXPECTDEC(1,0x80,0,5);
4206   CONVERT(VarDecFromDate,-0.4); EXPECTDEC(1,0x80,0,4);
4207   CONVERT(VarDecFromDate,0.0);  EXPECTDEC(0,0,0,0);
4208   CONVERT(VarDecFromDate,0.4);  EXPECTDEC(1,0,0,4);
4209   CONVERT(VarDecFromDate,0.5);  EXPECTDEC(1,0,0,5);
4210   CONVERT(VarDecFromDate,0.6);  EXPECTDEC(1,0,0,6);
4211 }
4212
4213 static void test_VarDecFromStr(void)
4214 {
4215   CONVVARS(LCID);
4216   OLECHAR buff[128];
4217
4218   CHECKPTR(VarDecFromStr);
4219
4220   in = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4221
4222   CONVERT_STR(VarDecFromStr,NULL,0);                       EXPECT_MISMATCH;
4223   CONVERT_STR(VarDecFromStr,"-1",  LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0x80,0,1);
4224   CONVERT_STR(VarDecFromStr,"0",   LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,0,0);
4225   CONVERT_STR(VarDecFromStr,"1",   LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,0,1);
4226   CONVERT_STR(VarDecFromStr,"0.5", LOCALE_NOUSEROVERRIDE); EXPECTDEC(1,0,0,5);
4227   CONVERT_STR(VarDecFromStr,"4294967296", LOCALE_NOUSEROVERRIDE); EXPECTDEC64(0,0,0,1,0);
4228   CONVERT_STR(VarDecFromStr,"18446744073709551616", LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,1,0);
4229   CONVERT_STR(VarDecFromStr,"4294967296.0", LOCALE_NOUSEROVERRIDE); EXPECTDEC64(0,0,0,1,0);
4230   CONVERT_STR(VarDecFromStr,"18446744073709551616.0", LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,1,0);
4231 }
4232
4233 static void test_VarDecFromCy(void)
4234 {
4235   CONVVARS(CY);
4236
4237   CHECKPTR(VarDecFromCy);
4238
4239   CONVERT_CY(VarDecFromCy, -1);  EXPECTDEC(4,0x80,0,10000);
4240   CONVERT_CY(VarDecFromCy, 0);   EXPECTDEC(4,0,0,0);
4241   CONVERT_CY(VarDecFromCy, 1);   EXPECTDEC(4,0,0,10000);
4242   CONVERT_CY(VarDecFromCy, 0.5); EXPECTDEC(4,0,0,5000);
4243 }
4244
4245 #undef MATHVARS1
4246 #define MATHVARS1 HRESULT hres; DECIMAL l, out
4247 #undef MATHVARS2
4248 #define MATHVARS2 MATHVARS1; DECIMAL r
4249 #undef MATH1
4250 #define MATH1(func) hres = p##func(&l, &out)
4251 #undef MATH2
4252 #define MATH2(func) hres = p##func(&l, &r, &out)
4253
4254 static void test_VarDecAbs(void)
4255 {
4256   MATHVARS1;
4257
4258   CHECKPTR(VarDecAbs);
4259   SETDEC(l,0,0x80,0,1);  MATH1(VarDecAbs); EXPECTDEC(0,0,0,1);
4260   SETDEC(l,0,0,0,0);     MATH1(VarDecAbs); EXPECTDEC(0,0,0,0);
4261   SETDEC(l,0,0x80,0,0);  MATH1(VarDecAbs); EXPECTDEC(0,0,0,0);
4262   SETDEC(l,0,0,0,1);     MATH1(VarDecAbs); EXPECTDEC(0,0,0,1);
4263
4264   /* Doesn't check for invalid input */
4265   SETDEC(l,0,0x7f,0,1);  MATH1(VarDecAbs); EXPECTDEC(0,0x7f,0,1);
4266   SETDEC(l,0,0x80,29,1); MATH1(VarDecAbs); EXPECTDEC(0,0,29,1);
4267 }
4268
4269 static void test_VarDecNeg(void)
4270 {
4271   MATHVARS1;
4272
4273   CHECKPTR(VarDecNeg);
4274   SETDEC(l,0,0x80,0,1); MATH1(VarDecNeg); EXPECTDEC(0,0,0,1);
4275   SETDEC(l,0,0,0,0);    MATH1(VarDecNeg); EXPECTDEC(0,0x80,0,0); /* '-0'! */
4276   SETDEC(l,0,0x80,0,0); MATH1(VarDecNeg); EXPECTDEC(0,0,0,0);
4277   SETDEC(l,0,0,0,1);    MATH1(VarDecNeg); EXPECTDEC(0,0x80,0,1);
4278
4279   /* Doesn't check for invalid input */
4280   SETDEC(l,0,0x7f,0,1);  MATH1(VarDecNeg); EXPECTDEC(0,0xff,0,1);
4281   SETDEC(l,0,0x80,29,1); MATH1(VarDecNeg); EXPECTDEC(0,0,29,1);
4282   SETDEC(l,0,0,29,1);    MATH1(VarDecNeg); EXPECTDEC(0,0x80,29,1);
4283 }
4284
4285 static void test_VarDecAdd(void)
4286 {
4287   MATHVARS2;
4288
4289   CHECKPTR(VarDecAdd);
4290   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,0);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,0);
4291   SETDEC(l,0,0,0,0);    SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,1);
4292   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4293
4294   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,0);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4295   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,2);
4296   SETDEC(l,0,0,0,1);    SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDECZERO();
4297   SETDEC(l,0,0,0,1);    SETDEC(r,0,0x80,0,2); MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,1);
4298
4299   SETDEC(l,0,0x80,0,0); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4300   SETDEC(l,0,0x80,0,1); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDECZERO();
4301   SETDEC(l,0,0x80,0,1); SETDEC(r,0,0,0,2);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4302   SETDEC(l,0,0x80,0,1); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,2);
4303   SETDEC(l,0,0x80,0,2); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,1);
4304
4305   SETDEC(l,0,0,0,0xffffffff); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0,0,0xfffffffe);
4306   SETDEC(l,0,0,0,0xffffffff); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,(ULONG64)1 << 32);
4307   SETDEC(l,0,0,0,0xffffffff); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,(ULONG64)1 << 32);
4308
4309   SETDEC64(l,0,0,0,0xffffffff,0); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC64(0,0,0,0xffffffff,1);
4310   SETDEC64(l,0,0,0,0xffffffff,0); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4311   EXPECTDEC64(0,0,0,0xfffffffe,0xffffffff);
4312
4313   SETDEC64(l,0,0,0,0xffffffff,0xffffffff); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,1,0);
4314   SETDEC64(l,0,0,0,0xffffffff,0xffffffff); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4315   EXPECTDEC64(0,0,0,0xffffffff,0xfffffffe);
4316
4317   SETDEC(l,0,0,0xffffffff,0); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0xffffffff,1);
4318   SETDEC(l,0,0,0xffffffff,0); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4319   EXPECTDEC64(0,0,0xfffffffe,0xffffffff,0xffffffff);
4320
4321   SETDEC64(l,0,0,0xffffffff,0xffffffff,0xffffffff);SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4322   EXPECTDEC64(0,0,0xffffffff,0xffffffff,0xfffffffe);
4323   SETDEC64(l,0,0,0xffffffff,0xffffffff,0xffffffff);SETDEC(r,0,0,0,1); MATH2(VarDecAdd);
4324   ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4325      S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4326
4327   /* Promotes to the highest scale, so here the results are in the scale of 2 */
4328   SETDEC(l,2,0,0,0);   SETDEC(r,0,0,0,0); MATH2(VarDecAdd); EXPECTDEC(2,0,0,0);
4329   SETDEC(l,2,0,0,100); SETDEC(r,0,0,0,1); MATH2(VarDecAdd); EXPECTDEC(2,0,0,200);
4330 }
4331
4332 static void test_VarDecSub(void)
4333 {
4334   MATHVARS2;
4335
4336   CHECKPTR(VarDecSub);
4337   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,0);    MATH2(VarDecSub); EXPECTDECZERO();
4338   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,1);    MATH2(VarDecSub); EXPECTDEC(0,0x80,0,1);
4339   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,1);    MATH2(VarDecSub); EXPECTDECZERO();
4340   SETDEC(l,0,0,0,1);    SETDEC(r,0,0x80,0,1); MATH2(VarDecSub); EXPECTDEC(0,0,0,2);
4341 }
4342
4343 static void test_VarDecMul(void)
4344 {
4345   MATHVARS2;
4346   
4347   CHECKPTR(VarDecMul);
4348   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,0);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,0);
4349   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,0);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,0);
4350   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,1);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,0);
4351   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,1);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,1);
4352   SETDEC(l,0,0,0,45000);SETDEC(r,0,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,90000);
4353   SETDEC(l,0,0,0,2);    SETDEC(r,0,0,0,45000);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,90000);
4354
4355   SETDEC(l,0,0x80,0,2); SETDEC(r,0,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(0,0x80,0,4);
4356   SETDEC(l,0,0,0,2);    SETDEC(r,0,0x80,0,2);  MATH2(VarDecMul);   EXPECTDEC(0,0x80,0,4);
4357   SETDEC(l,0,0x80,0,2); SETDEC(r,0,0x80,0,2);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,4);
4358
4359   SETDEC(l,4,0,0,2);    SETDEC(r,0,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(4,0,0,4);
4360   SETDEC(l,0,0,0,2);    SETDEC(r,3,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(3,0,0,4);
4361   SETDEC(l,4,0,0,2);    SETDEC(r,3,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(7,0,0,4);
4362   /* this last one shows that native oleaut32 does *not* gratuitously seize opportunities
4363      to reduce the scale if possible - the canonical result for the expected value is (6,0,0,1)
4364    */
4365   SETDEC(l,4,0,0,5);    SETDEC(r,3,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(7,0,0,10);
4366   
4367   SETDEC64(l,0,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC(r,0,0,0,2);  MATH2(VarDecMul);   EXPECTDEC64(0,0,1,0xFFFFFFFF,0xFFFFFFFE);
4368   SETDEC(l,0,0,0,2);    SETDEC64(r,0,0,0,0xFFFFFFFF,0xFFFFFFFF);  MATH2(VarDecMul);   EXPECTDEC64(0,0,1,0xFFFFFFFF,0xFFFFFFFE);
4369   SETDEC(l,0,0,1,1);    SETDEC(r,0,0,0,0x80000000);  MATH2(VarDecMul);   EXPECTDEC(0,0,0x80000000,0x80000000);
4370   SETDEC(l,0,0,0,0x80000000);    SETDEC(r,0,0,1,1);  MATH2(VarDecMul);   EXPECTDEC(0,0,0x80000000,0x80000000);
4371   
4372   /* near-overflow, used as a reference */
4373   SETDEC64(l,0,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC(r,0,0,0,2000000000);  MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4374   /* actual overflow - right operand is 10 times the previous value */
4375   SETDEC64(l,0,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC64(r,0,0,0,4,0xA817C800);  MATH2(VarDecMul);
4376   ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4377      S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4378   /* here, native oleaut32 has an opportunity to avert the overflow, by reducing the scale of the result  */
4379   SETDEC64(l,1,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC64(r,0,0,0,4,0xA817C800);  MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4380
4381   /* near-overflow, used as a reference */
4382   SETDEC64(l,0,0,1,0xFFFFFFFF,0xFFFFFFFE);    SETDEC(r,0,0,0,1000000000);  MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4383   /* actual overflow - right operand is 10 times the previous value */
4384   SETDEC64(l,0,0,1,0xFFFFFFFF,0xFFFFFFFE);    SETDEC64(r,0,0,0,2,0x540BE400);  MATH2(VarDecMul);
4385   ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4386      S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4387   /* here, native oleaut32 has an opportunity to avert the overflow, by reducing the scale of the result  */
4388   SETDEC64(l,1,0,1,0xFFFFFFFF,0xFFFFFFFE);    SETDEC64(r,0,0,0,2,0x540BE400);  MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4389   
4390   /* this one shows that native oleaut32 is willing to lose significant digits in order to avert an overflow */
4391   SETDEC64(l,2,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC64(r,0,0,0,9,0x502F9001);  MATH2(VarDecMul);EXPECTDEC64(1,0,0xee6b2800,0x19999998,0xab2e719a);
4392 }
4393
4394 static void test_VarDecDiv(void)
4395 {
4396   MATHVARS2;
4397   
4398   CHECKPTR(VarDecDiv);
4399   /* identity divisions */
4400   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,1);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,0);
4401   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,1);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,1);
4402   SETDEC(l,1,0,0,1);    SETDEC(r,0,0,0,1);  MATH2(VarDecDiv);   EXPECTDEC(1,0,0,1);
4403
4404   /* exact divisions */  
4405   SETDEC(l,0,0,0,45);    SETDEC(r,0,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,5);
4406   SETDEC(l,1,0,0,45);    SETDEC(r,0,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(1,0,0,5);
4407   SETDEC(l,0,0,0,45);    SETDEC(r,1,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,50);
4408   SETDEC(l,1,0,0,45);    SETDEC(r,2,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,50);
4409   /* these last three results suggest that native oleaut32 scales both operands down to zero
4410      before the division, but does not always try to scale the result, even if it is possible -
4411      analogous to multiplication behavior.
4412    */
4413   SETDEC(l,1,0,0,45);    SETDEC(r,1,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,5);
4414   SETDEC(l,2,0,0,450);    SETDEC(r,1,0,0,9);  MATH2(VarDecDiv);
4415   if (S(U(out)).scale == 1) EXPECTDEC(1,0,0,50);
4416   else EXPECTDEC(0,0,0,5);
4417
4418   /* inexact divisions */
4419   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,180700362,0x14b700cb,0x05555555);
4420   SETDEC(l,1,0,0,1);    SETDEC(r,0,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,18070036,0x35458014,0x4d555555);
4421   SETDEC(l,0,0,0,1);    SETDEC(r,1,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,1807003620,0xcf2607ee,0x35555555);
4422   SETDEC(l,1,0,0,1);    SETDEC(r,2,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,1807003620,0xcf2607ee,0x35555555);
4423   SETDEC(l,1,0,0,1);    SETDEC(r,1,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,180700362,0x14b700cb,0x05555555);
4424   SETDEC(l,2,0,0,10);    SETDEC(r,1,0,0,3);  MATH2(VarDecDiv);  EXPECTDEC64(28,0,180700362,0x14b700cb,0x05555555);
4425
4426   /* this one shows that native oleaut32 rounds up the result */
4427   SETDEC(l,0,0,0,2);    SETDEC(r,0,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,361400724,0x296e0196,0x0aaaaaab);
4428   
4429   /* sign tests */
4430   SETDEC(l,0,0x80,0,45);    SETDEC(r,0,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0x80,0,5);
4431   SETDEC(l,0,0,0,45);       SETDEC(r,0,0x80,0,9);  MATH2(VarDecDiv);EXPECTDEC(0,0x80,0,5);
4432   SETDEC(l,0,0x80,0,45);    SETDEC(r,0,0x80,0,9);  MATH2(VarDecDiv);EXPECTDEC(0,0,0,5);
4433   
4434   /* oddballs */
4435   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,0);  MATH2(VarDecDiv);/* indeterminate */
4436   ok(hres == DISP_E_DIVBYZERO,"Expected division-by-zero, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4437      S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4438   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,0);  MATH2(VarDecDiv);/* division by zero */
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   
4442 }
4443
4444 static void test_VarDecCmp(void)
4445 {
4446   MATHVARS1;
4447
4448   CHECKPTR(VarDecCmp);
4449
4450   SETDEC(l,0,0,0,1); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_EQ;
4451   SETDEC(l,0,0,0,1); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_GT;
4452   SETDEC(l,0,0,0,1); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4453
4454   SETDEC(l,0,0,0,1); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4455   SETDEC(l,0,0,0,1); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_GT;
4456   SETDEC(l,0,0,0,1); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4457
4458   SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4459   SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_LT;
4460   SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4461
4462   SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_EQ;
4463   SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_LT;
4464   SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4465
4466   SETDEC(l,0,0,0,0); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4467   SETDEC(l,0,0,0,0); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4468   SETDEC(l,0,0,0,0); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4469
4470   SETDEC(l,0,0,0,0); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4471   SETDEC(l,0,0,0,0); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4472   SETDEC(l,0,0,0,0); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4473
4474   SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4475   SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4476   SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4477
4478   SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4479   SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4480   SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4481
4482   SETDEC(l,0,0,-1,-1); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4483   SETDEC(l,0,0,-1,-1); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_GT;
4484   SETDEC(l,0,0,-1,-1); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_EQ;
4485
4486   SETDEC(l,0,0,-1,-1); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4487   SETDEC(l,0,0,-1,-1); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_GT;
4488   SETDEC(l,0,0,-1,-1); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4489
4490   SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4491   SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_LT;
4492   SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4493
4494   SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4495   SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_LT;
4496   SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_EQ;
4497
4498
4499   SETDEC(out,0,0,0,1); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_EQ;
4500   SETDEC(out,0,0,0,1); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_LT;
4501   SETDEC(out,0,0,0,1); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4502
4503   SETDEC(out,0,0,0,1); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4504   SETDEC(out,0,0,0,1); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_LT;
4505   SETDEC(out,0,0,0,1); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4506
4507   SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4508   SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_GT;
4509   SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4510
4511   SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_EQ;
4512   SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_GT;
4513   SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4514
4515   SETDEC(out,0,0,0,0); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4516   SETDEC(out,0,0,0,0); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4517   SETDEC(out,0,0,0,0); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4518
4519   SETDEC(out,0,0,0,0); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4520   SETDEC(out,0,0,0,0); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4521   SETDEC(out,0,0,0,0); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4522
4523   SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4524   SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4525   SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4526
4527   SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4528   SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4529   SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4530
4531   SETDEC(out,0,0,-1,-1); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4532   SETDEC(out,0,0,-1,-1); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_LT;
4533   SETDEC(out,0,0,-1,-1); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_EQ;
4534
4535   SETDEC(out,0,0,-1,-1); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4536   SETDEC(out,0,0,-1,-1); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_LT;
4537   SETDEC(out,0,0,-1,-1); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4538
4539   SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4540   SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_GT;
4541   SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4542
4543   SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4544   SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_GT;
4545   SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_EQ;
4546
4547 }
4548
4549 /*
4550  * VT_BOOL
4551  */
4552
4553 #undef CONV_TYPE
4554 #define CONV_TYPE VARIANT_BOOL
4555 #undef _EXPECTRES
4556 #define _EXPECTRES(res, x, fs) \
4557   ok((hres == S_OK && out == (CONV_TYPE)(x)) || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
4558      "expected " #x ", got " fs "; hres=0x%08x\n", out, hres)
4559 #undef EXPECTRES
4560 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%d")
4561 #undef CONVERTRANGE
4562 #define CONVERTRANGE(func,start,end) for (i = start; i < end; i++) { \
4563   CONVERT(func, i); if (i) { EXPECT(VARIANT_TRUE); } else { EXPECT(VARIANT_FALSE); } }
4564
4565 static void test_VarBoolFromI1(void)
4566 {
4567   CONVVARS(signed char);
4568   int i;
4569
4570   CHECKPTR(VarBoolFromI1);
4571   CONVERTRANGE(VarBoolFromI1, -128, 128);
4572 }
4573
4574 static void test_VarBoolFromUI1(void)
4575 {
4576   CONVVARS(BYTE);
4577   int i;
4578
4579   CHECKPTR(VarBoolFromUI1);
4580   CONVERTRANGE(VarBoolFromUI1, 0, 256);
4581 }
4582
4583 static void test_VarBoolFromI2(void)
4584 {
4585   CONVVARS(SHORT);
4586   int i;
4587
4588   CHECKPTR(VarBoolFromI2);
4589   CONVERTRANGE(VarBoolFromI2, -32768, 32768);
4590 }
4591
4592 static void test_VarBoolFromUI2(void)
4593 {
4594   CONVVARS(USHORT);
4595   int i;
4596
4597   CHECKPTR(VarBoolFromUI2);
4598   CONVERTRANGE(VarBoolFromUI2, 0, 65536);
4599 }
4600
4601 static void test_VarBoolFromI4(void)
4602 {
4603   CONVVARS(int);
4604
4605   CHECKPTR(VarBoolFromI4);
4606   CONVERT(VarBoolFromI4, 0x80000000); EXPECT(VARIANT_TRUE);
4607   CONVERT(VarBoolFromI4, -1);         EXPECT(VARIANT_TRUE);
4608   CONVERT(VarBoolFromI4, 0);          EXPECT(VARIANT_FALSE);
4609   CONVERT(VarBoolFromI4, 1);          EXPECT(VARIANT_TRUE);
4610   CONVERT(VarBoolFromI4, 0x7fffffff); EXPECT(VARIANT_TRUE);
4611 }
4612
4613 static void test_VarBoolFromUI4(void)
4614 {
4615   CONVVARS(ULONG);
4616
4617   CHECKPTR(VarBoolFromUI4);
4618   CONVERT(VarBoolFromI4, 0);          EXPECT(VARIANT_FALSE);
4619   CONVERT(VarBoolFromI4, 1);          EXPECT(VARIANT_TRUE);
4620   CONVERT(VarBoolFromI4, 0x80000000); EXPECT(VARIANT_TRUE);
4621 }
4622
4623 static void test_VarBoolFromR4(void)
4624 {
4625   CONVVARS(FLOAT);
4626
4627   CHECKPTR(VarBoolFromR4);
4628   CONVERT(VarBoolFromR4, -1.0f); EXPECT(VARIANT_TRUE);
4629   CONVERT(VarBoolFromR4, 0.0f);  EXPECT(VARIANT_FALSE);
4630   CONVERT(VarBoolFromR4, 1.0f);  EXPECT(VARIANT_TRUE);
4631   CONVERT(VarBoolFromR4, 1.5f);  EXPECT(VARIANT_TRUE);
4632
4633   /* Rounding */
4634   CONVERT(VarBoolFromR4, -1.5f); EXPECT(VARIANT_TRUE);
4635   CONVERT(VarBoolFromR4, -0.6f); EXPECT(VARIANT_TRUE);
4636   CONVERT(VarBoolFromR4, -0.5f); EXPECT(VARIANT_TRUE);
4637   CONVERT(VarBoolFromR4, -0.4f); EXPECT(VARIANT_TRUE);
4638   CONVERT(VarBoolFromR4, 0.4f);  EXPECT(VARIANT_TRUE);
4639   CONVERT(VarBoolFromR4, 0.5f);  EXPECT(VARIANT_TRUE);
4640   CONVERT(VarBoolFromR4, 0.6f);  EXPECT(VARIANT_TRUE);
4641   CONVERT(VarBoolFromR4, 1.5f);  EXPECT(VARIANT_TRUE);
4642 }
4643
4644 static void test_VarBoolFromR8(void)
4645 {
4646   CONVVARS(DOUBLE);
4647
4648   /* Hopefully we made the point with R4 above that rounding is
4649    * irrelevant, so we'll skip that for R8 and Date
4650    */
4651   CHECKPTR(VarBoolFromR8);
4652   CONVERT(VarBoolFromR8, -1.0); EXPECT(VARIANT_TRUE);
4653   CONVERT(VarBoolFromR8, -0.0); EXPECT(VARIANT_FALSE);
4654   CONVERT(VarBoolFromR8, 1.0);  EXPECT(VARIANT_TRUE);
4655 }
4656
4657 static void test_VarBoolFromCy(void)
4658 {
4659   CONVVARS(CY);
4660
4661   CHECKPTR(VarBoolFromCy);
4662   CONVERT_CY(VarBoolFromCy, -32769); EXPECT(VARIANT_TRUE);
4663   CONVERT_CY(VarBoolFromCy, -32768); EXPECT(VARIANT_TRUE);
4664   CONVERT_CY(VarBoolFromCy, -1);     EXPECT(VARIANT_TRUE);
4665   CONVERT_CY(VarBoolFromCy, 0);      EXPECT(VARIANT_FALSE);
4666   CONVERT_CY(VarBoolFromCy, 1);      EXPECT(VARIANT_TRUE);
4667   CONVERT_CY(VarBoolFromCy, 32767);  EXPECT(VARIANT_TRUE);
4668   CONVERT_CY(VarBoolFromCy, 32768);  EXPECT(VARIANT_TRUE);
4669 }
4670
4671 static void test_VarBoolFromI8(void)
4672 {
4673   CONVVARS(LONG64);
4674
4675   CHECKPTR(VarBoolFromI8);
4676   CONVERT(VarBoolFromI8, -1); EXPECT(VARIANT_TRUE);
4677   CONVERT(VarBoolFromI8, 0);  EXPECT(VARIANT_FALSE);
4678   CONVERT(VarBoolFromI8, 1);  EXPECT(VARIANT_TRUE);
4679 }
4680
4681 static void test_VarBoolFromUI8(void)
4682 {
4683   CONVVARS(ULONG64);
4684
4685   CHECKPTR(VarBoolFromUI8);
4686   CONVERT(VarBoolFromUI8, 0); EXPECT(VARIANT_FALSE);
4687   CONVERT(VarBoolFromUI8, 1); EXPECT(VARIANT_TRUE);
4688 }
4689
4690 static void test_VarBoolFromDec(void)
4691 {
4692   CONVVARS(DECIMAL);
4693
4694   CHECKPTR(VarBoolFromDec);
4695   CONVERT_BADDEC(VarBoolFromDec);
4696
4697   if (HAVE_OLEAUT32_DECIMAL)
4698   {
4699     /* Early versions of oleaut32 don't catch these errors */
4700     CONVERT_DEC(VarBoolFromDec,29,0,0,0);   EXPECT_INVALID;
4701     CONVERT_DEC(VarBoolFromDec,0,0x1,0,0);  EXPECT_INVALID;
4702     CONVERT_DEC(VarBoolFromDec,0,0x40,0,0); EXPECT_INVALID;
4703     CONVERT_DEC(VarBoolFromDec,0,0x7f,0,0); EXPECT_INVALID;
4704   }
4705
4706   CONVERT_DEC(VarBoolFromDec,0,0x80,0,1); EXPECT(VARIANT_TRUE);
4707   CONVERT_DEC(VarBoolFromDec,0,0,0,0);    EXPECT(VARIANT_FALSE);
4708   CONVERT_DEC(VarBoolFromDec,0,0,0,1);    EXPECT(VARIANT_TRUE);
4709   CONVERT_DEC(VarBoolFromDec,0,0,1,0);    EXPECT(VARIANT_TRUE);
4710
4711   CONVERT_DEC(VarBoolFromDec,2,0,0,CY_MULTIPLIER);    EXPECT(VARIANT_TRUE);
4712   CONVERT_DEC(VarBoolFromDec,2,0x80,0,CY_MULTIPLIER); EXPECT(VARIANT_TRUE);
4713 }
4714
4715 static void test_VarBoolFromDate(void)
4716 {
4717   CONVVARS(DATE);
4718
4719   CHECKPTR(VarBoolFromDate);
4720   CONVERT(VarBoolFromDate, -1.0); EXPECT(VARIANT_TRUE);
4721   CONVERT(VarBoolFromDate, -0.0); EXPECT(VARIANT_FALSE);
4722   CONVERT(VarBoolFromDate, 1.0);  EXPECT(VARIANT_TRUE);
4723 }
4724
4725 static void test_VarBoolFromStr(void)
4726 {
4727   CONVVARS(LCID);
4728   OLECHAR buff[128];
4729
4730   CHECKPTR(VarBoolFromStr);
4731
4732   in = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4733
4734   CONVERT_STR(VarBoolFromStr,NULL,0);
4735   if (hres != E_INVALIDARG)
4736     EXPECT_MISMATCH;
4737
4738   /* #FALSE# and #TRUE# Are always accepted */
4739   CONVERT_STR(VarBoolFromStr,"#FALSE#",0); EXPECT(VARIANT_FALSE);
4740   CONVERT_STR(VarBoolFromStr,"#TRUE#",0);  EXPECT(VARIANT_TRUE);
4741
4742   /* Match of #FALSE# and #TRUE# is case sensitive */
4743   CONVERT_STR(VarBoolFromStr,"#False#",0); EXPECT_MISMATCH;
4744   /* But match against English is not */
4745   CONVERT_STR(VarBoolFromStr,"false",0);   EXPECT(VARIANT_FALSE);
4746   CONVERT_STR(VarBoolFromStr,"False",0);   EXPECT(VARIANT_FALSE);
4747   /* On/Off and yes/no are not acceptable inputs, with any flags set */
4748   CONVERT_STR(VarBoolFromStr,"On",0xffffffff);  EXPECT_MISMATCH;
4749   CONVERT_STR(VarBoolFromStr,"Yes",0xffffffff); EXPECT_MISMATCH;
4750
4751   /* Change the LCID. This doesn't make any difference for text,unless we ask
4752    * to check local boolean text with the VARIANT_LOCALBOOL flag. */
4753   in = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT);
4754
4755   /* #FALSE# and #TRUE# are accepted in all locales */
4756   CONVERT_STR(VarBoolFromStr,"#FALSE#",0); EXPECT(VARIANT_FALSE);
4757   CONVERT_STR(VarBoolFromStr,"#TRUE#",0);  EXPECT(VARIANT_TRUE);
4758   CONVERT_STR(VarBoolFromStr,"#FALSE#",VARIANT_LOCALBOOL); EXPECT(VARIANT_FALSE);
4759   CONVERT_STR(VarBoolFromStr,"#TRUE#",VARIANT_LOCALBOOL);  EXPECT(VARIANT_TRUE);
4760
4761   /* English is accepted regardless of the locale */
4762   CONVERT_STR(VarBoolFromStr,"false",0); EXPECT(VARIANT_FALSE);
4763   /* And is still not case sensitive */
4764   CONVERT_STR(VarBoolFromStr,"False",0); EXPECT(VARIANT_FALSE);
4765
4766   if (HAVE_OLEAUT32_LOCALES)
4767   {
4768     /* French is rejected without VARIANT_LOCALBOOL */
4769     CONVERT_STR(VarBoolFromStr,"faux",0); EXPECT_MISMATCH;
4770     /* But accepted if this flag is given */
4771     CONVERT_STR(VarBoolFromStr,"faux",VARIANT_LOCALBOOL); EXPECT(VARIANT_FALSE);
4772     /* Regardless of case - from this we assume locale text comparisons ignore case */
4773     CONVERT_STR(VarBoolFromStr,"Faux",VARIANT_LOCALBOOL); EXPECT(VARIANT_FALSE);
4774
4775     /* Changing the locale prevents the localised text from being compared -
4776      * this demonstrates that only the indicated LCID and English are searched */
4777     in = MAKELCID(MAKELANGID(LANG_POLISH, SUBLANG_DEFAULT), SORT_DEFAULT);
4778     CONVERT_STR(VarBoolFromStr,"faux",VARIANT_LOCALBOOL); EXPECT_MISMATCH;
4779   }
4780
4781   /* Numeric strings are read as 0 or non-0 */
4782   CONVERT_STR(VarBoolFromStr,"0",0);  EXPECT(VARIANT_FALSE);
4783   CONVERT_STR(VarBoolFromStr,"-1",0); EXPECT(VARIANT_TRUE);
4784   CONVERT_STR(VarBoolFromStr,"+1",0); EXPECT(VARIANT_TRUE);
4785
4786   if (HAVE_OLEAUT32_LOCALES)
4787   {
4788     /* Numeric strings are read as floating point numbers. The line below fails
4789      * because '.' is not a valid decimal separator for Polish numbers */
4790     CONVERT_STR(VarBoolFromStr,"0.1",LOCALE_NOUSEROVERRIDE); EXPECT_MISMATCH;
4791   }
4792
4793   /* Changing the lcid back to US English reads the r8 correctly */
4794   in = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4795   CONVERT_STR(VarBoolFromStr,"0.1",LOCALE_NOUSEROVERRIDE); EXPECT(VARIANT_TRUE);
4796 }
4797
4798 static void test_VarBoolCopy(void)
4799 {
4800   COPYTEST(1, VT_BOOL, V_BOOL(&vSrc), V_BOOL(&vDst), V_BOOLREF(&vSrc), V_BOOLREF(&vDst), "%d");
4801 }
4802
4803 #define BOOL_STR(flags, str) hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, flags, VT_BSTR); \
4804   ok(hres == S_OK && V_VT(&vDst) == VT_BSTR && \
4805      V_BSTR(&vDst) && !memcmp(V_BSTR(&vDst), str, sizeof(str)), \
4806      "hres=0x%X, type=%d (should be VT_BSTR), *bstr='%c'\n", \
4807      hres, V_VT(&vDst), V_BSTR(&vDst) ? *V_BSTR(&vDst) : '?'); \
4808   VariantClear(&vDst)
4809
4810 static void test_VarBoolChangeTypeEx(void)
4811 {
4812   static const WCHAR szTrue[] = { 'T','r','u','e','\0' };
4813   static const WCHAR szFalse[] = { 'F','a','l','s','e','\0' };
4814   static const WCHAR szFaux[] = { 'F','a','u','x','\0' };
4815   CONVVARS(CONV_TYPE);
4816   VARIANTARG vSrc, vDst;
4817   LCID lcid;
4818
4819   in = 1;
4820
4821   INITIAL_TYPETEST(VT_BOOL, V_BOOL, "%d");
4822   COMMON_TYPETEST;
4823
4824   /* The common tests convert to a number. Try the different flags */
4825   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4826
4827   V_VT(&vSrc) = VT_BOOL;
4828   V_BOOL(&vSrc) = 1;
4829
4830   if (!IS_ANCIENT)
4831   {
4832       BOOL_STR(VARIANT_ALPHABOOL, szTrue);
4833       V_BOOL(&vSrc) = 0;
4834       BOOL_STR(VARIANT_ALPHABOOL, szFalse);
4835   }
4836
4837   if (HAVE_OLEAUT32_LOCALES)
4838   {
4839     lcid = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT);
4840
4841     /* VARIANT_ALPHABOOL is always English */
4842     BOOL_STR(VARIANT_ALPHABOOL, szFalse);
4843     /* VARIANT_LOCALBOOL uses the localised text */
4844     BOOL_STR(VARIANT_LOCALBOOL, szFaux);
4845     /* Both flags together acts as VARIANT_LOCALBOOL */
4846     BOOL_STR(VARIANT_ALPHABOOL|VARIANT_LOCALBOOL, szFaux);
4847   }
4848 }
4849
4850 /*
4851  * BSTR
4852  */
4853
4854 static void test_VarBstrFromR4(void)
4855 {
4856   static const WCHAR szNative[] = { '6','5','4','3','2','2','.','3','\0' };
4857   static const WCHAR szZero[] = {'0', '\0'};
4858   static const WCHAR szOneHalf_English[] = { '0','.','5','\0' };    /* uses period */
4859   static const WCHAR szOneHalf_Spanish[] = { '0',',','5','\0' };    /* uses comma */
4860   LCID lcid;
4861   LCID lcid_spanish;
4862   HRESULT hres;
4863   BSTR bstr = NULL;
4864
4865   float f;
4866
4867   CHECKPTR(VarBstrFromR4);
4868
4869   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4870   lcid_spanish = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), SORT_DEFAULT);
4871   f = 654322.23456f;
4872   hres = pVarBstrFromR4(f, lcid, 0, &bstr);
4873   ok(hres == S_OK, "got hres 0x%08x\n", hres);
4874   if (bstr)
4875   {
4876     todo_wine {
4877     /* MSDN states that rounding of R4/R8 is dependent on the underlying
4878      * bit pattern of the number and so is architecture dependent. In this
4879      * case Wine returns .2 (which is more correct) and Native returns .3
4880      */
4881     ok(memcmp(bstr, szNative, sizeof(szNative)) == 0, "string different\n");
4882     }
4883     SysFreeString(bstr);
4884   }
4885
4886   f = -0.0;
4887   hres = pVarBstrFromR4(f, lcid, 0, &bstr);
4888   ok(hres == S_OK, "got hres 0x%08x\n", hres);
4889   if (bstr)
4890   {
4891       if (bstr[0] == '-')
4892           ok(memcmp(bstr + 1, szZero, sizeof(szZero)) == 0, "negative zero (got %s)\n", wtoascii(bstr));
4893       else
4894           ok(memcmp(bstr, szZero, sizeof(szZero)) == 0, "negative zero (got %s)\n", wtoascii(bstr));
4895       SysFreeString(bstr);
4896   }
4897   
4898   /* The following tests that lcid is used for decimal separator even without LOCALE_USE_NLS */
4899   f = 0.5;
4900   hres = pVarBstrFromR4(f, lcid, LOCALE_NOUSEROVERRIDE, &bstr);
4901   ok(hres == S_OK, "got hres 0x%08x\n", hres);
4902   if (bstr)
4903   {
4904     ok(memcmp(bstr, szOneHalf_English, sizeof(szOneHalf_English)) == 0, "English locale failed (got %s)\n", wtoascii(bstr));
4905     SysFreeString(bstr);
4906   }
4907   f = 0.5;
4908   hres = pVarBstrFromR4(f, lcid_spanish, LOCALE_NOUSEROVERRIDE, &bstr);
4909   ok(hres == S_OK, "got hres 0x%08x\n", hres);
4910   if (bstr)
4911   {
4912     ok(memcmp(bstr, szOneHalf_Spanish, sizeof(szOneHalf_Spanish)) == 0, "Spanish locale failed (got %s)\n", wtoascii(bstr));
4913     SysFreeString(bstr);
4914   }
4915 }
4916
4917 static void _BSTR_DATE(DATE dt, const char *str, int line)
4918 {
4919   LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
4920   char buff[256];
4921   BSTR bstr = NULL;
4922   HRESULT hres;
4923
4924   hres = pVarBstrFromDate(dt, lcid, LOCALE_NOUSEROVERRIDE, &bstr);
4925   if (bstr)
4926   {
4927     WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0);
4928     SysFreeString(bstr);
4929   }
4930   else
4931     buff[0] = 0;
4932   ok_(__FILE__, line)(hres == S_OK && !strcmp(str, buff),
4933       "Expected '%s', got '%s', hres = 0x%08x\n", str, buff, hres);
4934 }
4935
4936 static void test_VarBstrFromDate(void)
4937 {
4938 #define BSTR_DATE(dt,str) _BSTR_DATE(dt,str,__LINE__)
4939
4940   CHECKPTR(VarBstrFromDate);
4941
4942   BSTR_DATE(0.0, "12:00:00 AM");
4943   BSTR_DATE(3.34, "1/2/1900 8:09:36 AM");
4944   BSTR_DATE(3339.34, "2/20/1909 8:09:36 AM");
4945   BSTR_DATE(365.00, "12/30/1900");
4946   BSTR_DATE(365.25, "12/30/1900 6:00:00 AM");
4947   BSTR_DATE(1461.0, "12/31/1903");
4948   BSTR_DATE(1461.5, "12/31/1903 12:00:00 PM");
4949   todo_wine { BSTR_DATE(-657434.0, "1/1/100"); }
4950   BSTR_DATE(2958465.0, "12/31/9999");
4951
4952 #undef BSTR_DATE
4953 }
4954
4955 static void _BSTR_CY(LONG a, LONG b, const char *str, LCID lcid, int line)
4956 {
4957   HRESULT hr;
4958   BSTR bstr = NULL;
4959   char buff[256];
4960   CY l;
4961
4962   S(l).Lo = b;
4963   S(l).Hi = a;
4964   hr = pVarBstrFromCy(l, lcid, LOCALE_NOUSEROVERRIDE, &bstr);
4965   ok(hr == S_OK, "got hr 0x%08x\n", hr);
4966
4967   if(bstr)
4968   {
4969     WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0);
4970     SysFreeString(bstr);
4971   }
4972   else
4973     buff[0] = 0;
4974
4975   if(hr == S_OK)
4976   {
4977     ok_(__FILE__, line)(!strcmp(str, buff), "Expected '%s', got '%s'\n", str, buff);
4978   }
4979 }
4980
4981 static void test_VarBstrFromCy(void)
4982 {
4983 #define BSTR_CY(a, b, str, lcid) _BSTR_CY(a, b, str, lcid, __LINE__)
4984
4985   LCID en_us, sp;
4986
4987   CHECKPTR(VarBstrFromCy);
4988
4989   en_us = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
4990   sp = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
4991
4992   BSTR_CY(0, 0, "0", en_us);
4993   BSTR_CY(0, 10000, "1", en_us);
4994   BSTR_CY(0, 15000, "1.5", en_us);
4995   BSTR_CY(0xffffffff, ((15000)^0xffffffff)+1, "-1.5", en_us);
4996   /* (1 << 32) - 1 / 1000 */
4997   BSTR_CY(0, 0xffffffff, "429496.7295", en_us);
4998   /* (1 << 32) / 1000 */
4999   BSTR_CY(1, 0, "429496.7296", en_us);
5000   /* ((1 << 63) - 1)/10000 */
5001   BSTR_CY(0x7fffffff, 0xffffffff, "922337203685477.5807", en_us);
5002   BSTR_CY(0, 9, "0.0009", en_us);
5003   BSTR_CY(0, 9, "0,0009", sp);
5004
5005 #undef BSTR_CY
5006 }
5007
5008 static void _BSTR_DEC(BYTE scale, BYTE sign, ULONG hi, ULONG mid, ULONGLONG lo, const char *str,
5009     LCID lcid, int line)
5010 {
5011   char buff[256];
5012   HRESULT hr;
5013   BSTR bstr = NULL;
5014   DECIMAL dec;
5015
5016   SETDEC64(dec, scale, sign, hi, mid, lo);
5017   hr = pVarBstrFromDec(&dec, lcid, LOCALE_NOUSEROVERRIDE, &bstr);
5018   ok_(__FILE__, line)(hr == S_OK, "got hr 0x%08x\n", hr);
5019
5020   if(bstr)
5021   {
5022     WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0);
5023     SysFreeString(bstr);
5024   }
5025   else
5026     buff[0] = 0;
5027
5028   if(hr == S_OK)
5029   {
5030     ok_(__FILE__, line)(!strcmp(str, buff), "Expected '%s', got '%s'\n", str, buff);
5031   }
5032 }
5033
5034 static void test_VarBstrFromDec(void)
5035 {
5036 #define BSTR_DEC(scale, sign, hi, lo, str, lcid) _BSTR_DEC(scale, sign, hi, 0, lo, str, lcid, __LINE__)
5037 #define BSTR_DEC64(scale, sign, hi, mid, lo, str, lcid) _BSTR_DEC(scale, sign, hi, mid, lo, str, lcid, __LINE__)
5038
5039   LCID en_us, sp;
5040
5041   CHECKPTR(VarBstrFromDec);
5042
5043   en_us = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
5044   sp = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
5045
5046   BSTR_DEC(0,0,0,0, "0", en_us);
5047
5048   BSTR_DEC(0,0,0,1,   "1", en_us);
5049   BSTR_DEC(1,0,0,10,  "1", en_us);
5050   BSTR_DEC(2,0,0,100, "1", en_us);
5051   BSTR_DEC(3,0,0,1000,"1", en_us);
5052
5053   BSTR_DEC(1,0,0,15,  "1.5", en_us);
5054   BSTR_DEC(2,0,0,150, "1.5", en_us);
5055   BSTR_DEC(3,0,0,1500,"1.5", en_us);
5056
5057   BSTR_DEC(1,0x80,0,15, "-1.5", en_us);
5058
5059   /* (1 << 32) - 1 */
5060   BSTR_DEC(0,0,0,0xffffffff, "4294967295", en_us);
5061   /* (1 << 32) */
5062   BSTR_DEC64(0,0,0,1,0, "4294967296", en_us);
5063   /* (1 << 64) - 1 */
5064   BSTR_DEC64(0,0,0,0xffffffff,0xffffffff, "18446744073709551615", en_us);
5065   /* (1 << 64) */
5066   BSTR_DEC(0,0,1,0, "18446744073709551616", en_us);
5067   /* (1 << 96) - 1 */
5068   BSTR_DEC64(0,0,0xffffffff,0xffffffff,0xffffffff, "79228162514264337593543950335", en_us);
5069   /* 1 * 10^-10 */
5070   BSTR_DEC(10,0,0,1, "0.0000000001", en_us);
5071   /* ((1 << 96) - 1) * 10^-10 */
5072   BSTR_DEC64(10,0,0xffffffffUL,0xffffffff,0xffffffff, "7922816251426433759.3543950335", en_us);
5073   /* ((1 << 96) - 1) * 10^-28 */
5074   BSTR_DEC64(28,0,0xffffffffUL,0xffffffff,0xffffffff, "7.9228162514264337593543950335", en_us);
5075
5076   /* check leading zeros and decimal sep. for English locale */
5077   BSTR_DEC(4,0,0,9, "0.0009", en_us);
5078   BSTR_DEC(5,0,0,90, "0.0009", en_us);
5079   BSTR_DEC(6,0,0,900, "0.0009", en_us);
5080   BSTR_DEC(7,0,0,9000, "0.0009", en_us);
5081   
5082   /* check leading zeros and decimal sep. for Spanish locale */
5083   BSTR_DEC(4,0,0,9, "0,0009", sp);
5084   BSTR_DEC(5,0,0,90, "0,0009", sp);
5085   BSTR_DEC(6,0,0,900, "0,0009", sp);
5086   BSTR_DEC(7,0,0,9000, "0,0009", sp);
5087
5088 #undef BSTR_DEC
5089 #undef BSTR_DEC64
5090 }
5091
5092 #define _VARBSTRCMP(left,right,lcid,flags,result) \
5093         hres = pVarBstrCmp(left,right,lcid,flags); \
5094         ok(hres == result, "VarBstrCmp: expected " #result ", got hres=0x%x\n", hres)
5095 #define VARBSTRCMP(left,right,flags,result) \
5096         _VARBSTRCMP(left,right,lcid,flags,result)
5097
5098 static void test_VarBstrCmp(void)
5099 {
5100     LCID lcid;
5101     HRESULT hres;
5102     static const WCHAR sz[] = {'W','u','r','s','c','h','t','\0'};
5103     static const WCHAR szempty[] = {'\0'};
5104     static const WCHAR sz1[] = { 'a',0 };
5105     static const WCHAR sz2[] = { 'A',0 };
5106     static const WCHAR s1[] = { 'a',0 };
5107     static const WCHAR s2[] = { 'a',0,'b' };
5108     static const char sb1[] = {1,0,1};
5109     static const char sb2[] = {1,0,2};
5110     static const char sbchr0[] = {0,0};
5111     static const char sbchr00[] = {0,0,0};
5112     BSTR bstr, bstrempty, bstr2;
5113
5114     CHECKPTR(VarBstrCmp);
5115     
5116     lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
5117     bstr = SysAllocString(sz);
5118     bstrempty = SysAllocString(szempty);
5119     
5120     /* NULL handling. Yepp, MSDN is totally wrong here */
5121     VARBSTRCMP(NULL,NULL,0,VARCMP_EQ);
5122     VARBSTRCMP(bstr,NULL,0,VARCMP_GT);
5123     VARBSTRCMP(NULL,bstr,0,VARCMP_LT);
5124
5125     /* NULL and empty string comparisons */
5126     VARBSTRCMP(bstrempty,NULL,0,VARCMP_EQ);
5127     VARBSTRCMP(NULL,bstrempty,0,VARCMP_EQ);
5128
5129     SysFreeString(bstr);
5130     bstr = SysAllocString(sz1);
5131
5132     bstr2 = SysAllocString(sz2);
5133     VARBSTRCMP(bstr,bstr2,0,VARCMP_LT);
5134     VARBSTRCMP(bstr,bstr2,NORM_IGNORECASE,VARCMP_EQ);
5135     SysFreeString(bstr2);
5136     /* These two strings are considered equal even though one is
5137      * NULL-terminated and the other not.
5138      */
5139     bstr2 = SysAllocStringLen(s1, sizeof(s1) / sizeof(WCHAR));
5140     VARBSTRCMP(bstr,bstr2,0,VARCMP_EQ);
5141     SysFreeString(bstr2);
5142
5143     /* These two strings are not equal */
5144     bstr2 = SysAllocStringLen(s2, sizeof(s2) / sizeof(WCHAR));
5145     VARBSTRCMP(bstr,bstr2,0,VARCMP_LT);
5146     SysFreeString(bstr2);
5147
5148     SysFreeString(bstr);
5149
5150     bstr = SysAllocStringByteLen(sbchr0, sizeof(sbchr0));
5151     bstr2 = SysAllocStringByteLen(sbchr0, sizeof(sbchr00));
5152     VARBSTRCMP(bstr,bstrempty,0,VARCMP_GT);
5153     VARBSTRCMP(bstrempty,bstr,0,VARCMP_LT);
5154     VARBSTRCMP(bstr2,bstrempty,0,VARCMP_GT);
5155     VARBSTRCMP(bstr2,bstr,0,VARCMP_EQ);
5156     SysFreeString(bstr2);
5157     SysFreeString(bstr);
5158
5159     /* When (LCID == 0) it should be a binary comparison
5160      * so these two strings could not match.
5161      */
5162     bstr = SysAllocStringByteLen(sb1, sizeof(sb1));
5163     bstr2 = SysAllocStringByteLen(sb2, sizeof(sb2));
5164     lcid = 0;
5165     VARBSTRCMP(bstr,bstr2,0,VARCMP_LT);
5166     SysFreeString(bstr2);
5167     SysFreeString(bstr);
5168
5169     bstr = SysAllocStringByteLen(sbchr0, sizeof(sbchr0));
5170     bstr2 = SysAllocStringByteLen(sbchr0, sizeof(sbchr00));
5171     VARBSTRCMP(bstr,bstrempty,0,VARCMP_GT);
5172     VARBSTRCMP(bstrempty,bstr,0,VARCMP_LT);
5173     VARBSTRCMP(bstr2,bstrempty,0,VARCMP_GT);
5174     VARBSTRCMP(bstr2,bstr,0,VARCMP_GT);
5175     SysFreeString(bstr2);
5176     SysFreeString(bstr);
5177     SysFreeString(bstrempty);
5178 }
5179
5180 /* Get the internal representation of a BSTR */
5181 static inline LPINTERNAL_BSTR Get(const BSTR lpszString)
5182 {
5183   return lpszString ? (LPINTERNAL_BSTR)((char*)lpszString - sizeof(DWORD)) : NULL;
5184 }
5185
5186 static inline BSTR GetBSTR(const LPINTERNAL_BSTR bstr)
5187 {
5188   return (BSTR)bstr->szString;
5189 }
5190
5191 static void test_SysStringLen(void)
5192 {
5193   INTERNAL_BSTR bstr;
5194   BSTR str = GetBSTR(&bstr);
5195
5196   bstr.dwLen = 0;
5197   ok (SysStringLen(str) == 0, "Expected dwLen 0, got %d\n", SysStringLen(str));
5198   bstr.dwLen = 2;
5199   ok (SysStringLen(str) == 1, "Expected dwLen 1, got %d\n", SysStringLen(str));
5200 }
5201
5202 static void test_SysStringByteLen(void)
5203 {
5204   INTERNAL_BSTR bstr;
5205   BSTR str = GetBSTR(&bstr);
5206
5207   bstr.dwLen = 0;
5208   ok (SysStringByteLen(str) == 0, "Expected dwLen 0, got %d\n", SysStringByteLen(str));
5209   bstr.dwLen = 2;
5210   ok (SysStringByteLen(str) == 2, "Expected dwLen 2, got %d\n", SysStringByteLen(str));
5211 }
5212
5213 static void test_SysAllocString(void)
5214 {
5215   const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
5216   BSTR str;
5217
5218   str = SysAllocString(NULL);
5219   ok (str == NULL, "Expected NULL, got %p\n", str);
5220
5221   str = SysAllocString(szTest);
5222   ok (str != NULL, "Expected non-NULL\n");
5223   if (str)
5224   {
5225     LPINTERNAL_BSTR bstr = Get(str);
5226
5227     ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5228     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5229     SysFreeString(str);
5230   }
5231 }
5232
5233 static void test_SysAllocStringLen(void)
5234 {
5235   const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
5236   BSTR str;
5237
5238   /* Very early native dlls do not limit the size of strings, so skip this test */
5239   if (0)
5240   {
5241   str = SysAllocStringLen(szTest, 0x80000000);
5242   ok (str == NULL, "Expected NULL, got %p\n", str);
5243   }
5244   
5245   str = SysAllocStringLen(NULL, 0);
5246   ok (str != NULL, "Expected non-NULL\n");
5247   if (str)
5248   {
5249     LPINTERNAL_BSTR bstr = Get(str);
5250
5251     ok (bstr->dwLen == 0, "Expected 0, got %d\n", bstr->dwLen);
5252     ok (!bstr->szString[0], "String not empty\n");
5253     SysFreeString(str);
5254   }
5255
5256   str = SysAllocStringLen(szTest, 4);
5257   ok (str != NULL, "Expected non-NULL\n");
5258   if (str)
5259   {
5260     LPINTERNAL_BSTR bstr = Get(str);
5261
5262     ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5263     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5264     SysFreeString(str);
5265   }
5266 }
5267
5268 static void test_SysAllocStringByteLen(void)
5269 {
5270   const OLECHAR szTest[10] = { 'T','e','s','t','\0' };
5271   const CHAR szTestA[6] = { 'T','e','s','t','\0','?' };
5272   BSTR str;
5273
5274   if (sizeof(void *) == 4)  /* not limited to 0x80000000 on Win64 */
5275   {
5276       str = SysAllocStringByteLen(szTestA, 0x80000000);
5277       ok (str == NULL, "Expected NULL, got %p\n", str);
5278   }
5279
5280   str = SysAllocStringByteLen(szTestA, 0xffffffff);
5281   ok (str == NULL, "Expected NULL, got %p\n", str);
5282
5283   str = SysAllocStringByteLen(NULL, 0);
5284   ok (str != NULL, "Expected non-NULL\n");
5285   if (str)
5286   {
5287     LPINTERNAL_BSTR bstr = Get(str);
5288
5289     ok (bstr->dwLen == 0, "Expected 0, got %d\n", bstr->dwLen);
5290     ok (!bstr->szString[0], "String not empty\n");
5291     SysFreeString(str);
5292   }
5293
5294   str = SysAllocStringByteLen(szTestA, 4);
5295   ok (str != NULL, "Expected non-NULL\n");
5296   if (str)
5297   {
5298     LPINTERNAL_BSTR bstr = Get(str);
5299
5300     ok (bstr->dwLen == 4, "Expected 4, got %d\n", bstr->dwLen);
5301     ok (!lstrcmpA((LPCSTR)bstr->szString, szTestA), "String different\n");
5302     SysFreeString(str);
5303   }
5304
5305   /* Odd lengths are allocated rounded up, but truncated at the right position */
5306   str = SysAllocStringByteLen(szTestA, 3);
5307   ok (str != NULL, "Expected non-NULL\n");
5308   if (str)
5309   {
5310     const CHAR szTestTruncA[4] = { 'T','e','s','\0' };
5311     LPINTERNAL_BSTR bstr = Get(str);
5312
5313     ok (bstr->dwLen == 3, "Expected 3, got %d\n", bstr->dwLen);
5314     ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n");
5315     SysFreeString(str);
5316   }
5317
5318   str = SysAllocStringByteLen((LPCSTR)szTest, 8);
5319   ok (str != NULL, "Expected non-NULL\n");
5320   if (str)
5321   {
5322     LPINTERNAL_BSTR bstr = Get(str);
5323
5324     ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5325     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5326     SysFreeString(str);
5327   }
5328 }
5329
5330 static void test_SysReAllocString(void)
5331 {
5332   const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
5333   const OLECHAR szSmaller[2] = { 'x','\0' };
5334   const OLECHAR szLarger[7] = { 'L','a','r','g','e','r','\0' };
5335   BSTR str;
5336
5337   str = SysAllocStringLen(szTest, 4);
5338   ok (str != NULL, "Expected non-NULL\n");
5339   if (str)
5340   {
5341     LPINTERNAL_BSTR bstr;
5342     int changed;
5343
5344     bstr = Get(str);
5345     ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5346     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5347
5348     changed = SysReAllocString(&str, szSmaller);
5349     ok (changed == 1, "Expected 1, got %d\n", changed);
5350     /* Vista creates a new string, but older versions reuse the existing string. */
5351     /*ok (str == oldstr, "Created new string\n");*/
5352     bstr = Get(str);
5353     ok (bstr->dwLen == 2, "Expected 2, got %d\n", bstr->dwLen);
5354     ok (!lstrcmpW(bstr->szString, szSmaller), "String different\n");
5355
5356     changed = SysReAllocString(&str, szLarger);
5357     ok (changed == 1, "Expected 1, got %d\n", changed);
5358     /* Early versions always make new strings rather than resizing */
5359     /* ok (str == oldstr, "Created new string\n"); */
5360     bstr = Get(str);
5361     ok (bstr->dwLen == 12, "Expected 12, got %d\n", bstr->dwLen);
5362     ok (!lstrcmpW(bstr->szString, szLarger), "String different\n");
5363
5364     SysFreeString(str);
5365   }
5366 }
5367
5368 static void test_SysReAllocStringLen(void)
5369 {
5370   const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
5371   const OLECHAR szSmaller[2] = { 'x','\0' };
5372   const OLECHAR szLarger[7] = { 'L','a','r','g','e','r','\0' };
5373   BSTR str;
5374
5375   str = SysAllocStringLen(szTest, 4);
5376   ok (str != NULL, "Expected non-NULL\n");
5377   if (str)
5378   {
5379     LPINTERNAL_BSTR bstr;
5380     int changed;
5381
5382     bstr = Get(str);
5383     ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5384     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5385
5386     changed = SysReAllocStringLen(&str, szSmaller, 1);
5387     ok (changed == 1, "Expected 1, got %d\n", changed);
5388     /* Vista creates a new string, but older versions reuse the existing string. */
5389     /*ok (str == oldstr, "Created new string\n");*/
5390     bstr = Get(str);
5391     ok (bstr->dwLen == 2, "Expected 2, got %d\n", bstr->dwLen);
5392     ok (!lstrcmpW(bstr->szString, szSmaller), "String different\n");
5393
5394     changed = SysReAllocStringLen(&str, szLarger, 6);
5395     ok (changed == 1, "Expected 1, got %d\n", changed);
5396     /* Early versions always make new strings rather than resizing */
5397     /* ok (str == oldstr, "Created new string\n"); */
5398     bstr = Get(str);
5399     ok (bstr->dwLen == 12, "Expected 12, got %d\n", bstr->dwLen);
5400     ok (!lstrcmpW(bstr->szString, szLarger), "String different\n");
5401
5402     changed = SysReAllocStringLen(&str, str, 6);
5403     ok (changed == 1, "Expected 1, got %d\n", changed);
5404
5405     SysFreeString(str);
5406   }
5407
5408   /* Windows always returns null terminated strings */
5409   str = SysAllocStringLen(szTest, 4);
5410   ok (str != NULL, "Expected non-NULL\n");
5411   if (str)
5412   {
5413     const int CHUNK_SIZE = 64;
5414     const int STRING_SIZE = 24;
5415     int changed;
5416     changed = SysReAllocStringLen(&str, NULL, CHUNK_SIZE);
5417     ok (changed == 1, "Expected 1, got %d\n", changed);
5418     ok (str != NULL, "Expected non-NULL\n");
5419     if (str)
5420     {
5421       BSTR oldstr = str;
5422
5423       /* Filling string */
5424       memset (str, 0xAB, CHUNK_SIZE * sizeof (OLECHAR));
5425       /* Checking null terminator */
5426       changed = SysReAllocStringLen(&str, NULL, STRING_SIZE);
5427       ok (changed == 1, "Expected 1, got %d\n", changed);
5428       ok (str != NULL, "Expected non-NULL\n");
5429       if (str)
5430       {
5431         ok (str == oldstr, "Expected reuse of the old string memory\n");
5432         ok (str[STRING_SIZE] == 0,
5433             "Expected null terminator, got 0x%04X\n", str[STRING_SIZE]);
5434         SysFreeString(str);
5435       }
5436     }
5437   }
5438
5439   /* Some Windows applications use the same pointer for pbstr and psz */
5440   str = SysAllocStringLen(szTest, 4);
5441   ok(str != NULL, "Expected non-NULL\n");
5442   if(str)
5443   {
5444       SysReAllocStringLen(&str, str, 1000000);
5445       ok(SysStringLen(str)==1000000, "Incorrect string length\n");
5446       ok(!memcmp(szTest, str, 4*sizeof(WCHAR)), "Incorrect string returned\n");
5447
5448       SysFreeString(str);
5449   }
5450 }
5451
5452 static void test_BstrCopy(void)
5453 {
5454   const CHAR szTestA[6] = { 'T','e','s','t','\0','?' };
5455   const CHAR szTestTruncA[4] = { 'T','e','s','\0' };
5456   LPINTERNAL_BSTR bstr;
5457   BSTR str;
5458   HRESULT hres;
5459   VARIANT vt1, vt2;
5460
5461   str = SysAllocStringByteLen(szTestA, 3);
5462   ok (str != NULL, "Expected non-NULL\n");
5463   if (str)
5464   {
5465     V_VT(&vt1) = VT_BSTR;
5466     V_BSTR(&vt1) = str;
5467     V_VT(&vt2) = VT_EMPTY;
5468     hres = VariantCopy(&vt2, &vt1);
5469     ok (hres == S_OK,"Failed to copy binary bstring with hres 0x%08x\n", hres);
5470     bstr = Get(V_BSTR(&vt2));
5471     ok (bstr->dwLen == 3, "Expected 3, got %d\n", bstr->dwLen);
5472     ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n");
5473     VariantClear(&vt2);
5474     VariantClear(&vt1);
5475   }
5476 }
5477
5478 static void test_VarBstrCat(void)
5479 {
5480     static const WCHAR sz1[] = { 'a',0 };
5481     static const WCHAR sz2[] = { 'b',0 };
5482     static const WCHAR sz1sz2[] = { 'a','b',0 };
5483     static const WCHAR s1[] = { 'a',0 };
5484     static const WCHAR s2[] = { 'b',0 };
5485     static const WCHAR s1s2[] = { 'a',0,'b',0 };
5486     static const char str1A[] = "Have ";
5487     static const char str2A[] = "A Cigar";
5488     HRESULT ret;
5489     BSTR str1, str2, res;
5490     UINT len;
5491
5492 if (0)
5493 {
5494     /* Crash */
5495     VarBstrCat(NULL, NULL, NULL);
5496 }
5497
5498     /* Concatenation of two NULL strings works */
5499     ret = VarBstrCat(NULL, NULL, &res);
5500     ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5501     ok(res != NULL, "Expected a string\n");
5502     ok(SysStringLen(res) == 0, "Expected a 0-length string\n");
5503     SysFreeString(res);
5504
5505     str1 = SysAllocString(sz1);
5506
5507     /* Concatenation with one NULL arg */
5508     ret = VarBstrCat(NULL, str1, &res);
5509     ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5510     ok(res != NULL, "Expected a string\n");
5511     ok(SysStringLen(res) == SysStringLen(str1), "Unexpected length\n");
5512     ok(!memcmp(res, sz1, SysStringLen(str1)), "Unexpected value\n");
5513     SysFreeString(res);
5514     ret = VarBstrCat(str1, NULL, &res);
5515     ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5516     ok(res != NULL, "Expected a string\n");
5517     ok(SysStringLen(res) == SysStringLen(str1), "Unexpected length\n");
5518     ok(!memcmp(res, sz1, SysStringLen(str1)), "Unexpected value\n");
5519     SysFreeString(res);
5520
5521     /* Concatenation of two zero-terminated strings */
5522     str2 = SysAllocString(sz2);
5523     ret = VarBstrCat(str1, str2, &res);
5524     ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5525     ok(res != NULL, "Expected a string\n");
5526     ok(SysStringLen(res) == sizeof(sz1sz2) / sizeof(WCHAR) - 1,
5527      "Unexpected length\n");
5528     ok(!memcmp(res, sz1sz2, sizeof(sz1sz2)), "Unexpected value\n");
5529     SysFreeString(res);
5530
5531     SysFreeString(str2);
5532     SysFreeString(str1);
5533
5534     /* Concatenation of two strings with embedded NULLs */
5535     str1 = SysAllocStringLen(s1, sizeof(s1) / sizeof(WCHAR));
5536     str2 = SysAllocStringLen(s2, sizeof(s2) / sizeof(WCHAR));
5537
5538     ret = VarBstrCat(str1, str2, &res);
5539     ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5540     ok(res != NULL, "Expected a string\n");
5541     ok(SysStringLen(res) == sizeof(s1s2) / sizeof(WCHAR),
5542      "Unexpected length\n");
5543     ok(!memcmp(res, s1s2, sizeof(s1s2)), "Unexpected value\n");
5544     SysFreeString(res);
5545
5546     SysFreeString(str2);
5547     SysFreeString(str1);
5548
5549     /* Concatenation of ansi BSTRs, both odd byte count not including termination */
5550     str1 = SysAllocStringByteLen(str1A, sizeof(str1A)-1);
5551     str2 = SysAllocStringByteLen(str2A, sizeof(str2A)-1);
5552     len = SysStringLen(str1);
5553     ok(len == (sizeof(str1A)-1)/sizeof(WCHAR), "got length %u\n", len);
5554     len = SysStringLen(str2);
5555     ok(len == (sizeof(str2A)-1)/sizeof(WCHAR), "got length %u\n", len);
5556
5557     ret = VarBstrCat(str1, str2, &res);
5558     ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5559     ok(res != NULL, "Expected a string\n");
5560     len = (sizeof(str1A) + sizeof(str2A) - 2)/sizeof(WCHAR);
5561     ok(SysStringLen(res) == len, "got %d, expected %u\n", SysStringLen(res), len);
5562     ok(!memcmp(res, "Have A Cigar", sizeof(str1A) + sizeof(str2A) - 1), "got (%s)\n", (char*)res);
5563     SysFreeString(res);
5564
5565     SysFreeString(str2);
5566     SysFreeString(str1);
5567
5568     /* Concatenation of ansi BSTRs, both 1 byte length not including termination */
5569     str1 = SysAllocStringByteLen(str1A, 1);
5570     str2 = SysAllocStringByteLen(str2A, 1);
5571     len = SysStringLen(str1);
5572     ok(len == 0, "got length %u\n", len);
5573     len = SysStringLen(str2);
5574     ok(len == 0, "got length %u\n", len);
5575
5576     ret = VarBstrCat(str1, str2, &res);
5577     ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5578     ok(res != NULL, "Expected a string\n");
5579     ok(SysStringLen(res) == 1, "got %d, expected 1\n", SysStringLen(res));
5580     ok(!memcmp(res, "HA", 2), "got (%s)\n", (char*)res);
5581     SysFreeString(res);
5582
5583     SysFreeString(str2);
5584     SysFreeString(str1);
5585 }
5586
5587 /* IUnknown */
5588
5589 static void test_IUnknownClear(void)
5590 {
5591   HRESULT hres;
5592   VARIANTARG v;
5593   DummyDispatch u = { { &DummyDispatch_VTable }, 1, VT_UI1, FALSE };
5594   IUnknown* pu = (IUnknown*)&u.IDispatch_iface;
5595
5596   /* Test that IUnknown_Release is called on by-value */
5597   V_VT(&v) = VT_UNKNOWN;
5598   V_UNKNOWN(&v) = (IUnknown*)&u.IDispatch_iface;
5599   hres = VariantClear(&v);
5600   ok(hres == S_OK && u.ref == 0 && V_VT(&v) == VT_EMPTY,
5601      "clear unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5602      S_OK, 0, VT_EMPTY, hres, u.ref, V_VT(&v));
5603
5604   /* But not when clearing a by-reference*/
5605   u.ref = 1;
5606   V_VT(&v) = VT_UNKNOWN|VT_BYREF;
5607   V_UNKNOWNREF(&v) = &pu;
5608   hres = VariantClear(&v);
5609   ok(hres == S_OK && u.ref == 1 && V_VT(&v) == VT_EMPTY,
5610      "clear dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5611      S_OK, 1, VT_EMPTY, hres, u.ref, V_VT(&v));
5612 }
5613
5614 static void test_IUnknownCopy(void)
5615 {
5616   HRESULT hres;
5617   VARIANTARG vSrc, vDst;
5618   DummyDispatch u = { { &DummyDispatch_VTable }, 1, VT_UI1, FALSE };
5619   IUnknown* pu = (IUnknown*)&u.IDispatch_iface;
5620
5621   /* AddRef is called on by-value copy */
5622   VariantInit(&vDst);
5623   V_VT(&vSrc) = VT_UNKNOWN;
5624   V_UNKNOWN(&vSrc) = pu;
5625   hres = VariantCopy(&vDst, &vSrc);
5626   ok(hres == S_OK && u.ref == 2 && V_VT(&vDst) == VT_UNKNOWN,
5627      "copy unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5628      S_OK, 2, VT_EMPTY, hres, u.ref, V_VT(&vDst));
5629
5630   /* AddRef is skipped on copy of by-reference IDispatch */
5631   VariantInit(&vDst);
5632   u.ref = 1;
5633   V_VT(&vSrc) = VT_UNKNOWN|VT_BYREF;
5634   V_UNKNOWNREF(&vSrc) = &pu;
5635   hres = VariantCopy(&vDst, &vSrc);
5636   ok(hres == S_OK && u.ref == 1 && V_VT(&vDst) == (VT_UNKNOWN|VT_BYREF),
5637      "copy unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5638      S_OK, 1, VT_DISPATCH, hres, u.ref, V_VT(&vDst));
5639
5640   /* AddRef is called copying by-reference IDispatch with indirection */
5641   VariantInit(&vDst);
5642   u.ref = 1;
5643   V_VT(&vSrc) = VT_UNKNOWN|VT_BYREF;
5644   V_UNKNOWNREF(&vSrc) = &pu;
5645   hres = VariantCopyInd(&vDst, &vSrc);
5646   ok(hres == S_OK && u.ref == 2 && V_VT(&vDst) == VT_UNKNOWN,
5647      "copy unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5648      S_OK, 2, VT_DISPATCH, hres, u.ref, V_VT(&vDst));
5649
5650   /* Indirection in place also calls AddRef */
5651   u.ref = 1;
5652   V_VT(&vSrc) = VT_UNKNOWN|VT_BYREF;
5653   V_UNKNOWNREF(&vSrc) = &pu;
5654   hres = VariantCopyInd(&vSrc, &vSrc);
5655   ok(hres == S_OK && u.ref == 2 && V_VT(&vSrc) == VT_UNKNOWN,
5656      "copy unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5657      S_OK, 2, VT_DISPATCH, hres, u.ref, V_VT(&vSrc));
5658 }
5659
5660 static void test_IUnknownChangeTypeEx(void)
5661 {
5662   HRESULT hres;
5663   VARIANTARG vSrc, vDst;
5664   LCID lcid;
5665   VARTYPE vt;
5666   DummyDispatch u = { { &DummyDispatch_VTable }, 1, VT_UI1, FALSE };
5667   IUnknown* pu = (IUnknown*)&u.IDispatch_iface;
5668
5669   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5670
5671   V_VT(&vSrc) = VT_UNKNOWN;
5672   V_UNKNOWN(&vSrc) = pu;
5673
5674   /* =>IDispatch in place */
5675   hres = VariantChangeTypeEx(&vSrc, &vSrc, lcid, 0, VT_DISPATCH);
5676   ok(hres == S_OK && u.ref == 1 &&
5677      V_VT(&vSrc) == VT_DISPATCH && V_DISPATCH(&vSrc) == (IDispatch*)pu,
5678      "change unk(src=src): expected 0x%08x,%d,%d,%p, got 0x%08x,%d,%d,%p\n",
5679      S_OK, 1, VT_DISPATCH, pu, hres, u.ref, V_VT(&vSrc), V_DISPATCH(&vSrc));
5680
5681   /* =>IDispatch */
5682   u.ref = 1;
5683   V_VT(&vSrc) = VT_UNKNOWN;
5684   V_UNKNOWN(&vSrc) = pu;
5685   VariantInit(&vDst);
5686   hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, VT_UNKNOWN);
5687   /* Note vSrc is not cleared, as final refcount is 2 */
5688   ok(hres == S_OK && u.ref == 2 &&
5689      V_VT(&vDst) == VT_UNKNOWN && V_UNKNOWN(&vDst) == pu,
5690      "change unk(src,dst): expected 0x%08x,%d,%d,%p, got 0x%08x,%d,%d,%p\n",
5691      S_OK, 2, VT_UNKNOWN, pu, hres, u.ref, V_VT(&vDst), V_UNKNOWN(&vDst));
5692
5693   /* Can't change unknown to anything else */
5694   for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
5695   {
5696     HRESULT hExpected = DISP_E_BADVARTYPE;
5697
5698     V_VT(&vSrc) = VT_UNKNOWN;
5699     V_UNKNOWN(&vSrc) = pu;
5700     VariantInit(&vDst);
5701
5702     if (vt == VT_UNKNOWN || vt == VT_DISPATCH || vt == VT_EMPTY || vt == VT_NULL)
5703       hExpected = S_OK;
5704     else
5705     {
5706       if (vt == VT_I8 || vt == VT_UI8)
5707       {
5708         if (HAVE_OLEAUT32_I8)
5709           hExpected = DISP_E_TYPEMISMATCH;
5710       }
5711       else if (vt == VT_RECORD)
5712       {
5713         if (HAVE_OLEAUT32_RECORD)
5714           hExpected = DISP_E_TYPEMISMATCH;
5715       }
5716       else if (vt  >= VT_I2 && vt <= VT_UINT && vt != (VARTYPE)15)
5717         hExpected = DISP_E_TYPEMISMATCH;
5718     }
5719     if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
5720         hExpected = DISP_E_BADVARTYPE;
5721
5722     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
5723     ok(hres == hExpected,
5724        "change unk(badvar): vt %d expected 0x%08x, got 0x%08x\n",
5725        vt, hExpected, hres);
5726   }
5727 }
5728
5729 /* IDispatch */
5730 static void test_IDispatchClear(void)
5731 {
5732   HRESULT hres;
5733   VARIANTARG v;
5734   DummyDispatch d = { { &DummyDispatch_VTable }, 1, VT_UI1, FALSE };
5735   IDispatch* pd = &d.IDispatch_iface;
5736
5737   /* As per IUnknown */
5738
5739   V_VT(&v) = VT_DISPATCH;
5740   V_DISPATCH(&v) = pd;
5741   hres = VariantClear(&v);
5742   ok(hres == S_OK && d.ref == 0 && V_VT(&v) == VT_EMPTY,
5743      "clear dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5744      S_OK, 0, VT_EMPTY, hres, d.ref, V_VT(&v));
5745
5746   d.ref = 1;
5747   V_VT(&v) = VT_DISPATCH|VT_BYREF;
5748   V_DISPATCHREF(&v) = &pd;
5749   hres = VariantClear(&v);
5750   ok(hres == S_OK && d.ref == 1 && V_VT(&v) == VT_EMPTY,
5751      "clear dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5752      S_OK, 1, VT_EMPTY, hres, d.ref, V_VT(&v));
5753 }
5754
5755 static void test_IDispatchCopy(void)
5756 {
5757   HRESULT hres;
5758   VARIANTARG vSrc, vDst;
5759   DummyDispatch d = { { &DummyDispatch_VTable }, 1, VT_UI1, FALSE };
5760   IDispatch* pd = &d.IDispatch_iface;
5761
5762   /* As per IUnknown */
5763
5764   VariantInit(&vDst);
5765   V_VT(&vSrc) = VT_DISPATCH;
5766   V_DISPATCH(&vSrc) = pd;
5767   hres = VariantCopy(&vDst, &vSrc);
5768   ok(hres == S_OK && d.ref == 2 && V_VT(&vDst) == VT_DISPATCH,
5769      "copy dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5770      S_OK, 2, VT_EMPTY, hres, d.ref, V_VT(&vDst));
5771
5772   VariantInit(&vDst);
5773   d.ref = 1;
5774   V_VT(&vSrc) = VT_DISPATCH|VT_BYREF;
5775   V_DISPATCHREF(&vSrc) = &pd;
5776   hres = VariantCopy(&vDst, &vSrc);
5777   ok(hres == S_OK && d.ref == 1 && V_VT(&vDst) == (VT_DISPATCH|VT_BYREF),
5778      "copy dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5779      S_OK, 1, VT_DISPATCH, hres, d.ref, V_VT(&vDst));
5780
5781   VariantInit(&vDst);
5782   d.ref = 1;
5783   V_VT(&vSrc) = VT_DISPATCH|VT_BYREF;
5784   V_DISPATCHREF(&vSrc) = &pd;
5785   hres = VariantCopyInd(&vDst, &vSrc);
5786   ok(hres == S_OK && d.ref == 2 && V_VT(&vDst) == VT_DISPATCH,
5787      "copy dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5788      S_OK, 2, VT_DISPATCH, hres, d.ref, V_VT(&vDst));
5789
5790   d.ref = 1;
5791   V_VT(&vSrc) = VT_DISPATCH|VT_BYREF;
5792   V_DISPATCHREF(&vSrc) = &pd;
5793   hres = VariantCopyInd(&vSrc, &vSrc);
5794   ok(hres == S_OK && d.ref == 2 && V_VT(&vSrc) == VT_DISPATCH,
5795      "copy dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5796      S_OK, 2, VT_DISPATCH, hres, d.ref, V_VT(&vSrc));
5797 }
5798
5799 static void test_IDispatchChangeTypeEx(void)
5800 {
5801   HRESULT hres;
5802   VARIANTARG vSrc, vDst;
5803   LCID lcid;
5804   DummyDispatch d = { { &DummyDispatch_VTable }, 1, VT_UI1, FALSE };
5805   IDispatch* pd = &d.IDispatch_iface;
5806
5807   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5808
5809   V_VT(&vSrc) = VT_DISPATCH;
5810   V_DISPATCH(&vSrc) = pd;
5811
5812   /* =>IUnknown in place */
5813   hres = VariantChangeTypeEx(&vSrc, &vSrc, lcid, 0, VT_UNKNOWN);
5814   ok(hres == S_OK && d.ref == 1 &&
5815      V_VT(&vSrc) == VT_UNKNOWN && V_UNKNOWN(&vSrc) == (IUnknown*)pd,
5816      "change disp(src=src): expected 0x%08x,%d,%d,%p, got 0x%08x,%d,%d,%p\n",
5817      S_OK, 1, VT_UNKNOWN, pd, hres, d.ref, V_VT(&vSrc), V_UNKNOWN(&vSrc));
5818
5819   /* =>IUnknown */
5820   d.ref = 1;
5821   V_VT(&vSrc) = VT_DISPATCH;
5822   V_DISPATCH(&vSrc) = pd;
5823   VariantInit(&vDst);
5824   hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, VT_UNKNOWN);
5825   /* Note vSrc is not cleared, as final refcount is 2 */
5826   ok(hres == S_OK && d.ref == 2 &&
5827      V_VT(&vDst) == VT_UNKNOWN && V_UNKNOWN(&vDst) == (IUnknown*)pd,
5828      "change disp(src,dst): expected 0x%08x,%d,%d,%p, got 0x%08x,%d,%d,%p\n",
5829      S_OK, 2, VT_UNKNOWN, pd, hres, d.ref, V_VT(&vDst), V_UNKNOWN(&vDst));
5830
5831   /* FIXME: Verify that VARIANT_NOVALUEPROP prevents conversion to integral
5832    *        types. this requires that the xxxFromDisp tests work first.
5833    */
5834 }
5835
5836 /* VT_ERROR */
5837 static void test_ErrorChangeTypeEx(void)
5838 {
5839   HRESULT hres;
5840   VARIANTARG vSrc, vDst;
5841   VARTYPE vt;
5842   LCID lcid;
5843
5844   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5845
5846   for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
5847   {
5848     HRESULT hExpected = DISP_E_BADVARTYPE;
5849
5850     V_VT(&vSrc) = VT_ERROR;
5851     V_ERROR(&vSrc) = 1;
5852     VariantInit(&vDst);
5853     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
5854
5855     if (vt == VT_ERROR)
5856       hExpected = S_OK;
5857     else
5858     {
5859       if (vt == VT_I8 || vt == VT_UI8)
5860       {
5861         if (HAVE_OLEAUT32_I8)
5862           hExpected = DISP_E_TYPEMISMATCH;
5863       }
5864       else if (vt == VT_RECORD)
5865       {
5866         if (HAVE_OLEAUT32_RECORD)
5867           hExpected = DISP_E_TYPEMISMATCH;
5868       }
5869       else if (vt <= VT_UINT && vt != (VARTYPE)15)
5870         hExpected = DISP_E_TYPEMISMATCH;
5871     }
5872     if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
5873         hExpected = DISP_E_BADVARTYPE;
5874
5875     ok(hres == hExpected,
5876      "change err: vt %d expected 0x%08x, got 0x%08x\n", vt, hExpected, hres);
5877   }
5878 }
5879
5880 /* VT_EMPTY */
5881 static void test_EmptyChangeTypeEx(void)
5882 {
5883   HRESULT hres;
5884   VARIANTARG vSrc, vDst;
5885   VARTYPE vt;
5886   LCID lcid;
5887
5888   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5889
5890   for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
5891   {
5892     HRESULT hExpected = DISP_E_BADVARTYPE;
5893
5894     VariantInit(&vSrc);
5895     memset(&vDst, 0, sizeof(vDst));
5896     V_VT(&vDst) = VT_EMPTY;
5897
5898     if (vt == VT_I8 || vt == VT_UI8)
5899     {
5900       if (HAVE_OLEAUT32_I8)
5901         hExpected = S_OK;
5902     }
5903     else if (vt == VT_RECORD)
5904     {
5905       if (HAVE_OLEAUT32_RECORD)
5906         hExpected = DISP_E_TYPEMISMATCH;
5907     }
5908     else if (vt == VT_VARIANT || vt == VT_DISPATCH ||
5909               vt == VT_UNKNOWN || vt == VT_ERROR)
5910     {
5911       hExpected = DISP_E_TYPEMISMATCH;
5912     }
5913     else if (vt <= VT_UINT && vt != (VARTYPE)15)
5914       hExpected = S_OK;
5915
5916     if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
5917         hExpected = DISP_E_BADVARTYPE;
5918
5919     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
5920
5921     ok(hres == hExpected && (hres != S_OK || V_VT(&vDst) == vt),
5922        "change empty: vt %d expected 0x%08x, got 0x%08x, vt %d\n",
5923        vt, hExpected, hres, V_VT(&vDst));
5924     if(hres == S_OK) VariantClear(&vDst);
5925   }
5926 }
5927
5928 /* VT_NULL */
5929 static void test_NullChangeTypeEx(void)
5930 {
5931   HRESULT hres;
5932   VARIANTARG vSrc, vDst;
5933   VARTYPE vt;
5934   LCID lcid;
5935
5936   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5937
5938   for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
5939   {
5940     HRESULT hExpected = DISP_E_BADVARTYPE;
5941
5942     VariantInit(&vSrc);
5943     V_VT(&vSrc) = VT_NULL;
5944     memset(&vDst, 0, sizeof(vDst));
5945     V_VT(&vDst) = VT_EMPTY;
5946
5947     if (vt == VT_I8 || vt == VT_UI8)
5948     {
5949       if (HAVE_OLEAUT32_I8)
5950         hExpected = DISP_E_TYPEMISMATCH;
5951     }
5952     else if (vt == VT_RECORD)
5953     {
5954       if (HAVE_OLEAUT32_RECORD)
5955         hExpected = DISP_E_TYPEMISMATCH;
5956     }
5957     else if (vt == VT_NULL)
5958     {
5959       hExpected = S_OK;
5960     }
5961     else if (vt == VT_VARIANT || vt == VT_DISPATCH ||
5962               vt == VT_UNKNOWN || vt == VT_ERROR ||
5963               (vt <= VT_UINT && vt != (VARTYPE)15))
5964       hExpected = DISP_E_TYPEMISMATCH;
5965
5966     if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
5967         hExpected = DISP_E_BADVARTYPE;
5968
5969     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
5970
5971     ok(hres == hExpected && (hres != S_OK || V_VT(&vDst) == vt),
5972        "change null: vt %d expected 0x%08x, got 0x%08x, vt %d\n",
5973        vt, hExpected, hres, V_VT(&vDst));
5974   }
5975 }
5976
5977  
5978 /* VT_UINT */
5979 static void test_UintChangeTypeEx(void)
5980 {
5981   HRESULT hres;
5982   VARIANTARG vSrc, vDst;
5983   LCID lcid;
5984
5985   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5986
5987   /* Converting a VT_UINT to a VT_INT does not check for overflow */
5988   V_VT(&vDst) = VT_EMPTY;
5989   V_VT(&vSrc) = VT_UINT;
5990   V_UI4(&vSrc) = -1;
5991   hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, VT_I4);
5992   ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == -1,
5993      "change uint: Expected %d,0x%08x,%d got %d,0x%08x,%d\n",
5994      VT_I4, S_OK, -1, V_VT(&vDst), hres, V_I4(&vDst));
5995 }
5996
5997 #define NUM_CUST_ITEMS 16
5998
5999 static void test_ClearCustData(void)
6000 {
6001   CUSTDATA ci;
6002   unsigned i;
6003
6004   CHECKPTR(ClearCustData);
6005
6006   ci.cCustData = NUM_CUST_ITEMS;
6007   ci.prgCustData = CoTaskMemAlloc( sizeof(CUSTDATAITEM) * NUM_CUST_ITEMS );
6008   for (i = 0; i < NUM_CUST_ITEMS; i++)
6009     VariantInit(&ci.prgCustData[i].varValue);
6010   pClearCustData(&ci);
6011   ok(!ci.cCustData && !ci.prgCustData, "ClearCustData didn't clear fields!\n");
6012 }
6013
6014 static void test_NullByRef(void)
6015 {
6016   VARIANT v1, v2;
6017   HRESULT hRes;
6018
6019   VariantInit(&v1);
6020   VariantInit(&v2);
6021   V_VT(&v1) = VT_BYREF|VT_VARIANT;
6022   V_BYREF(&v1) = 0;
6023
6024   hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_I4);
6025   ok(hRes == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx should return DISP_E_TYPEMISMATCH\n");
6026
6027   VariantClear(&v1);
6028   V_VT(&v1) = VT_BYREF|VT_VARIANT;
6029   V_BYREF(&v1) = 0;
6030   V_VT(&v2) = VT_I4;
6031   V_I4(&v2) = 123;
6032
6033   hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_VARIANT);
6034   ok(hRes == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx should return DISP_E_TYPEMISMATCH\n");
6035   ok(V_VT(&v2) == VT_I4 && V_I4(&v2) == 123, "VariantChangeTypeEx shouldn't change pvargDest\n");
6036
6037   hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_BYREF|VT_I4);
6038   ok(hRes == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx should return DISP_E_TYPEMISMATCH\n");
6039
6040   hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, 0x3847);
6041   ok(hRes == DISP_E_BADVARTYPE, "VariantChangeTypeEx should return DISP_E_BADVARTYPE\n");
6042 }
6043
6044 /* Dst Variant should remain unchanged if VariantChangeType cannot convert */
6045 static void test_ChangeType_keep_dst(void)
6046 {
6047      VARIANT v1, v2;
6048      BSTR bstr;
6049      static const WCHAR testW[] = {'t','e','s','t',0};
6050      HRESULT hres;
6051
6052      bstr = SysAllocString(testW);
6053      VariantInit(&v1);
6054      VariantInit(&v2);
6055      V_VT(&v1) = VT_BSTR;
6056      V_BSTR(&v1) = bstr;
6057      hres = VariantChangeTypeEx(&v1, &v1, 0, 0, VT_INT);
6058      ok(hres == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx returns %08x\n", hres);
6059      ok(V_VT(&v1) == VT_BSTR && V_BSTR(&v1) == bstr, "VariantChangeTypeEx changed dst variant\n");
6060      V_VT(&v2) = VT_INT;
6061      V_INT(&v2) = 4;
6062      hres = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_INT);
6063      ok(hres == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx returns %08x\n", hres);
6064      ok(V_VT(&v2) == VT_INT && V_INT(&v2) == 4, "VariantChangeTypeEx changed dst variant\n");     
6065      SysFreeString(bstr);
6066 }
6067
6068 START_TEST(vartype)
6069 {
6070   hOleaut32 = GetModuleHandleA("oleaut32.dll");
6071
6072   trace("LCID's: System=0x%08x, User=0x%08x\n", GetSystemDefaultLCID(),
6073         GetUserDefaultLCID());
6074
6075   test_VarI1FromI2();
6076   test_VarI1FromI4();
6077   test_VarI1FromI8();
6078   test_VarI1FromUI1();
6079   test_VarI1FromUI2();
6080   test_VarI1FromUI4();
6081   test_VarI1FromUI8();
6082   test_VarI1FromBool();
6083   test_VarI1FromR4();
6084   test_VarI1FromR8();
6085   test_VarI1FromDate();
6086   test_VarI1FromCy();
6087   test_VarI1FromDec();
6088   test_VarI1FromStr();
6089   test_VarUI1FromDisp();
6090   test_VarI1Copy();
6091   test_VarI1ChangeTypeEx();
6092
6093   test_VarUI1FromI1();
6094   test_VarUI1FromI2();
6095   test_VarUI1FromI4();
6096   test_VarUI1FromI8();
6097   test_VarUI1FromUI2();
6098   test_VarUI1FromUI4();
6099   test_VarUI1FromUI8();
6100   test_VarUI1FromBool();
6101   test_VarUI1FromR4();
6102   test_VarUI1FromR8();
6103   test_VarUI1FromDate();
6104   test_VarUI1FromCy();
6105   test_VarUI1FromDec();
6106   test_VarUI1FromStr();
6107   test_VarUI1Copy();
6108   test_VarUI1ChangeTypeEx();
6109
6110   test_VarI2FromI1();
6111   test_VarI2FromI4();
6112   test_VarI2FromI8();
6113   test_VarI2FromUI1();
6114   test_VarI2FromUI2();
6115   test_VarI2FromUI4();
6116   test_VarI2FromUI8();
6117   test_VarI2FromBool();
6118   test_VarI2FromR4();
6119   test_VarI2FromR8();
6120   test_VarI2FromDate();
6121   test_VarI2FromCy();
6122   test_VarI2FromDec();
6123   test_VarI2FromStr();
6124   test_VarI2Copy();
6125   test_VarI2ChangeTypeEx();
6126
6127   test_VarUI2FromI1();
6128   test_VarUI2FromI2();
6129   test_VarUI2FromI4();
6130   test_VarUI2FromI8();
6131   test_VarUI2FromUI1();
6132   test_VarUI2FromUI4();
6133   test_VarUI2FromUI8();
6134   test_VarUI2FromBool();
6135   test_VarUI2FromR4();
6136   test_VarUI2FromR8();
6137   test_VarUI2FromDate();
6138   test_VarUI2FromCy();
6139   test_VarUI2FromDec();
6140   test_VarUI2FromStr();
6141   test_VarUI2Copy();
6142   test_VarUI2ChangeTypeEx();
6143
6144   test_VarI4FromI1();
6145   test_VarI4FromI2();
6146   test_VarI4FromI8();
6147   test_VarI4FromUI1();
6148   test_VarI4FromUI2();
6149   test_VarI4FromUI4();
6150   test_VarI4FromUI8();
6151   test_VarI4FromBool();
6152   test_VarI4FromR4();
6153   test_VarI4FromR8();
6154   test_VarI4FromDate();
6155   test_VarI4FromCy();
6156   test_VarI4FromDec();
6157   test_VarI4FromStr();
6158   test_VarI4Copy();
6159   test_VarI4ChangeTypeEx();
6160
6161   test_VarUI4FromI1();
6162   test_VarUI4FromI2();
6163   test_VarUI4FromUI2();
6164   test_VarUI4FromI8();
6165   test_VarUI4FromUI1();
6166   test_VarUI4FromI4();
6167   test_VarUI4FromUI8();
6168   test_VarUI4FromBool();
6169   test_VarUI4FromR4();
6170   test_VarUI4FromR8();
6171   test_VarUI4FromDate();
6172   test_VarUI4FromCy();
6173   test_VarUI4FromDec();
6174   test_VarUI4FromStr();
6175   test_VarUI4Copy();
6176   test_VarUI4ChangeTypeEx();
6177
6178   test_VarI8FromI1();
6179   test_VarI8FromUI1();
6180   test_VarI8FromI2();
6181   test_VarI8FromUI2();
6182   test_VarI8FromUI4();
6183   test_VarI8FromR4();
6184   test_VarI8FromR8();
6185   test_VarI8FromBool();
6186   test_VarI8FromUI8();
6187   test_VarI8FromCy();
6188   test_VarI8FromDec();
6189   test_VarI8FromDate();
6190   test_VarI8FromStr();
6191   test_VarI8Copy();
6192   test_VarI8ChangeTypeEx();
6193
6194   test_VarUI8FromI1();
6195   test_VarUI8FromUI1();
6196   test_VarUI8FromI2();
6197   test_VarUI8FromUI2();
6198   test_VarUI8FromUI4();
6199   test_VarUI8FromR4();
6200   test_VarUI8FromR8();
6201   test_VarUI8FromBool();
6202   test_VarUI8FromI8();
6203   test_VarUI8FromCy();
6204   test_VarUI8FromDec();
6205   test_VarUI8FromDate();
6206   test_VarUI8FromStr();
6207   test_VarUI8Copy();
6208   test_VarUI8ChangeTypeEx();
6209
6210   test_VarR4FromI1();
6211   test_VarR4FromUI1();
6212   test_VarR4FromI2();
6213   test_VarR4FromUI2();
6214   test_VarR4FromI4();
6215   test_VarR4FromUI4();
6216   test_VarR4FromR8();
6217   test_VarR4FromBool();
6218   test_VarR4FromCy();
6219   test_VarR4FromI8();
6220   test_VarR4FromUI8();
6221   test_VarR4FromDec();
6222   test_VarR4FromDate();
6223   test_VarR4FromStr();
6224   test_VarR4Copy();
6225   test_VarR4ChangeTypeEx();
6226
6227   test_VarR8FromI1();
6228   test_VarR8FromUI1();
6229   test_VarR8FromI2();
6230   test_VarR8FromUI2();
6231   test_VarR8FromI4();
6232   test_VarR8FromUI4();
6233   test_VarR8FromR4();
6234   test_VarR8FromBool();
6235   test_VarR8FromCy();
6236   test_VarR8FromI8();
6237   test_VarR8FromUI8();
6238   test_VarR8FromDec();
6239   test_VarR8FromDate();
6240   test_VarR8FromStr();
6241   test_VarR8Copy();
6242   test_VarR8ChangeTypeEx();
6243   test_VarR8Round();
6244
6245   test_VarDateFromI1();
6246   test_VarDateFromUI1();
6247   test_VarDateFromI2();
6248   test_VarDateFromUI2();
6249   test_VarDateFromI4();
6250   test_VarDateFromUI4();
6251   test_VarDateFromR4();
6252   test_VarDateFromR8();
6253   test_VarDateFromBool();
6254   test_VarDateFromCy();
6255   test_VarDateFromI8();
6256   test_VarDateFromUI8();
6257   test_VarDateFromDec();
6258   test_VarDateFromStr();
6259   test_VarDateCopy();
6260   test_VarDateChangeTypeEx();
6261
6262   test_VarCyFromI1();
6263   test_VarCyFromUI1();
6264   test_VarCyFromI2();
6265   test_VarCyFromUI2();
6266   test_VarCyFromI4();
6267   test_VarCyFromUI4();
6268   test_VarCyFromR4();
6269   test_VarCyFromR8();
6270   test_VarCyFromBool();
6271   test_VarCyFromI8();
6272   test_VarCyFromUI8();
6273   test_VarCyFromDec();
6274   test_VarCyFromDate();
6275
6276   test_VarCyAdd();
6277   test_VarCyMul();
6278   test_VarCySub();
6279   test_VarCyAbs();
6280   test_VarCyNeg();
6281   test_VarCyMulI4();
6282   test_VarCyMulI8();
6283   test_VarCyCmp();
6284   test_VarCyCmpR8();
6285   test_VarCyRound();
6286   test_VarCyFix();
6287   test_VarCyInt();
6288
6289   test_VarDecFromI1();
6290   test_VarDecFromI2();
6291   test_VarDecFromI4();
6292   test_VarDecFromI8();
6293   test_VarDecFromUI1();
6294   test_VarDecFromUI2();
6295   test_VarDecFromUI4();
6296   test_VarDecFromUI8();
6297   test_VarDecFromR4();
6298   test_VarDecFromR8();
6299   test_VarDecFromDate();
6300   test_VarDecFromStr();
6301   test_VarDecFromCy();
6302   test_VarDecFromDate();
6303   test_VarDecFromBool();
6304
6305   test_VarDecAbs();
6306   test_VarDecNeg();
6307   test_VarDecAdd();
6308   test_VarDecSub();
6309   test_VarDecCmp();
6310   test_VarDecMul();
6311   test_VarDecDiv();
6312
6313   test_VarBoolFromI1();
6314   test_VarBoolFromUI1();
6315   test_VarBoolFromI2();
6316   test_VarBoolFromUI2();
6317   test_VarBoolFromI4();
6318   test_VarBoolFromUI4();
6319   test_VarBoolFromR4();
6320   test_VarBoolFromR8();
6321   test_VarBoolFromCy();
6322   test_VarBoolFromI8();
6323   test_VarBoolFromUI8();
6324   test_VarBoolFromDec();
6325   test_VarBoolFromDate();
6326   test_VarBoolFromStr();
6327   test_VarBoolCopy();
6328   test_VarBoolChangeTypeEx();
6329
6330   test_VarBstrFromR4();
6331   test_VarBstrFromDate();
6332   test_VarBstrFromCy();
6333   test_VarBstrFromDec();
6334   test_VarBstrCmp();
6335   test_SysStringLen();
6336   test_SysStringByteLen();
6337   test_SysAllocString();
6338   test_SysAllocStringLen();
6339   test_SysAllocStringByteLen();
6340   test_SysReAllocString();
6341   test_SysReAllocStringLen();
6342   test_BstrCopy();
6343   test_VarBstrCat();
6344
6345   test_IUnknownClear();
6346   test_IUnknownCopy();
6347   test_IUnknownChangeTypeEx();
6348
6349   test_IDispatchClear();
6350   test_IDispatchCopy();
6351   test_IDispatchChangeTypeEx();
6352
6353   test_ErrorChangeTypeEx();
6354   test_EmptyChangeTypeEx();
6355   test_NullChangeTypeEx();
6356   test_UintChangeTypeEx();
6357
6358   test_ClearCustData();
6359
6360   test_NullByRef();
6361   test_ChangeType_keep_dst();
6362 }