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