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