oleaut32: Fix parse error when converting non-ascii string to VT_DATE.
[wine.git] / dlls / oleaut32 / tests / vartype.c
blob0f390437ed6c8812dfd47e07b1832ed9ee0554b6
1 /*
2 * Low level variant tests
4 * Copyright 2003 Jon Griffiths
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.
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.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define CONST_VTABLE
22 #define COBJMACROS
24 #include "wine/test.h"
25 #include "oleauto.h"
26 #include <math.h>
27 #include <stdio.h>
28 #include "test_tlb.h"
30 #include "initguid.h"
32 DEFINE_GUID(UUID_test_struct, 0x4029f190, 0xca4a, 0x4611, 0xae,0xb9,0x67,0x39,0x83,0xcb,0x96,0xdd);
34 /* Some Visual C++ versions choke on __uint64 to float conversions.
35 * To fix this you need either VC++ 6.0 plus the processor pack
36 * or Visual C++ >=7.0.
38 #ifndef _MSC_VER
39 # define HAS_UINT64_TO_FLOAT
40 #else
41 # if _MSC_VER >= 1300
42 # define HAS_UINT64_TO_FLOAT
43 # else
44 # include <malloc.h>
45 # if defined(_mm_free)
46 /* _mm_free is defined if the Processor Pack has been installed */
47 # define HAS_UINT64_TO_FLOAT
48 # endif
50 # endif
51 #endif
53 static HMODULE hOleaut32;
55 /* Get a conversion function ptr, return if function not available */
56 #define CHECKPTR(func) p##func = (void*)GetProcAddress(hOleaut32, #func); \
57 if (!p##func) { \
58 win_skip("function " # func " not available, not testing it\n"); return; }
60 /* Has I8/UI8 data type? */
61 static BOOL has_i8;
62 /* Has proper locale conversions? */
63 static BOOL has_locales;
65 /* Is vt a type unavailable to ancient versions? */
66 #define IS_MODERN_VTYPE(vt) (vt==VT_VARIANT||vt==VT_DECIMAL|| \
67 vt==VT_I1||vt==VT_UI2||vt==VT_UI4||vt == VT_INT||vt == VT_UINT)
69 /* Macros for converting and testing results */
70 #define CONVVARS(typ) HRESULT hres; CONV_TYPE out; typ in
72 #define _EXPECT_NO_OUT(res) ok(hres == res, "expected " #res ", got hres=0x%08x\n", hres)
73 #define EXPECT_OVERFLOW _EXPECT_NO_OUT(DISP_E_OVERFLOW)
74 #define EXPECT_MISMATCH _EXPECT_NO_OUT(DISP_E_TYPEMISMATCH)
75 #define EXPECT_BADVAR _EXPECT_NO_OUT(DISP_E_BADVARTYPE)
76 #define EXPECT_INVALID _EXPECT_NO_OUT(E_INVALIDARG)
77 #define EXPECT_LT _EXPECT_NO_OUT(VARCMP_LT)
78 #define EXPECT_GT _EXPECT_NO_OUT(VARCMP_GT)
79 #define EXPECT_EQ _EXPECT_NO_OUT(VARCMP_EQ)
81 #define _EXPECTRES(res, x, fs) \
82 ok(hres == S_OK && out == (CONV_TYPE)(x), "expected " #x ", got " fs "; hres=0x%08x\n", out, hres)
83 #define EXPECT(x) EXPECTRES(S_OK, (x))
84 #define EXPECT_DBL(x) \
85 ok(hres == S_OK && fabs(out-(x))<=1e-14*(x), "expected %16.16g, got %16.16g; hres=0x%08x\n", (x), out, hres)
87 #define CONVERT(func, val) in = val; hres = p##func(in, &out)
88 #define CONVERTRANGE(func,start,end) for (i = start; i < end; i+=1) { CONVERT(func, i); EXPECT(i); };
89 #define OVERFLOWRANGE(func,start,end) for (i = start; i < end; i+=1) { CONVERT(func, i); EXPECT_OVERFLOW; };
91 #define CY_MULTIPLIER 10000
93 #define DATE_MIN -657434
94 #define DATE_MAX 2958465
96 #define CONVERT_I8(func,hi,lo) in = hi; in = (in << 32) | lo; hres = p##func(in, &out)
98 #define CONVERT_CY(func,val) in.int64 = (LONGLONG)(val * CY_MULTIPLIER); hres = p##func(in, &out)
100 #define CONVERT_CY64(func,hi,lo) S(in).Hi = hi; S(in).Lo = lo; in.int64 *= CY_MULTIPLIER; hres = p##func(in, &out)
102 #define SETDEC(dec, scl, sgn, hi, lo) S(U(dec)).scale = (BYTE)scl; S(U(dec)).sign = (BYTE)sgn; \
103 dec.Hi32 = (ULONG)hi; U1(dec).Lo64 = (ULONG64)lo
105 #define SETDEC64(dec, scl, sgn, hi, mid, lo) S(U(dec)).scale = (BYTE)scl; S(U(dec)).sign = (BYTE)sgn; \
106 dec.Hi32 = (ULONG)hi; S1(U1(dec)).Mid32 = mid; S1(U1(dec)).Lo32 = lo;
108 #define CONVERT_DEC(func,scl,sgn,hi,lo) SETDEC(in,scl,sgn,hi,lo); hres = p##func(&in, &out)
110 #define CONVERT_DEC64(func,scl,sgn,hi,mid,lo) SETDEC64(in,scl,sgn,hi,mid,lo); hres = p##func(&in, &out)
112 #define CONVERT_BADDEC(func) \
113 CONVERT_DEC(func,29,0,0,0); EXPECT_INVALID; \
114 CONVERT_DEC(func,0,0x1,0,0); EXPECT_INVALID; \
115 CONVERT_DEC(func,0,0x40,0,0); EXPECT_INVALID; \
116 CONVERT_DEC(func,0,0x7f,0,0); EXPECT_INVALID;
118 #define CONVERT_STR(func,str,flags) \
119 SetLastError(0); \
120 if (str) MultiByteToWideChar(CP_ACP,0,str,-1,buff,sizeof(buff)/sizeof(WCHAR)); \
121 hres = p##func(str ? buff : NULL,in,flags,&out)
123 #define COPYTEST(val, vt, srcval, dstval, srcref, dstref, fs) do { \
124 HRESULT hres; VARIANTARG vSrc, vDst; CONV_TYPE in = val; \
125 VariantInit(&vSrc); VariantInit(&vDst); \
126 V_VT(&vSrc) = vt; srcval = in; \
127 hres = VariantCopy(&vDst, &vSrc); \
128 ok(hres == S_OK && V_VT(&vDst) == vt && dstval == in, \
129 "copy hres 0x%X, type %d, value (" fs ") " fs "\n", hres, V_VT(&vDst), val, dstval); \
130 V_VT(&vSrc) = vt|VT_BYREF; srcref = &in; \
131 hres = VariantCopy(&vDst, &vSrc); \
132 ok(hres == S_OK && V_VT(&vDst) == (vt|VT_BYREF) && dstref == &in, \
133 "ref hres 0x%X, type %d, ref (%p) %p\n", hres, V_VT(&vDst), &in, dstref); \
134 hres = VariantCopyInd(&vDst, &vSrc); \
135 ok(hres == S_OK && V_VT(&vDst) == vt && dstval == in, \
136 "ind hres 0x%X, type %d, value (" fs ") " fs "\n", hres, V_VT(&vDst), val, dstval); \
137 } while(0)
139 #define CHANGETYPEEX(typ) hres = VariantChangeTypeEx(&vDst, &vSrc, 0, 0, typ)
141 #define TYPETEST(typ,res,fs) CHANGETYPEEX(typ); \
142 ok(hres == S_OK && V_VT(&vDst) == typ && (CONV_TYPE)res == in, \
143 "hres=0x%X, type=%d (should be %d(" #typ ")), value=" fs " (should be " fs ")\n", \
144 hres, V_VT(&vDst), typ, (CONV_TYPE)res, in);
145 #define TYPETESTI8(typ,res) CHANGETYPEEX(typ); \
146 ok(hres == S_OK && V_VT(&vDst) == typ && (CONV_TYPE)res == in, \
147 "hres=0x%X, type=%d (should be %d(" #typ ")), value=%d (should be 1)\n", \
148 hres, V_VT(&vDst), typ, (int)res);
149 #define BADVAR(typ) CHANGETYPEEX(typ); EXPECT_BADVAR
150 #define MISMATCH(typ) CHANGETYPEEX(typ); EXPECT_MISMATCH
152 #define INITIAL_TYPETEST(vt, val, fs) \
153 VariantInit(&vSrc); \
154 VariantInit(&vDst); \
155 V_VT(&vSrc) = vt; \
156 (val(&vSrc)) = in; \
157 TYPETEST(VT_I1, V_I1(&vDst), fs); \
158 TYPETEST(VT_UI2, V_UI2(&vDst), fs); \
159 TYPETEST(VT_UI4, V_UI4(&vDst), fs); \
160 TYPETEST(VT_INT, V_INT(&vDst), fs); \
161 TYPETEST(VT_UINT, V_UINT(&vDst), fs); \
162 TYPETEST(VT_UI1, V_UI1(&vDst), fs); \
163 TYPETEST(VT_I2, V_I2(&vDst), fs); \
164 TYPETEST(VT_I4, V_I4(&vDst), fs); \
165 TYPETEST(VT_R4, V_R4(&vDst), fs); \
166 TYPETEST(VT_R8, V_R8(&vDst), fs); \
167 TYPETEST(VT_DATE, V_DATE(&vDst), fs); \
168 if (has_i8) \
170 TYPETEST(VT_I8, V_I8(&vDst), fs); \
171 TYPETEST(VT_UI8, V_UI8(&vDst), fs); \
173 #define NEGATIVE_TYPETEST(vt, val, fs, vtneg, valneg) \
174 in = -in; \
175 VariantInit(&vSrc); \
176 VariantInit(&vDst); \
177 V_VT(&vSrc) = vt; \
178 (val(&vSrc)) = in; \
179 TYPETEST(vtneg, valneg(&vDst), fs);
181 #define INITIAL_TYPETESTI8(vt, val) \
182 VariantInit(&vSrc); \
183 VariantInit(&vDst); \
184 V_VT(&vSrc) = vt; \
185 (val(&vSrc)) = in; \
186 TYPETESTI8(VT_I1, V_I1(&vDst)); \
187 TYPETESTI8(VT_UI1, V_UI1(&vDst)); \
188 TYPETESTI8(VT_I2, V_I2(&vDst)); \
189 TYPETESTI8(VT_UI2, V_UI2(&vDst)); \
190 TYPETESTI8(VT_I4, V_I4(&vDst)); \
191 TYPETESTI8(VT_UI4, V_UI4(&vDst)); \
192 TYPETESTI8(VT_INT, V_INT(&vDst)); \
193 TYPETESTI8(VT_UINT, V_UINT(&vDst)); \
194 TYPETESTI8(VT_R4, V_R4(&vDst)); \
195 TYPETESTI8(VT_R8, V_R8(&vDst)); \
196 TYPETESTI8(VT_DATE, V_DATE(&vDst)); \
197 TYPETESTI8(VT_I8, V_I8(&vDst)); \
198 TYPETESTI8(VT_UI8, V_UI8(&vDst))
200 #define COMMON_TYPETEST \
201 hres = VariantChangeTypeEx(&vDst, &vSrc, 0, 0, VT_BOOL); \
202 ok(hres == S_OK && V_VT(&vDst) == VT_BOOL && \
203 (V_BOOL(&vDst) == VARIANT_TRUE || (V_VT(&vSrc) == VT_BOOL && V_BOOL(&vDst) == 1)), \
204 "->VT_BOOL hres=0x%X, type=%d (should be VT_BOOL), value %d (should be VARIANT_TRUE)\n", \
205 hres, V_VT(&vDst), V_BOOL(&vDst)); \
206 hres = VariantChangeTypeEx(&vDst, &vSrc, 0, 0, VT_CY); \
207 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == CY_MULTIPLIER, \
208 "->VT_CY hres=0x%X, type=%d (should be VT_CY), value (%08x,%08x) (should be CY_MULTIPLIER)\n", \
209 hres, V_VT(&vDst), S(V_CY(&vDst)).Hi, S(V_CY(&vDst)).Lo); \
210 if (V_VT(&vSrc) != VT_DATE) \
212 hres = VariantChangeTypeEx(&vDst, &vSrc, 0, 0, VT_BSTR); \
213 ok(hres == S_OK && V_VT(&vDst) == VT_BSTR && \
214 V_BSTR(&vDst) && V_BSTR(&vDst)[0] == '1' && V_BSTR(&vDst)[1] == '\0', \
215 "->VT_BSTR hres=0x%X, type=%d (should be VT_BSTR), *bstr='%c'\n", \
216 hres, V_VT(&vDst), V_BSTR(&vDst) ? *V_BSTR(&vDst) : '?'); \
218 hres = VariantChangeTypeEx(&vDst, &vSrc, 0, 0, VT_DECIMAL); \
219 ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL && \
220 S(U(V_DECIMAL(&vDst))).sign == 0 && S(U(V_DECIMAL(&vDst))).scale == 0 && \
221 V_DECIMAL(&vDst).Hi32 == 0 && U1(V_DECIMAL(&vDst)).Lo64 == (ULONGLONG)in, \
222 "->VT_DECIMAL hres=0x%X, type=%d (should be VT_DECIMAL), sign=%d, scale=%d, hi=%u, lo=(%8x %8x),\n", \
223 hres, V_VT(&vDst), S(U(V_DECIMAL(&vDst))).sign, S(U(V_DECIMAL(&vDst))).scale, \
224 V_DECIMAL(&vDst).Hi32, S1(U1(V_DECIMAL(&vDst))).Mid32, S1(U1(V_DECIMAL(&vDst))).Lo32); \
225 hres = VariantChangeTypeEx(&vDst, &vSrc, 0, 0, VT_EMPTY); \
226 ok(hres == S_OK && V_VT(&vDst) == VT_EMPTY, "->VT_EMPTY hres=0x%X, type=%d (should be VT_EMPTY)\n", hres, V_VT(&vDst)); \
227 hres = VariantChangeTypeEx(&vDst, &vSrc, 0, 0, VT_NULL); \
228 ok(hres == S_OK && V_VT(&vDst) == VT_NULL, "->VT_NULL hres=0x%X, type=%d (should be VT_NULL)\n", hres, V_VT(&vDst)); \
229 MISMATCH(VT_DISPATCH); \
230 MISMATCH(VT_ERROR); \
231 MISMATCH(VT_UNKNOWN); \
232 MISMATCH(VT_VARIANT); \
233 MISMATCH(VT_RECORD); \
234 BADVAR(VT_VOID); \
235 BADVAR(VT_HRESULT); \
236 BADVAR(VT_SAFEARRAY); \
237 BADVAR(VT_CARRAY); \
238 BADVAR(VT_USERDEFINED); \
239 BADVAR(VT_LPSTR); \
240 BADVAR(VT_LPWSTR); \
241 BADVAR(VT_PTR); \
242 BADVAR(VT_INT_PTR); \
243 BADVAR(VT_UINT_PTR); \
244 BADVAR(VT_FILETIME); \
245 BADVAR(VT_BLOB); \
246 BADVAR(VT_STREAM); \
247 BADVAR(VT_STORAGE); \
248 BADVAR(VT_STREAMED_OBJECT); \
249 BADVAR(VT_STORED_OBJECT); \
250 BADVAR(VT_BLOB_OBJECT); \
251 BADVAR(VT_CF); \
252 BADVAR(VT_CLSID); \
253 BADVAR(VT_BSTR_BLOB)
255 #define DEFINE_EXPECT(func) \
256 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
258 #define SET_EXPECT(func) \
259 do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
261 #define CHECK_EXPECT2(func) \
262 do { \
263 ok(expect_ ##func, "unexpected call " #func "\n"); \
264 called_ ## func = TRUE; \
265 }while(0)
267 #define CHECK_EXPECT(func) \
268 do { \
269 CHECK_EXPECT2(func); \
270 expect_ ## func = FALSE; \
271 }while(0)
273 #define CHECK_CALLED(func) \
274 do { \
275 ok(called_ ## func, "expected " #func "\n"); \
276 expect_ ## func = called_ ## func = FALSE; \
277 }while(0)
279 DEFINE_EXPECT(dispatch_invoke);
281 /* Early versions of oleaut32 are missing many functions */
282 static HRESULT (WINAPI *pVarI1FromUI1)(BYTE,signed char*);
283 static HRESULT (WINAPI *pVarI1FromI2)(SHORT,signed char*);
284 static HRESULT (WINAPI *pVarI1FromI4)(LONG,signed char*);
285 static HRESULT (WINAPI *pVarI1FromR4)(FLOAT,signed char*);
286 static HRESULT (WINAPI *pVarI1FromR8)(double,signed char*);
287 static HRESULT (WINAPI *pVarI1FromDate)(DATE,signed char*);
288 static HRESULT (WINAPI *pVarI1FromCy)(CY,signed char*);
289 static HRESULT (WINAPI *pVarI1FromStr)(OLECHAR*,LCID,ULONG,signed char*);
290 static HRESULT (WINAPI *pVarI1FromBool)(VARIANT_BOOL,signed char*);
291 static HRESULT (WINAPI *pVarI1FromUI2)(USHORT,signed char*);
292 static HRESULT (WINAPI *pVarI1FromUI4)(ULONG,signed char*);
293 static HRESULT (WINAPI *pVarI1FromDec)(DECIMAL*,signed char*);
294 static HRESULT (WINAPI *pVarI1FromI8)(LONG64,signed char*);
295 static HRESULT (WINAPI *pVarI1FromUI8)(ULONG64,signed char*);
296 static HRESULT (WINAPI *pVarUI1FromI2)(SHORT,BYTE*);
297 static HRESULT (WINAPI *pVarUI1FromI4)(LONG,BYTE*);
298 static HRESULT (WINAPI *pVarUI1FromR4)(FLOAT,BYTE*);
299 static HRESULT (WINAPI *pVarUI1FromR8)(double,BYTE*);
300 static HRESULT (WINAPI *pVarUI1FromCy)(CY,BYTE*);
301 static HRESULT (WINAPI *pVarUI1FromDate)(DATE,BYTE*);
302 static HRESULT (WINAPI *pVarUI1FromStr)(OLECHAR*,LCID,ULONG,BYTE*);
303 static HRESULT (WINAPI *pVarUI1FromBool)(VARIANT_BOOL,BYTE*);
304 static HRESULT (WINAPI *pVarUI1FromI1)(signed char,BYTE*);
305 static HRESULT (WINAPI *pVarUI1FromUI2)(USHORT,BYTE*);
306 static HRESULT (WINAPI *pVarUI1FromUI4)(ULONG,BYTE*);
307 static HRESULT (WINAPI *pVarUI1FromDec)(DECIMAL*,BYTE*);
308 static HRESULT (WINAPI *pVarUI1FromI8)(LONG64,BYTE*);
309 static HRESULT (WINAPI *pVarUI1FromUI8)(ULONG64,BYTE*);
310 static HRESULT (WINAPI *pVarUI1FromDisp)(IDispatch*,LCID,BYTE*);
312 static HRESULT (WINAPI *pVarI2FromUI1)(BYTE,SHORT*);
313 static HRESULT (WINAPI *pVarI2FromI4)(LONG,SHORT*);
314 static HRESULT (WINAPI *pVarI2FromR4)(FLOAT,SHORT*);
315 static HRESULT (WINAPI *pVarI2FromR8)(double,SHORT*);
316 static HRESULT (WINAPI *pVarI2FromCy)(CY,SHORT*);
317 static HRESULT (WINAPI *pVarI2FromDate)(DATE,SHORT*);
318 static HRESULT (WINAPI *pVarI2FromStr)(OLECHAR*,LCID,ULONG,SHORT*);
319 static HRESULT (WINAPI *pVarI2FromBool)(VARIANT_BOOL,SHORT*);
320 static HRESULT (WINAPI *pVarI2FromI1)(signed char,SHORT*);
321 static HRESULT (WINAPI *pVarI2FromUI2)(USHORT,SHORT*);
322 static HRESULT (WINAPI *pVarI2FromUI4)(ULONG,SHORT*);
323 static HRESULT (WINAPI *pVarI2FromDec)(DECIMAL*,SHORT*);
324 static HRESULT (WINAPI *pVarI2FromI8)(LONG64,SHORT*);
325 static HRESULT (WINAPI *pVarI2FromUI8)(ULONG64,SHORT*);
326 static HRESULT (WINAPI *pVarUI2FromUI1)(BYTE,USHORT*);
327 static HRESULT (WINAPI *pVarUI2FromI2)(SHORT,USHORT*);
328 static HRESULT (WINAPI *pVarUI2FromI4)(LONG,USHORT*);
329 static HRESULT (WINAPI *pVarUI2FromR4)(FLOAT,USHORT*);
330 static HRESULT (WINAPI *pVarUI2FromR8)(double,USHORT*);
331 static HRESULT (WINAPI *pVarUI2FromDate)(DATE,USHORT*);
332 static HRESULT (WINAPI *pVarUI2FromCy)(CY,USHORT*);
333 static HRESULT (WINAPI *pVarUI2FromStr)(OLECHAR*,LCID,ULONG,USHORT*);
334 static HRESULT (WINAPI *pVarUI2FromBool)(VARIANT_BOOL,USHORT*);
335 static HRESULT (WINAPI *pVarUI2FromI1)(signed char,USHORT*);
336 static HRESULT (WINAPI *pVarUI2FromUI4)(ULONG,USHORT*);
337 static HRESULT (WINAPI *pVarUI2FromDec)(DECIMAL*,USHORT*);
338 static HRESULT (WINAPI *pVarUI2FromI8)(LONG64,USHORT*);
339 static HRESULT (WINAPI *pVarUI2FromUI8)(ULONG64,USHORT*);
341 static HRESULT (WINAPI *pVarI4FromUI1)(BYTE,LONG*);
342 static HRESULT (WINAPI *pVarI4FromI2)(SHORT,LONG*);
343 static HRESULT (WINAPI *pVarI4FromR4)(FLOAT,LONG*);
344 static HRESULT (WINAPI *pVarI4FromR8)(DOUBLE,LONG*);
345 static HRESULT (WINAPI *pVarI4FromCy)(CY,LONG*);
346 static HRESULT (WINAPI *pVarI4FromDate)(DATE,LONG*);
347 static HRESULT (WINAPI *pVarI4FromStr)(OLECHAR*,LCID,ULONG,LONG*);
348 static HRESULT (WINAPI *pVarI4FromBool)(VARIANT_BOOL,LONG*);
349 static HRESULT (WINAPI *pVarI4FromI1)(signed char,LONG*);
350 static HRESULT (WINAPI *pVarI4FromUI2)(USHORT,LONG*);
351 static HRESULT (WINAPI *pVarI4FromUI4)(ULONG,LONG*);
352 static HRESULT (WINAPI *pVarI4FromDec)(DECIMAL*,LONG*);
353 static HRESULT (WINAPI *pVarI4FromI8)(LONG64,LONG*);
354 static HRESULT (WINAPI *pVarI4FromUI8)(ULONG64,LONG*);
355 static HRESULT (WINAPI *pVarUI4FromUI1)(BYTE,ULONG*);
356 static HRESULT (WINAPI *pVarUI4FromI2)(SHORT,ULONG*);
357 static HRESULT (WINAPI *pVarUI4FromI4)(LONG,ULONG*);
358 static HRESULT (WINAPI *pVarUI4FromR4)(FLOAT,ULONG*);
359 static HRESULT (WINAPI *pVarUI4FromR8)(DOUBLE,ULONG*);
360 static HRESULT (WINAPI *pVarUI4FromDate)(DATE,ULONG*);
361 static HRESULT (WINAPI *pVarUI4FromCy)(CY,ULONG*);
362 static HRESULT (WINAPI *pVarUI4FromStr)(OLECHAR*,LCID,ULONG,ULONG*);
363 static HRESULT (WINAPI *pVarUI4FromBool)(VARIANT_BOOL,ULONG*);
364 static HRESULT (WINAPI *pVarUI4FromI1)(signed char,ULONG*);
365 static HRESULT (WINAPI *pVarUI4FromUI2)(USHORT,ULONG*);
366 static HRESULT (WINAPI *pVarUI4FromDec)(DECIMAL*,ULONG*);
367 static HRESULT (WINAPI *pVarUI4FromI8)(LONG64,ULONG*);
368 static HRESULT (WINAPI *pVarUI4FromUI8)(ULONG64,ULONG*);
370 static HRESULT (WINAPI *pVarI8FromUI1)(BYTE,LONG64*);
371 static HRESULT (WINAPI *pVarI8FromI2)(SHORT,LONG64*);
372 static HRESULT (WINAPI *pVarI8FromR4)(FLOAT,LONG64*);
373 static HRESULT (WINAPI *pVarI8FromR8)(double,LONG64*);
374 static HRESULT (WINAPI *pVarI8FromCy)(CY,LONG64*);
375 static HRESULT (WINAPI *pVarI8FromDate)(DATE,LONG64*);
376 static HRESULT (WINAPI *pVarI8FromStr)(OLECHAR*,LCID,ULONG,LONG64*);
377 static HRESULT (WINAPI *pVarI8FromBool)(VARIANT_BOOL,LONG64*);
378 static HRESULT (WINAPI *pVarI8FromI1)(signed char,LONG64*);
379 static HRESULT (WINAPI *pVarI8FromUI2)(USHORT,LONG64*);
380 static HRESULT (WINAPI *pVarI8FromUI4)(ULONG,LONG64*);
381 static HRESULT (WINAPI *pVarI8FromDec)(DECIMAL*,LONG64*);
382 static HRESULT (WINAPI *pVarI8FromUI8)(ULONG64,LONG64*);
383 static HRESULT (WINAPI *pVarUI8FromI8)(LONG64,ULONG64*);
384 static HRESULT (WINAPI *pVarUI8FromUI1)(BYTE,ULONG64*);
385 static HRESULT (WINAPI *pVarUI8FromI2)(SHORT,ULONG64*);
386 static HRESULT (WINAPI *pVarUI8FromR4)(FLOAT,ULONG64*);
387 static HRESULT (WINAPI *pVarUI8FromR8)(double,ULONG64*);
388 static HRESULT (WINAPI *pVarUI8FromCy)(CY,ULONG64*);
389 static HRESULT (WINAPI *pVarUI8FromDate)(DATE,ULONG64*);
390 static HRESULT (WINAPI *pVarUI8FromStr)(OLECHAR*,LCID,ULONG,ULONG64*);
391 static HRESULT (WINAPI *pVarUI8FromBool)(VARIANT_BOOL,ULONG64*);
392 static HRESULT (WINAPI *pVarUI8FromI1)(signed char,ULONG64*);
393 static HRESULT (WINAPI *pVarUI8FromUI2)(USHORT,ULONG64*);
394 static HRESULT (WINAPI *pVarUI8FromUI4)(ULONG,ULONG64*);
395 static HRESULT (WINAPI *pVarUI8FromDec)(DECIMAL*,ULONG64*);
397 static HRESULT (WINAPI *pVarR4FromUI1)(BYTE,float*);
398 static HRESULT (WINAPI *pVarR4FromI2)(SHORT,float*);
399 static HRESULT (WINAPI *pVarR4FromI4)(LONG,float*);
400 static HRESULT (WINAPI *pVarR4FromR8)(double,float*);
401 static HRESULT (WINAPI *pVarR4FromCy)(CY,float*);
402 static HRESULT (WINAPI *pVarR4FromDate)(DATE,float*);
403 static HRESULT (WINAPI *pVarR4FromStr)(OLECHAR*,LCID,ULONG,float*);
404 static HRESULT (WINAPI *pVarR4FromBool)(VARIANT_BOOL,float*);
405 static HRESULT (WINAPI *pVarR4FromI1)(signed char,float*);
406 static HRESULT (WINAPI *pVarR4FromUI2)(USHORT,float*);
407 static HRESULT (WINAPI *pVarR4FromUI4)(ULONG,float*);
408 static HRESULT (WINAPI *pVarR4FromDec)(DECIMAL*,float*);
409 static HRESULT (WINAPI *pVarR4FromI8)(LONG64,float*);
410 static HRESULT (WINAPI *pVarR4FromUI8)(ULONG64,float*);
412 static HRESULT (WINAPI *pVarR8FromUI1)(BYTE,double*);
413 static HRESULT (WINAPI *pVarR8FromI2)(SHORT,double*);
414 static HRESULT (WINAPI *pVarR8FromI4)(LONG,double*);
415 static HRESULT (WINAPI *pVarR8FromR4)(FLOAT,double*);
416 static HRESULT (WINAPI *pVarR8FromCy)(CY,double*);
417 static HRESULT (WINAPI *pVarR8FromDate)(DATE,double*);
418 static HRESULT (WINAPI *pVarR8FromStr)(OLECHAR*,LCID,ULONG,double*);
419 static HRESULT (WINAPI *pVarR8FromBool)(VARIANT_BOOL,double*);
420 static HRESULT (WINAPI *pVarR8FromI1)(signed char,double*);
421 static HRESULT (WINAPI *pVarR8FromUI2)(USHORT,double*);
422 static HRESULT (WINAPI *pVarR8FromUI4)(ULONG,double*);
423 static HRESULT (WINAPI *pVarR8FromDec)(DECIMAL*,double*);
424 static HRESULT (WINAPI *pVarR8FromI8)(LONG64,double*);
425 static HRESULT (WINAPI *pVarR8FromUI8)(ULONG64,double*);
426 static HRESULT (WINAPI *pVarR8Round)(double,int,double*);
428 static HRESULT (WINAPI *pVarDateFromUI1)(BYTE,DATE*);
429 static HRESULT (WINAPI *pVarDateFromI2)(SHORT,DATE*);
430 static HRESULT (WINAPI *pVarDateFromI4)(LONG,DATE*);
431 static HRESULT (WINAPI *pVarDateFromR4)(FLOAT,DATE*);
432 static HRESULT (WINAPI *pVarDateFromCy)(CY,DATE*);
433 static HRESULT (WINAPI *pVarDateFromR8)(double,DATE*);
434 static HRESULT (WINAPI *pVarDateFromStr)(OLECHAR*,LCID,ULONG,DATE*);
435 static HRESULT (WINAPI *pVarDateFromBool)(VARIANT_BOOL,DATE*);
436 static HRESULT (WINAPI *pVarDateFromI1)(signed char,DATE*);
437 static HRESULT (WINAPI *pVarDateFromUI2)(USHORT,DATE*);
438 static HRESULT (WINAPI *pVarDateFromUI4)(ULONG,DATE*);
439 static HRESULT (WINAPI *pVarDateFromDec)(DECIMAL*,DATE*);
440 static HRESULT (WINAPI *pVarDateFromI8)(LONG64,DATE*);
441 static HRESULT (WINAPI *pVarDateFromUI8)(ULONG64,DATE*);
443 static HRESULT (WINAPI *pVarCyFromUI1)(BYTE,CY*);
444 static HRESULT (WINAPI *pVarCyFromI2)(SHORT,CY*);
445 static HRESULT (WINAPI *pVarCyFromI4)(LONG,CY*);
446 static HRESULT (WINAPI *pVarCyFromR4)(FLOAT,CY*);
447 static HRESULT (WINAPI *pVarCyFromR8)(double,CY*);
448 static HRESULT (WINAPI *pVarCyFromDate)(DATE,CY*);
449 static HRESULT (WINAPI *pVarCyFromBool)(VARIANT_BOOL,CY*);
450 static HRESULT (WINAPI *pVarCyFromI1)(signed char,CY*);
451 static HRESULT (WINAPI *pVarCyFromUI2)(USHORT,CY*);
452 static HRESULT (WINAPI *pVarCyFromUI4)(ULONG,CY*);
453 static HRESULT (WINAPI *pVarCyFromDec)(DECIMAL*,CY*);
454 static HRESULT (WINAPI *pVarCyFromI8)(LONG64,CY*);
455 static HRESULT (WINAPI *pVarCyFromUI8)(ULONG64,CY*);
456 static HRESULT (WINAPI *pVarCyAdd)(const CY,const CY,CY*);
457 static HRESULT (WINAPI *pVarCyMul)(const CY,const CY,CY*);
458 static HRESULT (WINAPI *pVarCyMulI4)(const CY,LONG,CY*);
459 static HRESULT (WINAPI *pVarCySub)(const CY,const CY,CY*);
460 static HRESULT (WINAPI *pVarCyAbs)(const CY,CY*);
461 static HRESULT (WINAPI *pVarCyFix)(const CY,CY*);
462 static HRESULT (WINAPI *pVarCyInt)(const CY,CY*);
463 static HRESULT (WINAPI *pVarCyNeg)(const CY,CY*);
464 static HRESULT (WINAPI *pVarCyRound)(const CY,int,CY*);
465 static HRESULT (WINAPI *pVarCyCmp)(const CY,const CY);
466 static HRESULT (WINAPI *pVarCyCmpR8)(const CY,double);
467 static HRESULT (WINAPI *pVarCyMulI8)(const CY,LONG64,CY*);
469 static HRESULT (WINAPI *pVarDecFromUI1)(BYTE,DECIMAL*);
470 static HRESULT (WINAPI *pVarDecFromI2)(SHORT,DECIMAL*);
471 static HRESULT (WINAPI *pVarDecFromI4)(LONG,DECIMAL*);
472 static HRESULT (WINAPI *pVarDecFromI8)(LONG64,DECIMAL*);
473 static HRESULT (WINAPI *pVarDecFromR4)(FLOAT,DECIMAL*);
474 static HRESULT (WINAPI *pVarDecFromR8)(DOUBLE,DECIMAL*);
475 static HRESULT (WINAPI *pVarDecFromDate)(DATE,DECIMAL*);
476 static HRESULT (WINAPI *pVarDecFromStr)(OLECHAR*,LCID,ULONG,DECIMAL*);
477 static HRESULT (WINAPI *pVarDecFromBool)(VARIANT_BOOL,DECIMAL*);
478 static HRESULT (WINAPI *pVarDecFromI1)(signed char,DECIMAL*);
479 static HRESULT (WINAPI *pVarDecFromUI2)(USHORT,DECIMAL*);
480 static HRESULT (WINAPI *pVarDecFromUI4)(ULONG,DECIMAL*);
481 static HRESULT (WINAPI *pVarDecFromUI8)(ULONG64,DECIMAL*);
482 static HRESULT (WINAPI *pVarDecFromCy)(CY,DECIMAL*);
483 static HRESULT (WINAPI *pVarDecAbs)(const DECIMAL*,DECIMAL*);
484 static HRESULT (WINAPI *pVarDecAdd)(const DECIMAL*,const DECIMAL*,DECIMAL*);
485 static HRESULT (WINAPI *pVarDecSub)(const DECIMAL*,const DECIMAL*,DECIMAL*);
486 static HRESULT (WINAPI *pVarDecMul)(const DECIMAL*,const DECIMAL*,DECIMAL*);
487 static HRESULT (WINAPI *pVarDecDiv)(const DECIMAL*,const DECIMAL*,DECIMAL*);
488 static HRESULT (WINAPI *pVarDecCmp)(const DECIMAL*,const DECIMAL*);
489 static HRESULT (WINAPI *pVarDecCmpR8)(const DECIMAL*,double);
490 static HRESULT (WINAPI *pVarDecNeg)(const DECIMAL*,DECIMAL*);
491 static HRESULT (WINAPI *pVarDecRound)(const DECIMAL*,int,DECIMAL*);
493 static HRESULT (WINAPI *pVarBoolFromUI1)(BYTE,VARIANT_BOOL*);
494 static HRESULT (WINAPI *pVarBoolFromI2)(SHORT,VARIANT_BOOL*);
495 static HRESULT (WINAPI *pVarBoolFromI4)(LONG,VARIANT_BOOL*);
496 static HRESULT (WINAPI *pVarBoolFromR4)(FLOAT,VARIANT_BOOL*);
497 static HRESULT (WINAPI *pVarBoolFromR8)(DOUBLE,VARIANT_BOOL*);
498 static HRESULT (WINAPI *pVarBoolFromDate)(DATE,VARIANT_BOOL*);
499 static HRESULT (WINAPI *pVarBoolFromCy)(CY,VARIANT_BOOL*);
500 static HRESULT (WINAPI *pVarBoolFromStr)(OLECHAR*,LCID,ULONG,VARIANT_BOOL*);
501 static HRESULT (WINAPI *pVarBoolFromI1)(signed char,VARIANT_BOOL*);
502 static HRESULT (WINAPI *pVarBoolFromUI2)(USHORT,VARIANT_BOOL*);
503 static HRESULT (WINAPI *pVarBoolFromUI4)(ULONG,VARIANT_BOOL*);
504 static HRESULT (WINAPI *pVarBoolFromDec)(DECIMAL*,VARIANT_BOOL*);
505 static HRESULT (WINAPI *pVarBoolFromI8)(LONG64,VARIANT_BOOL*);
506 static HRESULT (WINAPI *pVarBoolFromUI8)(ULONG64,VARIANT_BOOL*);
508 static HRESULT (WINAPI *pVarBstrFromR4)(FLOAT,LCID,ULONG,BSTR*);
509 static HRESULT (WINAPI *pVarBstrFromDate)(DATE,LCID,ULONG,BSTR*);
510 static HRESULT (WINAPI *pVarBstrFromCy)(CY,LCID,ULONG,BSTR*);
511 static HRESULT (WINAPI *pVarBstrFromDec)(DECIMAL*,LCID,ULONG,BSTR*);
512 static HRESULT (WINAPI *pVarBstrCmp)(BSTR,BSTR,LCID,ULONG);
513 static HRESULT (WINAPI *pVarBstrCat)(BSTR,BSTR,BSTR*);
515 static INT (WINAPI *pSystemTimeToVariantTime)(LPSYSTEMTIME,double*);
516 static void (WINAPI *pClearCustData)(LPCUSTDATA);
518 /* Internal representation of a BSTR */
519 typedef struct tagINTERNAL_BSTR
521 DWORD dwLen;
522 OLECHAR szString[1];
523 } INTERNAL_BSTR, *LPINTERNAL_BSTR;
525 typedef struct
527 IDispatch IDispatch_iface;
528 LONG ref;
529 VARTYPE vt;
530 BOOL bFailInvoke;
531 } DummyDispatch;
533 static inline DummyDispatch *impl_from_IDispatch(IDispatch *iface)
535 return CONTAINING_RECORD(iface, DummyDispatch, IDispatch_iface);
538 static ULONG WINAPI DummyDispatch_AddRef(IDispatch *iface)
540 DummyDispatch *This = impl_from_IDispatch(iface);
541 return InterlockedIncrement(&This->ref);
544 static ULONG WINAPI DummyDispatch_Release(IDispatch *iface)
546 DummyDispatch *This = impl_from_IDispatch(iface);
547 return InterlockedDecrement(&This->ref);
550 static HRESULT WINAPI DummyDispatch_QueryInterface(IDispatch *iface,
551 REFIID riid,
552 void** ppvObject)
554 *ppvObject = NULL;
556 if (IsEqualIID(riid, &IID_IDispatch) ||
557 IsEqualIID(riid, &IID_IUnknown))
559 *ppvObject = iface;
560 IDispatch_AddRef(iface);
563 return *ppvObject ? S_OK : E_NOINTERFACE;
566 static HRESULT WINAPI DummyDispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
568 ok(0, "Unexpected call\n");
569 return E_NOTIMPL;
572 static HRESULT WINAPI DummyDispatch_GetTypeInfo(IDispatch *iface, UINT tinfo, LCID lcid, ITypeInfo **ti)
574 ok(0, "Unexpected call\n");
575 return E_NOTIMPL;
578 static HRESULT WINAPI DummyDispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *names,
579 UINT cnames, LCID lcid, DISPID *dispid)
581 ok(0, "Unexpected call\n");
582 return E_NOTIMPL;
585 static HRESULT WINAPI DummyDispatch_Invoke(IDispatch *iface,
586 DISPID dispid, REFIID riid,
587 LCID lcid, WORD wFlags,
588 DISPPARAMS *params,
589 VARIANT *res,
590 EXCEPINFO *ei,
591 UINT *arg_err)
593 DummyDispatch *This = impl_from_IDispatch(iface);
595 CHECK_EXPECT(dispatch_invoke);
597 ok(dispid == DISPID_VALUE, "got dispid %d\n", dispid);
598 ok(IsEqualIID(riid, &IID_NULL), "go riid %s\n", wine_dbgstr_guid(riid));
599 ok(wFlags == DISPATCH_PROPERTYGET, "Flags wrong\n");
601 ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
602 ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
603 ok(params->cArgs == 0, "got %d\n", params->cArgs);
604 ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
606 ok(res != NULL, "got %p\n", res);
607 ok(V_VT(res) == VT_EMPTY, "got %d\n", V_VT(res));
608 ok(ei == NULL, "got %p\n", ei);
609 ok(arg_err == NULL, "got %p\n", arg_err);
611 if (This->bFailInvoke)
612 return E_OUTOFMEMORY;
614 V_VT(res) = This->vt;
615 if (This->vt == VT_UI1)
616 V_UI1(res) = 1;
617 else
618 memset(res, 0, sizeof(*res));
620 return S_OK;
623 static const IDispatchVtbl DummyDispatch_VTable =
625 DummyDispatch_QueryInterface,
626 DummyDispatch_AddRef,
627 DummyDispatch_Release,
628 DummyDispatch_GetTypeInfoCount,
629 DummyDispatch_GetTypeInfo,
630 DummyDispatch_GetIDsOfNames,
631 DummyDispatch_Invoke
634 static void init_test_dispatch(LONG ref, VARTYPE vt, DummyDispatch *dispatch)
636 dispatch->IDispatch_iface.lpVtbl = &DummyDispatch_VTable;
637 dispatch->ref = ref;
638 dispatch->vt = vt;
639 dispatch->bFailInvoke = FALSE;
643 * VT_I1/VT_UI1
646 #undef CONV_TYPE
647 #define CONV_TYPE signed char
648 #undef EXPECTRES
649 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%d")
651 static void test_VarI1FromI2(void)
653 CONVVARS(SHORT);
654 int i;
656 CHECKPTR(VarI1FromI2);
657 OVERFLOWRANGE(VarI1FromI2, -32768, -128);
658 CONVERTRANGE(VarI1FromI2, -128, 128);
659 OVERFLOWRANGE(VarI1FromI2, 129, 32768);
662 static void test_VarI1FromI4(void)
664 CONVVARS(LONG);
665 int i;
667 CHECKPTR(VarI1FromI4);
668 CONVERT(VarI1FromI4, -129); EXPECT_OVERFLOW;
669 CONVERTRANGE(VarI1FromI4, -128, 128);
670 CONVERT(VarI1FromI4, 128); EXPECT_OVERFLOW;
673 static void test_VarI1FromI8(void)
675 CONVVARS(LONG64);
676 int i;
678 CHECKPTR(VarI1FromI8);
679 CONVERT(VarI1FromI8, -129); EXPECT_OVERFLOW;
680 CONVERTRANGE(VarI1FromI8, -127, 128);
681 CONVERT(VarI1FromI8, 128); EXPECT_OVERFLOW;
684 static void test_VarI1FromUI1(void)
686 CONVVARS(BYTE);
687 int i;
689 CHECKPTR(VarI1FromUI1);
690 CONVERTRANGE(VarI1FromUI1, 0, 127);
691 OVERFLOWRANGE(VarI1FromUI1, 128, 255);
694 static void test_VarI1FromUI2(void)
696 CONVVARS(USHORT);
697 int i;
699 CHECKPTR(VarI1FromUI2);
700 CONVERTRANGE(VarI1FromUI2, 0, 127);
701 OVERFLOWRANGE(VarI1FromUI2, 128, 32768);
704 static void test_VarI1FromUI4(void)
706 CONVVARS(ULONG);
707 int i;
709 CHECKPTR(VarI1FromUI4);
710 CONVERTRANGE(VarI1FromUI4, 0, 127);
711 CONVERT(VarI1FromUI4, 128); EXPECT_OVERFLOW;
714 static void test_VarI1FromUI8(void)
716 CONVVARS(ULONG64);
717 int i;
719 CHECKPTR(VarI1FromUI8);
720 CONVERTRANGE(VarI1FromUI8, 0, 127);
721 CONVERT(VarI1FromUI8, 128); EXPECT_OVERFLOW;
724 static void test_VarI1FromBool(void)
726 CONVVARS(VARIANT_BOOL);
727 int i;
729 CHECKPTR(VarI1FromBool);
730 /* Note that conversions from bool wrap around! */
731 CONVERT(VarI1FromBool, -129); EXPECT(127);
732 CONVERTRANGE(VarI1FromBool, -128, 128);
733 CONVERT(VarI1FromBool, 128); EXPECT(-128);
736 static void test_VarI1FromR4(void)
738 CONVVARS(FLOAT);
740 CHECKPTR(VarI1FromR4);
741 CONVERT(VarI1FromR4, -129.0f); EXPECT_OVERFLOW;
742 CONVERT(VarI1FromR4, -128.51f); EXPECT_OVERFLOW;
743 CONVERT(VarI1FromR4, -128.5f); EXPECT(-128);
744 CONVERT(VarI1FromR4, -128.0f); EXPECT(-128);
745 CONVERT(VarI1FromR4, -1.0f); EXPECT(-1);
746 CONVERT(VarI1FromR4, 0.0f); EXPECT(0);
747 CONVERT(VarI1FromR4, 1.0f); EXPECT(1);
748 CONVERT(VarI1FromR4, 127.0f); EXPECT(127);
749 CONVERT(VarI1FromR4, 127.49f); EXPECT(127);
750 CONVERT(VarI1FromR4, 127.5f); EXPECT_OVERFLOW;
751 CONVERT(VarI1FromR4, 128.0f); EXPECT_OVERFLOW;
753 CONVERT(VarI1FromR4, -1.5f); EXPECT(-2);
754 CONVERT(VarI1FromR4, -0.6f); EXPECT(-1);
755 CONVERT(VarI1FromR4, -0.5f); EXPECT(0);
756 CONVERT(VarI1FromR4, -0.4f); EXPECT(0);
757 CONVERT(VarI1FromR4, 0.4f); EXPECT(0);
758 CONVERT(VarI1FromR4, 0.5f); EXPECT(0);
759 CONVERT(VarI1FromR4, 0.6f); EXPECT(1);
760 CONVERT(VarI1FromR4, 1.5f); EXPECT(2);
763 static void test_VarI1FromR8(void)
765 CONVVARS(DOUBLE);
767 CHECKPTR(VarI1FromR8);
768 CONVERT(VarI1FromR8, -129.0); EXPECT_OVERFLOW;
769 CONVERT(VarI1FromR8, -128.51); EXPECT_OVERFLOW;
770 CONVERT(VarI1FromR8, -128.5); EXPECT(-128);
771 CONVERT(VarI1FromR8, -128.0); EXPECT(-128);
772 CONVERT(VarI1FromR8, -1.0); EXPECT(-1);
773 CONVERT(VarI1FromR8, 0.0); EXPECT(0);
774 CONVERT(VarI1FromR8, 1.0); EXPECT(1);
775 CONVERT(VarI1FromR8, 127.0); EXPECT(127);
776 CONVERT(VarI1FromR8, 127.49); EXPECT(127);
777 CONVERT(VarI1FromR8, 127.5); EXPECT_OVERFLOW;
778 CONVERT(VarI1FromR8, 128.0); EXPECT_OVERFLOW;
780 CONVERT(VarI1FromR8, -1.5); EXPECT(-2);
781 CONVERT(VarI1FromR8, -0.6); EXPECT(-1);
782 CONVERT(VarI1FromR8, -0.5); EXPECT(0);
783 CONVERT(VarI1FromR8, -0.4); EXPECT(0);
784 CONVERT(VarI1FromR8, 0.4); EXPECT(0);
785 CONVERT(VarI1FromR8, 0.5); EXPECT(0);
786 CONVERT(VarI1FromR8, 0.6); EXPECT(1);
787 CONVERT(VarI1FromR8, 1.5); EXPECT(2);
790 static void test_VarI1FromDate(void)
792 CONVVARS(DATE);
794 CHECKPTR(VarI1FromDate);
795 CONVERT(VarI1FromDate, -129.0); EXPECT_OVERFLOW;
796 CONVERT(VarI1FromDate, -128.0); EXPECT(-128);
797 CONVERT(VarI1FromDate, -1.0); EXPECT(-1);
798 CONVERT(VarI1FromDate, 0.0); EXPECT(0);
799 CONVERT(VarI1FromDate, 1.0); EXPECT(1);
800 CONVERT(VarI1FromDate, 127.0); EXPECT(127);
801 CONVERT(VarI1FromDate, 128.0); EXPECT_OVERFLOW;
803 CONVERT(VarI1FromDate, -1.5); EXPECT(-2);
804 CONVERT(VarI1FromDate, -0.6); EXPECT(-1);
805 CONVERT(VarI1FromDate, -0.5); EXPECT(0);
806 CONVERT(VarI1FromDate, -0.4); EXPECT(0);
807 CONVERT(VarI1FromDate, 0.4); EXPECT(0);
808 CONVERT(VarI1FromDate, 0.5); EXPECT(0);
809 CONVERT(VarI1FromDate, 0.6); EXPECT(1);
810 CONVERT(VarI1FromDate, 1.5); EXPECT(2);
813 static void test_VarI1FromCy(void)
815 CONVVARS(CY);
817 CHECKPTR(VarI1FromCy);
818 CONVERT_CY(VarI1FromCy,-129); EXPECT_OVERFLOW;
819 CONVERT_CY(VarI1FromCy,-128); EXPECT(128);
820 CONVERT_CY(VarI1FromCy,-1); EXPECT(-1);
821 CONVERT_CY(VarI1FromCy,0); EXPECT(0);
822 CONVERT_CY(VarI1FromCy,1); EXPECT(1);
823 CONVERT_CY(VarI1FromCy,127); EXPECT(127);
824 CONVERT_CY(VarI1FromCy,128); EXPECT_OVERFLOW;
826 CONVERT_CY(VarI1FromCy,-1.5); EXPECT(-2);
827 CONVERT_CY(VarI1FromCy,-0.6); EXPECT(-1);
828 CONVERT_CY(VarI1FromCy,-0.5); EXPECT(0);
829 CONVERT_CY(VarI1FromCy,-0.4); EXPECT(0);
830 CONVERT_CY(VarI1FromCy,0.4); EXPECT(0);
831 CONVERT_CY(VarI1FromCy,0.5); EXPECT(0);
832 CONVERT_CY(VarI1FromCy,0.6); EXPECT(1);
833 CONVERT_CY(VarI1FromCy,1.5); EXPECT(2);
836 static void test_VarI1FromDec(void)
838 CONVVARS(DECIMAL);
840 CHECKPTR(VarI1FromDec);
842 CONVERT_BADDEC(VarI1FromDec);
844 CONVERT_DEC(VarI1FromDec,0,0x80,0,129); EXPECT_OVERFLOW;
845 CONVERT_DEC(VarI1FromDec,0,0x80,0,128); EXPECT(-128);
846 CONVERT_DEC(VarI1FromDec,0,0x80,0,1); EXPECT(-1);
847 CONVERT_DEC(VarI1FromDec,0,0,0,0); EXPECT(0);
848 CONVERT_DEC(VarI1FromDec,0,0,0,1); EXPECT(1);
849 CONVERT_DEC(VarI1FromDec,0,0,0,127); EXPECT(127);
850 CONVERT_DEC(VarI1FromDec,0,0,0,128); EXPECT_OVERFLOW;
852 CONVERT_DEC(VarI1FromDec,2,0x80,0,12800); EXPECT(-128);
853 CONVERT_DEC(VarI1FromDec,2,0,0,12700); EXPECT(127);
856 static void test_VarI1FromStr(void)
858 CONVVARS(LCID);
859 OLECHAR buff[128];
861 in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
863 CHECKPTR(VarI1FromStr);
865 CONVERT_STR(VarI1FromStr,NULL, 0); EXPECT_MISMATCH;
866 CONVERT_STR(VarI1FromStr,"0", 0); EXPECT(0);
867 CONVERT_STR(VarI1FromStr,"-129", 0); EXPECT_OVERFLOW;
868 CONVERT_STR(VarI1FromStr,"-128", 0); EXPECT(-128);
869 CONVERT_STR(VarI1FromStr,"127", 0); EXPECT(127);
870 CONVERT_STR(VarI1FromStr,"128", 0); EXPECT_OVERFLOW;
872 CONVERT_STR(VarI1FromStr,"-1.5", LOCALE_NOUSEROVERRIDE); EXPECT(-2);
873 CONVERT_STR(VarI1FromStr,"-0.6", LOCALE_NOUSEROVERRIDE); EXPECT(-1);
874 CONVERT_STR(VarI1FromStr,"-0.5", LOCALE_NOUSEROVERRIDE); EXPECT(0);
875 CONVERT_STR(VarI1FromStr,"-0.4", LOCALE_NOUSEROVERRIDE); EXPECT(0);
876 CONVERT_STR(VarI1FromStr,"0.4", LOCALE_NOUSEROVERRIDE); EXPECT(0);
877 CONVERT_STR(VarI1FromStr,"0.5", LOCALE_NOUSEROVERRIDE); EXPECT(0);
878 CONVERT_STR(VarI1FromStr,"0.6", LOCALE_NOUSEROVERRIDE); EXPECT(1);
879 CONVERT_STR(VarI1FromStr,"1.5", LOCALE_NOUSEROVERRIDE); EXPECT(2);
882 static void test_VarI1Copy(void)
884 COPYTEST(1, VT_I1, V_I1(&vSrc), V_I1(&vDst), V_I1REF(&vSrc), V_I1REF(&vDst), "%d");
887 static void test_VarI1ChangeTypeEx(void)
889 HRESULT hres;
890 signed char in;
891 VARIANTARG vSrc, vDst;
893 in = 1;
895 INITIAL_TYPETEST(VT_I1, V_I1, "%d");
896 COMMON_TYPETEST;
897 NEGATIVE_TYPETEST(VT_I1, V_I1, "%d", VT_UI1, V_UI1);
900 #undef CONV_TYPE
901 #define CONV_TYPE BYTE
903 static void test_VarUI1FromI1(void)
905 CONVVARS(signed char);
906 int i;
908 CHECKPTR(VarUI1FromI1);
909 OVERFLOWRANGE(VarUI1FromI1, -128, 0);
910 CONVERTRANGE(VarUI1FromI1, 0, 128);
913 static void test_VarUI1FromI2(void)
915 CONVVARS(SHORT);
916 int i;
918 CHECKPTR(VarUI1FromI2);
919 OVERFLOWRANGE(VarUI1FromI2, -32768, 0);
920 CONVERTRANGE(VarUI1FromI2, 0, 256);
921 OVERFLOWRANGE(VarUI1FromI2, 256, 32768);
924 static void test_VarUI1FromI4(void)
926 CONVVARS(LONG);
927 int i;
929 CHECKPTR(VarUI1FromI4);
930 CONVERT(VarUI1FromI4, -1); EXPECT_OVERFLOW;
931 CONVERTRANGE(VarUI1FromI4, 0, 256);
932 CONVERT(VarUI1FromI4, 256); EXPECT_OVERFLOW;
935 static void test_VarUI1FromI8(void)
937 CONVVARS(LONG64);
938 int i;
940 CHECKPTR(VarUI1FromI8);
941 CONVERT(VarUI1FromI8, -1); EXPECT_OVERFLOW;
942 CONVERTRANGE(VarUI1FromI8, 0, 256);
943 CONVERT(VarUI1FromI8, 256); EXPECT_OVERFLOW;
946 static void test_VarUI1FromUI2(void)
948 CONVVARS(USHORT);
949 int i;
951 CHECKPTR(VarUI1FromUI2);
952 CONVERTRANGE(VarUI1FromUI2, 0, 256);
953 OVERFLOWRANGE(VarUI1FromUI2, 256, 65536);
956 static void test_VarUI1FromUI4(void)
958 CONVVARS(ULONG);
959 int i;
961 CHECKPTR(VarUI1FromUI4);
962 CONVERTRANGE(VarUI1FromUI4, 0, 256);
963 CONVERT(VarUI1FromUI4, 256); EXPECT_OVERFLOW;
966 static void test_VarUI1FromUI8(void)
968 CONVVARS(ULONG64);
969 int i;
971 CHECKPTR(VarUI1FromUI8);
972 CONVERTRANGE(VarUI1FromUI8, 0, 256);
973 CONVERT(VarUI1FromUI8, 256); EXPECT_OVERFLOW;
976 static void test_VarUI1FromBool(void)
978 CONVVARS(VARIANT_BOOL);
979 int i;
981 CHECKPTR(VarUI1FromBool);
982 /* Note that conversions from bool overflow! */
983 CONVERT(VarUI1FromBool, -1); EXPECT(255);
984 CONVERTRANGE(VarUI1FromBool, 0, 256);
985 CONVERT(VarUI1FromBool, 256); EXPECT(0);
988 static void test_VarUI1FromR4(void)
990 CONVVARS(FLOAT);
992 CHECKPTR(VarUI1FromR4);
993 CONVERT(VarUI1FromR4, -1.0f); EXPECT_OVERFLOW;
994 CONVERT(VarUI1FromR4, -0.51f); EXPECT_OVERFLOW;
995 CONVERT(VarUI1FromR4, -0.5f); EXPECT(0);
996 CONVERT(VarUI1FromR4, 0.0f); EXPECT(0);
997 CONVERT(VarUI1FromR4, 1.0f); EXPECT(1);
998 CONVERT(VarUI1FromR4, 255.0f); EXPECT(255);
999 CONVERT(VarUI1FromR4, 255.49f); EXPECT(255);
1000 CONVERT(VarUI1FromR4, 255.5f); EXPECT_OVERFLOW;
1001 CONVERT(VarUI1FromR4, 256.0f); EXPECT_OVERFLOW;
1003 /* Rounding */
1004 CONVERT(VarUI1FromR4, -1.5f); EXPECT_OVERFLOW;
1005 CONVERT(VarUI1FromR4, -0.6f); EXPECT_OVERFLOW;
1006 CONVERT(VarUI1FromR4, -0.5f); EXPECT(0);
1007 CONVERT(VarUI1FromR4, -0.4f); EXPECT(0);
1008 CONVERT(VarUI1FromR4, 0.4f); EXPECT(0);
1009 CONVERT(VarUI1FromR4, 0.5f); EXPECT(0);
1010 CONVERT(VarUI1FromR4, 0.6f); EXPECT(1);
1011 CONVERT(VarUI1FromR4, 1.5f); EXPECT(2);
1014 static void test_VarUI1FromR8(void)
1016 CONVVARS(DOUBLE);
1018 CHECKPTR(VarUI1FromR8);
1019 CONVERT(VarUI1FromR8, -1.0); EXPECT_OVERFLOW;
1020 CONVERT(VarUI1FromR8, -0.51); EXPECT_OVERFLOW;
1021 CONVERT(VarUI1FromR8, -0.5); EXPECT(0);
1022 CONVERT(VarUI1FromR8, 0.0); EXPECT(0);
1023 CONVERT(VarUI1FromR8, 1.0); EXPECT(1);
1024 CONVERT(VarUI1FromR8, 255.0); EXPECT(255);
1025 CONVERT(VarUI1FromR8, 255.49); EXPECT(255);
1026 CONVERT(VarUI1FromR8, 255.5); EXPECT_OVERFLOW;
1027 CONVERT(VarUI1FromR8, 256.0); EXPECT_OVERFLOW;
1029 /* Rounding */
1030 CONVERT(VarUI1FromR8, -1.5); EXPECT_OVERFLOW;
1031 CONVERT(VarUI1FromR8, -0.6); EXPECT_OVERFLOW;
1032 CONVERT(VarUI1FromR8, -0.5); EXPECT(0);
1033 CONVERT(VarUI1FromR8, -0.4); EXPECT(0);
1034 CONVERT(VarUI1FromR8, 0.4); EXPECT(0);
1035 CONVERT(VarUI1FromR8, 0.5); EXPECT(0);
1036 CONVERT(VarUI1FromR8, 0.6); EXPECT(1);
1037 CONVERT(VarUI1FromR8, 1.5); EXPECT(2);
1040 static void test_VarUI1FromDate(void)
1042 CONVVARS(DATE);
1044 CHECKPTR(VarUI1FromDate);
1045 CONVERT(VarUI1FromDate, -1.0); EXPECT_OVERFLOW;
1046 CONVERT(VarUI1FromDate, 0.0); EXPECT(0);
1047 CONVERT(VarUI1FromDate, 1.0); EXPECT(1);
1048 CONVERT(VarUI1FromDate, 255.0); EXPECT(255);
1049 CONVERT(VarUI1FromDate, 256.0); EXPECT_OVERFLOW;
1051 /* Rounding */
1052 CONVERT(VarUI1FromDate, -1.5); EXPECT_OVERFLOW;
1053 CONVERT(VarUI1FromDate, -0.6); EXPECT_OVERFLOW;
1054 CONVERT(VarUI1FromDate, -0.5); EXPECT(0);
1055 CONVERT(VarUI1FromDate, -0.4); EXPECT(0);
1056 CONVERT(VarUI1FromDate, 0.4); EXPECT(0);
1057 CONVERT(VarUI1FromDate, 0.5); EXPECT(0);
1058 CONVERT(VarUI1FromDate, 0.6); EXPECT(1);
1059 CONVERT(VarUI1FromDate, 1.5); EXPECT(2);
1062 static void test_VarUI1FromCy(void)
1064 CONVVARS(CY);
1066 CHECKPTR(VarUI1FromCy);
1067 CONVERT_CY(VarUI1FromCy,-1); EXPECT_OVERFLOW;
1068 CONVERT_CY(VarUI1FromCy,0); EXPECT(0);
1069 CONVERT_CY(VarUI1FromCy,1); EXPECT(1);
1070 CONVERT_CY(VarUI1FromCy,255); EXPECT(255);
1071 CONVERT_CY(VarUI1FromCy,256); EXPECT_OVERFLOW;
1073 /* Rounding */
1074 CONVERT_CY(VarUI1FromCy,-1.5); EXPECT_OVERFLOW;
1075 CONVERT_CY(VarUI1FromCy,-0.6); EXPECT_OVERFLOW;
1076 CONVERT_CY(VarUI1FromCy,-0.5); EXPECT(0);
1077 CONVERT_CY(VarUI1FromCy,-0.4); EXPECT(0);
1078 CONVERT_CY(VarUI1FromCy,0.4); EXPECT(0);
1079 CONVERT_CY(VarUI1FromCy,0.5); EXPECT(0);
1080 CONVERT_CY(VarUI1FromCy,0.6); EXPECT(1);
1081 CONVERT_CY(VarUI1FromCy,1.5); EXPECT(2);
1084 static void test_VarUI1FromDec(void)
1086 CONVVARS(DECIMAL);
1088 CHECKPTR(VarUI1FromDec);
1090 CONVERT_BADDEC(VarUI1FromDec);
1092 CONVERT_DEC(VarUI1FromDec,0,0x80,0,1); EXPECT_OVERFLOW;
1093 CONVERT_DEC(VarUI1FromDec,0,0,0,0); EXPECT(0);
1094 CONVERT_DEC(VarUI1FromDec,0,0,0,1); EXPECT(1);
1095 CONVERT_DEC(VarUI1FromDec,0,0,0,255); EXPECT(255);
1096 CONVERT_DEC(VarUI1FromDec,0,0,0,256); EXPECT_OVERFLOW;
1098 CONVERT_DEC(VarUI1FromDec,2,0x80,0,100); EXPECT_OVERFLOW;
1099 CONVERT_DEC(VarUI1FromDec,2,0,0,25500); EXPECT(255);
1102 static void test_VarUI1FromStr(void)
1104 CONVVARS(LCID);
1105 OLECHAR buff[128];
1107 in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
1109 CHECKPTR(VarUI1FromStr);
1111 CONVERT_STR(VarUI1FromStr,NULL, 0); EXPECT_MISMATCH;
1112 CONVERT_STR(VarUI1FromStr,"0", 0); EXPECT(0);
1113 CONVERT_STR(VarUI1FromStr,"-1", 0); EXPECT_OVERFLOW;
1114 CONVERT_STR(VarUI1FromStr,"255", 0); EXPECT(255);
1115 CONVERT_STR(VarUI1FromStr,"256", 0); EXPECT_OVERFLOW;
1117 /* Rounding */
1118 CONVERT_STR(VarUI1FromStr,"-1.5", LOCALE_NOUSEROVERRIDE); EXPECT_OVERFLOW;
1119 CONVERT_STR(VarUI1FromStr,"-0.6", LOCALE_NOUSEROVERRIDE); EXPECT_OVERFLOW;
1120 CONVERT_STR(VarUI1FromStr,"-0.5", LOCALE_NOUSEROVERRIDE); EXPECT(0);
1121 CONVERT_STR(VarUI1FromStr,"-0.4", LOCALE_NOUSEROVERRIDE); EXPECT(0);
1122 CONVERT_STR(VarUI1FromStr,"0.4", LOCALE_NOUSEROVERRIDE); EXPECT(0);
1123 CONVERT_STR(VarUI1FromStr,"0.5", LOCALE_NOUSEROVERRIDE); EXPECT(0);
1124 CONVERT_STR(VarUI1FromStr,"0.6", LOCALE_NOUSEROVERRIDE); EXPECT(1);
1125 CONVERT_STR(VarUI1FromStr,"1.5", LOCALE_NOUSEROVERRIDE); EXPECT(2);
1128 static void test_VarUI1FromDisp(void)
1130 DummyDispatch dispatch;
1131 CONVVARS(LCID);
1132 VARIANTARG vSrc, vDst;
1134 CHECKPTR(VarUI1FromDisp);
1136 /* FIXME
1137 * Conversions from IDispatch should get the default 'value' property
1138 * from the IDispatch pointer and return it. The following tests this.
1139 * However, I can't get these tests to return a valid value under native
1140 * oleaut32, regardless of the value returned in response to the Invoke()
1141 * call (early versions of oleaut32 call AddRef/Release, but not Invoke.
1142 * I'm obviously missing something, as these conversions work fine
1143 * when called through VBA on an object to get its default value property.
1145 * Should this test be corrected so that it works under native it should be
1146 * generalised and the remaining types checked as well.
1148 in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
1150 VariantInit(&vSrc);
1151 VariantInit(&vDst);
1153 init_test_dispatch(1, VT_UI1, &dispatch);
1154 V_VT(&vSrc) = VT_DISPATCH;
1155 V_DISPATCH(&vSrc) = &dispatch.IDispatch_iface;
1157 SET_EXPECT(dispatch_invoke);
1158 out = 10;
1159 hres = pVarUI1FromDisp(&dispatch.IDispatch_iface, in, &out);
1160 ok(broken(hres == DISP_E_BADVARTYPE) || hres == S_OK, "got 0x%08x\n", hres);
1161 ok(broken(out == 10) || out == 1, "got %d\n", out);
1162 CHECK_CALLED(dispatch_invoke);
1164 SET_EXPECT(dispatch_invoke);
1165 V_VT(&vDst) = VT_EMPTY;
1166 V_UI1(&vDst) = 0;
1167 hres = VariantChangeTypeEx(&vDst, &vSrc, in, 0, VT_UI1);
1168 ok(hres == S_OK, "got 0x%08x\n", hres);
1169 ok(V_VT(&vDst) == VT_UI1, "got %d\n", V_VT(&vDst));
1170 ok(V_UI1(&vDst) == 1, "got %d\n", V_UI1(&vDst));
1171 CHECK_CALLED(dispatch_invoke);
1173 dispatch.bFailInvoke = TRUE;
1175 SET_EXPECT(dispatch_invoke);
1176 out = 10;
1177 hres = pVarUI1FromDisp(&dispatch.IDispatch_iface, in, &out);
1178 ok(hres == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hres);
1179 ok(out == 10, "got %d\n", out);
1180 CHECK_CALLED(dispatch_invoke);
1182 SET_EXPECT(dispatch_invoke);
1183 V_VT(&vDst) = VT_EMPTY;
1184 hres = VariantChangeTypeEx(&vDst, &vSrc, in, 0, VT_UI1);
1185 ok(hres == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hres);
1186 ok(V_VT(&vDst) == VT_EMPTY, "got %d\n", V_VT(&vDst));
1187 CHECK_CALLED(dispatch_invoke);
1190 static void test_VarUI1Copy(void)
1192 COPYTEST(1, VT_UI1, V_UI1(&vSrc), V_UI1(&vDst), V_UI1REF(&vSrc), V_UI1REF(&vDst), "%d");
1195 static void test_VarUI1ChangeTypeEx(void)
1197 HRESULT hres;
1198 BYTE in;
1199 VARIANTARG vSrc, vDst;
1201 in = 1;
1203 INITIAL_TYPETEST(VT_UI1, V_UI1, "%d");
1204 COMMON_TYPETEST;
1205 NEGATIVE_TYPETEST(VT_UI1, V_UI1, "%d", VT_I1, V_I1);
1209 * VT_I2/VT_UI2
1212 #undef CONV_TYPE
1213 #define CONV_TYPE SHORT
1215 static void test_VarI2FromI1(void)
1217 CONVVARS(signed char);
1218 int i;
1220 CHECKPTR(VarI2FromI1);
1221 CONVERTRANGE(VarI2FromI1, -128, 128);
1224 static void test_VarI2FromI4(void)
1226 CONVVARS(LONG);
1227 int i;
1229 CHECKPTR(VarI2FromI4);
1230 CONVERT(VarI2FromI4, -32769); EXPECT_OVERFLOW;
1231 CONVERTRANGE(VarI2FromI4, -32768, 32768);
1232 CONVERT(VarI2FromI4, 32768); EXPECT_OVERFLOW;
1235 static void test_VarI2FromI8(void)
1237 CONVVARS(LONG64);
1239 CHECKPTR(VarI2FromI8);
1240 CONVERT(VarI2FromI8, -32769); EXPECT_OVERFLOW;
1241 CONVERT(VarI2FromI8, -32768); EXPECT(-32768);
1242 CONVERT(VarI2FromI8, 32767); EXPECT(32767);
1243 CONVERT(VarI2FromI8, 32768); EXPECT_OVERFLOW;
1246 static void test_VarI2FromUI1(void)
1248 CONVVARS(BYTE);
1249 int i;
1251 CHECKPTR(VarI2FromUI1);
1252 CONVERTRANGE(VarI2FromUI1, 0, 256);
1255 static void test_VarI2FromUI2(void)
1257 CONVVARS(USHORT);
1258 int i;
1260 CHECKPTR(VarI2FromUI2);
1261 CONVERTRANGE(VarI2FromUI2, 0, 32768);
1262 CONVERT(VarI2FromUI2, 32768); EXPECT_OVERFLOW;
1265 static void test_VarI2FromUI4(void)
1267 CONVVARS(ULONG);
1268 int i;
1270 CHECKPTR(VarI2FromUI4);
1271 CONVERTRANGE(VarI2FromUI4, 0, 32768);
1272 CONVERT(VarI2FromUI4, 32768); EXPECT_OVERFLOW;
1275 static void test_VarI2FromUI8(void)
1277 CONVVARS(ULONG64);
1278 int i;
1280 CHECKPTR(VarI2FromUI8);
1281 CONVERTRANGE(VarI2FromUI8, 0, 32768);
1282 CONVERT(VarI2FromUI8, 32768); EXPECT_OVERFLOW;
1285 static void test_VarI2FromBool(void)
1287 CONVVARS(VARIANT_BOOL);
1288 int i;
1290 CHECKPTR(VarI2FromBool);
1291 CONVERTRANGE(VarI2FromBool, -32768, 32768);
1294 static void test_VarI2FromR4(void)
1296 CONVVARS(FLOAT);
1298 CHECKPTR(VarI2FromR4);
1299 CONVERT(VarI2FromR4, -32769.0f); EXPECT_OVERFLOW;
1300 CONVERT(VarI2FromR4, -32768.51f); EXPECT_OVERFLOW;
1301 CONVERT(VarI2FromR4, -32768.5f); EXPECT(-32768);
1302 CONVERT(VarI2FromR4, -32768.0f); EXPECT(-32768);
1303 CONVERT(VarI2FromR4, -1.0f); EXPECT(-1);
1304 CONVERT(VarI2FromR4, 0.0f); EXPECT(0);
1305 CONVERT(VarI2FromR4, 1.0f); EXPECT(1);
1306 CONVERT(VarI2FromR4, 32767.0f); EXPECT(32767);
1307 CONVERT(VarI2FromR4, 32767.49f); EXPECT(32767);
1308 CONVERT(VarI2FromR4, 32767.5f); EXPECT_OVERFLOW;
1309 CONVERT(VarI2FromR4, 32768.0f); EXPECT_OVERFLOW;
1311 /* Rounding */
1312 CONVERT(VarI2FromR4, -1.5f); EXPECT(-2);
1313 CONVERT(VarI2FromR4, -0.6f); EXPECT(-1);
1314 CONVERT(VarI2FromR4, -0.5f); EXPECT(0);
1315 CONVERT(VarI2FromR4, -0.4f); EXPECT(0);
1316 CONVERT(VarI2FromR4, 0.4f); EXPECT(0);
1317 CONVERT(VarI2FromR4, 0.5f); EXPECT(0);
1318 CONVERT(VarI2FromR4, 0.6f); EXPECT(1);
1319 CONVERT(VarI2FromR4, 1.5f); EXPECT(2);
1322 static void test_VarI2FromR8(void)
1324 CONVVARS(DOUBLE);
1326 CHECKPTR(VarI2FromR8);
1327 CONVERT(VarI2FromR8, -32769.0); EXPECT_OVERFLOW;
1328 CONVERT(VarI2FromR8, -32768.51); EXPECT_OVERFLOW;
1329 CONVERT(VarI2FromR8, -32768.5); EXPECT(-32768);
1330 CONVERT(VarI2FromR8, -32768.0); EXPECT(-32768);
1331 CONVERT(VarI2FromR8, -1.0); EXPECT(-1);
1332 CONVERT(VarI2FromR8, 0.0); EXPECT(0);
1333 CONVERT(VarI2FromR8, 1.0); EXPECT(1);
1334 CONVERT(VarI2FromR8, 32767.0); EXPECT(32767);
1335 CONVERT(VarI2FromR8, 32767.49); EXPECT(32767);
1336 CONVERT(VarI2FromR8, 32767.5); EXPECT_OVERFLOW;
1337 CONVERT(VarI2FromR8, 32768.0); EXPECT_OVERFLOW;
1339 /* Rounding */
1340 CONVERT(VarI2FromR8, -1.5); EXPECT(-2);
1341 CONVERT(VarI2FromR8, -0.6); EXPECT(-1);
1342 CONVERT(VarI2FromR8, -0.5); EXPECT(0);
1343 CONVERT(VarI2FromR8, -0.4); EXPECT(0);
1344 CONVERT(VarI2FromR8, 0.4); EXPECT(0);
1345 CONVERT(VarI2FromR8, 0.5); EXPECT(0);
1346 CONVERT(VarI2FromR8, 0.6); EXPECT(1);
1347 CONVERT(VarI2FromR8, 1.5); EXPECT(2);
1350 static void test_VarI2FromDate(void)
1352 CONVVARS(DATE);
1354 CHECKPTR(VarI2FromDate);
1355 CONVERT(VarI2FromDate, -32769.0); EXPECT_OVERFLOW;
1356 CONVERT(VarI2FromDate, -32768.0); EXPECT(-32768);
1357 CONVERT(VarI2FromDate, -1.0); EXPECT(-1);
1358 CONVERT(VarI2FromDate, 0.0); EXPECT(0);
1359 CONVERT(VarI2FromDate, 1.0); EXPECT(1);
1360 CONVERT(VarI2FromDate, 32767.0); EXPECT(32767);
1361 CONVERT(VarI2FromDate, 32768.0); EXPECT_OVERFLOW;
1363 /* Rounding */
1364 CONVERT(VarI2FromDate, -1.5); EXPECT(-2);
1365 CONVERT(VarI2FromDate, -0.6); EXPECT(-1);
1366 CONVERT(VarI2FromDate, -0.5); EXPECT(0);
1367 CONVERT(VarI2FromDate, -0.4); EXPECT(0);
1368 CONVERT(VarI2FromDate, 0.4); EXPECT(0);
1369 CONVERT(VarI2FromDate, 0.5); EXPECT(0);
1370 CONVERT(VarI2FromDate, 0.6); EXPECT(1);
1371 CONVERT(VarI2FromDate, 1.5); EXPECT(2);
1374 static void test_VarI2FromCy(void)
1376 CONVVARS(CY);
1378 CHECKPTR(VarI2FromCy);
1379 CONVERT_CY(VarI2FromCy,-32769); EXPECT_OVERFLOW;
1380 CONVERT_CY(VarI2FromCy,-32768); EXPECT(32768);
1381 CONVERT_CY(VarI2FromCy,-1); EXPECT(-1);
1382 CONVERT_CY(VarI2FromCy,0); EXPECT(0);
1383 CONVERT_CY(VarI2FromCy,1); EXPECT(1);
1384 CONVERT_CY(VarI2FromCy,32767); EXPECT(32767);
1385 CONVERT_CY(VarI2FromCy,32768); EXPECT_OVERFLOW;
1387 /* Rounding */
1388 CONVERT_CY(VarI2FromCy,-1.5); EXPECT(-2);
1389 CONVERT_CY(VarI2FromCy,-0.6); EXPECT(-1);
1390 CONVERT_CY(VarI2FromCy,-0.5); EXPECT(0);
1391 CONVERT_CY(VarI2FromCy,-0.4); EXPECT(0);
1392 CONVERT_CY(VarI2FromCy,0.4); EXPECT(0);
1393 CONVERT_CY(VarI2FromCy,0.5); EXPECT(0);
1394 CONVERT_CY(VarI2FromCy,0.6); EXPECT(1);
1395 CONVERT_CY(VarI2FromCy,1.5); EXPECT(2);
1398 static void test_VarI2FromDec(void)
1400 CONVVARS(DECIMAL);
1402 CHECKPTR(VarI2FromDec);
1404 CONVERT_BADDEC(VarI2FromDec);
1406 CONVERT_DEC(VarI2FromDec,0,0x80,0,32769); EXPECT_OVERFLOW;
1407 CONVERT_DEC(VarI2FromDec,0,0x80,0,32768); EXPECT(-32768);
1408 CONVERT_DEC(VarI2FromDec,0,0x80,0,1); EXPECT(-1);
1409 CONVERT_DEC(VarI2FromDec,0,0,0,0); EXPECT(0);
1410 CONVERT_DEC(VarI2FromDec,0,0,0,1); EXPECT(1);
1411 CONVERT_DEC(VarI2FromDec,0,0,0,32767); EXPECT(32767);
1412 CONVERT_DEC(VarI2FromDec,0,0,0,32768); EXPECT_OVERFLOW;
1414 CONVERT_DEC(VarI2FromDec,2,0x80,0,3276800); EXPECT(-32768);
1415 CONVERT_DEC(VarI2FromDec,2,0,0,3276700); EXPECT(32767);
1416 CONVERT_DEC(VarI2FromDec,2,0,0,3276800); EXPECT_OVERFLOW;
1419 static void test_VarI2FromStr(void)
1421 CONVVARS(LCID);
1422 OLECHAR buff[128];
1424 in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
1426 CHECKPTR(VarI2FromStr);
1428 CONVERT_STR(VarI2FromStr,NULL, 0); EXPECT_MISMATCH;
1429 CONVERT_STR(VarI2FromStr,"0", 0); EXPECT(0);
1430 CONVERT_STR(VarI2FromStr,"-32769", 0); EXPECT_OVERFLOW;
1431 CONVERT_STR(VarI2FromStr,"-32768", 0); EXPECT(-32768);
1432 CONVERT_STR(VarI2FromStr,"32767", 0); EXPECT(32767);
1433 CONVERT_STR(VarI2FromStr,"32768", 0); EXPECT_OVERFLOW;
1435 /* Rounding */
1436 CONVERT_STR(VarI2FromStr,"-1.5", LOCALE_NOUSEROVERRIDE); EXPECT(-2);
1437 CONVERT_STR(VarI2FromStr,"-0.6", LOCALE_NOUSEROVERRIDE); EXPECT(-1);
1438 CONVERT_STR(VarI2FromStr,"-0.5", LOCALE_NOUSEROVERRIDE); EXPECT(0);
1439 CONVERT_STR(VarI2FromStr,"-0.4", LOCALE_NOUSEROVERRIDE); EXPECT(0);
1440 CONVERT_STR(VarI2FromStr,"0.4", LOCALE_NOUSEROVERRIDE); EXPECT(0);
1441 CONVERT_STR(VarI2FromStr,"0.5", LOCALE_NOUSEROVERRIDE); EXPECT(0);
1442 CONVERT_STR(VarI2FromStr,"0.6", LOCALE_NOUSEROVERRIDE); EXPECT(1);
1443 CONVERT_STR(VarI2FromStr,"1.5", LOCALE_NOUSEROVERRIDE); EXPECT(2);
1446 static void test_VarI2Copy(void)
1448 COPYTEST(1, VT_I2, V_I2(&vSrc), V_I2(&vDst), V_I2REF(&vSrc), V_I2REF(&vDst), "%d");
1451 static void test_VarI2ChangeTypeEx(void)
1453 HRESULT hres;
1454 SHORT in;
1455 VARIANTARG vSrc, vDst;
1457 in = 1;
1459 INITIAL_TYPETEST(VT_I2, V_I2, "%d");
1460 COMMON_TYPETEST;
1461 NEGATIVE_TYPETEST(VT_I2, V_I2, "%d", VT_UI2, V_UI2);
1464 #undef CONV_TYPE
1465 #define CONV_TYPE USHORT
1467 static void test_VarUI2FromI1(void)
1469 CONVVARS(signed char);
1470 int i;
1472 CHECKPTR(VarUI2FromI1);
1473 OVERFLOWRANGE(VarUI2FromI1, -128, 0);
1474 CONVERTRANGE(VarUI2FromI1, 0, 128);
1477 static void test_VarUI2FromI2(void)
1479 CONVVARS(SHORT);
1480 int i;
1482 CHECKPTR(VarUI2FromI2);
1483 OVERFLOWRANGE(VarUI2FromI2, -32768, 0);
1484 CONVERTRANGE(VarUI2FromI2, 0, 32768);
1487 static void test_VarUI2FromI4(void)
1489 CONVVARS(LONG);
1490 int i;
1492 CHECKPTR(VarUI2FromI4);
1493 OVERFLOWRANGE(VarUI2FromI4, -32768, 0);
1494 CONVERT(VarUI2FromI4, 0); EXPECT(0);
1495 CONVERT(VarUI2FromI4, 65535); EXPECT(65535);
1496 CONVERT(VarUI2FromI4, 65536); EXPECT_OVERFLOW;
1499 static void test_VarUI2FromI8(void)
1501 CONVVARS(LONG64);
1502 int i;
1504 CHECKPTR(VarUI2FromI8);
1505 OVERFLOWRANGE(VarUI2FromI8, -32768, 0);
1506 CONVERT(VarUI2FromI8, 0); EXPECT(0);
1507 CONVERT(VarUI2FromI8, 65535); EXPECT(65535);
1508 CONVERT(VarUI2FromI8, 65536); EXPECT_OVERFLOW;
1511 static void test_VarUI2FromUI1(void)
1513 CONVVARS(BYTE);
1514 int i;
1516 CHECKPTR(VarUI2FromUI1);
1517 CONVERTRANGE(VarUI2FromUI1, 0, 256);
1520 static void test_VarUI2FromUI4(void)
1522 CONVVARS(ULONG);
1524 CHECKPTR(VarUI2FromUI4);
1525 CONVERT(VarUI2FromUI4, 0); EXPECT(0);
1526 CONVERT(VarUI2FromUI4, 65535); EXPECT(65535);
1527 CONVERT(VarUI2FromUI4, 65536); EXPECT_OVERFLOW;
1530 static void test_VarUI2FromUI8(void)
1532 CONVVARS(ULONG64);
1534 CHECKPTR(VarUI2FromUI8);
1535 CONVERT(VarUI2FromUI8, 0); EXPECT(0);
1536 CONVERT(VarUI2FromUI8, 65535); EXPECT(65535);
1537 CONVERT(VarUI2FromUI8, 65536); EXPECT_OVERFLOW;
1540 static void test_VarUI2FromBool(void)
1542 CONVVARS(VARIANT_BOOL);
1543 int i;
1545 CHECKPTR(VarUI2FromBool);
1546 CONVERT(VarUI2FromBool, -1); EXPECT(65535); /* Wraps! */
1547 CONVERTRANGE(VarUI2FromBool, 0, 32768);
1550 static void test_VarUI2FromR4(void)
1552 CONVVARS(FLOAT);
1554 CHECKPTR(VarUI2FromR4);
1555 CONVERT(VarUI2FromR4, -1.0f); EXPECT_OVERFLOW;
1556 CONVERT(VarUI2FromR4, -0.51f); EXPECT_OVERFLOW;
1557 CONVERT(VarUI2FromR4, -0.5f); EXPECT(0);
1558 CONVERT(VarUI2FromR4, 0.0f); EXPECT(0);
1559 CONVERT(VarUI2FromR4, 1.0f); EXPECT(1);
1560 CONVERT(VarUI2FromR4, 65535.0f); EXPECT(65535);
1561 CONVERT(VarUI2FromR4, 65535.49f); EXPECT(65535);
1562 CONVERT(VarUI2FromR4, 65535.5f); EXPECT_OVERFLOW;
1563 CONVERT(VarUI2FromR4, 65536.0f); EXPECT_OVERFLOW;
1565 /* Rounding */
1566 CONVERT(VarUI2FromR4, -1.5f); EXPECT_OVERFLOW;
1567 CONVERT(VarUI2FromR4, -0.6f); EXPECT_OVERFLOW;
1568 CONVERT(VarUI2FromR4, -0.5f); EXPECT(0);
1569 CONVERT(VarUI2FromR4, -0.4f); EXPECT(0);
1570 CONVERT(VarUI2FromR4, 0.4f); EXPECT(0);
1571 CONVERT(VarUI2FromR4, 0.5f); EXPECT(0);
1572 CONVERT(VarUI2FromR4, 0.6f); EXPECT(1);
1573 CONVERT(VarUI2FromR4, 1.5f); EXPECT(2);
1576 static void test_VarUI2FromR8(void)
1578 CONVVARS(DOUBLE);
1580 CHECKPTR(VarUI2FromR8);
1581 CONVERT(VarUI2FromR8, -1.0); EXPECT_OVERFLOW;
1582 CONVERT(VarUI2FromR8, -0.51); EXPECT_OVERFLOW;
1583 CONVERT(VarUI2FromR8, -0.5); EXPECT(0);
1584 CONVERT(VarUI2FromR8, 0.0); EXPECT(0);
1585 CONVERT(VarUI2FromR8, 1.0); EXPECT(1);
1586 CONVERT(VarUI2FromR8, 65535.0); EXPECT(65535);
1587 CONVERT(VarUI2FromR8, 65535.49); EXPECT(65535);
1588 CONVERT(VarUI2FromR8, 65535.5); EXPECT_OVERFLOW;
1589 CONVERT(VarUI2FromR8, 65536.0); EXPECT_OVERFLOW;
1591 /* Rounding */
1592 CONVERT(VarUI2FromR8, -1.5); EXPECT_OVERFLOW;
1593 CONVERT(VarUI2FromR8, -0.6); EXPECT_OVERFLOW;
1594 CONVERT(VarUI2FromR8, -0.5); EXPECT(0);
1595 CONVERT(VarUI2FromR8, -0.4); EXPECT(0);
1596 CONVERT(VarUI2FromR8, 0.4); EXPECT(0);
1597 CONVERT(VarUI2FromR8, 0.5); EXPECT(0);
1598 CONVERT(VarUI2FromR8, 0.6); EXPECT(1);
1599 CONVERT(VarUI2FromR8, 1.5); EXPECT(2);
1602 static void test_VarUI2FromDate(void)
1604 CONVVARS(DATE);
1606 CHECKPTR(VarUI2FromDate);
1607 CONVERT(VarUI2FromDate, -1.0); EXPECT_OVERFLOW;
1608 CONVERT(VarUI2FromDate, 0.0); EXPECT(0);
1609 CONVERT(VarUI2FromDate, 1.0); EXPECT(1);
1610 CONVERT(VarUI2FromDate, 65535.0); EXPECT(65535);
1611 CONVERT(VarUI2FromDate, 65536.0); EXPECT_OVERFLOW;
1613 /* Rounding */
1614 CONVERT(VarUI2FromDate, -1.5); EXPECT_OVERFLOW;
1615 CONVERT(VarUI2FromDate, -0.6); EXPECT_OVERFLOW;
1616 CONVERT(VarUI2FromDate, -0.5); EXPECT(0);
1617 CONVERT(VarUI2FromDate, -0.4); EXPECT(0);
1618 CONVERT(VarUI2FromDate, 0.4); EXPECT(0);
1619 CONVERT(VarUI2FromDate, 0.5); EXPECT(0);
1620 CONVERT(VarUI2FromDate, 0.6); EXPECT(1);
1621 CONVERT(VarUI2FromDate, 1.5); EXPECT(2);
1624 static void test_VarUI2FromCy(void)
1626 CONVVARS(CY);
1628 CHECKPTR(VarUI2FromCy);
1629 CONVERT_CY(VarUI2FromCy,-1); EXPECT_OVERFLOW;
1630 CONVERT_CY(VarUI2FromCy,0); EXPECT(0);
1631 CONVERT_CY(VarUI2FromCy,1); EXPECT(1);
1632 CONVERT_CY(VarUI2FromCy,65535); EXPECT(65535);
1633 CONVERT_CY(VarUI2FromCy,65536); EXPECT_OVERFLOW;
1635 /* Rounding */
1636 CONVERT_CY(VarUI2FromCy,-1.5); EXPECT_OVERFLOW;
1637 CONVERT_CY(VarUI2FromCy,-0.6); EXPECT_OVERFLOW;
1638 CONVERT_CY(VarUI2FromCy,-0.5); EXPECT(0);
1639 CONVERT_CY(VarUI2FromCy,-0.4); EXPECT(0);
1640 CONVERT_CY(VarUI2FromCy,0.4); EXPECT(0);
1641 CONVERT_CY(VarUI2FromCy,0.5); EXPECT(0);
1642 CONVERT_CY(VarUI2FromCy,0.6); EXPECT(1);
1643 CONVERT_CY(VarUI2FromCy,1.5); EXPECT(2);
1646 static void test_VarUI2FromDec(void)
1648 CONVVARS(DECIMAL);
1650 CHECKPTR(VarUI2FromDec);
1652 CONVERT_BADDEC(VarUI2FromDec);
1654 CONVERT_DEC(VarUI2FromDec,0,0x80,0,1); EXPECT_OVERFLOW;
1655 CONVERT_DEC(VarUI2FromDec,0,0,0,0); EXPECT(0);
1656 CONVERT_DEC(VarUI2FromDec,0,0,0,1); EXPECT(1);
1657 CONVERT_DEC(VarUI2FromDec,0,0,0,65535); EXPECT(65535);
1658 CONVERT_DEC(VarUI2FromDec,0,0,0,65536); EXPECT_OVERFLOW;
1660 CONVERT_DEC(VarUI2FromDec,2,0x80,0,100); EXPECT_OVERFLOW;
1661 CONVERT_DEC(VarUI2FromDec,2,0,0,6553500); EXPECT(65535);
1662 CONVERT_DEC(VarUI2FromDec,2,0,0,6553600); EXPECT_OVERFLOW;
1665 static void test_VarUI2FromStr(void)
1667 CONVVARS(LCID);
1668 OLECHAR buff[128];
1670 in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
1672 CHECKPTR(VarUI2FromStr);
1674 CONVERT_STR(VarUI2FromStr,NULL, 0); EXPECT_MISMATCH;
1675 CONVERT_STR(VarUI2FromStr,"0", 0); EXPECT(0);
1676 CONVERT_STR(VarUI2FromStr,"-1", 0); EXPECT_OVERFLOW;
1677 CONVERT_STR(VarUI2FromStr,"65535", 0); EXPECT(65535);
1678 CONVERT_STR(VarUI2FromStr,"65536", 0); EXPECT_OVERFLOW;
1680 /* Rounding */
1681 CONVERT_STR(VarUI2FromStr,"-1.5", LOCALE_NOUSEROVERRIDE); EXPECT_OVERFLOW;
1682 CONVERT_STR(VarUI2FromStr,"-0.6", LOCALE_NOUSEROVERRIDE); EXPECT_OVERFLOW;
1683 CONVERT_STR(VarUI2FromStr,"-0.5", LOCALE_NOUSEROVERRIDE); EXPECT(0);
1684 CONVERT_STR(VarUI2FromStr,"-0.4", LOCALE_NOUSEROVERRIDE); EXPECT(0);
1685 CONVERT_STR(VarUI2FromStr,"0.4", LOCALE_NOUSEROVERRIDE); EXPECT(0);
1686 CONVERT_STR(VarUI2FromStr,"0.5", LOCALE_NOUSEROVERRIDE); EXPECT(0);
1687 CONVERT_STR(VarUI2FromStr,"0.6", LOCALE_NOUSEROVERRIDE); EXPECT(1);
1688 CONVERT_STR(VarUI2FromStr,"1.5", LOCALE_NOUSEROVERRIDE); EXPECT(2);
1691 static void test_VarUI2Copy(void)
1693 COPYTEST(1, VT_UI2, V_UI2(&vSrc), V_UI2(&vDst), V_UI2REF(&vSrc), V_UI2REF(&vDst), "%d");
1696 static void test_VarUI2ChangeTypeEx(void)
1698 HRESULT hres;
1699 USHORT in;
1700 VARIANTARG vSrc, vDst;
1702 in = 1;
1704 INITIAL_TYPETEST(VT_UI2, V_UI2, "%d");
1705 COMMON_TYPETEST;
1706 NEGATIVE_TYPETEST(VT_UI2, V_UI2, "%d", VT_I2, V_I2);
1710 * VT_I4/VT_UI4
1713 #undef CONV_TYPE
1714 #define CONV_TYPE LONG
1716 static void test_VarI4FromI1(void)
1718 CONVVARS(signed char);
1719 int i;
1721 CHECKPTR(VarI4FromI1);
1722 CONVERTRANGE(VarI4FromI1, -128, 128);
1725 static void test_VarI4FromI2(void)
1727 CONVVARS(SHORT);
1728 int i;
1730 CHECKPTR(VarI4FromI2);
1731 CONVERTRANGE(VarI4FromI2, -32768, 32768);
1734 static void test_VarI4FromI8(void)
1736 CONVVARS(LONG64);
1738 CHECKPTR(VarI4FromI8);
1739 CHECKPTR(VarI4FromDec);
1741 CONVERT(VarI4FromI8, -1); EXPECT(-1);
1742 CONVERT(VarI4FromI8, 0); EXPECT(0);
1743 CONVERT(VarI4FromI8, 1); EXPECT(1);
1745 CONVERT_I8(VarI4FromI8, -1, 2147483647ul); EXPECT_OVERFLOW;
1746 CONVERT_I8(VarI4FromI8, -1, 2147483648ul); EXPECT(-2147483647 - 1);
1747 CONVERT_I8(VarI4FromI8, 0, 2147483647ul); EXPECT(2147483647);
1748 CONVERT_I8(VarI4FromI8, 0, 2147483648ul); EXPECT_OVERFLOW;
1751 static void test_VarI4FromUI1(void)
1753 CONVVARS(BYTE);
1754 int i;
1756 CHECKPTR(VarI4FromUI1);
1757 CONVERTRANGE(VarI4FromUI1, 0, 256);
1760 static void test_VarI4FromUI2(void)
1762 CONVVARS(USHORT);
1763 int i;
1765 CHECKPTR(VarI4FromUI2);
1766 CONVERTRANGE(VarI4FromUI2, 0, 65536);
1769 static void test_VarI4FromUI4(void)
1771 CONVVARS(ULONG);
1773 CHECKPTR(VarI4FromUI4);
1774 CONVERT(VarI4FromUI4, 0); EXPECT(0);
1775 CONVERT(VarI4FromUI4, 1); EXPECT(1);
1776 CONVERT(VarI4FromUI4, 2147483647); EXPECT(2147483647);
1777 CONVERT(VarI4FromUI4, 2147483648ul); EXPECT_OVERFLOW;
1780 static void test_VarI4FromUI8(void)
1782 CONVVARS(ULONG64);
1784 CHECKPTR(VarI4FromUI8);
1785 CONVERT(VarI4FromUI8, 0); EXPECT(0);
1786 CONVERT(VarI4FromUI8, 1); EXPECT(1);
1787 CONVERT(VarI4FromUI8, 2147483647); EXPECT(2147483647);
1788 CONVERT(VarI4FromUI8, 2147483648ul); EXPECT_OVERFLOW;
1791 static void test_VarI4FromBool(void)
1793 CONVVARS(VARIANT_BOOL);
1794 int i;
1796 CHECKPTR(VarI4FromBool);
1797 CONVERTRANGE(VarI4FromBool, -32768, 32768);
1800 static void test_VarI4FromR4(void)
1802 CONVVARS(FLOAT);
1804 CHECKPTR(VarI4FromR4);
1806 /* min/max values are not exactly representable in a float */
1807 CONVERT(VarI4FromR4, -1.0f); EXPECT(-1);
1808 CONVERT(VarI4FromR4, 0.0f); EXPECT(0);
1809 CONVERT(VarI4FromR4, 1.0f); EXPECT(1);
1811 CONVERT(VarI4FromR4, -1.5f); EXPECT(-2);
1812 CONVERT(VarI4FromR4, -0.6f); EXPECT(-1);
1813 CONVERT(VarI4FromR4, -0.5f); EXPECT(0);
1814 CONVERT(VarI4FromR4, -0.4f); EXPECT(0);
1815 CONVERT(VarI4FromR4, 0.4f); EXPECT(0);
1816 CONVERT(VarI4FromR4, 0.5f); EXPECT(0);
1817 CONVERT(VarI4FromR4, 0.6f); EXPECT(1);
1818 CONVERT(VarI4FromR4, 1.5f); EXPECT(2);
1821 static void test_VarI4FromR8(void)
1823 CONVVARS(DOUBLE);
1825 CHECKPTR(VarI4FromR8);
1826 CONVERT(VarI4FromR8, -2147483649.0); EXPECT_OVERFLOW;
1827 CONVERT(VarI4FromR8, -2147483648.51); EXPECT_OVERFLOW;
1828 CONVERT(VarI4FromR8, -2147483648.5); EXPECT(-2147483647 - 1);
1829 CONVERT(VarI4FromR8, -2147483648.0); EXPECT(-2147483647 - 1);
1830 CONVERT(VarI4FromR8, -1.0); EXPECT(-1);
1831 CONVERT(VarI4FromR8, 0.0); EXPECT(0);
1832 CONVERT(VarI4FromR8, 1.0); EXPECT(1);
1833 CONVERT(VarI4FromR8, 2147483647.0); EXPECT(2147483647);
1834 CONVERT(VarI4FromR8, 2147483647.49); EXPECT(2147483647);
1835 CONVERT(VarI4FromR8, 2147483647.5); EXPECT_OVERFLOW;
1836 CONVERT(VarI4FromR8, 2147483648.0); EXPECT_OVERFLOW;
1838 CONVERT(VarI4FromR8, -1.5); EXPECT(-2);
1839 CONVERT(VarI4FromR8, -0.6); EXPECT(-1);
1840 CONVERT(VarI4FromR8, -0.5); EXPECT(0);
1841 CONVERT(VarI4FromR8, -0.4); EXPECT(0);
1842 CONVERT(VarI4FromR8, 0.4); EXPECT(0);
1843 CONVERT(VarI4FromR8, 0.5); EXPECT(0);
1844 CONVERT(VarI4FromR8, 0.6); EXPECT(1);
1845 CONVERT(VarI4FromR8, 1.5); EXPECT(2);
1848 static void test_VarI4FromDate(void)
1850 CONVVARS(DATE);
1852 CHECKPTR(VarI4FromDate);
1853 CONVERT(VarI4FromDate, -2147483649.0); EXPECT_OVERFLOW;
1854 CONVERT(VarI4FromDate, -2147483648.0); EXPECT(-2147483647 - 1);
1855 CONVERT(VarI4FromDate, -1.0); EXPECT(-1);
1856 CONVERT(VarI4FromDate, 0.0); EXPECT(0);
1857 CONVERT(VarI4FromDate, 1.0); EXPECT(1);
1858 CONVERT(VarI4FromDate, 2147483647.0); EXPECT(2147483647);
1859 CONVERT(VarI4FromDate, 2147483648.0); EXPECT_OVERFLOW;
1861 CONVERT(VarI4FromDate, -1.5); EXPECT(-2);
1862 CONVERT(VarI4FromDate, -0.6); EXPECT(-1);
1863 CONVERT(VarI4FromDate, -0.5); EXPECT(0);
1864 CONVERT(VarI4FromDate, -0.4); EXPECT(0);
1865 CONVERT(VarI4FromDate, 0.4); EXPECT(0);
1866 CONVERT(VarI4FromDate, 0.5); EXPECT(0);
1867 CONVERT(VarI4FromDate, 0.6); EXPECT(1);
1868 CONVERT(VarI4FromDate, 1.5); EXPECT(2);
1871 static void test_VarI4FromCy(void)
1873 CONVVARS(CY);
1875 CHECKPTR(VarI4FromCy);
1876 CONVERT_CY(VarI4FromCy,-1); EXPECT(-1);
1877 CONVERT_CY(VarI4FromCy,0); EXPECT(0);
1878 CONVERT_CY(VarI4FromCy,1); EXPECT(1);
1880 CONVERT_CY64(VarI4FromCy,-1,2147483647ul); EXPECT_OVERFLOW;
1881 CONVERT_CY64(VarI4FromCy,-1,2147483648ul); EXPECT(-2147483647 - 1);
1882 CONVERT_CY64(VarI4FromCy,0,2147483647ul); EXPECT(2147483647ul);
1883 CONVERT_CY64(VarI4FromCy,0,2147483648ul); EXPECT_OVERFLOW;
1885 CONVERT_CY(VarI4FromCy,-1.5); EXPECT(-2);
1886 CONVERT_CY(VarI4FromCy,-0.6); EXPECT(-1);
1887 CONVERT_CY(VarI4FromCy,-0.5); EXPECT(0);
1888 CONVERT_CY(VarI4FromCy,-0.4); EXPECT(0);
1889 CONVERT_CY(VarI4FromCy,0.4); EXPECT(0);
1890 CONVERT_CY(VarI4FromCy,0.5); EXPECT(0);
1891 CONVERT_CY(VarI4FromCy,0.6); EXPECT(1);
1892 CONVERT_CY(VarI4FromCy,1.5); EXPECT(2);
1895 static void test_VarI4FromDec(void)
1897 CONVVARS(DECIMAL);
1899 CHECKPTR(VarI4FromDec);
1901 CONVERT_BADDEC(VarI4FromDec);
1903 CONVERT_DEC(VarI4FromDec,0,0x80,0,1); EXPECT(-1);
1904 CONVERT_DEC(VarI4FromDec,0,0,0,0); EXPECT(0);
1905 CONVERT_DEC(VarI4FromDec,0,0,0,1); EXPECT(1);
1907 CONVERT_DEC64(VarI4FromDec,0,0x80,0,0,2147483649ul); EXPECT_OVERFLOW;
1908 CONVERT_DEC64(VarI4FromDec,0,0x80,0,0,2147483648ul); EXPECT(-2147483647 - 1);
1909 CONVERT_DEC64(VarI4FromDec,0,0,0,0,2147483647ul); EXPECT(2147483647ul);
1910 CONVERT_DEC64(VarI4FromDec,0,0,0,0,2147483648ul); EXPECT_OVERFLOW;
1912 CONVERT_DEC64(VarI4FromDec,2,0x80,0,50,100); EXPECT_OVERFLOW;
1913 CONVERT_DEC64(VarI4FromDec,2,0x80,0,50,0); EXPECT(-2147483647 - 1);
1914 CONVERT_DEC64(VarI4FromDec,2,0,0,49,4294967196ul); EXPECT(2147483647);
1915 CONVERT_DEC64(VarI4FromDec,2,0,0,50,0); EXPECT_OVERFLOW;
1918 static void test_VarI4FromStr(void)
1920 CONVVARS(LCID);
1921 OLECHAR buff[128];
1923 in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
1925 CHECKPTR(VarI4FromStr);
1927 CONVERT_STR(VarI4FromStr,NULL,0); EXPECT_MISMATCH;
1928 CONVERT_STR(VarI4FromStr,"0",0); EXPECT(0);
1929 CONVERT_STR(VarI4FromStr,"-2147483649",0); EXPECT_OVERFLOW;
1930 CONVERT_STR(VarI4FromStr,"-2147483648",0); EXPECT(-2147483647 -1);
1931 CONVERT_STR(VarI4FromStr,"2147483647",0); EXPECT(2147483647);
1932 CONVERT_STR(VarI4FromStr,"2147483648",0); EXPECT_OVERFLOW;
1934 /* Rounding */
1935 CONVERT_STR(VarI4FromStr,"-1.5",LOCALE_NOUSEROVERRIDE); EXPECT(-2);
1936 CONVERT_STR(VarI4FromStr,"-0.6",LOCALE_NOUSEROVERRIDE); EXPECT(-1);
1937 CONVERT_STR(VarI4FromStr,"-0.5",LOCALE_NOUSEROVERRIDE); EXPECT(0);
1938 CONVERT_STR(VarI4FromStr,"-0.4",LOCALE_NOUSEROVERRIDE); EXPECT(0);
1939 CONVERT_STR(VarI4FromStr,"0.4",LOCALE_NOUSEROVERRIDE); EXPECT(0);
1940 CONVERT_STR(VarI4FromStr,"0.5",LOCALE_NOUSEROVERRIDE); EXPECT(0);
1941 CONVERT_STR(VarI4FromStr,"0.6",LOCALE_NOUSEROVERRIDE); EXPECT(1);
1942 CONVERT_STR(VarI4FromStr,"1.5",LOCALE_NOUSEROVERRIDE); EXPECT(2);
1945 static void test_VarI4Copy(void)
1947 COPYTEST(1, VT_I4, V_I4(&vSrc), V_I4(&vDst), V_I4REF(&vSrc), V_I4REF(&vDst), "%d");
1950 static void test_VarI4ChangeTypeEx(void)
1952 HRESULT hres;
1953 LONG in;
1954 VARIANTARG vSrc, vDst;
1956 in = 1;
1958 INITIAL_TYPETEST(VT_I4, V_I4, "%d");
1959 COMMON_TYPETEST;
1960 NEGATIVE_TYPETEST(VT_I4, V_I4, "%d", VT_UI4, V_UI4);
1963 #undef CONV_TYPE
1964 #define CONV_TYPE ULONG
1965 #undef EXPECTRES
1966 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%u")
1968 static void test_VarUI4FromI1(void)
1970 CONVVARS(signed char);
1971 int i;
1973 CHECKPTR(VarUI4FromI1);
1974 OVERFLOWRANGE(VarUI4FromI1, -127, 0);
1975 CONVERTRANGE(VarUI4FromI1, 0, 128);
1978 static void test_VarUI4FromI2(void)
1980 CONVVARS(SHORT);
1981 int i;
1983 CHECKPTR(VarUI4FromI2);
1984 OVERFLOWRANGE(VarUI4FromI2, -32768, 0);
1985 CONVERTRANGE(VarUI4FromI2, 0, 32768);
1988 static void test_VarUI4FromUI2(void)
1990 CONVVARS(USHORT);
1991 int i;
1993 CHECKPTR(VarUI4FromUI2);
1994 CONVERTRANGE(VarUI4FromUI2, 0, 65536);
1997 static void test_VarUI4FromI8(void)
1999 CONVVARS(LONG64);
2001 CHECKPTR(VarUI4FromI8);
2002 CONVERT(VarUI4FromI8, -1); EXPECT_OVERFLOW;
2003 CONVERT(VarUI4FromI8, 0); EXPECT(0);
2004 CONVERT(VarUI4FromI8, 1); EXPECT(1);
2005 CONVERT(VarUI4FromI8, 4294967295ul); EXPECT(4294967295ul);
2006 CONVERT_I8(VarUI4FromI8, 1, 0); EXPECT_OVERFLOW;
2009 static void test_VarUI4FromUI1(void)
2011 CONVVARS(BYTE);
2012 int i;
2014 CHECKPTR(VarUI4FromUI1);
2015 CONVERTRANGE(VarUI4FromUI1, 0, 256);
2018 static void test_VarUI4FromI4(void)
2020 CONVVARS(int);
2022 CHECKPTR(VarUI4FromI4);
2023 CONVERT(VarUI4FromI4, -1); EXPECT_OVERFLOW;
2024 CONVERT(VarUI4FromI4, 0); EXPECT(0);
2025 CONVERT(VarUI4FromI4, 1); EXPECT(1);
2026 CONVERT(VarUI4FromI4, 2147483647); EXPECT(2147483647);
2029 static void test_VarUI4FromUI8(void)
2031 CONVVARS(ULONG64);
2033 CHECKPTR(VarUI4FromUI8);
2034 CONVERT(VarUI4FromUI8, 0); EXPECT(0);
2035 CONVERT(VarUI4FromUI8, 1); EXPECT(1);
2036 CONVERT(VarUI4FromI8, 4294967295ul); EXPECT(4294967295ul);
2037 CONVERT_I8(VarUI4FromI8, 1, 0); EXPECT_OVERFLOW;
2040 static void test_VarUI4FromBool(void)
2042 CONVVARS(VARIANT_BOOL);
2043 int i;
2045 CHECKPTR(VarUI4FromBool);
2046 CONVERTRANGE(VarUI4FromBool, -32768, 32768);
2049 static void test_VarUI4FromR4(void)
2051 CONVVARS(FLOAT);
2053 CHECKPTR(VarUI4FromR4);
2054 /* We can't test max values as they are not exactly representable in a float */
2055 CONVERT(VarUI4FromR4, -1.0f); EXPECT_OVERFLOW;
2056 CONVERT(VarUI4FromR4, -0.51f); EXPECT_OVERFLOW;
2057 CONVERT(VarUI4FromR4, -0.5f); EXPECT(0);
2058 CONVERT(VarUI4FromR4, 0.0f); EXPECT(0);
2059 CONVERT(VarUI4FromR4, 1.0f); EXPECT(1);
2061 CONVERT(VarUI4FromR4, -1.5f); EXPECT_OVERFLOW;
2062 CONVERT(VarUI4FromR4, -0.6f); EXPECT_OVERFLOW;
2063 CONVERT(VarUI4FromR4, -0.5f); EXPECT(0);
2064 CONVERT(VarUI4FromR4, -0.4f); EXPECT(0);
2065 CONVERT(VarUI4FromR4, 0.4f); EXPECT(0);
2066 CONVERT(VarUI4FromR4, 0.5f); EXPECT(0);
2067 CONVERT(VarUI4FromR4, 0.6f); EXPECT(1);
2068 CONVERT(VarUI4FromR4, 1.5f); EXPECT(2);
2072 static void test_VarUI4FromR8(void)
2074 CONVVARS(DOUBLE);
2076 CHECKPTR(VarUI4FromR8);
2077 CONVERT(VarUI4FromR8, -1.0); EXPECT_OVERFLOW;
2078 CONVERT(VarUI4FromR4, -0.51f); EXPECT_OVERFLOW;
2079 CONVERT(VarUI4FromR4, -0.5f); EXPECT(0);
2080 CONVERT(VarUI4FromR8, 0.0); EXPECT(0);
2081 CONVERT(VarUI4FromR8, 1.0); EXPECT(1);
2082 CONVERT(VarUI4FromR8, 4294967295.0); EXPECT(4294967295ul);
2083 CONVERT(VarUI4FromR8, 4294967295.49); EXPECT(4294967295ul);
2084 CONVERT(VarUI4FromR8, 4294967295.5); EXPECT_OVERFLOW;
2085 CONVERT(VarUI4FromR8, 4294967296.0); EXPECT_OVERFLOW;
2087 CONVERT(VarUI4FromR8, -1.5); EXPECT_OVERFLOW;
2088 CONVERT(VarUI4FromR8, -0.6); EXPECT_OVERFLOW;
2089 CONVERT(VarUI4FromR8, -0.5); EXPECT(0);
2090 CONVERT(VarUI4FromR8, -0.4); EXPECT(0);
2091 CONVERT(VarUI4FromR8, 0.4); EXPECT(0);
2092 CONVERT(VarUI4FromR8, 0.5); EXPECT(0);
2093 CONVERT(VarUI4FromR8, 0.6); EXPECT(1);
2094 CONVERT(VarUI4FromR8, 1.5); EXPECT(2);
2097 static void test_VarUI4FromDate(void)
2099 CONVVARS(DOUBLE);
2101 CHECKPTR(VarUI4FromDate);
2102 CONVERT(VarUI4FromDate, -1.0); EXPECT_OVERFLOW;
2103 CONVERT(VarUI4FromDate, 0.0); EXPECT(0);
2104 CONVERT(VarUI4FromDate, 1.0); EXPECT(1);
2105 CONVERT(VarUI4FromDate, 4294967295.0); EXPECT(4294967295ul);
2106 CONVERT(VarUI4FromDate, 4294967296.0); EXPECT_OVERFLOW;
2108 CONVERT(VarUI4FromDate, -1.5); EXPECT_OVERFLOW;
2109 CONVERT(VarUI4FromDate, -0.6); EXPECT_OVERFLOW;
2110 CONVERT(VarUI4FromDate, -0.5); EXPECT(0);
2111 CONVERT(VarUI4FromDate, -0.4); EXPECT(0);
2112 CONVERT(VarUI4FromDate, 0.4); EXPECT(0);
2113 CONVERT(VarUI4FromDate, 0.5); EXPECT(0);
2114 CONVERT(VarUI4FromDate, 0.6); EXPECT(1);
2115 CONVERT(VarUI4FromDate, 1.5); EXPECT(2);
2118 static void test_VarUI4FromCy(void)
2120 CONVVARS(CY);
2122 CHECKPTR(VarUI4FromCy);
2123 CONVERT_CY(VarUI4FromCy,-1); EXPECT_OVERFLOW;
2124 CONVERT_CY(VarUI4FromCy,0); EXPECT(0);
2125 CONVERT_CY(VarUI4FromCy,1); EXPECT(1);
2126 CONVERT_CY64(VarUI4FromCy,0,4294967295ul); EXPECT(4294967295ul);
2127 CONVERT_CY64(VarUI4FromCy,1,0); EXPECT_OVERFLOW;
2129 CONVERT_CY(VarUI4FromCy,-1.5); EXPECT_OVERFLOW;
2130 CONVERT_CY(VarUI4FromCy,-0.6); EXPECT_OVERFLOW;
2131 CONVERT_CY(VarUI4FromCy,-0.5); EXPECT(0);
2132 CONVERT_CY(VarUI4FromCy,-0.4); EXPECT(0);
2133 CONVERT_CY(VarUI4FromCy,0.4); EXPECT(0);
2134 CONVERT_CY(VarUI4FromCy,0.5); EXPECT(0);
2135 CONVERT_CY(VarUI4FromCy,0.6); EXPECT(1);
2136 CONVERT_CY(VarUI4FromCy,1.5); EXPECT(2);
2139 static void test_VarUI4FromDec(void)
2141 CONVVARS(DECIMAL);
2143 CHECKPTR(VarUI4FromDec);
2145 CONVERT_BADDEC(VarUI4FromDec);
2147 CONVERT_DEC(VarUI4FromDec,0,0x80,0,1); EXPECT_OVERFLOW;
2148 CONVERT_DEC(VarUI4FromDec,0,0,0,0); EXPECT(0);
2149 CONVERT_DEC(VarUI4FromDec,0,0,0,1); EXPECT(1);
2150 CONVERT_DEC64(VarUI4FromDec,0,0,0,0,4294967295ul); EXPECT(4294967295ul);
2151 CONVERT_DEC64(VarUI4FromDec,0,0,0,1,0); EXPECT_OVERFLOW;
2153 CONVERT_DEC64(VarUI4FromDec,2,0,0,99,4294967196ul); EXPECT(4294967295ul);
2154 CONVERT_DEC64(VarUI4FromDec,2,0,0,100,0); EXPECT_OVERFLOW;
2157 static void test_VarUI4FromStr(void)
2159 CONVVARS(LCID);
2160 OLECHAR buff[128];
2162 in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
2164 CHECKPTR(VarUI4FromStr);
2166 CONVERT_STR(VarUI4FromStr,NULL,0); EXPECT_MISMATCH;
2167 CONVERT_STR(VarUI4FromStr,"-1",0); EXPECT_OVERFLOW;
2168 CONVERT_STR(VarUI4FromStr,"0",0); EXPECT(0);
2169 CONVERT_STR(VarUI4FromStr,"4294967295",0); EXPECT(4294967295ul);
2170 CONVERT_STR(VarUI4FromStr,"4294967296",0); EXPECT_OVERFLOW;
2172 /* Rounding */
2173 CONVERT_STR(VarUI4FromStr,"-1.5",LOCALE_NOUSEROVERRIDE); EXPECT_OVERFLOW;
2174 CONVERT_STR(VarUI4FromStr,"-0.6",LOCALE_NOUSEROVERRIDE); EXPECT_OVERFLOW;
2175 CONVERT_STR(VarUI4FromStr,"-0.5",LOCALE_NOUSEROVERRIDE); EXPECT(0);
2176 CONVERT_STR(VarUI4FromStr,"-0.4",LOCALE_NOUSEROVERRIDE); EXPECT(0);
2177 CONVERT_STR(VarUI4FromStr,"0.4",LOCALE_NOUSEROVERRIDE); EXPECT(0);
2178 CONVERT_STR(VarUI4FromStr,"0.5",LOCALE_NOUSEROVERRIDE); EXPECT(0);
2179 CONVERT_STR(VarUI4FromStr,"0.6",LOCALE_NOUSEROVERRIDE); EXPECT(1);
2180 CONVERT_STR(VarUI4FromStr,"1.5",LOCALE_NOUSEROVERRIDE); EXPECT(2);
2183 static void test_VarUI4Copy(void)
2185 COPYTEST(1u, VT_UI4, V_UI4(&vSrc), V_UI4(&vDst), V_UI4REF(&vSrc), V_UI4REF(&vDst), "%u");
2188 static void test_VarUI4ChangeTypeEx(void)
2190 HRESULT hres;
2191 ULONG in;
2192 VARIANTARG vSrc, vDst;
2194 in = 1;
2196 INITIAL_TYPETEST(VT_UI4, V_UI4, "%u");
2197 COMMON_TYPETEST;
2198 NEGATIVE_TYPETEST(VT_UI4, V_UI4, "%u", VT_I4, V_I4);
2202 * VT_I8/VT_UI8
2205 #undef CONV_TYPE
2206 #define CONV_TYPE LONG64
2208 #define EXPECTI8(x) \
2209 ok((hres == S_OK && out == (CONV_TYPE)(x)), \
2210 "expected " #x "(%u,%u), got (%u,%u); hres=0x%08x\n", \
2211 (ULONG)((LONG64)(x) >> 32), (ULONG)((x) & 0xffffffff), \
2212 (ULONG)(out >> 32), (ULONG)(out & 0xffffffff), hres)
2214 #define EXPECTI864(x,y) \
2215 ok(hres == S_OK && (out >> 32) == (CONV_TYPE)(x) && (out & 0xffffffff) == (CONV_TYPE)(y), \
2216 "expected " #x "(%u,%u), got (%u,%u); hres=0x%08x\n", \
2217 (ULONG)(x), (ULONG)(y), \
2218 (ULONG)(out >> 32), (ULONG)(out & 0xffffffff), hres)
2220 static void test_VarI8FromI1(void)
2222 CONVVARS(signed char);
2223 int i;
2225 CHECKPTR(VarI8FromI1);
2226 for (i = -128; i < 128; i++)
2228 CONVERT(VarI8FromI1,i); EXPECTI8(i);
2232 static void test_VarI8FromUI1(void)
2234 CONVVARS(BYTE);
2235 int i;
2237 CHECKPTR(VarI8FromUI1);
2238 for (i = 0; i < 256; i++)
2240 CONVERT(VarI8FromUI1,i); EXPECTI8(i);
2244 static void test_VarI8FromI2(void)
2246 CONVVARS(SHORT);
2247 int i;
2249 CHECKPTR(VarI8FromI2);
2250 for (i = -32768; i < 32768; i++)
2252 CONVERT(VarI8FromI2,i); EXPECTI8(i);
2256 static void test_VarI8FromUI2(void)
2258 CONVVARS(USHORT);
2259 int i;
2261 CHECKPTR(VarI8FromUI2);
2262 for (i = -0; i < 65535; i++)
2264 CONVERT(VarI8FromUI2,i); EXPECTI8(i);
2268 static void test_VarI8FromUI4(void)
2270 CONVVARS(ULONG);
2272 CHECKPTR(VarI8FromUI4);
2273 CONVERT(VarI8FromUI4, 0); EXPECTI8(0);
2274 CONVERT(VarI8FromUI4, 1); EXPECTI8(1);
2275 CONVERT(VarI8FromUI4, 4294967295ul); EXPECTI8(4294967295ul);
2278 static void test_VarI8FromR4(void)
2280 CONVVARS(FLOAT);
2282 CHECKPTR(VarI8FromR4);
2284 CONVERT(VarI8FromR4, -128.0f); EXPECTI8(-128);
2285 CONVERT(VarI8FromR4, -1.0f); EXPECTI8(-1);
2286 CONVERT(VarI8FromR4, 0.0f); EXPECTI8(0);
2287 CONVERT(VarI8FromR4, 1.0f); EXPECTI8(1);
2288 CONVERT(VarI8FromR4, 127.0f); EXPECTI8(127);
2290 CONVERT(VarI8FromR4, -1.5f); EXPECTI8(-2);
2291 CONVERT(VarI8FromR4, -0.6f); EXPECTI8(-1);
2292 CONVERT(VarI8FromR4, -0.5f); EXPECTI8(0);
2293 CONVERT(VarI8FromR4, -0.4f); EXPECTI8(0);
2294 CONVERT(VarI8FromR4, 0.4f); EXPECTI8(0);
2295 CONVERT(VarI8FromR4, 0.5f); EXPECTI8(0);
2296 CONVERT(VarI8FromR4, 0.6f); EXPECTI8(1);
2297 CONVERT(VarI8FromR4, 1.5f); EXPECTI8(2);
2300 static void test_VarI8FromR8(void)
2302 CONVVARS(DOUBLE);
2304 CHECKPTR(VarI8FromR8);
2305 CONVERT(VarI8FromR8, -128.0); EXPECTI8(-128);
2306 CONVERT(VarI8FromR8, -1.0); EXPECTI8(-1);
2307 CONVERT(VarI8FromR8, 0.0); EXPECTI8(0);
2308 CONVERT(VarI8FromR8, 1.0); EXPECTI8(1);
2309 CONVERT(VarI8FromR8, 127.0); EXPECTI8(127);
2311 CONVERT(VarI8FromR8, -1.5); EXPECTI8(-2);
2312 CONVERT(VarI8FromR8, -0.6); EXPECTI8(-1);
2313 CONVERT(VarI8FromR8, -0.5); EXPECTI8(0);
2314 CONVERT(VarI8FromR8, -0.4); EXPECTI8(0);
2315 CONVERT(VarI8FromR8, 0.4); EXPECTI8(0);
2316 CONVERT(VarI8FromR8, 0.5); EXPECTI8(0);
2317 CONVERT(VarI8FromR8, 0.6); EXPECTI8(1);
2318 CONVERT(VarI8FromR8, 1.5); EXPECTI8(2);
2321 static void test_VarI8FromDate(void)
2323 CONVVARS(DATE);
2325 CHECKPTR(VarI8FromDate);
2326 CONVERT(VarI8FromDate, -128.0); EXPECTI8(-128);
2327 CONVERT(VarI8FromDate, -1.0); EXPECTI8(-1);
2328 CONVERT(VarI8FromDate, 0.0); EXPECTI8(0);
2329 CONVERT(VarI8FromDate, 1.0); EXPECTI8(1);
2330 CONVERT(VarI8FromDate, 127.0); EXPECTI8(127);
2332 CONVERT(VarI8FromDate, -1.5); EXPECTI8(-2);
2333 CONVERT(VarI8FromDate, -0.6); EXPECTI8(-1);
2334 CONVERT(VarI8FromDate, -0.5); EXPECTI8(0);
2335 CONVERT(VarI8FromDate, -0.4); EXPECTI8(0);
2336 CONVERT(VarI8FromDate, 0.4); EXPECTI8(0);
2337 CONVERT(VarI8FromDate, 0.5); EXPECTI8(0);
2338 CONVERT(VarI8FromDate, 0.6); EXPECTI8(1);
2339 CONVERT(VarI8FromDate, 1.5); EXPECTI8(2);
2342 static void test_VarI8FromBool(void)
2344 CONVVARS(VARIANT_BOOL);
2345 int i;
2347 CHECKPTR(VarI8FromBool);
2348 for (i = -32768; i < 32768; i++)
2350 CONVERT(VarI8FromBool,i); EXPECTI8(i);
2354 static void test_VarI8FromUI8(void)
2356 CONVVARS(ULONG64);
2358 CHECKPTR(VarI8FromUI8);
2359 CONVERT(VarI8FromUI8, 0); EXPECTI8(0);
2360 CONVERT(VarI8FromUI8, 1); EXPECTI8(1);
2361 CONVERT_I8(VarI8FromUI8, 0x7fffffff, 0xffffffff); EXPECTI864(0x7fffffff, 0xffffffff);
2362 CONVERT_I8(VarI8FromUI8, 0x80000000, 0); EXPECT_OVERFLOW;
2365 static void test_VarI8FromCy(void)
2367 CONVVARS(CY);
2369 CHECKPTR(VarI8FromCy);
2370 CONVERT_CY(VarI8FromCy,-128); EXPECTI8(-129);
2371 CONVERT_CY(VarI8FromCy,-1); EXPECTI8(-2);
2372 CONVERT_CY(VarI8FromCy,0); EXPECTI8(0);
2373 CONVERT_CY(VarI8FromCy,1); EXPECTI8(1);
2374 CONVERT_CY(VarI8FromCy,127); EXPECTI8(127);
2376 CONVERT_CY(VarI8FromCy,-1.5); EXPECTI8(-2);
2377 CONVERT_CY(VarI8FromCy,-0.6); EXPECTI8(-1);
2378 CONVERT_CY(VarI8FromCy,-0.5); EXPECTI8(-1);
2379 CONVERT_CY(VarI8FromCy,-0.4); EXPECTI8(-1);
2380 CONVERT_CY(VarI8FromCy,0.4); EXPECTI8(0);
2381 CONVERT_CY(VarI8FromCy,0.5); EXPECTI8(0);
2382 CONVERT_CY(VarI8FromCy,0.6); EXPECTI8(1);
2383 CONVERT_CY(VarI8FromCy,1.5); EXPECTI8(2);
2386 static void test_VarI8FromDec(void)
2388 CONVVARS(DECIMAL);
2390 CHECKPTR(VarI8FromDec);
2392 CONVERT_BADDEC(VarI8FromDec);
2394 CONVERT_DEC(VarI8FromDec,0,0x80,0,128); EXPECTI8(-128);
2395 CONVERT_DEC(VarI8FromDec,0,0x80,0,1); EXPECTI8(-1);
2396 CONVERT_DEC(VarI8FromDec,0,0,0,0); EXPECTI8(0);
2397 CONVERT_DEC(VarI8FromDec,0,0,0,1); EXPECTI8(1);
2398 CONVERT_DEC(VarI8FromDec,0,0,0,127); EXPECTI8(127);
2400 CONVERT_DEC(VarI8FromDec,2,0x80,0,12700); EXPECTI8(-127);
2401 CONVERT_DEC(VarI8FromDec,2,0,0,12700); EXPECTI8(127);
2404 static void test_VarI8FromStr(void)
2406 CONVVARS(LCID);
2407 OLECHAR buff[128];
2409 in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
2411 CHECKPTR(VarI8FromStr);
2413 CONVERT_STR(VarI8FromStr,NULL,0); EXPECT_MISMATCH;
2414 CONVERT_STR(VarI8FromStr,"0",0); EXPECTI8(0);
2415 CONVERT_STR(VarI8FromStr,"-1",0); EXPECTI8(-1);
2416 CONVERT_STR(VarI8FromStr,"2147483647",0); EXPECTI8(2147483647);
2418 CONVERT_STR(VarI8FromStr,"-1.5",LOCALE_NOUSEROVERRIDE); EXPECTI8(-2);
2419 CONVERT_STR(VarI8FromStr,"-0.6",LOCALE_NOUSEROVERRIDE); EXPECTI8(-1);
2420 CONVERT_STR(VarI8FromStr,"-0.5",LOCALE_NOUSEROVERRIDE); EXPECTI8(0);
2421 CONVERT_STR(VarI8FromStr,"-0.4",LOCALE_NOUSEROVERRIDE); EXPECTI8(0);
2422 CONVERT_STR(VarI8FromStr,"0.4",LOCALE_NOUSEROVERRIDE); EXPECTI8(0);
2423 CONVERT_STR(VarI8FromStr,"0.5",LOCALE_NOUSEROVERRIDE); EXPECTI8(0);
2424 CONVERT_STR(VarI8FromStr,"0.6",LOCALE_NOUSEROVERRIDE); EXPECTI8(1);
2425 CONVERT_STR(VarI8FromStr,"1.5",LOCALE_NOUSEROVERRIDE); EXPECTI8(2);
2428 static void test_VarI8Copy(void)
2430 HRESULT hres;
2431 VARIANTARG vSrc, vDst;
2432 LONGLONG in = 1;
2434 if (!has_i8)
2436 win_skip("I8 and UI8 data types are not available\n");
2437 return;
2440 VariantInit(&vSrc);
2441 VariantInit(&vDst);
2442 V_VT(&vSrc) = VT_I8;
2443 V_I8(&vSrc) = in;
2444 hres = VariantCopy(&vDst, &vSrc);
2445 ok(hres == S_OK && V_VT(&vDst) == VT_I8 && V_I8(&vDst) == in,
2446 "copy hres 0x%X, type %d, value (%x%08x) %x%08x\n",
2447 hres, V_VT(&vDst), (UINT)(in >> 32), (UINT)in, (UINT)(V_I8(&vDst) >> 32), (UINT)V_I8(&vDst) );
2448 V_VT(&vSrc) = VT_I8|VT_BYREF;
2449 V_I8REF(&vSrc) = &in;
2450 hres = VariantCopy(&vDst, &vSrc);
2451 ok(hres == S_OK && V_VT(&vDst) == (VT_I8|VT_BYREF) && V_I8REF(&vDst) == &in,
2452 "ref hres 0x%X, type %d, ref (%p) %p\n", hres, V_VT(&vDst), &in, V_I8REF(&vDst));
2453 hres = VariantCopyInd(&vDst, &vSrc);
2454 ok(hres == S_OK && V_VT(&vDst) == VT_I8 && V_I8(&vDst) == in,
2455 "copy hres 0x%X, type %d, value (%x%08x) %x%08x\n",
2456 hres, V_VT(&vDst), (UINT)(in >> 32), (UINT)in, (UINT)(V_I8(&vDst) >> 32), (UINT)V_I8(&vDst) );
2459 static void test_VarI8ChangeTypeEx(void)
2461 HRESULT hres;
2462 LONG64 in;
2463 VARIANTARG vSrc, vDst;
2465 if (!has_i8)
2467 win_skip("I8 and UI8 data types are not available\n");
2468 return;
2471 in = 1;
2473 INITIAL_TYPETESTI8(VT_I8, V_I8);
2474 COMMON_TYPETEST;
2477 /* Adapt the test macros to UI8 */
2478 #undef CONV_TYPE
2479 #define CONV_TYPE ULONG64
2481 static void test_VarUI8FromI1(void)
2483 CONVVARS(signed char);
2484 int i;
2486 CHECKPTR(VarUI8FromI1);
2487 for (i = -128; i < 128; i++)
2489 CONVERT(VarUI8FromI1,i);
2490 if (i < 0)
2491 EXPECT_OVERFLOW;
2492 else
2493 EXPECTI8(i);
2497 static void test_VarUI8FromUI1(void)
2499 CONVVARS(BYTE);
2500 int i;
2502 CHECKPTR(VarUI8FromUI1);
2503 for (i = 0; i < 256; i++)
2505 CONVERT(VarUI8FromUI1,i); EXPECTI8(i);
2509 static void test_VarUI8FromI2(void)
2511 CONVVARS(SHORT);
2512 int i;
2514 CHECKPTR(VarUI8FromI2);
2515 for (i = -32768; i < 32768; i++)
2517 CONVERT(VarUI8FromI2,i);
2518 if (i < 0)
2519 EXPECT_OVERFLOW;
2520 else
2521 EXPECTI8(i);
2525 static void test_VarUI8FromUI2(void)
2527 CONVVARS(USHORT);
2528 int i;
2530 CHECKPTR(VarUI8FromUI2);
2531 for (i = 0; i < 65535; i++)
2533 CONVERT(VarUI8FromUI2,i); EXPECTI8(i);
2537 static void test_VarUI8FromUI4(void)
2539 CONVVARS(ULONG);
2541 CHECKPTR(VarUI8FromUI4);
2542 CONVERT(VarUI8FromUI4, 0); EXPECTI8(0);
2543 CONVERT(VarUI8FromUI4, 0xffffffff); EXPECTI8(0xffffffff);
2546 static void test_VarUI8FromR4(void)
2548 CONVVARS(FLOAT);
2550 CHECKPTR(VarUI8FromR4);
2551 CONVERT(VarUI8FromR4, -1.0f); EXPECT_OVERFLOW;
2552 CONVERT(VarUI8FromR4, 0.0f); EXPECTI8(0);
2553 CONVERT(VarUI8FromR4, 1.0f); EXPECTI8(1);
2554 CONVERT(VarUI8FromR4, 255.0f); EXPECTI8(255);
2556 CONVERT(VarUI8FromR4, -1.5f); EXPECT_OVERFLOW;
2557 CONVERT(VarUI8FromR4, -0.6f); EXPECT_OVERFLOW;
2558 CONVERT(VarUI8FromR4, -0.5f); EXPECTI8(0);
2559 CONVERT(VarUI8FromR4, -0.4f); EXPECTI8(0);
2560 CONVERT(VarUI8FromR4, 0.4f); EXPECTI8(0);
2561 CONVERT(VarUI8FromR4, 0.5f); EXPECTI8(0);
2562 CONVERT(VarUI8FromR4, 0.6f); EXPECTI8(1);
2563 CONVERT(VarUI8FromR4, 1.5f); EXPECTI8(2);
2566 static void test_VarUI8FromR8(void)
2568 CONVVARS(DOUBLE);
2570 CHECKPTR(VarUI8FromR8);
2571 CONVERT(VarUI8FromR8, -1.0); EXPECT_OVERFLOW;
2572 CONVERT(VarUI8FromR8, 0.0); EXPECTI8(0);
2573 CONVERT(VarUI8FromR8, 1.0); EXPECTI8(1);
2574 CONVERT(VarUI8FromR8, 255.0); EXPECTI8(255);
2576 CONVERT(VarUI8FromR8, -1.5); EXPECT_OVERFLOW;
2577 CONVERT(VarUI8FromR8, -0.6); EXPECT_OVERFLOW;
2578 CONVERT(VarUI8FromR8, -0.5); EXPECTI8(0);
2579 CONVERT(VarUI8FromR8, -0.4); EXPECTI8(0);
2580 CONVERT(VarUI8FromR8, 0.4); EXPECTI8(0);
2581 CONVERT(VarUI8FromR8, 0.5); EXPECTI8(0);
2582 CONVERT(VarUI8FromR8, 0.6); EXPECTI8(1);
2583 CONVERT(VarUI8FromR8, 1.5); EXPECTI8(2);
2586 static void test_VarUI8FromDate(void)
2588 CONVVARS(DATE);
2590 CHECKPTR(VarUI8FromDate);
2591 CONVERT(VarUI8FromDate, -1.0); EXPECT_OVERFLOW;
2592 CONVERT(VarUI8FromDate, 0.0); EXPECTI8(0);
2593 CONVERT(VarUI8FromDate, 1.0); EXPECTI8(1);
2594 CONVERT(VarUI8FromDate, 255.0); EXPECTI8(255);
2596 CONVERT(VarUI8FromDate, -1.5); EXPECT_OVERFLOW;
2597 CONVERT(VarUI8FromDate, -0.6); EXPECT_OVERFLOW;
2598 CONVERT(VarUI8FromDate, -0.5); EXPECTI8(0);
2599 CONVERT(VarUI8FromDate, -0.4); EXPECTI8(0);
2600 CONVERT(VarUI8FromDate, 0.4); EXPECTI8(0);
2601 CONVERT(VarUI8FromDate, 0.5); EXPECTI8(0);
2602 CONVERT(VarUI8FromDate, 0.6); EXPECTI8(1);
2603 CONVERT(VarUI8FromDate, 1.5); EXPECTI8(2);
2606 static void test_VarUI8FromBool(void)
2608 CONVVARS(VARIANT_BOOL);
2609 int i;
2611 CHECKPTR(VarUI8FromBool);
2612 for (i = -32768; i < 32768; i++)
2614 CONVERT(VarUI8FromBool, i); EXPECTI8(i);
2618 static void test_VarUI8FromI8(void)
2620 CONVVARS(LONG64);
2622 CHECKPTR(VarUI8FromI8);
2623 CONVERT(VarUI8FromI8, -1); EXPECT_OVERFLOW;
2624 CONVERT(VarUI8FromI8, 0); EXPECTI8(0);
2625 CONVERT(VarUI8FromI8, 1); EXPECTI8(1);
2628 static void test_VarUI8FromCy(void)
2630 CONVVARS(CY);
2632 CHECKPTR(VarUI8FromCy);
2633 CONVERT_CY(VarUI8FromCy,-1); EXPECT_OVERFLOW;
2634 CONVERT_CY(VarUI8FromCy,0); EXPECTI8(0);
2635 CONVERT_CY(VarUI8FromCy,1); EXPECTI8(1);
2636 CONVERT_CY(VarUI8FromCy,255); EXPECTI8(255);
2638 CONVERT_CY(VarUI8FromCy,-1.5); EXPECT_OVERFLOW;
2639 CONVERT_CY(VarUI8FromCy,-0.6); EXPECT_OVERFLOW;
2640 CONVERT_CY(VarUI8FromCy,-0.5); EXPECTI8(0);
2641 CONVERT_CY(VarUI8FromCy,-0.4); EXPECTI8(0);
2642 CONVERT_CY(VarUI8FromCy,0.4); EXPECTI8(0);
2643 CONVERT_CY(VarUI8FromCy,0.5); EXPECTI8(0);
2644 CONVERT_CY(VarUI8FromCy,0.6); EXPECTI8(1);
2645 CONVERT_CY(VarUI8FromCy,1.5); EXPECTI8(2);
2648 static void test_VarUI8FromDec(void)
2650 CONVVARS(DECIMAL);
2652 CHECKPTR(VarUI8FromDec);
2654 CONVERT_BADDEC(VarUI8FromDec);
2656 /* This returns 1 under native; Wine fixes this bug and returns overflow */
2657 if (0)
2659 CONVERT_DEC(VarUI8FromDec,0,0x80,0,1);
2662 CONVERT_DEC(VarUI8FromDec,0,0,0,0); EXPECTI8(0);
2663 CONVERT_DEC(VarUI8FromDec,0,0,0,1); EXPECTI8(1);
2664 CONVERT_DEC(VarUI8FromDec,0,0,0,255); EXPECTI8(255);
2666 CONVERT_DEC(VarUI8FromDec,2,0x80,0,100); EXPECT_OVERFLOW;
2667 CONVERT_DEC(VarUI8FromDec,2,0,0,25500); EXPECTI8(255);
2670 static void test_VarUI8FromStr(void)
2672 CONVVARS(LCID);
2673 OLECHAR buff[128];
2675 in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
2677 CHECKPTR(VarUI8FromStr);
2679 CONVERT_STR(VarUI8FromStr,NULL,0); EXPECT_MISMATCH;
2680 CONVERT_STR(VarUI8FromStr,"0",0); EXPECTI8(0);
2681 CONVERT_STR(VarUI8FromStr,"-1",0); EXPECT_OVERFLOW;
2682 CONVERT_STR(VarUI8FromStr,"2147483647",0); EXPECTI8(2147483647);
2683 CONVERT_STR(VarUI8FromStr,"18446744073709551614",0); EXPECTI864(0xFFFFFFFF,0xFFFFFFFE);
2684 CONVERT_STR(VarUI8FromStr,"18446744073709551615",0); EXPECTI864(0xFFFFFFFF,0xFFFFFFFF);
2685 CONVERT_STR(VarUI8FromStr,"18446744073709551616",0); EXPECT_OVERFLOW;
2687 CONVERT_STR(VarUI8FromStr,"-1.5",LOCALE_NOUSEROVERRIDE); EXPECT_OVERFLOW;
2688 CONVERT_STR(VarUI8FromStr,"-0.6",LOCALE_NOUSEROVERRIDE); EXPECT_OVERFLOW;
2689 CONVERT_STR(VarUI8FromStr,"-0.5",LOCALE_NOUSEROVERRIDE); EXPECTI8(0);
2690 CONVERT_STR(VarUI8FromStr,"-0.4",LOCALE_NOUSEROVERRIDE); EXPECTI8(0);
2691 CONVERT_STR(VarUI8FromStr,"0.4",LOCALE_NOUSEROVERRIDE); EXPECTI8(0);
2692 CONVERT_STR(VarUI8FromStr,"0.5",LOCALE_NOUSEROVERRIDE); EXPECTI8(0);
2693 CONVERT_STR(VarUI8FromStr,"0.6",LOCALE_NOUSEROVERRIDE); EXPECTI8(1);
2694 CONVERT_STR(VarUI8FromStr,"1.5",LOCALE_NOUSEROVERRIDE); EXPECTI8(2);
2697 static void test_VarUI8Copy(void)
2699 HRESULT hres;
2700 VARIANTARG vSrc, vDst;
2701 ULONGLONG in = 1;
2703 if (!has_i8)
2705 win_skip("I8 and UI8 data types are not available\n");
2706 return;
2709 VariantInit(&vSrc);
2710 VariantInit(&vDst);
2711 V_VT(&vSrc) = VT_UI8;
2712 V_UI8(&vSrc) = in;
2713 hres = VariantCopy(&vDst, &vSrc);
2714 ok(hres == S_OK && V_VT(&vDst) == VT_UI8 && V_UI8(&vDst) == in,
2715 "copy hres 0x%X, type %d, value (%x%08x) %x%08x\n",
2716 hres, V_VT(&vDst), (UINT)(in >> 32), (UINT)in, (UINT)(V_UI8(&vDst) >> 32), (UINT)V_UI8(&vDst) );
2717 V_VT(&vSrc) = VT_UI8|VT_BYREF;
2718 V_UI8REF(&vSrc) = &in;
2719 hres = VariantCopy(&vDst, &vSrc);
2720 ok(hres == S_OK && V_VT(&vDst) == (VT_UI8|VT_BYREF) && V_UI8REF(&vDst) == &in,
2721 "ref hres 0x%X, type %d, ref (%p) %p\n", hres, V_VT(&vDst), &in, V_UI8REF(&vDst));
2722 hres = VariantCopyInd(&vDst, &vSrc);
2723 ok(hres == S_OK && V_VT(&vDst) == VT_UI8 && V_UI8(&vDst) == in,
2724 "copy hres 0x%X, type %d, value (%x%08x) %x%08x\n",
2725 hres, V_VT(&vDst), (UINT)(in >> 32), (UINT)in, (UINT)(V_UI8(&vDst) >> 32), (UINT)V_UI8(&vDst) );
2728 static void test_VarUI8ChangeTypeEx(void)
2730 HRESULT hres;
2731 ULONG64 in;
2732 VARIANTARG vSrc, vDst;
2734 if (!has_i8)
2736 win_skip("I8 and UI8 data types are not available\n");
2737 return;
2740 in = 1;
2742 INITIAL_TYPETESTI8(VT_UI8, V_UI8);
2743 COMMON_TYPETEST;
2747 * VT_R4
2750 #undef CONV_TYPE
2751 #define CONV_TYPE float
2752 #undef EXPECTRES
2753 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%15.15f")
2755 static void test_VarR4FromI1(void)
2757 CONVVARS(signed char);
2758 int i;
2760 CHECKPTR(VarR4FromI1);
2761 CONVERTRANGE(VarR4FromI1, -128, 128);
2764 static void test_VarR4FromUI1(void)
2766 CONVVARS(BYTE);
2767 int i;
2769 CHECKPTR(VarR4FromUI1);
2770 CONVERTRANGE(VarR4FromUI1, 0, 256);
2773 static void test_VarR4FromI2(void)
2775 CONVVARS(SHORT);
2776 int i;
2778 CHECKPTR(VarR4FromI2);
2779 CONVERTRANGE(VarR4FromI2, -32768, 32768);
2782 static void test_VarR4FromUI2(void)
2784 CONVVARS(USHORT);
2785 int i;
2787 CHECKPTR(VarR4FromUI2);
2788 CONVERTRANGE(VarR4FromUI2, 0, 65536);
2791 static void test_VarR4FromI4(void)
2793 CONVVARS(int);
2795 CHECKPTR(VarR4FromI4);
2796 CONVERT(VarR4FromI4, -2147483647-1); EXPECT(-2147483648.0f);
2797 CONVERT(VarR4FromI4, -1); EXPECT(-1.0f);
2798 CONVERT(VarR4FromI4, 0); EXPECT(0.0f);
2799 CONVERT(VarR4FromI4, 1); EXPECT(1.0f);
2800 CONVERT(VarR4FromI4, 2147483647); EXPECT(2147483647.0f);
2803 static void test_VarR4FromUI4(void)
2805 CONVVARS(unsigned int);
2807 CHECKPTR(VarR4FromUI4);
2808 CONVERT(VarR4FromUI4, 0); EXPECT(0.0f);
2809 CONVERT(VarR4FromUI4, 1); EXPECT(1.0f);
2810 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
2811 CONVERT(VarR4FromUI4, 0xffffffff); EXPECT(4294967296.0f);
2812 #endif
2815 static void test_VarR4FromR8(void)
2817 CONVVARS(FLOAT);
2819 CHECKPTR(VarR4FromR8);
2820 CONVERT(VarR4FromR8, -1.0); EXPECT(-1.0f);
2821 CONVERT(VarR4FromR8, 0.0); EXPECT(0.0f);
2822 CONVERT(VarR4FromR8, 1.0); EXPECT(1.0f);
2823 CONVERT(VarR4FromR8, 1.5); EXPECT(1.5f);
2825 /* Skip rounding tests - no rounding is done */
2828 static void test_VarR4FromBool(void)
2830 CONVVARS(VARIANT_BOOL);
2832 CHECKPTR(VarR4FromBool);
2833 CONVERT(VarR4FromBool, VARIANT_TRUE); EXPECT(VARIANT_TRUE * 1.0f);
2834 CONVERT(VarR4FromBool, VARIANT_FALSE); EXPECT(VARIANT_FALSE * 1.0f);
2837 static void test_VarR4FromCy(void)
2839 CONVVARS(CY);
2841 CHECKPTR(VarR4FromCy);
2842 CONVERT_CY(VarR4FromCy,-32768); EXPECT(-32768.0f);
2843 CONVERT_CY(VarR4FromCy,-1); EXPECT(-1.0f);
2844 CONVERT_CY(VarR4FromCy,0); EXPECT(0.0f);
2845 CONVERT_CY(VarR4FromCy,1); EXPECT(1.0f);
2846 CONVERT_CY(VarR4FromCy,32768); EXPECT(32768.0f);
2848 CONVERT_CY(VarR4FromCy,-1.5); EXPECT(-1.5f);
2849 CONVERT_CY(VarR4FromCy,-0.6); EXPECT(-0.6f);
2850 CONVERT_CY(VarR4FromCy,-0.5); EXPECT(-0.5f);
2851 CONVERT_CY(VarR4FromCy,-0.4); EXPECT(-0.4f);
2852 CONVERT_CY(VarR4FromCy,0.4); EXPECT(0.4f);
2853 CONVERT_CY(VarR4FromCy,0.5); EXPECT(0.5f);
2854 CONVERT_CY(VarR4FromCy,0.6); EXPECT(0.6f);
2855 CONVERT_CY(VarR4FromCy,1.5); EXPECT(1.5f);
2858 static void test_VarR4FromI8(void)
2860 CONVVARS(LONG64);
2862 CHECKPTR(VarR4FromI8);
2863 CONVERT(VarR4FromI8, -1); EXPECT(-1.0f);
2864 CONVERT(VarR4FromI8, 0); EXPECT(0.0f);
2865 CONVERT(VarR4FromI8, 1); EXPECT(1.0f);
2868 static void test_VarR4FromUI8(void)
2870 CONVVARS(ULONG64);
2872 CHECKPTR(VarR4FromUI8);
2873 CONVERT(VarR4FromUI8, 0); EXPECT(0.0f);
2874 CONVERT(VarR4FromUI8, 1); EXPECT(1.0f);
2877 static void test_VarR4FromDec(void)
2879 CONVVARS(DECIMAL);
2881 CHECKPTR(VarR4FromDec);
2883 CONVERT_BADDEC(VarR4FromDec);
2885 CONVERT_DEC(VarR4FromDec,0,0x80,0,32768); EXPECT(-32768.0f);
2886 CONVERT_DEC(VarR4FromDec,0,0x80,0,1); EXPECT(-1.0f);
2887 CONVERT_DEC(VarR4FromDec,0,0,0,0); EXPECT(0.0f);
2888 CONVERT_DEC(VarR4FromDec,0,0,0,1); EXPECT(1.0f);
2889 CONVERT_DEC(VarR4FromDec,0,0,0,32767); EXPECT(32767.0f);
2891 CONVERT_DEC(VarR4FromDec,2,0x80,0,3276800); EXPECT(-32768.0f);
2892 CONVERT_DEC(VarR4FromDec,2,0,0,3276700); EXPECT(32767.0f);
2893 CONVERT_DEC(VarR4FromDec,10,0,0,3276700); EXPECT(0.00032767f);
2895 CONVERT_DEC(VarR4FromDec,0,0,1,0); EXPECT(18446744073709551616.0f);
2898 static void test_VarR4FromDate(void)
2900 CONVVARS(DATE);
2902 CHECKPTR(VarR4FromDate);
2903 CONVERT(VarR4FromDate, -1.0); EXPECT(-1.0f);
2904 CONVERT(VarR4FromDate, 0.0); EXPECT(0.0f);
2905 CONVERT(VarR4FromDate, 1.0); EXPECT(1.0f);
2908 static void test_VarR4FromStr(void)
2910 CONVVARS(LCID);
2911 OLECHAR buff[128];
2913 in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
2915 CHECKPTR(VarR4FromStr);
2917 CONVERT_STR(VarR4FromStr,NULL,0); EXPECT_MISMATCH;
2918 CONVERT_STR(VarR4FromStr,"-1", 0); EXPECT(-1.0f);
2919 CONVERT_STR(VarR4FromStr,"0", 0); EXPECT(0.0f);
2920 CONVERT_STR(VarR4FromStr,"1", 0); EXPECT(1.0f);
2922 CONVERT_STR(VarR4FromStr,"-1.5",LOCALE_NOUSEROVERRIDE); EXPECT(-1.5f);
2923 CONVERT_STR(VarR4FromStr,"-0.6",LOCALE_NOUSEROVERRIDE); EXPECT(-0.6f);
2924 CONVERT_STR(VarR4FromStr,"-0.5",LOCALE_NOUSEROVERRIDE); EXPECT(-0.5f);
2925 CONVERT_STR(VarR4FromStr,"-0.4",LOCALE_NOUSEROVERRIDE); EXPECT(-0.4f);
2926 CONVERT_STR(VarR4FromStr,"0.4",LOCALE_NOUSEROVERRIDE); EXPECT(0.4f);
2927 CONVERT_STR(VarR4FromStr,"0.5",LOCALE_NOUSEROVERRIDE); EXPECT(0.5f);
2928 CONVERT_STR(VarR4FromStr,"0.6",LOCALE_NOUSEROVERRIDE); EXPECT(0.6f);
2929 CONVERT_STR(VarR4FromStr,"1.5",LOCALE_NOUSEROVERRIDE); EXPECT(1.5f);
2932 static void test_VarR4Copy(void)
2934 COPYTEST(77665544.0f, VT_R4, V_R4(&vSrc), V_R4(&vDst), V_R4REF(&vSrc),V_R4REF(&vDst), "%15.15f");
2937 static void test_VarR4ChangeTypeEx(void)
2939 #ifdef HAS_UINT64_TO_FLOAT
2940 HRESULT hres;
2941 float in;
2942 VARIANTARG vSrc, vDst;
2944 in = 1.0f;
2946 INITIAL_TYPETEST(VT_R4, V_R4, "%f");
2947 COMMON_TYPETEST;
2948 #endif
2952 * VT_R8
2955 #undef CONV_TYPE
2956 #define CONV_TYPE double
2958 static void test_VarR8FromI1(void)
2960 CONVVARS(signed char);
2961 int i;
2963 CHECKPTR(VarR8FromI1);
2964 CONVERTRANGE(VarR8FromI1, -128, 128);
2967 static void test_VarR8FromUI1(void)
2969 CONVVARS(BYTE);
2970 int i;
2972 CHECKPTR(VarR8FromUI1);
2973 CONVERTRANGE(VarR8FromUI1, 0, 256);
2976 static void test_VarR8FromI2(void)
2978 CONVVARS(SHORT);
2979 int i;
2981 CHECKPTR(VarR8FromI2);
2982 CONVERTRANGE(VarR8FromI2, -32768, 32768);
2985 static void test_VarR8FromUI2(void)
2987 CONVVARS(USHORT);
2988 int i;
2990 CHECKPTR(VarR8FromUI2);
2991 CONVERTRANGE(VarR8FromUI2, 0, 65536);
2994 static void test_VarR8FromI4(void)
2996 CONVVARS(int);
2998 CHECKPTR(VarR8FromI4);
2999 CONVERT(VarR8FromI4, -2147483647-1); EXPECT(-2147483648.0);
3000 CONVERT(VarR8FromI4, -1); EXPECT(-1.0);
3001 CONVERT(VarR8FromI4, 0); EXPECT(0.0);
3002 CONVERT(VarR8FromI4, 1); EXPECT(1.0);
3003 CONVERT(VarR8FromI4, 0x7fffffff); EXPECT(2147483647.0);
3006 static void test_VarR8FromUI4(void)
3008 CONVVARS(unsigned int);
3010 CHECKPTR(VarR8FromUI4);
3011 CONVERT(VarR8FromUI4, 0); EXPECT(0.0);
3012 CONVERT(VarR8FromUI4, 1); EXPECT(1.0);
3013 CONVERT(VarR8FromUI4, 0xffffffff); EXPECT(4294967295.0);
3016 static void test_VarR8FromR4(void)
3018 CONVVARS(FLOAT);
3020 CHECKPTR(VarR8FromR4);
3021 CONVERT(VarR8FromR4, -1.0f); EXPECT(-1.0);
3022 CONVERT(VarR8FromR4, 0.0f); EXPECT(0.0);
3023 CONVERT(VarR8FromR4, 1.0f); EXPECT(1.0);
3024 CONVERT(VarR8FromR4, 1.5f); EXPECT(1.5);
3026 /* Skip rounding tests - no rounding is done */
3029 static void test_VarR8FromBool(void)
3031 CONVVARS(VARIANT_BOOL);
3033 CHECKPTR(VarR8FromBool);
3034 CONVERT(VarR8FromBool, VARIANT_TRUE); EXPECT(VARIANT_TRUE * 1.0);
3035 CONVERT(VarR8FromBool, VARIANT_FALSE); EXPECT(VARIANT_FALSE * 1.0);
3038 static void test_VarR8FromCy(void)
3040 CONVVARS(CY);
3042 CHECKPTR(VarR8FromCy);
3043 CONVERT_CY(VarR8FromCy,-32769); EXPECT(-32769.0);
3044 CONVERT_CY(VarR8FromCy,-32768); EXPECT(-32768.0);
3045 CONVERT_CY(VarR8FromCy,-1); EXPECT(-1.0);
3046 CONVERT_CY(VarR8FromCy,0); EXPECT(0.0);
3047 CONVERT_CY(VarR8FromCy,1); EXPECT(1.0);
3048 CONVERT_CY(VarR8FromCy,32767); EXPECT(32767.0);
3049 CONVERT_CY(VarR8FromCy,32768); EXPECT(32768.0);
3051 CONVERT_CY(VarR8FromCy,-1.5); EXPECT(-1.5);
3052 CONVERT_CY(VarR8FromCy,-0.6); EXPECT(-0.6);
3053 CONVERT_CY(VarR8FromCy,-0.5); EXPECT(-0.5);
3054 CONVERT_CY(VarR8FromCy,-0.4); EXPECT(-0.4);
3055 CONVERT_CY(VarR8FromCy,0.4); EXPECT(0.4);
3056 CONVERT_CY(VarR8FromCy,0.5); EXPECT(0.5);
3057 CONVERT_CY(VarR8FromCy,0.6); EXPECT(0.6);
3058 CONVERT_CY(VarR8FromCy,1.5); EXPECT(1.5);
3061 static void test_VarR8FromI8(void)
3063 CONVVARS(LONG64);
3065 CHECKPTR(VarR8FromI8);
3066 CONVERT(VarR8FromI8, -1); EXPECT(-1.0);
3067 CONVERT(VarR8FromI8, 0); EXPECT(0.0);
3068 CONVERT(VarR8FromI8, 1); EXPECT(1.0);
3069 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
3070 CONVERT_I8(VarR8FromI8, 0x7fffffff,0xffffffff); EXPECT(9223372036854775808.0);
3071 #endif
3074 static void test_VarR8FromUI8(void)
3076 CONVVARS(ULONG64);
3078 CHECKPTR(VarR8FromUI8);
3079 CONVERT(VarR8FromUI8, 0); EXPECT(0.0);
3080 CONVERT(VarR8FromUI8, 1); EXPECT(1.0);
3081 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
3082 CONVERT_I8(VarR8FromUI8, 0x80000000,0); EXPECT(9223372036854775808.0);
3083 #endif
3086 static void test_VarR8FromDec(void)
3088 CONVVARS(DECIMAL);
3090 CHECKPTR(VarR8FromDec);
3092 CONVERT_BADDEC(VarR8FromDec);
3094 CONVERT_DEC(VarR8FromDec,0,0x80,0,32768); EXPECT(-32768.0);
3095 CONVERT_DEC(VarR8FromDec,0,0x80,0,1); EXPECT(-1.0);
3096 CONVERT_DEC(VarR8FromDec,0,0,0,0); EXPECT(0.0);
3097 CONVERT_DEC(VarR8FromDec,0,0,0,1); EXPECT(1.0);
3098 CONVERT_DEC(VarR8FromDec,0,0,0,32767); EXPECT(32767.0);
3100 CONVERT_DEC(VarR8FromDec,2,0x80,0,3276800); EXPECT(-32768.0);
3101 CONVERT_DEC(VarR8FromDec,2,0,0,3276700); EXPECT(32767.0);
3103 CONVERT_DEC(VarR8FromDec,0,0,1,0); EXPECT(18446744073709551616.0);
3106 static void test_VarR8FromDate(void)
3108 CONVVARS(DATE);
3110 CHECKPTR(VarR8FromDate);
3111 CONVERT(VarR8FromDate, -1.0); EXPECT(-1.0);
3112 CONVERT(VarR8FromDate, -0.0); EXPECT(0.0);
3113 CONVERT(VarR8FromDate, 1.0); EXPECT(1.0);
3116 static void test_VarR8FromStr(void)
3118 CONVVARS(LCID);
3119 OLECHAR buff[128];
3121 in = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3123 CHECKPTR(VarR8FromStr);
3125 CONVERT_STR(VarR8FromStr,NULL,0); EXPECT_MISMATCH;
3126 CONVERT_STR(VarR8FromStr,"",0); EXPECT_MISMATCH;
3127 CONVERT_STR(VarR8FromStr," ",0); EXPECT_MISMATCH;
3129 CONVERT_STR(VarR8FromStr,"0",LOCALE_NOUSEROVERRIDE); EXPECT(0.0);
3130 CONVERT_STR(VarR8FromStr,"-1.5",LOCALE_NOUSEROVERRIDE); EXPECT(-1.5);
3131 CONVERT_STR(VarR8FromStr,"-0.6",LOCALE_NOUSEROVERRIDE); EXPECT(-0.6);
3132 CONVERT_STR(VarR8FromStr,"-0.5",LOCALE_NOUSEROVERRIDE); EXPECT(-0.5);
3133 CONVERT_STR(VarR8FromStr,"-0.4",LOCALE_NOUSEROVERRIDE); EXPECT(-0.4);
3134 CONVERT_STR(VarR8FromStr,"0.4",LOCALE_NOUSEROVERRIDE); EXPECT(0.4);
3135 CONVERT_STR(VarR8FromStr,"0.5",LOCALE_NOUSEROVERRIDE); EXPECT(0.5);
3136 CONVERT_STR(VarR8FromStr,"0.6",LOCALE_NOUSEROVERRIDE); EXPECT(0.6);
3137 CONVERT_STR(VarR8FromStr,"1.5",LOCALE_NOUSEROVERRIDE); EXPECT(1.5);
3139 /* We already have exhaustive tests for number parsing, so skip those tests here */
3142 static void test_VarR8Copy(void)
3144 COPYTEST(77665544.0, VT_R8, V_R8(&vSrc), V_R8(&vDst), V_R8REF(&vSrc),V_R8REF(&vDst), "%16.16g");
3147 static void test_VarR8ChangeTypeEx(void)
3149 #ifdef HAS_UINT64_TO_FLOAT
3150 HRESULT hres;
3151 double in;
3152 VARIANTARG vSrc, vDst;
3154 in = 1.0;
3156 INITIAL_TYPETEST(VT_R8, V_R8, "%g");
3157 COMMON_TYPETEST;
3158 #endif
3161 #define MATHRND(l, r) left = l; right = r; hres = pVarR8Round(left, right, &out)
3163 static void test_VarR8Round(void)
3165 HRESULT hres;
3166 double left = 0.0, out;
3167 int right;
3169 CHECKPTR(VarR8Round);
3170 MATHRND(0.5432, 5); EXPECT(0.5432);
3171 MATHRND(0.5432, 4); EXPECT(0.5432);
3172 MATHRND(0.5432, 3); EXPECT(0.543);
3173 MATHRND(0.5432, 2); EXPECT(0.54);
3174 MATHRND(0.5432, 1); EXPECT(0.5);
3175 MATHRND(0.5532, 0); EXPECT(1);
3176 MATHRND(0.5532, -1); EXPECT_INVALID;
3178 MATHRND(0.5568, 5); EXPECT(0.5568);
3179 MATHRND(0.5568, 4); EXPECT(0.5568);
3180 MATHRND(0.5568, 3); EXPECT(0.557);
3181 MATHRND(0.5568, 2); EXPECT(0.56);
3182 MATHRND(0.5568, 1); EXPECT(0.6);
3183 MATHRND(0.5568, 0); EXPECT(1);
3184 MATHRND(0.5568, -1); EXPECT_INVALID;
3186 MATHRND(0.4999, 0); EXPECT(0);
3187 MATHRND(0.5000, 0); EXPECT(0);
3188 MATHRND(0.5001, 0); EXPECT(1);
3189 MATHRND(1.4999, 0); EXPECT(1);
3190 MATHRND(1.5000, 0); EXPECT(2);
3191 MATHRND(1.5001, 0); EXPECT(2);
3195 * VT_DATE
3198 #undef CONV_TYPE
3199 #define CONV_TYPE DATE
3201 static void test_VarDateFromI1(void)
3203 CONVVARS(signed char);
3204 int i;
3206 CHECKPTR(VarDateFromI1);
3207 CONVERTRANGE(VarDateFromI1, -128, 128);
3210 static void test_VarDateFromUI1(void)
3212 CONVVARS(BYTE);
3213 int i;
3215 CHECKPTR(VarDateFromUI1);
3216 CONVERTRANGE(VarDateFromUI1, 0, 256);
3219 static void test_VarDateFromI2(void)
3221 CONVVARS(SHORT);
3222 int i;
3224 CHECKPTR(VarDateFromI2);
3225 CONVERTRANGE(VarDateFromI2, -32768, 32768);
3228 static void test_VarDateFromUI2(void)
3230 CONVVARS(USHORT);
3231 int i;
3233 CHECKPTR(VarDateFromUI2);
3234 CONVERTRANGE(VarDateFromUI2, 0, 65536);
3237 static void test_VarDateFromI4(void)
3239 CONVVARS(int);
3241 CHECKPTR(VarDateFromI4);
3242 CONVERT(VarDateFromI4, DATE_MIN-1);
3243 if (hres != DISP_E_TYPEMISMATCH) /* Early versions return this, incorrectly */
3244 EXPECT_OVERFLOW;
3245 CONVERT(VarDateFromI4, DATE_MIN); EXPECT(DATE_MIN);
3246 CONVERT(VarDateFromI4, -1); EXPECT(-1.0);
3247 CONVERT(VarDateFromI4, 0); EXPECT(0.0);
3248 CONVERT(VarDateFromI4, 1); EXPECT(1.0);
3249 CONVERT(VarDateFromI4, DATE_MAX); EXPECT(DATE_MAX);
3250 CONVERT(VarDateFromI4, DATE_MAX+1);
3251 if (hres != DISP_E_TYPEMISMATCH) /* Early versions return this, incorrectly */
3252 EXPECT_OVERFLOW;
3255 static void test_VarDateFromUI4(void)
3257 CONVVARS(unsigned int);
3259 CHECKPTR(VarDateFromUI4);
3260 CONVERT(VarDateFromUI4, 0); EXPECT(0.0);
3261 CONVERT(VarDateFromUI4, 1); EXPECT(1.0);
3262 CONVERT(VarDateFromUI4, DATE_MAX); EXPECT(DATE_MAX);
3263 CONVERT(VarDateFromUI4, DATE_MAX+1);
3264 if (hres != DISP_E_TYPEMISMATCH) /* Early versions return this, incorrectly */
3265 EXPECT_OVERFLOW;
3268 static void test_VarDateFromR4(void)
3270 CONVVARS(FLOAT);
3272 CHECKPTR(VarDateFromR4);
3273 CONVERT(VarDateFromR4, -1.0f); EXPECT(-1.0);
3274 CONVERT(VarDateFromR4, 0.0f); EXPECT(0.0);
3275 CONVERT(VarDateFromR4, 1.0f); EXPECT(1.0);
3276 CONVERT(VarDateFromR4, 1.5f); EXPECT(1.5);
3279 static void test_VarDateFromR8(void)
3281 CONVVARS(double);
3283 CHECKPTR(VarDateFromR8);
3284 CONVERT(VarDateFromR8, -1.0f); EXPECT(-1.0);
3285 CONVERT(VarDateFromR8, 0.0f); EXPECT(0.0);
3286 CONVERT(VarDateFromR8, 1.0f); EXPECT(1.0);
3287 CONVERT(VarDateFromR8, 1.5f); EXPECT(1.5);
3290 static void test_VarDateFromBool(void)
3292 CONVVARS(VARIANT_BOOL);
3294 CHECKPTR(VarDateFromBool);
3295 CONVERT(VarDateFromBool, VARIANT_TRUE); EXPECT(VARIANT_TRUE * 1.0);
3296 CONVERT(VarDateFromBool, VARIANT_FALSE); EXPECT(VARIANT_FALSE * 1.0);
3299 static void test_VarDateFromCy(void)
3301 CONVVARS(CY);
3303 CHECKPTR(VarDateFromCy);
3304 CONVERT_CY(VarDateFromCy,-32769); EXPECT(-32769.0);
3305 CONVERT_CY(VarDateFromCy,-32768); EXPECT(-32768.0);
3306 CONVERT_CY(VarDateFromCy,-1); EXPECT(-1.0);
3307 CONVERT_CY(VarDateFromCy,0); EXPECT(0.0);
3308 CONVERT_CY(VarDateFromCy,1); EXPECT(1.0);
3309 CONVERT_CY(VarDateFromCy,32767); EXPECT(32767.0);
3310 CONVERT_CY(VarDateFromCy,32768); EXPECT(32768.0);
3312 CONVERT_CY(VarDateFromCy,-1.5); EXPECT(-1.5);
3313 CONVERT_CY(VarDateFromCy,-0.6); EXPECT(-0.6);
3314 CONVERT_CY(VarDateFromCy,-0.5); EXPECT(-0.5);
3315 CONVERT_CY(VarDateFromCy,-0.4); EXPECT(-0.4);
3316 CONVERT_CY(VarDateFromCy,0.4); EXPECT(0.4);
3317 CONVERT_CY(VarDateFromCy,0.5); EXPECT(0.5);
3318 CONVERT_CY(VarDateFromCy,0.6); EXPECT(0.6);
3319 CONVERT_CY(VarDateFromCy,1.5); EXPECT(1.5);
3322 static void test_VarDateFromI8(void)
3324 CONVVARS(LONG64);
3326 CHECKPTR(VarDateFromI8);
3327 CONVERT(VarDateFromI8, DATE_MIN-1); EXPECT_OVERFLOW;
3328 CONVERT(VarDateFromI8, DATE_MIN); EXPECT(DATE_MIN);
3329 CONVERT(VarDateFromI8, -1); EXPECT(-1.0);
3330 CONVERT(VarDateFromI8, 0); EXPECT(0.0);
3331 CONVERT(VarDateFromI8, 1); EXPECT(1.0);
3332 CONVERT(VarDateFromI8, DATE_MAX); EXPECT(DATE_MAX);
3333 CONVERT(VarDateFromI8, DATE_MAX+1); EXPECT_OVERFLOW;
3336 static void test_VarDateFromUI8(void)
3338 CONVVARS(ULONG64);
3340 CHECKPTR(VarDateFromUI8);
3341 CONVERT(VarDateFromUI8, 0); EXPECT(0.0);
3342 CONVERT(VarDateFromUI8, 1); EXPECT(1.0);
3343 CONVERT(VarDateFromUI8, DATE_MAX); EXPECT(DATE_MAX);
3344 CONVERT(VarDateFromUI8, DATE_MAX+1); EXPECT_OVERFLOW;
3347 static void test_VarDateFromDec(void)
3349 CONVVARS(DECIMAL);
3351 CHECKPTR(VarDateFromDec);
3353 CONVERT_BADDEC(VarDateFromDec);
3355 CONVERT_DEC(VarDateFromDec,0,0x80,0,32768); EXPECT(-32768.0);
3356 CONVERT_DEC(VarDateFromDec,0,0x80,0,1); EXPECT(-1.0);
3357 CONVERT_DEC(VarDateFromDec,0,0,0,0); EXPECT(0.0);
3358 CONVERT_DEC(VarDateFromDec,0,0,0,1); EXPECT(1.0);
3359 CONVERT_DEC(VarDateFromDec,0,0,0,32767); EXPECT(32767.0);
3361 CONVERT_DEC(VarDateFromDec,2,0x80,0,3276800); EXPECT(-32768.0);
3362 CONVERT_DEC(VarDateFromDec,2,0,0,3276700); EXPECT(32767.0);
3365 #define DFS(str) \
3366 buff[0] = '\0'; out = 0.0; \
3367 if (str) MultiByteToWideChar(CP_ACP,0,str,-1,buff,sizeof(buff)/sizeof(WCHAR)); \
3368 hres = pVarDateFromStr(str ? buff : NULL,lcid,LOCALE_NOUSEROVERRIDE,&out)
3370 #define MKRELDATE(day,mth) st.wMonth = mth; st.wDay = day; \
3371 pSystemTimeToVariantTime(&st,&relative)
3373 static const char * const BadDateStrings[] =
3375 "True", "False", /* Plain text */
3376 "0.", ".0", "-1.1", "1.1-", /* Partial specifications */
3377 "1;2;3", "1*2*3", "1@2@3", "1#2#3", "(1:2)","<1:2>","1|2|3", /* Bad chars */
3378 "0", "1", /* 1 element */
3379 "0.60", "24.00", "0:60", "24:00", "1 2 am", "1 am 2", /* 2 elements */
3380 "1.5 2", "1 5.2", "2 32 3", "1 2 am 3", /* 3 elements */
3381 "1 2.3 4", "1.2.3 4", "1 2.3.4", "1.2 3.4", "1.2.3.4", "1 2 3 4",
3382 "1 am 2 3.4", "1 2 am 3.4", "1.2 3 am 4", "1.2 3 4 am", /* 4 elements */
3383 "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",
3384 "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",
3385 "1.2.3 4 am 5", "1.2.3 4 5 am", "1.2 3 am 4 5",
3386 "1.2 3 4 am 5", "1.2 3 4 5 am", "1 am 2 3.4.5", "1 2 am 3.4.5",
3387 "1 am 2 3 4.5", "1 2 am 3 4.5", "1 2 3 am 4.5", /* 5 elements */
3388 /* 6 elements */
3389 "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",
3390 "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",
3391 "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",
3392 "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",
3393 #if 0
3394 /* following throws an exception on winME */
3395 "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",
3396 #endif
3397 "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",
3398 #if 0
3399 /* following throws an exception on winME */
3400 "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",
3401 #endif
3402 "1 2 am 3 4.5.6", "1 2 3 am 4.5.6"
3405 static void test_VarDateFromStr(void)
3407 LCID lcid;
3408 DATE out, relative;
3409 HRESULT hres;
3410 SYSTEMTIME st;
3411 OLECHAR buff[128];
3412 size_t i;
3413 OLECHAR with_ideographic_spaceW[] = { '6','/','3','0','/','2','0','1','1',0x3000,
3414 '1',':','2','0',':','3','4',0 };
3416 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3418 CHECKPTR(VarDateFromStr);
3419 CHECKPTR(SystemTimeToVariantTime);
3421 /* Some date formats are relative, so we need to find the current year */
3422 GetSystemTime(&st);
3423 st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0;
3424 DFS(NULL); EXPECT_MISMATCH;
3426 /* Floating point number are not recognised */
3427 DFS("0.0");
3428 if (hres == S_OK)
3429 EXPECT_DBL(0.0); /* Very old versions accept this string */
3430 else
3431 EXPECT_MISMATCH;
3433 /* 1 element - can only be a time, and only if it has am/pm */
3434 DFS("1 am"); EXPECT_DBL(0.04166666666666666);
3435 /* 2 elements */
3436 /* A decimal point is treated as a time separator.
3437 * The following are converted as hours/minutes.
3439 DFS("0.1"); EXPECT_DBL(0.0006944444444444445);
3440 DFS("0.40"); EXPECT_DBL(0.02777777777777778);
3441 DFS("2.5"); EXPECT_DBL(0.08680555555555555);
3442 /* A colon acts as a decimal point */
3443 DFS("0:1"); EXPECT_DBL(0.0006944444444444445);
3444 DFS("0:20"); EXPECT_DBL(0.01388888888888889);
3445 DFS("0:40"); EXPECT_DBL(0.02777777777777778);
3446 DFS("3:5"); EXPECT_DBL(0.1284722222222222);
3447 /* Check the am/pm limits */
3448 DFS("00:00 AM"); EXPECT_DBL(0.0);
3449 DFS("00:00 a"); EXPECT_DBL(0.0);
3450 DFS("12:59 AM"); EXPECT_DBL(0.04097222222222222);
3451 DFS("12:59 A"); EXPECT_DBL(0.04097222222222222);
3452 DFS("00:00 pm"); EXPECT_DBL(0.5);
3453 DFS("00:00 p"); EXPECT_DBL(0.5);
3454 DFS("12:59 pm"); EXPECT_DBL(0.5409722222222222);
3455 DFS("12:59 p"); EXPECT_DBL(0.5409722222222222);
3456 /* AM/PM is ignored if hours > 12 */
3457 DFS("13:00 AM"); EXPECT_DBL(0.5416666666666666);
3458 DFS("13:00 PM"); EXPECT_DBL(0.5416666666666666);
3460 /* Space, dash and slash all indicate a date format. */
3461 /* If both numbers are valid month values => month/day of current year */
3462 DFS("1 2"); MKRELDATE(2,1); EXPECT_DBL(relative);
3463 DFS("2 1"); MKRELDATE(1,2); EXPECT_DBL(relative);
3464 /* one number not valid month, is a valid day, other number valid month:
3465 * that number becomes the day.
3467 DFS("14 1"); MKRELDATE(14,1); EXPECT_DBL(relative);
3468 DFS("1 14"); EXPECT_DBL(relative);
3469 /* If the numbers can't be day/month, they are assumed to be year/month */
3470 DFS("30 2"); EXPECT_DBL(10990.0);
3471 DFS("2 30"); EXPECT_DBL(10990.0);
3472 DFS("32 49"); EXPECT_MISMATCH; /* Can't be any format */
3473 DFS("0 49"); EXPECT_MISMATCH; /* Can't be any format */
3474 /* If a month name is given the other number is the day */
3475 DFS("Jan 2"); MKRELDATE(2,1); EXPECT_DBL(relative);
3476 DFS("2 Jan"); EXPECT_DBL(relative);
3477 /* Unless it can't be, in which case it becomes the year */
3478 DFS("Jan 35"); EXPECT_DBL(12785.0);
3479 DFS("35 Jan"); EXPECT_DBL(12785.0);
3480 DFS("Jan-35"); EXPECT_DBL(12785.0);
3481 DFS("35-Jan"); EXPECT_DBL(12785.0);
3482 DFS("Jan/35"); EXPECT_DBL(12785.0);
3483 DFS("35/Jan"); EXPECT_DBL(12785.0);
3484 /* 3 elements */
3485 /* 3 numbers and time separator => h:m:s */
3486 DFS("0.1.0"); EXPECT_DBL(0.0006944444444444445);
3487 DFS("1.5.2"); EXPECT_DBL(0.04516203703703704);
3488 /* 3 numbers => picks date giving preference to lcid format */
3489 DFS("1 2 3"); EXPECT_DBL(37623.0);
3490 DFS("14 2 3"); EXPECT_DBL(41673.0);
3491 DFS("2 14 3"); EXPECT_DBL(37666.0);
3492 DFS("2 3 14"); EXPECT_DBL(41673.0);
3493 DFS("32 2 3"); EXPECT_DBL(11722.0);
3494 DFS("2 3 32"); EXPECT_DBL(11722.0);
3495 DFS("1 2 29"); EXPECT_DBL(47120.0);
3496 /* After 30, two digit dates are expected to be in the 1900's */
3497 DFS("1 2 30"); EXPECT_DBL(10960.0);
3498 DFS("1 2 31"); EXPECT_DBL(11325.0);
3499 DFS("3 am 1 2"); MKRELDATE(2,1); relative += 0.125; EXPECT_DBL(relative);
3500 DFS("1 2 3 am"); EXPECT_DBL(relative);
3502 /* 4 elements -interpreted as 2 digit date & time */
3503 DFS("1.2 3 4"); MKRELDATE(4,3); relative += 0.04305555556; EXPECT_DBL(relative);
3504 DFS("3 4 1.2"); EXPECT_DBL(relative);
3505 /* 5 elements - interpreted as 2 & 3 digit date/times */
3506 DFS("1.2.3 4 5"); MKRELDATE(5,4); relative += 0.04309027778; EXPECT_DBL(relative);
3507 DFS("1.2 3 4 5"); EXPECT_DBL(38415.04305555556);
3508 #if 0
3509 /* following throws an exception on winME */
3510 DFS("1 2 3.4.5"); MKRELDATE(2,1); relative += 0.12783564815; EXPECT_DBL(relative);
3511 #endif
3512 DFS("1 2 3 4.5"); EXPECT_DBL(37623.17013888889);
3513 /* 6 elements - interpreted as 3 digit date/times */
3514 DFS("1.2.3 4 5 6"); EXPECT_DBL(38812.04309027778);
3515 DFS("1 2 3 4.5.6"); EXPECT_DBL(37623.17020833334);
3517 for (i = 0; i < sizeof(BadDateStrings)/sizeof(char*); i++)
3519 DFS(BadDateStrings[i]); EXPECT_MISMATCH;
3522 /* Some normal-ish strings */
3523 DFS("2 January, 1970"); EXPECT_DBL(25570.0);
3524 DFS("2 January 1970"); EXPECT_DBL(25570.0);
3525 DFS("2 Jan 1970"); EXPECT_DBL(25570.0);
3526 DFS("2/Jan/1970"); EXPECT_DBL(25570.0);
3527 DFS("2-Jan-1970"); EXPECT_DBL(25570.0);
3528 DFS("1 2 1970"); EXPECT_DBL(25570.0);
3529 DFS("1/2/1970"); EXPECT_DBL(25570.0);
3530 DFS("1-2-1970"); EXPECT_DBL(25570.0);
3531 DFS("13-1-1970"); EXPECT_DBL(25581.0);
3532 DFS("1970-1-13"); EXPECT_DBL(25581.0);
3533 DFS("6/30/2011 01:20:34"); EXPECT_DBL(40724.05594907407);
3534 DFS("6/30/2011 01:20:34 AM"); EXPECT_DBL(40724.05594907407);
3535 DFS("6/30/2011 01:20:34 PM"); EXPECT_DBL(40724.55594907407);
3536 /* Native fails "1999 January 3, 9AM". I consider that a bug in native */
3538 /* test a data with ideographic space */
3539 out = 0.0;
3540 hres = pVarDateFromStr(with_ideographic_spaceW, lcid, LOCALE_NOUSEROVERRIDE, &out);
3541 EXPECT_DBL(40724.05594907407);
3543 /* test a non-english data string */
3544 DFS("02.01.1970"); EXPECT_MISMATCH;
3545 DFS("02.01.1970 00:00:00"); EXPECT_MISMATCH;
3546 lcid = MAKELCID(MAKELANGID(LANG_GERMAN,SUBLANG_GERMAN),SORT_DEFAULT);
3547 DFS("02.01.1970"); EXPECT_DBL(25570.0);
3548 DFS("02.13.1970"); EXPECT_DBL(25612.0);
3549 DFS("02-13-1970"); EXPECT_DBL(25612.0);
3550 DFS("2020-01-11"); EXPECT_DBL(43841.0);
3551 DFS("2173-10-14"); EXPECT_DBL(100000.0);
3553 DFS("02.01.1970 00:00:00"); EXPECT_DBL(25570.0);
3554 lcid = MAKELCID(MAKELANGID(LANG_SPANISH,SUBLANG_SPANISH),SORT_DEFAULT);
3555 DFS("02.01.1970"); EXPECT_MISMATCH;
3556 DFS("02.01.1970 00:00:00"); EXPECT_MISMATCH;
3559 static void test_VarDateCopy(void)
3561 COPYTEST(77665544.0, VT_DATE, V_DATE(&vSrc), V_DATE(&vDst), V_DATEREF(&vSrc),
3562 V_DATEREF(&vDst), "%16.16g");
3565 static const char* wtoascii(LPWSTR lpszIn)
3567 static char buff[256];
3568 WideCharToMultiByte(CP_ACP, 0, lpszIn, -1, buff, sizeof(buff), NULL, NULL);
3569 return buff;
3572 static void test_VarDateChangeTypeEx(void)
3574 static const WCHAR sz25570[] = {
3575 '1','/','2','/','1','9','7','0','\0' };
3576 static const WCHAR sz25570_2[] = {
3577 '1','/','2','/','7','0','\0' };
3578 static const WCHAR sz25570Nls[] = {
3579 '1','/','2','/','1','9','7','0',' ','1','2',':','0','0',':','0','0',' ','A','M','\0' };
3580 HRESULT hres;
3581 DATE in;
3582 VARIANTARG vSrc, vDst;
3583 LCID lcid;
3585 in = 1.0;
3587 #ifdef HAS_UINT64_TO_FLOAT
3588 INITIAL_TYPETEST(VT_DATE, V_DATE, "%g");
3589 COMMON_TYPETEST;
3590 #endif
3592 V_VT(&vDst) = VT_EMPTY;
3593 V_VT(&vSrc) = VT_DATE;
3594 V_DATE(&vSrc) = 25570.0;
3595 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3597 hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, VARIANT_NOUSEROVERRIDE, VT_BSTR);
3598 ok(hres == S_OK && V_VT(&vDst) == VT_BSTR && V_BSTR(&vDst) &&
3599 (!lstrcmpW(V_BSTR(&vDst), sz25570) || !lstrcmpW(V_BSTR(&vDst), sz25570_2)),
3600 "hres=0x%X, type=%d (should be VT_BSTR), *bstr=%s\n",
3601 hres, V_VT(&vDst), V_BSTR(&vDst) ? wtoascii(V_BSTR(&vDst)) : "?");
3602 VariantClear(&vDst);
3604 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3605 if (has_locales)
3607 hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, VARIANT_NOUSEROVERRIDE|VARIANT_USE_NLS, VT_BSTR);
3608 ok(hres == S_OK && V_VT(&vDst) == VT_BSTR && V_BSTR(&vDst) && !lstrcmpW(V_BSTR(&vDst), sz25570Nls),
3609 "hres=0x%X, type=%d (should be VT_BSTR), *bstr=%s\n",
3610 hres, V_VT(&vDst), V_BSTR(&vDst) ? wtoascii(V_BSTR(&vDst)) : "?");
3611 VariantClear(&vDst);
3616 * VT_CY
3619 #undef CONV_TYPE
3620 #define CONV_TYPE CY
3622 #define EXPECTCY(x) \
3623 ok((hres == S_OK && out.int64 == (LONGLONG)(x*CY_MULTIPLIER)), \
3624 "expected " #x "*CY_MULTIPLIER, got (%8x %8x); hres=0x%08x\n", S(out).Hi, S(out).Lo, hres)
3626 #define EXPECTCY64(x,y) \
3627 ok(hres == S_OK && S(out).Hi == (LONG)x && S(out).Lo == y, \
3628 "expected " #x " " #y " (%u,%u), got (%u,%u); hres=0x%08x\n", \
3629 (ULONG)(x), (ULONG)(y), S(out).Hi, S(out).Lo, hres)
3631 static void test_VarCyFromI1(void)
3633 CONVVARS(signed char);
3634 int i;
3636 CHECKPTR(VarCyFromI1);
3637 for (i = -128; i < 128; i++)
3639 CONVERT(VarCyFromI1,i); EXPECTCY(i);
3643 static void test_VarCyFromUI1(void)
3645 CONVVARS(BYTE);
3646 int i;
3648 CHECKPTR(VarCyFromUI1);
3649 for (i = 0; i < 256; i++)
3651 CONVERT(VarCyFromUI1,i); EXPECTCY(i);
3655 static void test_VarCyFromI2(void)
3657 CONVVARS(SHORT);
3658 int i;
3660 CHECKPTR(VarCyFromI2);
3661 for (i = -16384; i < 16384; i++)
3663 CONVERT(VarCyFromI2,i); EXPECTCY(i);
3667 static void test_VarCyFromUI2(void)
3669 CONVVARS(int);
3670 int i;
3672 CHECKPTR(VarCyFromUI2);
3673 for (i = 0; i < 32768; i++)
3675 CONVERT(VarCyFromUI2,i); EXPECTCY(i);
3679 static void test_VarCyFromI4(void)
3681 CONVVARS(int);
3683 CHECKPTR(VarCyFromI4);
3684 CONVERT(VarCyFromI4, -1); EXPECTCY(-1);
3685 CONVERT(VarCyFromI4, 0); EXPECTCY(0);
3686 CONVERT(VarCyFromI4, 1); EXPECTCY(1);
3687 CONVERT(VarCyFromI4, 0x7fffffff); EXPECTCY64(0x1387, 0xffffd8f0);
3688 CONVERT(VarCyFromI4, 0x80000000); EXPECTCY64(0xffffec78, 0);
3691 static void test_VarCyFromUI4(void)
3693 CONVVARS(unsigned int);
3695 CHECKPTR(VarCyFromUI4);
3696 CONVERT(VarCyFromUI4, 0); EXPECTCY(0);
3697 CONVERT(VarCyFromUI4, 1); EXPECTCY(1);
3698 CONVERT(VarCyFromUI4, 0x80000000); EXPECTCY64(5000, 0);
3701 static void test_VarCyFromR4(void)
3703 CONVVARS(FLOAT);
3705 CHECKPTR(VarCyFromR4);
3706 CONVERT(VarCyFromR4, -1.0f); EXPECTCY(-1);
3707 CONVERT(VarCyFromR4, 0.0f); EXPECTCY(0);
3708 CONVERT(VarCyFromR4, 1.0f); EXPECTCY(1);
3709 CONVERT(VarCyFromR4, 1.5f); EXPECTCY(1.5);
3711 CONVERT(VarCyFromR4, -1.5f); EXPECTCY(-1.5);
3712 CONVERT(VarCyFromR4, -0.6f); EXPECTCY(-0.6);
3713 CONVERT(VarCyFromR4, -0.5f); EXPECTCY(-0.5);
3714 CONVERT(VarCyFromR4, -0.4f); EXPECTCY(-0.4);
3715 CONVERT(VarCyFromR4, 0.4f); EXPECTCY(0.4);
3716 CONVERT(VarCyFromR4, 0.5f); EXPECTCY(0.5);
3717 CONVERT(VarCyFromR4, 0.6f); EXPECTCY(0.6);
3718 CONVERT(VarCyFromR4, 1.5f); EXPECTCY(1.5);
3719 CONVERT(VarCyFromR4, 1.00009f); EXPECTCY(1.0001);
3720 CONVERT(VarCyFromR4, -1.00001f); EXPECTCY(-1);
3721 CONVERT(VarCyFromR4, -1.00005f); EXPECTCY(-1);
3722 CONVERT(VarCyFromR4, -0.00009f); EXPECTCY(-0.0001);
3723 CONVERT(VarCyFromR4, -0.00005f); EXPECTCY(0);
3724 CONVERT(VarCyFromR4, -0.00001f); EXPECTCY(0);
3725 CONVERT(VarCyFromR4, 0.00001f); EXPECTCY(0);
3726 CONVERT(VarCyFromR4, 0.00005f); EXPECTCY(0);
3727 CONVERT(VarCyFromR4, 0.00009f); EXPECTCY(0.0001);
3728 CONVERT(VarCyFromR4, -1.00001f); EXPECTCY(-1);
3729 CONVERT(VarCyFromR4, -1.00005f); EXPECTCY(-1);
3730 CONVERT(VarCyFromR4, -1.00009f); EXPECTCY(-1.0001);
3733 static void test_VarCyFromR8(void)
3735 CONVVARS(DOUBLE);
3737 CHECKPTR(VarCyFromR8);
3739 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
3740 /* Test our rounding is exactly the same. This fails if the special x86
3741 * code is taken out of VarCyFromR8.
3743 CONVERT(VarCyFromR8, -461168601842738.7904); EXPECTCY64(0xbfffffff, 0xffffff23);
3744 #endif
3746 CONVERT(VarCyFromR8, -4611686018427388416.1); EXPECT_OVERFLOW;
3747 CONVERT(VarCyFromR8, -1.0); EXPECTCY(-1);
3748 CONVERT(VarCyFromR8, -0.0); EXPECTCY(0);
3749 CONVERT(VarCyFromR8, 1.0); EXPECTCY(1);
3750 CONVERT(VarCyFromR8, 4611686018427387648.0); EXPECT_OVERFLOW;
3752 /* Rounding */
3753 CONVERT(VarCyFromR8, -1.5f); EXPECTCY(-1.5);
3754 CONVERT(VarCyFromR8, -0.6f); EXPECTCY(-0.6);
3755 CONVERT(VarCyFromR8, -0.5f); EXPECTCY(-0.5);
3756 CONVERT(VarCyFromR8, -0.4f); EXPECTCY(-0.4);
3757 CONVERT(VarCyFromR8, 0.4f); EXPECTCY(0.4);
3758 CONVERT(VarCyFromR8, 0.5f); EXPECTCY(0.5);
3759 CONVERT(VarCyFromR8, 0.6f); EXPECTCY(0.6);
3760 CONVERT(VarCyFromR8, 1.5f); EXPECTCY(1.5);
3761 CONVERT(VarCyFromR8, 1.00009f); EXPECTCY(1.0001);
3762 CONVERT(VarCyFromR8, -1.00001f); EXPECTCY(-1);
3763 CONVERT(VarCyFromR8, -1.00005f); EXPECTCY(-1);
3764 CONVERT(VarCyFromR8, -0.00009f); EXPECTCY(-0.0001);
3765 CONVERT(VarCyFromR8, -0.00005f); EXPECTCY(0);
3766 CONVERT(VarCyFromR8, -0.00001f); EXPECTCY(0);
3767 CONVERT(VarCyFromR8, 0.00001f); EXPECTCY(0);
3768 CONVERT(VarCyFromR8, 0.00005f); EXPECTCY(0);
3769 CONVERT(VarCyFromR8, 0.00009f); EXPECTCY(0.0001);
3770 CONVERT(VarCyFromR8, -1.00001f); EXPECTCY(-1);
3771 CONVERT(VarCyFromR8, -1.00005f); EXPECTCY(-1);
3772 CONVERT(VarCyFromR8, -1.00009f); EXPECTCY(-1.0001);
3775 static void test_VarCyFromBool(void)
3777 CONVVARS(VARIANT_BOOL);
3778 int i;
3780 CHECKPTR(VarCyFromBool);
3781 for (i = -32768; i < 32768; i++)
3783 CONVERT(VarCyFromBool, i); EXPECTCY(i);
3787 static void test_VarCyFromI8(void)
3789 CONVVARS(LONG64);
3791 CHECKPTR(VarCyFromI8);
3792 CONVERT_I8(VarCyFromI8, -214749, 2728163227ul); EXPECT_OVERFLOW;
3793 CONVERT_I8(VarCyFromI8, -214749, 2728163228ul); EXPECTCY64(2147483648ul,15808);
3794 CONVERT(VarCyFromI8, -1); EXPECTCY(-1);
3795 CONVERT(VarCyFromI8, 0); EXPECTCY(0);
3796 CONVERT(VarCyFromI8, 1); EXPECTCY(1);
3797 CONVERT_I8(VarCyFromI8, 214748, 1566804068); EXPECTCY64(2147483647ul, 4294951488ul);
3798 CONVERT_I8(VarCyFromI8, 214748, 1566804069); EXPECT_OVERFLOW;
3801 static void test_VarCyFromUI8(void)
3803 CONVVARS(ULONG64);
3805 CHECKPTR(VarCyFromUI8);
3806 CONVERT(VarCyFromUI8, 0); EXPECTCY(0);
3807 CONVERT(VarCyFromUI8, 1); EXPECTCY(1);
3808 CONVERT_I8(VarCyFromUI8, 214748, 1566804068); EXPECTCY64(2147483647ul, 4294951488ul);
3809 CONVERT_I8(VarCyFromUI8, 214748, 1566804069); EXPECTCY64(2147483647ul, 4294961488ul);
3810 CONVERT_I8(VarCyFromUI8, 214748, 1566804070); EXPECT_OVERFLOW;
3811 CONVERT_I8(VarCyFromUI8, 214749, 1566804068); EXPECT_OVERFLOW;
3814 static void test_VarCyFromDec(void)
3816 CONVVARS(DECIMAL);
3818 CHECKPTR(VarCyFromDec);
3820 CONVERT_BADDEC(VarCyFromDec);
3822 CONVERT_DEC(VarCyFromDec,0,0x80,0,1); EXPECTCY(-1);
3823 CONVERT_DEC(VarCyFromDec,0,0,0,0); EXPECTCY(0);
3824 CONVERT_DEC(VarCyFromDec,0,0,0,1); EXPECTCY(1);
3826 CONVERT_DEC64(VarCyFromDec,0,0,0,214748, 1566804068); EXPECTCY64(2147483647ul, 4294951488ul);
3827 CONVERT_DEC64(VarCyFromDec,0,0,0,214748, 1566804069); EXPECTCY64(2147483647ul, 4294961488ul);
3828 CONVERT_DEC64(VarCyFromDec,0,0,0,214748, 1566804070); EXPECT_OVERFLOW;
3829 CONVERT_DEC64(VarCyFromDec,0,0,0,214749, 1566804068); EXPECT_OVERFLOW;
3831 CONVERT_DEC(VarCyFromDec,2,0,0,100); EXPECTCY(1);
3832 CONVERT_DEC(VarCyFromDec,2,0x80,0,100); EXPECTCY(-1);
3833 CONVERT_DEC(VarCyFromDec,2,0x80,0,1); EXPECTCY(-0.01);
3834 CONVERT_DEC(VarCyFromDec,2,0,0,1); EXPECTCY(0.01);
3835 CONVERT_DEC(VarCyFromDec,2,0x80,0,1); EXPECTCY(-0.01);
3836 CONVERT_DEC(VarCyFromDec,2,0,0,999); EXPECTCY(9.99);
3837 CONVERT_DEC(VarCyFromDec,2,0x80,0,999); EXPECTCY(-9.99);
3838 CONVERT_DEC(VarCyFromDec,2,0,0,1500); EXPECTCY(15);
3839 CONVERT_DEC(VarCyFromDec,2,0x80,0,1500); EXPECTCY(-15);
3842 static void test_VarCyFromDate(void)
3844 CONVVARS(DATE);
3846 CHECKPTR(VarCyFromDate);
3848 #if defined(__i386__) && (defined(_MSC_VER) || defined(__GNUC__))
3849 CONVERT(VarCyFromR8, -461168601842738.7904); EXPECTCY64(0xbfffffff, 0xffffff23);
3850 #endif
3852 CONVERT(VarCyFromDate, -1.0); EXPECTCY(-1);
3853 CONVERT(VarCyFromDate, -0.0); EXPECTCY(0);
3854 CONVERT(VarCyFromDate, 1.0); EXPECTCY(1);
3855 CONVERT(VarCyFromDate, -4611686018427388416.1); EXPECT_OVERFLOW;
3856 CONVERT(VarCyFromDate, 4611686018427387648.0); EXPECT_OVERFLOW;
3858 /* Rounding */
3859 CONVERT(VarCyFromDate, -1.5f); EXPECTCY(-1.5);
3860 CONVERT(VarCyFromDate, -0.6f); EXPECTCY(-0.6);
3861 CONVERT(VarCyFromDate, -0.5f); EXPECTCY(-0.5);
3862 CONVERT(VarCyFromDate, -0.4f); EXPECTCY(-0.4);
3863 CONVERT(VarCyFromDate, 0.4f); EXPECTCY(0.4);
3864 CONVERT(VarCyFromDate, 0.5f); EXPECTCY(0.5);
3865 CONVERT(VarCyFromDate, 0.6f); EXPECTCY(0.6);
3866 CONVERT(VarCyFromDate, 1.5f); EXPECTCY(1.5);
3867 CONVERT(VarCyFromDate, 1.00009f); EXPECTCY(1.0001);
3868 CONVERT(VarCyFromDate, -1.00001f); EXPECTCY(-1);
3869 CONVERT(VarCyFromDate, -1.00005f); EXPECTCY(-1);
3870 CONVERT(VarCyFromDate, -0.00009f); EXPECTCY(-0.0001);
3871 CONVERT(VarCyFromDate, -0.00005f); EXPECTCY(0);
3872 CONVERT(VarCyFromDate, -0.00001f); EXPECTCY(0);
3873 CONVERT(VarCyFromDate, 0.00001f); EXPECTCY(0);
3874 CONVERT(VarCyFromDate, 0.00005f); EXPECTCY(0);
3875 CONVERT(VarCyFromDate, 0.00009f); EXPECTCY(0.0001);
3876 CONVERT(VarCyFromDate, -1.00001f); EXPECTCY(-1);
3877 CONVERT(VarCyFromDate, -1.00005f); EXPECTCY(-1);
3878 CONVERT(VarCyFromDate, -1.00009f); EXPECTCY(-1.0001);
3881 #define MATHVARS1 HRESULT hres; double left = 0.0; CY cyLeft, out
3882 #define MATHVARS2 MATHVARS1; double right = 0.0; CY cyRight
3883 #define MATH1(func, l) left = (double)l; pVarCyFromR8(left, &cyLeft); hres = p##func(cyLeft, &out)
3884 #define MATH2(func, l, r) left = (double)l; right = (double)r; \
3885 pVarCyFromR8(left, &cyLeft); pVarCyFromR8(right, &cyRight); \
3886 hres = p##func(cyLeft, cyRight, &out)
3888 static void test_VarCyAdd(void)
3890 MATHVARS2;
3892 CHECKPTR(VarCyAdd);
3893 MATH2(VarCyAdd, 0.5, 0.5); EXPECTCY(1);
3894 MATH2(VarCyAdd, 0.5, -0.4); EXPECTCY(0.1);
3895 MATH2(VarCyAdd, 0.5, -0.6); EXPECTCY(-0.1);
3896 MATH2(VarCyAdd, -0.5, -0.5); EXPECTCY(-1);
3897 MATH2(VarCyAdd, -922337203685476.0, -922337203685476.0); EXPECT_OVERFLOW;
3898 MATH2(VarCyAdd, -922337203685476.0, 922337203685476.0); EXPECTCY(0);
3899 MATH2(VarCyAdd, 922337203685476.0, -922337203685476.0); EXPECTCY(0);
3900 MATH2(VarCyAdd, 922337203685476.0, 922337203685476.0); EXPECT_OVERFLOW;
3903 static void test_VarCyMul(void)
3905 MATHVARS2;
3907 CHECKPTR(VarCyMul);
3908 MATH2(VarCyMul, 534443.0, 0.0); EXPECTCY(0);
3909 MATH2(VarCyMul, 0.5, 0.5); EXPECTCY(0.25);
3910 MATH2(VarCyMul, 0.5, -0.4); EXPECTCY(-0.2);
3911 MATH2(VarCyMul, 0.5, -0.6); EXPECTCY(-0.3);
3912 MATH2(VarCyMul, -0.5, -0.5); EXPECTCY(0.25);
3913 MATH2(VarCyMul, 922337203685476.0, 20000); EXPECT_OVERFLOW;
3916 static void test_VarCySub(void)
3918 MATHVARS2;
3920 CHECKPTR(VarCySub);
3921 MATH2(VarCySub, 0.5, 0.5); EXPECTCY(0);
3922 MATH2(VarCySub, 0.5, -0.4); EXPECTCY(0.9);
3923 MATH2(VarCySub, 0.5, -0.6); EXPECTCY(1.1);
3924 MATH2(VarCySub, -0.5, -0.5); EXPECTCY(0);
3925 MATH2(VarCySub, -922337203685476.0, -922337203685476.0); EXPECTCY(0);
3926 MATH2(VarCySub, -922337203685476.0, 922337203685476.0); EXPECT_OVERFLOW;
3927 MATH2(VarCySub, 922337203685476.0, -922337203685476.0); EXPECT_OVERFLOW;
3928 MATH2(VarCySub, 922337203685476.0, 922337203685476.0); EXPECTCY(0);
3931 static void test_VarCyAbs(void)
3933 MATHVARS1;
3935 CHECKPTR(VarCyAbs);
3936 MATH1(VarCyAbs, 0.5); EXPECTCY(0.5);
3937 MATH1(VarCyAbs, -0.5); EXPECTCY(0.5);
3938 MATH1(VarCyAbs, 922337203685476.0); EXPECTCY64(2147483647ul,4294951488ul);
3939 MATH1(VarCyAbs, -922337203685476.0); EXPECTCY64(2147483647ul,4294951488ul);
3942 static void test_VarCyNeg(void)
3944 MATHVARS1;
3946 CHECKPTR(VarCyNeg);
3947 MATH1(VarCyNeg, 0.5); EXPECTCY(-0.5);
3948 MATH1(VarCyNeg, -0.5); EXPECTCY(0.5);
3949 MATH1(VarCyNeg, 922337203685476.0); EXPECTCY64(2147483648ul,15808);
3950 MATH1(VarCyNeg, -922337203685476.0); EXPECTCY64(2147483647ul,4294951488ul);
3953 #define MATHMULI4(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
3954 hres = pVarCyMulI4(cyLeft, right, &out)
3956 static void test_VarCyMulI4(void)
3958 MATHVARS1;
3959 LONG right;
3961 CHECKPTR(VarCyMulI4);
3962 MATHMULI4(534443.0, 0); EXPECTCY(0);
3963 MATHMULI4(0.5, 1); EXPECTCY(0.5);
3964 MATHMULI4(0.5, 2); EXPECTCY(1);
3965 MATHMULI4(922337203685476.0, 1); EXPECTCY64(2147483647ul,4294951488ul);
3966 MATHMULI4(922337203685476.0, 2); EXPECT_OVERFLOW;
3969 #define MATHMULI8(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
3970 hres = pVarCyMulI8(cyLeft, right, &out)
3972 static void test_VarCyMulI8(void)
3974 MATHVARS1;
3975 LONG64 right;
3977 CHECKPTR(VarCyMulI8);
3978 MATHMULI8(534443.0, 0); EXPECTCY(0);
3979 MATHMULI8(0.5, 1); EXPECTCY(0.5);
3980 MATHMULI8(0.5, 2); EXPECTCY(1);
3981 MATHMULI8(922337203685476.0, 1); EXPECTCY64(2147483647ul,4294951488ul);
3982 MATHMULI8(922337203685476.0, 2); EXPECT_OVERFLOW;
3985 #define MATHCMP(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); pVarCyFromR8(right, &cyRight); \
3986 hres = pVarCyCmp(cyLeft, cyRight)
3988 static void test_VarCyCmp(void)
3990 HRESULT hres;
3991 double left = 0.0, right = 0.0;
3992 CY cyLeft, cyRight;
3994 CHECKPTR(VarCyCmp);
3995 MATHCMP(-1.0, -1.0); EXPECT_EQ;
3996 MATHCMP(-1.0, 0.0); EXPECT_LT;
3997 MATHCMP(-1.0, 1.0); EXPECT_LT;
3998 MATHCMP(-1.0, 2.0); EXPECT_LT;
3999 MATHCMP(0.0, 1.0); EXPECT_LT;
4000 MATHCMP(0.0, 0.0); EXPECT_EQ;
4001 MATHCMP(0.0, -1.0); EXPECT_GT;
4002 MATHCMP(1.0, -1.0); EXPECT_GT;
4003 MATHCMP(1.0, 0.0); EXPECT_GT;
4004 MATHCMP(1.0, 1.0); EXPECT_EQ;
4005 MATHCMP(1.0, 2.0); EXPECT_LT;
4008 #define MATHCMPR8(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
4009 hres = pVarCyCmpR8(cyLeft, right);
4011 static void test_VarCyCmpR8(void)
4013 HRESULT hres;
4014 double left = 0.0;
4015 CY cyLeft;
4016 double right;
4018 CHECKPTR(VarCyCmpR8);
4019 MATHCMPR8(-1.0, -1.0); EXPECT_EQ;
4020 MATHCMPR8(-1.0, 0.0); EXPECT_LT;
4021 MATHCMPR8(-1.0, 1.0); EXPECT_LT;
4022 MATHCMPR8(-1.0, 2.0); EXPECT_LT;
4023 MATHCMPR8(0.0, 1.0); EXPECT_LT;
4024 MATHCMPR8(0.0, 0.0); EXPECT_EQ;
4025 MATHCMPR8(0.0, -1.0); EXPECT_GT;
4026 MATHCMPR8(1.0, -1.0); EXPECT_GT;
4027 MATHCMPR8(1.0, 0.0); EXPECT_GT;
4028 MATHCMPR8(1.0, 1.0); EXPECT_EQ;
4029 MATHCMPR8(1.0, 2.0); EXPECT_LT;
4032 #undef MATHRND
4033 #define MATHRND(l, r) left = l; right = r; pVarCyFromR8(left, &cyLeft); \
4034 hres = pVarCyRound(cyLeft, right, &out)
4036 static void test_VarCyRound(void)
4038 MATHVARS1;
4039 int right;
4041 CHECKPTR(VarCyRound);
4042 MATHRND(0.5432, 5); EXPECTCY(0.5432);
4043 MATHRND(0.5432, 4); EXPECTCY(0.5432);
4044 MATHRND(0.5432, 3); EXPECTCY(0.543);
4045 MATHRND(0.5432, 2); EXPECTCY(0.54);
4046 MATHRND(0.5432, 1); EXPECTCY(0.5);
4047 MATHRND(0.5532, 0); EXPECTCY(1);
4048 MATHRND(0.5532, -1); EXPECT_INVALID;
4050 MATHRND(0.5568, 5); EXPECTCY(0.5568);
4051 MATHRND(0.5568, 4); EXPECTCY(0.5568);
4052 MATHRND(0.5568, 3); EXPECTCY(0.557);
4053 MATHRND(0.5568, 2); EXPECTCY(0.56);
4054 MATHRND(0.5568, 1); EXPECTCY(0.6);
4055 MATHRND(0.5568, 0); EXPECTCY(1);
4056 MATHRND(0.5568, -1); EXPECT_INVALID;
4058 MATHRND(0.4999, 0); EXPECTCY(0);
4059 MATHRND(0.5000, 0); EXPECTCY(0);
4060 MATHRND(0.5001, 0); EXPECTCY(1);
4061 MATHRND(1.4999, 0); EXPECTCY(1);
4062 MATHRND(1.5000, 0); EXPECTCY(2);
4063 MATHRND(1.5001, 0); EXPECTCY(2);
4066 #define MATHFIX(l) left = l; pVarCyFromR8(left, &cyLeft); \
4067 hres = pVarCyFix(cyLeft, &out)
4069 static void test_VarCyFix(void)
4071 MATHVARS1;
4073 CHECKPTR(VarCyFix);
4074 MATHFIX(-1.0001); EXPECTCY(-1);
4075 MATHFIX(-1.4999); EXPECTCY(-1);
4076 MATHFIX(-1.5001); EXPECTCY(-1);
4077 MATHFIX(-1.9999); EXPECTCY(-1);
4078 MATHFIX(-0.0001); EXPECTCY(0);
4079 MATHFIX(-0.4999); EXPECTCY(0);
4080 MATHFIX(-0.5001); EXPECTCY(0);
4081 MATHFIX(-0.9999); EXPECTCY(0);
4082 MATHFIX(0.0001); EXPECTCY(0);
4083 MATHFIX(0.4999); EXPECTCY(0);
4084 MATHFIX(0.5001); EXPECTCY(0);
4085 MATHFIX(0.9999); EXPECTCY(0);
4086 MATHFIX(1.0001); EXPECTCY(1);
4087 MATHFIX(1.4999); EXPECTCY(1);
4088 MATHFIX(1.5001); EXPECTCY(1);
4089 MATHFIX(1.9999); EXPECTCY(1);
4092 #define MATHINT(l) left = l; pVarCyFromR8(left, &cyLeft); \
4093 hres = pVarCyInt(cyLeft, &out)
4095 static void test_VarCyInt(void)
4097 MATHVARS1;
4099 CHECKPTR(VarCyInt);
4100 MATHINT(-1.0001); EXPECTCY(-2);
4101 MATHINT(-1.4999); EXPECTCY(-2);
4102 MATHINT(-1.5001); EXPECTCY(-2);
4103 MATHINT(-1.9999); EXPECTCY(-2);
4104 MATHINT(-0.0001); EXPECTCY(-1);
4105 MATHINT(-0.4999); EXPECTCY(-1);
4106 MATHINT(-0.5001); EXPECTCY(-1);
4107 MATHINT(-0.9999); EXPECTCY(-1);
4108 MATHINT(0.0001); EXPECTCY(0);
4109 MATHINT(0.4999); EXPECTCY(0);
4110 MATHINT(0.5001); EXPECTCY(0);
4111 MATHINT(0.9999); EXPECTCY(0);
4112 MATHINT(1.0001); EXPECTCY(1);
4113 MATHINT(1.4999); EXPECTCY(1);
4114 MATHINT(1.5001); EXPECTCY(1);
4115 MATHINT(1.9999); EXPECTCY(1);
4119 * VT_DECIMAL
4122 #undef CONV_TYPE
4123 #define CONV_TYPE DECIMAL
4125 #define EXPECTDEC(scl, sgn, hi, lo) ok(hres == S_OK && \
4126 S(U(out)).scale == (BYTE)(scl) && S(U(out)).sign == (BYTE)(sgn) && \
4127 out.Hi32 == (ULONG)(hi) && U1(out).Lo64 == (ULONG64)(lo), \
4128 "expected (%d,%d,%d,(%x %x)), got (%d,%d,%d,(%x %x)) hres 0x%08x\n", \
4129 scl, sgn, hi, (LONG)((LONG64)(lo) >> 32), (LONG)((lo) & 0xffffffff), S(U(out)).scale, \
4130 S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres)
4132 #define EXPECTDEC64(scl, sgn, hi, mid, lo) ok(hres == S_OK && \
4133 S(U(out)).scale == (BYTE)(scl) && S(U(out)).sign == (BYTE)(sgn) && \
4134 out.Hi32 == (ULONG)(hi) && S1(U1(out)).Mid32 == (ULONG)(mid) && \
4135 S1(U1(out)).Lo32 == (ULONG)(lo), \
4136 "expected (%d,%d,%d,(%x %x)), got (%d,%d,%d,(%x %x)) hres 0x%08x\n", \
4137 scl, sgn, hi, (LONG)(mid), (LONG)(lo), S(U(out)).scale, \
4138 S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres)
4140 /* expect either a positive or negative zero */
4141 #define EXPECTDECZERO() ok(hres == S_OK && S(U(out)).scale == 0 && \
4142 (S(U(out)).sign == 0 || S(U(out)).sign == 0x80) && out.Hi32 == 0 && U1(out).Lo64 == 0, \
4143 "expected zero, got (%d,%d,%d,(%x %x)) hres 0x%08x\n", \
4144 S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres)
4146 #define EXPECTDECI if (i < 0) EXPECTDEC(0, 0x80, 0, -i); else EXPECTDEC(0, 0, 0, i)
4148 static void test_VarDecFromI1(void)
4150 CONVVARS(signed char);
4151 int i;
4153 CHECKPTR(VarDecFromI1);
4154 for (i = -128; i < 128; i++)
4156 CONVERT(VarDecFromI1,i); EXPECTDECI;
4160 static void test_VarDecFromI2(void)
4162 CONVVARS(SHORT);
4163 int i;
4165 CHECKPTR(VarDecFromI2);
4166 for (i = -32768; i < 32768; i++)
4168 CONVERT(VarDecFromI2,i); EXPECTDECI;
4172 static void test_VarDecFromI4(void)
4174 CONVVARS(LONG);
4175 int i;
4177 CHECKPTR(VarDecFromI4);
4178 for (i = -32768; i < 32768; i++)
4180 CONVERT(VarDecFromI4,i); EXPECTDECI;
4184 static void test_VarDecFromI8(void)
4186 CONVVARS(LONG64);
4187 int i;
4189 CHECKPTR(VarDecFromI8);
4190 for (i = -32768; i < 32768; i++)
4192 CONVERT(VarDecFromI8,i); EXPECTDECI;
4196 static void test_VarDecFromUI1(void)
4198 CONVVARS(BYTE);
4199 int i;
4201 CHECKPTR(VarDecFromUI1);
4202 for (i = 0; i < 256; i++)
4204 CONVERT(VarDecFromUI1,i); EXPECTDECI;
4208 static void test_VarDecFromUI2(void)
4210 CONVVARS(USHORT);
4211 int i;
4213 CHECKPTR(VarDecFromUI2);
4214 for (i = 0; i < 65536; i++)
4216 CONVERT(VarDecFromUI2,i); EXPECTDECI;
4220 static void test_VarDecFromUI4(void)
4222 CONVVARS(ULONG);
4223 int i;
4225 CHECKPTR(VarDecFromUI4);
4226 for (i = 0; i < 65536; i++)
4228 CONVERT(VarDecFromUI4,i); EXPECTDECI;
4232 static void test_VarDecFromUI8(void)
4234 CONVVARS(ULONG64);
4235 int i;
4237 CHECKPTR(VarDecFromUI8);
4238 for (i = 0; i < 65536; i++)
4240 CONVERT(VarDecFromUI8,i); EXPECTDECI;
4244 static void test_VarDecFromBool(void)
4246 CONVVARS(SHORT);
4247 int i;
4249 CHECKPTR(VarDecFromBool);
4250 /* Test all possible type values. Note that the result is reduced to 0 or -1 */
4251 for (i = -32768; i < 0; i++)
4253 CONVERT(VarDecFromBool,i);
4254 if (i)
4255 EXPECTDEC(0,0x80,0,1);
4256 else
4257 EXPECTDEC(0,0,0,0);
4261 static void test_VarDecFromR4(void)
4263 CONVVARS(float);
4265 CHECKPTR(VarDecFromR4);
4267 CONVERT(VarDecFromR4,-0.6f); EXPECTDEC(1,0x80,0,6);
4268 CONVERT(VarDecFromR4,-0.5f); EXPECTDEC(1,0x80,0,5);
4269 CONVERT(VarDecFromR4,-0.4f); EXPECTDEC(1,0x80,0,4);
4270 CONVERT(VarDecFromR4,0.0f); EXPECTDEC(0,0,0,0);
4271 CONVERT(VarDecFromR4,0.4f); EXPECTDEC(1,0,0,4);
4272 CONVERT(VarDecFromR4,0.5f); EXPECTDEC(1,0,0,5);
4273 CONVERT(VarDecFromR4,0.6f); EXPECTDEC(1,0,0,6);
4276 static void test_VarDecFromR8(void)
4278 CONVVARS(double);
4280 CHECKPTR(VarDecFromR8);
4282 CONVERT(VarDecFromR8,-0.6); EXPECTDEC(1,0x80,0,6);
4283 CONVERT(VarDecFromR8,-0.5); EXPECTDEC(1,0x80,0,5);
4284 CONVERT(VarDecFromR8,-0.4); EXPECTDEC(1,0x80,0,4);
4285 CONVERT(VarDecFromR8,0.0); EXPECTDEC(0,0,0,0);
4286 CONVERT(VarDecFromR8,0.4); EXPECTDEC(1,0,0,4);
4287 CONVERT(VarDecFromR8,0.5); EXPECTDEC(1,0,0,5);
4288 CONVERT(VarDecFromR8,0.6); EXPECTDEC(1,0,0,6);
4291 static void test_VarDecFromDate(void)
4293 CONVVARS(DATE);
4295 CHECKPTR(VarDecFromDate);
4297 CONVERT(VarDecFromDate,-0.6); EXPECTDEC(1,0x80,0,6);
4298 CONVERT(VarDecFromDate,-0.5); EXPECTDEC(1,0x80,0,5);
4299 CONVERT(VarDecFromDate,-0.4); EXPECTDEC(1,0x80,0,4);
4300 CONVERT(VarDecFromDate,0.0); EXPECTDEC(0,0,0,0);
4301 CONVERT(VarDecFromDate,0.4); EXPECTDEC(1,0,0,4);
4302 CONVERT(VarDecFromDate,0.5); EXPECTDEC(1,0,0,5);
4303 CONVERT(VarDecFromDate,0.6); EXPECTDEC(1,0,0,6);
4306 static void test_VarDecFromStr(void)
4308 CONVVARS(LCID);
4309 OLECHAR buff[128];
4311 CHECKPTR(VarDecFromStr);
4313 in = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4315 CONVERT_STR(VarDecFromStr,NULL,0); EXPECT_MISMATCH;
4316 CONVERT_STR(VarDecFromStr,"-1", LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0x80,0,1);
4317 CONVERT_STR(VarDecFromStr,"0", LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,0,0);
4318 CONVERT_STR(VarDecFromStr,"1", LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,0,1);
4319 CONVERT_STR(VarDecFromStr,"0.5", LOCALE_NOUSEROVERRIDE); EXPECTDEC(1,0,0,5);
4320 CONVERT_STR(VarDecFromStr,"4294967296", LOCALE_NOUSEROVERRIDE); EXPECTDEC64(0,0,0,1,0);
4321 CONVERT_STR(VarDecFromStr,"18446744073709551616", LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,1,0);
4322 CONVERT_STR(VarDecFromStr,"4294967296.0", LOCALE_NOUSEROVERRIDE); EXPECTDEC64(0,0,0,1,0);
4323 CONVERT_STR(VarDecFromStr,"18446744073709551616.0", LOCALE_NOUSEROVERRIDE); EXPECTDEC(0,0,1,0);
4326 static void test_VarDecFromCy(void)
4328 CONVVARS(CY);
4330 CHECKPTR(VarDecFromCy);
4332 CONVERT_CY(VarDecFromCy, -1); EXPECTDEC(4,0x80,0,10000);
4333 CONVERT_CY(VarDecFromCy, 0); EXPECTDEC(4,0,0,0);
4334 CONVERT_CY(VarDecFromCy, 1); EXPECTDEC(4,0,0,10000);
4335 CONVERT_CY(VarDecFromCy, 0.5); EXPECTDEC(4,0,0,5000);
4338 #undef MATHVARS1
4339 #define MATHVARS1 HRESULT hres; DECIMAL l, out
4340 #undef MATHVARS2
4341 #define MATHVARS2 MATHVARS1; DECIMAL r
4342 #undef MATH1
4343 #define MATH1(func) hres = p##func(&l, &out)
4344 #undef MATH2
4345 #define MATH2(func) hres = p##func(&l, &r, &out)
4346 #undef MATH3
4347 #define MATH3(func) hres = p##func(&l, r)
4349 static void test_VarDecAbs(void)
4351 MATHVARS1;
4353 CHECKPTR(VarDecAbs);
4354 SETDEC(l,0,0x80,0,1); MATH1(VarDecAbs); EXPECTDEC(0,0,0,1);
4355 SETDEC(l,0,0,0,0); MATH1(VarDecAbs); EXPECTDEC(0,0,0,0);
4356 SETDEC(l,0,0x80,0,0); MATH1(VarDecAbs); EXPECTDEC(0,0,0,0);
4357 SETDEC(l,0,0,0,1); MATH1(VarDecAbs); EXPECTDEC(0,0,0,1);
4359 /* Doesn't check for invalid input */
4360 SETDEC(l,0,0x7f,0,1); MATH1(VarDecAbs); EXPECTDEC(0,0x7f,0,1);
4361 SETDEC(l,0,0x80,29,1); MATH1(VarDecAbs); EXPECTDEC(0,0,29,1);
4364 static void test_VarDecNeg(void)
4366 MATHVARS1;
4368 CHECKPTR(VarDecNeg);
4369 SETDEC(l,0,0x80,0,1); MATH1(VarDecNeg); EXPECTDEC(0,0,0,1);
4370 SETDEC(l,0,0,0,0); MATH1(VarDecNeg); EXPECTDEC(0,0x80,0,0); /* '-0'! */
4371 SETDEC(l,0,0x80,0,0); MATH1(VarDecNeg); EXPECTDEC(0,0,0,0);
4372 SETDEC(l,0,0,0,1); MATH1(VarDecNeg); EXPECTDEC(0,0x80,0,1);
4374 /* Doesn't check for invalid input */
4375 SETDEC(l,0,0x7f,0,1); MATH1(VarDecNeg); EXPECTDEC(0,0xff,0,1);
4376 SETDEC(l,0,0x80,29,1); MATH1(VarDecNeg); EXPECTDEC(0,0,29,1);
4377 SETDEC(l,0,0,29,1); MATH1(VarDecNeg); EXPECTDEC(0,0x80,29,1);
4380 static void test_VarDecAdd(void)
4382 MATHVARS2;
4384 CHECKPTR(VarDecAdd);
4385 SETDEC(l,0,0,0,0); SETDEC(r,0,0,0,0); MATH2(VarDecAdd); EXPECTDEC(0,0,0,0);
4386 SETDEC(l,0,0,0,0); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,1);
4387 SETDEC(l,0,0,0,0); SETDEC(r,0,0,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4389 SETDEC(l,0,0,0,1); SETDEC(r,0,0,0,0); MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4390 SETDEC(l,0,0,0,1); SETDEC(r,0,0,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0,0,2);
4391 SETDEC(l,0,0,0,1); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDECZERO();
4392 SETDEC(l,0,0,0,1); SETDEC(r,0,0x80,0,2); MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,1);
4394 SETDEC(l,0,0x80,0,0); SETDEC(r,0,0,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4395 SETDEC(l,0,0x80,0,1); SETDEC(r,0,0,0,1); MATH2(VarDecAdd); EXPECTDECZERO();
4396 SETDEC(l,0,0x80,0,1); SETDEC(r,0,0,0,2); MATH2(VarDecAdd); EXPECTDEC(0,0,0,1);
4397 SETDEC(l,0,0x80,0,1); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,2);
4398 SETDEC(l,0,0x80,0,2); SETDEC(r,0,0,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0x80,0,1);
4400 SETDEC(l,0,0,0,0xffffffff); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0,0,0xfffffffe);
4401 SETDEC(l,0,0,0,0xffffffff); SETDEC(r,0,0,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0,0,(ULONG64)1 << 32);
4402 SETDEC(l,0,0,0,0xffffffff); SETDEC(r,0,0,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0,0,(ULONG64)1 << 32);
4404 SETDEC64(l,0,0,0,0xffffffff,0); SETDEC(r,0,0,0,1); MATH2(VarDecAdd); EXPECTDEC64(0,0,0,0xffffffff,1);
4405 SETDEC64(l,0,0,0,0xffffffff,0); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4406 EXPECTDEC64(0,0,0,0xfffffffe,0xffffffff);
4408 SETDEC64(l,0,0,0,0xffffffff,0xffffffff); SETDEC(r,0,0,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0,1,0);
4409 SETDEC64(l,0,0,0,0xffffffff,0xffffffff); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4410 EXPECTDEC64(0,0,0,0xffffffff,0xfffffffe);
4412 SETDEC(l,0,0,0xffffffff,0); SETDEC(r,0,0,0,1); MATH2(VarDecAdd); EXPECTDEC(0,0,0xffffffff,1);
4413 SETDEC(l,0,0,0xffffffff,0); SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4414 EXPECTDEC64(0,0,0xfffffffe,0xffffffff,0xffffffff);
4416 SETDEC64(l,0,0,0xffffffff,0xffffffff,0xffffffff);SETDEC(r,0,0x80,0,1); MATH2(VarDecAdd);
4417 EXPECTDEC64(0,0,0xffffffff,0xffffffff,0xfffffffe);
4418 SETDEC64(l,0,0,0xffffffff,0xffffffff,0xffffffff);SETDEC(r,0,0,0,1); MATH2(VarDecAdd);
4419 ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4420 S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4422 SETDEC64(l,1,0,0xffffffff,0xffffffff,0xffffffff);SETDEC(r,1,0,0,1); MATH2(VarDecAdd);
4423 todo_wine EXPECTDEC64(0,0,0x19999999,0x99999999,0x9999999A);
4425 SETDEC64(l,0,0,0xe22ea493,0xb30310a7,0x70000000);SETDEC64(r,0,0,0xe22ea493,0xb30310a7,0x70000000); MATH2(VarDecAdd);
4426 ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4427 S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4429 SETDEC64(l,1,0,0xe22ea493,0xb30310a7,0x70000000);SETDEC64(r,1,0,0xe22ea493,0xb30310a7,0x70000000); MATH2(VarDecAdd);
4430 todo_wine EXPECTDEC64(0,0,0x2d3c8750,0xbd670354,0xb0000000);
4432 SETDEC(l,3,128,0,123456); SETDEC64(r,0,0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF);
4433 MATH2(VarDecAdd); EXPECTDEC64(0,0,-1,0xFFFFFFFF,0xFFFFFF84);
4435 SETDEC(l,3,0,0,123456); SETDEC64(r,0,0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF); MATH2(VarDecAdd);
4436 ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4437 S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4439 SETDEC(l,4,0,0,123456); SETDEC64(r,0,0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF); MATH2(VarDecAdd);
4440 ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4441 S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4443 SETDEC(l,5,0,0,123456); SETDEC64(r,0,0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF); MATH2(VarDecAdd);
4444 ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4445 S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4447 SETDEC(l,6,0,0,123456); SETDEC64(r,0,0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF);
4448 MATH2(VarDecAdd); EXPECTDEC64(0,0,-1,0xFFFFFFFF,0xFFFFFFFF);
4450 SETDEC(l,3,128,0,123456); SETDEC64(r,0,0,0x19999999,0x99999999,0x99999999);
4451 MATH2(VarDecAdd); EXPECTDEC64(1,0,-1,0xFFFFFFFF,0xFFFFFB27);
4453 SETDEC(l,3,128,0,123567); SETDEC64(r,0,0,0x19999999,0x99999999,0x99999999);
4454 MATH2(VarDecAdd); EXPECTDEC64(1,0,-1,0xFFFFFFFF,0xFFFFFB26);
4456 /* Promotes to the highest scale, so here the results are in the scale of 2 */
4457 SETDEC(l,2,0,0,0); SETDEC(r,0,0,0,0); MATH2(VarDecAdd); EXPECTDEC(2,0,0,0);
4458 SETDEC(l,2,0,0,100); SETDEC(r,0,0,0,1); MATH2(VarDecAdd); EXPECTDEC(2,0,0,200);
4461 static void test_VarDecSub(void)
4463 MATHVARS2;
4465 CHECKPTR(VarDecSub);
4466 SETDEC(l,0,0,0,0); SETDEC(r,0,0,0,0); MATH2(VarDecSub); EXPECTDECZERO();
4467 SETDEC(l,0,0,0,0); SETDEC(r,0,0,0,1); MATH2(VarDecSub); EXPECTDEC(0,0x80,0,1);
4468 SETDEC(l,0,0,0,1); SETDEC(r,0,0,0,1); MATH2(VarDecSub); EXPECTDECZERO();
4469 SETDEC(l,0,0,0,1); SETDEC(r,0,0x80,0,1); MATH2(VarDecSub); EXPECTDEC(0,0,0,2);
4472 static void test_VarDecMul(void)
4474 MATHVARS2;
4476 CHECKPTR(VarDecMul);
4477 SETDEC(l,0,0,0,0); SETDEC(r,0,0,0,0); MATH2(VarDecMul); EXPECTDEC(0,0,0,0);
4478 SETDEC(l,0,0,0,1); SETDEC(r,0,0,0,0); MATH2(VarDecMul); EXPECTDEC(0,0,0,0);
4479 SETDEC(l,0,0,0,0); SETDEC(r,0,0,0,1); MATH2(VarDecMul); EXPECTDEC(0,0,0,0);
4480 SETDEC(l,0,0,0,1); SETDEC(r,0,0,0,1); MATH2(VarDecMul); EXPECTDEC(0,0,0,1);
4481 SETDEC(l,0,0,0,45000);SETDEC(r,0,0,0,2); MATH2(VarDecMul); EXPECTDEC(0,0,0,90000);
4482 SETDEC(l,0,0,0,2); SETDEC(r,0,0,0,45000); MATH2(VarDecMul); EXPECTDEC(0,0,0,90000);
4484 SETDEC(l,0,0x80,0,2); SETDEC(r,0,0,0,2); MATH2(VarDecMul); EXPECTDEC(0,0x80,0,4);
4485 SETDEC(l,0,0,0,2); SETDEC(r,0,0x80,0,2); MATH2(VarDecMul); EXPECTDEC(0,0x80,0,4);
4486 SETDEC(l,0,0x80,0,2); SETDEC(r,0,0x80,0,2); MATH2(VarDecMul); EXPECTDEC(0,0,0,4);
4488 SETDEC(l,4,0,0,2); SETDEC(r,0,0,0,2); MATH2(VarDecMul); EXPECTDEC(4,0,0,4);
4489 SETDEC(l,0,0,0,2); SETDEC(r,3,0,0,2); MATH2(VarDecMul); EXPECTDEC(3,0,0,4);
4490 SETDEC(l,4,0,0,2); SETDEC(r,3,0,0,2); MATH2(VarDecMul); EXPECTDEC(7,0,0,4);
4491 /* this last one shows that native oleaut32 does *not* gratuitously seize opportunities
4492 to reduce the scale if possible - the canonical result for the expected value is (6,0,0,1)
4494 SETDEC(l,4,0,0,5); SETDEC(r,3,0,0,2); MATH2(VarDecMul); EXPECTDEC(7,0,0,10);
4496 SETDEC64(l,0,0,0,0xFFFFFFFF,0xFFFFFFFF); SETDEC(r,0,0,0,2); MATH2(VarDecMul); EXPECTDEC64(0,0,1,0xFFFFFFFF,0xFFFFFFFE);
4497 SETDEC(l,0,0,0,2); SETDEC64(r,0,0,0,0xFFFFFFFF,0xFFFFFFFF); MATH2(VarDecMul); EXPECTDEC64(0,0,1,0xFFFFFFFF,0xFFFFFFFE);
4498 SETDEC(l,0,0,1,1); SETDEC(r,0,0,0,0x80000000); MATH2(VarDecMul); EXPECTDEC(0,0,0x80000000,0x80000000);
4499 SETDEC(l,0,0,0,0x80000000); SETDEC(r,0,0,1,1); MATH2(VarDecMul); EXPECTDEC(0,0,0x80000000,0x80000000);
4501 /* near-overflow, used as a reference */
4502 SETDEC64(l,0,0,0,0xFFFFFFFF,0xFFFFFFFF); SETDEC(r,0,0,0,2000000000); MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4503 /* actual overflow - right operand is 10 times the previous value */
4504 SETDEC64(l,0,0,0,0xFFFFFFFF,0xFFFFFFFF); SETDEC64(r,0,0,0,4,0xA817C800); MATH2(VarDecMul);
4505 ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4506 S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4507 /* here, native oleaut32 has an opportunity to avert the overflow, by reducing the scale of the result */
4508 SETDEC64(l,1,0,0,0xFFFFFFFF,0xFFFFFFFF); SETDEC64(r,0,0,0,4,0xA817C800); MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4510 /* near-overflow, used as a reference */
4511 SETDEC64(l,0,0,1,0xFFFFFFFF,0xFFFFFFFE); SETDEC(r,0,0,0,1000000000); MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4512 /* actual overflow - right operand is 10 times the previous value */
4513 SETDEC64(l,0,0,1,0xFFFFFFFF,0xFFFFFFFE); SETDEC64(r,0,0,0,2,0x540BE400); MATH2(VarDecMul);
4514 ok(hres == DISP_E_OVERFLOW,"Expected overflow, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4515 S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4516 /* here, native oleaut32 has an opportunity to avert the overflow, by reducing the scale of the result */
4517 SETDEC64(l,1,0,1,0xFFFFFFFF,0xFFFFFFFE); SETDEC64(r,0,0,0,2,0x540BE400); MATH2(VarDecMul);EXPECTDEC64(0,0,1999999999,0xFFFFFFFF,0x88CA6C00);
4519 /* this one shows that native oleaut32 is willing to lose significant digits in order to avert an overflow */
4520 SETDEC64(l,2,0,0,0xFFFFFFFF,0xFFFFFFFF); SETDEC64(r,0,0,0,9,0x502F9001); MATH2(VarDecMul);EXPECTDEC64(1,0,0xee6b2800,0x19999998,0xab2e719a);
4523 static void test_VarDecDiv(void)
4525 MATHVARS2;
4527 CHECKPTR(VarDecDiv);
4528 /* identity divisions */
4529 SETDEC(l,0,0,0,0); SETDEC(r,0,0,0,1); MATH2(VarDecDiv); EXPECTDEC(0,0,0,0);
4530 SETDEC(l,0,0,0,1); SETDEC(r,0,0,0,1); MATH2(VarDecDiv); EXPECTDEC(0,0,0,1);
4531 SETDEC(l,1,0,0,1); SETDEC(r,0,0,0,1); MATH2(VarDecDiv); EXPECTDEC(1,0,0,1);
4533 /* exact divisions */
4534 SETDEC(l,0,0,0,45); SETDEC(r,0,0,0,9); MATH2(VarDecDiv); EXPECTDEC(0,0,0,5);
4535 SETDEC(l,1,0,0,45); SETDEC(r,0,0,0,9); MATH2(VarDecDiv); EXPECTDEC(1,0,0,5);
4536 SETDEC(l,0,0,0,45); SETDEC(r,1,0,0,9); MATH2(VarDecDiv); EXPECTDEC(0,0,0,50);
4537 SETDEC(l,1,0,0,45); SETDEC(r,2,0,0,9); MATH2(VarDecDiv); EXPECTDEC(0,0,0,50);
4538 /* these last three results suggest that native oleaut32 scales both operands down to zero
4539 before the division, but does not always try to scale the result, even if it is possible -
4540 analogous to multiplication behavior.
4542 SETDEC(l,1,0,0,45); SETDEC(r,1,0,0,9); MATH2(VarDecDiv); EXPECTDEC(0,0,0,5);
4543 SETDEC(l,2,0,0,450); SETDEC(r,1,0,0,9); MATH2(VarDecDiv);
4544 if (S(U(out)).scale == 1) EXPECTDEC(1,0,0,50);
4545 else EXPECTDEC(0,0,0,5);
4547 /* inexact divisions */
4548 SETDEC(l,0,0,0,1); SETDEC(r,0,0,0,3); MATH2(VarDecDiv); EXPECTDEC64(28,0,180700362,0x14b700cb,0x05555555);
4549 SETDEC(l,1,0,0,1); SETDEC(r,0,0,0,3); MATH2(VarDecDiv); EXPECTDEC64(28,0,18070036,0x35458014,0x4d555555);
4550 SETDEC(l,0,0,0,1); SETDEC(r,1,0,0,3); MATH2(VarDecDiv); EXPECTDEC64(28,0,1807003620,0xcf2607ee,0x35555555);
4551 SETDEC(l,1,0,0,1); SETDEC(r,2,0,0,3); MATH2(VarDecDiv); EXPECTDEC64(28,0,1807003620,0xcf2607ee,0x35555555);
4552 SETDEC(l,1,0,0,1); SETDEC(r,1,0,0,3); MATH2(VarDecDiv); EXPECTDEC64(28,0,180700362,0x14b700cb,0x05555555);
4553 SETDEC(l,2,0,0,10); SETDEC(r,1,0,0,3); MATH2(VarDecDiv); EXPECTDEC64(28,0,180700362,0x14b700cb,0x05555555);
4555 /* this one shows that native oleaut32 rounds up the result */
4556 SETDEC(l,0,0,0,2); SETDEC(r,0,0,0,3); MATH2(VarDecDiv); EXPECTDEC64(28,0,361400724,0x296e0196,0x0aaaaaab);
4558 /* sign tests */
4559 SETDEC(l,0,0x80,0,45); SETDEC(r,0,0,0,9); MATH2(VarDecDiv); EXPECTDEC(0,0x80,0,5);
4560 SETDEC(l,0,0,0,45); SETDEC(r,0,0x80,0,9); MATH2(VarDecDiv);EXPECTDEC(0,0x80,0,5);
4561 SETDEC(l,0,0x80,0,45); SETDEC(r,0,0x80,0,9); MATH2(VarDecDiv);EXPECTDEC(0,0,0,5);
4563 /* oddballs */
4564 SETDEC(l,0,0,0,0); SETDEC(r,0,0,0,0); MATH2(VarDecDiv);/* indeterminate */
4565 ok(hres == DISP_E_DIVBYZERO,"Expected division-by-zero, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4566 S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4567 SETDEC(l,0,0,0,1); SETDEC(r,0,0,0,0); MATH2(VarDecDiv);/* division by zero */
4568 ok(hres == DISP_E_DIVBYZERO,"Expected division-by-zero, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x\n",
4569 S(U(out)).scale, S(U(out)).sign, out.Hi32, S1(U1(out)).Mid32, S1(U1(out)).Lo32, hres);
4573 static void test_VarDecCmp(void)
4575 MATHVARS1;
4577 CHECKPTR(VarDecCmp);
4579 SETDEC(l,0,0,0,1); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_EQ;
4580 SETDEC(l,0,0,0,1); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_GT;
4581 SETDEC(l,0,0,0,1); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4583 SETDEC(l,0,0,0,1); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4584 SETDEC(l,0,0,0,1); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_GT;
4585 SETDEC(l,0,0,0,1); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4587 SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4588 SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_LT;
4589 SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4591 SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_EQ;
4592 SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_LT;
4593 SETDEC(l,0,DECIMAL_NEG,0,1); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4595 SETDEC(l,0,0,0,0); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4596 SETDEC(l,0,0,0,0); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4597 SETDEC(l,0,0,0,0); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4599 SETDEC(l,0,0,0,0); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4600 SETDEC(l,0,0,0,0); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4601 SETDEC(l,0,0,0,0); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4603 SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4604 SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4605 SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4607 SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4608 SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4609 SETDEC(l,0,DECIMAL_NEG,0,0); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4611 SETDEC(l,0,0,-1,-1); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4612 SETDEC(l,0,0,-1,-1); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_GT;
4613 SETDEC(l,0,0,-1,-1); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_EQ;
4615 SETDEC(l,0,0,-1,-1); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4616 SETDEC(l,0,0,-1,-1); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_GT;
4617 SETDEC(l,0,0,-1,-1); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4619 SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4620 SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,0,0,0); MATH1(VarDecCmp); EXPECT_LT;
4621 SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4623 SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4624 SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_LT;
4625 SETDEC(l,0,DECIMAL_NEG,-1,-1); SETDEC(out,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_EQ;
4628 SETDEC(out,0,0,0,1); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_EQ;
4629 SETDEC(out,0,0,0,1); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_LT;
4630 SETDEC(out,0,0,0,1); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4632 SETDEC(out,0,0,0,1); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4633 SETDEC(out,0,0,0,1); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_LT;
4634 SETDEC(out,0,0,0,1); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4636 SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4637 SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_GT;
4638 SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4640 SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_EQ;
4641 SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_GT;
4642 SETDEC(out,0,DECIMAL_NEG,0,1); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4644 SETDEC(out,0,0,0,0); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4645 SETDEC(out,0,0,0,0); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4646 SETDEC(out,0,0,0,0); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4648 SETDEC(out,0,0,0,0); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4649 SETDEC(out,0,0,0,0); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4650 SETDEC(out,0,0,0,0); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4652 SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4653 SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4654 SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4656 SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4657 SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_EQ;
4658 SETDEC(out,0,DECIMAL_NEG,0,0); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4660 SETDEC(out,0,0,-1,-1); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_LT;
4661 SETDEC(out,0,0,-1,-1); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_LT;
4662 SETDEC(out,0,0,-1,-1); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_EQ;
4664 SETDEC(out,0,0,-1,-1); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_LT;
4665 SETDEC(out,0,0,-1,-1); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_LT;
4666 SETDEC(out,0,0,-1,-1); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_LT;
4668 SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,0,0,1); MATH1(VarDecCmp); EXPECT_GT;
4669 SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,0,0,0); MATH1(VarDecCmp); EXPECT_GT;
4670 SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,0,-1,-1); MATH1(VarDecCmp); EXPECT_GT;
4672 SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,DECIMAL_NEG,0,1); MATH1(VarDecCmp); EXPECT_GT;
4673 SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,DECIMAL_NEG,0,0); MATH1(VarDecCmp); EXPECT_GT;
4674 SETDEC(out,0,DECIMAL_NEG,-1,-1); SETDEC(l,0,DECIMAL_NEG,-1,-1); MATH1(VarDecCmp); EXPECT_EQ;
4676 SETDEC(l,3,0,0,123456); SETDEC64(out,0,0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF);
4677 MATH1(VarDecCmp); EXPECT_LT;
4680 static void test_VarDecCmpR8(void)
4682 HRESULT hres;
4683 DECIMAL l;
4684 double r;
4686 CHECKPTR(VarDecCmpR8);
4688 SETDEC(l,0,0,0,1); r = 0.0; MATH3(VarDecCmpR8); EXPECT_GT;
4689 SETDEC(l,0,0,0,1); r = 0.1; MATH3(VarDecCmpR8); EXPECT_GT;
4690 SETDEC(l,0,0,0,1); r = -0.1; MATH3(VarDecCmpR8); EXPECT_GT;
4692 SETDEC(l,0,DECIMAL_NEG,0,1); r = 0.0; MATH3(VarDecCmpR8); EXPECT_LT;
4693 SETDEC(l,0,DECIMAL_NEG,0,1); r = 0.1; MATH3(VarDecCmpR8); EXPECT_LT;
4694 SETDEC(l,0,DECIMAL_NEG,0,1); r = -0.1; MATH3(VarDecCmpR8); EXPECT_LT;
4696 SETDEC(l,0,0,0,0); r = 0.0; MATH3(VarDecCmpR8); EXPECT_EQ;
4697 SETDEC(l,0,0,0,0); r = 0.1; MATH3(VarDecCmpR8); EXPECT_LT;
4698 SETDEC(l,0,0,0,0); r = -0.1; MATH3(VarDecCmpR8); EXPECT_GT;
4700 SETDEC(l,0,DECIMAL_NEG,0,0); r = 0.0; MATH3(VarDecCmpR8); EXPECT_EQ;
4701 SETDEC(l,0,DECIMAL_NEG,0,0); r = 0.1; MATH3(VarDecCmpR8); EXPECT_LT;
4702 SETDEC(l,0,DECIMAL_NEG,0,0); r = -0.1; MATH3(VarDecCmpR8); EXPECT_GT;
4704 SETDEC(l,0,0,0,1); r = DECIMAL_NEG; MATH3(VarDecCmpR8); EXPECT_LT;
4705 SETDEC(l,0,DECIMAL_NEG,0,0); r = DECIMAL_NEG; MATH3(VarDecCmpR8); EXPECT_LT;
4706 SETDEC(l,0,0,-1,-1); r = DECIMAL_NEG; MATH3(VarDecCmpR8); EXPECT_GT;
4707 SETDEC(l,0,DECIMAL_NEG,-1,-1); r = DECIMAL_NEG; MATH3(VarDecCmpR8); EXPECT_LT;
4710 #define CLEAR(x) memset(&(x), 0xBB, sizeof(x))
4712 static void test_VarDecRound(void)
4714 HRESULT hres;
4715 DECIMAL l, out;
4717 CHECKPTR(VarDecRound);
4719 CLEAR(out); SETDEC(l, 0, 0, 0, 1); hres = pVarDecRound(&l, 3, &out); EXPECTDEC(0, 0, 0, 1);
4721 CLEAR(out); SETDEC(l, 0, 0, 0, 1); hres = pVarDecRound(&l, 0, &out); EXPECTDEC(0, 0, 0, 1);
4722 CLEAR(out); SETDEC(l, 1, 0, 0, 1); hres = pVarDecRound(&l, 0, &out); EXPECTDEC(0, 0, 0, 0);
4723 CLEAR(out); SETDEC(l, 1, 0, 0, 1); hres = pVarDecRound(&l, 1, &out); EXPECTDEC(1, 0, 0, 1);
4724 CLEAR(out); SETDEC(l, 2, 0, 0, 11); hres = pVarDecRound(&l, 1, &out); EXPECTDEC(1, 0, 0, 1);
4725 CLEAR(out); SETDEC(l, 2, 0, 0, 15); hres = pVarDecRound(&l, 1, &out); EXPECTDEC(1, 0, 0, 2);
4726 CLEAR(out); SETDEC(l, 6, 0, 0, 550001); hres = pVarDecRound(&l, 1, &out); EXPECTDEC(1, 0, 0, 6);
4728 CLEAR(out); SETDEC(l, 0, DECIMAL_NEG, 0, 1); hres = pVarDecRound(&l, 0, &out); EXPECTDEC(0, DECIMAL_NEG, 0, 1);
4729 CLEAR(out); SETDEC(l, 1, DECIMAL_NEG, 0, 1); hres = pVarDecRound(&l, 0, &out); EXPECTDEC(0, DECIMAL_NEG, 0, 0);
4730 CLEAR(out); SETDEC(l, 1, DECIMAL_NEG, 0, 1); hres = pVarDecRound(&l, 1, &out); EXPECTDEC(1, DECIMAL_NEG, 0, 1);
4731 CLEAR(out); SETDEC(l, 2, DECIMAL_NEG, 0, 11); hres = pVarDecRound(&l, 1, &out); EXPECTDEC(1, DECIMAL_NEG, 0, 1);
4732 CLEAR(out); SETDEC(l, 2, DECIMAL_NEG, 0, 15); hres = pVarDecRound(&l, 1, &out); EXPECTDEC(1, DECIMAL_NEG, 0, 2);
4733 CLEAR(out); SETDEC(l, 6, DECIMAL_NEG, 0, 550001); hres = pVarDecRound(&l, 1, &out); EXPECTDEC(1, DECIMAL_NEG, 0, 6);
4735 CLEAR(out); SETDEC64(l, 0, 0, 0xffffffff, 0xffffffff, 0xffffffff); hres = pVarDecRound(&l, 0, &out); EXPECTDEC64(0, 0, 0xffffffff, 0xffffffff, 0xffffffff);
4736 CLEAR(out); SETDEC64(l, 28, 0, 0xffffffff, 0xffffffff, 0xffffffff); hres = pVarDecRound(&l, 0, &out); EXPECTDEC64(0, 0, 0, 0, 8);
4737 CLEAR(out); SETDEC64(l, 0, DECIMAL_NEG, 0xffffffff, 0xffffffff, 0xffffffff); hres = pVarDecRound(&l, 0, &out); EXPECTDEC64(0, DECIMAL_NEG, 0xffffffff, 0xffffffff, 0xffffffff);
4738 CLEAR(out); SETDEC64(l, 28, DECIMAL_NEG, 0xffffffff, 0xffffffff, 0xffffffff); hres = pVarDecRound(&l, 0, &out); EXPECTDEC64(0, DECIMAL_NEG, 0, 0, 8);
4740 CLEAR(out); SETDEC(l, 2, 0, 0, 0); hres = pVarDecRound(&l, 1, &out); EXPECTDEC(1, 0, 0, 0);
4744 * VT_BOOL
4747 #undef CONV_TYPE
4748 #define CONV_TYPE VARIANT_BOOL
4749 #undef EXPECTRES
4750 #define EXPECTRES(res, x) _EXPECTRES(res, x, "%d")
4751 #undef CONVERTRANGE
4752 #define CONVERTRANGE(func,start,end) for (i = start; i < end; i++) { \
4753 CONVERT(func, i); if (i) { EXPECT(VARIANT_TRUE); } else { EXPECT(VARIANT_FALSE); } }
4755 static void test_VarBoolFromI1(void)
4757 CONVVARS(signed char);
4758 int i;
4760 CHECKPTR(VarBoolFromI1);
4761 CONVERTRANGE(VarBoolFromI1, -128, 128);
4764 static void test_VarBoolFromUI1(void)
4766 CONVVARS(BYTE);
4767 int i;
4769 CHECKPTR(VarBoolFromUI1);
4770 CONVERTRANGE(VarBoolFromUI1, 0, 256);
4773 static void test_VarBoolFromI2(void)
4775 CONVVARS(SHORT);
4776 int i;
4778 CHECKPTR(VarBoolFromI2);
4779 CONVERTRANGE(VarBoolFromI2, -32768, 32768);
4782 static void test_VarBoolFromUI2(void)
4784 CONVVARS(USHORT);
4785 int i;
4787 CHECKPTR(VarBoolFromUI2);
4788 CONVERTRANGE(VarBoolFromUI2, 0, 65536);
4791 static void test_VarBoolFromI4(void)
4793 CONVVARS(int);
4795 CHECKPTR(VarBoolFromI4);
4796 CONVERT(VarBoolFromI4, 0x80000000); EXPECT(VARIANT_TRUE);
4797 CONVERT(VarBoolFromI4, -1); EXPECT(VARIANT_TRUE);
4798 CONVERT(VarBoolFromI4, 0); EXPECT(VARIANT_FALSE);
4799 CONVERT(VarBoolFromI4, 1); EXPECT(VARIANT_TRUE);
4800 CONVERT(VarBoolFromI4, 0x7fffffff); EXPECT(VARIANT_TRUE);
4803 static void test_VarBoolFromUI4(void)
4805 CONVVARS(ULONG);
4807 CHECKPTR(VarBoolFromUI4);
4808 CONVERT(VarBoolFromI4, 0); EXPECT(VARIANT_FALSE);
4809 CONVERT(VarBoolFromI4, 1); EXPECT(VARIANT_TRUE);
4810 CONVERT(VarBoolFromI4, 0x80000000); EXPECT(VARIANT_TRUE);
4813 static void test_VarBoolFromR4(void)
4815 CONVVARS(FLOAT);
4817 CHECKPTR(VarBoolFromR4);
4818 CONVERT(VarBoolFromR4, -1.0f); EXPECT(VARIANT_TRUE);
4819 CONVERT(VarBoolFromR4, 0.0f); EXPECT(VARIANT_FALSE);
4820 CONVERT(VarBoolFromR4, 1.0f); EXPECT(VARIANT_TRUE);
4821 CONVERT(VarBoolFromR4, 1.5f); EXPECT(VARIANT_TRUE);
4823 /* Rounding */
4824 CONVERT(VarBoolFromR4, -1.5f); EXPECT(VARIANT_TRUE);
4825 CONVERT(VarBoolFromR4, -0.6f); EXPECT(VARIANT_TRUE);
4826 CONVERT(VarBoolFromR4, -0.5f); EXPECT(VARIANT_TRUE);
4827 CONVERT(VarBoolFromR4, -0.4f); EXPECT(VARIANT_TRUE);
4828 CONVERT(VarBoolFromR4, 0.4f); EXPECT(VARIANT_TRUE);
4829 CONVERT(VarBoolFromR4, 0.5f); EXPECT(VARIANT_TRUE);
4830 CONVERT(VarBoolFromR4, 0.6f); EXPECT(VARIANT_TRUE);
4831 CONVERT(VarBoolFromR4, 1.5f); EXPECT(VARIANT_TRUE);
4834 static void test_VarBoolFromR8(void)
4836 CONVVARS(DOUBLE);
4838 /* Hopefully we made the point with R4 above that rounding is
4839 * irrelevant, so we'll skip that for R8 and Date
4841 CHECKPTR(VarBoolFromR8);
4842 CONVERT(VarBoolFromR8, -1.0); EXPECT(VARIANT_TRUE);
4843 CONVERT(VarBoolFromR8, -0.0); EXPECT(VARIANT_FALSE);
4844 CONVERT(VarBoolFromR8, 1.0); EXPECT(VARIANT_TRUE);
4847 static void test_VarBoolFromCy(void)
4849 CONVVARS(CY);
4851 CHECKPTR(VarBoolFromCy);
4852 CONVERT_CY(VarBoolFromCy, -32769); EXPECT(VARIANT_TRUE);
4853 CONVERT_CY(VarBoolFromCy, -32768); EXPECT(VARIANT_TRUE);
4854 CONVERT_CY(VarBoolFromCy, -1); EXPECT(VARIANT_TRUE);
4855 CONVERT_CY(VarBoolFromCy, 0); EXPECT(VARIANT_FALSE);
4856 CONVERT_CY(VarBoolFromCy, 1); EXPECT(VARIANT_TRUE);
4857 CONVERT_CY(VarBoolFromCy, 32767); EXPECT(VARIANT_TRUE);
4858 CONVERT_CY(VarBoolFromCy, 32768); EXPECT(VARIANT_TRUE);
4861 static void test_VarBoolFromI8(void)
4863 CONVVARS(LONG64);
4865 CHECKPTR(VarBoolFromI8);
4866 CONVERT(VarBoolFromI8, -1); EXPECT(VARIANT_TRUE);
4867 CONVERT(VarBoolFromI8, 0); EXPECT(VARIANT_FALSE);
4868 CONVERT(VarBoolFromI8, 1); EXPECT(VARIANT_TRUE);
4871 static void test_VarBoolFromUI8(void)
4873 CONVVARS(ULONG64);
4875 CHECKPTR(VarBoolFromUI8);
4876 CONVERT(VarBoolFromUI8, 0); EXPECT(VARIANT_FALSE);
4877 CONVERT(VarBoolFromUI8, 1); EXPECT(VARIANT_TRUE);
4880 static void test_VarBoolFromDec(void)
4882 CONVVARS(DECIMAL);
4884 CHECKPTR(VarBoolFromDec);
4885 CONVERT_BADDEC(VarBoolFromDec);
4887 CONVERT_DEC(VarBoolFromDec,29,0,0,0); EXPECT_INVALID;
4888 CONVERT_DEC(VarBoolFromDec,0,0x1,0,0); EXPECT_INVALID;
4889 CONVERT_DEC(VarBoolFromDec,0,0x40,0,0); EXPECT_INVALID;
4890 CONVERT_DEC(VarBoolFromDec,0,0x7f,0,0); EXPECT_INVALID;
4892 CONVERT_DEC(VarBoolFromDec,0,0x80,0,1); EXPECT(VARIANT_TRUE);
4893 CONVERT_DEC(VarBoolFromDec,0,0,0,0); EXPECT(VARIANT_FALSE);
4894 CONVERT_DEC(VarBoolFromDec,0,0,0,1); EXPECT(VARIANT_TRUE);
4895 CONVERT_DEC(VarBoolFromDec,0,0,1,0); EXPECT(VARIANT_TRUE);
4897 CONVERT_DEC(VarBoolFromDec,2,0,0,CY_MULTIPLIER); EXPECT(VARIANT_TRUE);
4898 CONVERT_DEC(VarBoolFromDec,2,0x80,0,CY_MULTIPLIER); EXPECT(VARIANT_TRUE);
4901 static void test_VarBoolFromDate(void)
4903 CONVVARS(DATE);
4905 CHECKPTR(VarBoolFromDate);
4906 CONVERT(VarBoolFromDate, -1.0); EXPECT(VARIANT_TRUE);
4907 CONVERT(VarBoolFromDate, -0.0); EXPECT(VARIANT_FALSE);
4908 CONVERT(VarBoolFromDate, 1.0); EXPECT(VARIANT_TRUE);
4911 static void test_VarBoolFromStr(void)
4913 CONVVARS(LCID);
4914 OLECHAR buff[128];
4916 CHECKPTR(VarBoolFromStr);
4918 in = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4920 CONVERT_STR(VarBoolFromStr,NULL,0);
4921 if (hres != E_INVALIDARG)
4922 EXPECT_MISMATCH;
4924 /* #FALSE# and #TRUE# Are always accepted */
4925 CONVERT_STR(VarBoolFromStr,"#FALSE#",0); EXPECT(VARIANT_FALSE);
4926 CONVERT_STR(VarBoolFromStr,"#TRUE#",0); EXPECT(VARIANT_TRUE);
4928 /* Match of #FALSE# and #TRUE# is case sensitive */
4929 CONVERT_STR(VarBoolFromStr,"#False#",0); EXPECT_MISMATCH;
4930 /* But match against English is not */
4931 CONVERT_STR(VarBoolFromStr,"false",0); EXPECT(VARIANT_FALSE);
4932 CONVERT_STR(VarBoolFromStr,"False",0); EXPECT(VARIANT_FALSE);
4933 /* On/Off and yes/no are not acceptable inputs, with any flags set */
4934 CONVERT_STR(VarBoolFromStr,"On",0xffffffff); EXPECT_MISMATCH;
4935 CONVERT_STR(VarBoolFromStr,"Yes",0xffffffff); EXPECT_MISMATCH;
4937 /* Change the LCID. This doesn't make any difference for text,unless we ask
4938 * to check local boolean text with the VARIANT_LOCALBOOL flag. */
4939 in = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT);
4941 /* #FALSE# and #TRUE# are accepted in all locales */
4942 CONVERT_STR(VarBoolFromStr,"#FALSE#",0); EXPECT(VARIANT_FALSE);
4943 CONVERT_STR(VarBoolFromStr,"#TRUE#",0); EXPECT(VARIANT_TRUE);
4944 CONVERT_STR(VarBoolFromStr,"#FALSE#",VARIANT_LOCALBOOL); EXPECT(VARIANT_FALSE);
4945 CONVERT_STR(VarBoolFromStr,"#TRUE#",VARIANT_LOCALBOOL); EXPECT(VARIANT_TRUE);
4947 /* English is accepted regardless of the locale */
4948 CONVERT_STR(VarBoolFromStr,"false",0); EXPECT(VARIANT_FALSE);
4949 /* And is still not case sensitive */
4950 CONVERT_STR(VarBoolFromStr,"False",0); EXPECT(VARIANT_FALSE);
4952 if (has_locales)
4954 /* French is rejected without VARIANT_LOCALBOOL */
4955 CONVERT_STR(VarBoolFromStr,"faux",0); EXPECT_MISMATCH;
4956 /* But accepted if this flag is given */
4957 CONVERT_STR(VarBoolFromStr,"faux",VARIANT_LOCALBOOL); EXPECT(VARIANT_FALSE);
4958 /* Regardless of case - from this we assume locale text comparisons ignore case */
4959 CONVERT_STR(VarBoolFromStr,"Faux",VARIANT_LOCALBOOL); EXPECT(VARIANT_FALSE);
4961 /* Changing the locale prevents the localised text from being compared -
4962 * this demonstrates that only the indicated LCID and English are searched */
4963 in = MAKELCID(MAKELANGID(LANG_POLISH, SUBLANG_DEFAULT), SORT_DEFAULT);
4964 CONVERT_STR(VarBoolFromStr,"faux",VARIANT_LOCALBOOL); EXPECT_MISMATCH;
4967 /* Numeric strings are read as 0 or non-0 */
4968 CONVERT_STR(VarBoolFromStr,"0",0); EXPECT(VARIANT_FALSE);
4969 CONVERT_STR(VarBoolFromStr,"-1",0); EXPECT(VARIANT_TRUE);
4970 CONVERT_STR(VarBoolFromStr,"+1",0); EXPECT(VARIANT_TRUE);
4972 if (has_locales)
4974 /* Numeric strings are read as floating point numbers. The line below fails
4975 * because '.' is not a valid decimal separator for Polish numbers */
4976 CONVERT_STR(VarBoolFromStr,"0.1",LOCALE_NOUSEROVERRIDE); EXPECT_MISMATCH;
4979 /* Changing the lcid back to US English reads the r8 correctly */
4980 in = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
4981 CONVERT_STR(VarBoolFromStr,"0.1",LOCALE_NOUSEROVERRIDE); EXPECT(VARIANT_TRUE);
4984 static void test_VarBoolCopy(void)
4986 COPYTEST(1, VT_BOOL, V_BOOL(&vSrc), V_BOOL(&vDst), V_BOOLREF(&vSrc), V_BOOLREF(&vDst), "%d");
4989 #define BOOL_STR(flags, str) hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, flags, VT_BSTR); \
4990 ok(hres == S_OK && V_VT(&vDst) == VT_BSTR && \
4991 V_BSTR(&vDst) && !memcmp(V_BSTR(&vDst), str, sizeof(str)), \
4992 "hres=0x%X, type=%d (should be VT_BSTR), *bstr='%c'\n", \
4993 hres, V_VT(&vDst), V_BSTR(&vDst) ? *V_BSTR(&vDst) : '?'); \
4994 VariantClear(&vDst)
4996 static void test_VarBoolChangeTypeEx(void)
4998 static const WCHAR szTrue[] = { 'T','r','u','e','\0' };
4999 static const WCHAR szFalse[] = { 'F','a','l','s','e','\0' };
5000 static const WCHAR szFaux[] = { 'F','a','u','x','\0' };
5001 HRESULT hres;
5002 VARIANT_BOOL in;
5003 VARIANTARG vSrc, vDst;
5004 LCID lcid;
5006 in = 1;
5008 INITIAL_TYPETEST(VT_BOOL, V_BOOL, "%d");
5009 COMMON_TYPETEST;
5011 /* The common tests convert to a number. Try the different flags */
5012 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5014 V_VT(&vSrc) = VT_BOOL;
5015 V_BOOL(&vSrc) = 1;
5017 BOOL_STR(VARIANT_ALPHABOOL, szTrue);
5018 V_BOOL(&vSrc) = 0;
5019 BOOL_STR(VARIANT_ALPHABOOL, szFalse);
5021 if (has_locales)
5023 lcid = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT);
5025 /* VARIANT_ALPHABOOL is always English */
5026 BOOL_STR(VARIANT_ALPHABOOL, szFalse);
5027 /* VARIANT_LOCALBOOL uses the localised text */
5028 BOOL_STR(VARIANT_LOCALBOOL, szFaux);
5029 /* Both flags together acts as VARIANT_LOCALBOOL */
5030 BOOL_STR(VARIANT_ALPHABOOL|VARIANT_LOCALBOOL, szFaux);
5035 * BSTR
5038 static void test_VarBstrFromR4(void)
5040 static const WCHAR szNative[] = { '6','5','4','3','2','2','.','3','\0' };
5041 static const WCHAR szZero[] = {'0', '\0'};
5042 static const WCHAR szOneHalf_English[] = { '0','.','5','\0' }; /* uses period */
5043 static const WCHAR szOneHalf_Spanish[] = { '0',',','5','\0' }; /* uses comma */
5044 LCID lcid;
5045 LCID lcid_spanish;
5046 HRESULT hres;
5047 BSTR bstr = NULL;
5049 float f;
5051 CHECKPTR(VarBstrFromR4);
5053 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5054 lcid_spanish = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), SORT_DEFAULT);
5055 f = 654322.23456f;
5056 hres = pVarBstrFromR4(f, lcid, 0, &bstr);
5057 ok(hres == S_OK, "got hres 0x%08x\n", hres);
5058 if (bstr)
5060 todo_wine {
5061 /* MSDN states that rounding of R4/R8 is dependent on the underlying
5062 * bit pattern of the number and so is architecture dependent. In this
5063 * case Wine returns .2 (which is more correct) and Native returns .3
5065 ok(memcmp(bstr, szNative, sizeof(szNative)) == 0, "string different\n");
5067 SysFreeString(bstr);
5070 f = -0.0;
5071 hres = pVarBstrFromR4(f, lcid, 0, &bstr);
5072 ok(hres == S_OK, "got hres 0x%08x\n", hres);
5073 if (bstr)
5075 if (bstr[0] == '-')
5076 ok(memcmp(bstr + 1, szZero, sizeof(szZero)) == 0, "negative zero (got %s)\n", wtoascii(bstr));
5077 else
5078 ok(memcmp(bstr, szZero, sizeof(szZero)) == 0, "negative zero (got %s)\n", wtoascii(bstr));
5079 SysFreeString(bstr);
5082 /* The following tests that lcid is used for decimal separator even without LOCALE_USE_NLS */
5083 f = 0.5;
5084 hres = pVarBstrFromR4(f, lcid, LOCALE_NOUSEROVERRIDE, &bstr);
5085 ok(hres == S_OK, "got hres 0x%08x\n", hres);
5086 if (bstr)
5088 ok(memcmp(bstr, szOneHalf_English, sizeof(szOneHalf_English)) == 0, "English locale failed (got %s)\n", wtoascii(bstr));
5089 SysFreeString(bstr);
5091 f = 0.5;
5092 hres = pVarBstrFromR4(f, lcid_spanish, LOCALE_NOUSEROVERRIDE, &bstr);
5093 ok(hres == S_OK, "got hres 0x%08x\n", hres);
5094 if (bstr)
5096 ok(memcmp(bstr, szOneHalf_Spanish, sizeof(szOneHalf_Spanish)) == 0, "Spanish locale failed (got %s)\n", wtoascii(bstr));
5097 SysFreeString(bstr);
5101 static void _BSTR_DATE(DATE dt, const char *str, int line)
5103 LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
5104 char buff[256];
5105 BSTR bstr = NULL;
5106 HRESULT hres;
5108 hres = pVarBstrFromDate(dt, lcid, LOCALE_NOUSEROVERRIDE, &bstr);
5109 if (bstr)
5111 WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0);
5112 SysFreeString(bstr);
5114 else
5115 buff[0] = 0;
5116 ok_(__FILE__, line)(hres == S_OK && !strcmp(str, buff),
5117 "Expected '%s', got '%s', hres = 0x%08x\n", str, buff, hres);
5120 static void test_VarBstrFromDate(void)
5122 #define BSTR_DATE(dt,str) _BSTR_DATE(dt,str,__LINE__)
5124 CHECKPTR(VarBstrFromDate);
5126 BSTR_DATE(0.0, "12:00:00 AM");
5127 BSTR_DATE(3.34, "1/2/1900 8:09:36 AM");
5128 BSTR_DATE(3339.34, "2/20/1909 8:09:36 AM");
5129 BSTR_DATE(365.00, "12/30/1900");
5130 BSTR_DATE(365.25, "12/30/1900 6:00:00 AM");
5131 BSTR_DATE(1461.0, "12/31/1903");
5132 BSTR_DATE(1461.5, "12/31/1903 12:00:00 PM");
5133 BSTR_DATE(-49192.24, "4/24/1765 5:45:36 AM");
5134 BSTR_DATE(-657434.0, "1/1/100");
5135 BSTR_DATE(2958465.0, "12/31/9999");
5137 #undef BSTR_DATE
5140 static void _BSTR_CY(LONG a, LONG b, const char *str, LCID lcid, int line)
5142 HRESULT hr;
5143 BSTR bstr = NULL;
5144 char buff[256];
5145 CY l;
5147 S(l).Lo = b;
5148 S(l).Hi = a;
5149 hr = pVarBstrFromCy(l, lcid, LOCALE_NOUSEROVERRIDE, &bstr);
5150 ok(hr == S_OK, "got hr 0x%08x\n", hr);
5152 if(bstr)
5154 WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0);
5155 SysFreeString(bstr);
5157 else
5158 buff[0] = 0;
5160 if(hr == S_OK)
5162 ok_(__FILE__, line)(!strcmp(str, buff), "Expected '%s', got '%s'\n", str, buff);
5166 static void test_VarBstrFromCy(void)
5168 #define BSTR_CY(a, b, str, lcid) _BSTR_CY(a, b, str, lcid, __LINE__)
5170 LCID en_us, sp;
5172 CHECKPTR(VarBstrFromCy);
5174 en_us = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
5175 sp = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
5177 BSTR_CY(0, 0, "0", en_us);
5178 BSTR_CY(0, 10000, "1", en_us);
5179 BSTR_CY(0, 15000, "1.5", en_us);
5180 BSTR_CY(0xffffffff, ((15000)^0xffffffff)+1, "-1.5", en_us);
5181 /* (1 << 32) - 1 / 1000 */
5182 BSTR_CY(0, 0xffffffff, "429496.7295", en_us);
5183 /* (1 << 32) / 1000 */
5184 BSTR_CY(1, 0, "429496.7296", en_us);
5185 /* ((1 << 63) - 1)/10000 */
5186 BSTR_CY(0x7fffffff, 0xffffffff, "922337203685477.5807", en_us);
5187 BSTR_CY(0, 9, "0.0009", en_us);
5188 BSTR_CY(0, 9, "0,0009", sp);
5190 #undef BSTR_CY
5193 static void _BSTR_DEC(BYTE scale, BYTE sign, ULONG hi, ULONG mid, ULONGLONG lo, const char *str,
5194 LCID lcid, int line)
5196 char buff[256];
5197 HRESULT hr;
5198 BSTR bstr = NULL;
5199 DECIMAL dec;
5201 SETDEC64(dec, scale, sign, hi, mid, lo);
5202 hr = pVarBstrFromDec(&dec, lcid, LOCALE_NOUSEROVERRIDE, &bstr);
5203 ok_(__FILE__, line)(hr == S_OK, "got hr 0x%08x\n", hr);
5205 if(bstr)
5207 WideCharToMultiByte(CP_ACP, 0, bstr, -1, buff, sizeof(buff), 0, 0);
5208 SysFreeString(bstr);
5210 else
5211 buff[0] = 0;
5213 if(hr == S_OK)
5215 ok_(__FILE__, line)(!strcmp(str, buff), "Expected '%s', got '%s'\n", str, buff);
5219 static void test_VarBstrFromDec(void)
5221 #define BSTR_DEC(scale, sign, hi, lo, str, lcid) _BSTR_DEC(scale, sign, hi, 0, lo, str, lcid, __LINE__)
5222 #define BSTR_DEC64(scale, sign, hi, mid, lo, str, lcid) _BSTR_DEC(scale, sign, hi, mid, lo, str, lcid, __LINE__)
5224 LCID en_us, sp;
5226 CHECKPTR(VarBstrFromDec);
5228 en_us = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
5229 sp = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), SORT_DEFAULT);
5231 BSTR_DEC(0,0,0,0, "0", en_us);
5233 BSTR_DEC(0,0,0,1, "1", en_us);
5234 BSTR_DEC(1,0,0,10, "1", en_us);
5235 BSTR_DEC(2,0,0,100, "1", en_us);
5236 BSTR_DEC(3,0,0,1000,"1", en_us);
5238 BSTR_DEC(1,0,0,15, "1.5", en_us);
5239 BSTR_DEC(2,0,0,150, "1.5", en_us);
5240 BSTR_DEC(3,0,0,1500,"1.5", en_us);
5242 BSTR_DEC(1,0x80,0,15, "-1.5", en_us);
5244 /* (1 << 32) - 1 */
5245 BSTR_DEC(0,0,0,0xffffffff, "4294967295", en_us);
5246 /* (1 << 32) */
5247 BSTR_DEC64(0,0,0,1,0, "4294967296", en_us);
5248 /* (1 << 64) - 1 */
5249 BSTR_DEC64(0,0,0,0xffffffff,0xffffffff, "18446744073709551615", en_us);
5250 /* (1 << 64) */
5251 BSTR_DEC(0,0,1,0, "18446744073709551616", en_us);
5252 /* (1 << 96) - 1 */
5253 BSTR_DEC64(0,0,0xffffffff,0xffffffff,0xffffffff, "79228162514264337593543950335", en_us);
5254 /* 1 * 10^-10 */
5255 BSTR_DEC(10,0,0,1, "0.0000000001", en_us);
5256 /* ((1 << 96) - 1) * 10^-10 */
5257 BSTR_DEC64(10,0,0xffffffffUL,0xffffffff,0xffffffff, "7922816251426433759.3543950335", en_us);
5258 /* ((1 << 96) - 1) * 10^-28 */
5259 BSTR_DEC64(28,0,0xffffffffUL,0xffffffff,0xffffffff, "7.9228162514264337593543950335", en_us);
5261 /* check leading zeros and decimal sep. for English locale */
5262 BSTR_DEC(4,0,0,9, "0.0009", en_us);
5263 BSTR_DEC(5,0,0,90, "0.0009", en_us);
5264 BSTR_DEC(6,0,0,900, "0.0009", en_us);
5265 BSTR_DEC(7,0,0,9000, "0.0009", en_us);
5267 /* check leading zeros and decimal sep. for Spanish locale */
5268 BSTR_DEC(4,0,0,9, "0,0009", sp);
5269 BSTR_DEC(5,0,0,90, "0,0009", sp);
5270 BSTR_DEC(6,0,0,900, "0,0009", sp);
5271 BSTR_DEC(7,0,0,9000, "0,0009", sp);
5273 #undef BSTR_DEC
5274 #undef BSTR_DEC64
5277 #define _VARBSTRCMP(left,right,lcid,flags,result) \
5278 hres = pVarBstrCmp(left,right,lcid,flags); \
5279 ok(hres == result, "VarBstrCmp: expected " #result ", got hres=0x%x\n", hres)
5280 #define VARBSTRCMP(left,right,flags,result) \
5281 _VARBSTRCMP(left,right,lcid,flags,result)
5283 static void test_VarBstrCmp(void)
5285 LCID lcid;
5286 HRESULT hres;
5287 static const WCHAR sz[] = {'W','u','r','s','c','h','t','\0'};
5288 static const WCHAR szempty[] = {'\0'};
5289 static const WCHAR sz1[] = { 'a',0 };
5290 static const WCHAR sz2[] = { 'A',0 };
5291 static const WCHAR s1[] = { 'a',0 };
5292 static const WCHAR s2[] = { 'a',0,'b' };
5293 static const char sb1[] = {1,0,1};
5294 static const char sb2[] = {1,0,2};
5295 static const char sbchr0[] = {0,0};
5296 static const char sbchr00[] = {0,0,0};
5297 BSTR bstr, bstrempty, bstr2;
5299 CHECKPTR(VarBstrCmp);
5301 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
5302 bstr = SysAllocString(sz);
5303 bstrempty = SysAllocString(szempty);
5305 /* NULL handling. Yepp, MSDN is totally wrong here */
5306 VARBSTRCMP(NULL,NULL,0,VARCMP_EQ);
5307 VARBSTRCMP(bstr,NULL,0,VARCMP_GT);
5308 VARBSTRCMP(NULL,bstr,0,VARCMP_LT);
5310 /* NULL and empty string comparisons */
5311 VARBSTRCMP(bstrempty,NULL,0,VARCMP_EQ);
5312 VARBSTRCMP(NULL,bstrempty,0,VARCMP_EQ);
5314 SysFreeString(bstr);
5315 bstr = SysAllocString(sz1);
5317 bstr2 = SysAllocString(sz2);
5318 VARBSTRCMP(bstr,bstr2,0,VARCMP_LT);
5319 VARBSTRCMP(bstr,bstr2,NORM_IGNORECASE,VARCMP_EQ);
5320 SysFreeString(bstr2);
5321 /* These two strings are considered equal even though one is
5322 * NULL-terminated and the other not.
5324 bstr2 = SysAllocStringLen(s1, sizeof(s1) / sizeof(WCHAR));
5325 VARBSTRCMP(bstr,bstr2,0,VARCMP_EQ);
5326 SysFreeString(bstr2);
5328 /* These two strings are not equal */
5329 bstr2 = SysAllocStringLen(s2, sizeof(s2) / sizeof(WCHAR));
5330 VARBSTRCMP(bstr,bstr2,0,VARCMP_LT);
5331 SysFreeString(bstr2);
5333 SysFreeString(bstr);
5335 bstr = SysAllocStringByteLen(sbchr0, sizeof(sbchr0));
5336 bstr2 = SysAllocStringByteLen(sbchr00, sizeof(sbchr00));
5337 VARBSTRCMP(bstr,bstrempty,0,VARCMP_GT);
5338 VARBSTRCMP(bstrempty,bstr,0,VARCMP_LT);
5339 VARBSTRCMP(bstr2,bstrempty,0,VARCMP_GT);
5340 VARBSTRCMP(bstr2,bstr,0,VARCMP_EQ);
5341 SysFreeString(bstr2);
5342 SysFreeString(bstr);
5344 /* When (LCID == 0) it should be a binary comparison
5345 * so these two strings could not match.
5347 bstr = SysAllocStringByteLen(sb1, sizeof(sb1));
5348 bstr2 = SysAllocStringByteLen(sb2, sizeof(sb2));
5349 lcid = 0;
5350 VARBSTRCMP(bstr,bstr2,0,VARCMP_LT);
5351 SysFreeString(bstr2);
5352 SysFreeString(bstr);
5354 bstr = SysAllocStringByteLen(sbchr0, sizeof(sbchr0));
5355 bstr2 = SysAllocStringByteLen(sbchr00, sizeof(sbchr00));
5356 VARBSTRCMP(bstr,bstrempty,0,VARCMP_GT);
5357 VARBSTRCMP(bstrempty,bstr,0,VARCMP_LT);
5358 VARBSTRCMP(bstr2,bstrempty,0,VARCMP_GT);
5359 VARBSTRCMP(bstr2,bstr,0,VARCMP_GT);
5360 SysFreeString(bstr2);
5361 SysFreeString(bstr);
5362 SysFreeString(bstrempty);
5365 /* Get the internal representation of a BSTR */
5366 static inline LPINTERNAL_BSTR Get(const BSTR lpszString)
5368 return lpszString ? (LPINTERNAL_BSTR)((char*)lpszString - sizeof(DWORD)) : NULL;
5371 static inline BSTR GetBSTR(const LPINTERNAL_BSTR bstr)
5373 return (BSTR)bstr->szString;
5376 static void test_SysStringLen(void)
5378 INTERNAL_BSTR bstr;
5379 BSTR str = GetBSTR(&bstr);
5381 bstr.dwLen = 0;
5382 ok (SysStringLen(str) == 0, "Expected dwLen 0, got %d\n", SysStringLen(str));
5383 bstr.dwLen = 2;
5384 ok (SysStringLen(str) == 1, "Expected dwLen 1, got %d\n", SysStringLen(str));
5387 static void test_SysStringByteLen(void)
5389 INTERNAL_BSTR bstr;
5390 BSTR str = GetBSTR(&bstr);
5392 bstr.dwLen = 0;
5393 ok (SysStringByteLen(str) == 0, "Expected dwLen 0, got %d\n", SysStringByteLen(str));
5394 bstr.dwLen = 2;
5395 ok (SysStringByteLen(str) == 2, "Expected dwLen 2, got %d\n", SysStringByteLen(str));
5398 static void test_SysAllocString(void)
5400 const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
5401 BSTR str;
5403 str = SysAllocString(NULL);
5404 ok (str == NULL, "Expected NULL, got %p\n", str);
5406 str = SysAllocString(szTest);
5407 ok (str != NULL, "Expected non-NULL\n");
5408 if (str)
5410 LPINTERNAL_BSTR bstr = Get(str);
5411 DWORD_PTR p = (DWORD_PTR)str;
5412 int align = sizeof(void *);
5414 ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5415 ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5416 ok ((p & ~(align-1)) == p, "Not aligned to %d\n", align);
5417 SysFreeString(str);
5421 static void test_SysAllocStringLen(void)
5423 const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
5424 BSTR str;
5426 /* Very early native dlls do not limit the size of strings, so skip this test */
5427 if (0)
5429 str = SysAllocStringLen(szTest, 0x80000000);
5430 ok (str == NULL, "Expected NULL, got %p\n", str);
5433 str = SysAllocStringLen(NULL, 0);
5434 ok (str != NULL, "Expected non-NULL\n");
5435 if (str)
5437 LPINTERNAL_BSTR bstr = Get(str);
5439 ok (bstr->dwLen == 0, "Expected 0, got %d\n", bstr->dwLen);
5440 ok (!bstr->szString[0], "String not empty\n");
5441 SysFreeString(str);
5444 str = SysAllocStringLen(szTest, 4);
5445 ok (str != NULL, "Expected non-NULL\n");
5446 if (str)
5448 LPINTERNAL_BSTR bstr = Get(str);
5450 ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5451 ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5452 SysFreeString(str);
5456 static void test_SysAllocStringByteLen(void)
5458 const OLECHAR szTest[10] = { 'T','e','s','t','\0' };
5459 const CHAR szTestA[6] = { 'T','e','s','t','\0','?' };
5460 char *buf;
5461 BSTR str;
5462 int i;
5464 if (sizeof(void *) == 4) /* not limited to 0x80000000 on Win64 */
5466 str = SysAllocStringByteLen(szTestA, 0x80000000);
5467 ok (str == NULL, "Expected NULL, got %p\n", str);
5470 str = SysAllocStringByteLen(szTestA, 0xffffffff);
5471 ok (str == NULL, "Expected NULL, got %p\n", str);
5473 str = SysAllocStringByteLen(NULL, 0);
5474 ok (str != NULL, "Expected non-NULL\n");
5475 if (str)
5477 LPINTERNAL_BSTR bstr = Get(str);
5479 ok (bstr->dwLen == 0, "Expected 0, got %d\n", bstr->dwLen);
5480 ok (!bstr->szString[0], "String not empty\n");
5481 SysFreeString(str);
5484 str = SysAllocStringByteLen(szTestA, 4);
5485 ok (str != NULL, "Expected non-NULL\n");
5486 if (str)
5488 LPINTERNAL_BSTR bstr = Get(str);
5490 ok (bstr->dwLen == 4, "Expected 4, got %d\n", bstr->dwLen);
5491 ok (!lstrcmpA((LPCSTR)bstr->szString, szTestA), "String different\n");
5492 SysFreeString(str);
5495 /* Odd lengths are allocated rounded up, but truncated at the right position */
5496 str = SysAllocStringByteLen(szTestA, 3);
5497 ok (str != NULL, "Expected non-NULL\n");
5498 if (str)
5500 const CHAR szTestTruncA[4] = { 'T','e','s','\0' };
5501 LPINTERNAL_BSTR bstr = Get(str);
5503 ok (bstr->dwLen == 3, "Expected 3, got %d\n", bstr->dwLen);
5504 ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n");
5505 ok (!bstr->szString[2], "String not terminated\n");
5506 SysFreeString(str);
5509 str = SysAllocStringByteLen((LPCSTR)szTest, 8);
5510 ok (str != NULL, "Expected non-NULL\n");
5511 if (str)
5513 LPINTERNAL_BSTR bstr = Get(str);
5515 ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5516 ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5517 SysFreeString(str);
5520 /* Make sure terminating null is aligned properly */
5521 buf = HeapAlloc(GetProcessHeap(), 0, 1025);
5522 ok (buf != NULL, "Expected non-NULL\n");
5523 for (i = 0; i < 1024; i++)
5525 LPINTERNAL_BSTR bstr;
5527 str = SysAllocStringByteLen(NULL, i);
5528 ok (str != NULL, "Expected non-NULL\n");
5529 bstr = Get(str);
5530 ok (bstr->dwLen == i, "Expected %d, got %d\n", i, bstr->dwLen);
5531 ok (!bstr->szString[(i+sizeof(WCHAR)-1)/sizeof(WCHAR)], "String not terminated\n");
5532 SysFreeString(str);
5534 memset(buf, 0xaa, 1025);
5535 str = SysAllocStringByteLen(buf, i);
5536 ok (str != NULL, "Expected non-NULL\n");
5537 bstr = Get(str);
5538 ok (bstr->dwLen == i, "Expected %d, got %d\n", i, bstr->dwLen);
5539 buf[i] = 0;
5540 ok (!lstrcmpA((LPCSTR)bstr->szString, buf), "String different\n");
5541 ok (!bstr->szString[(i+sizeof(WCHAR)-1)/sizeof(WCHAR)], "String not terminated\n");
5542 SysFreeString(str);
5544 HeapFree(GetProcessHeap(), 0, buf);
5547 static void test_SysReAllocString(void)
5549 const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
5550 const OLECHAR szSmaller[2] = { 'x','\0' };
5551 const OLECHAR szLarger[7] = { 'L','a','r','g','e','r','\0' };
5552 BSTR str;
5554 str = SysAllocStringLen(szTest, 4);
5555 ok (str != NULL, "Expected non-NULL\n");
5556 if (str)
5558 LPINTERNAL_BSTR bstr;
5559 int changed;
5561 bstr = Get(str);
5562 ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5563 ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5565 changed = SysReAllocString(&str, szSmaller);
5566 ok (changed == 1, "Expected 1, got %d\n", changed);
5567 /* Vista creates a new string, but older versions reuse the existing string. */
5568 /*ok (str == oldstr, "Created new string\n");*/
5569 bstr = Get(str);
5570 ok (bstr->dwLen == 2, "Expected 2, got %d\n", bstr->dwLen);
5571 ok (!lstrcmpW(bstr->szString, szSmaller), "String different\n");
5573 changed = SysReAllocString(&str, szLarger);
5574 ok (changed == 1, "Expected 1, got %d\n", changed);
5575 /* Early versions always make new strings rather than resizing */
5576 /* ok (str == oldstr, "Created new string\n"); */
5577 bstr = Get(str);
5578 ok (bstr->dwLen == 12, "Expected 12, got %d\n", bstr->dwLen);
5579 ok (!lstrcmpW(bstr->szString, szLarger), "String different\n");
5581 SysFreeString(str);
5585 static void test_SysReAllocStringLen(void)
5587 const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
5588 const OLECHAR szSmaller[2] = { 'x','\0' };
5589 const OLECHAR szLarger[7] = { 'L','a','r','g','e','r','\0' };
5590 BSTR str;
5592 str = SysAllocStringLen(szTest, 4);
5593 ok (str != NULL, "Expected non-NULL\n");
5594 if (str)
5596 LPINTERNAL_BSTR bstr;
5597 int changed;
5599 bstr = Get(str);
5600 ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen);
5601 ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
5603 changed = SysReAllocStringLen(&str, szSmaller, 1);
5604 ok (changed == 1, "Expected 1, got %d\n", changed);
5605 /* Vista creates a new string, but older versions reuse the existing string. */
5606 /*ok (str == oldstr, "Created new string\n");*/
5607 bstr = Get(str);
5608 ok (bstr->dwLen == 2, "Expected 2, got %d\n", bstr->dwLen);
5609 ok (!lstrcmpW(bstr->szString, szSmaller), "String different\n");
5611 changed = SysReAllocStringLen(&str, szLarger, 6);
5612 ok (changed == 1, "Expected 1, got %d\n", changed);
5613 /* Early versions always make new strings rather than resizing */
5614 /* ok (str == oldstr, "Created new string\n"); */
5615 bstr = Get(str);
5616 ok (bstr->dwLen == 12, "Expected 12, got %d\n", bstr->dwLen);
5617 ok (!lstrcmpW(bstr->szString, szLarger), "String different\n");
5619 changed = SysReAllocStringLen(&str, str, 6);
5620 ok (changed == 1, "Expected 1, got %d\n", changed);
5622 SysFreeString(str);
5625 /* Windows always returns null terminated strings */
5626 str = SysAllocStringLen(szTest, 4);
5627 ok (str != NULL, "Expected non-NULL\n");
5628 if (str)
5630 const int CHUNK_SIZE = 64;
5631 const int STRING_SIZE = 24;
5632 int changed;
5633 changed = SysReAllocStringLen(&str, NULL, CHUNK_SIZE);
5634 ok (changed == 1, "Expected 1, got %d\n", changed);
5635 ok (str != NULL, "Expected non-NULL\n");
5636 if (str)
5638 BSTR oldstr = str;
5640 /* Filling string */
5641 memset (str, 0xAB, CHUNK_SIZE * sizeof (OLECHAR));
5642 /* Checking null terminator */
5643 changed = SysReAllocStringLen(&str, NULL, STRING_SIZE);
5644 ok (changed == 1, "Expected 1, got %d\n", changed);
5645 ok (str != NULL, "Expected non-NULL\n");
5646 if (str)
5648 ok (str == oldstr, "Expected reuse of the old string memory\n");
5649 ok (str[STRING_SIZE] == 0,
5650 "Expected null terminator, got 0x%04X\n", str[STRING_SIZE]);
5651 SysFreeString(str);
5656 /* Some Windows applications use the same pointer for pbstr and psz */
5657 str = SysAllocStringLen(szTest, 4);
5658 ok(str != NULL, "Expected non-NULL\n");
5659 if(str)
5661 SysReAllocStringLen(&str, str, 1000000);
5662 ok(SysStringLen(str)==1000000, "Incorrect string length\n");
5663 ok(!memcmp(szTest, str, 4*sizeof(WCHAR)), "Incorrect string returned\n");
5665 SysFreeString(str);
5669 static void test_BstrCopy(void)
5671 const CHAR szTestA[6] = { 'T','e','s','t','\0','?' };
5672 const CHAR szTestTruncA[4] = { 'T','e','s','\0' };
5673 LPINTERNAL_BSTR bstr;
5674 BSTR str;
5675 HRESULT hres;
5676 VARIANT vt1, vt2;
5678 str = SysAllocStringByteLen(szTestA, 3);
5679 ok (str != NULL, "Expected non-NULL\n");
5680 if (str)
5682 V_VT(&vt1) = VT_BSTR;
5683 V_BSTR(&vt1) = str;
5684 V_VT(&vt2) = VT_EMPTY;
5685 hres = VariantCopy(&vt2, &vt1);
5686 ok (hres == S_OK,"Failed to copy binary bstring with hres 0x%08x\n", hres);
5687 bstr = Get(V_BSTR(&vt2));
5688 ok (bstr->dwLen == 3, "Expected 3, got %d\n", bstr->dwLen);
5689 ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n");
5690 VariantClear(&vt2);
5691 VariantClear(&vt1);
5695 static void test_VarBstrCat(void)
5697 static const WCHAR sz1[] = { 'a',0 };
5698 static const WCHAR sz2[] = { 'b',0 };
5699 static const WCHAR sz1sz2[] = { 'a','b',0 };
5700 static const WCHAR s1[] = { 'a',0 };
5701 static const WCHAR s2[] = { 'b',0 };
5702 static const WCHAR s1s2[] = { 'a',0,'b',0 };
5703 static const char str1A[] = "Have ";
5704 static const char str2A[] = "A Cigar";
5705 HRESULT ret;
5706 BSTR str1, str2, res;
5707 UINT len;
5709 CHECKPTR(VarBstrCat);
5711 if (0)
5713 /* Crash */
5714 pVarBstrCat(NULL, NULL, NULL);
5717 /* Concatenation of two NULL strings works */
5718 ret = pVarBstrCat(NULL, NULL, &res);
5719 ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5720 ok(res != NULL, "Expected a string\n");
5721 ok(SysStringLen(res) == 0, "Expected a 0-length string\n");
5722 SysFreeString(res);
5724 str1 = SysAllocString(sz1);
5726 /* Concatenation with one NULL arg */
5727 ret = pVarBstrCat(NULL, str1, &res);
5728 ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5729 ok(res != NULL, "Expected a string\n");
5730 ok(SysStringLen(res) == SysStringLen(str1), "Unexpected length\n");
5731 ok(!memcmp(res, sz1, SysStringLen(str1)), "Unexpected value\n");
5732 SysFreeString(res);
5733 ret = pVarBstrCat(str1, NULL, &res);
5734 ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5735 ok(res != NULL, "Expected a string\n");
5736 ok(SysStringLen(res) == SysStringLen(str1), "Unexpected length\n");
5737 ok(!memcmp(res, sz1, SysStringLen(str1)), "Unexpected value\n");
5738 SysFreeString(res);
5740 /* Concatenation of two zero-terminated strings */
5741 str2 = SysAllocString(sz2);
5742 ret = pVarBstrCat(str1, str2, &res);
5743 ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5744 ok(res != NULL, "Expected a string\n");
5745 ok(SysStringLen(res) == sizeof(sz1sz2) / sizeof(WCHAR) - 1,
5746 "Unexpected length\n");
5747 ok(!memcmp(res, sz1sz2, sizeof(sz1sz2)), "Unexpected value\n");
5748 SysFreeString(res);
5750 SysFreeString(str2);
5751 SysFreeString(str1);
5753 /* Concatenation of two strings with embedded NULLs */
5754 str1 = SysAllocStringLen(s1, sizeof(s1) / sizeof(WCHAR));
5755 str2 = SysAllocStringLen(s2, sizeof(s2) / sizeof(WCHAR));
5757 ret = pVarBstrCat(str1, str2, &res);
5758 ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5759 ok(res != NULL, "Expected a string\n");
5760 ok(SysStringLen(res) == sizeof(s1s2) / sizeof(WCHAR),
5761 "Unexpected length\n");
5762 ok(!memcmp(res, s1s2, sizeof(s1s2)), "Unexpected value\n");
5763 SysFreeString(res);
5765 SysFreeString(str2);
5766 SysFreeString(str1);
5768 /* Concatenation of ansi BSTRs, both odd byte count not including termination */
5769 str1 = SysAllocStringByteLen(str1A, sizeof(str1A)-1);
5770 str2 = SysAllocStringByteLen(str2A, sizeof(str2A)-1);
5771 len = SysStringLen(str1);
5772 ok(len == (sizeof(str1A)-1)/sizeof(WCHAR), "got length %u\n", len);
5773 len = SysStringLen(str2);
5774 ok(len == (sizeof(str2A)-1)/sizeof(WCHAR), "got length %u\n", len);
5776 ret = pVarBstrCat(str1, str2, &res);
5777 ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5778 ok(res != NULL, "Expected a string\n");
5779 len = (sizeof(str1A) + sizeof(str2A) - 2)/sizeof(WCHAR);
5780 ok(SysStringLen(res) == len, "got %d, expected %u\n", SysStringLen(res), len);
5781 ok(!memcmp(res, "Have A Cigar", sizeof(str1A) + sizeof(str2A) - 1), "got (%s)\n", (char*)res);
5782 SysFreeString(res);
5784 SysFreeString(str2);
5785 SysFreeString(str1);
5787 /* Concatenation of ansi BSTRs, both 1 byte length not including termination */
5788 str1 = SysAllocStringByteLen(str1A, 1);
5789 str2 = SysAllocStringByteLen(str2A, 1);
5790 len = SysStringLen(str1);
5791 ok(len == 0, "got length %u\n", len);
5792 len = SysStringLen(str2);
5793 ok(len == 0, "got length %u\n", len);
5795 ret = pVarBstrCat(str1, str2, &res);
5796 ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
5797 ok(res != NULL, "Expected a string\n");
5798 ok(SysStringLen(res) == 1, "got %d, expected 1\n", SysStringLen(res));
5799 ok(!memcmp(res, "HA", 2), "got (%s)\n", (char*)res);
5800 SysFreeString(res);
5802 SysFreeString(str2);
5803 SysFreeString(str1);
5806 /* IUnknown */
5808 static void test_IUnknownClear(void)
5810 HRESULT hres;
5811 VARIANTARG v;
5812 DummyDispatch u;
5813 IUnknown* pu;
5815 init_test_dispatch(1, VT_UI1, &u);
5816 pu = (IUnknown*)&u.IDispatch_iface;
5818 /* Test that IUnknown_Release is called on by-value */
5819 V_VT(&v) = VT_UNKNOWN;
5820 V_UNKNOWN(&v) = (IUnknown*)&u.IDispatch_iface;
5821 hres = VariantClear(&v);
5822 ok(hres == S_OK && u.ref == 0 && V_VT(&v) == VT_EMPTY,
5823 "clear unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5824 S_OK, 0, VT_EMPTY, hres, u.ref, V_VT(&v));
5826 /* But not when clearing a by-reference*/
5827 u.ref = 1;
5828 V_VT(&v) = VT_UNKNOWN|VT_BYREF;
5829 V_UNKNOWNREF(&v) = &pu;
5830 hres = VariantClear(&v);
5831 ok(hres == S_OK && u.ref == 1 && V_VT(&v) == VT_EMPTY,
5832 "clear dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5833 S_OK, 1, VT_EMPTY, hres, u.ref, V_VT(&v));
5836 static void test_IUnknownCopy(void)
5838 HRESULT hres;
5839 VARIANTARG vSrc, vDst;
5840 DummyDispatch u;
5841 IUnknown* pu;
5843 init_test_dispatch(1, VT_UI1, &u);
5844 pu = (IUnknown*)&u.IDispatch_iface;
5846 /* AddRef is called on by-value copy */
5847 VariantInit(&vDst);
5848 V_VT(&vSrc) = VT_UNKNOWN;
5849 V_UNKNOWN(&vSrc) = pu;
5850 hres = VariantCopy(&vDst, &vSrc);
5851 ok(hres == S_OK && u.ref == 2 && V_VT(&vDst) == VT_UNKNOWN,
5852 "copy unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5853 S_OK, 2, VT_EMPTY, hres, u.ref, V_VT(&vDst));
5855 /* AddRef is skipped on copy of by-reference IDispatch */
5856 VariantInit(&vDst);
5857 u.ref = 1;
5858 V_VT(&vSrc) = VT_UNKNOWN|VT_BYREF;
5859 V_UNKNOWNREF(&vSrc) = &pu;
5860 hres = VariantCopy(&vDst, &vSrc);
5861 ok(hres == S_OK && u.ref == 1 && V_VT(&vDst) == (VT_UNKNOWN|VT_BYREF),
5862 "copy unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5863 S_OK, 1, VT_DISPATCH, hres, u.ref, V_VT(&vDst));
5865 /* AddRef is called copying by-reference IDispatch with indirection */
5866 VariantInit(&vDst);
5867 u.ref = 1;
5868 V_VT(&vSrc) = VT_UNKNOWN|VT_BYREF;
5869 V_UNKNOWNREF(&vSrc) = &pu;
5870 hres = VariantCopyInd(&vDst, &vSrc);
5871 ok(hres == S_OK && u.ref == 2 && V_VT(&vDst) == VT_UNKNOWN,
5872 "copy unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5873 S_OK, 2, VT_DISPATCH, hres, u.ref, V_VT(&vDst));
5875 /* Indirection in place also calls AddRef */
5876 u.ref = 1;
5877 V_VT(&vSrc) = VT_UNKNOWN|VT_BYREF;
5878 V_UNKNOWNREF(&vSrc) = &pu;
5879 hres = VariantCopyInd(&vSrc, &vSrc);
5880 ok(hres == S_OK && u.ref == 2 && V_VT(&vSrc) == VT_UNKNOWN,
5881 "copy unknown: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5882 S_OK, 2, VT_DISPATCH, hres, u.ref, V_VT(&vSrc));
5885 static void test_IUnknownChangeTypeEx(void)
5887 HRESULT hres;
5888 VARIANTARG vSrc, vDst;
5889 LCID lcid;
5890 VARTYPE vt;
5891 DummyDispatch u;
5892 IUnknown* pu;
5894 init_test_dispatch(1, VT_UI1, &u);
5895 pu = (IUnknown*)&u.IDispatch_iface;
5897 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
5899 /* NULL IUnknown -> IDispatch */
5900 V_VT(&vSrc) = VT_UNKNOWN;
5901 V_UNKNOWN(&vSrc) = NULL;
5902 VariantInit(&vDst);
5903 V_DISPATCH(&vDst) = (void*)0xdeadbeef;
5904 hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, VT_DISPATCH);
5905 ok(hres == S_OK && V_VT(&vDst) == VT_DISPATCH && V_DISPATCH(&vDst) == NULL,
5906 "change unk(src,dst): expected 0x%08x,%d,%p, got 0x%08x,%d,%p\n",
5907 S_OK, VT_DISPATCH, NULL, hres, V_VT(&vDst), V_DISPATCH(&vDst));
5909 V_VT(&vSrc) = VT_UNKNOWN;
5910 V_UNKNOWN(&vSrc) = pu;
5912 /* =>IDispatch in place */
5913 hres = VariantChangeTypeEx(&vSrc, &vSrc, lcid, 0, VT_DISPATCH);
5914 ok(hres == S_OK && u.ref == 1 &&
5915 V_VT(&vSrc) == VT_DISPATCH && V_DISPATCH(&vSrc) == (IDispatch*)pu,
5916 "change unk(src=src): expected 0x%08x,%d,%d,%p, got 0x%08x,%d,%d,%p\n",
5917 S_OK, 1, VT_DISPATCH, pu, hres, u.ref, V_VT(&vSrc), V_DISPATCH(&vSrc));
5919 /* =>IDispatch */
5920 u.ref = 1;
5921 V_VT(&vSrc) = VT_UNKNOWN;
5922 V_UNKNOWN(&vSrc) = pu;
5923 VariantInit(&vDst);
5924 hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, VT_UNKNOWN);
5925 /* Note vSrc is not cleared, as final refcount is 2 */
5926 ok(hres == S_OK && u.ref == 2 &&
5927 V_VT(&vDst) == VT_UNKNOWN && V_UNKNOWN(&vDst) == pu,
5928 "change unk(src,dst): expected 0x%08x,%d,%d,%p, got 0x%08x,%d,%d,%p\n",
5929 S_OK, 2, VT_UNKNOWN, pu, hres, u.ref, V_VT(&vDst), V_UNKNOWN(&vDst));
5931 /* Can't change unknown to anything else */
5932 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
5934 HRESULT hExpected = DISP_E_BADVARTYPE;
5936 V_VT(&vSrc) = VT_UNKNOWN;
5937 V_UNKNOWN(&vSrc) = pu;
5938 VariantInit(&vDst);
5940 if (vt == VT_UNKNOWN || vt == VT_DISPATCH || vt == VT_EMPTY || vt == VT_NULL)
5941 hExpected = S_OK;
5942 else
5944 if (vt == VT_I8 || vt == VT_UI8)
5946 if (has_i8)
5947 hExpected = DISP_E_TYPEMISMATCH;
5949 else if (vt == VT_RECORD)
5951 hExpected = DISP_E_TYPEMISMATCH;
5953 else if (vt >= VT_I2 && vt <= VT_UINT && vt != (VARTYPE)15)
5954 hExpected = DISP_E_TYPEMISMATCH;
5957 hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
5958 ok(hres == hExpected,
5959 "change unk(badvar): vt %d expected 0x%08x, got 0x%08x\n",
5960 vt, hExpected, hres);
5964 /* IDispatch */
5965 static void test_IDispatchClear(void)
5967 HRESULT hres;
5968 VARIANTARG v;
5969 DummyDispatch d;
5970 IDispatch* pd;
5972 init_test_dispatch(1, VT_UI1, &d);
5973 pd = &d.IDispatch_iface;
5975 /* As per IUnknown */
5977 V_VT(&v) = VT_DISPATCH;
5978 V_DISPATCH(&v) = pd;
5979 hres = VariantClear(&v);
5980 ok(hres == S_OK && d.ref == 0 && V_VT(&v) == VT_EMPTY,
5981 "clear dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5982 S_OK, 0, VT_EMPTY, hres, d.ref, V_VT(&v));
5984 d.ref = 1;
5985 V_VT(&v) = VT_DISPATCH|VT_BYREF;
5986 V_DISPATCHREF(&v) = &pd;
5987 hres = VariantClear(&v);
5988 ok(hres == S_OK && d.ref == 1 && V_VT(&v) == VT_EMPTY,
5989 "clear dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
5990 S_OK, 1, VT_EMPTY, hres, d.ref, V_VT(&v));
5993 static void test_IDispatchCopy(void)
5995 HRESULT hres;
5996 VARIANTARG vSrc, vDst;
5997 DummyDispatch d;
5998 IDispatch* pd;
6000 init_test_dispatch(1, VT_UI1, &d);
6001 pd = &d.IDispatch_iface;
6003 /* As per IUnknown */
6005 VariantInit(&vDst);
6006 V_VT(&vSrc) = VT_DISPATCH;
6007 V_DISPATCH(&vSrc) = pd;
6008 hres = VariantCopy(&vDst, &vSrc);
6009 ok(hres == S_OK && d.ref == 2 && V_VT(&vDst) == VT_DISPATCH,
6010 "copy dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
6011 S_OK, 2, VT_EMPTY, hres, d.ref, V_VT(&vDst));
6013 VariantInit(&vDst);
6014 d.ref = 1;
6015 V_VT(&vSrc) = VT_DISPATCH|VT_BYREF;
6016 V_DISPATCHREF(&vSrc) = &pd;
6017 hres = VariantCopy(&vDst, &vSrc);
6018 ok(hres == S_OK && d.ref == 1 && V_VT(&vDst) == (VT_DISPATCH|VT_BYREF),
6019 "copy dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
6020 S_OK, 1, VT_DISPATCH, hres, d.ref, V_VT(&vDst));
6022 VariantInit(&vDst);
6023 d.ref = 1;
6024 V_VT(&vSrc) = VT_DISPATCH|VT_BYREF;
6025 V_DISPATCHREF(&vSrc) = &pd;
6026 hres = VariantCopyInd(&vDst, &vSrc);
6027 ok(hres == S_OK && d.ref == 2 && V_VT(&vDst) == VT_DISPATCH,
6028 "copy dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
6029 S_OK, 2, VT_DISPATCH, hres, d.ref, V_VT(&vDst));
6031 d.ref = 1;
6032 V_VT(&vSrc) = VT_DISPATCH|VT_BYREF;
6033 V_DISPATCHREF(&vSrc) = &pd;
6034 hres = VariantCopyInd(&vSrc, &vSrc);
6035 ok(hres == S_OK && d.ref == 2 && V_VT(&vSrc) == VT_DISPATCH,
6036 "copy dispatch: expected 0x%08x, %d, %d, got 0x%08x, %d, %d\n",
6037 S_OK, 2, VT_DISPATCH, hres, d.ref, V_VT(&vSrc));
6040 static void test_IDispatchChangeTypeEx(void)
6042 HRESULT hres;
6043 VARIANTARG vSrc, vDst;
6044 LCID lcid;
6045 DummyDispatch d;
6046 IDispatch* pd;
6048 init_test_dispatch(1, VT_UI1, &d);
6049 pd = &d.IDispatch_iface;
6051 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
6053 /* NULL IDispatch -> IUnknown */
6054 V_VT(&vSrc) = VT_DISPATCH;
6055 V_DISPATCH(&vSrc) = NULL;
6056 VariantInit(&vDst);
6057 V_UNKNOWN(&vDst) = (void*)0xdeadbeef;
6058 hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, VT_UNKNOWN);
6059 ok(hres == S_OK && V_VT(&vDst) == VT_UNKNOWN && V_UNKNOWN(&vDst) == NULL,
6060 "change unk(src,dst): expected 0x%08x,%d,%p, got 0x%08x,%d,%p\n",
6061 S_OK, VT_UNKNOWN, NULL, hres, V_VT(&vDst), V_UNKNOWN(&vDst));
6063 V_VT(&vSrc) = VT_DISPATCH;
6064 V_DISPATCH(&vSrc) = pd;
6066 /* =>IUnknown in place */
6067 hres = VariantChangeTypeEx(&vSrc, &vSrc, lcid, 0, VT_UNKNOWN);
6068 ok(hres == S_OK && d.ref == 1 &&
6069 V_VT(&vSrc) == VT_UNKNOWN && V_UNKNOWN(&vSrc) == (IUnknown*)pd,
6070 "change disp(src=src): expected 0x%08x,%d,%d,%p, got 0x%08x,%d,%d,%p\n",
6071 S_OK, 1, VT_UNKNOWN, pd, hres, d.ref, V_VT(&vSrc), V_UNKNOWN(&vSrc));
6073 /* =>IUnknown */
6074 d.ref = 1;
6075 V_VT(&vSrc) = VT_DISPATCH;
6076 V_DISPATCH(&vSrc) = pd;
6077 VariantInit(&vDst);
6078 hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, VT_UNKNOWN);
6079 /* Note vSrc is not cleared, as final refcount is 2 */
6080 ok(hres == S_OK && d.ref == 2 &&
6081 V_VT(&vDst) == VT_UNKNOWN && V_UNKNOWN(&vDst) == (IUnknown*)pd,
6082 "change disp(src,dst): expected 0x%08x,%d,%d,%p, got 0x%08x,%d,%d,%p\n",
6083 S_OK, 2, VT_UNKNOWN, pd, hres, d.ref, V_VT(&vDst), V_UNKNOWN(&vDst));
6085 /* FIXME: Verify that VARIANT_NOVALUEPROP prevents conversion to integral
6086 * types. this requires that the xxxFromDisp tests work first.
6090 /* VT_ERROR */
6091 static void test_ErrorChangeTypeEx(void)
6093 HRESULT hres;
6094 VARIANTARG vSrc, vDst;
6095 VARTYPE vt;
6096 LCID lcid;
6098 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
6100 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
6102 HRESULT hExpected = DISP_E_BADVARTYPE;
6104 V_VT(&vSrc) = VT_ERROR;
6105 V_ERROR(&vSrc) = 1;
6106 VariantInit(&vDst);
6107 hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
6109 if (vt == VT_ERROR)
6110 hExpected = S_OK;
6111 else
6113 if (vt == VT_I8 || vt == VT_UI8)
6115 if (has_i8)
6116 hExpected = DISP_E_TYPEMISMATCH;
6118 else if (vt == VT_RECORD)
6120 hExpected = DISP_E_TYPEMISMATCH;
6122 else if (vt <= VT_UINT && vt != (VARTYPE)15)
6123 hExpected = DISP_E_TYPEMISMATCH;
6126 ok(hres == hExpected,
6127 "change err: vt %d expected 0x%08x, got 0x%08x\n", vt, hExpected, hres);
6131 /* VT_EMPTY */
6132 static void test_EmptyChangeTypeEx(void)
6134 VARTYPE vt;
6135 LCID lcid;
6137 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
6139 for (vt = VT_EMPTY; vt <= VT_BSTR_BLOB; vt++)
6141 HRESULT hExpected, hres;
6142 VARIANTARG vSrc, vDst;
6144 /* skip for undefined types */
6145 if ((vt == 15) || (vt > VT_VERSIONED_STREAM && vt < VT_BSTR_BLOB))
6146 continue;
6148 switch (vt)
6150 case VT_I8:
6151 case VT_UI8:
6152 if (has_i8)
6153 hExpected = S_OK;
6154 else
6155 hExpected = DISP_E_BADVARTYPE;
6156 break;
6157 case VT_RECORD:
6158 case VT_VARIANT:
6159 case VT_DISPATCH:
6160 case VT_UNKNOWN:
6161 case VT_ERROR:
6162 hExpected = DISP_E_TYPEMISMATCH;
6163 break;
6164 case VT_EMPTY:
6165 case VT_NULL:
6166 case VT_I2:
6167 case VT_I4:
6168 case VT_R4:
6169 case VT_R8:
6170 case VT_CY:
6171 case VT_DATE:
6172 case VT_BSTR:
6173 case VT_BOOL:
6174 case VT_DECIMAL:
6175 case VT_I1:
6176 case VT_UI1:
6177 case VT_UI2:
6178 case VT_UI4:
6179 case VT_INT:
6180 case VT_UINT:
6181 hExpected = S_OK;
6182 break;
6183 default:
6184 hExpected = DISP_E_BADVARTYPE;
6187 VariantInit(&vSrc);
6188 V_VT(&vSrc) = VT_EMPTY;
6189 memset(&vDst, 0, sizeof(vDst));
6190 V_VT(&vDst) = VT_NULL;
6192 hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
6193 ok(hres == hExpected, "change empty: vt %d expected 0x%08x, got 0x%08x, vt %d\n",
6194 vt, hExpected, hres, V_VT(&vDst));
6195 if (hres == S_OK)
6197 ok(V_VT(&vDst) == vt, "change empty: vt %d, got %d\n", vt, V_VT(&vDst));
6198 VariantClear(&vDst);
6203 /* VT_NULL */
6204 static void test_NullChangeTypeEx(void)
6206 VARTYPE vt;
6207 LCID lcid;
6209 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
6211 for (vt = VT_EMPTY; vt <= VT_BSTR_BLOB; vt++)
6213 VARIANTARG vSrc, vDst;
6214 HRESULT hExpected, hres;
6216 /* skip for undefined types */
6217 if ((vt == 15) || (vt > VT_VERSIONED_STREAM && vt < VT_BSTR_BLOB))
6218 continue;
6220 switch (vt)
6222 case VT_I8:
6223 case VT_UI8:
6224 if (has_i8)
6225 hExpected = DISP_E_TYPEMISMATCH;
6226 else
6227 hExpected = DISP_E_BADVARTYPE;
6228 break;
6229 case VT_NULL:
6230 hExpected = S_OK;
6231 break;
6232 case VT_EMPTY:
6233 case VT_I2:
6234 case VT_I4:
6235 case VT_R4:
6236 case VT_R8:
6237 case VT_CY:
6238 case VT_DATE:
6239 case VT_BSTR:
6240 case VT_DISPATCH:
6241 case VT_ERROR:
6242 case VT_BOOL:
6243 case VT_VARIANT:
6244 case VT_UNKNOWN:
6245 case VT_DECIMAL:
6246 case VT_I1:
6247 case VT_UI1:
6248 case VT_UI2:
6249 case VT_UI4:
6250 case VT_INT:
6251 case VT_UINT:
6252 case VT_RECORD:
6253 hExpected = DISP_E_TYPEMISMATCH;
6254 break;
6255 default:
6256 hExpected = DISP_E_BADVARTYPE;
6259 VariantInit(&vSrc);
6260 V_VT(&vSrc) = VT_NULL;
6261 memset(&vDst, 0, sizeof(vDst));
6262 V_VT(&vDst) = VT_EMPTY;
6264 hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
6265 ok(hres == hExpected, "change null: vt %d expected 0x%08x, got 0x%08x, vt %d\n",
6266 vt, hExpected, hres, V_VT(&vDst));
6268 /* should work only for VT_NULL -> VT_NULL case */
6269 if (hres == S_OK)
6270 ok(V_VT(&vDst) == VT_NULL, "change null: VT_NULL expected 0x%08x, got 0x%08x, vt %d\n",
6271 hExpected, hres, V_VT(&vDst));
6272 else
6273 ok(V_VT(&vDst) == VT_EMPTY, "change null: vt %d expected 0x%08x, got 0x%08x, vt %d\n",
6274 vt, hExpected, hres, V_VT(&vDst));
6279 /* VT_UINT */
6280 static void test_UintChangeTypeEx(void)
6282 HRESULT hres;
6283 VARIANTARG vSrc, vDst;
6284 LCID lcid;
6286 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
6288 /* Converting a VT_UINT to a VT_INT does not check for overflow */
6289 V_VT(&vDst) = VT_EMPTY;
6290 V_VT(&vSrc) = VT_UINT;
6291 V_UI4(&vSrc) = -1;
6292 hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, VT_I4);
6293 ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == -1,
6294 "change uint: Expected %d,0x%08x,%d got %d,0x%08x,%d\n",
6295 VT_I4, S_OK, -1, V_VT(&vDst), hres, V_I4(&vDst));
6298 #define NUM_CUST_ITEMS 16
6300 static void test_ClearCustData(void)
6302 CUSTDATA ci;
6303 unsigned i;
6305 CHECKPTR(ClearCustData);
6307 ci.cCustData = NUM_CUST_ITEMS;
6308 ci.prgCustData = CoTaskMemAlloc( sizeof(CUSTDATAITEM) * NUM_CUST_ITEMS );
6309 for (i = 0; i < NUM_CUST_ITEMS; i++)
6310 VariantInit(&ci.prgCustData[i].varValue);
6311 pClearCustData(&ci);
6312 ok(!ci.cCustData && !ci.prgCustData, "ClearCustData didn't clear fields!\n");
6315 static void test_NullByRef(void)
6317 VARIANT v1, v2;
6318 HRESULT hRes;
6320 VariantInit(&v1);
6321 VariantInit(&v2);
6322 V_VT(&v1) = VT_BYREF|VT_VARIANT;
6323 V_BYREF(&v1) = 0;
6325 hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_I4);
6326 ok(hRes == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx should return DISP_E_TYPEMISMATCH\n");
6328 VariantClear(&v1);
6329 V_VT(&v1) = VT_BYREF|VT_VARIANT;
6330 V_BYREF(&v1) = 0;
6331 V_VT(&v2) = VT_I4;
6332 V_I4(&v2) = 123;
6334 hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_VARIANT);
6335 ok(hRes == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx should return DISP_E_TYPEMISMATCH\n");
6336 ok(V_VT(&v2) == VT_I4 && V_I4(&v2) == 123, "VariantChangeTypeEx shouldn't change pvargDest\n");
6338 hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_BYREF|VT_I4);
6339 ok(hRes == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx should return DISP_E_TYPEMISMATCH\n");
6341 hRes = VariantChangeTypeEx(&v2, &v1, 0, 0, 0x3847);
6342 ok(hRes == DISP_E_BADVARTYPE, "VariantChangeTypeEx should return DISP_E_BADVARTYPE\n");
6345 /* Dst Variant should remain unchanged if VariantChangeType cannot convert */
6346 static void test_ChangeType_keep_dst(void)
6348 VARIANT v1, v2;
6349 BSTR bstr;
6350 static const WCHAR testW[] = {'t','e','s','t',0};
6351 HRESULT hres;
6353 bstr = SysAllocString(testW);
6354 VariantInit(&v1);
6355 VariantInit(&v2);
6356 V_VT(&v1) = VT_BSTR;
6357 V_BSTR(&v1) = bstr;
6358 hres = VariantChangeTypeEx(&v1, &v1, 0, 0, VT_INT);
6359 ok(hres == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx returns %08x\n", hres);
6360 ok(V_VT(&v1) == VT_BSTR && V_BSTR(&v1) == bstr, "VariantChangeTypeEx changed dst variant\n");
6361 V_VT(&v2) = VT_INT;
6362 V_INT(&v2) = 4;
6363 hres = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_INT);
6364 ok(hres == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx returns %08x\n", hres);
6365 ok(V_VT(&v2) == VT_INT && V_INT(&v2) == 4, "VariantChangeTypeEx changed dst variant\n");
6366 V_VT(&v2) = 0xff; /* incorrect variant type */
6367 hres = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_INT);
6368 ok(hres == DISP_E_TYPEMISMATCH, "VariantChangeTypeEx returns %08x\n", hres);
6369 ok(V_VT(&v2) == 0xff, "VariantChangeTypeEx changed dst variant\n");
6370 hres = VariantChangeTypeEx(&v2, &v1, 0, 0, VT_BSTR);
6371 ok(hres == DISP_E_BADVARTYPE, "VariantChangeTypeEx returns %08x\n", hres);
6372 ok(V_VT(&v2) == 0xff, "VariantChangeTypeEx changed dst variant\n");
6373 SysFreeString(bstr);
6376 /* This tests assumes an empty cache, so it needs to be ran early in the test. */
6377 static void test_bstr_cache(void)
6379 BSTR str, str2, strs[20];
6380 unsigned i;
6382 static const WCHAR testW[] = {'t','e','s','t',0};
6384 if (GetEnvironmentVariableA("OANOCACHE", NULL, 0)) {
6385 skip("BSTR cache is disabled, some tests will be skipped.\n");
6386 return;
6389 str = SysAllocString(testW);
6390 /* This should put the string into cache */
6391 SysFreeString(str);
6392 /* The string is in cache, this won't touch it */
6393 SysFreeString(str);
6395 ok(SysStringLen(str) == 4, "unexpected len\n");
6396 ok(!lstrcmpW(str, testW), "string changed\n");
6398 str2 = SysAllocString(testW);
6399 ok(str == str2, "str != str2\n");
6400 SysFreeString(str2);
6402 /* Fill the bucket with cached entries.
6403 We roll our own, to show that the cache doesn't use
6404 the bstr length field to determine bucket allocation. */
6405 for(i=0; i < sizeof(strs)/sizeof(*strs); i++)
6407 DWORD_PTR *ptr = CoTaskMemAlloc(64);
6408 ptr[0] = 0;
6409 strs[i] = (BSTR)(ptr + 1);
6411 for(i=0; i < sizeof(strs)/sizeof(*strs); i++)
6412 SysFreeString(strs[i]);
6414 /* Following allocation will be made from cache */
6415 str = SysAllocStringLen(NULL, 24);
6416 ok(str == strs[0], "str != strs[0]\n");
6418 /* Smaller buffers may also use larget cached buffers */
6419 str2 = SysAllocStringLen(NULL, 16);
6420 ok(str2 == strs[1], "str2 != strs[1]\n");
6422 SysFreeString(str);
6423 SysFreeString(str2);
6424 SysFreeString(str);
6425 SysFreeString(str2);
6428 static void write_typelib(int res_no, const char *filename)
6430 DWORD written;
6431 HANDLE file;
6432 HRSRC res;
6433 void *ptr;
6435 file = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
6436 ok( file != INVALID_HANDLE_VALUE, "file creation failed\n" );
6437 if (file == INVALID_HANDLE_VALUE) return;
6438 res = FindResourceA( GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(res_no), "TYPELIB" );
6439 ok( res != 0, "couldn't find resource\n" );
6440 ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
6441 WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
6442 ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
6443 CloseHandle( file );
6446 static const char *create_test_typelib(int res_no)
6448 static char filename[MAX_PATH];
6450 GetTempFileNameA( ".", "tlb", 0, filename );
6451 write_typelib(res_no, filename);
6452 return filename;
6455 static void test_recinfo(void)
6457 static const WCHAR testW[] = {'t','e','s','t',0};
6458 static WCHAR teststructW[] = {'t','e','s','t','_','s','t','r','u','c','t',0};
6459 static WCHAR teststruct2W[] = {'t','e','s','t','_','s','t','r','u','c','t','2',0};
6460 static WCHAR teststruct3W[] = {'t','e','s','t','_','s','t','r','u','c','t','3',0};
6461 WCHAR filenameW[MAX_PATH], filename2W[MAX_PATH];
6462 ITypeInfo *typeinfo, *typeinfo2, *typeinfo3;
6463 IRecordInfo *recinfo, *recinfo2, *recinfo3;
6464 struct test_struct teststruct, testcopy;
6465 ITypeLib *typelib, *typelib2;
6466 const char *filename;
6467 DummyDispatch dispatch;
6468 TYPEATTR *attr;
6469 MEMBERID memid;
6470 UINT16 found;
6471 HRESULT hr;
6472 ULONG size;
6473 BOOL ret;
6475 filename = create_test_typelib(2);
6476 MultiByteToWideChar(CP_ACP, 0, filename, -1, filenameW, MAX_PATH);
6477 hr = LoadTypeLibEx(filenameW, REGKIND_NONE, &typelib);
6478 ok(hr == S_OK, "got 0x%08x\n", hr);
6480 filename = create_test_typelib(3);
6481 MultiByteToWideChar(CP_ACP, 0, filename, -1, filename2W, MAX_PATH);
6482 hr = LoadTypeLibEx(filename2W, REGKIND_NONE, &typelib2);
6483 ok(hr == S_OK, "got 0x%08x\n", hr);
6485 typeinfo = NULL;
6486 found = 1;
6487 hr = ITypeLib_FindName(typelib, teststructW, 0, &typeinfo, &memid, &found);
6488 ok(hr == S_OK, "got 0x%08x\n", hr);
6489 ok(typeinfo != NULL, "got %p\n", typeinfo);
6490 hr = ITypeInfo_GetTypeAttr(typeinfo, &attr);
6491 ok(hr == S_OK, "got 0x%08x\n", hr);
6492 ok(IsEqualGUID(&attr->guid, &UUID_test_struct), "got %s\n", wine_dbgstr_guid(&attr->guid));
6493 ok(attr->typekind == TKIND_RECORD, "got %d\n", attr->typekind);
6495 typeinfo2 = NULL;
6496 found = 1;
6497 hr = ITypeLib_FindName(typelib, teststruct2W, 0, &typeinfo2, &memid, &found);
6498 ok(hr == S_OK, "got 0x%08x\n", hr);
6499 ok(typeinfo2 != NULL, "got %p\n", typeinfo2);
6501 typeinfo3 = NULL;
6502 found = 1;
6503 hr = ITypeLib_FindName(typelib2, teststruct3W, 0, &typeinfo3, &memid, &found);
6504 ok(hr == S_OK, "got 0x%08x\n", hr);
6505 ok(typeinfo3 != NULL, "got %p\n", typeinfo3);
6507 hr = GetRecordInfoFromTypeInfo(typeinfo, &recinfo);
6508 ok(hr == S_OK, "got 0x%08x\n", hr);
6510 hr = GetRecordInfoFromTypeInfo(typeinfo2, &recinfo2);
6511 ok(hr == S_OK, "got 0x%08x\n", hr);
6513 hr = GetRecordInfoFromTypeInfo(typeinfo3, &recinfo3);
6514 ok(hr == S_OK, "got 0x%08x\n", hr);
6516 /* IsMatchingType, these two records only differ in GUIDs */
6517 ret = IRecordInfo_IsMatchingType(recinfo, recinfo2);
6518 ok(!ret, "got %d\n", ret);
6520 /* these two have same GUIDs, but different set of fields */
6521 ret = IRecordInfo_IsMatchingType(recinfo2, recinfo3);
6522 ok(ret, "got %d\n", ret);
6524 IRecordInfo_Release(recinfo3);
6525 ITypeInfo_Release(typeinfo3);
6526 IRecordInfo_Release(recinfo2);
6527 ITypeInfo_Release(typeinfo2);
6529 size = 0;
6530 hr = IRecordInfo_GetSize(recinfo, &size);
6531 ok(hr == S_OK, "got 0x%08x\n", hr);
6532 ok(size == sizeof(struct test_struct), "got size %d\n", size);
6533 ok(attr->cbSizeInstance == sizeof(struct test_struct), "got instance size %d\n", attr->cbSizeInstance);
6534 ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
6536 /* RecordInit() */
6537 teststruct.hr = E_FAIL;
6538 teststruct.b = 0x1;
6539 teststruct.disp = (void*)0xdeadbeef;
6540 teststruct.bstr = (void*)0xdeadbeef;
6542 hr = IRecordInfo_RecordInit(recinfo, &teststruct);
6543 ok(hr == S_OK, "got 0x%08x\n", hr);
6544 ok(teststruct.hr == 0, "got 0x%08x\n", teststruct.hr);
6545 ok(teststruct.b == 0, "got 0x%08x\n", teststruct.b);
6546 ok(teststruct.disp == NULL, "got %p\n", teststruct.disp);
6547 ok(teststruct.bstr == NULL, "got %p\n", teststruct.bstr);
6549 init_test_dispatch(10, VT_UI1, &dispatch);
6551 /* RecordCopy(), interface field reference increased */
6552 teststruct.hr = S_FALSE;
6553 teststruct.b = VARIANT_TRUE;
6554 teststruct.disp = &dispatch.IDispatch_iface;
6555 teststruct.bstr = SysAllocString(testW);
6556 memset(&testcopy, 0, sizeof(testcopy));
6557 hr = IRecordInfo_RecordCopy(recinfo, &teststruct, &testcopy);
6558 ok(hr == S_OK, "got 0x%08x\n", hr);
6559 ok(testcopy.hr == S_FALSE, "got 0x%08x\n", testcopy.hr);
6560 ok(testcopy.b == VARIANT_TRUE, "got %d\n", testcopy.b);
6561 ok(testcopy.disp == teststruct.disp, "got %p\n", testcopy.disp);
6562 ok(dispatch.ref == 11, "got %d\n", dispatch.ref);
6563 ok(testcopy.bstr != teststruct.bstr, "got %p\n", testcopy.bstr);
6564 ok(!lstrcmpW(testcopy.bstr, teststruct.bstr), "got %s, %s\n", wine_dbgstr_w(testcopy.bstr), wine_dbgstr_w(teststruct.bstr));
6566 /* RecordClear() */
6567 hr = IRecordInfo_RecordClear(recinfo, &teststruct);
6568 ok(hr == S_OK, "got 0x%08x\n", hr);
6569 ok(teststruct.bstr == NULL, "got %p\n", teststruct.bstr);
6570 hr = IRecordInfo_RecordClear(recinfo, &testcopy);
6571 ok(hr == S_OK, "got 0x%08x\n", hr);
6572 ok(testcopy.bstr == NULL, "got %p\n", testcopy.bstr);
6574 /* now the destination contains the interface pointer */
6575 memset(&testcopy, 0, sizeof(testcopy));
6576 testcopy.disp = &dispatch.IDispatch_iface;
6577 dispatch.ref = 10;
6579 hr = IRecordInfo_RecordCopy(recinfo, &teststruct, &testcopy);
6580 ok(hr == S_OK, "got 0x%08x\n", hr);
6581 ok(dispatch.ref == 9, "got %d\n", dispatch.ref);
6583 IRecordInfo_Release(recinfo);
6585 ITypeInfo_Release(typeinfo);
6586 ITypeLib_Release(typelib);
6587 DeleteFileW(filenameW);
6588 DeleteFileW(filename2W);
6591 START_TEST(vartype)
6593 hOleaut32 = GetModuleHandleA("oleaut32.dll");
6595 has_i8 = GetProcAddress(hOleaut32, "VarI8FromI1") != NULL;
6596 has_locales = has_i8 && GetProcAddress(hOleaut32, "GetVarConversionLocaleSetting") != NULL;
6598 trace("LCIDs: System=0x%08x, User=0x%08x\n", GetSystemDefaultLCID(),
6599 GetUserDefaultLCID());
6601 test_bstr_cache();
6603 test_VarI1FromI2();
6604 test_VarI1FromI4();
6605 test_VarI1FromI8();
6606 test_VarI1FromUI1();
6607 test_VarI1FromUI2();
6608 test_VarI1FromUI4();
6609 test_VarI1FromUI8();
6610 test_VarI1FromBool();
6611 test_VarI1FromR4();
6612 test_VarI1FromR8();
6613 test_VarI1FromDate();
6614 test_VarI1FromCy();
6615 test_VarI1FromDec();
6616 test_VarI1FromStr();
6617 test_VarUI1FromDisp();
6618 test_VarI1Copy();
6619 test_VarI1ChangeTypeEx();
6621 test_VarUI1FromI1();
6622 test_VarUI1FromI2();
6623 test_VarUI1FromI4();
6624 test_VarUI1FromI8();
6625 test_VarUI1FromUI2();
6626 test_VarUI1FromUI4();
6627 test_VarUI1FromUI8();
6628 test_VarUI1FromBool();
6629 test_VarUI1FromR4();
6630 test_VarUI1FromR8();
6631 test_VarUI1FromDate();
6632 test_VarUI1FromCy();
6633 test_VarUI1FromDec();
6634 test_VarUI1FromStr();
6635 test_VarUI1Copy();
6636 test_VarUI1ChangeTypeEx();
6638 test_VarI2FromI1();
6639 test_VarI2FromI4();
6640 test_VarI2FromI8();
6641 test_VarI2FromUI1();
6642 test_VarI2FromUI2();
6643 test_VarI2FromUI4();
6644 test_VarI2FromUI8();
6645 test_VarI2FromBool();
6646 test_VarI2FromR4();
6647 test_VarI2FromR8();
6648 test_VarI2FromDate();
6649 test_VarI2FromCy();
6650 test_VarI2FromDec();
6651 test_VarI2FromStr();
6652 test_VarI2Copy();
6653 test_VarI2ChangeTypeEx();
6655 test_VarUI2FromI1();
6656 test_VarUI2FromI2();
6657 test_VarUI2FromI4();
6658 test_VarUI2FromI8();
6659 test_VarUI2FromUI1();
6660 test_VarUI2FromUI4();
6661 test_VarUI2FromUI8();
6662 test_VarUI2FromBool();
6663 test_VarUI2FromR4();
6664 test_VarUI2FromR8();
6665 test_VarUI2FromDate();
6666 test_VarUI2FromCy();
6667 test_VarUI2FromDec();
6668 test_VarUI2FromStr();
6669 test_VarUI2Copy();
6670 test_VarUI2ChangeTypeEx();
6672 test_VarI4FromI1();
6673 test_VarI4FromI2();
6674 test_VarI4FromI8();
6675 test_VarI4FromUI1();
6676 test_VarI4FromUI2();
6677 test_VarI4FromUI4();
6678 test_VarI4FromUI8();
6679 test_VarI4FromBool();
6680 test_VarI4FromR4();
6681 test_VarI4FromR8();
6682 test_VarI4FromDate();
6683 test_VarI4FromCy();
6684 test_VarI4FromDec();
6685 test_VarI4FromStr();
6686 test_VarI4Copy();
6687 test_VarI4ChangeTypeEx();
6689 test_VarUI4FromI1();
6690 test_VarUI4FromI2();
6691 test_VarUI4FromUI2();
6692 test_VarUI4FromI8();
6693 test_VarUI4FromUI1();
6694 test_VarUI4FromI4();
6695 test_VarUI4FromUI8();
6696 test_VarUI4FromBool();
6697 test_VarUI4FromR4();
6698 test_VarUI4FromR8();
6699 test_VarUI4FromDate();
6700 test_VarUI4FromCy();
6701 test_VarUI4FromDec();
6702 test_VarUI4FromStr();
6703 test_VarUI4Copy();
6704 test_VarUI4ChangeTypeEx();
6706 test_VarI8FromI1();
6707 test_VarI8FromUI1();
6708 test_VarI8FromI2();
6709 test_VarI8FromUI2();
6710 test_VarI8FromUI4();
6711 test_VarI8FromR4();
6712 test_VarI8FromR8();
6713 test_VarI8FromBool();
6714 test_VarI8FromUI8();
6715 test_VarI8FromCy();
6716 test_VarI8FromDec();
6717 test_VarI8FromDate();
6718 test_VarI8FromStr();
6719 test_VarI8Copy();
6720 test_VarI8ChangeTypeEx();
6722 test_VarUI8FromI1();
6723 test_VarUI8FromUI1();
6724 test_VarUI8FromI2();
6725 test_VarUI8FromUI2();
6726 test_VarUI8FromUI4();
6727 test_VarUI8FromR4();
6728 test_VarUI8FromR8();
6729 test_VarUI8FromBool();
6730 test_VarUI8FromI8();
6731 test_VarUI8FromCy();
6732 test_VarUI8FromDec();
6733 test_VarUI8FromDate();
6734 test_VarUI8FromStr();
6735 test_VarUI8Copy();
6736 test_VarUI8ChangeTypeEx();
6738 test_VarR4FromI1();
6739 test_VarR4FromUI1();
6740 test_VarR4FromI2();
6741 test_VarR4FromUI2();
6742 test_VarR4FromI4();
6743 test_VarR4FromUI4();
6744 test_VarR4FromR8();
6745 test_VarR4FromBool();
6746 test_VarR4FromCy();
6747 test_VarR4FromI8();
6748 test_VarR4FromUI8();
6749 test_VarR4FromDec();
6750 test_VarR4FromDate();
6751 test_VarR4FromStr();
6752 test_VarR4Copy();
6753 test_VarR4ChangeTypeEx();
6755 test_VarR8FromI1();
6756 test_VarR8FromUI1();
6757 test_VarR8FromI2();
6758 test_VarR8FromUI2();
6759 test_VarR8FromI4();
6760 test_VarR8FromUI4();
6761 test_VarR8FromR4();
6762 test_VarR8FromBool();
6763 test_VarR8FromCy();
6764 test_VarR8FromI8();
6765 test_VarR8FromUI8();
6766 test_VarR8FromDec();
6767 test_VarR8FromDate();
6768 test_VarR8FromStr();
6769 test_VarR8Copy();
6770 test_VarR8ChangeTypeEx();
6771 test_VarR8Round();
6773 test_VarDateFromI1();
6774 test_VarDateFromUI1();
6775 test_VarDateFromI2();
6776 test_VarDateFromUI2();
6777 test_VarDateFromI4();
6778 test_VarDateFromUI4();
6779 test_VarDateFromR4();
6780 test_VarDateFromR8();
6781 test_VarDateFromBool();
6782 test_VarDateFromCy();
6783 test_VarDateFromI8();
6784 test_VarDateFromUI8();
6785 test_VarDateFromDec();
6786 test_VarDateFromStr();
6787 test_VarDateCopy();
6788 test_VarDateChangeTypeEx();
6790 test_VarCyFromI1();
6791 test_VarCyFromUI1();
6792 test_VarCyFromI2();
6793 test_VarCyFromUI2();
6794 test_VarCyFromI4();
6795 test_VarCyFromUI4();
6796 test_VarCyFromR4();
6797 test_VarCyFromR8();
6798 test_VarCyFromBool();
6799 test_VarCyFromI8();
6800 test_VarCyFromUI8();
6801 test_VarCyFromDec();
6802 test_VarCyFromDate();
6804 test_VarCyAdd();
6805 test_VarCyMul();
6806 test_VarCySub();
6807 test_VarCyAbs();
6808 test_VarCyNeg();
6809 test_VarCyMulI4();
6810 test_VarCyMulI8();
6811 test_VarCyCmp();
6812 test_VarCyCmpR8();
6813 test_VarCyRound();
6814 test_VarCyFix();
6815 test_VarCyInt();
6817 test_VarDecFromI1();
6818 test_VarDecFromI2();
6819 test_VarDecFromI4();
6820 test_VarDecFromI8();
6821 test_VarDecFromUI1();
6822 test_VarDecFromUI2();
6823 test_VarDecFromUI4();
6824 test_VarDecFromUI8();
6825 test_VarDecFromR4();
6826 test_VarDecFromR8();
6827 test_VarDecFromDate();
6828 test_VarDecFromStr();
6829 test_VarDecFromCy();
6830 test_VarDecFromDate();
6831 test_VarDecFromBool();
6833 test_VarDecAbs();
6834 test_VarDecNeg();
6835 test_VarDecAdd();
6836 test_VarDecSub();
6837 test_VarDecCmp();
6838 test_VarDecCmpR8();
6839 test_VarDecMul();
6840 test_VarDecDiv();
6841 test_VarDecRound();
6843 test_VarBoolFromI1();
6844 test_VarBoolFromUI1();
6845 test_VarBoolFromI2();
6846 test_VarBoolFromUI2();
6847 test_VarBoolFromI4();
6848 test_VarBoolFromUI4();
6849 test_VarBoolFromR4();
6850 test_VarBoolFromR8();
6851 test_VarBoolFromCy();
6852 test_VarBoolFromI8();
6853 test_VarBoolFromUI8();
6854 test_VarBoolFromDec();
6855 test_VarBoolFromDate();
6856 test_VarBoolFromStr();
6857 test_VarBoolCopy();
6858 test_VarBoolChangeTypeEx();
6860 test_VarBstrFromR4();
6861 test_VarBstrFromDate();
6862 test_VarBstrFromCy();
6863 test_VarBstrFromDec();
6864 test_VarBstrCmp();
6865 test_SysStringLen();
6866 test_SysStringByteLen();
6867 test_SysAllocString();
6868 test_SysAllocStringLen();
6869 test_SysAllocStringByteLen();
6870 test_SysReAllocString();
6871 test_SysReAllocStringLen();
6872 test_BstrCopy();
6873 test_VarBstrCat();
6875 test_IUnknownClear();
6876 test_IUnknownCopy();
6877 test_IUnknownChangeTypeEx();
6879 test_IDispatchClear();
6880 test_IDispatchCopy();
6881 test_IDispatchChangeTypeEx();
6883 test_ErrorChangeTypeEx();
6884 test_EmptyChangeTypeEx();
6885 test_NullChangeTypeEx();
6886 test_UintChangeTypeEx();
6888 test_ClearCustData();
6890 test_NullByRef();
6891 test_ChangeType_keep_dst();
6893 test_recinfo();