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