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