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