oleaut32: Add test for dibs vs. ddbs in IPicture.
[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
2596   CONVERT_STR(VarUI8FromStr,"-1.5",LOCALE_NOUSEROVERRIDE); EXPECT_OVERFLOW;
2597   CONVERT_STR(VarUI8FromStr,"-0.6",LOCALE_NOUSEROVERRIDE); EXPECT_OVERFLOW;
2598   CONVERT_STR(VarUI8FromStr,"-0.5",LOCALE_NOUSEROVERRIDE); EXPECTI8(0);
2599   CONVERT_STR(VarUI8FromStr,"-0.4",LOCALE_NOUSEROVERRIDE); EXPECTI8(0);
2600   CONVERT_STR(VarUI8FromStr,"0.4",LOCALE_NOUSEROVERRIDE);  EXPECTI8(0);
2601   CONVERT_STR(VarUI8FromStr,"0.5",LOCALE_NOUSEROVERRIDE);  EXPECTI8(0);
2602   CONVERT_STR(VarUI8FromStr,"0.6",LOCALE_NOUSEROVERRIDE);  EXPECTI8(1);
2603   CONVERT_STR(VarUI8FromStr,"1.5",LOCALE_NOUSEROVERRIDE);  EXPECTI8(2);
2604 }
2605
2606 static void test_VarUI8Copy(void)
2607 {
2608   HRESULT hres;
2609   VARIANTARG vSrc, vDst;
2610   ULONGLONG in = 1;
2611
2612   if (!HAVE_OLEAUT32_I8)
2613   {
2614     win_skip("I8 and UI8 data types are not available\n");
2615     return;
2616   }
2617
2618   VariantInit(&vSrc);
2619   VariantInit(&vDst);
2620   V_VT(&vSrc) = VT_UI8;
2621   V_UI8(&vSrc) = in;
2622   hres = VariantCopy(&vDst, &vSrc);
2623   ok(hres == S_OK && V_VT(&vDst) == VT_UI8 && V_UI8(&vDst) == in,
2624      "copy hres 0x%X, type %d, value (%x%08x) %x%08x\n",
2625      hres, V_VT(&vDst), (UINT)(in >> 32), (UINT)in, (UINT)(V_UI8(&vDst) >> 32), (UINT)V_UI8(&vDst) );
2626   V_VT(&vSrc) = VT_UI8|VT_BYREF;
2627   V_UI8REF(&vSrc) = &in;
2628   hres = VariantCopy(&vDst, &vSrc);
2629   ok(hres == S_OK && V_VT(&vDst) == (VT_UI8|VT_BYREF) && V_UI8REF(&vDst) == &in,
2630      "ref hres 0x%X, type %d, ref (%p) %p\n", hres, V_VT(&vDst), &in, V_UI8REF(&vDst));
2631   hres = VariantCopyInd(&vDst, &vSrc);
2632   ok(hres == S_OK && V_VT(&vDst) == VT_UI8 && V_UI8(&vDst) == in,
2633      "copy hres 0x%X, type %d, value (%x%08x) %x%08x\n",
2634      hres, V_VT(&vDst), (UINT)(in >> 32), (UINT)in, (UINT)(V_UI8(&vDst) >> 32), (UINT)V_UI8(&vDst) );
2635 }
2636
2637 static void test_VarUI8ChangeTypeEx(void)
2638 {
2639   CONVVARS(CONV_TYPE);
2640   VARIANTARG vSrc, vDst;
2641
2642   if (!HAVE_OLEAUT32_I8)
2643   {
2644     win_skip("I8 and UI8 data types are not available\n");
2645     return;
2646   }
2647
2648   in = 1;
2649
2650   INITIAL_TYPETESTI8(VT_UI8, V_UI8);
2651   COMMON_TYPETEST;
2652 }
2653
2654 /*
2655  * VT_R4
2656  */
2657
2658 #undef CONV_TYPE
2659 #define CONV_TYPE float
2660 #undef EXPECTRES
2661 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%15.15f")
2662
2663 static void test_VarR4FromI1(void)
2664 {
2665   CONVVARS(signed char);
2666   int i;
2667
2668   CHECKPTR(VarR4FromI1);
2669   CONVERTRANGE(VarR4FromI1, -128, 128);
2670 }
2671
2672 static void test_VarR4FromUI1(void)
2673 {
2674   CONVVARS(BYTE);
2675   int i;
2676
2677   CHECKPTR(VarR4FromUI1);
2678   CONVERTRANGE(VarR4FromUI1, 0, 256);
2679 }
2680
2681 static void test_VarR4FromI2(void)
2682 {
2683   CONVVARS(SHORT);
2684   int i;
2685
2686   CHECKPTR(VarR4FromI2);
2687   CONVERTRANGE(VarR4FromI2, -32768, 32768);
2688 }
2689
2690 static void test_VarR4FromUI2(void)
2691 {
2692   CONVVARS(USHORT);
2693   int i;
2694
2695   CHECKPTR(VarR4FromUI2);
2696   CONVERTRANGE(VarR4FromUI2, 0, 65536);
2697 }
2698
2699 static void test_VarR4FromI4(void)
2700 {
2701   CONVVARS(int);
2702
2703   CHECKPTR(VarR4FromI4);
2704   CONVERT(VarR4FromI4, -2147483647-1); EXPECT(-2147483648.0f);
2705   CONVERT(VarR4FromI4, -1);            EXPECT(-1.0f);
2706   CONVERT(VarR4FromI4, 0);             EXPECT(0.0f);
2707   CONVERT(VarR4FromI4, 1);             EXPECT(1.0f);
2708   CONVERT(VarR4FromI4, 2147483647);    EXPECT(2147483647.0f);
2709 }
2710
2711 static void test_VarR4FromUI4(void)
2712 {
2713   CONVVARS(unsigned int);
2714
2715   CHECKPTR(VarR4FromUI4);
2716   CONVERT(VarR4FromUI4, 0);          EXPECT(0.0f);
2717   CONVERT(VarR4FromUI4, 1);          EXPECT(1.0f);
2718 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
2719   CONVERT(VarR4FromUI4, 0xffffffff); EXPECT(4294967296.0f);
2720 #endif
2721 }
2722
2723 static void test_VarR4FromR8(void)
2724 {
2725   CONVVARS(FLOAT);
2726
2727   CHECKPTR(VarR4FromR8);
2728   CONVERT(VarR4FromR8, -1.0); EXPECT(-1.0f);
2729   CONVERT(VarR4FromR8, 0.0); EXPECT(0.0f);
2730   CONVERT(VarR4FromR8, 1.0); EXPECT(1.0f);
2731   CONVERT(VarR4FromR8, 1.5); EXPECT(1.5f);
2732
2733   /* Skip rounding tests - no rounding is done */
2734 }
2735
2736 static void test_VarR4FromBool(void)
2737 {
2738   CONVVARS(VARIANT_BOOL);
2739
2740   CHECKPTR(VarR4FromBool);
2741   CONVERT(VarR4FromBool, VARIANT_TRUE);  EXPECT(VARIANT_TRUE * 1.0f);
2742   CONVERT(VarR4FromBool, VARIANT_FALSE); EXPECT(VARIANT_FALSE * 1.0f);
2743 }
2744
2745 static void test_VarR4FromCy(void)
2746 {
2747   CONVVARS(CY);
2748
2749   CHECKPTR(VarR4FromCy);
2750   CONVERT_CY(VarR4FromCy,-32768); EXPECT(-32768.0f);
2751   CONVERT_CY(VarR4FromCy,-1);     EXPECT(-1.0f);
2752   CONVERT_CY(VarR4FromCy,0);      EXPECT(0.0f);
2753   CONVERT_CY(VarR4FromCy,1);      EXPECT(1.0f);
2754   CONVERT_CY(VarR4FromCy,32768);  EXPECT(32768.0f);
2755
2756   CONVERT_CY(VarR4FromCy,-1.5); EXPECT(-1.5f);
2757   CONVERT_CY(VarR4FromCy,-0.6); EXPECT(-0.6f);
2758   CONVERT_CY(VarR4FromCy,-0.5); EXPECT(-0.5f);
2759   CONVERT_CY(VarR4FromCy,-0.4); EXPECT(-0.4f);
2760   CONVERT_CY(VarR4FromCy,0.4);  EXPECT(0.4f);
2761   CONVERT_CY(VarR4FromCy,0.5);  EXPECT(0.5f);
2762   CONVERT_CY(VarR4FromCy,0.6);  EXPECT(0.6f);
2763   CONVERT_CY(VarR4FromCy,1.5);  EXPECT(1.5f);
2764 }
2765
2766 static void test_VarR4FromI8(void)
2767 {
2768   CONVVARS(LONG64);
2769
2770   CHECKPTR(VarR4FromI8);
2771   CONVERT(VarR4FromI8, -1); EXPECT(-1.0f);
2772   CONVERT(VarR4FromI8, 0);  EXPECT(0.0f);
2773   CONVERT(VarR4FromI8, 1);  EXPECT(1.0f);
2774 }
2775
2776 static void test_VarR4FromUI8(void)
2777 {
2778   CONVVARS(ULONG64);
2779
2780   CHECKPTR(VarR4FromUI8);
2781   CONVERT(VarR4FromUI8, 0); EXPECT(0.0f);
2782   CONVERT(VarR4FromUI8, 1); EXPECT(1.0f);
2783 }
2784
2785 static void test_VarR4FromDec(void)
2786 {
2787   CONVVARS(DECIMAL);
2788
2789   CHECKPTR(VarR4FromDec);
2790
2791   CONVERT_BADDEC(VarR4FromDec);
2792
2793   CONVERT_DEC(VarR4FromDec,0,0x80,0,32768); EXPECT(-32768.0f);
2794   CONVERT_DEC(VarR4FromDec,0,0x80,0,1);     EXPECT(-1.0f);
2795   CONVERT_DEC(VarR4FromDec,0,0,0,0);        EXPECT(0.0f);
2796   CONVERT_DEC(VarR4FromDec,0,0,0,1);        EXPECT(1.0f);
2797   CONVERT_DEC(VarR4FromDec,0,0,0,32767);    EXPECT(32767.0f);
2798
2799   CONVERT_DEC(VarR4FromDec,2,0x80,0,3276800); EXPECT(-32768.0f);
2800   CONVERT_DEC(VarR4FromDec,2,0,0,3276700);    EXPECT(32767.0f);
2801   
2802   CONVERT_DEC(VarR4FromDec,0,0,1,0);        EXPECT(18446744073709551616.0f);
2803 }
2804
2805 static void test_VarR4FromDate(void)
2806 {
2807   CONVVARS(DATE);
2808
2809   CHECKPTR(VarR4FromDate);
2810   CONVERT(VarR4FromDate, -1.0); EXPECT(-1.0f);
2811   CONVERT(VarR4FromDate, 0.0);  EXPECT(0.0f);
2812   CONVERT(VarR4FromDate, 1.0);  EXPECT(1.0f);
2813 }
2814
2815 static void test_VarR4FromStr(void)
2816 {
2817   CONVVARS(LCID);
2818   OLECHAR buff[128];
2819
2820   in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
2821
2822   CHECKPTR(VarR4FromStr);
2823
2824   CONVERT_STR(VarR4FromStr,NULL,0);    EXPECT_MISMATCH;
2825   CONVERT_STR(VarR4FromStr,"-1", 0);   EXPECT(-1.0f);
2826   CONVERT_STR(VarR4FromStr,"0", 0);    EXPECT(0.0f);
2827   CONVERT_STR(VarR4FromStr,"1", 0);    EXPECT(1.0f);
2828
2829   CONVERT_STR(VarR4FromStr,"-1.5",LOCALE_NOUSEROVERRIDE); EXPECT(-1.5f);
2830   CONVERT_STR(VarR4FromStr,"-0.6",LOCALE_NOUSEROVERRIDE); EXPECT(-0.6f);
2831   CONVERT_STR(VarR4FromStr,"-0.5",LOCALE_NOUSEROVERRIDE); EXPECT(-0.5f);
2832   CONVERT_STR(VarR4FromStr,"-0.4",LOCALE_NOUSEROVERRIDE); EXPECT(-0.4f);
2833   CONVERT_STR(VarR4FromStr,"0.4",LOCALE_NOUSEROVERRIDE);  EXPECT(0.4f);
2834   CONVERT_STR(VarR4FromStr,"0.5",LOCALE_NOUSEROVERRIDE);  EXPECT(0.5f);
2835   CONVERT_STR(VarR4FromStr,"0.6",LOCALE_NOUSEROVERRIDE);  EXPECT(0.6f);
2836   CONVERT_STR(VarR4FromStr,"1.5",LOCALE_NOUSEROVERRIDE);  EXPECT(1.5f);
2837 }
2838
2839 static void test_VarR4Copy(void)
2840 {
2841   COPYTEST(77665544.0f, VT_R4, V_R4(&vSrc), V_R4(&vDst), V_R4REF(&vSrc),V_R4REF(&vDst), "%15.15f");
2842 }
2843
2844 static void test_VarR4ChangeTypeEx(void)
2845 {
2846 #ifdef HAS_UINT64_TO_FLOAT
2847   CONVVARS(CONV_TYPE);
2848   VARIANTARG vSrc, vDst;
2849
2850   in = 1.0f;
2851
2852   INITIAL_TYPETEST(VT_R4, V_R4, "%f");
2853   COMMON_TYPETEST;
2854 #endif
2855 }
2856
2857 /*
2858  * VT_R8
2859  */
2860
2861 #undef CONV_TYPE
2862 #define CONV_TYPE double
2863 #undef EXPECTRES
2864 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%15.15f")
2865
2866 static void test_VarR8FromI1(void)
2867 {
2868   CONVVARS(signed char);
2869   int i;
2870
2871   CHECKPTR(VarR8FromI1);
2872   CONVERTRANGE(VarR8FromI1, -128, 128);
2873 }
2874
2875 static void test_VarR8FromUI1(void)
2876 {
2877   CONVVARS(BYTE);
2878   int i;
2879
2880   CHECKPTR(VarR8FromUI1);
2881   CONVERTRANGE(VarR8FromUI1, 0, 256);
2882 }
2883
2884 static void test_VarR8FromI2(void)
2885 {
2886   CONVVARS(SHORT);
2887   int i;
2888
2889   CHECKPTR(VarR8FromI2);
2890   CONVERTRANGE(VarR8FromI2, -32768, 32768);
2891 }
2892
2893 static void test_VarR8FromUI2(void)
2894 {
2895   CONVVARS(USHORT);
2896   int i;
2897
2898   CHECKPTR(VarR8FromUI2);
2899   CONVERTRANGE(VarR8FromUI2, 0, 65536);
2900 }
2901
2902 static void test_VarR8FromI4(void)
2903 {
2904   CONVVARS(int);
2905
2906   CHECKPTR(VarR8FromI4);
2907   CONVERT(VarR8FromI4, -2147483647-1); EXPECT(-2147483648.0);
2908   CONVERT(VarR8FromI4, -1);            EXPECT(-1.0);
2909   CONVERT(VarR8FromI4, 0);             EXPECT(0.0);
2910   CONVERT(VarR8FromI4, 1);             EXPECT(1.0);
2911   CONVERT(VarR8FromI4, 0x7fffffff);    EXPECT(2147483647.0);
2912 }
2913
2914 static void test_VarR8FromUI4(void)
2915 {
2916   CONVVARS(unsigned int);
2917
2918   CHECKPTR(VarR8FromUI4);
2919   CONVERT(VarR8FromUI4, 0);          EXPECT(0.0);
2920   CONVERT(VarR8FromUI4, 1);          EXPECT(1.0);
2921   CONVERT(VarR8FromUI4, 0xffffffff); EXPECT(4294967295.0);
2922 }
2923
2924 static void test_VarR8FromR4(void)
2925 {
2926   CONVVARS(FLOAT);
2927
2928   CHECKPTR(VarR8FromR4);
2929   CONVERT(VarR8FromR4, -1.0f); EXPECT(-1.0);
2930   CONVERT(VarR8FromR4, 0.0f);  EXPECT(0.0);
2931   CONVERT(VarR8FromR4, 1.0f);  EXPECT(1.0);
2932   CONVERT(VarR8FromR4, 1.5f);  EXPECT(1.5);
2933
2934   /* Skip rounding tests - no rounding is done */
2935 }
2936
2937 static void test_VarR8FromBool(void)
2938 {
2939   CONVVARS(VARIANT_BOOL);
2940
2941   CHECKPTR(VarR8FromBool);
2942   CONVERT(VarR8FromBool, VARIANT_TRUE);  EXPECT(VARIANT_TRUE * 1.0);
2943   CONVERT(VarR8FromBool, VARIANT_FALSE); EXPECT(VARIANT_FALSE * 1.0);
2944 }
2945
2946 static void test_VarR8FromCy(void)
2947 {
2948   CONVVARS(CY);
2949
2950   CHECKPTR(VarR8FromCy);
2951   CONVERT_CY(VarR8FromCy,-32769); EXPECT(-32769.0);
2952   CONVERT_CY(VarR8FromCy,-32768); EXPECT(-32768.0);
2953   CONVERT_CY(VarR8FromCy,-1);     EXPECT(-1.0);
2954   CONVERT_CY(VarR8FromCy,0);      EXPECT(0.0);
2955   CONVERT_CY(VarR8FromCy,1);      EXPECT(1.0);
2956   CONVERT_CY(VarR8FromCy,32767);  EXPECT(32767.0);
2957   CONVERT_CY(VarR8FromCy,32768);  EXPECT(32768.0);
2958
2959   CONVERT_CY(VarR8FromCy,-1.5); EXPECT(-1.5);
2960   CONVERT_CY(VarR8FromCy,-0.6); EXPECT(-0.6);
2961   CONVERT_CY(VarR8FromCy,-0.5); EXPECT(-0.5);
2962   CONVERT_CY(VarR8FromCy,-0.4); EXPECT(-0.4);
2963   CONVERT_CY(VarR8FromCy,0.4);  EXPECT(0.4);
2964   CONVERT_CY(VarR8FromCy,0.5);  EXPECT(0.5);
2965   CONVERT_CY(VarR8FromCy,0.6);  EXPECT(0.6);
2966   CONVERT_CY(VarR8FromCy,1.5);  EXPECT(1.5);
2967 }
2968
2969 static void test_VarR8FromI8(void)
2970 {
2971   CONVVARS(LONG64);
2972
2973   CHECKPTR(VarR8FromI8);
2974   CONVERT(VarR8FromI8, -1); EXPECT(-1.0);
2975   CONVERT(VarR8FromI8, 0);  EXPECT(0.0);
2976   CONVERT(VarR8FromI8, 1);  EXPECT(1.0);
2977 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
2978   CONVERT_I8(VarR8FromI8, 0x7fffffff,0xffffffff); EXPECT(9223372036854775808.0);
2979 #endif
2980 }
2981
2982 static void test_VarR8FromUI8(void)
2983 {
2984   CONVVARS(ULONG64);
2985
2986   CHECKPTR(VarR8FromUI8);
2987   CONVERT(VarR8FromUI8, 0); EXPECT(0.0);
2988   CONVERT(VarR8FromUI8, 1); EXPECT(1.0);
2989 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
2990   CONVERT_I8(VarR8FromUI8, 0x80000000,0); EXPECT(9223372036854775808.0);
2991 #endif
2992 }
2993
2994 static void test_VarR8FromDec(void)
2995 {
2996   CONVVARS(DECIMAL);
2997
2998   CHECKPTR(VarR8FromDec);
2999
3000   CONVERT_BADDEC(VarR8FromDec);
3001
3002   CONVERT_DEC(VarR8FromDec,0,0x80,0,32768); EXPECT(-32768.0);
3003   CONVERT_DEC(VarR8FromDec,0,0x80,0,1);     EXPECT(-1.0);
3004   CONVERT_DEC(VarR8FromDec,0,0,0,0);        EXPECT(0.0);
3005   CONVERT_DEC(VarR8FromDec,0,0,0,1);        EXPECT(1.0);
3006   CONVERT_DEC(VarR8FromDec,0,0,0,32767);    EXPECT(32767.0);
3007
3008   CONVERT_DEC(VarR8FromDec,2,0x80,0,3276800); EXPECT(-32768.0);
3009   CONVERT_DEC(VarR8FromDec,2,0,0,3276700);    EXPECT(32767.0);
3010
3011   CONVERT_DEC(VarR8FromDec,0,0,1,0);        EXPECT(18446744073709551616.0);
3012 }
3013
3014 static void test_VarR8FromDate(void)
3015 {
3016   CONVVARS(DATE);
3017
3018   CHECKPTR(VarR8FromDate);
3019   CONVERT(VarR8FromDate, -1.0); EXPECT(-1.0);
3020   CONVERT(VarR8FromDate, -0.0); EXPECT(0.0);
3021   CONVERT(VarR8FromDate, 1.0);  EXPECT(1.0);
3022 }
3023
3024 static void test_VarR8FromStr(void)
3025 {
3026   CONVVARS(LCID);
3027   OLECHAR buff[128];
3028
3029   in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3030
3031   CHECKPTR(VarR8FromStr);
3032
3033   CONVERT_STR(VarR8FromStr,NULL,0);   EXPECT_MISMATCH;
3034   CONVERT_STR(VarR8FromStr,"",0);     EXPECT_MISMATCH;
3035   CONVERT_STR(VarR8FromStr," ",0);    EXPECT_MISMATCH;
3036
3037   CONVERT_STR(VarR8FromStr,"0",LOCALE_NOUSEROVERRIDE);    EXPECT(0.0);
3038   CONVERT_STR(VarR8FromStr,"-1.5",LOCALE_NOUSEROVERRIDE); EXPECT(-1.5);
3039   CONVERT_STR(VarR8FromStr,"-0.6",LOCALE_NOUSEROVERRIDE); EXPECT(-0.6);
3040   CONVERT_STR(VarR8FromStr,"-0.5",LOCALE_NOUSEROVERRIDE); EXPECT(-0.5);
3041   CONVERT_STR(VarR8FromStr,"-0.4",LOCALE_NOUSEROVERRIDE); EXPECT(-0.4);
3042   CONVERT_STR(VarR8FromStr,"0.4",LOCALE_NOUSEROVERRIDE);  EXPECT(0.4);
3043   CONVERT_STR(VarR8FromStr,"0.5",LOCALE_NOUSEROVERRIDE);  EXPECT(0.5);
3044   CONVERT_STR(VarR8FromStr,"0.6",LOCALE_NOUSEROVERRIDE);  EXPECT(0.6);
3045   CONVERT_STR(VarR8FromStr,"1.5",LOCALE_NOUSEROVERRIDE);  EXPECT(1.5);
3046
3047   /* We already have exhaustive tests for number parsing, so skip those tests here */
3048 }
3049
3050 static void test_VarR8Copy(void)
3051 {
3052   COPYTEST(77665544.0, VT_R8, V_R8(&vSrc), V_R8(&vDst), V_R8REF(&vSrc),V_R8REF(&vDst), "%16.16g");
3053 }
3054
3055 static void test_VarR8ChangeTypeEx(void)
3056 {
3057 #ifdef HAS_UINT64_TO_FLOAT
3058   CONVVARS(CONV_TYPE);
3059   VARIANTARG vSrc, vDst;
3060
3061   in = 1.0;
3062
3063   INITIAL_TYPETEST(VT_R8, V_R8, "%g");
3064   COMMON_TYPETEST;
3065 #endif
3066 }
3067
3068 #define MATHRND(l, r) left = l; right = r; hres = pVarR8Round(left, right, &out)
3069
3070 static void test_VarR8Round(void)
3071 {
3072   HRESULT hres;
3073   double left = 0.0, out;
3074   int right;
3075
3076   CHECKPTR(VarR8Round);
3077   MATHRND(0.5432, 5);  EXPECT(0.5432);
3078   MATHRND(0.5432, 4);  EXPECT(0.5432);
3079   MATHRND(0.5432, 3);  EXPECT(0.543);
3080   MATHRND(0.5432, 2);  EXPECT(0.54);
3081   MATHRND(0.5432, 1);  EXPECT(0.5);
3082   MATHRND(0.5532, 0);  EXPECT(1);
3083   MATHRND(0.5532, -1); EXPECT_INVALID;
3084
3085   MATHRND(0.5568, 5);  EXPECT(0.5568);
3086   MATHRND(0.5568, 4);  EXPECT(0.5568);
3087   MATHRND(0.5568, 3);  EXPECT(0.557);
3088   MATHRND(0.5568, 2);  EXPECT(0.56);
3089   MATHRND(0.5568, 1);  EXPECT(0.6);
3090   MATHRND(0.5568, 0);  EXPECT(1);
3091   MATHRND(0.5568, -1); EXPECT_INVALID;
3092
3093   MATHRND(0.4999, 0); EXPECT(0);
3094   MATHRND(0.5000, 0); EXPECT(0);
3095   MATHRND(0.5001, 0); EXPECT(1);
3096   MATHRND(1.4999, 0); EXPECT(1);
3097   MATHRND(1.5000, 0); EXPECT(2);
3098   MATHRND(1.5001, 0); EXPECT(2);
3099 }
3100
3101 /*
3102  * VT_DATE
3103  */
3104
3105 #undef CONV_TYPE
3106 #define CONV_TYPE DATE
3107
3108 static void test_VarDateFromI1(void)
3109 {
3110   CONVVARS(signed char);
3111   int i;
3112
3113   CHECKPTR(VarDateFromI1);
3114   CONVERTRANGE(VarDateFromI1, -128, 128);
3115 }
3116
3117 static void test_VarDateFromUI1(void)
3118 {
3119   CONVVARS(BYTE);
3120   int i;
3121
3122   CHECKPTR(VarDateFromUI1);
3123   CONVERTRANGE(VarDateFromUI1, 0, 256);
3124 }
3125
3126 static void test_VarDateFromI2(void)
3127 {
3128   CONVVARS(SHORT);
3129   int i;
3130
3131   CHECKPTR(VarDateFromI2);
3132   CONVERTRANGE(VarDateFromI2, -32768, 32768);
3133 }
3134
3135 static void test_VarDateFromUI2(void)
3136 {
3137   CONVVARS(USHORT);
3138   int i;
3139
3140   CHECKPTR(VarDateFromUI2);
3141   CONVERTRANGE(VarDateFromUI2, 0, 65536);
3142 }
3143
3144 static void test_VarDateFromI4(void)
3145 {
3146   CONVVARS(int);
3147
3148   CHECKPTR(VarDateFromI4);
3149   CONVERT(VarDateFromI4, DATE_MIN-1);
3150   if (hres != DISP_E_TYPEMISMATCH) /* Early versions return this, incorrectly */
3151     EXPECT_OVERFLOW;
3152   CONVERT(VarDateFromI4, DATE_MIN);   EXPECT(DATE_MIN);
3153   CONVERT(VarDateFromI4, -1);         EXPECT(-1.0);
3154   CONVERT(VarDateFromI4, 0);          EXPECT(0.0);
3155   CONVERT(VarDateFromI4, 1);          EXPECT(1.0);
3156   CONVERT(VarDateFromI4, DATE_MAX);   EXPECT(DATE_MAX);
3157   CONVERT(VarDateFromI4, DATE_MAX+1);
3158   if (hres != DISP_E_TYPEMISMATCH) /* Early versions return this, incorrectly */
3159     EXPECT_OVERFLOW;
3160 }
3161
3162 static void test_VarDateFromUI4(void)
3163 {
3164   CONVVARS(unsigned int);
3165
3166   CHECKPTR(VarDateFromUI4);
3167   CONVERT(VarDateFromUI4, 0);          EXPECT(0.0);
3168   CONVERT(VarDateFromUI4, 1);          EXPECT(1.0);
3169   CONVERT(VarDateFromUI4, DATE_MAX);   EXPECT(DATE_MAX);
3170   CONVERT(VarDateFromUI4, DATE_MAX+1);
3171   if (hres != DISP_E_TYPEMISMATCH) /* Early versions return this, incorrectly */
3172     EXPECT_OVERFLOW;
3173 }
3174
3175 static void test_VarDateFromR4(void)
3176 {
3177   CONVVARS(FLOAT);
3178
3179   CHECKPTR(VarDateFromR4);
3180   CONVERT(VarDateFromR4, -1.0f); EXPECT(-1.0);
3181   CONVERT(VarDateFromR4, 0.0f);  EXPECT(0.0);
3182   CONVERT(VarDateFromR4, 1.0f);  EXPECT(1.0);
3183   CONVERT(VarDateFromR4, 1.5f);  EXPECT(1.5);
3184 }
3185
3186 static void test_VarDateFromR8(void)
3187 {
3188   CONVVARS(double);
3189
3190   CHECKPTR(VarDateFromR8);
3191   CONVERT(VarDateFromR8, -1.0f); EXPECT(-1.0);
3192   CONVERT(VarDateFromR8, 0.0f);  EXPECT(0.0);
3193   CONVERT(VarDateFromR8, 1.0f);  EXPECT(1.0);
3194   CONVERT(VarDateFromR8, 1.5f);  EXPECT(1.5);
3195 }
3196
3197 static void test_VarDateFromBool(void)
3198 {
3199   CONVVARS(VARIANT_BOOL);
3200
3201   CHECKPTR(VarDateFromBool);
3202   CONVERT(VarDateFromBool, VARIANT_TRUE);  EXPECT(VARIANT_TRUE * 1.0);
3203   CONVERT(VarDateFromBool, VARIANT_FALSE); EXPECT(VARIANT_FALSE * 1.0);
3204 }
3205
3206 static void test_VarDateFromCy(void)
3207 {
3208   CONVVARS(CY);
3209
3210   CHECKPTR(VarDateFromCy);
3211   CONVERT_CY(VarDateFromCy,-32769); EXPECT(-32769.0);
3212   CONVERT_CY(VarDateFromCy,-32768); EXPECT(-32768.0);
3213   CONVERT_CY(VarDateFromCy,-1);     EXPECT(-1.0);
3214   CONVERT_CY(VarDateFromCy,0);      EXPECT(0.0);
3215   CONVERT_CY(VarDateFromCy,1);      EXPECT(1.0);
3216   CONVERT_CY(VarDateFromCy,32767);  EXPECT(32767.0);
3217   CONVERT_CY(VarDateFromCy,32768);  EXPECT(32768.0);
3218
3219   CONVERT_CY(VarDateFromCy,-1.5); EXPECT(-1.5);
3220   CONVERT_CY(VarDateFromCy,-0.6); EXPECT(-0.6);
3221   CONVERT_CY(VarDateFromCy,-0.5); EXPECT(-0.5);
3222   CONVERT_CY(VarDateFromCy,-0.4); EXPECT(-0.4);
3223   CONVERT_CY(VarDateFromCy,0.4);  EXPECT(0.4);
3224   CONVERT_CY(VarDateFromCy,0.5);  EXPECT(0.5);
3225   CONVERT_CY(VarDateFromCy,0.6);  EXPECT(0.6);
3226   CONVERT_CY(VarDateFromCy,1.5);  EXPECT(1.5);
3227 }
3228
3229 static void test_VarDateFromI8(void)
3230 {
3231   CONVVARS(LONG64);
3232
3233   CHECKPTR(VarDateFromI8);
3234   CONVERT(VarDateFromI8, DATE_MIN-1); EXPECT_OVERFLOW;
3235   CONVERT(VarDateFromI8, DATE_MIN);   EXPECT(DATE_MIN);
3236   CONVERT(VarDateFromI8, -1);         EXPECT(-1.0);
3237   CONVERT(VarDateFromI8, 0);          EXPECT(0.0);
3238   CONVERT(VarDateFromI8, 1);          EXPECT(1.0);
3239   CONVERT(VarDateFromI8, DATE_MAX);   EXPECT(DATE_MAX);
3240   CONVERT(VarDateFromI8, DATE_MAX+1); EXPECT_OVERFLOW;
3241 }
3242
3243 static void test_VarDateFromUI8(void)
3244 {
3245   CONVVARS(ULONG64);
3246
3247   CHECKPTR(VarDateFromUI8);
3248   CONVERT(VarDateFromUI8, 0);          EXPECT(0.0);
3249   CONVERT(VarDateFromUI8, 1);          EXPECT(1.0);
3250   CONVERT(VarDateFromUI8, DATE_MAX);   EXPECT(DATE_MAX);
3251   CONVERT(VarDateFromUI8, DATE_MAX+1); EXPECT_OVERFLOW;
3252 }
3253
3254 static void test_VarDateFromDec(void)
3255 {
3256   CONVVARS(DECIMAL);
3257
3258   CHECKPTR(VarDateFromDec);
3259
3260   CONVERT_BADDEC(VarDateFromDec);
3261
3262   CONVERT_DEC(VarDateFromDec,0,0x80,0,32768); EXPECT(-32768.0);
3263   CONVERT_DEC(VarDateFromDec,0,0x80,0,1);     EXPECT(-1.0);
3264   CONVERT_DEC(VarDateFromDec,0,0,0,0);        EXPECT(0.0);
3265   CONVERT_DEC(VarDateFromDec,0,0,0,1);        EXPECT(1.0);
3266   CONVERT_DEC(VarDateFromDec,0,0,0,32767);    EXPECT(32767.0);
3267
3268   CONVERT_DEC(VarDateFromDec,2,0x80,0,3276800); EXPECT(-32768.0);
3269   CONVERT_DEC(VarDateFromDec,2,0,0,3276700);    EXPECT(32767.0);
3270 }
3271
3272 #define DFS(str) \
3273   buff[0] = '\0'; out = 0.0; \
3274   if (str) MultiByteToWideChar(CP_ACP,0,str,-1,buff,sizeof(buff)/sizeof(WCHAR)); \
3275   hres = pVarDateFromStr(str ? buff : NULL,lcid,LOCALE_NOUSEROVERRIDE,&out)
3276
3277 #define MKRELDATE(day,mth) st.wMonth = mth; st.wDay = day; \
3278   pSystemTimeToVariantTime(&st,&relative)
3279
3280 static const char * const BadDateStrings[] =
3281 {
3282   "True", "False", /* Plain text */
3283   "0.", ".0", "-1.1", "1.1-", /* Partial specifications */
3284   "1;2;3", "1*2*3", "1@2@3", "1#2#3", "(1:2)","<1:2>","1|2|3", /* Bad chars */
3285   "0", "1", /* 1 element */
3286   "0.60", "24.00", "0:60", "24:00", "1 2 am", "1 am 2", /* 2 elements */
3287   "1.5 2", "1 5.2", "2 32 3", "1 2 am 3", /* 3 elements */
3288   "1 2.3 4", "1.2.3 4", "1 2.3.4", "1.2 3.4", "1.2.3.4", "1 2 3 4",
3289   "1 am 2 3.4", "1 2 am 3.4", "1.2 3 am 4", "1.2 3 4 am", /* 4 elements */
3290   "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",
3291   "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",
3292   "1.2.3 4 am 5", "1.2.3 4 5 am", "1.2 3 am 4 5",
3293   "1.2 3 4 am 5", "1.2 3 4 5 am", "1 am 2 3.4.5", "1 2 am 3.4.5",
3294   "1 am 2 3 4.5", "1 2 am 3 4.5", "1 2 3 am 4.5", /* 5 elements */
3295   /* 6 elements */
3296   "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",
3297   "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",
3298   "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",
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 #if 0
3301   /* following throws an exception on winME */
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 #endif
3304   "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",
3305 #if 0
3306   /* following throws an exception on winME */
3307   "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",
3308 #endif
3309   "1 2 am 3 4.5.6", "1 2 3 am 4.5.6"
3310 };
3311
3312 static void test_VarDateFromStr(void)
3313 {
3314   LCID lcid;
3315   DATE out, relative;
3316   HRESULT hres;
3317   SYSTEMTIME st;
3318   OLECHAR buff[128];
3319   size_t i;
3320
3321   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3322
3323   CHECKPTR(VarDateFromStr);
3324   CHECKPTR(SystemTimeToVariantTime);
3325
3326   /* Some date formats are relative, so we need to find the current year */
3327   GetSystemTime(&st);
3328   st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0;
3329   DFS(NULL); EXPECT_MISMATCH;
3330
3331   /* Floating point number are not recognised */
3332   DFS("0.0");
3333   if (hres == S_OK)
3334     EXPECT_DBL(0.0); /* Very old versions accept this string */
3335   else
3336     EXPECT_MISMATCH;
3337
3338   /* 1 element - can only be a time, and only if it has am/pm */
3339   DFS("1 am"); EXPECT_DBL(0.04166666666666666);
3340   /* 2 elements */
3341   /* A decimal point is treated as a time separator.
3342    * The following are converted as hours/minutes.
3343    */
3344   DFS("0.1");  EXPECT_DBL(0.0006944444444444445);
3345   DFS("0.40"); EXPECT_DBL(0.02777777777777778);
3346   DFS("2.5");  EXPECT_DBL(0.08680555555555555);
3347   /* A colon acts as a decimal point */
3348   DFS("0:1");  EXPECT_DBL(0.0006944444444444445);
3349   DFS("0:20"); EXPECT_DBL(0.01388888888888889);
3350   DFS("0:40"); EXPECT_DBL(0.02777777777777778);
3351   DFS("3:5");  EXPECT_DBL(0.1284722222222222);
3352   /* Check the am/pm limits */
3353   DFS("00:00 AM"); EXPECT_DBL(0.0);
3354   DFS("00:00 a");  EXPECT_DBL(0.0);
3355   DFS("12:59 AM"); EXPECT_DBL(0.04097222222222222);
3356   DFS("12:59 A");  EXPECT_DBL(0.04097222222222222);
3357   DFS("00:00 pm"); EXPECT_DBL(0.5);
3358   DFS("00:00 p");  EXPECT_DBL(0.5);
3359   DFS("12:59 pm"); EXPECT_DBL(0.5409722222222222);
3360   DFS("12:59 p");  EXPECT_DBL(0.5409722222222222);
3361   /* AM/PM is ignored if hours > 12 */
3362   DFS("13:00 AM"); EXPECT_DBL(0.5416666666666666);
3363   DFS("13:00 PM"); EXPECT_DBL(0.5416666666666666);
3364
3365   /* Space, dash and slash all indicate a date format. */
3366   /* If both numbers are valid month values => month/day of current year */
3367   DFS("1 2"); MKRELDATE(2,1); EXPECT_DBL(relative);
3368   DFS("2 1"); MKRELDATE(1,2); EXPECT_DBL(relative);
3369   /* one number not valid month, is a valid day, other number valid month:
3370    * that number becomes the day.
3371    */
3372   DFS("14 1");   MKRELDATE(14,1); EXPECT_DBL(relative);
3373   DFS("1 14");   EXPECT_DBL(relative);
3374   /* If the numbers can't be day/month, they are assumed to be year/month */
3375   DFS("30 2");   EXPECT_DBL(10990.0);
3376   DFS("2 30");   EXPECT_DBL(10990.0);
3377   DFS("32 49");  EXPECT_MISMATCH; /* Can't be any format */
3378   DFS("0 49");   EXPECT_MISMATCH; /* Can't be any format */
3379   /* If a month name is given the other number is the day */
3380   DFS("Jan 2");  MKRELDATE(2,1); EXPECT_DBL(relative);
3381   DFS("2 Jan");  EXPECT_DBL(relative);
3382   /* Unless it can't be, in which case it becomes the year */
3383   DFS("Jan 35"); EXPECT_DBL(12785.0);
3384   DFS("35 Jan"); EXPECT_DBL(12785.0);
3385   DFS("Jan-35"); EXPECT_DBL(12785.0);
3386   DFS("35-Jan"); EXPECT_DBL(12785.0);
3387   DFS("Jan/35"); EXPECT_DBL(12785.0);
3388   DFS("35/Jan"); EXPECT_DBL(12785.0);
3389   /* 3 elements */
3390   /* 3 numbers and time separator => h:m:s */
3391   DFS("0.1.0");  EXPECT_DBL(0.0006944444444444445);
3392   DFS("1.5.2");  EXPECT_DBL(0.04516203703703704);
3393   /* 3 numbers => picks date giving preference to lcid format */
3394   DFS("1 2 3");  EXPECT_DBL(37623.0);
3395   DFS("14 2 3"); EXPECT_DBL(41673.0);
3396   DFS("2 14 3"); EXPECT_DBL(37666.0);
3397   DFS("2 3 14"); EXPECT_DBL(41673.0);
3398   DFS("32 2 3"); EXPECT_DBL(11722.0);
3399   DFS("2 3 32"); EXPECT_DBL(11722.0);
3400   DFS("1 2 29"); EXPECT_DBL(47120.0);
3401   /* After 30, two digit dates are expected to be in the 1900's */
3402   DFS("1 2 30"); EXPECT_DBL(10960.0);
3403   DFS("1 2 31"); EXPECT_DBL(11325.0);
3404   DFS("3 am 1 2"); MKRELDATE(2,1); relative += 0.125; EXPECT_DBL(relative);
3405   DFS("1 2 3 am"); EXPECT_DBL(relative);
3406
3407   /* 4 elements -interpreted as 2 digit date & time */
3408   DFS("1.2 3 4");   MKRELDATE(4,3); relative += 0.04305555556; EXPECT_DBL(relative);
3409   DFS("3 4 1.2");   EXPECT_DBL(relative);
3410   /* 5 elements - interpreted as 2 & 3 digit date/times */
3411   DFS("1.2.3 4 5"); MKRELDATE(5,4); relative += 0.04309027778; EXPECT_DBL(relative);
3412   DFS("1.2 3 4 5"); EXPECT_DBL(38415.04305555556);
3413 #if 0
3414   /* following throws an exception on winME */
3415   DFS("1 2 3.4.5"); MKRELDATE(2,1); relative += 0.12783564815; EXPECT_DBL(relative);
3416 #endif
3417   DFS("1 2 3 4.5"); EXPECT_DBL(37623.17013888889);
3418   /* 6 elements - interpreted as 3 digit date/times */
3419   DFS("1.2.3 4 5 6"); EXPECT_DBL(38812.04309027778);
3420   DFS("1 2 3 4.5.6"); EXPECT_DBL(37623.17020833334);
3421
3422   for (i = 0; i < sizeof(BadDateStrings)/sizeof(char*); i++)
3423   {
3424     DFS(BadDateStrings[i]); EXPECT_MISMATCH;
3425   }
3426
3427   /* Some normal-ish strings */
3428   DFS("2 January, 1970"); EXPECT_DBL(25570.0);
3429   DFS("2 January 1970");  EXPECT_DBL(25570.0);
3430   DFS("2 Jan 1970");      EXPECT_DBL(25570.0);
3431   DFS("2/Jan/1970");      EXPECT_DBL(25570.0);
3432   DFS("2-Jan-1970");      EXPECT_DBL(25570.0);
3433   DFS("1 2 1970");        EXPECT_DBL(25570.0);
3434   DFS("1/2/1970");        EXPECT_DBL(25570.0);
3435   DFS("1-2-1970");        EXPECT_DBL(25570.0);
3436   /* Native fails "1999 January 3, 9AM". I consider that a bug in native */
3437
3438   /* test a non-english data string */
3439   DFS("02.01.1970"); EXPECT_MISMATCH;
3440   DFS("02.01.1970 00:00:00"); EXPECT_MISMATCH;
3441   lcid = MAKELCID(MAKELANGID(LANG_GERMAN,SUBLANG_GERMAN),SORT_DEFAULT);
3442   DFS("02.01.1970"); EXPECT_DBL(25570.0);
3443   DFS("02.01.1970 00:00:00"); EXPECT_DBL(25570.0);
3444   lcid = MAKELCID(MAKELANGID(LANG_SPANISH,SUBLANG_SPANISH),SORT_DEFAULT);
3445   DFS("02.01.1970"); EXPECT_MISMATCH;
3446   DFS("02.01.1970 00:00:00"); EXPECT_MISMATCH;
3447 }
3448
3449 static void test_VarDateCopy(void)
3450 {
3451   COPYTEST(77665544.0, VT_DATE, V_DATE(&vSrc), V_DATE(&vDst), V_DATEREF(&vSrc),
3452            V_DATEREF(&vDst), "%16.16g");
3453 }
3454
3455 static const char* wtoascii(LPWSTR lpszIn)
3456 {
3457     static char buff[256];
3458     WideCharToMultiByte(CP_ACP, 0, lpszIn, -1, buff, sizeof(buff), NULL, NULL);
3459     return buff;
3460 }
3461
3462 static void test_VarDateChangeTypeEx(void)
3463 {
3464   static const WCHAR sz25570[] = {
3465     '1','/','2','/','1','9','7','0','\0' };
3466   static const WCHAR sz25570_2[] = {
3467           '1','/','2','/','7','0','\0' };
3468   static const WCHAR sz25570Nls[] = {
3469     '1','/','2','/','1','9','7','0',' ','1','2',':','0','0',':','0','0',' ','A','M','\0' };
3470   CONVVARS(CONV_TYPE);
3471   VARIANTARG vSrc, vDst;
3472   LCID lcid;
3473
3474   in = 1.0;
3475
3476 #ifdef HAS_UINT64_TO_FLOAT
3477   INITIAL_TYPETEST(VT_DATE, V_DATE, "%g");
3478   COMMON_TYPETEST;
3479 #endif
3480
3481   V_VT(&vDst) = VT_EMPTY;
3482   V_VT(&vSrc) = VT_DATE;
3483   V_DATE(&vSrc) = 25570.0;
3484   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3485
3486   hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, VARIANT_NOUSEROVERRIDE, VT_BSTR); 
3487   ok(hres == S_OK && V_VT(&vDst) == VT_BSTR && V_BSTR(&vDst) &&
3488           (!lstrcmpW(V_BSTR(&vDst), sz25570) || !lstrcmpW(V_BSTR(&vDst), sz25570_2)),
3489           "hres=0x%X, type=%d (should be VT_BSTR), *bstr=%s\n", 
3490           hres, V_VT(&vDst), V_BSTR(&vDst) ? wtoascii(V_BSTR(&vDst)) : "?");
3491   VariantClear(&vDst);
3492
3493   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3494   if (HAVE_OLEAUT32_LOCALES)
3495   {
3496     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, VARIANT_NOUSEROVERRIDE|VARIANT_USE_NLS, VT_BSTR);
3497     ok(hres == S_OK && V_VT(&vDst) == VT_BSTR && V_BSTR(&vDst) && !lstrcmpW(V_BSTR(&vDst), sz25570Nls), 
3498             "hres=0x%X, type=%d (should be VT_BSTR), *bstr=%s\n", 
3499             hres, V_VT(&vDst), V_BSTR(&vDst) ? wtoascii(V_BSTR(&vDst)) : "?");
3500     VariantClear(&vDst);
3501   }
3502 }
3503
3504 /*
3505  * VT_CY
3506  */
3507
3508 #undef CONV_TYPE
3509 #define CONV_TYPE CY
3510 #undef EXPECTRES
3511 #define EXPECTRES(res, x) \
3512   ok(hres == S_OK || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
3513      "expected hres " #x ", got hres=0x%08x\n", hres)
3514
3515 #define EXPECTCY(x) \
3516   ok((hres == S_OK && out.int64 == (LONGLONG)(x*CY_MULTIPLIER)), \
3517      "expected " #x "*CY_MULTIPLIER, got (%8x %8x); hres=0x%08x\n", S(out).Hi, S(out).Lo, hres)
3518
3519 #define EXPECTCY64(x,y) \
3520   ok(hres == S_OK && S(out).Hi == (LONG)x && S(out).Lo == y, \
3521      "expected " #x " " #y " (%u,%u), got (%u,%u); hres=0x%08x\n", \
3522       (ULONG)(x), (ULONG)(y), S(out).Hi, S(out).Lo, hres)
3523
3524 static void test_VarCyFromI1(void)
3525 {
3526   CONVVARS(signed char);
3527   int i;
3528
3529   CHECKPTR(VarCyFromI1);
3530   for (i = -128; i < 128; i++)
3531   {
3532     CONVERT(VarCyFromI1,i); EXPECTCY(i);
3533   }
3534 }
3535
3536 static void test_VarCyFromUI1(void)
3537 {
3538   CONVVARS(BYTE);
3539   int i;
3540
3541   CHECKPTR(VarCyFromUI1);
3542   for (i = 0; i < 256; i++)
3543   {
3544     CONVERT(VarCyFromUI1,i); EXPECTCY(i);
3545   }
3546 }
3547
3548 static void test_VarCyFromI2(void)
3549 {
3550   CONVVARS(SHORT);
3551   int i;
3552
3553   CHECKPTR(VarCyFromI2);
3554   for (i = -16384; i < 16384; i++)
3555   {
3556     CONVERT(VarCyFromI2,i); EXPECTCY(i);
3557   }
3558 }
3559
3560 static void test_VarCyFromUI2(void)
3561 {
3562   CONVVARS(int);
3563   int i;
3564
3565   CHECKPTR(VarCyFromUI2);
3566   for (i = 0; i < 32768; i++)
3567   {
3568     CONVERT(VarCyFromUI2,i); EXPECTCY(i);
3569   }
3570 }
3571
3572 static void test_VarCyFromI4(void)
3573 {
3574   CONVVARS(int);
3575
3576   CHECKPTR(VarCyFromI4);
3577   CONVERT(VarCyFromI4, -1);         EXPECTCY(-1);
3578   CONVERT(VarCyFromI4, 0);          EXPECTCY(0);
3579   CONVERT(VarCyFromI4, 1);          EXPECTCY(1);
3580   CONVERT(VarCyFromI4, 0x7fffffff); EXPECTCY64(0x1387, 0xffffd8f0);
3581   CONVERT(VarCyFromI4, 0x80000000); EXPECTCY64(0xffffec78, 0);
3582 }
3583
3584 static void test_VarCyFromUI4(void)
3585 {
3586   CONVVARS(unsigned int);
3587
3588   CHECKPTR(VarCyFromUI4);
3589   CONVERT(VarCyFromUI4, 0); EXPECTCY(0);
3590   CONVERT(VarCyFromUI4, 1); EXPECTCY(1);
3591   CONVERT(VarCyFromUI4, 0x80000000); EXPECTCY64(5000, 0);
3592 }
3593
3594 static void test_VarCyFromR4(void)
3595 {
3596   CONVVARS(FLOAT);
3597
3598   CHECKPTR(VarCyFromR4);
3599   CONVERT(VarCyFromR4, -1.0f); EXPECTCY(-1);
3600   CONVERT(VarCyFromR4, 0.0f);  EXPECTCY(0);
3601   CONVERT(VarCyFromR4, 1.0f);  EXPECTCY(1);
3602   CONVERT(VarCyFromR4, 1.5f);  EXPECTCY(1.5);
3603
3604   CONVERT(VarCyFromR4, -1.5f);     EXPECTCY(-1.5);
3605   CONVERT(VarCyFromR4, -0.6f);     EXPECTCY(-0.6);
3606   CONVERT(VarCyFromR4, -0.5f);     EXPECTCY(-0.5);
3607   CONVERT(VarCyFromR4, -0.4f);     EXPECTCY(-0.4);
3608   CONVERT(VarCyFromR4, 0.4f);      EXPECTCY(0.4);
3609   CONVERT(VarCyFromR4, 0.5f);      EXPECTCY(0.5);
3610   CONVERT(VarCyFromR4, 0.6f);      EXPECTCY(0.6);
3611   CONVERT(VarCyFromR4, 1.5f);      EXPECTCY(1.5);
3612   CONVERT(VarCyFromR4, 1.00009f);  EXPECTCY(1.0001);
3613   CONVERT(VarCyFromR4, -1.00001f); EXPECTCY(-1);
3614   CONVERT(VarCyFromR4, -1.00005f); EXPECTCY(-1);
3615   CONVERT(VarCyFromR4, -0.00009f); EXPECTCY(-0.0001);
3616   CONVERT(VarCyFromR4, -0.00005f); EXPECTCY(0);
3617   CONVERT(VarCyFromR4, -0.00001f); EXPECTCY(0);
3618   CONVERT(VarCyFromR4, 0.00001f);  EXPECTCY(0);
3619   CONVERT(VarCyFromR4, 0.00005f);  EXPECTCY(0);
3620   CONVERT(VarCyFromR4, 0.00009f);  EXPECTCY(0.0001);
3621   CONVERT(VarCyFromR4, -1.00001f); EXPECTCY(-1);
3622   CONVERT(VarCyFromR4, -1.00005f); EXPECTCY(-1);
3623   CONVERT(VarCyFromR4, -1.00009f); EXPECTCY(-1.0001);
3624 }
3625
3626 static void test_VarCyFromR8(void)
3627 {
3628   CONVVARS(DOUBLE);
3629
3630   CHECKPTR(VarCyFromR8);
3631
3632 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
3633   /* Test our rounding is exactly the same. This fails if the special x86
3634    * code is taken out of VarCyFromR8.
3635    */
3636   CONVERT(VarCyFromR8, -461168601842738.7904); EXPECTCY64(0xbfffffff, 0xffffff23);
3637 #endif
3638
3639   CONVERT(VarCyFromR8, -4611686018427388416.1); EXPECT_OVERFLOW;
3640   CONVERT(VarCyFromR8, -1.0);                   EXPECTCY(-1);
3641   CONVERT(VarCyFromR8, -0.0);                   EXPECTCY(0);
3642   CONVERT(VarCyFromR8, 1.0);                    EXPECTCY(1);
3643   CONVERT(VarCyFromR8, 4611686018427387648.0);  EXPECT_OVERFLOW;
3644
3645   /* Rounding */
3646   CONVERT(VarCyFromR8, -1.5f);     EXPECTCY(-1.5);
3647   CONVERT(VarCyFromR8, -0.6f);     EXPECTCY(-0.6);
3648   CONVERT(VarCyFromR8, -0.5f);     EXPECTCY(-0.5);
3649   CONVERT(VarCyFromR8, -0.4f);     EXPECTCY(-0.4);
3650   CONVERT(VarCyFromR8, 0.4f);      EXPECTCY(0.4);
3651   CONVERT(VarCyFromR8, 0.5f);      EXPECTCY(0.5);
3652   CONVERT(VarCyFromR8, 0.6f);      EXPECTCY(0.6);
3653   CONVERT(VarCyFromR8, 1.5f);      EXPECTCY(1.5);
3654   CONVERT(VarCyFromR8, 1.00009f);  EXPECTCY(1.0001);
3655   CONVERT(VarCyFromR8, -1.00001f); EXPECTCY(-1);
3656   CONVERT(VarCyFromR8, -1.00005f); EXPECTCY(-1);
3657   CONVERT(VarCyFromR8, -0.00009f); EXPECTCY(-0.0001);
3658   CONVERT(VarCyFromR8, -0.00005f); EXPECTCY(0);
3659   CONVERT(VarCyFromR8, -0.00001f); EXPECTCY(0);
3660   CONVERT(VarCyFromR8, 0.00001f);  EXPECTCY(0);
3661   CONVERT(VarCyFromR8, 0.00005f);  EXPECTCY(0);
3662   CONVERT(VarCyFromR8, 0.00009f);  EXPECTCY(0.0001);
3663   CONVERT(VarCyFromR8, -1.00001f); EXPECTCY(-1);
3664   CONVERT(VarCyFromR8, -1.00005f); EXPECTCY(-1);
3665   CONVERT(VarCyFromR8, -1.00009f); EXPECTCY(-1.0001);
3666 }
3667
3668 static void test_VarCyFromBool(void)
3669 {
3670   CONVVARS(VARIANT_BOOL);
3671   int i;
3672
3673   CHECKPTR(VarCyFromBool);
3674   for (i = -32768; i < 32768; i++)
3675   {
3676     CONVERT(VarCyFromBool, i);  EXPECTCY(i);
3677   }
3678 }
3679
3680 static void test_VarCyFromI8(void)
3681 {
3682   CONVVARS(LONG64);
3683
3684   CHECKPTR(VarCyFromI8);
3685   CONVERT_I8(VarCyFromI8, -214749, 2728163227ul);   EXPECT_OVERFLOW;
3686   CONVERT_I8(VarCyFromI8, -214749, 2728163228ul);   EXPECTCY64(2147483648ul,15808);
3687   CONVERT(VarCyFromI8, -1); EXPECTCY(-1);
3688   CONVERT(VarCyFromI8, 0);  EXPECTCY(0);
3689   CONVERT(VarCyFromI8, 1);  EXPECTCY(1);
3690   CONVERT_I8(VarCyFromI8, 214748, 1566804068); EXPECTCY64(2147483647ul, 4294951488ul);
3691   CONVERT_I8(VarCyFromI8, 214748, 1566804069); EXPECT_OVERFLOW;
3692 }
3693
3694 static void test_VarCyFromUI8(void)
3695 {
3696   CONVVARS(ULONG64);
3697
3698   CHECKPTR(VarCyFromUI8);
3699   CONVERT(VarCyFromUI8, 0); EXPECTCY(0);
3700   CONVERT(VarCyFromUI8, 1); EXPECTCY(1);
3701   CONVERT_I8(VarCyFromUI8, 214748, 1566804068); EXPECTCY64(2147483647ul, 4294951488ul);
3702   CONVERT_I8(VarCyFromUI8, 214748, 1566804069); EXPECT_OVERFLOW;
3703 }
3704
3705 static void test_VarCyFromDec(void)
3706 {
3707   CONVVARS(DECIMAL);
3708
3709   CHECKPTR(VarCyFromDec);
3710
3711   CONVERT_BADDEC(VarCyFromDec);
3712
3713   CONVERT_DEC(VarCyFromDec,0,0x80,0,1); EXPECTCY(-1);
3714   CONVERT_DEC(VarCyFromDec,0,0,0,0);    EXPECTCY(0);
3715   CONVERT_DEC(VarCyFromDec,0,0,0,1);    EXPECTCY(1);
3716
3717   CONVERT_DEC64(VarCyFromDec,0,0,0,214748, 1566804068); EXPECTCY64(2147483647ul, 4294951488ul);
3718   CONVERT_DEC64(VarCyFromDec,0,0,0,214748, 1566804069); EXPECT_OVERFLOW;
3719
3720   CONVERT_DEC(VarCyFromDec,2,0,0,100);     EXPECTCY(1);
3721   CONVERT_DEC(VarCyFromDec,2,0x80,0,100);  EXPECTCY(-1);
3722   CONVERT_DEC(VarCyFromDec,2,0x80,0,1);    EXPECTCY(-0.01);
3723   CONVERT_DEC(VarCyFromDec,2,0,0,1);       EXPECTCY(0.01);
3724   CONVERT_DEC(VarCyFromDec,2,0x80,0,1);    EXPECTCY(-0.01);
3725   CONVERT_DEC(VarCyFromDec,2,0,0,999);     EXPECTCY(9.99);
3726   CONVERT_DEC(VarCyFromDec,2,0x80,0,999);  EXPECTCY(-9.99);
3727   CONVERT_DEC(VarCyFromDec,2,0,0,1500);    EXPECTCY(15);
3728   CONVERT_DEC(VarCyFromDec,2,0x80,0,1500); EXPECTCY(-15);
3729 }
3730
3731 static void test_VarCyFromDate(void)
3732 {
3733   CONVVARS(DATE);
3734
3735   CHECKPTR(VarCyFromDate);
3736
3737 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
3738   CONVERT(VarCyFromR8, -461168601842738.7904); EXPECTCY64(0xbfffffff, 0xffffff23);
3739 #endif
3740
3741   CONVERT(VarCyFromDate, -1.0); EXPECTCY(-1);
3742   CONVERT(VarCyFromDate, -0.0); EXPECTCY(0);
3743   CONVERT(VarCyFromDate, 1.0);  EXPECTCY(1);
3744   CONVERT(VarCyFromDate, -4611686018427388416.1); EXPECT_OVERFLOW;
3745   CONVERT(VarCyFromDate, 4611686018427387648.0);  EXPECT_OVERFLOW;
3746
3747   /* Rounding */
3748   CONVERT(VarCyFromDate, -1.5f);     EXPECTCY(-1.5);
3749   CONVERT(VarCyFromDate, -0.6f);     EXPECTCY(-0.6);
3750   CONVERT(VarCyFromDate, -0.5f);     EXPECTCY(-0.5);
3751   CONVERT(VarCyFromDate, -0.4f);     EXPECTCY(-0.4);
3752   CONVERT(VarCyFromDate, 0.4f);      EXPECTCY(0.4);
3753   CONVERT(VarCyFromDate, 0.5f);      EXPECTCY(0.5);
3754   CONVERT(VarCyFromDate, 0.6f);      EXPECTCY(0.6);
3755   CONVERT(VarCyFromDate, 1.5f);      EXPECTCY(1.5);
3756   CONVERT(VarCyFromDate, 1.00009f);  EXPECTCY(1.0001);
3757   CONVERT(VarCyFromDate, -1.00001f); EXPECTCY(-1);
3758   CONVERT(VarCyFromDate, -1.00005f); EXPECTCY(-1);
3759   CONVERT(VarCyFromDate, -0.00009f); EXPECTCY(-0.0001);
3760   CONVERT(VarCyFromDate, -0.00005f); EXPECTCY(0);
3761   CONVERT(VarCyFromDate, -0.00001f); EXPECTCY(0);
3762   CONVERT(VarCyFromDate, 0.00001f);  EXPECTCY(0);
3763   CONVERT(VarCyFromDate, 0.00005f);  EXPECTCY(0);
3764   CONVERT(VarCyFromDate, 0.00009f);  EXPECTCY(0.0001);
3765   CONVERT(VarCyFromDate, -1.00001f); EXPECTCY(-1);
3766   CONVERT(VarCyFromDate, -1.00005f); EXPECTCY(-1);
3767   CONVERT(VarCyFromDate, -1.00009f); EXPECTCY(-1.0001);
3768 }
3769
3770 #define MATHVARS1 HRESULT hres; double left = 0.0; CY cyLeft, out
3771 #define MATHVARS2 MATHVARS1; double right = 0.0; CY cyRight
3772 #define MATH1(func, l) left = (double)l; pVarCyFromR8(left, &cyLeft); hres = p##func(cyLeft, &out)
3773 #define MATH2(func, l, r) left = (double)l; right = (double)r; \
3774   pVarCyFromR8(left, &cyLeft); pVarCyFromR8(right, &cyRight); \
3775   hres = p##func(cyLeft, cyRight, &out)
3776
3777 static void test_VarCyAdd(void)
3778 {
3779   MATHVARS2;
3780
3781   CHECKPTR(VarCyAdd);
3782   MATH2(VarCyAdd, 0.5, 0.5);   EXPECTCY(1);
3783   MATH2(VarCyAdd, 0.5, -0.4);  EXPECTCY(0.1);
3784   MATH2(VarCyAdd, 0.5, -0.6);  EXPECTCY(-0.1);
3785   MATH2(VarCyAdd, -0.5, -0.5); EXPECTCY(-1);
3786   MATH2(VarCyAdd, -922337203685476.0, -922337203685476.0); EXPECT_OVERFLOW;
3787   MATH2(VarCyAdd, -922337203685476.0, 922337203685476.0);  EXPECTCY(0);
3788   MATH2(VarCyAdd, 922337203685476.0, -922337203685476.0);  EXPECTCY(0);
3789   MATH2(VarCyAdd, 922337203685476.0, 922337203685476.0);   EXPECT_OVERFLOW;
3790 }
3791
3792 static void test_VarCyMul(void)
3793 {
3794   MATHVARS2;
3795
3796   CHECKPTR(VarCyMul);
3797   MATH2(VarCyMul, 534443.0, 0.0); EXPECTCY(0);
3798   MATH2(VarCyMul, 0.5, 0.5);      EXPECTCY(0.25);
3799   MATH2(VarCyMul, 0.5, -0.4);     EXPECTCY(-0.2);
3800   MATH2(VarCyMul, 0.5, -0.6);     EXPECTCY(-0.3);
3801   MATH2(VarCyMul, -0.5, -0.5);    EXPECTCY(0.25);
3802   MATH2(VarCyMul, 922337203685476.0, 20000); EXPECT_OVERFLOW;
3803 }
3804
3805 static void test_VarCySub(void)
3806 {
3807   MATHVARS2;
3808
3809   CHECKPTR(VarCySub);
3810   MATH2(VarCySub, 0.5, 0.5);   EXPECTCY(0);
3811   MATH2(VarCySub, 0.5, -0.4);  EXPECTCY(0.9);
3812   MATH2(VarCySub, 0.5, -0.6);  EXPECTCY(1.1);
3813   MATH2(VarCySub, -0.5, -0.5); EXPECTCY(0);
3814   MATH2(VarCySub, -922337203685476.0, -922337203685476.0); EXPECTCY(0);
3815   MATH2(VarCySub, -922337203685476.0, 922337203685476.0);  EXPECT_OVERFLOW;
3816   MATH2(VarCySub, 922337203685476.0, -922337203685476.0);  EXPECT_OVERFLOW;
3817   MATH2(VarCySub, 922337203685476.0, 922337203685476.0);   EXPECTCY(0);
3818 }
3819
3820 static void test_VarCyAbs(void)
3821 {
3822   MATHVARS1;
3823
3824   CHECKPTR(VarCyAbs);
3825   MATH1(VarCyAbs, 0.5);  EXPECTCY(0.5);
3826   MATH1(VarCyAbs, -0.5); EXPECTCY(0.5);
3827   MATH1(VarCyAbs, 922337203685476.0);  EXPECTCY64(2147483647ul,4294951488ul);
3828   MATH1(VarCyAbs, -922337203685476.0); EXPECTCY64(2147483647ul,4294951488ul);
3829 }
3830
3831 static void test_VarCyNeg(void)
3832 {
3833   MATHVARS1;
3834
3835   CHECKPTR(VarCyNeg);
3836   MATH1(VarCyNeg, 0.5); EXPECTCY(-0.5);
3837   MATH1(VarCyNeg, -0.5); EXPECTCY(0.5);
3838   MATH1(VarCyNeg, 922337203685476.0);  EXPECTCY64(2147483648ul,15808);
3839   MATH1(VarCyNeg, -922337203685476.0); EXPECTCY64(2147483647ul,4294951488ul);
3840 }
3841
3842 #define MATHMULI4(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
3843   hres = pVarCyMulI4(cyLeft, right, &out)
3844
3845 static void test_VarCyMulI4(void)
3846 {
3847   MATHVARS1;
3848   LONG right;
3849
3850   CHECKPTR(VarCyMulI4);
3851   MATHMULI4(534443.0, 0); EXPECTCY(0);
3852   MATHMULI4(0.5, 1);      EXPECTCY(0.5);
3853   MATHMULI4(0.5, 2);      EXPECTCY(1);
3854   MATHMULI4(922337203685476.0, 1); EXPECTCY64(2147483647ul,4294951488ul);
3855   MATHMULI4(922337203685476.0, 2); EXPECT_OVERFLOW;
3856 }
3857
3858 #define MATHMULI8(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
3859   hres = pVarCyMulI8(cyLeft, right, &out)
3860
3861 static void test_VarCyMulI8(void)
3862 {
3863   MATHVARS1;
3864   LONG64 right;
3865
3866   CHECKPTR(VarCyMulI8);
3867   MATHMULI8(534443.0, 0); EXPECTCY(0);
3868   MATHMULI8(0.5, 1);      EXPECTCY(0.5);
3869   MATHMULI8(0.5, 2);      EXPECTCY(1);
3870   MATHMULI8(922337203685476.0, 1); EXPECTCY64(2147483647ul,4294951488ul);
3871   MATHMULI8(922337203685476.0, 2); EXPECT_OVERFLOW;
3872 }
3873
3874 #define MATHCMP(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); pVarCyFromR8(right, &cyRight); \
3875   hres = pVarCyCmp(cyLeft, cyRight); out.int64 = hres
3876
3877 static void test_VarCyCmp(void)
3878 {
3879   MATHVARS2;
3880
3881   CHECKPTR(VarCyCmp);
3882   MATHCMP(-1.0, -1.0); EXPECT_EQ;
3883   MATHCMP(-1.0, 0.0);  EXPECT_LT;
3884   MATHCMP(-1.0, 1.0);  EXPECT_LT;
3885   MATHCMP(-1.0, 2.0);  EXPECT_LT;
3886   MATHCMP(0.0, 1.0);   EXPECT_LT;
3887   MATHCMP(0.0, 0.0);   EXPECT_EQ;
3888   MATHCMP(0.0, -1.0);  EXPECT_GT;
3889   MATHCMP(1.0, -1.0);  EXPECT_GT;
3890   MATHCMP(1.0, 0.0);   EXPECT_GT;
3891   MATHCMP(1.0, 1.0);   EXPECT_EQ;
3892   MATHCMP(1.0, 2.0);   EXPECT_LT;
3893 }
3894
3895 #define MATHCMPR8(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
3896   hres = pVarCyCmpR8(cyLeft, right); out.int64 = hres
3897
3898 static void test_VarCyCmpR8(void)
3899 {
3900   MATHVARS1;
3901   double right;
3902
3903   CHECKPTR(VarCyCmpR8);
3904   MATHCMPR8(-1.0, -1.0); EXPECT_EQ;
3905   MATHCMPR8(-1.0, 0.0);  EXPECT_LT;
3906   MATHCMPR8(-1.0, 1.0);  EXPECT_LT;
3907   MATHCMPR8(-1.0, 2.0);  EXPECT_LT;
3908   MATHCMPR8(0.0, 1.0);   EXPECT_LT;
3909   MATHCMPR8(0.0, 0.0);   EXPECT_EQ;
3910   MATHCMPR8(0.0, -1.0);  EXPECT_GT;
3911   MATHCMPR8(1.0, -1.0);  EXPECT_GT;
3912   MATHCMPR8(1.0, 0.0);   EXPECT_GT;
3913   MATHCMPR8(1.0, 1.0);   EXPECT_EQ;
3914   MATHCMPR8(1.0, 2.0);   EXPECT_LT;
3915 }
3916
3917 #undef MATHRND
3918 #define MATHRND(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
3919   hres = pVarCyRound(cyLeft, right, &out)
3920
3921 static void test_VarCyRound(void)
3922 {
3923   MATHVARS1;
3924   int right;
3925
3926   CHECKPTR(VarCyRound);
3927   MATHRND(0.5432, 5);  EXPECTCY(0.5432);
3928   MATHRND(0.5432, 4);  EXPECTCY(0.5432);
3929   MATHRND(0.5432, 3);  EXPECTCY(0.543);
3930   MATHRND(0.5432, 2);  EXPECTCY(0.54);
3931   MATHRND(0.5432, 1);  EXPECTCY(0.5);
3932   MATHRND(0.5532, 0);  EXPECTCY(1);
3933   MATHRND(0.5532, -1); EXPECT_INVALID;
3934
3935   MATHRND(0.5568, 5);  EXPECTCY(0.5568);
3936   MATHRND(0.5568, 4);  EXPECTCY(0.5568);
3937   MATHRND(0.5568, 3);  EXPECTCY(0.557);
3938   MATHRND(0.5568, 2);  EXPECTCY(0.56);
3939   MATHRND(0.5568, 1);  EXPECTCY(0.6);
3940   MATHRND(0.5568, 0);  EXPECTCY(1);
3941   MATHRND(0.5568, -1); EXPECT_INVALID;
3942
3943   MATHRND(0.4999, 0); EXPECTCY(0);
3944   MATHRND(0.5000, 0); EXPECTCY(0);
3945   MATHRND(0.5001, 0); EXPECTCY(1);
3946   MATHRND(1.4999, 0); EXPECTCY(1);
3947   MATHRND(1.5000, 0); EXPECTCY(2);
3948   MATHRND(1.5001, 0); EXPECTCY(2);
3949 }
3950
3951 #define MATHFIX(l) left = l; pVarCyFromR8(left, &cyLeft); \
3952   hres = pVarCyFix(cyLeft, &out)
3953
3954 static void test_VarCyFix(void)
3955 {
3956   MATHVARS1;
3957
3958   CHECKPTR(VarCyFix);
3959   MATHFIX(-1.0001); EXPECTCY(-1);
3960   MATHFIX(-1.4999); EXPECTCY(-1);
3961   MATHFIX(-1.5001); EXPECTCY(-1);
3962   MATHFIX(-1.9999); EXPECTCY(-1);
3963   MATHFIX(-0.0001); EXPECTCY(0);
3964   MATHFIX(-0.4999); EXPECTCY(0);
3965   MATHFIX(-0.5001); EXPECTCY(0);
3966   MATHFIX(-0.9999); EXPECTCY(0);
3967   MATHFIX(0.0001);  EXPECTCY(0);
3968   MATHFIX(0.4999);  EXPECTCY(0);
3969   MATHFIX(0.5001);  EXPECTCY(0);
3970   MATHFIX(0.9999);  EXPECTCY(0);
3971   MATHFIX(1.0001);  EXPECTCY(1);
3972   MATHFIX(1.4999);  EXPECTCY(1);
3973   MATHFIX(1.5001);  EXPECTCY(1);
3974   MATHFIX(1.9999);  EXPECTCY(1);
3975 }
3976
3977 #define MATHINT(l) left = l; pVarCyFromR8(left, &cyLeft); \
3978   hres = pVarCyInt(cyLeft, &out)
3979
3980 static void test_VarCyInt(void)
3981 {
3982   MATHVARS1;
3983
3984   CHECKPTR(VarCyInt);
3985   MATHINT(-1.0001); EXPECTCY(-2);
3986   MATHINT(-1.4999); EXPECTCY(-2);
3987   MATHINT(-1.5001); EXPECTCY(-2);
3988   MATHINT(-1.9999); EXPECTCY(-2);
3989   MATHINT(-0.0001); EXPECTCY(-1);
3990   MATHINT(-0.4999); EXPECTCY(-1);
3991   MATHINT(-0.5001); EXPECTCY(-1);
3992   MATHINT(-0.9999); EXPECTCY(-1);
3993   MATHINT(0.0001);  EXPECTCY(0);
3994   MATHINT(0.4999);  EXPECTCY(0);
3995   MATHINT(0.5001);  EXPECTCY(0);
3996   MATHINT(0.9999);  EXPECTCY(0);
3997   MATHINT(1.0001);  EXPECTCY(1);
3998   MATHINT(1.4999);  EXPECTCY(1);
3999   MATHINT(1.5001);  EXPECTCY(1);
4000   MATHINT(1.9999);  EXPECTCY(1);
4001 }
4002
4003 /*
4004  * VT_DECIMAL
4005  */
4006
4007 #undef CONV_TYPE
4008 #define CONV_TYPE DECIMAL
4009 #undef EXPECTRES
4010 #define EXPECTRES(res, x) \
4011   ok(hres == S_OK || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
4012      "expected hres " #x ", got hres=0x%08x\n", hres)
4013
4014 #define EXPECTDEC(scl, sgn, hi, lo) ok(hres == S_OK && \
4015   S(U(out)).scale == (BYTE)(scl) && S(U(out)).sign == (BYTE)(sgn) && \
4016   out.Hi32 == (ULONG)(hi) && U1(out).Lo64 == (ULONG64)(lo), \
4017   "expected (%d,%d,%d,(%x %x)), got (%d,%d,%d,(%x %x)) hres 0x%08x\n", \
4018   scl, sgn, hi, (LONG)((LONG64)(lo) >> 32), (LONG)((lo) & 0xffffffff), S(U(out)).scale, \
4019   S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres)
4020
4021 #define EXPECTDEC64(scl, sgn, hi, mid, lo) ok(hres == S_OK && \
4022   S(U(out)).scale == (BYTE)(scl) && S(U(out)).sign == (BYTE)(sgn) && \
4023   out.Hi32 == (ULONG)(hi) && S1(U1(out)).Mid32 == (ULONG)(mid) && \
4024   S1(U1(out)).Lo32 == (ULONG)(lo), \
4025   "expected (%d,%d,%d,(%x %x)), got (%d,%d,%d,(%x %x)) hres 0x%08x\n", \
4026   scl, sgn, hi, (LONG)(mid), (LONG)(lo), S(U(out)).scale, \
4027   S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres)
4028
4029 /* expect either a positive or negative zero */
4030 #define EXPECTDECZERO() ok(hres == S_OK && S(U(out)).scale == 0 && \
4031   (S(U(out)).sign == 0 || S(U(out)).sign == 0x80) && out.Hi32 == 0 && U1(out).Lo64 == 0, \
4032   "expected zero, got (%d,%d,%d,(%x %x)) hres 0x%08x\n", \
4033   S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres)
4034
4035 #define EXPECTDECI if (i < 0) EXPECTDEC(0, 0x80, 0, -i); else EXPECTDEC(0, 0, 0, i)
4036
4037 static void test_VarDecFromI1(void)
4038 {
4039   CONVVARS(signed char);
4040   int i;
4041
4042   CHECKPTR(VarDecFromI1);
4043   for (i = -128; i < 128; i++)
4044   {
4045     CONVERT(VarDecFromI1,i); EXPECTDECI;
4046   }
4047 }
4048
4049 static void test_VarDecFromI2(void)
4050 {
4051   CONVVARS(SHORT);
4052   int i;
4053
4054   CHECKPTR(VarDecFromI2);
4055   for (i = -32768; i < 32768; i++)
4056   {
4057     CONVERT(VarDecFromI2,i); EXPECTDECI;
4058   }
4059 }
4060
4061 static void test_VarDecFromI4(void)
4062 {
4063   CONVVARS(LONG);
4064   int i;
4065
4066   CHECKPTR(VarDecFromI4);
4067   for (i = -32768; i < 32768; i++)
4068   {
4069     CONVERT(VarDecFromI4,i); EXPECTDECI;
4070   }
4071 }
4072
4073 static void test_VarDecFromI8(void)
4074 {
4075   CONVVARS(LONG64);
4076   int i;
4077
4078   CHECKPTR(VarDecFromI8);
4079   for (i = -32768; i < 32768; i++)
4080   {
4081     CONVERT(VarDecFromI8,i); EXPECTDECI;
4082   }
4083 }
4084
4085 static void test_VarDecFromUI1(void)
4086 {
4087   CONVVARS(BYTE);
4088   int i;
4089
4090   CHECKPTR(VarDecFromUI1);
4091   for (i = 0; i < 256; i++)
4092   {
4093     CONVERT(VarDecFromUI1,i); EXPECTDECI;
4094   }
4095 }
4096
4097 static void test_VarDecFromUI2(void)
4098 {
4099   CONVVARS(USHORT);
4100   int i;
4101
4102   CHECKPTR(VarDecFromUI2);
4103   for (i = 0; i < 65536; i++)
4104   {
4105     CONVERT(VarDecFromUI2,i); EXPECTDECI;
4106   }
4107 }
4108
4109 static void test_VarDecFromUI4(void)
4110 {
4111   CONVVARS(ULONG);
4112   int i;
4113
4114   CHECKPTR(VarDecFromUI4);
4115   for (i = 0; i < 65536; i++)
4116   {
4117     CONVERT(VarDecFromUI4,i); EXPECTDECI;
4118   }
4119 }
4120
4121 static void test_VarDecFromUI8(void)
4122 {
4123   CONVVARS(ULONG64);
4124   int i;
4125
4126   CHECKPTR(VarDecFromUI8);
4127   for (i = 0; i < 65536; i++)
4128   {
4129     CONVERT(VarDecFromUI8,i); EXPECTDECI;
4130   }
4131 }
4132
4133 static void test_VarDecFromBool(void)
4134 {
4135   CONVVARS(SHORT);
4136   int i;
4137
4138   CHECKPTR(VarDecFromBool);
4139   /* Test all possible type values. Note that the result is reduced to 0 or -1 */
4140   for (i = -32768; i < 0; i++)
4141   {
4142     CONVERT(VarDecFromBool,i);
4143     if (i)
4144       EXPECTDEC(0,0x80,0,1);
4145     else
4146       EXPECTDEC(0,0,0,0);
4147   }
4148 }
4149
4150 static void test_VarDecFromR4(void)
4151 {
4152   CONVVARS(float);
4153
4154   CHECKPTR(VarDecFromR4);
4155
4156   CONVERT(VarDecFromR4,-0.6f); EXPECTDEC(1,0x80,0,6);
4157   CONVERT(VarDecFromR4,-0.5f); EXPECTDEC(1,0x80,0,5);
4158   CONVERT(VarDecFromR4,-0.4f); EXPECTDEC(1,0x80,0,4);
4159   CONVERT(VarDecFromR4,0.0f);  EXPECTDEC(0,0,0,0);
4160   CONVERT(VarDecFromR4,0.4f);  EXPECTDEC(1,0,0,4);
4161   CONVERT(VarDecFromR4,0.5f);  EXPECTDEC(1,0,0,5);
4162   CONVERT(VarDecFromR4,0.6f);  EXPECTDEC(1,0,0,6);
4163 }
4164
4165 static void test_VarDecFromR8(void)
4166 {
4167   CONVVARS(double);
4168
4169   CHECKPTR(VarDecFromR8);
4170
4171   CONVERT(VarDecFromR8,-0.6); EXPECTDEC(1,0x80,0,6);
4172   CONVERT(VarDecFromR8,-0.5); EXPECTDEC(1,0x80,0,5);
4173   CONVERT(VarDecFromR8,-0.4); EXPECTDEC(1,0x80,0,4);
4174   CONVERT(VarDecFromR8,0.0);  EXPECTDEC(0,0,0,0);
4175   CONVERT(VarDecFromR8,0.4);  EXPECTDEC(1,0,0,4);
4176   CONVERT(VarDecFromR8,0.5);  EXPECTDEC(1,0,0,5);
4177   CONVERT(VarDecFromR8,0.6);  EXPECTDEC(1,0,0,6);
4178 }
4179
4180 static void test_VarDecFromDate(void)
4181 {
4182   CONVVARS(DATE);
4183
4184   CHECKPTR(VarDecFromDate);
4185
4186   CONVERT(VarDecFromDate,-0.6); EXPECTDEC(1,0x80,0,6);
4187   CONVERT(VarDecFromDate,-0.5); EXPECTDEC(1,0x80,0,5);
4188   CONVERT(VarDecFromDate,-0.4); EXPECTDEC(1,0x80,0,4);
4189   CONVERT(VarDecFromDate,0.0);  EXPECTDEC(0,0,0,0);
4190   CONVERT(VarDecFromDate,0.4);  EXPECTDEC(1,0,0,4);
4191   CONVERT(VarDecFromDate,0.5);  EXPECTDEC(1,0,0,5);
4192   CONVERT(VarDecFromDate,0.6);  EXPECTDEC(1,0,0,6);
4193 }
4194
4195 static void test_VarDecFromStr(void)
4196 {
4197   CONVVARS(LCID);
4198   OLECHAR buff[128];
4199
4200   CHECKPTR(VarDecFromStr);
4201
4202   in = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4203
4204   CONVERT_STR(VarDecFromStr,NULL,0);                       EXPECT_MISMATCH;
4205   CONVERT_STR(VarDecFromStr,"-1",  LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0x80,0,1);
4206   CONVERT_STR(VarDecFromStr,"0",   LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,0,0);
4207   CONVERT_STR(VarDecFromStr,"1",   LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,0,1);
4208   CONVERT_STR(VarDecFromStr,"0.5", LOCALE_NOUSEROVERRIDE); EXPECTDEC(1,0,0,5);
4209   CONVERT_STR(VarDecFromStr,"4294967296", LOCALE_NOUSEROVERRIDE); EXPECTDEC64(0,0,0,1,0);
4210   CONVERT_STR(VarDecFromStr,"18446744073709551616", LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,1,0);
4211   CONVERT_STR(VarDecFromStr,"4294967296.0", LOCALE_NOUSEROVERRIDE); EXPECTDEC64(0,0,0,1,0);
4212   CONVERT_STR(VarDecFromStr,"18446744073709551616.0", LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,1,0);
4213 }
4214
4215 static void test_VarDecFromCy(void)
4216 {
4217   CONVVARS(CY);
4218
4219   CHECKPTR(VarDecFromCy);
4220
4221   CONVERT_CY(VarDecFromCy, -1);  EXPECTDEC(4,0x80,0,10000);
4222   CONVERT_CY(VarDecFromCy, 0);   EXPECTDEC(4,0,0,0);
4223   CONVERT_CY(VarDecFromCy, 1);   EXPECTDEC(4,0,0,10000);
4224   CONVERT_CY(VarDecFromCy, 0.5); EXPECTDEC(4,0,0,5000);
4225 }
4226
4227 #undef MATHVARS1
4228 #define MATHVARS1 HRESULT hres; DECIMAL l, out
4229 #undef MATHVARS2
4230 #define MATHVARS2 MATHVARS1; DECIMAL r
4231 #undef MATH1
4232 #define MATH1(func) hres = p##func(&l, &out)
4233 #undef MATH2
4234 #define MATH2(func) hres = p##func(&l, &r, &out)
4235
4236 static void test_VarDecAbs(void)
4237 {
4238   MATHVARS1;
4239
4240   CHECKPTR(VarDecAbs);
4241   SETDEC(l,0,0x80,0,1);  MATH1(VarDecAbs); EXPECTDEC(0,0,0,1);
4242   SETDEC(l,0,0,0,0);     MATH1(VarDecAbs); EXPECTDEC(0,0,0,0);
4243   SETDEC(l,0,0x80,0,0);  MATH1(VarDecAbs); EXPECTDEC(0,0,0,0);
4244   SETDEC(l,0,0,0,1);     MATH1(VarDecAbs); EXPECTDEC(0,0,0,1);
4245
4246   /* Doesn't check for invalid input */
4247   SETDEC(l,0,0x7f,0,1);  MATH1(VarDecAbs); EXPECTDEC(0,0x7f,0,1);
4248   SETDEC(l,0,0x80,29,1); MATH1(VarDecAbs); EXPECTDEC(0,0,29,1);
4249 }
4250
4251 static void test_VarDecNeg(void)
4252 {
4253   MATHVARS1;
4254
4255   CHECKPTR(VarDecNeg);
4256   SETDEC(l,0,0x80,0,1); MATH1(VarDecNeg); EXPECTDEC(0,0,0,1);
4257   SETDEC(l,0,0,0,0);    MATH1(VarDecNeg); EXPECTDEC(0,0x80,0,0); /* '-0'! */
4258   SETDEC(l,0,0x80,0,0); MATH1(VarDecNeg); EXPECTDEC(0,0,0,0);
4259   SETDEC(l,0,0,0,1);    MATH1(VarDecNeg); EXPECTDEC(0,0x80,0,1);
4260
4261   /* Doesn't check for invalid input */
4262   SETDEC(l,0,0x7f,0,1);  MATH1(VarDecNeg); EXPECTDEC(0,0xff,0,1);
4263   SETDEC(l,0,0x80,29,1); MATH1(VarDecNeg); EXPECTDEC(0,0,29,1);
4264   SETDEC(l,0,0,29,1);    MATH1(VarDecNeg); EXPECTDEC(0,0x80,29,1);
4265 }
4266
4267 static void test_VarDecAdd(void)
4268 {
4269   MATHVARS2;
4270
4271   CHECKPTR(VarDecAdd);
4272   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,0);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,0);
4273   SETDEC(l,0,0,0,0);    SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,1);
4274   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4275
4276   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,0);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4277   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,2);
4278   SETDEC(l,0,0,0,1);    SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDECZERO();
4279   SETDEC(l,0,0,0,1);    SETDEC(r,0,0x80,0,2); MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,1);
4280
4281   SETDEC(l,0,0x80,0,0); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4282   SETDEC(l,0,0x80,0,1); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDECZERO();
4283   SETDEC(l,0,0x80,0,1); SETDEC(r,0,0,0,2);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4284   SETDEC(l,0,0x80,0,1); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,2);
4285   SETDEC(l,0,0x80,0,2); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,1);
4286
4287   SETDEC(l,0,0,0,0xffffffff); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0,0,0xfffffffe);
4288   SETDEC(l,0,0,0,0xffffffff); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,(ULONG64)1 << 32);
4289   SETDEC(l,0,0,0,0xffffffff); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0,(ULONG64)1 << 32);
4290
4291   SETDEC64(l,0,0,0,0xffffffff,0); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC64(0,0,0,0xffffffff,1);
4292   SETDEC64(l,0,0,0,0xffffffff,0); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4293   EXPECTDEC64(0,0,0,0xfffffffe,0xffffffff);
4294
4295   SETDEC64(l,0,0,0,0xffffffff,0xffffffff); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,1,0);
4296   SETDEC64(l,0,0,0,0xffffffff,0xffffffff); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4297   EXPECTDEC64(0,0,0,0xffffffff,0xfffffffe);
4298
4299   SETDEC(l,0,0,0xffffffff,0); SETDEC(r,0,0,0,1);    MATH2(VarDecAdd); EXPECTDEC(0,0,0xffffffff,1);
4300   SETDEC(l,0,0,0xffffffff,0); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4301   EXPECTDEC64(0,0,0xfffffffe,0xffffffff,0xffffffff);
4302
4303   SETDEC64(l,0,0,0xffffffff,0xffffffff,0xffffffff);SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4304   EXPECTDEC64(0,0,0xffffffff,0xffffffff,0xfffffffe);
4305   SETDEC64(l,0,0,0xffffffff,0xffffffff,0xffffffff);SETDEC(r,0,0,0,1); MATH2(VarDecAdd);
4306   ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4307      S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4308
4309   /* Promotes to the highest scale, so here the results are in the scale of 2 */
4310   SETDEC(l,2,0,0,0);   SETDEC(r,0,0,0,0); MATH2(VarDecAdd); EXPECTDEC(2,0,0,0);
4311   SETDEC(l,2,0,0,100); SETDEC(r,0,0,0,1); MATH2(VarDecAdd); EXPECTDEC(2,0,0,200);
4312 }
4313
4314 static void test_VarDecSub(void)
4315 {
4316   MATHVARS2;
4317
4318   CHECKPTR(VarDecSub);
4319   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,0);    MATH2(VarDecSub); EXPECTDECZERO();
4320   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,1);    MATH2(VarDecSub); EXPECTDEC(0,0x80,0,1);
4321   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,1);    MATH2(VarDecSub); EXPECTDECZERO();
4322   SETDEC(l,0,0,0,1);    SETDEC(r,0,0x80,0,1); MATH2(VarDecSub); EXPECTDEC(0,0,0,2);
4323 }
4324
4325 static void test_VarDecMul(void)
4326 {
4327   MATHVARS2;
4328   
4329   CHECKPTR(VarDecMul);
4330   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,0);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,0);
4331   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,0);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,0);
4332   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,1);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,0);
4333   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,1);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,1);
4334   SETDEC(l,0,0,0,45000);SETDEC(r,0,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,90000);
4335   SETDEC(l,0,0,0,2);    SETDEC(r,0,0,0,45000);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,90000);
4336
4337   SETDEC(l,0,0x80,0,2); SETDEC(r,0,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(0,0x80,0,4);
4338   SETDEC(l,0,0,0,2);    SETDEC(r,0,0x80,0,2);  MATH2(VarDecMul);   EXPECTDEC(0,0x80,0,4);
4339   SETDEC(l,0,0x80,0,2); SETDEC(r,0,0x80,0,2);  MATH2(VarDecMul);   EXPECTDEC(0,0,0,4);
4340
4341   SETDEC(l,4,0,0,2);    SETDEC(r,0,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(4,0,0,4);
4342   SETDEC(l,0,0,0,2);    SETDEC(r,3,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(3,0,0,4);
4343   SETDEC(l,4,0,0,2);    SETDEC(r,3,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(7,0,0,4);
4344   /* this last one shows that native oleaut32 does *not* gratuitously seize opportunities
4345      to reduce the scale if possible - the canonical result for the expected value is (6,0,0,1)
4346    */
4347   SETDEC(l,4,0,0,5);    SETDEC(r,3,0,0,2);  MATH2(VarDecMul);   EXPECTDEC(7,0,0,10);
4348   
4349   SETDEC64(l,0,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC(r,0,0,0,2);  MATH2(VarDecMul);   EXPECTDEC64(0,0,1,0xFFFFFFFF,0xFFFFFFFE);
4350   SETDEC(l,0,0,0,2);    SETDEC64(r,0,0,0,0xFFFFFFFF,0xFFFFFFFF);  MATH2(VarDecMul);   EXPECTDEC64(0,0,1,0xFFFFFFFF,0xFFFFFFFE);
4351   SETDEC(l,0,0,1,1);    SETDEC(r,0,0,0,0x80000000);  MATH2(VarDecMul);   EXPECTDEC(0,0,0x80000000,0x80000000);
4352   SETDEC(l,0,0,0,0x80000000);    SETDEC(r,0,0,1,1);  MATH2(VarDecMul);   EXPECTDEC(0,0,0x80000000,0x80000000);
4353   
4354   /* near-overflow, used as a reference */
4355   SETDEC64(l,0,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC(r,0,0,0,2000000000);  MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4356   /* actual overflow - right operand is 10 times the previous value */
4357   SETDEC64(l,0,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC64(r,0,0,0,4,0xA817C800);  MATH2(VarDecMul);
4358   ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4359      S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4360   /* here, native oleaut32 has an opportunity to avert the overflow, by reducing the scale of the result  */
4361   SETDEC64(l,1,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC64(r,0,0,0,4,0xA817C800);  MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4362
4363   /* near-overflow, used as a reference */
4364   SETDEC64(l,0,0,1,0xFFFFFFFF,0xFFFFFFFE);    SETDEC(r,0,0,0,1000000000);  MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4365   /* actual overflow - right operand is 10 times the previous value */
4366   SETDEC64(l,0,0,1,0xFFFFFFFF,0xFFFFFFFE);    SETDEC64(r,0,0,0,2,0x540BE400);  MATH2(VarDecMul);
4367   ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4368      S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4369   /* here, native oleaut32 has an opportunity to avert the overflow, by reducing the scale of the result  */
4370   SETDEC64(l,1,0,1,0xFFFFFFFF,0xFFFFFFFE);    SETDEC64(r,0,0,0,2,0x540BE400);  MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4371   
4372   /* this one shows that native oleaut32 is willing to lose significant digits in order to avert an overflow */
4373   SETDEC64(l,2,0,0,0xFFFFFFFF,0xFFFFFFFF);    SETDEC64(r,0,0,0,9,0x502F9001);  MATH2(VarDecMul);EXPECTDEC64(1,0,0xee6b2800,0x19999998,0xab2e719a);
4374 }
4375
4376 static void test_VarDecDiv(void)
4377 {
4378   MATHVARS2;
4379   
4380   CHECKPTR(VarDecDiv);
4381   /* identity divisions */
4382   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,1);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,0);
4383   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,1);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,1);
4384   SETDEC(l,1,0,0,1);    SETDEC(r,0,0,0,1);  MATH2(VarDecDiv);   EXPECTDEC(1,0,0,1);
4385
4386   /* exact divisions */  
4387   SETDEC(l,0,0,0,45);    SETDEC(r,0,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,5);
4388   SETDEC(l,1,0,0,45);    SETDEC(r,0,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(1,0,0,5);
4389   SETDEC(l,0,0,0,45);    SETDEC(r,1,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,50);
4390   SETDEC(l,1,0,0,45);    SETDEC(r,2,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,50);
4391   /* these last three results suggest that native oleaut32 scales both operands down to zero
4392      before the division, but does not always try to scale the result, even if it is possible -
4393      analogous to multiplication behavior.
4394    */
4395   SETDEC(l,1,0,0,45);    SETDEC(r,1,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0,0,5);
4396   SETDEC(l,2,0,0,450);    SETDEC(r,1,0,0,9);  MATH2(VarDecDiv);
4397   if (S(U(out)).scale == 1) EXPECTDEC(1,0,0,50);
4398   else EXPECTDEC(0,0,0,5);
4399
4400   /* inexact divisions */
4401   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,180700362,0x14b700cb,0x05555555);
4402   SETDEC(l,1,0,0,1);    SETDEC(r,0,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,18070036,0x35458014,0x4d555555);
4403   SETDEC(l,0,0,0,1);    SETDEC(r,1,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,1807003620,0xcf2607ee,0x35555555);
4404   SETDEC(l,1,0,0,1);    SETDEC(r,2,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,1807003620,0xcf2607ee,0x35555555);
4405   SETDEC(l,1,0,0,1);    SETDEC(r,1,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,180700362,0x14b700cb,0x05555555);
4406   SETDEC(l,2,0,0,10);    SETDEC(r,1,0,0,3);  MATH2(VarDecDiv);  EXPECTDEC64(28,0,180700362,0x14b700cb,0x05555555);
4407
4408   /* this one shows that native oleaut32 rounds up the result */
4409   SETDEC(l,0,0,0,2);    SETDEC(r,0,0,0,3);  MATH2(VarDecDiv);   EXPECTDEC64(28,0,361400724,0x296e0196,0x0aaaaaab);
4410   
4411   /* sign tests */
4412   SETDEC(l,0,0x80,0,45);    SETDEC(r,0,0,0,9);  MATH2(VarDecDiv);   EXPECTDEC(0,0x80,0,5);
4413   SETDEC(l,0,0,0,45);       SETDEC(r,0,0x80,0,9);  MATH2(VarDecDiv);EXPECTDEC(0,0x80,0,5);
4414   SETDEC(l,0,0x80,0,45);    SETDEC(r,0,0x80,0,9);  MATH2(VarDecDiv);EXPECTDEC(0,0,0,5);
4415   
4416   /* oddballs */
4417   SETDEC(l,0,0,0,0);    SETDEC(r,0,0,0,0);  MATH2(VarDecDiv);/* indeterminate */
4418   ok(hres == DISP_E_DIVBYZERO,"Expected division-by-zero, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4419      S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4420   SETDEC(l,0,0,0,1);    SETDEC(r,0,0,0,0);  MATH2(VarDecDiv);/* division by zero */
4421   ok(hres == DISP_E_DIVBYZERO,"Expected division-by-zero, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4422      S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4423   
4424 }
4425
4426 static void test_VarDecCmp(void)
4427 {
4428   MATHVARS1;
4429
4430   CHECKPTR(VarDecCmp);
4431
4432   SETDEC(l,0,0,0,1); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_EQ;
4433   SETDEC(l,0,0,0,1); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_GT;
4434   SETDEC(l,0,0,0,1); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4435
4436   SETDEC(l,0,0,0,1); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4437   SETDEC(l,0,0,0,1); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_GT;
4438   SETDEC(l,0,0,0,1); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4439
4440   SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4441   SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_LT;
4442   SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4443
4444   SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_EQ;
4445   SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_LT;
4446   SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4447
4448   SETDEC(l,0,0,0,0); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4449   SETDEC(l,0,0,0,0); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4450   SETDEC(l,0,0,0,0); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4451
4452   SETDEC(l,0,0,0,0); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4453   SETDEC(l,0,0,0,0); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4454   SETDEC(l,0,0,0,0); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4455
4456   SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4457   SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4458   SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4459
4460   SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4461   SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4462   SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4463
4464   SETDEC(l,0,0,-1,-1); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4465   SETDEC(l,0,0,-1,-1); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_GT;
4466   SETDEC(l,0,0,-1,-1); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_EQ;
4467
4468   SETDEC(l,0,0,-1,-1); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4469   SETDEC(l,0,0,-1,-1); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_GT;
4470   SETDEC(l,0,0,-1,-1); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4471
4472   SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4473   SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_LT;
4474   SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4475
4476   SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4477   SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_LT;
4478   SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_EQ;
4479
4480
4481   SETDEC(out,0,0,0,1); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_EQ;
4482   SETDEC(out,0,0,0,1); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_LT;
4483   SETDEC(out,0,0,0,1); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4484
4485   SETDEC(out,0,0,0,1); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4486   SETDEC(out,0,0,0,1); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_LT;
4487   SETDEC(out,0,0,0,1); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4488
4489   SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4490   SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_GT;
4491   SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4492
4493   SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_EQ;
4494   SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_GT;
4495   SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4496
4497   SETDEC(out,0,0,0,0); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4498   SETDEC(out,0,0,0,0); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4499   SETDEC(out,0,0,0,0); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4500
4501   SETDEC(out,0,0,0,0); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4502   SETDEC(out,0,0,0,0); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4503   SETDEC(out,0,0,0,0); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4504
4505   SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4506   SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4507   SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4508
4509   SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4510   SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4511   SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4512
4513   SETDEC(out,0,0,-1,-1); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4514   SETDEC(out,0,0,-1,-1); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_LT;
4515   SETDEC(out,0,0,-1,-1); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_EQ;
4516
4517   SETDEC(out,0,0,-1,-1); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4518   SETDEC(out,0,0,-1,-1); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_LT;
4519   SETDEC(out,0,0,-1,-1); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4520
4521   SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4522   SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_GT;
4523   SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4524
4525   SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4526   SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_GT;
4527   SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_EQ;
4528
4529 }
4530
4531 /*
4532  * VT_BOOL
4533  */
4534
4535 #undef CONV_TYPE
4536 #define CONV_TYPE VARIANT_BOOL
4537 #undef _EXPECTRES
4538 #define _EXPECTRES(res, x, fs) \
4539   ok((hres == S_OK && out == (CONV_TYPE)(x)) || ((HRESULT)res != S_OK && hres == (HRESULT)res), \
4540      "expected " #x ", got " fs "; hres=0x%08x\n", out, hres)
4541 #undef EXPECTRES
4542 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%d")
4543 #undef CONVERTRANGE
4544 #define CONVERTRANGE(func,start,end) for (i = start; i < end; i++) { \
4545   CONVERT(func, i); if (i) { EXPECT(VARIANT_TRUE); } else { EXPECT(VARIANT_FALSE); } }
4546
4547 static void test_VarBoolFromI1(void)
4548 {
4549   CONVVARS(signed char);
4550   int i;
4551
4552   CHECKPTR(VarBoolFromI1);
4553   CONVERTRANGE(VarBoolFromI1, -128, 128);
4554 }
4555
4556 static void test_VarBoolFromUI1(void)
4557 {
4558   CONVVARS(BYTE);
4559   int i;
4560
4561   CHECKPTR(VarBoolFromUI1);
4562   CONVERTRANGE(VarBoolFromUI1, 0, 256);
4563 }
4564
4565 static void test_VarBoolFromI2(void)
4566 {
4567   CONVVARS(SHORT);
4568   int i;
4569
4570   CHECKPTR(VarBoolFromI2);
4571   CONVERTRANGE(VarBoolFromI2, -32768, 32768);
4572 }
4573
4574 static void test_VarBoolFromUI2(void)
4575 {
4576   CONVVARS(USHORT);
4577   int i;
4578
4579   CHECKPTR(VarBoolFromUI2);
4580   CONVERTRANGE(VarBoolFromUI2, 0, 65536);
4581 }
4582
4583 static void test_VarBoolFromI4(void)
4584 {
4585   CONVVARS(int);
4586
4587   CHECKPTR(VarBoolFromI4);
4588   CONVERT(VarBoolFromI4, 0x80000000); EXPECT(VARIANT_TRUE);
4589   CONVERT(VarBoolFromI4, -1);         EXPECT(VARIANT_TRUE);
4590   CONVERT(VarBoolFromI4, 0);          EXPECT(VARIANT_FALSE);
4591   CONVERT(VarBoolFromI4, 1);          EXPECT(VARIANT_TRUE);
4592   CONVERT(VarBoolFromI4, 0x7fffffff); EXPECT(VARIANT_TRUE);
4593 }
4594
4595 static void test_VarBoolFromUI4(void)
4596 {
4597   CONVVARS(ULONG);
4598
4599   CHECKPTR(VarBoolFromUI4);
4600   CONVERT(VarBoolFromI4, 0);          EXPECT(VARIANT_FALSE);
4601   CONVERT(VarBoolFromI4, 1);          EXPECT(VARIANT_TRUE);
4602   CONVERT(VarBoolFromI4, 0x80000000); EXPECT(VARIANT_TRUE);
4603 }
4604
4605 static void test_VarBoolFromR4(void)
4606 {
4607   CONVVARS(FLOAT);
4608
4609   CHECKPTR(VarBoolFromR4);
4610   CONVERT(VarBoolFromR4, -1.0f); EXPECT(VARIANT_TRUE);
4611   CONVERT(VarBoolFromR4, 0.0f);  EXPECT(VARIANT_FALSE);
4612   CONVERT(VarBoolFromR4, 1.0f);  EXPECT(VARIANT_TRUE);
4613   CONVERT(VarBoolFromR4, 1.5f);  EXPECT(VARIANT_TRUE);
4614
4615   /* Rounding */
4616   CONVERT(VarBoolFromR4, -1.5f); EXPECT(VARIANT_TRUE);
4617   CONVERT(VarBoolFromR4, -0.6f); EXPECT(VARIANT_TRUE);
4618   CONVERT(VarBoolFromR4, -0.5f); EXPECT(VARIANT_TRUE);
4619   CONVERT(VarBoolFromR4, -0.4f); EXPECT(VARIANT_TRUE);
4620   CONVERT(VarBoolFromR4, 0.4f);  EXPECT(VARIANT_TRUE);
4621   CONVERT(VarBoolFromR4, 0.5f);  EXPECT(VARIANT_TRUE);
4622   CONVERT(VarBoolFromR4, 0.6f);  EXPECT(VARIANT_TRUE);
4623   CONVERT(VarBoolFromR4, 1.5f);  EXPECT(VARIANT_TRUE);
4624 }
4625
4626 static void test_VarBoolFromR8(void)
4627 {
4628   CONVVARS(DOUBLE);
4629
4630   /* Hopefully we made the point with R4 above that rounding is
4631    * irrelevant, so we'll skip that for R8 and Date
4632    */
4633   CHECKPTR(VarBoolFromR8);
4634   CONVERT(VarBoolFromR8, -1.0); EXPECT(VARIANT_TRUE);
4635   CONVERT(VarBoolFromR8, -0.0); EXPECT(VARIANT_FALSE);
4636   CONVERT(VarBoolFromR8, 1.0);  EXPECT(VARIANT_TRUE);
4637 }
4638
4639 static void test_VarBoolFromCy(void)
4640 {
4641   CONVVARS(CY);
4642
4643   CHECKPTR(VarBoolFromCy);
4644   CONVERT_CY(VarBoolFromCy, -32769); EXPECT(VARIANT_TRUE);
4645   CONVERT_CY(VarBoolFromCy, -32768); EXPECT(VARIANT_TRUE);
4646   CONVERT_CY(VarBoolFromCy, -1);     EXPECT(VARIANT_TRUE);
4647   CONVERT_CY(VarBoolFromCy, 0);      EXPECT(VARIANT_FALSE);
4648   CONVERT_CY(VarBoolFromCy, 1);      EXPECT(VARIANT_TRUE);
4649   CONVERT_CY(VarBoolFromCy, 32767);  EXPECT(VARIANT_TRUE);
4650   CONVERT_CY(VarBoolFromCy, 32768);  EXPECT(VARIANT_TRUE);
4651 }
4652
4653 static void test_VarBoolFromI8(void)
4654 {
4655   CONVVARS(LONG64);
4656
4657   CHECKPTR(VarBoolFromI8);
4658   CONVERT(VarBoolFromI8, -1); EXPECT(VARIANT_TRUE);
4659   CONVERT(VarBoolFromI8, 0);  EXPECT(VARIANT_FALSE);
4660   CONVERT(VarBoolFromI8, 1);  EXPECT(VARIANT_TRUE);
4661 }
4662
4663 static void test_VarBoolFromUI8(void)
4664 {
4665   CONVVARS(ULONG64);
4666
4667   CHECKPTR(VarBoolFromUI8);
4668   CONVERT(VarBoolFromUI8, 0); EXPECT(VARIANT_FALSE);
4669   CONVERT(VarBoolFromUI8, 1); EXPECT(VARIANT_TRUE);
4670 }
4671
4672 static void test_VarBoolFromDec(void)
4673 {
4674   CONVVARS(DECIMAL);
4675
4676   CHECKPTR(VarBoolFromDec);
4677   CONVERT_BADDEC(VarBoolFromDec);
4678
4679   if (HAVE_OLEAUT32_DECIMAL)
4680   {
4681     /* Early versions of oleaut32 don't catch these errors */
4682     CONVERT_DEC(VarBoolFromDec,29,0,0,0);   EXPECT_INVALID;
4683     CONVERT_DEC(VarBoolFromDec,0,0x1,0,0);  EXPECT_INVALID;
4684     CONVERT_DEC(VarBoolFromDec,0,0x40,0,0); EXPECT_INVALID;
4685     CONVERT_DEC(VarBoolFromDec,0,0x7f,0,0); EXPECT_INVALID;
4686   }
4687
4688   CONVERT_DEC(VarBoolFromDec,0,0x80,0,1); EXPECT(VARIANT_TRUE);
4689   CONVERT_DEC(VarBoolFromDec,0,0,0,0);    EXPECT(VARIANT_FALSE);
4690   CONVERT_DEC(VarBoolFromDec,0,0,0,1);    EXPECT(VARIANT_TRUE);
4691   CONVERT_DEC(VarBoolFromDec,0,0,1,0);    EXPECT(VARIANT_TRUE);
4692
4693   CONVERT_DEC(VarBoolFromDec,2,0,0,CY_MULTIPLIER);    EXPECT(VARIANT_TRUE);
4694   CONVERT_DEC(VarBoolFromDec,2,0x80,0,CY_MULTIPLIER); EXPECT(VARIANT_TRUE);
4695 }
4696
4697 static void test_VarBoolFromDate(void)
4698 {
4699   CONVVARS(DATE);
4700
4701   CHECKPTR(VarBoolFromDate);
4702   CONVERT(VarBoolFromDate, -1.0); EXPECT(VARIANT_TRUE);
4703   CONVERT(VarBoolFromDate, -0.0); EXPECT(VARIANT_FALSE);
4704   CONVERT(VarBoolFromDate, 1.0);  EXPECT(VARIANT_TRUE);
4705 }
4706
4707 static void test_VarBoolFromStr(void)
4708 {
4709   CONVVARS(LCID);
4710   OLECHAR buff[128];
4711
4712   CHECKPTR(VarBoolFromStr);
4713
4714   in = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4715
4716   CONVERT_STR(VarBoolFromStr,NULL,0);
4717   if (hres != E_INVALIDARG)
4718     EXPECT_MISMATCH;
4719
4720   /* #FALSE# and #TRUE# Are always accepted */
4721   CONVERT_STR(VarBoolFromStr,"#FALSE#",0); EXPECT(VARIANT_FALSE);
4722   CONVERT_STR(VarBoolFromStr,"#TRUE#",0);  EXPECT(VARIANT_TRUE);
4723
4724   /* Match of #FALSE# and #TRUE# is case sensitive */
4725   CONVERT_STR(VarBoolFromStr,"#False#",0); EXPECT_MISMATCH;
4726   /* But match against English is not */
4727   CONVERT_STR(VarBoolFromStr,"false",0);   EXPECT(VARIANT_FALSE);
4728   CONVERT_STR(VarBoolFromStr,"False",0);   EXPECT(VARIANT_FALSE);
4729   /* On/Off and yes/no are not acceptable inputs, with any flags set */
4730   CONVERT_STR(VarBoolFromStr,"On",0xffffffff);  EXPECT_MISMATCH;
4731   CONVERT_STR(VarBoolFromStr,"Yes",0xffffffff); EXPECT_MISMATCH;
4732
4733   /* Change the LCID. This doesn't make any difference for text,unless we ask
4734    * to check local boolean text with the VARIANT_LOCALBOOL flag. */
4735   in = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT);
4736
4737   /* #FALSE# and #TRUE# are accepted in all locales */
4738   CONVERT_STR(VarBoolFromStr,"#FALSE#",0); EXPECT(VARIANT_FALSE);
4739   CONVERT_STR(VarBoolFromStr,"#TRUE#",0);  EXPECT(VARIANT_TRUE);
4740   CONVERT_STR(VarBoolFromStr,"#FALSE#",VARIANT_LOCALBOOL); EXPECT(VARIANT_FALSE);
4741   CONVERT_STR(VarBoolFromStr,"#TRUE#",VARIANT_LOCALBOOL);  EXPECT(VARIANT_TRUE);
4742
4743   /* English is accepted regardless of the locale */
4744   CONVERT_STR(VarBoolFromStr,"false",0); EXPECT(VARIANT_FALSE);
4745   /* And is still not case sensitive */
4746   CONVERT_STR(VarBoolFromStr,"False",0); EXPECT(VARIANT_FALSE);
4747
4748   if (HAVE_OLEAUT32_LOCALES)
4749   {
4750     /* French is rejected without VARIANT_LOCALBOOL */
4751     CONVERT_STR(VarBoolFromStr,"faux",0); EXPECT_MISMATCH;
4752     /* But accepted if this flag is given */
4753     CONVERT_STR(VarBoolFromStr,"faux",VARIANT_LOCALBOOL); EXPECT(VARIANT_FALSE);
4754     /* Regardless of case - from this we assume locale text comparisons ignore case */
4755     CONVERT_STR(VarBoolFromStr,"Faux",VARIANT_LOCALBOOL); EXPECT(VARIANT_FALSE);
4756
4757     /* Changing the locale prevents the localised text from being compared -
4758      * this demonstrates that only the indicated LCID and English are searched */
4759     in = MAKELCID(MAKELANGID(LANG_POLISH, SUBLANG_DEFAULT), SORT_DEFAULT);
4760     CONVERT_STR(VarBoolFromStr,"faux",VARIANT_LOCALBOOL); EXPECT_MISMATCH;
4761   }
4762
4763   /* Numeric strings are read as 0 or non-0 */
4764   CONVERT_STR(VarBoolFromStr,"0",0);  EXPECT(VARIANT_FALSE);
4765   CONVERT_STR(VarBoolFromStr,"-1",0); EXPECT(VARIANT_TRUE);
4766   CONVERT_STR(VarBoolFromStr,"+1",0); EXPECT(VARIANT_TRUE);
4767
4768   if (HAVE_OLEAUT32_LOCALES)
4769   {
4770     /* Numeric strings are read as floating point numbers. The line below fails
4771      * because '.' is not a valid decimal separator for Polish numbers */
4772     CONVERT_STR(VarBoolFromStr,"0.1",LOCALE_NOUSEROVERRIDE); EXPECT_MISMATCH;
4773   }
4774
4775   /* Changing the lcid back to US English reads the r8 correctly */
4776   in = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4777   CONVERT_STR(VarBoolFromStr,"0.1",LOCALE_NOUSEROVERRIDE); EXPECT(VARIANT_TRUE);
4778 }
4779
4780 static void test_VarBoolCopy(void)
4781 {
4782   COPYTEST(1, VT_BOOL, V_BOOL(&vSrc), V_BOOL(&vDst), V_BOOLREF(&vSrc), V_BOOLREF(&vDst), "%d");
4783 }
4784
4785 #define BOOL_STR(flags, str) hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, flags, VT_BSTR); \
4786   ok(hres == S_OK && V_VT(&vDst) == VT_BSTR && \
4787      V_BSTR(&vDst) && !memcmp(V_BSTR(&vDst), str, sizeof(str)), \
4788      "hres=0x%X, type=%d (should be VT_BSTR), *bstr='%c'\n", \
4789      hres, V_VT(&vDst), V_BSTR(&vDst) ? *V_BSTR(&vDst) : '?'); \
4790   VariantClear(&vDst)
4791
4792 static void test_VarBoolChangeTypeEx(void)
4793 {
4794   static const WCHAR szTrue[] = { 'T','r','u','e','\0' };
4795   static const WCHAR szFalse[] = { 'F','a','l','s','e','\0' };
4796   static const WCHAR szFaux[] = { 'F','a','u','x','\0' };
4797   CONVVARS(CONV_TYPE);
4798   VARIANTARG vSrc, vDst;
4799   LCID lcid;
4800
4801   in = 1;
4802
4803   INITIAL_TYPETEST(VT_BOOL, V_BOOL, "%d");
4804   COMMON_TYPETEST;
4805
4806   /* The common tests convert to a number. Try the different flags */
4807   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4808
4809   V_VT(&vSrc) = VT_BOOL;
4810   V_BOOL(&vSrc) = 1;
4811
4812   if (!IS_ANCIENT)
4813   {
4814       BOOL_STR(VARIANT_ALPHABOOL, szTrue);
4815       V_BOOL(&vSrc) = 0;
4816       BOOL_STR(VARIANT_ALPHABOOL, szFalse);
4817   }
4818
4819   if (HAVE_OLEAUT32_LOCALES)
4820   {
4821     lcid = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT);
4822
4823     /* VARIANT_ALPHABOOL is always English */
4824     BOOL_STR(VARIANT_ALPHABOOL, szFalse);
4825     /* VARIANT_LOCALBOOL uses the localised text */
4826     BOOL_STR(VARIANT_LOCALBOOL, szFaux);
4827     /* Both flags together acts as VARIANT_LOCALBOOL */
4828     BOOL_STR(VARIANT_ALPHABOOL|VARIANT_LOCALBOOL, szFaux);
4829   }
4830 }
4831
4832 /*
4833  * BSTR
4834  */
4835
4836 static void test_VarBstrFromR4(void)
4837 {
4838   static const WCHAR szNative[] = { '6','5','4','3','2','2','.','3','\0' };
4839   static const WCHAR szZero[] = {'0', '\0'};
4840   static const WCHAR szOneHalf_English[] = { '0','.','5','\0' };    /* uses period */
4841   static const WCHAR szOneHalf_Spanish[] = { '0',',','5','\0' };    /* uses comma */
4842   LCID lcid;
4843   LCID lcid_spanish;
4844   HRESULT hres;
4845   BSTR bstr = NULL;
4846
4847   float f;
4848
4849   CHECKPTR(VarBstrFromR4);
4850
4851   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4852   lcid_spanish = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), SORT_DEFAULT);
4853   f = 654322.23456f;
4854   hres = pVarBstrFromR4(f, lcid, 0, &bstr);
4855   ok(hres == S_OK, "got hres 0x%08x\n", hres);
4856   if (bstr)
4857   {
4858     todo_wine {
4859     /* MSDN states that rounding of R4/R8 is dependent on the underlying
4860      * bit pattern of the number and so is architecture dependent. In this
4861      * case Wine returns .2 (which is more correct) and Native returns .3
4862      */
4863     ok(memcmp(bstr, szNative, sizeof(szNative)) == 0, "string different\n");
4864     }
4865     SysFreeString(bstr);
4866   }
4867
4868   f = -0.0;
4869   hres = pVarBstrFromR4(f, lcid, 0, &bstr);
4870   ok(hres == S_OK, "got hres 0x%08x\n", hres);
4871   if (bstr)
4872   {
4873       if (bstr[0] == '-')
4874           ok(memcmp(bstr + 1, szZero, sizeof(szZero)) == 0, "negative zero (got %s)\n", wtoascii(bstr));
4875       else
4876           ok(memcmp(bstr, szZero, sizeof(szZero)) == 0, "negative zero (got %s)\n", wtoascii(bstr));
4877       SysFreeString(bstr);
4878   }
4879   
4880   /* The following tests that lcid is used for decimal separator even without LOCALE_USE_NLS */
4881   f = 0.5;
4882   hres = pVarBstrFromR4(f, lcid, LOCALE_NOUSEROVERRIDE, &bstr);
4883   ok(hres == S_OK, "got hres 0x%08x\n", hres);
4884   if (bstr)
4885   {
4886     ok(memcmp(bstr, szOneHalf_English, sizeof(szOneHalf_English)) == 0, "English locale failed (got %s)\n", wtoascii(bstr));
4887     SysFreeString(bstr);
4888   }
4889   f = 0.5;
4890   hres = pVarBstrFromR4(f, lcid_spanish, LOCALE_NOUSEROVERRIDE, &bstr);
4891   ok(hres == S_OK, "got hres 0x%08x\n", hres);
4892   if (bstr)
4893   {
4894     ok(memcmp(bstr, szOneHalf_Spanish, sizeof(szOneHalf_Spanish)) == 0, "Spanish locale failed (got %s)\n", wtoascii(bstr));
4895     SysFreeString(bstr);
4896   }
4897 }
4898
4899 #define BSTR_DATE(dt,str) \
4900   bstr = NULL; \
4901   hres = pVarBstrFromDate(dt,lcid,LOCALE_NOUSEROVERRIDE,&bstr); \
4902   if (bstr) {WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0); SysFreeString(bstr);} \
4903   else buff[0] = 0; \
4904   ok(hres == S_OK && !strcmp(str,buff), "Expected '%s', got '%s', hres = 0x%08x\n", \
4905      str, buff, hres)
4906
4907 static void test_VarBstrFromDate(void)
4908 {
4909   char buff[256];
4910   LCID lcid;
4911   HRESULT hres;
4912   BSTR bstr;
4913
4914   CHECKPTR(VarBstrFromDate);
4915   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
4916
4917   BSTR_DATE(0.0, "12:00:00 AM");
4918   BSTR_DATE(3.34, "1/2/1900 8:09:36 AM");
4919   BSTR_DATE(3339.34, "2/20/1909 8:09:36 AM");
4920   BSTR_DATE(365.00, "12/30/1900");
4921   BSTR_DATE(365.25, "12/30/1900 6:00:00 AM");
4922   BSTR_DATE(1461.0, "12/31/1903");
4923   BSTR_DATE(1461.5, "12/31/1903 12:00:00 PM");
4924   todo_wine { BSTR_DATE(-657434.0, "1/1/100"); }
4925   BSTR_DATE(2958465.0, "12/31/9999");
4926 }
4927
4928 #define BSTR_CY(l, a, b, e) \
4929   S(l).Lo = b; S(l).Hi = a; \
4930   hres = pVarBstrFromCy(l, lcid, LOCALE_NOUSEROVERRIDE, &bstr);\
4931   ok(hres == S_OK, "got hres 0x%08x\n", hres);\
4932   if (hres== S_OK && bstr)\
4933   {\
4934     ok(lstrcmpW(bstr, e) == 0, "invalid number (got %s)\n", wtoascii(bstr));\
4935     SysFreeString(bstr);\
4936   }
4937
4938 static void test_VarBstrFromCy(void)
4939 {
4940   LCID lcid;
4941   HRESULT hres;
4942   BSTR bstr = NULL;
4943   CY l;
4944
4945   static const WCHAR szZero[] = {'0', '\0'};
4946   static const WCHAR szOne[] = {'1', '\0'};
4947   static const WCHAR szOnePointFive[] = {'1','.','5','\0'};
4948   static const WCHAR szMinusOnePointFive[] = {'-','1','.','5','\0'};
4949   static const WCHAR szBigNum1[] = {'4','2','9','4','9','6','.','7','2','9','5','\0'};    /* (1 << 32) - 1 / 1000 */
4950   static const WCHAR szBigNum2[] = {'4','2','9','4','9','6','.','7','2','9','6','\0'};    /* (1 << 32) / 1000 */
4951   static const WCHAR szBigNum3[] = {'9','2','2','3','3','7','2','0','3','6','8','5','4','7','7','.','5','8','0','7','\0'};    /* ((1 << 63) - 1)/10000 */
4952
4953   static const WCHAR szSmallNumber_English[] = {'0','.','0','0','0','9','\0'};
4954   static const WCHAR szSmallNumber_Spanish[] = {'0',',','0','0','0','9','\0'};
4955
4956   CHECKPTR(VarBstrFromCy);
4957   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
4958
4959   /* check zero */
4960   BSTR_CY(l, 0,0, szZero);
4961
4962   /* check one */
4963   BSTR_CY(l, 0, 10000, szOne);
4964
4965   /* check one point five */
4966   BSTR_CY(l, 0, 15000, szOnePointFive);
4967
4968   /* check minus one point five */
4969   BSTR_CY(l, 0xffffffff, ((15000)^0xffffffff)+1, szMinusOnePointFive);
4970
4971   /* check bignum (1) */
4972   BSTR_CY(l, 0, 0xffffffff, szBigNum1);
4973
4974   /* check bignum (2) */
4975   BSTR_CY(l, 1,0, szBigNum2);
4976
4977   /* check bignum (3) */
4978   BSTR_CY(l, 0x7fffffff,0xffffffff, szBigNum3);
4979
4980   /* check leading zeros and decimal sep. for English locale */
4981   BSTR_CY(l, 0,9, szSmallNumber_English);
4982
4983   lcid = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
4984
4985   /* check leading zeros and decimal sep. for Spanish locale */
4986   BSTR_CY(l, 0,9, szSmallNumber_Spanish);
4987 }
4988
4989 #undef BSTR_CY
4990
4991 #define BSTR_DEC(l, a, b, c, d, e) \
4992   SETDEC(l, a,b,c,d);\
4993   hres = pVarBstrFromDec(&l, lcid, LOCALE_NOUSEROVERRIDE, &bstr);\
4994   ok(hres == S_OK, "got hres 0x%08x\n", hres);\
4995   if (hres== S_OK && bstr)\
4996   {\
4997     ok(lstrcmpW(bstr, e) == 0, "invalid number (got %s)\n", wtoascii(bstr));\
4998     SysFreeString(bstr);\
4999   }
5000
5001 #define BSTR_DEC64(l, a, b, c, x, d, e) \
5002   SETDEC64(l, a,b,c,x,d);\
5003   hres = pVarBstrFromDec(&l, lcid, LOCALE_NOUSEROVERRIDE, &bstr);\
5004   ok(hres == S_OK, "got hres 0x%08x\n", hres);\
5005   if (hres== S_OK && bstr)\
5006   {\
5007     ok(lstrcmpW(bstr, e) == 0, "invalid number (got %s)\n", wtoascii(bstr));\
5008     SysFreeString(bstr);\
5009   }
5010
5011 static void test_VarBstrFromDec(void)
5012 {
5013   LCID lcid;
5014   HRESULT hres;
5015   BSTR bstr = NULL;
5016   DECIMAL l;
5017
5018   static const WCHAR szZero[] = {'0', '\0'};
5019   static const WCHAR szOne[] = {'1', '\0'};
5020   static const WCHAR szOnePointFive[] = {'1','.','5','\0'};
5021   static const WCHAR szMinusOnePointFive[] = {'-','1','.','5','\0'};
5022   static const WCHAR szBigNum1[] = {'4','2','9','4','9','6','7','2','9','5','\0'};    /* (1 << 32) - 1 */
5023   static const WCHAR szBigNum2[] = {'4','2','9','4','9','6','7','2','9','6','\0'};    /* (1 << 32) */
5024   static const WCHAR szBigNum3[] = {'1','8','4','4','6','7','4','4','0','7','3','7','0','9','5','5','1','6','1','5','\0'};    /* (1 << 64) - 1 */
5025   static const WCHAR szBigNum4[] = {'1','8','4','4','6','7','4','4','0','7','3','7','0','9','5','5','1','6','1','6','\0'};    /* (1 << 64) */
5026   static const WCHAR szBigNum5[] = {'7','9','2','2','8','1','6','2','5','1','4','2','6','4','3','3','7','5','9','3','5','4','3','9','5','0','3','3','5','\0'};    /* (1 << 96) - 1 */
5027   static const WCHAR szBigScale1[] = {'0','.','0','0','0','0','0','0','0','0','0','1','\0'};    /* 1 * 10^-10 */
5028   static const WCHAR szBigScale2[] = {'7','9','2','2','8','1','6','2','5','1','4','2','6','4','3','3','7','5','9','.','3','5','4','3','9','5','0','3','3','5','\0'};    /* ((1 << 96) - 1) * 10^-10 */
5029   static const WCHAR szBigScale3[] = {'7','.','9','2','2','8','1','6','2','5','1','4','2','6','4','3','3','7','5','9','3','5','4','3','9','5','0','3','3','5','\0'};    /* ((1 << 96) - 1) * 10^-28 */
5030
5031   static const WCHAR szSmallNumber_English[] = {'0','.','0','0','0','9','\0'};
5032   static const WCHAR szSmallNumber_Spanish[] = {'0',',','0','0','0','9','\0'};
5033
5034   CHECKPTR(VarBstrFromDec);
5035   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
5036
5037   /* check zero */
5038   BSTR_DEC(l, 0,0,0,0, szZero);
5039   
5040   /* check one */
5041   BSTR_DEC(l, 0,0,0,1, szOne);
5042   BSTR_DEC(l, 1,0,0,10,szOne);
5043   BSTR_DEC(l, 2,0,0,100,szOne);
5044   BSTR_DEC(l, 3,0,0,1000,szOne);
5045
5046   /* check one point five */
5047   BSTR_DEC(l, 1,0,0,15, szOnePointFive);
5048   BSTR_DEC(l, 2,0,0,150, szOnePointFive);
5049   BSTR_DEC(l, 3,0,0,1500, szOnePointFive);
5050
5051   /* check minus one point five */
5052   BSTR_DEC(l, 1,0x80,0,15, szMinusOnePointFive);
5053
5054   /* check bignum (1) */
5055   BSTR_DEC(l, 0,0,0,0xffffffff, szBigNum1);
5056
5057   /* check bignum (2) */
5058   BSTR_DEC64(l, 0,0,0,1,0, szBigNum2);
5059
5060   /* check bignum (3) */
5061   BSTR_DEC64(l, 0,0,0,0xffffffff,0xffffffff, szBigNum3);
5062
5063   /* check bignum (4) */
5064   BSTR_DEC(l, 0,0,1,0, szBigNum4);
5065
5066   /* check bignum (5) */
5067   BSTR_DEC64(l, 0,0,0xffffffff,0xffffffff,0xffffffff, szBigNum5);
5068
5069   /* check bigscale (1) */
5070   BSTR_DEC(l, 10,0,0,1, szBigScale1);
5071
5072   /* check bigscale (2) */
5073   BSTR_DEC64(l, 10,0,0xffffffffUL,0xffffffff,0xffffffff, szBigScale2);
5074
5075   /* check bigscale (3) */
5076   BSTR_DEC64(l, 28,0,0xffffffffUL,0xffffffff,0xffffffff, szBigScale3);
5077
5078   /* check leading zeros and decimal sep. for English locale */
5079   BSTR_DEC(l, 4,0,0,9, szSmallNumber_English);
5080   BSTR_DEC(l, 5,0,0,90, szSmallNumber_English);
5081   BSTR_DEC(l, 6,0,0,900, szSmallNumber_English);
5082   BSTR_DEC(l, 7,0,0,9000, szSmallNumber_English);
5083   
5084   lcid = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
5085   
5086   /* check leading zeros and decimal sep. for Spanish locale */
5087   BSTR_DEC(l, 4,0,0,9, szSmallNumber_Spanish);
5088   BSTR_DEC(l, 5,0,0,90, szSmallNumber_Spanish);
5089   BSTR_DEC(l, 6,0,0,900, szSmallNumber_Spanish);
5090   BSTR_DEC(l, 7,0,0,9000, szSmallNumber_Spanish);
5091 }
5092 #undef BSTR_DEC
5093 #undef BSTR_DEC64
5094
5095 #define _VARBSTRCMP(left,right,lcid,flags,result) \
5096         hres = pVarBstrCmp(left,right,lcid,flags); \
5097         ok(hres == result, "VarBstrCmp: expected " #result ", got hres=0x%x\n", hres)
5098 #define VARBSTRCMP(left,right,flags,result) \
5099         _VARBSTRCMP(left,right,lcid,flags,result)
5100
5101 static void test_VarBstrCmp(void)
5102 {
5103     LCID lcid;
5104     HRESULT hres;
5105     static const WCHAR sz[] = {'W','u','r','s','c','h','t','\0'};
5106     static const WCHAR szempty[] = {'\0'};
5107     static const WCHAR sz1[] = { 'a',0 };
5108     static const WCHAR sz2[] = { 'A',0 };
5109     static const WCHAR s1[] = { 'a',0 };
5110     static const WCHAR s2[] = { 'a',0,'b' };
5111     static const char sb1[] = {1,0,1};
5112     static const char sb2[] = {1,0,2};
5113     static const char sbchr0[] = {0,0};
5114     static const char sbchr00[] = {0,0,0};
5115     BSTR bstr, bstrempty, bstr2;
5116
5117     CHECKPTR(VarBstrCmp);
5118     
5119     lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
5120     bstr = SysAllocString(sz);
5121     bstrempty = SysAllocString(szempty);
5122     
5123     /* NULL handling. Yepp, MSDN is totally wrong here */
5124     VARBSTRCMP(NULL,NULL,0,VARCMP_EQ);
5125     VARBSTRCMP(bstr,NULL,0,VARCMP_GT);
5126     VARBSTRCMP(NULL,bstr,0,VARCMP_LT);
5127
5128     /* NULL and empty string comparisons */
5129     VARBSTRCMP(bstrempty,NULL,0,VARCMP_EQ);
5130     VARBSTRCMP(NULL,bstrempty,0,VARCMP_EQ);
5131
5132     SysFreeString(bstr);
5133     bstr = SysAllocString(sz1);
5134
5135     bstr2 = SysAllocString(sz2);
5136     VARBSTRCMP(bstr,bstr2,0,VARCMP_LT);
5137     VARBSTRCMP(bstr,bstr2,NORM_IGNORECASE,VARCMP_EQ);
5138     SysFreeString(bstr2);
5139     /* These two strings are considered equal even though one is
5140      * NULL-terminated and the other not.
5141      */
5142     bstr2 = SysAllocStringLen(s1, sizeof(s1) / sizeof(WCHAR));
5143     VARBSTRCMP(bstr,bstr2,0,VARCMP_EQ);
5144     SysFreeString(bstr2);
5145
5146     /* These two strings are not equal */
5147     bstr2 = SysAllocStringLen(s2, sizeof(s2) / sizeof(WCHAR));
5148     VARBSTRCMP(bstr,bstr2,0,VARCMP_LT);
5149     SysFreeString(bstr2);
5150
5151     SysFreeString(bstr);
5152
5153     bstr = SysAllocStringByteLen(sbchr0, sizeof(sbchr0));
5154     bstr2 = SysAllocStringByteLen(sbchr0, sizeof(sbchr00));
5155     VARBSTRCMP(bstr,bstrempty,0,VARCMP_GT);
5156     VARBSTRCMP(bstrempty,bstr,0,VARCMP_LT);
5157     VARBSTRCMP(bstr2,bstrempty,0,VARCMP_GT);
5158     VARBSTRCMP(bstr2,bstr,0,VARCMP_EQ);
5159     SysFreeString(bstr2);
5160     SysFreeString(bstr);
5161
5162     /* When (LCID == 0) it should be a binary comparison
5163      * so these two strings could not match.
5164      */
5165     bstr = SysAllocStringByteLen(sb1, sizeof(sb1));
5166     bstr2 = SysAllocStringByteLen(sb2, sizeof(sb2));
5167     lcid = 0;
5168     VARBSTRCMP(bstr,bstr2,0,VARCMP_LT);
5169     SysFreeString(bstr2);
5170     SysFreeString(bstr);
5171
5172     bstr = SysAllocStringByteLen(sbchr0, sizeof(sbchr0));
5173     bstr2 = SysAllocStringByteLen(sbchr0, sizeof(sbchr00));
5174     VARBSTRCMP(bstr,bstrempty,0,VARCMP_GT);
5175     VARBSTRCMP(bstrempty,bstr,0,VARCMP_LT);
5176     VARBSTRCMP(bstr2,bstrempty,0,VARCMP_GT);
5177     VARBSTRCMP(bstr2,bstr,0,VARCMP_GT);
5178     SysFreeString(bstr2);
5179     SysFreeString(bstr);
5180     SysFreeString(bstrempty);
5181 }
5182
5183 /* Get the internal representation of a BSTR */
5184 static inline LPINTERNAL_BSTR Get(const BSTR lpszString)
5185 {
5186   return lpszString ? (LPINTERNAL_BSTR)((char*)lpszString - sizeof(DWORD)) : NULL;
5187 }
5188
5189 static inline BSTR GetBSTR(const LPINTERNAL_BSTR bstr)
5190 {
5191   return (BSTR)bstr->szString;
5192 }
5193
5194 static void test_SysStringLen(void)
5195 {
5196   INTERNAL_BSTR bstr;
5197   BSTR str = GetBSTR(&bstr);
5198
5199   bstr.dwLen = 0;
5200   ok (SysStringLen(str) == 0, "Expected dwLen 0, got %d\n", SysStringLen(str));
5201   bstr.dwLen = 2;
5202   ok (SysStringLen(str) == 1, "Expected dwLen 1, got %d\n", SysStringLen(str));
5203 }
5204
5205 static void test_SysStringByteLen(void)
5206 {
5207   INTERNAL_BSTR bstr;
5208   BSTR str = GetBSTR(&bstr);
5209
5210   bstr.dwLen = 0;
5211   ok (SysStringByteLen(str) == 0, "Expected dwLen 0, got %d\n", SysStringByteLen(str));
5212   bstr.dwLen = 2;
5213   ok (SysStringByteLen(str) == 2, "Expected dwLen 2, got %d\n", SysStringByteLen(str));
5214 }
5215
5216 static void test_SysAllocString(void)
5217 {
5218   const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
5219   BSTR str;
5220
5221   str = SysAllocString(NULL);
5222   ok (str == NULL, "Expected NULL, got %p\n", str);
5223
5224   str = SysAllocString(szTest);
5225   ok (str != NULL, "Expected non-NULL\n");
5226   if (str)
5227   {
5228     LPINTERNAL_BSTR bstr = Get(str);
5229
5230     ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5231     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5232     SysFreeString(str);
5233   }
5234 }
5235
5236 static void test_SysAllocStringLen(void)
5237 {
5238   const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
5239   BSTR str;
5240
5241   /* Very early native dlls do not limit the size of strings, so skip this test */
5242   if (0)
5243   {
5244   str = SysAllocStringLen(szTest, 0x80000000);
5245   ok (str == NULL, "Expected NULL, got %p\n", str);
5246   }
5247   
5248   str = SysAllocStringLen(NULL, 0);
5249   ok (str != NULL, "Expected non-NULL\n");
5250   if (str)
5251   {
5252     LPINTERNAL_BSTR bstr = Get(str);
5253
5254     ok (bstr->dwLen == 0, "Expected 0, got %d\n", bstr->dwLen);
5255     ok (!bstr->szString[0], "String not empty\n");
5256     SysFreeString(str);
5257   }
5258
5259   str = SysAllocStringLen(szTest, 4);
5260   ok (str != NULL, "Expected non-NULL\n");
5261   if (str)
5262   {
5263     LPINTERNAL_BSTR bstr = Get(str);
5264
5265     ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5266     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5267     SysFreeString(str);
5268   }
5269 }
5270
5271 static void test_SysAllocStringByteLen(void)
5272 {
5273   const OLECHAR szTest[10] = { 'T','e','s','t','\0' };
5274   const CHAR szTestA[6] = { 'T','e','s','t','\0','?' };
5275   BSTR str;
5276
5277   if (sizeof(void *) == 4)  /* not limited to 0x80000000 on Win64 */
5278   {
5279       str = SysAllocStringByteLen(szTestA, 0x80000000);
5280       ok (str == NULL, "Expected NULL, got %p\n", str);
5281   }
5282
5283   str = SysAllocStringByteLen(szTestA, 0xffffffff);
5284   ok (str == NULL, "Expected NULL, got %p\n", str);
5285
5286   str = SysAllocStringByteLen(NULL, 0);
5287   ok (str != NULL, "Expected non-NULL\n");
5288   if (str)
5289   {
5290     LPINTERNAL_BSTR bstr = Get(str);
5291
5292     ok (bstr->dwLen == 0, "Expected 0, got %d\n", bstr->dwLen);
5293     ok (!bstr->szString[0], "String not empty\n");
5294     SysFreeString(str);
5295   }
5296
5297   str = SysAllocStringByteLen(szTestA, 4);
5298   ok (str != NULL, "Expected non-NULL\n");
5299   if (str)
5300   {
5301     LPINTERNAL_BSTR bstr = Get(str);
5302
5303     ok (bstr->dwLen == 4, "Expected 4, got %d\n", bstr->dwLen);
5304     ok (!lstrcmpA((LPCSTR)bstr->szString, szTestA), "String different\n");
5305     SysFreeString(str);
5306   }
5307
5308   /* Odd lengths are allocated rounded up, but truncated at the right position */
5309   str = SysAllocStringByteLen(szTestA, 3);
5310   ok (str != NULL, "Expected non-NULL\n");
5311   if (str)
5312   {
5313     const CHAR szTestTruncA[4] = { 'T','e','s','\0' };
5314     LPINTERNAL_BSTR bstr = Get(str);
5315
5316     ok (bstr->dwLen == 3, "Expected 3, got %d\n", bstr->dwLen);
5317     ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n");
5318     SysFreeString(str);
5319   }
5320
5321   str = SysAllocStringByteLen((LPCSTR)szTest, 8);
5322   ok (str != NULL, "Expected non-NULL\n");
5323   if (str)
5324   {
5325     LPINTERNAL_BSTR bstr = Get(str);
5326
5327     ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5328     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5329     SysFreeString(str);
5330   }
5331 }
5332
5333 static void test_SysReAllocString(void)
5334 {
5335   const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
5336   const OLECHAR szSmaller[2] = { 'x','\0' };
5337   const OLECHAR szLarger[7] = { 'L','a','r','g','e','r','\0' };
5338   BSTR str;
5339
5340   str = SysAllocStringLen(szTest, 4);
5341   ok (str != NULL, "Expected non-NULL\n");
5342   if (str)
5343   {
5344     LPINTERNAL_BSTR bstr;
5345     int changed;
5346
5347     bstr = Get(str);
5348     ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5349     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5350
5351     changed = SysReAllocString(&str, szSmaller);
5352     ok (changed == 1, "Expected 1, got %d\n", changed);
5353     /* Vista creates a new string, but older versions reuse the existing string. */
5354     /*ok (str == oldstr, "Created new string\n");*/
5355     bstr = Get(str);
5356     ok (bstr->dwLen == 2, "Expected 2, got %d\n", bstr->dwLen);
5357     ok (!lstrcmpW(bstr->szString, szSmaller), "String different\n");
5358
5359     changed = SysReAllocString(&str, szLarger);
5360     ok (changed == 1, "Expected 1, got %d\n", changed);
5361     /* Early versions always make new strings rather than resizing */
5362     /* ok (str == oldstr, "Created new string\n"); */
5363     bstr = Get(str);
5364     ok (bstr->dwLen == 12, "Expected 12, got %d\n", bstr->dwLen);
5365     ok (!lstrcmpW(bstr->szString, szLarger), "String different\n");
5366
5367     SysFreeString(str);
5368   }
5369 }
5370
5371 static void test_SysReAllocStringLen(void)
5372 {
5373   const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
5374   const OLECHAR szSmaller[2] = { 'x','\0' };
5375   const OLECHAR szLarger[7] = { 'L','a','r','g','e','r','\0' };
5376   BSTR str;
5377
5378   str = SysAllocStringLen(szTest, 4);
5379   ok (str != NULL, "Expected non-NULL\n");
5380   if (str)
5381   {
5382     LPINTERNAL_BSTR bstr;
5383     int changed;
5384
5385     bstr = Get(str);
5386     ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5387     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5388
5389     changed = SysReAllocStringLen(&str, szSmaller, 1);
5390     ok (changed == 1, "Expected 1, got %d\n", changed);
5391     /* Vista creates a new string, but older versions reuse the existing string. */
5392     /*ok (str == oldstr, "Created new string\n");*/
5393     bstr = Get(str);
5394     ok (bstr->dwLen == 2, "Expected 2, got %d\n", bstr->dwLen);
5395     ok (!lstrcmpW(bstr->szString, szSmaller), "String different\n");
5396
5397     changed = SysReAllocStringLen(&str, szLarger, 6);
5398     ok (changed == 1, "Expected 1, got %d\n", changed);
5399     /* Early versions always make new strings rather than resizing */
5400     /* ok (str == oldstr, "Created new string\n"); */
5401     bstr = Get(str);
5402     ok (bstr->dwLen == 12, "Expected 12, got %d\n", bstr->dwLen);
5403     ok (!lstrcmpW(bstr->szString, szLarger), "String different\n");
5404
5405     changed = SysReAllocStringLen(&str, str, 6);
5406     ok (changed == 1, "Expected 1, got %d\n", changed);
5407
5408     SysFreeString(str);
5409   }
5410
5411   /* Windows always returns null terminated strings */
5412   str = SysAllocStringLen(szTest, 4);
5413   ok (str != NULL, "Expected non-NULL\n");
5414   if (str)
5415   {
5416     const int CHUNK_SIZE = 64;
5417     const int STRING_SIZE = 24;
5418     int changed;
5419     changed = SysReAllocStringLen(&str, NULL, CHUNK_SIZE);
5420     ok (changed == 1, "Expected 1, got %d\n", changed);
5421     ok (str != NULL, "Expected non-NULL\n");
5422     if (str)
5423     {
5424       BSTR oldstr = str;
5425
5426       /* Filling string */
5427       memset (str, 0xAB, CHUNK_SIZE * sizeof (OLECHAR));
5428       /* Checking null terminator */
5429       changed = SysReAllocStringLen(&str, NULL, STRING_SIZE);
5430       ok (changed == 1, "Expected 1, got %d\n", changed);
5431       ok (str != NULL, "Expected non-NULL\n");
5432       if (str)
5433       {
5434         ok (str == oldstr, "Expected reuse of the old string memory\n");
5435         ok (str[STRING_SIZE] == 0,
5436             "Expected null terminator, got 0x%04X\n", str[STRING_SIZE]);
5437         SysFreeString(str);
5438       }
5439     }
5440   }
5441
5442   /* Some Windows applications use the same pointer for pbstr and psz */
5443   str = SysAllocStringLen(szTest, 4);
5444   ok(str != NULL, "Expected non-NULL\n");
5445   if(str)
5446   {
5447       SysReAllocStringLen(&str, str, 1000000);
5448       ok(SysStringLen(str)==1000000, "Incorrect string length\n");
5449       ok(!memcmp(szTest, str, 4*sizeof(WCHAR)), "Incorrect string returned\n");
5450
5451       SysFreeString(str);
5452   }
5453 }
5454
5455 static void test_BstrCopy(void)
5456 {
5457   const CHAR szTestA[6] = { 'T','e','s','t','\0','?' };
5458   const CHAR szTestTruncA[4] = { 'T','e','s','\0' };
5459   LPINTERNAL_BSTR bstr;
5460   BSTR str;
5461   HRESULT hres;
5462   VARIANT vt1, vt2;
5463
5464   str = SysAllocStringByteLen(szTestA, 3);
5465   ok (str != NULL, "Expected non-NULL\n");
5466   if (str)
5467   {
5468     V_VT(&vt1) = VT_BSTR;
5469     V_BSTR(&vt1) = str;
5470     V_VT(&vt2) = VT_EMPTY;
5471     hres = VariantCopy(&vt2, &vt1);
5472     ok (hres == S_OK,"Failed to copy binary bstring with hres 0x%08x\n", hres);
5473     bstr = Get(V_BSTR(&vt2));
5474     ok (bstr->dwLen == 3, "Expected 3, got %d\n", bstr->dwLen);
5475     ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n");
5476     VariantClear(&vt2);
5477     VariantClear(&vt1);
5478   }
5479 }
5480
5481 static void test_VarBstrCat(void)
5482 {
5483     static const WCHAR sz1[] = { 'a',0 };
5484     static const WCHAR sz2[] = { 'b',0 };
5485     static const WCHAR sz1sz2[] = { 'a','b',0 };
5486     static const WCHAR s1[] = { 'a',0 };
5487     static const WCHAR s2[] = { 'b',0 };
5488     static const WCHAR s1s2[] = { 'a',0,'b',0 };
5489     static const char str1A[] = "Have ";
5490     static const char str2A[] = "A Cigar";
5491     HRESULT ret;
5492     BSTR str1, str2, res;
5493     UINT len;
5494
5495 if (0)
5496 {
5497     /* Crash */
5498     ret = VarBstrCat(NULL, NULL, NULL);
5499 }
5500
5501     /* Concatenation of two NULL strings works */
5502     ret = VarBstrCat(NULL, NULL, &res);
5503     ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5504     ok(res != NULL, "Expected a string\n");
5505     ok(SysStringLen(res) == 0, "Expected a 0-length string\n");
5506     SysFreeString(res);
5507
5508     str1 = SysAllocString(sz1);
5509
5510     /* Concatenation with one NULL arg */
5511     ret = VarBstrCat(NULL, str1, &res);
5512     ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5513     ok(res != NULL, "Expected a string\n");
5514     ok(SysStringLen(res) == SysStringLen(str1), "Unexpected length\n");
5515     ok(!memcmp(res, sz1, SysStringLen(str1)), "Unexpected value\n");
5516     SysFreeString(res);
5517     ret = VarBstrCat(str1, NULL, &res);
5518     ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5519     ok(res != NULL, "Expected a string\n");
5520     ok(SysStringLen(res) == SysStringLen(str1), "Unexpected length\n");
5521     ok(!memcmp(res, sz1, SysStringLen(str1)), "Unexpected value\n");
5522     SysFreeString(res);
5523
5524     /* Concatenation of two zero-terminated strings */
5525     str2 = SysAllocString(sz2);
5526     ret = VarBstrCat(str1, str2, &res);
5527     ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5528     ok(res != NULL, "Expected a string\n");
5529     ok(SysStringLen(res) == sizeof(sz1sz2) / sizeof(WCHAR) - 1,
5530      "Unexpected length\n");
5531     ok(!memcmp(res, sz1sz2, sizeof(sz1sz2)), "Unexpected value\n");
5532     SysFreeString(res);
5533
5534     SysFreeString(str2);
5535     SysFreeString(str1);
5536
5537     /* Concatenation of two strings with embedded NULLs */
5538     str1 = SysAllocStringLen(s1, sizeof(s1) / sizeof(WCHAR));
5539     str2 = SysAllocStringLen(s2, sizeof(s2) / sizeof(WCHAR));
5540
5541     ret = VarBstrCat(str1, str2, &res);
5542     ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5543     ok(res != NULL, "Expected a string\n");
5544     ok(SysStringLen(res) == sizeof(s1s2) / sizeof(WCHAR),
5545      "Unexpected length\n");
5546     ok(!memcmp(res, s1s2, sizeof(s1s2)), "Unexpected value\n");
5547     SysFreeString(res);
5548
5549     SysFreeString(str2);
5550     SysFreeString(str1);
5551
5552     /* Concatenation of ansi BSTRs, both odd byte count not including termination */
5553     str1 = SysAllocStringByteLen(str1A, sizeof(str1A)-1);
5554     str2 = SysAllocStringByteLen(str2A, sizeof(str2A)-1);
5555     len = SysStringLen(str1);
5556     ok(len == (sizeof(str1A)-1)/sizeof(WCHAR), "got length %u\n", len);
5557     len = SysStringLen(str2);
5558     ok(len == (sizeof(str2A)-1)/sizeof(WCHAR), "got length %u\n", len);
5559
5560     ret = VarBstrCat(str1, str2, &res);
5561     ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5562     ok(res != NULL, "Expected a string\n");
5563     len = (sizeof(str1A) + sizeof(str2A) - 2)/sizeof(WCHAR);
5564     ok(SysStringLen(res) == len, "got %d, expected %u\n", SysStringLen(res), len);
5565     ok(!memcmp(res, "Have A Cigar", sizeof(str1A) + sizeof(str2A) - 1), "got (%s)\n", (char*)res);
5566     SysFreeString(res);
5567
5568     SysFreeString(str2);
5569     SysFreeString(str1);
5570
5571     /* Concatenation of ansi BSTRs, both 1 byte length not including termination */
5572     str1 = SysAllocStringByteLen(str1A, 1);
5573     str2 = SysAllocStringByteLen(str2A, 1);
5574     len = SysStringLen(str1);
5575     ok(len == 0, "got length %u\n", len);
5576     len = SysStringLen(str2);
5577     ok(len == 0, "got length %u\n", len);
5578
5579     ret = VarBstrCat(str1, str2, &res);
5580     ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5581     ok(res != NULL, "Expected a string\n");
5582     ok(SysStringLen(res) == 1, "got %d, expected 1\n", SysStringLen(res));
5583     ok(!memcmp(res, "HA", 2), "got (%s)\n", (char*)res);
5584     SysFreeString(res);
5585
5586     SysFreeString(str2);
5587     SysFreeString(str1);
5588 }
5589
5590 /* IUnknown */
5591
5592 static void test_IUnknownClear(void)
5593 {
5594   HRESULT hres;
5595   VARIANTARG v;
5596   DummyDispatch u = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
5597   IUnknown* pu = (IUnknown*)&u;
5598
5599   /* Test that IUnknown_Release is called on by-value */
5600   V_VT(&v) = VT_UNKNOWN;
5601   V_UNKNOWN(&v) = (IUnknown*)&u;
5602   hres = VariantClear(&v);
5603   ok(hres == S_OK && u.ref == 0 && V_VT(&v) == VT_EMPTY,
5604      "clear unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5605      S_OK, 0, VT_EMPTY, hres, u.ref, V_VT(&v));
5606
5607   /* But not when clearing a by-reference*/
5608   u.ref = 1;
5609   V_VT(&v) = VT_UNKNOWN|VT_BYREF;
5610   V_UNKNOWNREF(&v) = &pu;
5611   hres = VariantClear(&v);
5612   ok(hres == S_OK && u.ref == 1 && V_VT(&v) == VT_EMPTY,
5613      "clear dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5614      S_OK, 1, VT_EMPTY, hres, u.ref, V_VT(&v));
5615 }
5616
5617 static void test_IUnknownCopy(void)
5618 {
5619   HRESULT hres;
5620   VARIANTARG vSrc, vDst;
5621   DummyDispatch u = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
5622   IUnknown* pu = (IUnknown*)&u;
5623
5624   /* AddRef is called on by-value copy */
5625   VariantInit(&vDst);
5626   V_VT(&vSrc) = VT_UNKNOWN;
5627   V_UNKNOWN(&vSrc) = pu;
5628   hres = VariantCopy(&vDst, &vSrc);
5629   ok(hres == S_OK && u.ref == 2 && V_VT(&vDst) == VT_UNKNOWN,
5630      "copy unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5631      S_OK, 2, VT_EMPTY, hres, u.ref, V_VT(&vDst));
5632
5633   /* AddRef is skipped on copy of by-reference IDispatch */
5634   VariantInit(&vDst);
5635   u.ref = 1;
5636   V_VT(&vSrc) = VT_UNKNOWN|VT_BYREF;
5637   V_UNKNOWNREF(&vSrc) = &pu;
5638   hres = VariantCopy(&vDst, &vSrc);
5639   ok(hres == S_OK && u.ref == 1 && V_VT(&vDst) == (VT_UNKNOWN|VT_BYREF),
5640      "copy unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5641      S_OK, 1, VT_DISPATCH, hres, u.ref, V_VT(&vDst));
5642
5643   /* AddRef is called copying by-reference IDispatch with indirection */
5644   VariantInit(&vDst);
5645   u.ref = 1;
5646   V_VT(&vSrc) = VT_UNKNOWN|VT_BYREF;
5647   V_UNKNOWNREF(&vSrc) = &pu;
5648   hres = VariantCopyInd(&vDst, &vSrc);
5649   ok(hres == S_OK && u.ref == 2 && V_VT(&vDst) == VT_UNKNOWN,
5650      "copy unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5651      S_OK, 2, VT_DISPATCH, hres, u.ref, V_VT(&vDst));
5652
5653   /* Indirection in place also calls AddRef */
5654   u.ref = 1;
5655   V_VT(&vSrc) = VT_UNKNOWN|VT_BYREF;
5656   V_UNKNOWNREF(&vSrc) = &pu;
5657   hres = VariantCopyInd(&vSrc, &vSrc);
5658   ok(hres == S_OK && u.ref == 2 && V_VT(&vSrc) == VT_UNKNOWN,
5659      "copy unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5660      S_OK, 2, VT_DISPATCH, hres, u.ref, V_VT(&vSrc));
5661 }
5662
5663 static void test_IUnknownChangeTypeEx(void)
5664 {
5665   HRESULT hres;
5666   VARIANTARG vSrc, vDst;
5667   LCID lcid;
5668   VARTYPE vt;
5669   DummyDispatch u = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
5670   IUnknown* pu = (IUnknown*)&u;
5671
5672   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5673
5674   V_VT(&vSrc) = VT_UNKNOWN;
5675   V_UNKNOWN(&vSrc) = pu;
5676
5677   /* =>IDispatch in place */
5678   hres = VariantChangeTypeEx(&vSrc, &vSrc, lcid, 0, VT_DISPATCH);
5679   ok(hres == S_OK && u.ref == 1 &&
5680      V_VT(&vSrc) == VT_DISPATCH && V_DISPATCH(&vSrc) == (IDispatch*)pu,
5681      "change unk(src=src): expected 0x%08x,%d,%d,%p, got 0x%08x,%d,%d,%p\n",
5682      S_OK, 1, VT_DISPATCH, pu, hres, u.ref, V_VT(&vSrc), V_DISPATCH(&vSrc));
5683
5684   /* =>IDispatch */
5685   u.ref = 1;
5686   V_VT(&vSrc) = VT_UNKNOWN;
5687   V_UNKNOWN(&vSrc) = pu;
5688   VariantInit(&vDst);
5689   hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, VT_UNKNOWN);
5690   /* Note vSrc is not cleared, as final refcount is 2 */
5691   ok(hres == S_OK && u.ref == 2 &&
5692      V_VT(&vDst) == VT_UNKNOWN && V_UNKNOWN(&vDst) == pu,
5693      "change unk(src,dst): expected 0x%08x,%d,%d,%p, got 0x%08x,%d,%d,%p\n",
5694      S_OK, 2, VT_UNKNOWN, pu, hres, u.ref, V_VT(&vDst), V_UNKNOWN(&vDst));
5695
5696   /* Can't change unknown to anything else */
5697   for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
5698   {
5699     HRESULT hExpected = DISP_E_BADVARTYPE;
5700
5701     V_VT(&vSrc) = VT_UNKNOWN;
5702     V_UNKNOWN(&vSrc) = pu;
5703     VariantInit(&vDst);
5704
5705     if (vt == VT_UNKNOWN || vt == VT_DISPATCH || vt == VT_EMPTY || vt == VT_NULL)
5706       hExpected = S_OK;
5707     else
5708     {
5709       if (vt == VT_I8 || vt == VT_UI8)
5710       {
5711         if (HAVE_OLEAUT32_I8)
5712           hExpected = DISP_E_TYPEMISMATCH;
5713       }
5714       else if (vt == VT_RECORD)
5715       {
5716         if (HAVE_OLEAUT32_RECORD)
5717           hExpected = DISP_E_TYPEMISMATCH;
5718       }
5719       else if (vt  >= VT_I2 && vt <= VT_UINT && vt != (VARTYPE)15)
5720         hExpected = DISP_E_TYPEMISMATCH;
5721     }
5722     if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
5723         hExpected = DISP_E_BADVARTYPE;
5724
5725     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
5726     ok(hres == hExpected,
5727        "change unk(badvar): vt %d expected 0x%08x, got 0x%08x\n",
5728        vt, hExpected, hres);
5729   }
5730 }
5731
5732 /* IDispatch */
5733 static void test_IDispatchClear(void)
5734 {
5735   HRESULT hres;
5736   VARIANTARG v;
5737   DummyDispatch d = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
5738   IDispatch* pd = (IDispatch*)&d;
5739
5740   /* As per IUnknown */
5741
5742   V_VT(&v) = VT_DISPATCH;
5743   V_DISPATCH(&v) = pd;
5744   hres = VariantClear(&v);
5745   ok(hres == S_OK && d.ref == 0 && V_VT(&v) == VT_EMPTY,
5746      "clear dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5747      S_OK, 0, VT_EMPTY, hres, d.ref, V_VT(&v));
5748
5749   d.ref = 1;
5750   V_VT(&v) = VT_DISPATCH|VT_BYREF;
5751   V_DISPATCHREF(&v) = &pd;
5752   hres = VariantClear(&v);
5753   ok(hres == S_OK && d.ref == 1 && V_VT(&v) == VT_EMPTY,
5754      "clear dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5755      S_OK, 1, VT_EMPTY, hres, d.ref, V_VT(&v));
5756 }
5757
5758 static void test_IDispatchCopy(void)
5759 {
5760   HRESULT hres;
5761   VARIANTARG vSrc, vDst;
5762   DummyDispatch d = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
5763   IDispatch* pd = (IDispatch*)&d;
5764
5765   /* As per IUnknown */
5766
5767   VariantInit(&vDst);
5768   V_VT(&vSrc) = VT_DISPATCH;
5769   V_DISPATCH(&vSrc) = pd;
5770   hres = VariantCopy(&vDst, &vSrc);
5771   ok(hres == S_OK && d.ref == 2 && V_VT(&vDst) == VT_DISPATCH,
5772      "copy dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5773      S_OK, 2, VT_EMPTY, hres, d.ref, V_VT(&vDst));
5774
5775   VariantInit(&vDst);
5776   d.ref = 1;
5777   V_VT(&vSrc) = VT_DISPATCH|VT_BYREF;
5778   V_DISPATCHREF(&vSrc) = &pd;
5779   hres = VariantCopy(&vDst, &vSrc);
5780   ok(hres == S_OK && d.ref == 1 && V_VT(&vDst) == (VT_DISPATCH|VT_BYREF),
5781      "copy dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5782      S_OK, 1, VT_DISPATCH, hres, d.ref, V_VT(&vDst));
5783
5784   VariantInit(&vDst);
5785   d.ref = 1;
5786   V_VT(&vSrc) = VT_DISPATCH|VT_BYREF;
5787   V_DISPATCHREF(&vSrc) = &pd;
5788   hres = VariantCopyInd(&vDst, &vSrc);
5789   ok(hres == S_OK && d.ref == 2 && V_VT(&vDst) == VT_DISPATCH,
5790      "copy dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5791      S_OK, 2, VT_DISPATCH, hres, d.ref, V_VT(&vDst));
5792
5793   d.ref = 1;
5794   V_VT(&vSrc) = VT_DISPATCH|VT_BYREF;
5795   V_DISPATCHREF(&vSrc) = &pd;
5796   hres = VariantCopyInd(&vSrc, &vSrc);
5797   ok(hres == S_OK && d.ref == 2 && V_VT(&vSrc) == VT_DISPATCH,
5798      "copy dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5799      S_OK, 2, VT_DISPATCH, hres, d.ref, V_VT(&vSrc));
5800 }
5801
5802 static void test_IDispatchChangeTypeEx(void)
5803 {
5804   HRESULT hres;
5805   VARIANTARG vSrc, vDst;
5806   LCID lcid;
5807   DummyDispatch d = { &DummyDispatch_VTable, 1, VT_UI1, FALSE };
5808   IDispatch* pd = (IDispatch*)&d;
5809
5810   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5811
5812   V_VT(&vSrc) = VT_DISPATCH;
5813   V_DISPATCH(&vSrc) = pd;
5814
5815   /* =>IUnknown in place */
5816   hres = VariantChangeTypeEx(&vSrc, &vSrc, lcid, 0, VT_UNKNOWN);
5817   ok(hres == S_OK && d.ref == 1 &&
5818      V_VT(&vSrc) == VT_UNKNOWN && V_UNKNOWN(&vSrc) == (IUnknown*)pd,
5819      "change disp(src=src): expected 0x%08x,%d,%d,%p, got 0x%08x,%d,%d,%p\n",
5820      S_OK, 1, VT_UNKNOWN, pd, hres, d.ref, V_VT(&vSrc), V_UNKNOWN(&vSrc));
5821
5822   /* =>IUnknown */
5823   d.ref = 1;
5824   V_VT(&vSrc) = VT_DISPATCH;
5825   V_DISPATCH(&vSrc) = pd;
5826   VariantInit(&vDst);
5827   hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, VT_UNKNOWN);
5828   /* Note vSrc is not cleared, as final refcount is 2 */
5829   ok(hres == S_OK && d.ref == 2 &&
5830      V_VT(&vDst) == VT_UNKNOWN && V_UNKNOWN(&vDst) == (IUnknown*)pd,
5831      "change disp(src,dst): expected 0x%08x,%d,%d,%p, got 0x%08x,%d,%d,%p\n",
5832      S_OK, 2, VT_UNKNOWN, pd, hres, d.ref, V_VT(&vDst), V_UNKNOWN(&vDst));
5833
5834   /* FIXME: Verify that VARIANT_NOVALUEPROP prevents conversion to integral
5835    *        types. this requires that the xxxFromDisp tests work first.
5836    */
5837 }
5838
5839 /* VT_ERROR */
5840 static void test_ErrorChangeTypeEx(void)
5841 {
5842   HRESULT hres;
5843   VARIANTARG vSrc, vDst;
5844   VARTYPE vt;
5845   LCID lcid;
5846
5847   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5848
5849   for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
5850   {
5851     HRESULT hExpected = DISP_E_BADVARTYPE;
5852
5853     V_VT(&vSrc) = VT_ERROR;
5854     V_ERROR(&vSrc) = 1;
5855     VariantInit(&vDst);
5856     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
5857
5858     if (vt == VT_ERROR)
5859       hExpected = S_OK;
5860     else
5861     {
5862       if (vt == VT_I8 || vt == VT_UI8)
5863       {
5864         if (HAVE_OLEAUT32_I8)
5865           hExpected = DISP_E_TYPEMISMATCH;
5866       }
5867       else if (vt == VT_RECORD)
5868       {
5869         if (HAVE_OLEAUT32_RECORD)
5870           hExpected = DISP_E_TYPEMISMATCH;
5871       }
5872       else if (vt <= VT_UINT && vt != (VARTYPE)15)
5873         hExpected = DISP_E_TYPEMISMATCH;
5874     }
5875     if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
5876         hExpected = DISP_E_BADVARTYPE;
5877
5878     ok(hres == hExpected,
5879      "change err: vt %d expected 0x%08x, got 0x%08x\n", vt, hExpected, hres);
5880   }
5881 }
5882
5883 /* VT_EMPTY */
5884 static void test_EmptyChangeTypeEx(void)
5885 {
5886   HRESULT hres;
5887   VARIANTARG vSrc, vDst;
5888   VARTYPE vt;
5889   LCID lcid;
5890
5891   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5892
5893   for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
5894   {
5895     HRESULT hExpected = DISP_E_BADVARTYPE;
5896
5897     VariantInit(&vSrc);
5898     memset(&vDst, 0, sizeof(vDst));
5899     V_VT(&vDst) = VT_EMPTY;
5900
5901     if (vt == VT_I8 || vt == VT_UI8)
5902     {
5903       if (HAVE_OLEAUT32_I8)
5904         hExpected = S_OK;
5905     }
5906     else if (vt == VT_RECORD)
5907     {
5908       if (HAVE_OLEAUT32_RECORD)
5909         hExpected = DISP_E_TYPEMISMATCH;
5910     }
5911     else if (vt == VT_VARIANT || vt == VT_DISPATCH ||
5912               vt == VT_UNKNOWN || vt == VT_ERROR)
5913     {
5914       hExpected = DISP_E_TYPEMISMATCH;
5915     }
5916     else if (vt <= VT_UINT && vt != (VARTYPE)15)
5917       hExpected = S_OK;
5918
5919     if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
5920         hExpected = DISP_E_BADVARTYPE;
5921
5922     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
5923
5924     ok(hres == hExpected && (hres != S_OK || V_VT(&vDst) == vt),
5925        "change empty: vt %d expected 0x%08x, got 0x%08x, vt %d\n",
5926        vt, hExpected, hres, V_VT(&vDst));
5927     if(hres == S_OK) VariantClear(&vDst);
5928   }
5929 }
5930
5931 /* VT_NULL */
5932 static void test_NullChangeTypeEx(void)
5933 {
5934   HRESULT hres;
5935   VARIANTARG vSrc, vDst;
5936   VARTYPE vt;
5937   LCID lcid;
5938
5939   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5940
5941   for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
5942   {
5943     HRESULT hExpected = DISP_E_BADVARTYPE;
5944
5945     VariantInit(&vSrc);
5946     V_VT(&vSrc) = VT_NULL;
5947     memset(&vDst, 0, sizeof(vDst));
5948     V_VT(&vDst) = VT_EMPTY;
5949
5950     if (vt == VT_I8 || vt == VT_UI8)
5951     {
5952       if (HAVE_OLEAUT32_I8)
5953         hExpected = DISP_E_TYPEMISMATCH;
5954     }
5955     else if (vt == VT_RECORD)
5956     {
5957       if (HAVE_OLEAUT32_RECORD)
5958         hExpected = DISP_E_TYPEMISMATCH;
5959     }
5960     else if (vt == VT_NULL)
5961     {
5962       hExpected = S_OK;
5963     }
5964     else if (vt == VT_VARIANT || vt == VT_DISPATCH ||
5965               vt == VT_UNKNOWN || vt == VT_ERROR ||
5966               (vt <= VT_UINT && vt != (VARTYPE)15))
5967       hExpected = DISP_E_TYPEMISMATCH;
5968
5969     if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
5970         hExpected = DISP_E_BADVARTYPE;
5971
5972     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
5973
5974     ok(hres == hExpected && (hres != S_OK || V_VT(&vDst) == vt),
5975        "change null: vt %d expected 0x%08x, got 0x%08x, vt %d\n",
5976        vt, hExpected, hres, V_VT(&vDst));
5977   }
5978 }
5979
5980  
5981 /* VT_UINT */
5982 static void test_UintChangeTypeEx(void)
5983 {
5984   HRESULT hres;
5985   VARIANTARG vSrc, vDst;
5986   LCID lcid;
5987
5988   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5989
5990   /* Converting a VT_UINT to a VT_INT does not check for overflow */
5991   V_VT(&vDst) = VT_EMPTY;
5992   V_VT(&vSrc) = VT_UINT;
5993   V_UI4(&vSrc) = -1;
5994   hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, VT_I4);
5995   ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == -1,
5996      "change uint: Expected %d,0x%08x,%d got %d,0x%08x,%d\n",
5997      VT_I4, S_OK, -1, V_VT(&vDst), hres, V_I4(&vDst));
5998 }
5999
6000 #define NUM_CUST_ITEMS 16
6001
6002 static void test_ClearCustData(void)
6003 {
6004   CUSTDATA ci;
6005   unsigned i;
6006
6007   CHECKPTR(ClearCustData);
6008
6009   ci.cCustData = NUM_CUST_ITEMS;
6010   ci.prgCustData = CoTaskMemAlloc( sizeof(CUSTDATAITEM) * NUM_CUST_ITEMS );
6011   for (i = 0; i < NUM_CUST_ITEMS; i++)
6012     VariantInit(&ci.prgCustData[i].varValue);
6013   pClearCustData(&ci);
6014   ok(!ci.cCustData && !ci.prgCustData, "ClearCustData didn't clear fields!\n");
6015 }
6016
6017 static void test_NullByRef(void)
6018 {
6019   VARIANT v1, v2;
6020   HRESULT hRes;
6021
6022   VariantInit(&v1);
6023   VariantInit(&v2);
6024   V_VT(&v1) = VT_BYREF|VT_VARIANT;
6025   V_BYREF(&v1) = 0;
6026
6027   hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_I4);
6028   ok(hRes == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx should return DISP_E_TYPEMISMATCH\n");
6029
6030   VariantClear(&v1);
6031   V_VT(&v1) = VT_BYREF|VT_VARIANT;
6032   V_BYREF(&v1) = 0;
6033   V_VT(&v2) = VT_I4;
6034   V_I4(&v2) = 123;
6035
6036   hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_VARIANT);
6037   ok(hRes == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx should return DISP_E_TYPEMISMATCH\n");
6038   ok(V_VT(&v2) == VT_I4 && V_I4(&v2) == 123, "VariantChangeTypeEx shouldn't change pvargDest\n");
6039
6040   hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_BYREF|VT_I4);
6041   ok(hRes == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx should return DISP_E_TYPEMISMATCH\n");
6042
6043   hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, 0x3847);
6044   ok(hRes == DISP_E_BADVARTYPE, "VariantChangeTypeEx should return DISP_E_BADVARTYPE\n");
6045 }
6046
6047 /* Dst Variant should remain unchanged if VariantChangeType cannot convert */
6048 static void test_ChangeType_keep_dst(void)
6049 {
6050      VARIANT v1, v2;
6051      BSTR bstr;
6052      static const WCHAR testW[] = {'t','e','s','t',0};
6053      HRESULT hres;
6054
6055      bstr = SysAllocString(testW);
6056      VariantInit(&v1);
6057      VariantInit(&v2);
6058      V_VT(&v1) = VT_BSTR;
6059      V_BSTR(&v1) = bstr;
6060      hres = VariantChangeTypeEx(&v1, &v1, 0, 0, VT_INT);
6061      ok(hres == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx returns %08x\n", hres);
6062      ok(V_VT(&v1) == VT_BSTR && V_BSTR(&v1) == bstr, "VariantChangeTypeEx changed dst variant\n");
6063      V_VT(&v2) = VT_INT;
6064      V_INT(&v2) = 4;
6065      hres = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_INT);
6066      ok(hres == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx returns %08x\n", hres);
6067      ok(V_VT(&v2) == VT_INT && V_INT(&v2) == 4, "VariantChangeTypeEx changed dst variant\n");     
6068      SysFreeString(bstr);
6069 }
6070
6071 START_TEST(vartype)
6072 {
6073   hOleaut32 = GetModuleHandleA("oleaut32.dll");
6074
6075   trace("LCID's: System=0x%08x, User=0x%08x\n", GetSystemDefaultLCID(),
6076         GetUserDefaultLCID());
6077
6078   test_VarI1FromI2();
6079   test_VarI1FromI4();
6080   test_VarI1FromI8();
6081   test_VarI1FromUI1();
6082   test_VarI1FromUI2();
6083   test_VarI1FromUI4();
6084   test_VarI1FromUI8();
6085   test_VarI1FromBool();
6086   test_VarI1FromR4();
6087   test_VarI1FromR8();
6088   test_VarI1FromDate();
6089   test_VarI1FromCy();
6090   test_VarI1FromDec();
6091   test_VarI1FromStr();
6092   test_VarUI1FromDisp();
6093   test_VarI1Copy();
6094   test_VarI1ChangeTypeEx();
6095
6096   test_VarUI1FromI1();
6097   test_VarUI1FromI2();
6098   test_VarUI1FromI4();
6099   test_VarUI1FromI8();
6100   test_VarUI1FromUI2();
6101   test_VarUI1FromUI4();
6102   test_VarUI1FromUI8();
6103   test_VarUI1FromBool();
6104   test_VarUI1FromR4();
6105   test_VarUI1FromR8();
6106   test_VarUI1FromDate();
6107   test_VarUI1FromCy();
6108   test_VarUI1FromDec();
6109   test_VarUI1FromStr();
6110   test_VarUI1Copy();
6111   test_VarUI1ChangeTypeEx();
6112
6113   test_VarI2FromI1();
6114   test_VarI2FromI4();
6115   test_VarI2FromI8();
6116   test_VarI2FromUI1();
6117   test_VarI2FromUI2();
6118   test_VarI2FromUI4();
6119   test_VarI2FromUI8();
6120   test_VarI2FromBool();
6121   test_VarI2FromR4();
6122   test_VarI2FromR8();
6123   test_VarI2FromDate();
6124   test_VarI2FromCy();
6125   test_VarI2FromDec();
6126   test_VarI2FromStr();
6127   test_VarI2Copy();
6128   test_VarI2ChangeTypeEx();
6129
6130   test_VarUI2FromI1();
6131   test_VarUI2FromI2();
6132   test_VarUI2FromI4();
6133   test_VarUI2FromI8();
6134   test_VarUI2FromUI1();
6135   test_VarUI2FromUI4();
6136   test_VarUI2FromUI8();
6137   test_VarUI2FromBool();
6138   test_VarUI2FromR4();
6139   test_VarUI2FromR8();
6140   test_VarUI2FromDate();
6141   test_VarUI2FromCy();
6142   test_VarUI2FromDec();
6143   test_VarUI2FromStr();
6144   test_VarUI2Copy();
6145   test_VarUI2ChangeTypeEx();
6146
6147   test_VarI4FromI1();
6148   test_VarI4FromI2();
6149   test_VarI4FromI8();
6150   test_VarI4FromUI1();
6151   test_VarI4FromUI2();
6152   test_VarI4FromUI4();
6153   test_VarI4FromUI8();
6154   test_VarI4FromBool();
6155   test_VarI4FromR4();
6156   test_VarI4FromR8();
6157   test_VarI4FromDate();
6158   test_VarI4FromCy();
6159   test_VarI4FromDec();
6160   test_VarI4FromStr();
6161   test_VarI4Copy();
6162   test_VarI4ChangeTypeEx();
6163
6164   test_VarUI4FromI1();
6165   test_VarUI4FromI2();
6166   test_VarUI4FromUI2();
6167   test_VarUI4FromI8();
6168   test_VarUI4FromUI1();
6169   test_VarUI4FromI4();
6170   test_VarUI4FromUI8();
6171   test_VarUI4FromBool();
6172   test_VarUI4FromR4();
6173   test_VarUI4FromR8();
6174   test_VarUI4FromDate();
6175   test_VarUI4FromCy();
6176   test_VarUI4FromDec();
6177   test_VarUI4FromStr();
6178   test_VarUI4Copy();
6179   test_VarUI4ChangeTypeEx();
6180
6181   test_VarI8FromI1();
6182   test_VarI8FromUI1();
6183   test_VarI8FromI2();
6184   test_VarI8FromUI2();
6185   test_VarI8FromUI4();
6186   test_VarI8FromR4();
6187   test_VarI8FromR8();
6188   test_VarI8FromBool();
6189   test_VarI8FromUI8();
6190   test_VarI8FromCy();
6191   test_VarI8FromDec();
6192   test_VarI8FromDate();
6193   test_VarI8FromStr();
6194   test_VarI8Copy();
6195   test_VarI8ChangeTypeEx();
6196
6197   test_VarUI8FromI1();
6198   test_VarUI8FromUI1();
6199   test_VarUI8FromI2();
6200   test_VarUI8FromUI2();
6201   test_VarUI8FromUI4();
6202   test_VarUI8FromR4();
6203   test_VarUI8FromR8();
6204   test_VarUI8FromBool();
6205   test_VarUI8FromI8();
6206   test_VarUI8FromCy();
6207   test_VarUI8FromDec();
6208   test_VarUI8FromDate();
6209   test_VarUI8FromStr();
6210   test_VarUI8Copy();
6211   test_VarUI8ChangeTypeEx();
6212
6213   test_VarR4FromI1();
6214   test_VarR4FromUI1();
6215   test_VarR4FromI2();
6216   test_VarR4FromUI2();
6217   test_VarR4FromI4();
6218   test_VarR4FromUI4();
6219   test_VarR4FromR8();
6220   test_VarR4FromBool();
6221   test_VarR4FromCy();
6222   test_VarR4FromI8();
6223   test_VarR4FromUI8();
6224   test_VarR4FromDec();
6225   test_VarR4FromDate();
6226   test_VarR4FromStr();
6227   test_VarR4Copy();
6228   test_VarR4ChangeTypeEx();
6229
6230   test_VarR8FromI1();
6231   test_VarR8FromUI1();
6232   test_VarR8FromI2();
6233   test_VarR8FromUI2();
6234   test_VarR8FromI4();
6235   test_VarR8FromUI4();
6236   test_VarR8FromR4();
6237   test_VarR8FromBool();
6238   test_VarR8FromCy();
6239   test_VarR8FromI8();
6240   test_VarR8FromUI8();
6241   test_VarR8FromDec();
6242   test_VarR8FromDate();
6243   test_VarR8FromStr();
6244   test_VarR8Copy();
6245   test_VarR8ChangeTypeEx();
6246   test_VarR8Round();
6247
6248   test_VarDateFromI1();
6249   test_VarDateFromUI1();
6250   test_VarDateFromI2();
6251   test_VarDateFromUI2();
6252   test_VarDateFromI4();
6253   test_VarDateFromUI4();
6254   test_VarDateFromR4();
6255   test_VarDateFromR8();
6256   test_VarDateFromBool();
6257   test_VarDateFromCy();
6258   test_VarDateFromI8();
6259   test_VarDateFromUI8();
6260   test_VarDateFromDec();
6261   test_VarDateFromStr();
6262   test_VarDateCopy();
6263   test_VarDateChangeTypeEx();
6264
6265   test_VarCyFromI1();
6266   test_VarCyFromUI1();
6267   test_VarCyFromI2();
6268   test_VarCyFromUI2();
6269   test_VarCyFromI4();
6270   test_VarCyFromUI4();
6271   test_VarCyFromR4();
6272   test_VarCyFromR8();
6273   test_VarCyFromBool();
6274   test_VarCyFromI8();
6275   test_VarCyFromUI8();
6276   test_VarCyFromDec();
6277   test_VarCyFromDate();
6278
6279   test_VarCyAdd();
6280   test_VarCyMul();
6281   test_VarCySub();
6282   test_VarCyAbs();
6283   test_VarCyNeg();
6284   test_VarCyMulI4();
6285   test_VarCyMulI8();
6286   test_VarCyCmp();
6287   test_VarCyCmpR8();
6288   test_VarCyRound();
6289   test_VarCyFix();
6290   test_VarCyInt();
6291
6292   test_VarDecFromI1();
6293   test_VarDecFromI2();
6294   test_VarDecFromI4();
6295   test_VarDecFromI8();
6296   test_VarDecFromUI1();
6297   test_VarDecFromUI2();
6298   test_VarDecFromUI4();
6299   test_VarDecFromUI8();
6300   test_VarDecFromR4();
6301   test_VarDecFromR8();
6302   test_VarDecFromDate();
6303   test_VarDecFromStr();
6304   test_VarDecFromCy();
6305   test_VarDecFromDate();
6306   test_VarDecFromBool();
6307
6308   test_VarDecAbs();
6309   test_VarDecNeg();
6310   test_VarDecAdd();
6311   test_VarDecSub();
6312   test_VarDecCmp();
6313   test_VarDecMul();
6314   test_VarDecDiv();
6315
6316   test_VarBoolFromI1();
6317   test_VarBoolFromUI1();
6318   test_VarBoolFromI2();
6319   test_VarBoolFromUI2();
6320   test_VarBoolFromI4();
6321   test_VarBoolFromUI4();
6322   test_VarBoolFromR4();
6323   test_VarBoolFromR8();
6324   test_VarBoolFromCy();
6325   test_VarBoolFromI8();
6326   test_VarBoolFromUI8();
6327   test_VarBoolFromDec();
6328   test_VarBoolFromDate();
6329   test_VarBoolFromStr();
6330   test_VarBoolCopy();
6331   test_VarBoolChangeTypeEx();
6332
6333   test_VarBstrFromR4();
6334   test_VarBstrFromDate();
6335   test_VarBstrFromCy();
6336   test_VarBstrFromDec();
6337   test_VarBstrCmp();
6338   test_SysStringLen();
6339   test_SysStringByteLen();
6340   test_SysAllocString();
6341   test_SysAllocStringLen();
6342   test_SysAllocStringByteLen();
6343   test_SysReAllocString();
6344   test_SysReAllocStringLen();
6345   test_BstrCopy();
6346   test_VarBstrCat();
6347
6348   test_IUnknownClear();
6349   test_IUnknownCopy();
6350   test_IUnknownChangeTypeEx();
6351
6352   test_IDispatchClear();
6353   test_IDispatchCopy();
6354   test_IDispatchChangeTypeEx();
6355
6356   test_ErrorChangeTypeEx();
6357   test_EmptyChangeTypeEx();
6358   test_NullChangeTypeEx();
6359   test_UintChangeTypeEx();
6360
6361   test_ClearCustData();
6362
6363   test_NullByRef();
6364   test_ChangeType_keep_dst();
6365 }