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