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