oleaut32: Fix VarParseNumFromStr()'s handling of currency decimals.
[wine.git] / dlls / oleaut32 / tests / vartest.c
blobf61490051793b7097185d539c6de963d4905763d
1 /*
2 * VARIANT test program
4 * Copyright 1998 Jean-Claude Cote
5 * Copyright 2006 Google (Benjamin Arai)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <math.h>
25 #include <float.h>
27 #define COBJMACROS
28 #define CONST_VTABLE
29 #define NONAMELESSUNION
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winsock2.h"
34 #include "wine/test.h"
35 #include "winuser.h"
36 #include "wingdi.h"
37 #include "winnls.h"
38 #include "winerror.h"
39 #include "winnt.h"
41 #include "wtypes.h"
42 #include "oleauto.h"
44 static HMODULE hOleaut32;
46 static HRESULT (WINAPI *pVarUdateFromDate)(DATE,ULONG,UDATE*);
47 static HRESULT (WINAPI *pVarDateFromUdate)(UDATE*,ULONG,DATE*);
48 static INT (WINAPI *pSystemTimeToVariantTime)(LPSYSTEMTIME,double*);
49 static INT (WINAPI *pVariantTimeToSystemTime)(double,LPSYSTEMTIME);
50 static INT (WINAPI *pDosDateTimeToVariantTime)(USHORT,USHORT,double*);
51 static INT (WINAPI *pVariantTimeToDosDateTime)(double,USHORT*,USHORT *);
53 static const WCHAR sz12[] = {'1','2','\0'};
54 /* the strings are localized */
55 static WCHAR sz12_false[32];
56 static WCHAR sz12_true[32];
58 /* Get a conversion function ptr, return if function not available */
59 #define CHECKPTR(func) p##func = (void*)GetProcAddress(hOleaut32, #func); \
60 if (!p##func) { win_skip("function " # func " not available, not testing it\n"); return; }
62 /* Has I8/UI8 data type? */
63 static BOOL has_i8;
65 /* When comparing floating point values we cannot expect an exact match
66 * because the rounding errors depend on the exact algorithm.
68 #define EQ_DOUBLE(a,b) (fabs((a)-(b)) / (1.0+fabs(a)+fabs(b)) < 1e-14)
69 #define EQ_FLOAT(a,b) (fabs((a)-(b)) / (1.0+fabs(a)+fabs(b)) < 1e-7)
71 #define SKIPTESTS(a) if((a > VT_CLSID+10) && (a < VT_BSTR_BLOB-10)) continue
73 /* Allow our test macros to work for VT_NULL and VT_EMPTY too */
74 #define V_EMPTY(v) V_I4(v)
75 #define V_NULL(v) V_I4(v)
77 /* Size constraints for overflow tests */
78 #define I1_MAX 0x7f
79 #define I1_MIN ((-I1_MAX)-1)
80 #define UI1_MAX 0xff
81 #define UI1_MIN 0
82 #define I2_MAX 0x7fff
83 #define I2_MIN ((-I2_MAX)-1)
84 #define UI2_MAX 0xffff
85 #define UI2_MIN 0
86 #define I4_MAX 0x7fffffff
87 #define I4_MIN ((-I4_MAX)-1)
88 #define UI4_MAX 0xffffffff
89 #define UI4_MIN 0
90 #define I8_MAX (((LONGLONG)I4_MAX << 32) | UI4_MAX)
91 #define I8_MIN ((-I8_MAX)-1)
92 #define UI8_MAX (((ULONGLONG)UI4_MAX << 32) | UI4_MAX)
93 #define UI8_MIN 0
94 #define DATE_MAX 2958465
95 #define DATE_MIN -657434
96 #define R4_MAX FLT_MAX
97 #define R4_MIN FLT_MIN
98 #define R8_MAX DBL_MAX
99 #define R8_MIN DBL_MIN
101 #define DEFINE_EXPECT(func) \
102 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
104 #define SET_EXPECT(func) \
105 do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
107 #define CHECK_EXPECT2(func) \
108 do { \
109 ok(expect_ ##func, "unexpected call " #func "\n"); \
110 called_ ## func = TRUE; \
111 }while(0)
113 #define CHECK_EXPECT(func) \
114 do { \
115 CHECK_EXPECT2(func); \
116 expect_ ## func = FALSE; \
117 }while(0)
119 #define CHECK_CALLED(func) \
120 do { \
121 ok(called_ ## func, "expected " #func "\n"); \
122 expect_ ## func = called_ ## func = FALSE; \
123 }while(0)
125 DEFINE_EXPECT(dispatch_invoke);
127 typedef struct
129 IDispatch IDispatch_iface;
130 VARTYPE vt;
131 HRESULT result;
132 } DummyDispatch;
134 static inline DummyDispatch *impl_from_IDispatch(IDispatch *iface)
136 return CONTAINING_RECORD(iface, DummyDispatch, IDispatch_iface);
139 static ULONG WINAPI DummyDispatch_AddRef(IDispatch *iface)
141 return 2;
144 static ULONG WINAPI DummyDispatch_Release(IDispatch *iface)
146 return 1;
149 static HRESULT WINAPI DummyDispatch_QueryInterface(IDispatch *iface,
150 REFIID riid,
151 void** ppvObject)
153 *ppvObject = NULL;
155 if (IsEqualIID(riid, &IID_IDispatch) ||
156 IsEqualIID(riid, &IID_IUnknown))
158 *ppvObject = iface;
159 IDispatch_AddRef(iface);
162 return *ppvObject ? S_OK : E_NOINTERFACE;
165 static HRESULT WINAPI DummyDispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
167 ok(0, "Unexpected call\n");
168 return E_NOTIMPL;
171 static HRESULT WINAPI DummyDispatch_GetTypeInfo(IDispatch *iface, UINT tinfo, LCID lcid, ITypeInfo **ti)
173 ok(0, "Unexpected call\n");
174 return E_NOTIMPL;
177 static HRESULT WINAPI DummyDispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *names,
178 UINT cnames, LCID lcid, DISPID *dispid)
180 ok(0, "Unexpected call\n");
181 return E_NOTIMPL;
184 static HRESULT WINAPI DummyDispatch_Invoke(IDispatch *iface,
185 DISPID dispid, REFIID riid,
186 LCID lcid, WORD wFlags,
187 DISPPARAMS *params,
188 VARIANT *res,
189 EXCEPINFO *ei,
190 UINT *arg_err)
192 DummyDispatch *This = impl_from_IDispatch(iface);
194 CHECK_EXPECT(dispatch_invoke);
196 ok(dispid == DISPID_VALUE, "got dispid %d\n", dispid);
197 ok(IsEqualIID(riid, &IID_NULL), "go riid %s\n", wine_dbgstr_guid(riid));
198 ok(wFlags == DISPATCH_PROPERTYGET, "Flags wrong\n");
200 ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
201 ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
202 ok(params->cArgs == 0, "got %d\n", params->cArgs);
203 ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
205 ok(res != NULL, "got %p\n", res);
206 ok(V_VT(res) == VT_EMPTY, "got %d\n", V_VT(res));
207 ok(ei == NULL, "got %p\n", ei);
208 ok(arg_err == NULL, "got %p\n", arg_err);
210 if (FAILED(This->result))
211 return This->result;
213 V_VT(res) = This->vt;
214 if (This->vt == VT_UI1)
215 V_UI1(res) = 34;
216 else if (This->vt == VT_NULL)
218 V_VT(res) = VT_NULL;
219 V_BSTR(res) = NULL;
221 else
222 memset(res, 0, sizeof(*res));
224 return S_OK;
227 static const IDispatchVtbl DummyDispatch_VTable =
229 DummyDispatch_QueryInterface,
230 DummyDispatch_AddRef,
231 DummyDispatch_Release,
232 DummyDispatch_GetTypeInfoCount,
233 DummyDispatch_GetTypeInfo,
234 DummyDispatch_GetIDsOfNames,
235 DummyDispatch_Invoke
238 static void init_test_dispatch(VARTYPE vt, DummyDispatch *dispatch)
240 dispatch->IDispatch_iface.lpVtbl = &DummyDispatch_VTable;
241 dispatch->vt = vt;
242 dispatch->result = S_OK;
245 typedef struct IRecordInfoImpl
247 IRecordInfo IRecordInfo_iface;
248 LONG ref;
249 unsigned int recordclear;
250 unsigned int getsize;
251 unsigned int recordcopy;
252 struct __tagBRECORD *rec;
253 } IRecordInfoImpl;
255 static inline IRecordInfoImpl *impl_from_IRecordInfo(IRecordInfo *iface)
257 return CONTAINING_RECORD(iface, IRecordInfoImpl, IRecordInfo_iface);
260 static HRESULT WINAPI RecordInfo_QueryInterface(IRecordInfo *iface, REFIID riid, void **obj)
262 *obj = NULL;
264 if (IsEqualIID(riid, &IID_IUnknown) ||
265 IsEqualIID(riid, &IID_IRecordInfo))
267 *obj = iface;
268 IRecordInfo_AddRef(iface);
269 return S_OK;
272 return E_NOINTERFACE;
275 static ULONG WINAPI RecordInfo_AddRef(IRecordInfo *iface)
277 IRecordInfoImpl* This = impl_from_IRecordInfo(iface);
278 return InterlockedIncrement(&This->ref);
281 static ULONG WINAPI RecordInfo_Release(IRecordInfo *iface)
283 IRecordInfoImpl* This = impl_from_IRecordInfo(iface);
284 ULONG ref = InterlockedDecrement(&This->ref);
286 if (!ref)
287 HeapFree(GetProcessHeap(), 0, This);
289 return ref;
292 static HRESULT WINAPI RecordInfo_RecordInit(IRecordInfo *iface, PVOID pvNew)
294 ok(0, "unexpected call\n");
295 return E_NOTIMPL;
298 static HRESULT WINAPI RecordInfo_RecordClear(IRecordInfo *iface, void *data)
300 IRecordInfoImpl* This = impl_from_IRecordInfo(iface);
301 This->recordclear++;
302 This->rec->pvRecord = NULL;
303 return S_OK;
306 static HRESULT WINAPI RecordInfo_RecordCopy(IRecordInfo *iface, void *src, void *dest)
308 IRecordInfoImpl* This = impl_from_IRecordInfo(iface);
309 This->recordcopy++;
310 ok(src == (void*)0xdeadbeef, "wrong src pointer %p\n", src);
311 return S_OK;
314 static HRESULT WINAPI RecordInfo_GetGuid(IRecordInfo *iface, GUID *pguid)
316 ok(0, "unexpected call\n");
317 return E_NOTIMPL;
320 static HRESULT WINAPI RecordInfo_GetName(IRecordInfo *iface, BSTR *pbstrName)
322 ok(0, "unexpected call\n");
323 return E_NOTIMPL;
326 static HRESULT WINAPI RecordInfo_GetSize(IRecordInfo *iface, ULONG* size)
328 IRecordInfoImpl* This = impl_from_IRecordInfo(iface);
329 This->getsize++;
330 *size = 0;
331 return S_OK;
334 static HRESULT WINAPI RecordInfo_GetTypeInfo(IRecordInfo *iface, ITypeInfo **ppTypeInfo)
336 ok(0, "unexpected call\n");
337 return E_NOTIMPL;
340 static HRESULT WINAPI RecordInfo_GetField(IRecordInfo *iface, PVOID pvData,
341 LPCOLESTR szFieldName, VARIANT *pvarField)
343 ok(0, "unexpected call\n");
344 return E_NOTIMPL;
347 static HRESULT WINAPI RecordInfo_GetFieldNoCopy(IRecordInfo *iface, PVOID pvData,
348 LPCOLESTR szFieldName, VARIANT *pvarField, PVOID *ppvDataCArray)
350 ok(0, "unexpected call\n");
351 return E_NOTIMPL;
354 static HRESULT WINAPI RecordInfo_PutField(IRecordInfo *iface, ULONG wFlags, PVOID pvData,
355 LPCOLESTR szFieldName, VARIANT *pvarField)
357 ok(0, "unexpected call\n");
358 return E_NOTIMPL;
361 static HRESULT WINAPI RecordInfo_PutFieldNoCopy(IRecordInfo *iface, ULONG wFlags,
362 PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField)
364 ok(0, "unexpected call\n");
365 return E_NOTIMPL;
368 static HRESULT WINAPI RecordInfo_GetFieldNames(IRecordInfo *iface, ULONG *pcNames,
369 BSTR *rgBstrNames)
371 ok(0, "unexpected call\n");
372 return E_NOTIMPL;
375 static BOOL WINAPI RecordInfo_IsMatchingType(IRecordInfo *iface, IRecordInfo *info2)
377 ok(0, "unexpected call\n");
378 return FALSE;
381 static PVOID WINAPI RecordInfo_RecordCreate(IRecordInfo *iface)
383 ok(0, "unexpected call\n");
384 return NULL;
387 static HRESULT WINAPI RecordInfo_RecordCreateCopy(IRecordInfo *iface, PVOID pvSource,
388 PVOID *ppvDest)
390 ok(0, "unexpected call\n");
391 return E_NOTIMPL;
394 static HRESULT WINAPI RecordInfo_RecordDestroy(IRecordInfo *iface, PVOID pvRecord)
396 ok(0, "unexpected call\n");
397 return E_NOTIMPL;
400 static const IRecordInfoVtbl RecordInfoVtbl =
402 RecordInfo_QueryInterface,
403 RecordInfo_AddRef,
404 RecordInfo_Release,
405 RecordInfo_RecordInit,
406 RecordInfo_RecordClear,
407 RecordInfo_RecordCopy,
408 RecordInfo_GetGuid,
409 RecordInfo_GetName,
410 RecordInfo_GetSize,
411 RecordInfo_GetTypeInfo,
412 RecordInfo_GetField,
413 RecordInfo_GetFieldNoCopy,
414 RecordInfo_PutField,
415 RecordInfo_PutFieldNoCopy,
416 RecordInfo_GetFieldNames,
417 RecordInfo_IsMatchingType,
418 RecordInfo_RecordCreate,
419 RecordInfo_RecordCreateCopy,
420 RecordInfo_RecordDestroy
423 static IRecordInfoImpl *get_test_recordinfo(void)
425 IRecordInfoImpl *rec;
427 rec = HeapAlloc(GetProcessHeap(), 0, sizeof(IRecordInfoImpl));
428 rec->IRecordInfo_iface.lpVtbl = &RecordInfoVtbl;
429 rec->ref = 1;
430 rec->recordclear = 0;
431 rec->getsize = 0;
432 rec->recordcopy = 0;
434 return rec;
437 static void init(void)
439 BSTR bstr;
440 HRESULT res;
442 res = VarBstrFromBool(VARIANT_TRUE, LANG_USER_DEFAULT, VAR_LOCALBOOL, &bstr);
443 ok(res == S_OK && bstr[0], "Expected localized string for 'True'\n");
444 /* lstrcpyW / lstrcatW do not work on win95 */
445 memcpy(sz12_true, sz12, sizeof(sz12));
446 if (bstr) memcpy(&sz12_true[2], bstr, SysStringByteLen(bstr) + sizeof(WCHAR));
447 SysFreeString(bstr);
449 res = VarBstrFromBool(VARIANT_FALSE, LANG_USER_DEFAULT, VAR_LOCALBOOL, &bstr);
450 ok(res == S_OK && bstr[0], "Expected localized string for 'False'\n");
451 memcpy(sz12_false, sz12, sizeof(sz12));
452 if (bstr) memcpy(&sz12_false[2], bstr, SysStringByteLen(bstr) + sizeof(WCHAR));
453 SysFreeString(bstr);
455 hOleaut32 = GetModuleHandleA("oleaut32.dll");
456 has_i8 = GetProcAddress(hOleaut32, "VarI8FromI1") != NULL;
457 if (!has_i8)
458 skip("No support for I8 and UI8 data types\n");
461 /* Functions to set a DECIMAL */
462 static void setdec(DECIMAL* dec, BYTE scl, BYTE sgn, ULONG hi32, ULONG64 lo64)
464 S(U(*dec)).scale = scl;
465 S(U(*dec)).sign = sgn;
466 dec->Hi32 = hi32;
467 U1(*dec).Lo64 = lo64;
470 static void setdec64(DECIMAL* dec, BYTE scl, BYTE sgn, ULONG hi32, ULONG mid32, ULONG lo32)
472 S(U(*dec)).scale = scl;
473 S(U(*dec)).sign = sgn;
474 dec->Hi32 = hi32;
475 S1(U1(*dec)).Mid32 = mid32;
476 S1(U1(*dec)).Lo32 = lo32;
479 /* return the string text of a given variant type */
480 static char vtstr_buffer[16][256];
481 static int vtstr_current=0;
482 static const char *vtstr(int x)
484 switch(x) {
485 #define CASE(vt) case VT_##vt: return #vt
486 CASE(EMPTY);
487 CASE(NULL);
488 CASE(I2);
489 CASE(I4);
490 CASE(R4);
491 CASE(R8);
492 CASE(CY);
493 CASE(DATE);
494 CASE(BSTR);
495 CASE(DISPATCH);
496 CASE(ERROR);
497 CASE(BOOL);
498 CASE(VARIANT);
499 CASE(UNKNOWN);
500 CASE(DECIMAL);
501 CASE(I1);
502 CASE(UI1);
503 CASE(UI2);
504 CASE(UI4);
505 CASE(I8);
506 CASE(UI8);
507 CASE(INT);
508 CASE(UINT);
509 CASE(VOID);
510 CASE(HRESULT);
511 CASE(PTR);
512 CASE(SAFEARRAY);
513 CASE(CARRAY);
514 CASE(USERDEFINED);
515 CASE(LPSTR);
516 CASE(LPWSTR);
517 CASE(RECORD);
518 CASE(INT_PTR);
519 CASE(UINT_PTR);
520 CASE(FILETIME);
521 CASE(BLOB);
522 CASE(STREAM);
523 CASE(STORAGE);
524 CASE(STREAMED_OBJECT);
525 CASE(STORED_OBJECT);
526 CASE(BLOB_OBJECT);
527 CASE(CF);
528 CASE(CLSID);
529 CASE(VERSIONED_STREAM);
530 CASE(VECTOR);
531 CASE(ARRAY);
532 CASE(BYREF);
533 CASE(RESERVED);
534 CASE(ILLEGAL);
535 #undef CASE
537 case 0xfff:
538 return "VT_BSTR_BLOB/VT_ILLEGALMASKED/VT_TYPEMASK";
540 default:
541 vtstr_current %= ARRAY_SIZE(vtstr_buffer);
542 sprintf(vtstr_buffer[vtstr_current], "unknown variant type %d", x);
543 return vtstr_buffer[vtstr_current++];
547 static const char *variantstr( const VARIANT *var )
549 vtstr_current %= ARRAY_SIZE(vtstr_buffer);
550 switch(V_VT(var))
552 case VT_I1:
553 sprintf( vtstr_buffer[vtstr_current], "VT_I1(%d)", V_I1(var) ); break;
554 case VT_I2:
555 sprintf( vtstr_buffer[vtstr_current], "VT_I2(%d)", V_I2(var) ); break;
556 case VT_I4:
557 sprintf( vtstr_buffer[vtstr_current], "VT_I4(%d)", V_I4(var) ); break;
558 case VT_INT:
559 sprintf( vtstr_buffer[vtstr_current], "VT_INT(%d)", V_INT(var) ); break;
560 case VT_I8:
561 sprintf( vtstr_buffer[vtstr_current], "VT_I8(%x%08x)", (UINT)(V_I8(var) >> 32), (UINT)V_I8(var) ); break;
562 case VT_UI8:
563 sprintf( vtstr_buffer[vtstr_current], "VT_UI8(%x%08x)", (UINT)(V_UI8(var) >> 32), (UINT)V_UI8(var) ); break;
564 case VT_R4:
565 sprintf( vtstr_buffer[vtstr_current], "VT_R4(%g)", V_R4(var) ); break;
566 case VT_R8:
567 sprintf( vtstr_buffer[vtstr_current], "VT_R8(%g)", V_R8(var) ); break;
568 case VT_UI1:
569 sprintf( vtstr_buffer[vtstr_current], "VT_UI1(%u)", V_UI1(var) ); break;
570 case VT_UI2:
571 sprintf( vtstr_buffer[vtstr_current], "VT_UI2(%u)", V_UI2(var) ); break;
572 case VT_UI4:
573 sprintf( vtstr_buffer[vtstr_current], "VT_UI4(%u)", V_UI4(var) ); break;
574 case VT_UINT:
575 sprintf( vtstr_buffer[vtstr_current], "VT_UINT(%d)", V_UINT(var) ); break;
576 case VT_CY:
577 sprintf( vtstr_buffer[vtstr_current], "VT_CY(%x%08x)", S(V_CY(var)).Hi, S(V_CY(var)).Lo ); break;
578 case VT_DATE:
579 sprintf( vtstr_buffer[vtstr_current], "VT_DATE(%g)", V_DATE(var) ); break;
580 default:
581 return vtstr(V_VT(var));
583 return vtstr_buffer[vtstr_current++];
586 static BOOL is_expected_variant( const VARIANT *result, const VARIANT *expected )
588 if (V_VT(result) != V_VT(expected)) return FALSE;
589 switch(V_VT(expected))
591 case VT_EMPTY:
592 case VT_NULL:
593 return TRUE;
595 #define CASE(vt) case VT_##vt: return (V_##vt(result) == V_##vt(expected))
596 CASE(BOOL);
597 CASE(I1);
598 CASE(UI1);
599 CASE(I2);
600 CASE(UI2);
601 CASE(I4);
602 CASE(UI4);
603 CASE(I8);
604 CASE(UI8);
605 CASE(INT);
606 CASE(UINT);
607 #undef CASE
609 case VT_DATE:
610 return EQ_FLOAT(V_DATE(result), V_DATE(expected));
611 case VT_R4:
612 return EQ_FLOAT(V_R4(result), V_R4(expected));
613 case VT_R8:
614 return EQ_FLOAT(V_R8(result), V_R8(expected));
615 case VT_CY:
616 return (V_CY(result).int64 == V_CY(expected).int64);
617 case VT_BSTR:
618 return !lstrcmpW( V_BSTR(result), V_BSTR(expected) );
619 case VT_DECIMAL:
620 return !memcmp( &V_DECIMAL(result), &V_DECIMAL(expected), sizeof(DECIMAL) );
621 default:
622 ok(0, "unhandled variant type %s\n",vtstr(V_VT(expected)));
623 return FALSE;
627 static void test_var_call1( int line, HRESULT (WINAPI *func)(LPVARIANT,LPVARIANT),
628 VARIANT *arg, VARIANT *expected )
630 VARIANT old_arg = *arg;
631 VARIANT result;
632 HRESULT hres;
634 memset( &result, 0, sizeof(result) );
635 hres = func( arg, &result );
636 ok_(__FILE__,line)( hres == S_OK, "wrong result %x\n", hres );
637 if (hres == S_OK)
638 ok_(__FILE__,line)( is_expected_variant( &result, expected ),
639 "got %s expected %s\n", variantstr(&result), variantstr(expected) );
640 ok_(__FILE__,line)( is_expected_variant( arg, &old_arg ), "Modified argument %s / %s\n",
641 variantstr(&old_arg), variantstr(arg));
642 VariantClear( &result );
645 static void test_var_call2( int line, HRESULT (WINAPI *func)(LPVARIANT,LPVARIANT,LPVARIANT),
646 VARIANT *left, VARIANT *right, VARIANT *expected )
648 VARIANT old_left = *left, old_right = *right;
649 VARIANT result;
650 HRESULT hres;
652 memset( &result, 0, sizeof(result) );
653 hres = func( left, right, &result );
654 ok_(__FILE__,line)( hres == S_OK, "wrong result %x\n", hres );
655 if (hres == S_OK)
656 ok_(__FILE__,line)( is_expected_variant( &result, expected ),
657 "got %s expected %s\n", variantstr(&result), variantstr(expected) );
658 ok_(__FILE__,line)( is_expected_variant( left, &old_left ), "Modified left argument %s / %s\n",
659 variantstr(&old_left), variantstr(left));
660 ok_(__FILE__,line)( is_expected_variant( right, &old_right ), "Modified right argument %s / %s\n",
661 variantstr(&old_right), variantstr(right));
662 VariantClear( &result );
665 #define test_bstr_var(a,b) _test_bstr_var(__LINE__,a,b)
666 static void _test_bstr_var(unsigned line, const VARIANT *v, const WCHAR *str)
668 ok_(__FILE__,line)(V_VT(v) == VT_BSTR, "unexpected vt=%d\n", V_VT(v));
669 if(V_VT(v) == VT_BSTR)
670 ok(!lstrcmpW(V_BSTR(v), str), "v=%s, expected %s\n", wine_dbgstr_w(V_BSTR(v)),
671 wine_dbgstr_w(str));
674 static void test_VariantInit(void)
676 VARIANT v;
678 memset(&v, -1, sizeof(v));
679 VariantInit(&v);
680 ok(V_VT(&v) == VT_EMPTY, "VariantInit() returned vt %d\n", V_VT(&v));
683 /* All possible combinations of extra V_VT() flags */
684 static const VARTYPE ExtraFlags[16] =
687 VT_VECTOR,
688 VT_ARRAY,
689 VT_BYREF,
690 VT_RESERVED,
691 VT_VECTOR|VT_ARRAY,
692 VT_VECTOR|VT_BYREF,
693 VT_VECTOR|VT_RESERVED,
694 VT_VECTOR|VT_ARRAY|VT_BYREF,
695 VT_VECTOR|VT_ARRAY|VT_RESERVED,
696 VT_VECTOR|VT_BYREF|VT_RESERVED,
697 VT_VECTOR|VT_ARRAY|VT_BYREF|VT_RESERVED,
698 VT_ARRAY|VT_BYREF,
699 VT_ARRAY|VT_RESERVED,
700 VT_ARRAY|VT_BYREF|VT_RESERVED,
701 VT_BYREF|VT_RESERVED,
704 /* Determine if a vt is valid for VariantClear() */
705 static BOOL IsValidVariantClearVT(VARTYPE vt, VARTYPE extraFlags)
707 BOOL ret = FALSE;
709 /* Only the following flags/types are valid */
710 if ((vt <= VT_LPWSTR || vt == VT_RECORD || vt == VT_CLSID) &&
711 vt != (VARTYPE)15 &&
712 (vt < (VARTYPE)24 || vt > (VARTYPE)31) &&
713 (!(extraFlags & (VT_BYREF|VT_ARRAY)) || vt > VT_NULL) &&
714 (extraFlags == 0 || extraFlags == VT_BYREF || extraFlags == VT_ARRAY ||
715 extraFlags == (VT_ARRAY|VT_BYREF)))
716 ret = TRUE; /* ok */
718 if (!has_i8 && (vt == VT_I8 || vt == VT_UI8))
719 ret = FALSE; /* Old versions of oleaut32 */
720 return ret;
723 typedef struct
725 IUnknown IUnknown_iface;
726 LONG ref;
727 LONG events;
728 } test_VariantClearImpl;
730 static inline test_VariantClearImpl *impl_from_IUnknown(IUnknown *iface)
732 return CONTAINING_RECORD(iface, test_VariantClearImpl, IUnknown_iface);
735 static HRESULT WINAPI VC_QueryInterface(LPUNKNOWN iface,REFIID riid,LPVOID *ppobj)
737 test_VariantClearImpl *This = impl_from_IUnknown(iface);
738 This->events |= 0x1;
739 return E_NOINTERFACE;
742 static ULONG WINAPI VC_AddRef(LPUNKNOWN iface) {
743 test_VariantClearImpl *This = impl_from_IUnknown(iface);
744 This->events |= 0x2;
745 return InterlockedIncrement(&This->ref);
748 static ULONG WINAPI VC_Release(LPUNKNOWN iface) {
749 test_VariantClearImpl *This = impl_from_IUnknown(iface);
750 /* static class, won't be freed */
751 This->events |= 0x4;
752 return InterlockedDecrement(&This->ref);
755 static const IUnknownVtbl test_VariantClear_vtbl = {
756 VC_QueryInterface,
757 VC_AddRef,
758 VC_Release,
761 static test_VariantClearImpl test_myVariantClearImpl = {{&test_VariantClear_vtbl}, 1, 0};
763 static void test_VariantClear(void)
765 struct __tagBRECORD *rec;
766 IRecordInfoImpl *recinfo;
767 HRESULT hres;
768 VARIANTARG v;
769 VARIANT v2;
770 size_t i;
771 LONG i4;
772 IUnknown *punk;
774 /* Crashes: Native does not test input for NULL, so neither does Wine */
775 if (0)
776 VariantClear(NULL);
778 /* Only the type field is set, to VT_EMPTY */
779 V_VT(&v) = VT_UI4;
780 V_UI4(&v) = ~0u;
781 hres = VariantClear(&v);
782 ok((hres == S_OK && V_VT(&v) == VT_EMPTY),
783 "VariantClear: Type set to %d, res %08x\n", V_VT(&v), hres);
784 ok(V_UI4(&v) == ~0u, "VariantClear: Overwrote value\n");
786 /* Test all possible V_VT values.
787 * Also demonstrates that null pointers in 'v' are not dereferenced.
788 * Individual variant tests should test VariantClear() with non-NULL values.
790 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
792 VARTYPE vt;
794 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
796 HRESULT hExpected = DISP_E_BADVARTYPE;
798 SKIPTESTS(vt);
800 memset(&v, 0, sizeof(v));
801 V_VT(&v) = vt | ExtraFlags[i];
803 hres = VariantClear(&v);
805 if (IsValidVariantClearVT(vt, ExtraFlags[i]))
806 hExpected = S_OK;
808 ok(hres == hExpected, "VariantClear: expected 0x%X, got 0x%X for vt %d | 0x%X\n",
809 hExpected, hres, vt, ExtraFlags[i]);
813 /* Some BYREF tests with non-NULL ptrs */
815 /* VARIANT BYREF */
816 V_VT(&v2) = VT_I4;
817 V_I4(&v2) = 0x1234;
818 V_VT(&v) = VT_VARIANT | VT_BYREF;
819 V_VARIANTREF(&v) = &v2;
821 hres = VariantClear(&v);
822 ok(hres == S_OK, "ret %08x\n", hres);
823 ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
824 ok(V_VARIANTREF(&v) == &v2, "variant ref %p\n", V_VARIANTREF(&v2));
825 ok(V_VT(&v2) == VT_I4, "vt %04x\n", V_VT(&v2));
826 ok(V_I4(&v2) == 0x1234, "i4 %04x\n", V_I4(&v2));
828 /* I4 BYREF */
829 i4 = 0x4321;
830 V_VT(&v) = VT_I4 | VT_BYREF;
831 V_I4REF(&v) = &i4;
833 hres = VariantClear(&v);
834 ok(hres == S_OK, "ret %08x\n", hres);
835 ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
836 ok(V_I4REF(&v) == &i4, "i4 ref %p\n", V_I4REF(&v2));
837 ok(i4 == 0x4321, "i4 changed %08x\n", i4);
840 /* UNKNOWN */
841 V_VT(&v) = VT_UNKNOWN;
842 V_UNKNOWN(&v) = &test_myVariantClearImpl.IUnknown_iface;
843 test_myVariantClearImpl.events = 0;
844 hres = VariantClear(&v);
845 ok(hres == S_OK, "ret %08x\n", hres);
846 ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
847 ok(V_UNKNOWN(&v) == &test_myVariantClearImpl.IUnknown_iface, "unknown %p\n", V_UNKNOWN(&v));
848 /* Check that Release got called, but nothing else */
849 ok(test_myVariantClearImpl.events == 0x4, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
851 /* UNKNOWN BYREF */
852 punk = &test_myVariantClearImpl.IUnknown_iface;
853 V_VT(&v) = VT_UNKNOWN | VT_BYREF;
854 V_UNKNOWNREF(&v) = &punk;
855 test_myVariantClearImpl.events = 0;
856 hres = VariantClear(&v);
857 ok(hres == S_OK, "ret %08x\n", hres);
858 ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
859 ok(V_UNKNOWNREF(&v) == &punk, "unknown ref %p\n", V_UNKNOWNREF(&v));
860 /* Check that nothing got called */
861 ok(test_myVariantClearImpl.events == 0, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
863 /* DISPATCH */
864 V_VT(&v) = VT_DISPATCH;
865 V_DISPATCH(&v) = (IDispatch*)&test_myVariantClearImpl.IUnknown_iface;
866 test_myVariantClearImpl.events = 0;
867 hres = VariantClear(&v);
868 ok(hres == S_OK, "ret %08x\n", hres);
869 ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
870 ok(V_DISPATCH(&v) == (IDispatch*)&test_myVariantClearImpl.IUnknown_iface,
871 "dispatch %p\n", V_DISPATCH(&v));
872 /* Check that Release got called, but nothing else */
873 ok(test_myVariantClearImpl.events == 0x4, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
875 /* DISPATCH BYREF */
876 punk = &test_myVariantClearImpl.IUnknown_iface;
877 V_VT(&v) = VT_DISPATCH | VT_BYREF;
878 V_DISPATCHREF(&v) = (IDispatch**)&punk;
879 test_myVariantClearImpl.events = 0;
880 hres = VariantClear(&v);
881 ok(hres == S_OK, "ret %08x\n", hres);
882 ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
883 ok(V_DISPATCHREF(&v) == (IDispatch**)&punk, "dispatch ref %p\n", V_DISPATCHREF(&v));
884 /* Check that nothing got called */
885 ok(test_myVariantClearImpl.events == 0, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
887 /* RECORD */
888 recinfo = get_test_recordinfo();
889 V_VT(&v) = VT_RECORD;
890 rec = &V_UNION(&v, brecVal);
891 rec->pRecInfo = &recinfo->IRecordInfo_iface;
892 rec->pvRecord = (void*)0xdeadbeef;
893 recinfo->recordclear = 0;
894 recinfo->ref = 2;
895 recinfo->rec = rec;
896 hres = VariantClear(&v);
897 ok(hres == S_OK, "ret %08x\n", hres);
898 ok(rec->pvRecord == NULL, "got %p\n", rec->pvRecord);
899 ok(recinfo->recordclear == 1, "got %d\n", recinfo->recordclear);
900 ok(recinfo->ref == 1, "got %d\n", recinfo->ref);
901 IRecordInfo_Release(&recinfo->IRecordInfo_iface);
904 static void test_VariantCopy(void)
906 struct __tagBRECORD *rec;
907 IRecordInfoImpl *recinfo;
908 VARIANTARG vSrc, vDst;
909 VARTYPE vt;
910 size_t i;
911 HRESULT hres, hExpected;
913 /* Establish that the failure/other cases are dealt with. Individual tests
914 * for each type should verify that data is copied correctly, references
915 * are updated, etc.
918 /* vSrc == vDst */
919 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
921 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
923 SKIPTESTS(vt);
925 memset(&vSrc, 0, sizeof(vSrc));
926 V_VT(&vSrc) = vt | ExtraFlags[i];
928 hExpected = DISP_E_BADVARTYPE;
929 /* src is allowed to be a VT_CLSID */
930 if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
931 hExpected = S_OK;
933 hres = VariantCopy(&vSrc, &vSrc);
935 ok(hres == hExpected,
936 "Copy(src==dst): expected 0x%X, got 0x%X for src==dest vt %d|0x%X\n",
937 hExpected, hres, vt, ExtraFlags[i]);
941 /* Test that if VariantClear() fails on dest, the function fails. This also
942 * shows that dest is in fact cleared and not just overwritten
944 memset(&vSrc, 0, sizeof(vSrc));
945 V_VT(&vSrc) = VT_UI1;
947 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
949 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
951 SKIPTESTS(vt);
953 hExpected = DISP_E_BADVARTYPE;
955 memset(&vDst, 0, sizeof(vDst));
956 V_VT(&vDst) = vt | ExtraFlags[i];
958 if (IsValidVariantClearVT(vt, ExtraFlags[i]))
959 hExpected = S_OK;
961 hres = VariantCopy(&vDst, &vSrc);
963 ok(hres == hExpected,
964 "Copy(bad dst): expected 0x%X, got 0x%X for dest vt %d|0x%X\n",
965 hExpected, hres, vt, ExtraFlags[i]);
966 if (hres == S_OK)
967 ok(V_VT(&vDst) == VT_UI1,
968 "Copy(bad dst): expected vt = VT_UI1, got %d\n", V_VT(&vDst));
972 /* Test that VariantClear() checks vSrc for validity before copying */
973 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
975 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
977 SKIPTESTS(vt);
979 hExpected = DISP_E_BADVARTYPE;
981 memset(&vDst, 0, sizeof(vDst));
982 V_VT(&vDst) = VT_EMPTY;
984 memset(&vSrc, 0, sizeof(vSrc));
985 V_VT(&vSrc) = vt | ExtraFlags[i];
987 /* src is allowed to be a VT_CLSID */
988 if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
989 hExpected = S_OK;
991 hres = VariantCopy(&vDst, &vSrc);
993 ok(hres == hExpected,
994 "Copy(bad src): expected 0x%X, got 0x%X for src vt %d|0x%X\n",
995 hExpected, hres, vt, ExtraFlags[i]);
996 if (hres == S_OK)
998 ok(V_VT(&vDst) == (vt|ExtraFlags[i]),
999 "Copy(bad src): expected vt = %d, got %d\n",
1000 vt | ExtraFlags[i], V_VT(&vDst));
1001 VariantClear(&vDst);
1006 /* Test that copying a NULL BSTR results in an empty BSTR */
1007 memset(&vDst, 0, sizeof(vDst));
1008 V_VT(&vDst) = VT_EMPTY;
1009 memset(&vSrc, 0, sizeof(vSrc));
1010 V_VT(&vSrc) = VT_BSTR;
1011 hres = VariantCopy(&vDst, &vSrc);
1012 ok(hres == S_OK, "Copy(NULL BSTR): Failed to copy a NULL BSTR\n");
1013 if (hres == S_OK)
1015 ok((V_VT(&vDst) == VT_BSTR) && V_BSTR(&vDst),
1016 "Copy(NULL BSTR): should have non-NULL result\n");
1017 if ((V_VT(&vDst) == VT_BSTR) && V_BSTR(&vDst))
1019 ok(*V_BSTR(&vDst) == 0, "Copy(NULL BSTR): result not empty\n");
1021 VariantClear(&vDst);
1024 /* copy RECORD */
1025 recinfo = get_test_recordinfo();
1027 memset(&vDst, 0, sizeof(vDst));
1028 V_VT(&vDst) = VT_EMPTY;
1030 V_VT(&vSrc) = VT_RECORD;
1031 rec = &V_UNION(&vSrc, brecVal);
1032 rec->pRecInfo = &recinfo->IRecordInfo_iface;
1033 rec->pvRecord = (void*)0xdeadbeef;
1035 recinfo->recordclear = 0;
1036 recinfo->recordcopy = 0;
1037 recinfo->getsize = 0;
1038 recinfo->rec = rec;
1039 hres = VariantCopy(&vDst, &vSrc);
1040 ok(hres == S_OK, "ret %08x\n", hres);
1042 rec = &V_UNION(&vDst, brecVal);
1043 ok(rec->pvRecord != (void*)0xdeadbeef && rec->pvRecord != NULL, "got %p\n", rec->pvRecord);
1044 ok(rec->pRecInfo == &recinfo->IRecordInfo_iface, "got %p\n", rec->pRecInfo);
1045 ok(recinfo->getsize == 1, "got %d\n", recinfo->recordclear);
1046 ok(recinfo->recordcopy == 1, "got %d\n", recinfo->recordclear);
1048 VariantClear(&vDst);
1049 VariantClear(&vSrc);
1052 /* Determine if a vt is valid for VariantCopyInd() */
1053 static BOOL IsValidVariantCopyIndVT(VARTYPE vt, VARTYPE extraFlags)
1055 BOOL ret = FALSE;
1057 if ((extraFlags & VT_ARRAY) ||
1058 (vt > VT_NULL && vt != (VARTYPE)15 && vt < VT_VOID &&
1059 !(extraFlags & (VT_VECTOR|VT_RESERVED))))
1061 ret = TRUE; /* ok */
1063 return ret;
1066 static void test_VariantCopyInd(void)
1068 VARIANTARG vSrc, vDst, vRef, vRef2;
1069 VARTYPE vt;
1070 size_t i;
1071 BYTE buffer[64];
1072 HRESULT hres, hExpected;
1074 memset(buffer, 0, sizeof(buffer));
1076 /* vSrc == vDst */
1077 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
1079 if (ExtraFlags[i] & VT_ARRAY)
1080 continue; /* Native crashes on NULL safearray */
1082 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
1084 SKIPTESTS(vt);
1086 memset(&vSrc, 0, sizeof(vSrc));
1087 V_VT(&vSrc) = vt | ExtraFlags[i];
1089 hExpected = DISP_E_BADVARTYPE;
1090 if (!(ExtraFlags[i] & VT_BYREF))
1092 /* if src is not by-reference, acts as VariantCopy() */
1093 if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
1094 hExpected = S_OK;
1096 else
1098 if (vt == VT_SAFEARRAY || vt == VT_BSTR || vt == VT_UNKNOWN ||
1099 vt == VT_DISPATCH || vt == VT_RECORD)
1100 continue; /* Need valid ptrs for deep copies */
1102 V_BYREF(&vSrc) = &buffer;
1103 hExpected = E_INVALIDARG;
1105 if ((vt == VT_I8 || vt == VT_UI8) &&
1106 ExtraFlags[i] == VT_BYREF)
1108 if (has_i8)
1109 hExpected = S_OK; /* Only valid if I8 is a known type */
1111 else if (IsValidVariantCopyIndVT(vt, ExtraFlags[i]))
1112 hExpected = S_OK;
1115 hres = VariantCopyInd(&vSrc, &vSrc);
1117 ok(hres == hExpected,
1118 "CopyInd(src==dst): expected 0x%X, got 0x%X for src==dst vt %d|0x%X\n",
1119 hExpected, hres, vt, ExtraFlags[i]);
1123 /* Bad dest */
1124 memset(&vSrc, 0, sizeof(vSrc));
1125 V_VT(&vSrc) = VT_UI1|VT_BYREF;
1126 V_BYREF(&vSrc) = &buffer;
1128 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
1130 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
1132 SKIPTESTS(vt);
1134 memset(&vDst, 0, sizeof(vDst));
1135 V_VT(&vDst) = vt | ExtraFlags[i];
1137 hExpected = DISP_E_BADVARTYPE;
1139 if (IsValidVariantClearVT(vt, ExtraFlags[i]))
1140 hExpected = S_OK;
1142 hres = VariantCopyInd(&vDst, &vSrc);
1144 ok(hres == hExpected,
1145 "CopyInd(bad dst): expected 0x%X, got 0x%X for dst vt %d|0x%X\n",
1146 hExpected, hres, vt, ExtraFlags[i]);
1147 if (hres == S_OK)
1148 ok(V_VT(&vDst) == VT_UI1,
1149 "CopyInd(bad dst): expected vt = VT_UI1, got %d\n", V_VT(&vDst));
1153 /* bad src */
1154 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
1156 if (ExtraFlags[i] & VT_ARRAY)
1157 continue; /* Native crashes on NULL safearray */
1159 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
1161 SKIPTESTS(vt);
1163 memset(&vDst, 0, sizeof(vDst));
1164 V_VT(&vDst) = VT_EMPTY;
1166 memset(&vSrc, 0, sizeof(vSrc));
1167 V_VT(&vSrc) = vt | ExtraFlags[i];
1169 hExpected = DISP_E_BADVARTYPE;
1170 if (!(ExtraFlags[i] & VT_BYREF))
1172 /* if src is not by-reference, acts as VariantCopy() */
1173 if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
1174 hExpected = S_OK;
1176 else
1178 if (vt == VT_SAFEARRAY || vt == VT_BSTR || vt == VT_UNKNOWN ||
1179 vt == VT_DISPATCH || vt == VT_RECORD)
1180 continue; /* Need valid ptrs for deep copies, see vartype.c */
1182 V_BYREF(&vSrc) = &buffer;
1184 hExpected = E_INVALIDARG;
1186 if ((vt == VT_I8 || vt == VT_UI8) &&
1187 ExtraFlags[i] == VT_BYREF)
1189 if (has_i8)
1190 hExpected = S_OK; /* Only valid if I8 is a known type */
1192 else if (IsValidVariantCopyIndVT(vt, ExtraFlags[i]))
1193 hExpected = S_OK;
1196 hres = VariantCopyInd(&vDst, &vSrc);
1198 ok(hres == hExpected,
1199 "CopyInd(bad src): expected 0x%X, got 0x%X for src vt %d|0x%X\n",
1200 hExpected, hres, vt, ExtraFlags[i]);
1201 if (hres == S_OK)
1203 if (vt == VT_VARIANT && ExtraFlags[i] == VT_BYREF)
1205 /* Type of vDst should be the type of the referenced variant.
1206 * Since we set the buffer to all zeros, its type should be
1207 * VT_EMPTY.
1209 ok(V_VT(&vDst) == VT_EMPTY,
1210 "CopyInd(bad src): expected dst vt = VT_EMPTY, got %d|0x%X\n",
1211 V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK);
1213 else
1215 ok(V_VT(&vDst) == (vt|(ExtraFlags[i] & ~VT_BYREF)),
1216 "CopyInd(bad src): expected dst vt = %d|0x%X, got %d|0x%X\n",
1217 vt, ExtraFlags[i] & ~VT_BYREF,
1218 V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK);
1220 VariantClear(&vDst);
1225 /* By-reference variants are dereferenced */
1226 V_VT(&vRef) = VT_UI1;
1227 V_UI1(&vRef) = 0x77;
1228 V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
1229 V_VARIANTREF(&vSrc) = &vRef;
1230 VariantInit(&vDst);
1232 hres = VariantCopyInd(&vDst, &vSrc);
1233 ok(hres == S_OK, "VariantCopyInd failed: 0x%08x\n", hres);
1234 ok(V_VT(&vDst) == VT_UI1 && V_UI1(&vDst) == 0x77,
1235 "CopyInd(deref): expected dst vt = VT_UI1, val 0x77, got %d|0x%X, 0x%2X\n",
1236 V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK, V_UI1(&vDst));
1238 /* By-reference variant to a by-reference type succeeds */
1239 V_VT(&vRef) = VT_UI1|VT_BYREF;
1240 V_UI1REF(&vRef) = buffer; buffer[0] = 0x88;
1241 V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
1242 V_VARIANTREF(&vSrc) = &vRef;
1243 VariantInit(&vDst);
1245 hres = VariantCopyInd(&vDst, &vSrc);
1246 ok(hres == S_OK, "VariantCopyInd failed: 0x%08x\n", hres);
1247 ok(V_VT(&vDst) == VT_UI1 && V_UI1(&vDst) == 0x88,
1248 "CopyInd(deref): expected dst vt = VT_UI1, val 0x77, got %d|0x%X, 0x%2X\n",
1249 V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK, V_UI1(&vDst));
1251 /* But a by-reference variant to a by-reference variant fails */
1252 V_VT(&vRef2) = VT_UI1;
1253 V_UI1(&vRef2) = 0x77;
1254 V_VT(&vRef) = VT_VARIANT|VT_BYREF;
1255 V_VARIANTREF(&vRef) = &vRef2;
1256 V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
1257 V_VARIANTREF(&vSrc) = &vRef;
1258 VariantInit(&vDst);
1260 hres = VariantCopyInd(&vDst, &vSrc);
1261 ok(hres == E_INVALIDARG,
1262 "CopyInd(ref->ref): expected E_INVALIDARG, got 0x%08x\n", hres);
1265 static HRESULT (WINAPI *pVarParseNumFromStr)(const OLECHAR*,LCID,ULONG,NUMPARSE*,BYTE*);
1267 /* Macros for converting and testing the result of VarParseNumFromStr */
1268 #define FAILDIG 255
1270 static HRESULT wconvert_str( const OLECHAR *str, INT dig, ULONG npflags,
1271 NUMPARSE *np, BYTE rgb[128], LCID lcid, ULONG flags)
1273 memset( rgb, FAILDIG, 128 );
1274 memset( np, 255, sizeof(*np) );
1275 np->cDig = dig;
1276 np->dwInFlags = npflags;
1277 return pVarParseNumFromStr( str, lcid, flags, np, rgb);
1280 static HRESULT convert_str( const char *str, INT dig, ULONG flags,
1281 NUMPARSE *np, BYTE rgb[128], LCID lcid )
1283 OLECHAR buff[128];
1284 MultiByteToWideChar( CP_ACP,0, str, -1, buff, ARRAY_SIZE( buff ));
1285 return wconvert_str(buff, dig, flags, np, rgb, lcid, LOCALE_NOUSEROVERRIDE);
1288 static void expect_NumFromStr( int line, HRESULT hres, NUMPARSE *np, INT a, ULONG b, ULONG c,
1289 INT d, INT e, INT f )
1291 ok_(__FILE__,line)(hres == S_OK, "returned %08x\n", hres);
1292 if (hres == S_OK)
1294 ok_(__FILE__,line)(np->cDig == a, "Expected cDig = %d, got %d\n", a, np->cDig);
1295 ok_(__FILE__,line)(np->dwInFlags == b, "Expected dwInFlags = 0x%x, got 0x%x\n", b, np->dwInFlags);
1296 ok_(__FILE__,line)(np->dwOutFlags == c, "Expected dwOutFlags = 0x%x, got 0x%x\n", c, np->dwOutFlags);
1297 ok_(__FILE__,line)(np->cchUsed == d, "Expected cchUsed = %d, got %d\n", d, np->cchUsed);
1298 ok_(__FILE__,line)(np->nBaseShift == e, "Expected nBaseShift = %d, got %d\n", e, np->nBaseShift);
1299 ok_(__FILE__,line)(np->nPwr10 == f, "Expected nPwr10 = %d, got %d\n", f, np->nPwr10);
1303 #define WCONVERTN(str,dig,flags) hres = wconvert_str( str, dig, flags, &np, rgb, lcid, LOCALE_NOUSEROVERRIDE )
1304 #define WCONVERT(str,flags) WCONVERTN(str,sizeof(rgb),flags)
1305 #define CONVERTN(str,dig,flags) hres = convert_str( str, dig, flags, &np, rgb, lcid )
1306 #define CONVERT(str,flags) CONVERTN(str,sizeof(rgb),flags)
1307 #define EXPECT(a,b,c,d,e,f) expect_NumFromStr( __LINE__, hres, &np, a, b, c, d, e, f )
1308 #define EXPECTRGB(a,b) ok(rgb[a] == b, "Digit[%d], expected %d, got %d\n", a, b, rgb[a])
1309 #define EXPECTFAIL ok(hres == DISP_E_TYPEMISMATCH, "Call succeeded, hres = %08x\n", hres)
1310 #define EXPECT2(a,b) EXPECTRGB(0,a); EXPECTRGB(1,b)
1312 static void test_VarParseNumFromStrEn(void)
1314 HRESULT hres;
1315 /* Ensure all tests are using the same locale characters for '$', ',' etc */
1316 LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
1317 NUMPARSE np;
1318 BYTE rgb[128];
1319 OLECHAR wstr[128];
1320 OLECHAR spaces[] = L" \xa0\f\n\r\t\v"; /* man isspace() */
1321 int i;
1323 /** No flags **/
1325 CHECKPTR(VarParseNumFromStr);
1327 /* Consume an empty string */
1328 CONVERT("", 0);
1329 EXPECTFAIL;
1331 /* Consume a single digit */
1332 CONVERT("7", 0);
1333 EXPECT(1,0,0,1,0,0);
1334 EXPECT2(7,FAILDIG);
1336 /* cDig is not literal digits - zeros are suppressed and nPwr10 is increased */
1337 CONVERT("10", 0);
1338 EXPECT(1,0,0,2,0,1);
1339 /* Note: Win32 writes the trailing zeros if they are within cDig's limits,
1340 * but then excludes them from the returned cDig count.
1341 * In our implementation we don't bother writing them at all.
1343 EXPECTRGB(0, 1);
1345 /* if cDig is too small and numbers follow, sets INEXACT */
1346 CONVERTN("11",1, 0);
1347 EXPECT(1,0,NUMPRS_INEXACT,2,0,1);
1348 EXPECT2(1,FAILDIG);
1350 /* Strips leading zeros */
1351 CONVERT("01", 0);
1352 EXPECT(1,0,0,2,0,0);
1353 EXPECT2(1,FAILDIG);
1355 /* Strips leading zeros */
1356 CONVERTN("01",1, 0);
1357 EXPECT(1,0,0,2,0,0);
1358 EXPECT2(1,FAILDIG);
1361 /* Fails on non digits */
1362 CONVERT("a", 0);
1363 EXPECTFAIL;
1364 EXPECTRGB(0,FAILDIG);
1366 /** NUMPRS_LEADING_WHITE/NUMPRS_TRAILING_WHITE **/
1368 /* Without flag, fails on whitespace */
1369 CONVERT(" 0", 0);
1370 EXPECTFAIL;
1371 EXPECTRGB(0,FAILDIG);
1374 /* With flag, consumes any type of space */
1375 for (i = 0; i < ARRAY_SIZE(spaces)-1; i++)
1377 winetest_push_context("%d", i);
1379 wsprintfW(wstr, L"%c0", spaces[i]);
1380 WCONVERT(wstr, NUMPRS_LEADING_WHITE);
1381 EXPECT(1,NUMPRS_LEADING_WHITE,NUMPRS_LEADING_WHITE,2,0,0);
1382 EXPECT2(0,FAILDIG);
1384 winetest_pop_context();
1387 /* Doesn't pick up trailing whitespace without flag */
1388 CONVERT("0 ", 0);
1389 EXPECT(1,0,0,1,0,0);
1390 EXPECT2(0,FAILDIG);
1392 /* With flag, consumes trailing whitespace */
1393 CONVERT("0 ", NUMPRS_TRAILING_WHITE);
1394 EXPECT(1,NUMPRS_TRAILING_WHITE,NUMPRS_TRAILING_WHITE,2,0,0);
1395 EXPECT2(0,FAILDIG);
1397 /* Leading flag only consumes leading */
1398 CONVERT(" 0 ", NUMPRS_LEADING_WHITE);
1399 EXPECT(1,NUMPRS_LEADING_WHITE,NUMPRS_LEADING_WHITE,2,0,0);
1400 EXPECT2(0,FAILDIG);
1402 /* Both flags consumes both */
1403 CONVERT(" 0 ", NUMPRS_LEADING_WHITE|NUMPRS_TRAILING_WHITE);
1404 EXPECT(1,NUMPRS_LEADING_WHITE|NUMPRS_TRAILING_WHITE,NUMPRS_LEADING_WHITE|NUMPRS_TRAILING_WHITE,3,0,0);
1405 EXPECT2(0,FAILDIG);
1407 /** NUMPRS_LEADING_PLUS/NUMPRS_TRAILING_PLUS **/
1409 /* Without flag, fails on + */
1410 CONVERT("+0", 0);
1411 EXPECTFAIL;
1412 EXPECTRGB(0,FAILDIG);
1414 /* With flag, consumes + */
1415 CONVERT("+0", NUMPRS_LEADING_PLUS);
1416 EXPECT(1,NUMPRS_LEADING_PLUS,NUMPRS_LEADING_PLUS,2,0,0);
1417 EXPECT2(0,FAILDIG);
1419 /* Without flag, doesn't consume trailing + */
1420 CONVERT("0+", 0);
1421 EXPECT(1,0,0,1,0,0);
1422 EXPECT2(0,FAILDIG);
1424 /* With flag, consumes trailing + */
1425 CONVERT("0+", NUMPRS_TRAILING_PLUS);
1426 EXPECT(1,NUMPRS_TRAILING_PLUS,NUMPRS_TRAILING_PLUS,2,0,0);
1427 EXPECT2(0,FAILDIG);
1429 /* With leading flag, doesn't consume trailing + */
1430 CONVERT("+0+", NUMPRS_LEADING_PLUS);
1431 EXPECT(1,NUMPRS_LEADING_PLUS,NUMPRS_LEADING_PLUS,2,0,0);
1432 EXPECT2(0,FAILDIG);
1434 /* Trailing + doesn't get consumed if we specify both (unlike whitespace) */
1435 CONVERT("+0+", NUMPRS_LEADING_PLUS|NUMPRS_TRAILING_PLUS);
1436 EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_TRAILING_PLUS,NUMPRS_LEADING_PLUS,2,0,0);
1437 EXPECT2(0,FAILDIG);
1439 /** NUMPRS_LEADING_MINUS/NUMPRS_TRAILING_MINUS **/
1441 /* Without flag, fails on - */
1442 CONVERT("-0", 0);
1443 EXPECTFAIL;
1444 EXPECTRGB(0,FAILDIG);
1446 /* With flag, consumes - */
1447 CONVERT("-0", NUMPRS_LEADING_MINUS);
1448 EXPECT(1,NUMPRS_LEADING_MINUS,NUMPRS_NEG|NUMPRS_LEADING_MINUS,2,0,0);
1449 EXPECT2(0,FAILDIG);
1451 /* Without flag, doesn't consume trailing - */
1452 CONVERT("0-", 0);
1453 EXPECT(1,0,0,1,0,0);
1454 EXPECT2(0,FAILDIG);
1456 /* With flag, consumes trailing - */
1457 CONVERT("0-", NUMPRS_TRAILING_MINUS);
1458 EXPECT(1,NUMPRS_TRAILING_MINUS,NUMPRS_NEG|NUMPRS_TRAILING_MINUS,2,0,0);
1459 EXPECT2(0,FAILDIG);
1461 /* With leading flag, doesn't consume trailing - */
1462 CONVERT("-0-", NUMPRS_LEADING_MINUS);
1463 EXPECT(1,NUMPRS_LEADING_MINUS,NUMPRS_NEG|NUMPRS_LEADING_MINUS,2,0,0);
1464 EXPECT2(0,FAILDIG);
1466 /* Trailing - doesn't get consumed if we specify both (unlike whitespace) */
1467 CONVERT("-0-", NUMPRS_LEADING_MINUS|NUMPRS_TRAILING_MINUS);
1468 EXPECT(1,NUMPRS_LEADING_MINUS|NUMPRS_TRAILING_MINUS,NUMPRS_NEG|NUMPRS_LEADING_MINUS,2,0,0);
1469 EXPECT2(0,FAILDIG);
1471 /** NUMPRS_HEX_OCT **/
1473 /* Could be hex, octal or decimal - With flag reads as decimal */
1474 CONVERT("0", NUMPRS_HEX_OCT);
1475 EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
1476 EXPECT2(0,FAILDIG);
1478 /* Doesn't recognise hex in .asm syntax */
1479 CONVERT("0h", NUMPRS_HEX_OCT);
1480 EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
1481 EXPECT2(0,FAILDIG);
1483 /* Doesn't fail with valid leading string but no digits */
1484 CONVERT("0x", NUMPRS_HEX_OCT);
1485 EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
1486 EXPECT2(0,FAILDIG);
1488 /* Doesn't recognise hex format numbers at all! */
1489 CONVERT("0x0", NUMPRS_HEX_OCT);
1490 EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
1491 EXPECT2(0,FAILDIG);
1493 /* Doesn't recognise plain hex digits either */
1494 CONVERT("FE", NUMPRS_HEX_OCT);
1495 EXPECTFAIL;
1496 EXPECTRGB(0,FAILDIG);
1498 /* A leading 0 does not an octal number make */
1499 CONVERT("0100", NUMPRS_HEX_OCT);
1500 EXPECT(1,NUMPRS_HEX_OCT,0,4,0,2);
1501 EXPECTRGB(0,1);
1502 EXPECTRGB(1,0);
1503 EXPECTRGB(2,0);
1504 EXPECTRGB(3,FAILDIG);
1506 /* VB hex */
1507 CONVERT("&HF800", NUMPRS_HEX_OCT);
1508 EXPECT(4,NUMPRS_HEX_OCT,NUMPRS_HEX_OCT,6,4,0);
1509 EXPECTRGB(0,15);
1510 EXPECTRGB(1,8);
1511 EXPECTRGB(2,0);
1512 EXPECTRGB(3,0);
1513 EXPECTRGB(4,FAILDIG);
1515 /* VB hex lower case and leading zero */
1516 CONVERT("&h0abcdef", NUMPRS_HEX_OCT);
1517 EXPECT(6,NUMPRS_HEX_OCT,NUMPRS_HEX_OCT,9,4,0);
1518 EXPECTRGB(0,10);
1519 EXPECTRGB(1,11);
1520 EXPECTRGB(2,12);
1521 EXPECTRGB(3,13);
1522 EXPECTRGB(4,14);
1523 EXPECTRGB(5,15);
1524 EXPECTRGB(6,FAILDIG);
1526 /* VB oct */
1527 CONVERT("&O300", NUMPRS_HEX_OCT);
1528 EXPECT(3,NUMPRS_HEX_OCT,NUMPRS_HEX_OCT,5,3,0);
1529 EXPECTRGB(0,3);
1530 EXPECTRGB(1,0);
1531 EXPECTRGB(2,0);
1532 EXPECTRGB(3,FAILDIG);
1534 /* VB oct lower case and leading zero */
1535 CONVERT("&o0777", NUMPRS_HEX_OCT);
1536 EXPECT(3,NUMPRS_HEX_OCT,NUMPRS_HEX_OCT,6,3,0);
1537 EXPECTRGB(0,7);
1538 EXPECTRGB(1,7);
1539 EXPECTRGB(2,7);
1540 EXPECTRGB(3,FAILDIG);
1542 /* VB oct char bigger than 7 */
1543 CONVERT("&o128", NUMPRS_HEX_OCT);
1544 EXPECT(2,NUMPRS_HEX_OCT,NUMPRS_HEX_OCT,4,3,0);
1545 EXPECTRGB(0,1);
1546 EXPECTRGB(1,2);
1547 EXPECTRGB(3,FAILDIG);
1549 /* Only integers are allowed when using an alternative radix */
1550 CONVERT("&ha.2", NUMPRS_HEX_OCT|NUMPRS_DECIMAL);
1551 EXPECT(1,NUMPRS_HEX_OCT|NUMPRS_DECIMAL,NUMPRS_HEX_OCT,3,4,0);
1552 EXPECT2(10,FAILDIG);
1554 /* Except if it looks like a plain decimal number */
1555 CONVERT("01.2", NUMPRS_HEX_OCT|NUMPRS_DECIMAL);
1556 EXPECT(2,NUMPRS_HEX_OCT|NUMPRS_DECIMAL,NUMPRS_DECIMAL,4,0,-1);
1557 EXPECT2(1,2);
1558 EXPECTRGB(3,FAILDIG);
1560 /** NUMPRS_PARENS **/
1562 /* Empty parens = error */
1563 CONVERT("()", NUMPRS_PARENS);
1564 EXPECTFAIL;
1565 EXPECTRGB(0,FAILDIG);
1567 /* With flag, trailing parens not consumed */
1568 CONVERT("0()", NUMPRS_PARENS);
1569 EXPECT(1,NUMPRS_PARENS,0,1,0,0);
1570 EXPECT2(0,FAILDIG);
1572 /* With flag, Number in parens made negative and parens consumed */
1573 CONVERT("(0)", NUMPRS_PARENS);
1574 EXPECT(1,NUMPRS_PARENS,NUMPRS_NEG|NUMPRS_PARENS,3,0,0);
1575 EXPECT2(0,FAILDIG);
1577 /** NUMPRS_THOUSANDS **/
1579 /* With flag, thousands sep. not needed */
1580 CONVERT("0", NUMPRS_THOUSANDS);
1581 EXPECT(1,NUMPRS_THOUSANDS,0,1,0,0);
1582 EXPECT2(0,FAILDIG);
1584 /* Without flag stop at thousands separator */
1585 CONVERT("1,000", 0);
1586 EXPECT(1,0,0,1,0,0);
1587 EXPECT2(1,FAILDIG);
1589 /* With flag, thousands sep. and following digits consumed */
1590 CONVERT("1,000", NUMPRS_THOUSANDS);
1591 EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,3);
1592 EXPECTRGB(0,1);
1593 /* VarParseNumFromStr() may have added more digits to rgb but they are not
1594 * part of the returned value. So consider that an implementation detail.
1596 EXPECTRGB(4,FAILDIG);
1598 /* With flag, thousands sep. and following digits consumed */
1599 CONVERT("&h1,000", NUMPRS_HEX_OCT|NUMPRS_THOUSANDS);
1600 EXPECT(1,NUMPRS_HEX_OCT|NUMPRS_THOUSANDS,NUMPRS_HEX_OCT,3,4,0);
1601 EXPECTRGB(1,FAILDIG);
1603 /* With flag and decimal point, thousands sep. but not decimals consumed */
1604 CONVERT("1,001.0", NUMPRS_THOUSANDS);
1605 EXPECT(4,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,0);
1606 EXPECT2(1,0);
1607 EXPECTRGB(2,0);
1608 EXPECTRGB(3,1);
1609 EXPECTRGB(4,FAILDIG);
1611 /* With flag, consecutive thousands separators are allowed */
1612 CONVERT("1,,000", NUMPRS_THOUSANDS);
1613 EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,6,0,3);
1614 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
1615 EXPECTRGB(4,FAILDIG);
1617 /* With flag, thousands separators can be sprinkled at random */
1618 CONVERT("1,00,0,,", NUMPRS_THOUSANDS);
1619 EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,8,0,3);
1620 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
1621 EXPECTRGB(4,FAILDIG);
1623 /* With flag, but leading thousands separators are not allowed */
1624 CONVERT(",1,000", NUMPRS_THOUSANDS);
1625 EXPECTFAIL;
1627 /* With flag, thousands separator not needed but still reported */
1628 CONVERT("1,", NUMPRS_THOUSANDS);
1629 EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,2,0,0);
1630 EXPECT2(1,FAILDIG);
1632 /** NUMPRS_CURRENCY **/
1634 /* Without flag, chokes on currency sign */
1635 CONVERT("$11", 0);
1636 EXPECTFAIL;
1637 EXPECTRGB(0,FAILDIG);
1639 /* With flag, allows having no currency sign */
1640 CONVERT("11", NUMPRS_CURRENCY);
1641 EXPECT(2,NUMPRS_CURRENCY,0,2,0,0);
1642 EXPECT2(1,1);
1643 EXPECTRGB(2,FAILDIG);
1645 /* With flag, does not allow a lone currency sign */
1646 CONVERT("$", NUMPRS_CURRENCY);
1647 EXPECTFAIL;
1649 /* With flag, consumes currency sign */
1650 CONVERT("$11", NUMPRS_CURRENCY);
1651 EXPECT(2,NUMPRS_CURRENCY,NUMPRS_CURRENCY,3,0,0);
1652 EXPECT2(1,1);
1653 EXPECTRGB(2,FAILDIG);
1655 /* With flag, currency amounts cannot be in hexadecimal */
1656 CONVERT("$&ha", NUMPRS_HEX_OCT|NUMPRS_CURRENCY);
1657 todo_wine EXPECTFAIL;
1659 CONVERT("&ha$", NUMPRS_HEX_OCT|NUMPRS_CURRENCY);
1660 if (broken(1)) /* FIXME Reenable once Wine is less broken */
1661 EXPECT(1,NUMPRS_HEX_OCT|NUMPRS_CURRENCY,NUMPRS_HEX_OCT,3,4,0);
1662 todo_wine ok(np.dwOutFlags == NUMPRS_HEX_OCT, "Got dwOutFlags=%08x\n", np.dwOutFlags);
1663 EXPECTRGB(0,10);
1664 EXPECTRGB(1,FAILDIG);
1666 /* With flag, the sign cannot be repeated before the amount */
1667 CONVERT("$$11", NUMPRS_CURRENCY);
1668 EXPECTFAIL;
1670 /* With flag, but is allowed after the amount and can even be repeated! */
1671 CONVERT("$11$$", NUMPRS_CURRENCY|NUMPRS_USE_ALL);
1672 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_CURRENCY,5,0,0);
1673 EXPECT2(1,1);
1674 EXPECTRGB(2,FAILDIG);
1676 /* With flag, the British Pound is not allowed "1L" */
1677 WCONVERT(L"\x31\xa3", NUMPRS_CURRENCY|NUMPRS_USE_ALL);
1678 EXPECTFAIL;
1680 /* With flag, minus can go after the currency sign */
1681 CONVERT("$-11", NUMPRS_CURRENCY|NUMPRS_LEADING_MINUS);
1682 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_LEADING_MINUS,NUMPRS_CURRENCY|NUMPRS_LEADING_MINUS|NUMPRS_NEG,4,0,0);
1683 EXPECT2(1,1);
1684 EXPECTRGB(2,FAILDIG);
1686 /* With flag, or before */
1687 CONVERT("-$11", NUMPRS_CURRENCY|NUMPRS_LEADING_MINUS);
1688 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_LEADING_MINUS,NUMPRS_CURRENCY|NUMPRS_LEADING_MINUS|NUMPRS_NEG,4,0,0);
1689 EXPECT2(1,1);
1690 EXPECTRGB(2,FAILDIG);
1692 for (i = 0; i < ARRAY_SIZE(spaces)-1; i++)
1694 winetest_push_context("%d", i);
1696 /* With flag, no space is allowed after the currency sign */
1697 wsprintfW(wstr, L"$%c11", spaces[i]);
1698 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_USE_ALL);
1699 EXPECTFAIL;
1701 /* With flag, unless explicitly allowed before the digits */
1702 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_LEADING_WHITE);
1703 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_LEADING_WHITE,NUMPRS_CURRENCY|NUMPRS_LEADING_WHITE,4,0,0);
1704 EXPECT2(1,1);
1705 EXPECTRGB(2,FAILDIG);
1707 /* With flag, no space is allowed before the trailing currency sign */
1708 wsprintfW(wstr, L"11%c$", spaces[i]);
1709 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_USE_ALL);
1710 EXPECTFAIL;
1712 /* With flag, even with thousands flag (see the French situation) */
1713 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_USE_ALL);
1714 EXPECTFAIL;
1716 /* With flag, unless explicitly allowed */
1717 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_TRAILING_WHITE|NUMPRS_USE_ALL);
1718 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_TRAILING_WHITE|NUMPRS_USE_ALL,NUMPRS_CURRENCY|NUMPRS_TRAILING_WHITE,4,0,0);
1719 EXPECT2(1,1);
1720 EXPECTRGB(2,FAILDIG);
1722 winetest_pop_context();
1725 /* With flag only, doesn't consume decimal point */
1726 CONVERT("$11.1", NUMPRS_CURRENCY);
1727 EXPECT(2,NUMPRS_CURRENCY,NUMPRS_CURRENCY,3,0,0);
1728 EXPECT2(1,1);
1729 EXPECTRGB(2,FAILDIG);
1731 /* With flag and decimal flag, consumes decimal point and following digits */
1732 CONVERT("$11.1", NUMPRS_CURRENCY|NUMPRS_DECIMAL);
1733 EXPECT(3,NUMPRS_CURRENCY|NUMPRS_DECIMAL,NUMPRS_CURRENCY|NUMPRS_DECIMAL,5,0,-1);
1734 EXPECT2(1,1);
1735 EXPECTRGB(2,1);
1736 EXPECTRGB(3,FAILDIG);
1738 /* With flag, the currency cannot replace the decimal sign (see comment about
1739 * the Cape Verdean escudo).
1741 CONVERT("1$99", NUMPRS_CURRENCY|NUMPRS_DECIMAL);
1742 EXPECT(1,NUMPRS_CURRENCY|NUMPRS_DECIMAL,NUMPRS_CURRENCY,2,0,0);
1743 EXPECT2(1,FAILDIG);
1745 /* Thousands flag can also be used with currency */
1746 CONVERT("$1,234", NUMPRS_CURRENCY|NUMPRS_THOUSANDS);
1747 EXPECT(4,NUMPRS_CURRENCY|NUMPRS_THOUSANDS,NUMPRS_CURRENCY|NUMPRS_THOUSANDS,6,0,0);
1748 EXPECT2(1,2);
1749 EXPECTRGB(2,3);
1750 EXPECTRGB(3,4);
1751 EXPECTRGB(4,FAILDIG);
1753 /* Thousands flag can also be used with currency and decimal numbers */
1754 CONVERT("$1,234.5", NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_DECIMAL);
1755 EXPECT(5,NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_DECIMAL,NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_DECIMAL,8,0,-1);
1756 EXPECT2(1,2);
1757 EXPECTRGB(2,3);
1758 EXPECTRGB(3,4);
1759 EXPECTRGB(4,5);
1760 EXPECTRGB(5,FAILDIG);
1762 /** NUMPRS_DECIMAL **/
1764 /* With flag, consumes decimal point */
1765 CONVERT("1.1", NUMPRS_DECIMAL);
1766 EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL,3,0,-1);
1767 EXPECT2(1,1);
1768 EXPECTRGB(2,FAILDIG);
1770 /* With flag, consumes decimal point. Skipping the decimal part is not an error */
1771 CONVERT("1.", NUMPRS_DECIMAL);
1772 EXPECT(1,NUMPRS_DECIMAL,NUMPRS_DECIMAL,2,0,0);
1773 EXPECT2(1,FAILDIG);
1775 /* Consumes only one decimal point */
1776 CONVERT("1.1.", NUMPRS_DECIMAL);
1777 EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL,3,0,-1);
1778 EXPECT2(1,1);
1779 EXPECTRGB(2,FAILDIG);
1781 /* With flag, including if they are consecutive */
1782 CONVERT("1..1", NUMPRS_DECIMAL);
1783 EXPECT(1,NUMPRS_DECIMAL,NUMPRS_DECIMAL,2,0,0);
1784 EXPECT2(1,FAILDIG);
1786 /** NUMPRS_EXPONENT **/
1788 /* Without flag, doesn't consume exponent */
1789 CONVERT("1e1", 0);
1790 EXPECT(1,0,0,1,0,0);
1791 EXPECT2(1,FAILDIG);
1793 /* With flag, consumes exponent */
1794 CONVERT("1e1", NUMPRS_EXPONENT);
1795 EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,3,0,1);
1796 EXPECT2(1,FAILDIG);
1798 /* With flag, incompatible with NUMPRS_HEX_OCT */
1799 CONVERT("&o1e1", NUMPRS_HEX_OCT|NUMPRS_EXPONENT);
1800 if (broken(1)) /* FIXME Reenable once Wine is less broken */
1801 EXPECT(1,NUMPRS_HEX_OCT|NUMPRS_EXPONENT,NUMPRS_HEX_OCT,3,3,0);
1802 todo_wine ok(np.dwOutFlags == NUMPRS_HEX_OCT, "Got dwOutFlags=%08x\n", np.dwOutFlags);
1803 EXPECT2(1,FAILDIG);
1805 /* With flag, even if it sort of looks like an exponent */
1806 CONVERT("&h1e2", NUMPRS_HEX_OCT|NUMPRS_EXPONENT);
1807 EXPECT(3,NUMPRS_HEX_OCT|NUMPRS_EXPONENT,NUMPRS_HEX_OCT,5,4,0);
1808 EXPECT2(1,0xe);
1809 EXPECTRGB(2,2);
1810 EXPECTRGB(3,FAILDIG);
1812 /* Negative exponents are accepted without flags */
1813 CONVERT("1e-1", NUMPRS_EXPONENT);
1814 EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,4,0,-1);
1815 EXPECT2(1,FAILDIG);
1817 /* As are positive exponents and leading exponent 0s */
1818 CONVERT("1e+01", NUMPRS_EXPONENT);
1819 EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,5,0,1);
1820 EXPECT2(1,FAILDIG);
1822 /* The same for zero exponents */
1823 CONVERT("1e0", NUMPRS_EXPONENT);
1824 EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,3,0,0);
1825 EXPECT2(1,FAILDIG);
1827 /* Sign on a zero exponent doesn't matter */
1828 CONVERT("1e+0", NUMPRS_EXPONENT);
1829 EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,4,0,0);
1830 EXPECT2(1,FAILDIG);
1832 CONVERT("1e-0", NUMPRS_EXPONENT);
1833 EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,4,0,0);
1834 EXPECT2(1,FAILDIG);
1836 /* Doesn't consume a real number exponent */
1837 CONVERT("1e1.", NUMPRS_EXPONENT);
1838 EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,3,0,1);
1839 EXPECT2(1,FAILDIG);
1841 /* Powers of 10 are calculated from the position of any decimal point */
1842 CONVERT("1.5e20", NUMPRS_EXPONENT|NUMPRS_DECIMAL);
1843 EXPECT(2,NUMPRS_EXPONENT|NUMPRS_DECIMAL,NUMPRS_EXPONENT|NUMPRS_DECIMAL,6,0,19);
1844 EXPECT2(1,5);
1846 CONVERT("1.5e-20", NUMPRS_EXPONENT|NUMPRS_DECIMAL);
1847 EXPECT(2,NUMPRS_EXPONENT|NUMPRS_DECIMAL,NUMPRS_EXPONENT|NUMPRS_DECIMAL,7,0,-21);
1848 EXPECT2(1,5);
1850 /** NUMPRS_USE_ALL **/
1852 /* Flag expects all digits */
1853 CONVERT("0", NUMPRS_USE_ALL);
1854 EXPECT(1,NUMPRS_USE_ALL,0,1,0,0);
1855 EXPECT2(0,FAILDIG);
1857 /* Rejects anything trailing */
1858 CONVERT("0 ", NUMPRS_USE_ALL);
1859 EXPECTFAIL;
1860 EXPECT2(0,FAILDIG);
1862 /* Unless consumed by trailing flag */
1863 CONVERT("0 ", NUMPRS_USE_ALL|NUMPRS_TRAILING_WHITE);
1864 EXPECT(1,NUMPRS_USE_ALL|NUMPRS_TRAILING_WHITE,NUMPRS_TRAILING_WHITE,2,0,0);
1865 EXPECT2(0,FAILDIG);
1867 /** Combinations **/
1869 /* Leading whitespace and plus, doesn't consume trailing whitespace */
1870 CONVERT("+ 0 ", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
1871 EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,3,0,0);
1872 EXPECT2(0,FAILDIG);
1874 /* Order of whitespace and plus is unimportant */
1875 CONVERT(" +0", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
1876 EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,3,0,0);
1877 EXPECT2(0,FAILDIG);
1879 /* Leading whitespace can be repeated */
1880 CONVERT(" + 0", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
1881 EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,4,0,0);
1882 EXPECT2(0,FAILDIG);
1884 /* But plus/minus etc. cannot */
1885 CONVERT("+ +0", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
1886 EXPECTFAIL;
1887 EXPECTRGB(0,FAILDIG);
1889 /* Inexact is not set if trailing zeros are removed */
1890 CONVERTN("10", 1, 0);
1891 EXPECT(1,0,0,2,0,1);
1892 EXPECT2(1,FAILDIG);
1894 /* Make sure a leading 0 is stripped but decimals after it get read */
1895 CONVERT("-0.51", NUMPRS_STD);
1896 EXPECT(2,NUMPRS_STD,NUMPRS_NEG|NUMPRS_DECIMAL|NUMPRS_LEADING_MINUS,5,0,-2);
1897 EXPECT2(5,1);
1899 /* Keep trailing zeros on whole number part of a decimal */
1900 CONVERT("10.1", NUMPRS_STD);
1901 EXPECT(3,NUMPRS_STD,NUMPRS_DECIMAL,4,0,-1);
1902 EXPECT2(1,0);
1903 EXPECTRGB(2,1);
1905 /* Zeros after decimal sign */
1906 CONVERT("0.01", NUMPRS_STD);
1907 EXPECT(1,NUMPRS_STD,NUMPRS_DECIMAL,4,0,-2);
1908 EXPECT2(1,FAILDIG);
1910 /* Trailing zeros after decimal part */
1911 CONVERT("0.10", NUMPRS_STD);
1912 EXPECT(1,NUMPRS_STD,NUMPRS_DECIMAL,4,0,-1);
1913 EXPECT2(1,0);
1915 /* Arabic numerals are not allowed "0" */
1916 WCONVERT(L"\x660", NUMPRS_STD);
1917 EXPECTFAIL;
1920 static void test_VarParseNumFromStrFr(void)
1922 HRESULT hres;
1923 /* Test some aspects that are different in a non-English locale */
1924 LCID lcid = MAKELCID(MAKELANGID(LANG_FRENCH,SUBLANG_FRENCH),SORT_DEFAULT);
1925 NUMPARSE np;
1926 BYTE rgb[128];
1927 OLECHAR wstr[128];
1928 OLECHAR spaces[] = L" \xa0\f\n\r\t\v"; /* man isspace() */
1929 int i;
1931 CHECKPTR(VarParseNumFromStr);
1933 /** White spaces **/
1935 for (i = 0; i < ARRAY_SIZE(spaces)-1; i++)
1937 winetest_push_context("%d", i);
1939 /* Leading spaces must be explicitly allowed */
1940 wsprintfW(wstr, L"%c2", spaces[i]);
1941 WCONVERT(wstr, NUMPRS_USE_ALL);
1942 EXPECTFAIL;
1944 WCONVERT(wstr, NUMPRS_LEADING_WHITE|NUMPRS_USE_ALL);
1945 EXPECT(1,NUMPRS_LEADING_WHITE|NUMPRS_USE_ALL,NUMPRS_LEADING_WHITE,2,0,0);
1946 EXPECT2(2,FAILDIG);
1948 /* But trailing spaces... */
1949 wsprintfW(wstr, L"3%c", spaces[i]);
1950 WCONVERT(wstr, NUMPRS_TRAILING_WHITE|NUMPRS_USE_ALL);
1951 if (spaces[i] == ' ' || spaces[i] == 0xa0 /* non-breaking space */)
1953 /* Spaces aliased to the thousands separator are never allowed! */
1954 EXPECTFAIL;
1956 else
1958 /* The others behave normally */
1959 EXPECT(1,NUMPRS_TRAILING_WHITE|NUMPRS_USE_ALL,NUMPRS_TRAILING_WHITE,2,0,0);
1960 EXPECT2(3,FAILDIG);
1963 WCONVERT(wstr, NUMPRS_THOUSANDS|NUMPRS_USE_ALL);
1964 if (spaces[i] == ' ' || spaces[i] == 0xa0 /* non-breaking space */)
1966 /* Trailing thousands separators are allowed as usual */
1967 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,2,0,0);
1968 EXPECT2(3,FAILDIG);
1970 else
1972 /* But not other spaces */
1973 EXPECTFAIL;
1976 winetest_pop_context();
1980 /** NUMPRS_PARENS **/
1982 /* With flag, Number in parens made negative and parens consumed */
1983 CONVERT("(0)", NUMPRS_PARENS);
1984 EXPECT(1,NUMPRS_PARENS,NUMPRS_NEG|NUMPRS_PARENS,3,0,0);
1985 EXPECT2(0,FAILDIG);
1987 /** NUMPRS_THOUSANDS **/
1989 for (i = 0; i < ARRAY_SIZE(spaces)-1; i++)
1991 winetest_push_context("%d", i);
1993 /* With flag, thousands separator and following digits consumed */
1994 wsprintfW(wstr, L"1%c000", spaces[i]);
1995 WCONVERT(wstr, NUMPRS_THOUSANDS|NUMPRS_USE_ALL);
1996 if (spaces[i] == ' ' || spaces[i] == 0xa0 /* non-breaking space */)
1998 /* Non-breaking space and regular spaces work */
1999 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,5,0,3);
2000 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2001 EXPECTRGB(4,FAILDIG);
2003 else
2005 /* But not other spaces */
2006 EXPECTFAIL;
2009 winetest_pop_context();
2012 /* With flag and decimal point, thousands sep. but not decimals consumed */
2013 CONVERT("1 001,0", NUMPRS_THOUSANDS);
2014 EXPECT(4,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,0);
2015 EXPECT2(1,0);
2016 EXPECTRGB(2,0);
2017 EXPECTRGB(3,1);
2018 EXPECTRGB(4,FAILDIG);
2020 /* With flag, consecutive thousands separators are allowed */
2021 CONVERT("1 000", NUMPRS_THOUSANDS|NUMPRS_USE_ALL);
2022 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,6,0,3);
2023 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2024 EXPECTRGB(4,FAILDIG);
2026 /* With flag, thousands separators can be sprinkled at random */
2027 CONVERT("1 00 0 ", NUMPRS_THOUSANDS|NUMPRS_USE_ALL);
2028 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,8,0,3);
2029 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2030 EXPECTRGB(4,FAILDIG);
2032 /* With flag, but leading thousands separators are not allowed */
2033 CONVERT(" 1 000", NUMPRS_THOUSANDS);
2034 EXPECTFAIL;
2036 /* With flag, thousands separator not needed but still reported */
2037 CONVERT("1 ", NUMPRS_THOUSANDS|NUMPRS_USE_ALL);
2038 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,2,0,0);
2039 EXPECT2(1,FAILDIG);
2042 /** NUMPRS_CURRENCY **/
2044 /* With flag, consumes currency sign "E12" */
2045 WCONVERT(L"\x20ac\x31\x32", NUMPRS_CURRENCY);
2046 EXPECT(2,NUMPRS_CURRENCY,NUMPRS_CURRENCY,3,0,0);
2047 EXPECT2(1,2);
2048 EXPECTRGB(2,FAILDIG);
2050 /* With flag, consumes all currency signs! "E12EE" */
2051 WCONVERT(L"\x20ac\x31\x32\x20ac\x20ac", NUMPRS_CURRENCY|NUMPRS_USE_ALL);
2052 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_CURRENCY,5,0,0);
2053 EXPECT2(1,2);
2054 EXPECTRGB(2,FAILDIG);
2056 /* The presence of a trailing currency sign changes nothing for spaces */
2057 for (i = 0; i < ARRAY_SIZE(spaces)-1; i++)
2059 winetest_push_context("%d", i);
2061 /* With flag, no space is allowed before the currency sign "12 E" */
2062 wsprintfW(wstr, L"12%c\x20ac", spaces[i]);
2063 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_USE_ALL);
2064 EXPECTFAIL;
2066 /* With flag, even if explicitly allowed "12 E" */
2067 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_TRAILING_WHITE|NUMPRS_USE_ALL);
2068 if (spaces[i] == ' ' || spaces[i] == 0xa0 /* non-breaking space */)
2070 /* Spaces aliased to thousands separator are never allowed! */
2071 EXPECTFAIL;
2073 else
2075 /* The others behave normally */
2076 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_TRAILING_WHITE|NUMPRS_USE_ALL,NUMPRS_CURRENCY|NUMPRS_TRAILING_WHITE,4,0,0);
2077 EXPECT2(1,2);
2078 EXPECTRGB(2,FAILDIG);
2081 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_USE_ALL);
2082 if (spaces[i] == ' ' || spaces[i] == 0xa0 /* non-breaking space */)
2084 /* Spaces aliased to thousands separator are never allowed! */
2085 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_USE_ALL,NUMPRS_CURRENCY|NUMPRS_THOUSANDS,4,0,0);
2086 EXPECT2(1,2);
2087 EXPECTRGB(2,FAILDIG);
2089 else
2091 /* The others behave normally */
2092 EXPECTFAIL;
2095 winetest_pop_context();
2098 /* With flag only, doesn't consume decimal point */
2099 WCONVERT(L"12,1\x20ac", NUMPRS_CURRENCY);
2100 EXPECT(2,NUMPRS_CURRENCY,0,2,0,0);
2101 EXPECT2(1,2);
2102 EXPECTRGB(2,FAILDIG);
2104 /* With flag and decimal flag, consumes decimal point and following digits */
2105 WCONVERT(L"12,1\x20ac", NUMPRS_CURRENCY|NUMPRS_DECIMAL|NUMPRS_USE_ALL);
2106 EXPECT(3,NUMPRS_CURRENCY|NUMPRS_DECIMAL|NUMPRS_USE_ALL,NUMPRS_CURRENCY|NUMPRS_DECIMAL,5,0,-1);
2107 EXPECT2(1,2);
2108 EXPECTRGB(2,1);
2109 EXPECTRGB(3,FAILDIG);
2111 /* Thousands flag can also be used with currency */
2112 WCONVERT(L"1 234,5 \x20ac", NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_USE_ALL);
2113 EXPECT(5,NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_USE_ALL,NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_DECIMAL,9,0,-1);
2114 EXPECT2(1,2);
2115 EXPECTRGB(2,3);
2116 EXPECTRGB(3,4);
2117 EXPECTRGB(4,5);
2118 EXPECTRGB(5,FAILDIG);
2121 /** NUMPRS_DECIMAL **/
2123 /* With flag, consumes decimal point */
2124 CONVERT("1,2", NUMPRS_DECIMAL);
2125 EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL,3,0,-1);
2126 EXPECT2(1,2);
2127 EXPECTRGB(2,FAILDIG);
2129 /* With flag, but not regular point */
2130 CONVERT("1.2", NUMPRS_DECIMAL);
2131 EXPECT(1,NUMPRS_DECIMAL,0,1,0,0);
2132 EXPECT2(1,FAILDIG);
2135 static void test_VarParseNumFromStrMisc(void)
2137 HRESULT hres;
2138 LCID lcid;
2139 NUMPARSE np;
2140 BYTE rgb[128];
2141 OLECHAR currency[8], t1000[8], mont1000[8], dec[8], mondec[8];
2143 CHECKPTR(VarParseNumFromStr);
2145 /* Customize the regional settings to perform extra tests */
2147 if (GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, currency, ARRAY_SIZE(currency)) &&
2148 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, t1000, ARRAY_SIZE(t1000)) &&
2149 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, mont1000, ARRAY_SIZE(mont1000)) &&
2150 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, dec, ARRAY_SIZE(dec)) &&
2151 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, mondec, ARRAY_SIZE(mondec)))
2153 /* Start from a known configuration */
2154 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, L"$");
2155 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L",");
2156 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L",");
2157 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, L".");
2158 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L".");
2160 /* SCURRENCY defaults to '$' */
2161 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, L"");
2162 hres = wconvert_str(L"$1", ARRAY_SIZE(rgb), NUMPRS_CURRENCY, &np, rgb, LOCALE_USER_DEFAULT, 0);
2163 EXPECT(1,NUMPRS_CURRENCY,NUMPRS_CURRENCY,2,0,0);
2164 EXPECT2(1,FAILDIG);
2165 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, L"$");
2167 /* STHOUSAND has no default */
2168 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L"~");
2169 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L"");
2170 hres = wconvert_str(L"1,000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2171 EXPECTFAIL;
2172 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L"~");
2174 /* But SMONTHOUSANDSEP defaults to ','! */
2175 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L"");
2176 hres = wconvert_str(L"$1,000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY, &np, rgb, LOCALE_USER_DEFAULT, 0);
2177 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,6,0,3);
2178 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2179 EXPECTRGB(4,FAILDIG);
2180 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L",");
2181 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L",");
2183 /* SDECIMAL defaults to '.' */
2184 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L"~");
2185 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, L"");
2186 hres = wconvert_str(L"4.2", ARRAY_SIZE(rgb), NUMPRS_DECIMAL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2187 EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL,3,0,-1);
2188 EXPECT2(4,2);
2189 EXPECTRGB(2,FAILDIG);
2190 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, L"~");
2192 /* But SMONDECIMALSEP has no default! */
2193 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L"");
2194 hres = wconvert_str(L"3.9", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2195 EXPECTFAIL;
2196 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, L".");
2197 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L".");
2199 /* Non-breaking spaces are not allowed if sThousand is a regular space */
2200 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L" ");
2202 hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS, &np, rgb, LOCALE_USER_DEFAULT, 0);
2203 EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,3);
2204 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2205 EXPECTRGB(4,FAILDIG);
2207 hres = wconvert_str(L"1\xa0\x30\x30\x30", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2208 EXPECTFAIL;
2211 /* Show that NUMPRS_THOUSANDS activates sThousand and that
2212 * NUMPRS_THOUSANDS+NUMPRS_CURRENCY activates sMonThousandSep
2213 * whether a currency sign is present or not. Also the presence of
2214 * sMonThousandSep flags the value as being a currency.
2216 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L"|");
2217 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L" ");
2219 hres = wconvert_str(L"1|000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS, &np, rgb, LOCALE_USER_DEFAULT, 0);
2220 EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,3);
2221 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2222 EXPECTRGB(4,FAILDIG);
2224 hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2225 EXPECTFAIL;
2227 hres = wconvert_str(L"1|000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY, &np, rgb, LOCALE_USER_DEFAULT, 0);
2228 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,NUMPRS_THOUSANDS,5,0,3);
2229 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2230 EXPECTRGB(4,FAILDIG);
2232 hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2233 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,5,0,3);
2234 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2235 EXPECTRGB(4,FAILDIG);
2238 /* Leading sMonThousandSep are not allowed (same as sThousand) */
2239 hres = wconvert_str(L" 1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2240 EXPECTFAIL;
2242 /* But trailing ones are allowed (same as sThousand) */
2243 hres = wconvert_str(L"1 000 ", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2244 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,6,0,3);
2245 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2246 EXPECTRGB(4,FAILDIG);
2248 /* And they break NUMPRS_TRAILING_WHITE (same as sThousand) */
2249 hres = wconvert_str(L"1000 ", ARRAY_SIZE(rgb), NUMPRS_TRAILING_WHITE|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2250 EXPECTFAIL;
2253 /* NUMPRS_CURRENCY is not enough for sMonThousandSep */
2254 hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2255 EXPECTFAIL;
2258 /* Even with a currency sign, the regular thousands separator works */
2259 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, L"$");
2260 /* Make sure SMONDECIMALSEP is not the currency sign (see the
2261 * Cape Verdean escudo comment).
2263 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L"/");
2264 hres = wconvert_str(L"$1|000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2265 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,6,0,3);
2266 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2267 EXPECTRGB(4,FAILDIG);
2269 /* Mixing both thousands separators is allowed */
2270 hres = wconvert_str(L"1 000|000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2271 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,9,0,6);
2272 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2273 EXPECTRGB(7,FAILDIG);
2276 /* SMONTHOUSANDSEP does not consider regular spaces to be equivalent to
2277 * non-breaking spaces!
2279 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L"\xa0");
2280 hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2281 EXPECTFAIL;
2283 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L"\xa0");
2284 hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2285 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,5,0,3);
2286 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2287 EXPECTRGB(4,FAILDIG);
2290 /* Regular thousands separators also have precedence over the currency ones */
2291 hres = wconvert_str(L"1\xa0\x30\x30\x30", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2292 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,5,0,3);
2293 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2294 EXPECTRGB(4,FAILDIG);
2297 /* Show that the decimal separator masks the thousands one in all
2298 * positions, sometimes even without NUMPRS_DECIMAL.
2300 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L",");
2301 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L"~");
2302 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, L",");
2303 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L"~");
2305 hres = wconvert_str(L",1", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_DECIMAL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2306 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_DECIMAL,NUMPRS_DECIMAL,2,0,-1);
2307 EXPECT2(1,FAILDIG);
2309 hres = wconvert_str(L"1,000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2310 EXPECTFAIL;
2312 hres = wconvert_str(L"1,", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2313 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_USE_ALL,NUMPRS_DECIMAL,2,0,0);
2314 EXPECT2(1,FAILDIG);
2316 /* But not for their monetary equivalents */
2317 hres = wconvert_str(L"~1", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_CURRENCY, &np, rgb, LOCALE_USER_DEFAULT, 0);
2318 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_CURRENCY,NUMPRS_DECIMAL|NUMPRS_CURRENCY,2,0,-1);
2319 EXPECT2(1,FAILDIG);
2321 hres = wconvert_str(L"1~", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2322 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,2,0,0);
2323 EXPECT2(1,FAILDIG);
2326 /* Only the first sThousand character is used (sigh of relief) */
2327 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L" \xa0");
2328 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L" \xa0");
2330 hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2331 todo_wine EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,5,0,3);
2332 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2333 EXPECTRGB(4,FAILDIG);
2335 hres = wconvert_str(L"1\xa0\x30\x30\x30", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2336 EXPECTFAIL;
2338 hres = wconvert_str(L"1 \xa0\x30\x30\x30", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2339 EXPECTFAIL;
2342 /* Show that the currency decimal separator is active even without
2343 * NUMPRS_CURRENCY.
2345 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, L".");
2346 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L",");
2348 hres = wconvert_str(L"1.2", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2349 EXPECT(2,NUMPRS_DECIMAL|NUMPRS_USE_ALL,NUMPRS_DECIMAL,3,0,-1);
2350 EXPECT2(1,2);
2351 EXPECTRGB(2,FAILDIG);
2353 hres = wconvert_str(L"1,2", ARRAY_SIZE(rgb), NUMPRS_DECIMAL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2354 EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL|NUMPRS_CURRENCY,3,0,-1);
2355 EXPECT2(1,2);
2356 EXPECTRGB(2,FAILDIG);
2358 hres = wconvert_str(L"1.2", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2359 EXPECT(2,NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_DECIMAL,3,0,-1);
2360 EXPECT2(1,2);
2361 EXPECTRGB(2,FAILDIG);
2363 hres = wconvert_str(L"1,2", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2364 EXPECT(2,NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_DECIMAL|NUMPRS_CURRENCY,3,0,-1);
2365 EXPECT2(1,2);
2366 EXPECTRGB(2,FAILDIG);
2368 hres = wconvert_str(L"1.2,3", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_CURRENCY, &np, rgb, LOCALE_USER_DEFAULT, 0);
2369 EXPECT(2,NUMPRS_DECIMAL|NUMPRS_CURRENCY,NUMPRS_DECIMAL,3,0,-1);
2370 EXPECT2(1,2);
2371 EXPECTRGB(2,FAILDIG);
2373 hres = wconvert_str(L"1,2.3", ARRAY_SIZE(rgb), NUMPRS_DECIMAL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2374 EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL|NUMPRS_CURRENCY,3,0,-1);
2375 EXPECT2(1,2);
2376 EXPECTRGB(2,FAILDIG);
2379 /* In some locales the decimal separator is the currency sign.
2380 * For instance the Cape Verdean escudo.
2382 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L"$");
2383 hres = wconvert_str(L"1$99", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2384 EXPECT(3,NUMPRS_DECIMAL|NUMPRS_USE_ALL,NUMPRS_DECIMAL|NUMPRS_CURRENCY,4,0,-2);
2385 EXPECT2(1,9);
2386 EXPECTRGB(2,9);
2387 EXPECTRGB(3,FAILDIG);
2390 /* Restore all the settings */
2391 ok(SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, currency), "Restoring SCURRENCY failed\n");
2392 ok(SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, t1000), "Restoring STHOUSAND failed\n");
2393 ok(SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, mont1000), "Restoring SMONTHOUSANDSEP failed\n");
2394 ok(SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, dec), "Restoring SDECIMAL failed\n");
2395 ok(SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, mondec), "Restoring SMONDECIMALSEP failed\n");
2399 /* Test currencies of various lengths */
2401 /* 2 Polish zloty */
2402 lcid = MAKELCID(MAKELANGID(LANG_POLISH,SUBLANG_POLISH_POLAND),SORT_DEFAULT);
2403 WCONVERT(L"z\x142\x32", NUMPRS_CURRENCY|NUMPRS_USE_ALL);
2404 EXPECT(1,NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_CURRENCY,3,0,0);
2405 EXPECT2(2,FAILDIG);
2407 /* Multi-character currencies can be repeated too "zl2zlzl" */
2408 WCONVERT(L"z\x142\x32z\x142z\x142", NUMPRS_CURRENCY|NUMPRS_USE_ALL);
2409 EXPECT(1,NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_CURRENCY,7,0,0);
2410 EXPECT2(2,FAILDIG);
2412 lcid = MAKELCID(MAKELANGID(LANG_FRENCH,SUBLANG_FRENCH_SWISS),SORT_DEFAULT);
2413 WCONVERT(L"3CHF", NUMPRS_CURRENCY|NUMPRS_USE_ALL);
2414 /* Windows <= 8.1 uses an old currency symbol: "fr. 5" */
2415 todo_wine ok(hres == S_OK || broken(hres == DISP_E_TYPEMISMATCH), "returned %08x\n", hres);
2416 if (hres == S_OK)
2418 todo_wine EXPECT(1,NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_CURRENCY,4,0,0);
2419 EXPECT2(3,FAILDIG);
2422 /* 5 Moroccan dirham */
2423 lcid = MAKELCID(MAKELANGID(LANG_ARABIC,SUBLANG_ARABIC_MOROCCO),SORT_DEFAULT);
2424 WCONVERT(L"5\x62f.\x645.\x200f", NUMPRS_CURRENCY|NUMPRS_USE_ALL);
2425 /* Windows 8.1 incorrectly doubles the right-to-left mark:
2426 * "\x62f.\x645.\x200f\x200f 5"
2428 ok(hres == S_OK || broken(hres == DISP_E_TYPEMISMATCH), "returned %08x\n", hres);
2429 if (hres == S_OK)
2431 EXPECT(1,NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_CURRENCY,6,0,0);
2432 EXPECT2(5,FAILDIG);
2436 /* Test Arabic numerals in an Arabic locale */
2438 lcid = MAKELCID(MAKELANGID(LANG_ARABIC,SUBLANG_ARABIC_MOROCCO),SORT_DEFAULT);
2439 WCONVERT(L"\x660", NUMPRS_STD);
2440 EXPECTFAIL;
2443 static HRESULT (WINAPI *pVarNumFromParseNum)(NUMPARSE*,BYTE*,ULONG,VARIANT*);
2445 /* Macros for converting and testing the result of VarNumFromParseNum */
2446 #define SETRGB(indx,val) if (!indx) memset(rgb, FAILDIG, sizeof(rgb)); rgb[indx] = val
2447 #undef CONVERT
2448 #define CONVERT(a,b,c,d,e,f,bits) \
2449 np.cDig = (a); np.dwInFlags = (b); np.dwOutFlags = (c); np.cchUsed = (d); \
2450 np.nBaseShift = (e); np.nPwr10 = (f); hres = pVarNumFromParseNum(&np, rgb, bits, &vOut)
2451 static const char *szFailOverflow = "Expected overflow, hres = %08x\n";
2452 #define EXPECT_OVERFLOW ok(hres == DISP_E_OVERFLOW, szFailOverflow, hres)
2453 static const char *szFailOk = "Call failed, hres = %08x\n";
2454 #define EXPECT_OK ok(hres == S_OK, szFailOk, hres); \
2455 if (hres == S_OK)
2456 #define EXPECT_TYPE(typ) ok(V_VT(&vOut) == typ,"Expected Type = " #typ ", got %d\n", V_VT(&vOut))
2457 #define EXPECT_I1(val) EXPECT_OK { EXPECT_TYPE(VT_I1); \
2458 ok(V_I1(&vOut) == val, "Expected i1 = %d, got %d\n", (signed char)val, V_I1(&vOut)); }
2459 #define EXPECT_UI1(val) EXPECT_OK { EXPECT_TYPE(VT_UI1); \
2460 ok(V_UI1(&vOut) == val, "Expected ui1 = %d, got %d\n", (BYTE)val, V_UI1(&vOut)); }
2461 #define EXPECT_I2(val) EXPECT_OK { EXPECT_TYPE(VT_I2); \
2462 ok(V_I2(&vOut) == val, "Expected i2 = %d, got %d\n", (SHORT)val, V_I2(&vOut)); }
2463 #define EXPECT_UI2(val) EXPECT_OK { EXPECT_TYPE(VT_UI2); \
2464 ok(V_UI2(&vOut) == val, "Expected ui2 = %d, got %d\n", (USHORT)val, V_UI2(&vOut)); }
2465 #define EXPECT_I4(val) EXPECT_OK { EXPECT_TYPE(VT_I4); \
2466 ok(V_I4(&vOut) == val, "Expected i4 = %d, got %d\n", (LONG)val, V_I4(&vOut)); }
2467 #define EXPECT_UI4(val) EXPECT_OK { EXPECT_TYPE(VT_UI4); \
2468 ok(V_UI4(&vOut) == val, "Expected ui4 = %d, got %d\n", (ULONG)val, V_UI4(&vOut)); }
2469 #define EXPECT_I8(high,low) EXPECT_OK { EXPECT_TYPE(VT_I8); \
2470 ok(V_I8(&vOut) == ((((ULONG64)(high))<<32)|(low)), "Expected i8 = %x%08x, got %x%08x\n", \
2471 (LONG)(high), (LONG)(low), (LONG)(V_I8(&vOut)>>32), (LONG)V_I8(&vOut) ); }
2472 #define EXPECT_UI8(val) EXPECT_OK { EXPECT_TYPE(VT_UI8); \
2473 ok(V_UI8(&vOut) == val, "Expected ui8 = 0x%x%08x, got 0x%x%08x\n", \
2474 (DWORD)((ULONG64)val >> 32), (DWORD)(ULONG64)val, (DWORD)(V_UI8(&vOut) >> 32), (DWORD)V_UI8(&vOut)); }
2475 #define EXPECT_R4(val) EXPECT_OK { EXPECT_TYPE(VT_R4); \
2476 ok(V_R4(&vOut) == val, "Expected r4 = %f, got %f\n", val, V_R4(&vOut)); }
2477 #define EXPECT_R8(val) EXPECT_OK { EXPECT_TYPE(VT_R8); \
2478 ok(V_R8(&vOut) == val, "Expected r8 = %g, got %g\n", val, V_R8(&vOut)); }
2479 #define CY_MULTIPLIER 10000
2480 #define EXPECT_CY(val) EXPECT_OK { EXPECT_TYPE(VT_CY); \
2481 ok(V_CY(&vOut).int64 == (LONG64)(val * CY_MULTIPLIER), "Expected r8 = 0x%x%08x, got 0x%x%08x\n", \
2482 (DWORD)((LONG64)val >> 23), (DWORD)(LONG64)val, (DWORD)(V_CY(&vOut).int64 >>32), (DWORD)V_CY(&vOut).int64); }
2483 #define EXPECT_DECIMAL(valHi, valMid, valLo) EXPECT_OK { EXPECT_TYPE(VT_DECIMAL); \
2484 ok((V_DECIMAL(&vOut).Hi32 == valHi) && (S1(U1(V_DECIMAL(&vOut))).Mid32 == valMid) && \
2485 (S1(U1(V_DECIMAL(&vOut))).Lo32 == valLo), \
2486 "Expected decimal = %x/0x%x%08x, got %x/0x%x%08x\n", valHi, valMid, valLo, \
2487 V_DECIMAL(&vOut).Hi32, S1(U1(V_DECIMAL(&vOut))).Mid32, S1(U1(V_DECIMAL(&vOut))).Lo32); }
2489 static void test_VarNumFromParseNum(void)
2491 HRESULT hres;
2492 NUMPARSE np;
2493 BYTE rgb[128];
2494 VARIANT vOut;
2496 CHECKPTR(VarNumFromParseNum);
2498 /* Convert the number 1 to different types */
2499 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I1); EXPECT_I1(1);
2500 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_UI1); EXPECT_UI1(1);
2501 /* Prefers a signed type to unsigned of the same size */
2502 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I1|VTBIT_UI1); EXPECT_I1(1);
2503 /* But takes the smaller size if possible */
2504 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I2|VTBIT_UI1); EXPECT_UI1(1);
2506 /* Try different integer sizes */
2507 #define INTEGER_VTBITS (VTBIT_I1|VTBIT_UI1|VTBIT_I2|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|VTBIT_I8|VTBIT_UI8)
2509 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, INTEGER_VTBITS); EXPECT_I1(1);
2510 /* 127 */
2511 SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 7);
2512 CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_I1(127);
2513 /* 128 */
2514 SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 8);
2515 CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_UI1(128);
2516 /* 255 */
2517 SETRGB(0, 2); SETRGB(1, 5); SETRGB(2, 5);
2518 CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_UI1(255);
2519 /* 256 */
2520 SETRGB(0, 2); SETRGB(1, 5); SETRGB(2, 6);
2521 CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_I2(256);
2522 /* 32767 */
2523 SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 7);
2524 CONVERT(5,0,0,5,0,0, INTEGER_VTBITS); EXPECT_I2(32767);
2525 /* 32768 */
2526 SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 8);
2527 CONVERT(5,0,0,5,0,0, INTEGER_VTBITS); EXPECT_UI2(32768);
2529 /* Assume the above pattern holds for remaining positive integers; test negative */
2531 /* -128 */
2532 SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 8);
2533 CONVERT(3,0,NUMPRS_NEG,3,0,0, INTEGER_VTBITS); EXPECT_I1(-128);
2534 /* -129 */
2535 SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 9);
2536 CONVERT(3,0,NUMPRS_NEG,3,0,0, INTEGER_VTBITS); EXPECT_I2(-129);
2537 /* -32768 */
2538 SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 8);
2539 CONVERT(5,0,NUMPRS_NEG,5,0,0, INTEGER_VTBITS); EXPECT_I2(-32768);
2540 /* -32768 */
2541 SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 9);
2542 CONVERT(5,0,NUMPRS_NEG,5,0,0, INTEGER_VTBITS); EXPECT_I4(-32769);
2544 /* Assume the above pattern holds for remaining negative integers */
2546 /* Test hexadecimal conversions */
2547 SETRGB(0, 1); CONVERT(1,0,0,1,4,0, INTEGER_VTBITS); EXPECT_I1(0x01);
2548 /* 0x7f */
2549 SETRGB(0, 7); SETRGB(1, 0xf);
2550 CONVERT(2,0,0,2,4,0, INTEGER_VTBITS); EXPECT_I1(0x7f);
2551 SETRGB(0, 7); SETRGB(1, 0xf);
2552 CONVERT(2,0,0,2,4,0, VTBIT_DECIMAL); EXPECT_DECIMAL(0,0,0x7f);
2553 /* 0x7fff */
2554 SETRGB(0, 7); SETRGB(1, 0xf); SETRGB(2, 0xf); SETRGB(3, 0xf);
2555 CONVERT(4,0,0,4,4,0, INTEGER_VTBITS); EXPECT_I2(0x7fff);
2556 /* 0x7fffffff */
2557 SETRGB(0, 7); SETRGB(1, 0xf); SETRGB(2, 0xf); SETRGB(3, 0xf);
2558 SETRGB(4, 0xf); SETRGB(5, 0xf); SETRGB(6, 0xf); SETRGB(7, 0xf);
2559 CONVERT(8,0,0,8,4,0, INTEGER_VTBITS); EXPECT_I4(0x7fffffffL);
2560 /* 0x7fffffffffffffff (64 bits) */
2561 SETRGB(0, 7); SETRGB(1, 0xf); SETRGB(2, 0xf); SETRGB(3, 0xf);
2562 SETRGB(4, 0xf); SETRGB(5, 0xf); SETRGB(6, 0xf); SETRGB(7, 0xf);
2563 SETRGB(8, 0xf); SETRGB(9, 0xf); SETRGB(10, 0xf); SETRGB(11, 0xf);
2564 SETRGB(12, 0xf); SETRGB(13, 0xf); SETRGB(14, 0xf); SETRGB(15, 0xf);
2565 if (has_i8)
2567 /* We cannot use INTEGER_VTBITS as WinXP and Win2003 are broken(?). They
2568 truncate the number to the smallest integer size requested:
2569 CONVERT(16,0,0,16,4,0, INTEGER_VTBITS); EXPECT_I1((signed char)0xff); */
2570 CONVERT(16,0,0,16,4,0, VTBIT_I8); EXPECT_I8(0x7fffffff,0xffffffff);
2573 /* Assume the above pattern holds for numbers without hi-bit set, test (preservation of) hi-bit */
2574 /* 0x82 */
2575 SETRGB(0, 8); SETRGB(1, 2);
2576 CONVERT(2,0,0,2,4,0, INTEGER_VTBITS);
2577 EXPECT_I1((signed char)0x82);
2578 /* 0x8002 */
2579 SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 2);
2580 CONVERT(4,0,0,4,4,0, INTEGER_VTBITS);
2581 EXPECT_I2((signed short)0x8002);
2582 /* 0x80000002 */
2583 SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 0);
2584 SETRGB(4, 0); SETRGB(5, 0); SETRGB(6, 0); SETRGB(7, 2);
2585 CONVERT(8,0,0,8,4,0, INTEGER_VTBITS); EXPECT_I4(0x80000002);
2586 /* 0x8000000000000002 (64 bits) */
2587 SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 0);
2588 SETRGB(4, 0); SETRGB(5, 0); SETRGB(6, 0); SETRGB(7, 0);
2589 SETRGB(8, 0); SETRGB(9, 0); SETRGB(10, 0); SETRGB(11, 0);
2590 SETRGB(12, 0); SETRGB(13, 0); SETRGB(14, 0); SETRGB(15, 2);
2591 if (has_i8)
2593 /* We cannot use INTEGER_VTBITS as WinXP and Win2003 are broken(?). They
2594 truncate the number to the smallest integer size requested:
2595 CONVERT(16,0,0,16,4,0, INTEGER_VTBITS & ~VTBIT_I1);
2596 EXPECT_I2((signed short)0x0002); */
2597 CONVERT(16,0,0,16,4,0, VTBIT_I8); EXPECT_I8(0x80000000,0x00000002);
2600 /* Test (preservation of) hi-bit with STRICT type requesting */
2601 /* 0x82 */
2602 SETRGB(0, 8); SETRGB(1, 2);
2603 CONVERT(2,0,0,2,4,0, VTBIT_I1);
2604 EXPECT_I1((signed char)0x82);
2605 /* 0x8002 */
2606 SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 2);
2607 CONVERT(4,0,0,4,4,0, VTBIT_I2);
2608 EXPECT_I2((signed short)0x8002);
2609 /* 0x80000002 */
2610 SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 0);
2611 SETRGB(4, 0); SETRGB(5, 0); SETRGB(6, 0); SETRGB(7, 2);
2612 CONVERT(8,0,0,8,4,0, VTBIT_I4); EXPECT_I4(0x80000002);
2613 /* 0x8000000000000002 (64 bits) */
2614 SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 0);
2615 SETRGB(4, 0); SETRGB(5, 0); SETRGB(6, 0); SETRGB(7, 0);
2616 SETRGB(8, 0); SETRGB(9, 0); SETRGB(10, 0); SETRGB(11, 0);
2617 SETRGB(12, 0); SETRGB(13, 0); SETRGB(14, 0); SETRGB(15, 2);
2618 if (has_i8)
2620 CONVERT(16,0,0,16,4,0, VTBIT_I8); EXPECT_I8(0x80000000,0x00000002);
2622 /* Assume the above pattern holds for numbers with hi-bit set */
2624 /* Negative numbers overflow if we have only unsigned outputs */
2625 /* -1 */
2626 SETRGB(0, 1); CONVERT(1,0,NUMPRS_NEG,1,0,0, VTBIT_UI1); EXPECT_OVERFLOW;
2627 /* -0.6 */
2628 SETRGB(0, 6); CONVERT(1,0,NUMPRS_NEG,1,0,~0u, VTBIT_UI1); EXPECT_OVERFLOW;
2630 /* Except that rounding is done first, so -0.5 to 0 are accepted as 0 */
2631 /* -0.5 */
2632 SETRGB(0, 5); CONVERT(1,0,NUMPRS_NEG,1,0,~0u, VTBIT_UI1); EXPECT_UI1(0);
2634 /* Floating point zero is OK */
2635 /* 0.00000000E0 */
2636 SETRGB(0, 0); CONVERT(1,0,NUMPRS_DECIMAL|NUMPRS_EXPONENT,12,0,-8, VTBIT_R8);
2637 EXPECT_R8(0.0);
2639 /* Float is acceptable for an integer input value */
2640 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R4); EXPECT_R4(1.0f);
2641 /* As is double */
2642 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R8); EXPECT_R8(1.0);
2643 /* As is currency */
2644 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_CY); EXPECT_CY(1);
2646 /* Float is preferred over double */
2647 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R4|VTBIT_R8); EXPECT_R4(1.0f);
2649 /* Double is preferred over currency */
2650 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R8|VTBIT_CY); EXPECT_R8(1.0);
2652 /* Currency is preferred over decimal */
2653 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_CY|VTBIT_DECIMAL); EXPECT_CY(1);
2655 /* Underflow test */
2656 SETRGB(0, 1); CONVERT(1,0,NUMPRS_EXPONENT,1,0,-94938484, VTBIT_R4); EXPECT_R4(0.0);
2657 SETRGB(0, 1); CONVERT(1,0,NUMPRS_EXPONENT,1,0,-94938484, VTBIT_R8); EXPECT_R8(0.0);
2658 SETRGB(0, 1); CONVERT(1,0,NUMPRS_EXPONENT,1,0,-94938484, VTBIT_CY); EXPECT_CY(0);
2662 static void test_UdateFromDate( int line, DATE dt, ULONG flags, HRESULT r, WORD d, WORD m, WORD y,
2663 WORD h, WORD mn, WORD s, WORD ms, WORD dw, WORD dy)
2665 UDATE ud;
2666 HRESULT res;
2668 memset(&ud, 0, sizeof(ud));
2669 res = pVarUdateFromDate(dt, flags, &ud);
2670 ok_(__FILE__,line)(r == res && (res != S_OK || (ud.st.wYear == y && ud.st.wMonth == m && ud.st.wDay == d &&
2671 ud.st.wHour == h && ud.st.wMinute == mn && ud.st.wSecond == s &&
2672 ud.st.wMilliseconds == ms && ud.st.wDayOfWeek == dw && ud.wDayOfYear == dy)),
2673 "%.16g expected res(%x) %d,%d,%d,%d,%d,%d,%d %d %d, got res(%x) %d,%d,%d,%d,%d,%d,%d %d %d\n",
2674 dt, r, d, m, y, h, mn, s, ms, dw, dy,
2675 res, ud.st.wDay, ud.st.wMonth, ud.st.wYear, ud.st.wHour, ud.st.wMinute,
2676 ud.st.wSecond, ud.st.wMilliseconds, ud.st.wDayOfWeek, ud.wDayOfYear );
2678 #define DT2UD(dt,flags,r,d,m,y,h,mn,s,ms,dw,dy) test_UdateFromDate(__LINE__,dt,flags,r,d,m,y,h,mn,s,ms,dw,dy)
2680 static void test_VarUdateFromDate(void)
2682 CHECKPTR(VarUdateFromDate);
2683 DT2UD(29221.0,0,S_OK,1,1,1980,0,0,0,0,2,1); /* 1 Jan 1980 */
2684 DT2UD(29222.0,0,S_OK,2,1,1980,0,0,0,0,3,2); /* 2 Jan 1980 */
2685 DT2UD(33238.0,0,S_OK,31,12,1990,0,0,0,0,1,365); /* 31 Dec 1990 */
2686 DT2UD(0.0,0,S_OK,30,12,1899,0,0,0,0,6,364); /* 30 Dec 1899 - VT_DATE 0.0 */
2687 DT2UD(-657434.0,0,S_OK,1,1,100,0,0,0,0,5,1); /* 1 Jan 100 - Min */
2688 DT2UD(-657435.0,0,E_INVALIDARG,0,0,0,0,0,0,0,0,0); /* < 1 Jan 100 => err */
2689 DT2UD(2958465.0,0,S_OK,31,12,9999,0,0,0,0,5,365); /* 31 Dec 9999 - Max */
2690 DT2UD(2958466.0,0,E_INVALIDARG,0,0,0,0,0,0,0,0,0); /* > 31 Dec 9999 => err */
2692 /* VAR_VALIDDATE doesn't prevent upper and lower bounds being checked */
2693 DT2UD(-657435.0,VAR_VALIDDATE,E_INVALIDARG,0,0,0,0,0,0,0,0,0);
2694 DT2UD(2958466.0,VAR_VALIDDATE,E_INVALIDARG,0,0,0,0,0,0,0,0,0);
2696 /* Times */
2697 DT2UD(29221.25,0,S_OK,1,1,1980,6,0,0,0,2,1); /* 6 AM */
2698 DT2UD(29221.33333333,0,S_OK,1,1,1980,8,0,0,0,2,1); /* 8 AM */
2699 DT2UD(29221.5,0,S_OK,1,1,1980,12,0,0,0,2,1); /* 12 AM */
2700 DT2UD(29221.9888884444,0,S_OK,1,1,1980,23,44,0,0,2,1); /* 11:44 PM */
2701 DT2UD(29221.7508765432,0,S_OK,1,1,1980,18,1,16,0,2,1); /* 6:18:02 PM */
2703 /* Test handling of times on dates prior to the epoch */
2704 DT2UD(-5.25,0,S_OK,25,12,1899,6,0,0,0,1,359);
2705 DT2UD(-5.9999884259259,0,S_OK,25,12,1899,23,59,59,0,1,359);
2706 /* This just demonstrates the non-linear nature of values prior to the epoch */
2707 DT2UD(-4.0,0,S_OK,26,12,1899,0,0,0,0,2,360);
2708 /* Numerical oddity: for 0.0 < x < 1.0, x and -x represent the same datetime */
2709 DT2UD(-0.25,0,S_OK,30,12,1899,6,0,0,0,6,364);
2710 DT2UD(0.25,0,S_OK,30,12,1899,6,0,0,0,6,364);
2714 static void test_DateFromUDate( int line, WORD d, WORD m, WORD y, WORD h, WORD mn, WORD s, WORD ms,
2715 WORD dw, WORD dy, ULONG flags, HRESULT r, DATE dt )
2717 UDATE ud;
2718 double out;
2719 HRESULT res;
2721 ud.st.wYear = y;
2722 ud.st.wMonth = m;
2723 ud.st.wDay = d;
2724 ud.st.wHour = h;
2725 ud.st.wMinute = mn;
2726 ud.st.wSecond = s;
2727 ud.st.wMilliseconds = ms;
2728 ud.st.wDayOfWeek = dw;
2729 ud.wDayOfYear = dy;
2730 res = pVarDateFromUdate(&ud, flags, &out);
2731 ok_(__FILE__,line)(r == res && (r != S_OK || EQ_DOUBLE(out, dt)),
2732 "expected %x, %.16g, got %x, %.16g\n", r, dt, res, out);
2734 #define UD2T(d,m,y,h,mn,s,ms,dw,dy,flags,r,dt) test_DateFromUDate(__LINE__,d,m,y,h,mn,s,ms,dw,dy,flags,r,dt)
2736 static void test_VarDateFromUdate(void)
2738 CHECKPTR(VarDateFromUdate);
2739 UD2T(1,1,1980,0,0,0,0,2,1,0,S_OK,29221.0); /* 1 Jan 1980 */
2740 UD2T(2,1,1980,0,0,0,0,3,2,0,S_OK,29222.0); /* 2 Jan 1980 */
2741 UD2T(2,1,1980,0,0,0,0,4,5,0,S_OK,29222.0); /* 2 Jan 1980 */
2742 UD2T(31,12,1990,0,0,0,0,0,0,0,S_OK,33238.0); /* 31 Dec 1990 */
2743 UD2T(31,12,90,0,0,0,0,0,0,0,S_OK,33238.0); /* year < 100 is 1900+year! */
2744 UD2T(30,12,1899,0,0,0,0,6,364,0,S_OK,0.0); /* 30 Dec 1899 - VT_DATE 0.0 */
2745 UD2T(1,1,100,0,0,0,0,0,0,0,S_OK,-657434.0); /* 1 Jan 100 - Min */
2746 UD2T(31,12,9999,0,0,0,0,0,0,0,S_OK,2958465.0); /* 31 Dec 9999 - Max */
2747 UD2T(1,1,10000,0,0,0,0,0,0,0,E_INVALIDARG,0.0); /* > 31 Dec 9999 => err */
2748 UD2T(1,1,-10000,0,0,0,0,0,0,0,E_INVALIDARG,0.0);/* < -9999 => err */
2750 UD2T(30,12,1899,0,0,0,0,0,0,0,S_OK,0.0); /* 30 Dec 1899 0:00:00 */
2751 UD2T(30,12,1899,0,0,0,999,0,0,0,S_OK,0.0); /* Ignore milliseconds */
2753 UD2T(1,1,1980,18,1,16,0,2,1,0,S_OK,29221.75087962963); /* 6:18:02 PM */
2754 UD2T(1,300,1980,18,1,16,0,2,1,0,S_OK,38322.75087962963); /* Test fwdrolled month */
2755 UD2T(300,1,1980,18,1,16,0,2,1,0,S_OK,29520.75087962963); /* Test fwdrolled days */
2756 UD2T(0,1,1980,42,1,16,0,2,1,0,S_OK,29221.75087962963); /* Test fwdrolled hours */
2757 UD2T(1,1,1980,17,61,16,0,2,1,0,S_OK,29221.75087962963); /* Test fwdrolled minutes */
2758 UD2T(1,1,1980,18,0,76,0,2,1,0,S_OK,29221.75087962963); /* Test fwdrolled seconds */
2759 UD2T(1,-300,1980,18,1,16,0,2,1,0,S_OK,20059.75087962963); /* Test backrolled month */
2760 UD2T(-300,1,1980,18,1,16,0,2,1,0,S_OK,28920.75087962963); /* Test backrolled days */
2761 UD2T(3,1,1980,-30,1,16,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled hours */
2762 UD2T(1,1,1980,20,-119,16,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled minutes */
2763 UD2T(1,1,1980,18,3,-104,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled seconds */
2764 UD2T(1,12001,-1020,18,1,16,0,0,0,0,S_OK,29221.75087962963); /* Test rolled year and month */
2765 UD2T(1,-23,1982,18,1,16,0,0,0,0,S_OK,29221.75087962963); /* Test backrolled month */
2766 UD2T(-59,3,1980,18,1,16,0,0,0,0,S_OK,29221.75087962963); /* Test backrolled days */
2767 UD2T(1,1,0,0,0,0,0,0,0,0,S_OK,36526); /* Test zero year */
2768 UD2T(0,0,1980,0,0,0,0,0,0,0,S_OK,29189); /* Test zero day and month */
2769 UD2T(0,1,1980,0,0,0,0,2,1,0,S_OK,29220.0); /* Test zero day = LastDayOfMonth */
2770 UD2T(-1,1,1980,18,1,16,0,0,0,0,S_OK,29219.75087962963); /* Test day -1 = LastDayOfMonth - 1 */
2771 UD2T(1,1,-1,18,1,16,0,0,0,0,S_OK,36161.75087962963); /* Test year -1 = 1999 */
2772 UD2T(1,-1,1980,18,1,16,0,0,0,0,S_OK,29160.7508796296); /* Test month -1 = 11 */
2773 UD2T(1,13,1980,0,0,0,0,2,1,0,S_OK,29587.0); /* Rolls fwd to 1/1/1981 */
2775 /* Test handling of times on dates prior to the epoch */
2776 UD2T(25,12,1899,6,0,0,0,1,359,0,S_OK,-5.25);
2777 UD2T(25,12,1899,23,59,59,0,1,359,0,S_OK,-5.9999884259259);
2778 /* This just demonstrates the non-linear nature of values prior to the epoch */
2779 UD2T(26,12,1899,0,0,0,0,2,360,0,S_OK,-4.0);
2780 /* for DATE values 0.0 < x < 1.0, x and -x represent the same datetime */
2781 /* but when converting to DATE, prefer the positive versions */
2782 UD2T(30,12,1899,6,0,0,0,6,364,0,S_OK,0.25);
2784 UD2T(1,1,1980,18,1,16,0,2,1,VAR_TIMEVALUEONLY,S_OK,0.7508796296296296);
2785 UD2T(1,1,1980,18,1,16,0,2,1,VAR_DATEVALUEONLY,S_OK,29221.0);
2786 UD2T(25,12,1899,6,0,0,0,1,359,VAR_TIMEVALUEONLY,S_OK,0.25);
2787 UD2T(25,12,1899,6,0,0,0,1,359,VAR_DATEVALUEONLY,S_OK,-5.0);
2788 UD2T(1,-1,1980,18,1,16,0,0,0,VAR_TIMEVALUEONLY|VAR_DATEVALUEONLY,S_OK,0.7508796296296296);
2791 static void test_st2dt(int line, WORD d, WORD m, WORD y, WORD h, WORD mn,
2792 WORD s, WORD ms, INT r, double dt, double dt2)
2794 SYSTEMTIME st;
2795 double out;
2796 INT res;
2798 st.wYear = y;
2799 st.wMonth = m;
2800 st.wDay = d;
2801 st.wHour = h;
2802 st.wMinute = mn;
2803 st.wSecond = s;
2804 st.wMilliseconds = ms;
2805 st.wDayOfWeek = 0;
2806 res = pSystemTimeToVariantTime(&st, &out);
2807 ok_(__FILE__,line)(r == res, "expected %d, got %d\n", r, res);
2808 if (r && res)
2809 ok_(__FILE__,line)(EQ_DOUBLE(out, dt) || (dt2 && broken(EQ_DOUBLE(out, dt2))),
2810 "expected %.16g or %.16g, got %.16g\n", dt, dt2, out);
2812 #define ST2DT(d,m,y,h,mn,s,ms,r,dt,dt2) test_st2dt(__LINE__,d,m,y,h,mn,s,ms,r,dt,dt2)
2814 static void test_SystemTimeToVariantTime(void)
2816 CHECKPTR(SystemTimeToVariantTime);
2817 ST2DT(1,1,1980,0,0,0,0,TRUE,29221.0,0.0);
2818 ST2DT(2,1,1980,0,0,0,0,TRUE,29222.0,0.0);
2819 ST2DT(0,1,1980,0,0,0,0,TRUE,29220.0,0.0); /* Rolls back to 31 Dec 1899 */
2820 ST2DT(1,13,1980,0,0,0,0,FALSE,0.0,0.0); /* Fails on invalid month */
2821 ST2DT(32,1,1980,0,0,0,0,FALSE,0.0,0.0); /* Fails on invalid day */
2822 ST2DT(1,1,-1,0,0,0,0,FALSE,0.0,0.0); /* Fails on invalid year */
2823 ST2DT(1,1,10000,0,0,0,0,FALSE,0.0,0.0); /* Fails on invalid year */
2824 ST2DT(1,1,9999,0,0,0,0,TRUE,2958101.0,0.0); /* 9999 is last valid year */
2826 /* Old Windows versions use 29 as the Y2K cutoff:
2827 * years 00-29 map to 2000-2029 while years 30-99 map to 1930-1999
2829 ST2DT(1,1,0,0,0,0,0,TRUE,36526.0,0.0);
2830 ST2DT(1,1,29,0,0,0,0,TRUE,47119.0,0.0);
2831 ST2DT(1,1,30,0,0,0,0,TRUE,47484.0,10959.0);
2832 /* But Windows 1903+ uses 49 as the Y2K cutoff */
2833 ST2DT(1,1,49,0,0,0,0,TRUE,54424.0,17899.0);
2834 ST2DT(1,1,50,0,0,0,0,TRUE,18264.0,0.0);
2835 ST2DT(31,12,99,0,0,0,0,TRUE,36525.0,0.0);
2838 static void test_dt2st(int line, double dt, INT r, WORD d, WORD m, WORD y,
2839 WORD h, WORD mn, WORD s, WORD ms)
2841 SYSTEMTIME st;
2842 INT res;
2844 memset(&st, 0, sizeof(st));
2845 res = pVariantTimeToSystemTime(dt, &st);
2846 ok_(__FILE__,line)(r == res &&
2847 (!r || (st.wYear == y && st.wMonth == m && st.wDay == d &&
2848 st.wHour == h && st.wMinute == mn &&
2849 st.wSecond == s && st.wMilliseconds == ms)),
2850 "%.16g expected %d, %d,%d,%d,%d,%d,%d,%d, got %d, %d,%d,%d,%d,%d,%d,%d\n",
2851 dt, r, d, m, y, h, mn, s, ms, res, st.wDay, st.wMonth,
2852 st.wYear, st.wHour, st.wMinute, st.wSecond,
2853 st.wMilliseconds);
2855 #define DT2ST(dt,r,d,m,y,h,mn,s,ms) test_dt2st(__LINE__,dt,r,d,m,y,h,mn,s,ms)
2857 static void test_VariantTimeToSystemTime(void)
2859 CHECKPTR(VariantTimeToSystemTime);
2860 DT2ST(29221.0,1,1,1,1980,0,0,0,0);
2861 DT2ST(29222.0,1,2,1,1980,0,0,0,0);
2864 #define MKDOSDATE(d,m,y) ((d & 0x1f) | ((m & 0xf) << 5) | (((y-1980) & 0x7f) << 9))
2865 #define MKDOSTIME(h,m,s) (((s>>1) & 0x1f) | ((m & 0x3f) << 5) | ((h & 0x1f) << 11))
2867 static void test_dos2dt(int line, WORD d, WORD m, WORD y, WORD h, WORD mn,
2868 WORD s, INT r, double dt)
2870 unsigned short dosDate, dosTime;
2871 double out;
2872 INT res;
2874 out = 0.0;
2875 dosDate = MKDOSDATE(d, m, y);
2876 dosTime = MKDOSTIME(h, mn, s);
2877 res = pDosDateTimeToVariantTime(dosDate, dosTime, &out);
2878 ok_(__FILE__,line)(r == res && (!r || EQ_DOUBLE(out, dt)),
2879 "expected %d, %.16g, got %d, %.16g\n", r, dt, res, out);
2881 #define DOS2DT(d,m,y,h,mn,s,r,dt) test_dos2dt(__LINE__,d,m,y,h,mn,s,r,dt)
2883 static void test_DosDateTimeToVariantTime(void)
2885 CHECKPTR(DosDateTimeToVariantTime);
2887 /* Date */
2888 DOS2DT(1,1,1980,0,0,0,1,29221.0); /* 1/1/1980 */
2889 DOS2DT(31,12,2099,0,0,0,1,73050.0); /* 31/12/2099 */
2890 /* Dates are limited to the dos date max of 31/12/2099 */
2891 DOS2DT(31,12,2100,0,0,0,0,0.0); /* 31/12/2100 */
2892 /* Days and months of 0 cause date to roll back 1 day or month */
2893 DOS2DT(0,1,1980,0,0,0,1,29220.0); /* 0 Day => 31/12/1979 */
2894 DOS2DT(1,0,1980,0,0,0,1,29190.0); /* 0 Mth => 1/12/1979 */
2895 DOS2DT(0,0,1980,0,0,0,1,29189.0); /* 0 D/M => 30/11/1979 */
2896 /* Days > days in the month cause date to roll forward 1 month */
2897 DOS2DT(29,2,1981,0,0,0,1,29646.0); /* 29/2/1981 -> 3/1/1980 */
2898 DOS2DT(30,2,1981,0,0,0,1,29647.0); /* 30/2/1981 -> 4/1/1980 */
2899 /* Takes leap years into account when rolling forward */
2900 DOS2DT(29,2,1980,0,0,0,1,29280.0); /* 2/29/1980 */
2901 /* Months > 12 cause an error */
2902 DOS2DT(2,13,1980,0,0,0,0,0.0);
2904 /* Time */
2905 DOS2DT(1,1,1980,0,0,29,1,29221.00032407407); /* 1/1/1980 12:00:28 AM */
2906 DOS2DT(1,1,1980,0,0,31,1,29221.00034722222); /* 1/1/1980 12:00:30 AM */
2907 DOS2DT(1,1,1980,0,59,0,1,29221.04097222222); /* 1/1/1980 12:59:00 AM */
2908 DOS2DT(1,1,1980,0,60,0,0,0.0); /* Invalid minutes */
2909 DOS2DT(1,1,1980,0,0,60,0,0.0); /* Invalid seconds */
2910 DOS2DT(1,1,1980,23,0,0,1,29221.95833333333); /* 1/1/1980 11:00:00 PM */
2911 DOS2DT(1,1,1980,24,0,0,0,0.0); /* Invalid hours */
2913 DOS2DT(1,1,1980,0,0,1,1,29221.0);
2914 DOS2DT(2,1,1980,0,0,0,1,29222.0);
2915 DOS2DT(2,1,1980,0,0,0,1,29222.0);
2916 DOS2DT(31,12,1990,0,0,0,1,33238.0);
2917 DOS2DT(31,12,90,0,0,0,1,40543.0);
2918 DOS2DT(30,12,1899,0,0,0,1,46751.0);
2919 DOS2DT(1,1,100,0,0,0,1,43831.0);
2920 DOS2DT(31,12,9999,0,0,0,1,59901.0);
2921 DOS2DT(1,1,10000,0,0,0,1,59902.0);
2922 DOS2DT(1,1,-10000,0,0,0,1,48214.0);
2924 DOS2DT(30,12,1899,0,0,0,1,46751.0);
2925 DOS2DT(30,12,1899,0,0,1,1,46751.0);
2927 DOS2DT(1,1,1980,18,1,16,1,29221.75087962963);
2928 DOS2DT(1,300,1980,18,1,16,1,29556.75087962963);
2929 DOS2DT(300,1,1980,18,1,16,1,29232.75087962963);
2930 DOS2DT(0,1,1980,42,1,16,1,29220.4175462963);
2931 DOS2DT(1,1,1980,17,61,16,0,0.0);
2932 DOS2DT(1,1,1980,18,0,76,1,29221.75013888889);
2933 DOS2DT(1,-300,1980,18,1,16,1,29312.75087962963);
2934 DOS2DT(-300,1,1980,18,1,16,1,29240.75087962963);
2935 DOS2DT(3,1,1980,-30,1,16,1,29223.08421296296);
2936 DOS2DT(1,1,1980,20,-119,16,1,29221.83976851852);
2937 DOS2DT(1,1,1980,18,3,-104,1,29221.75236111111);
2938 DOS2DT(1,12001,-1020,18,1,16,1,55519.75087962963);
2939 DOS2DT(1,-23,1982,18,1,16,1,30195.75087962963);
2940 DOS2DT(-59,3,1980,18,1,16,1,29285.75087962963);
2941 DOS2DT(1,1,0,0,0,0,1,54058.0);
2942 DOS2DT(0,0,1980,0,0,0,1,29189.0);
2943 DOS2DT(0,1,1980,0,0,0,1,29220.0);
2944 DOS2DT(-1,1,1980,18,1,16,1,29251.75087962963);
2945 DOS2DT(1,1,-1,18,1,16,1,53693.75087962963);
2946 DOS2DT(1,-1,1980,18,1,16,0,0);
2949 static void test_dt2dos(int line, double dt, INT r, WORD d, WORD m, WORD y,
2950 WORD h, WORD mn, WORD s)
2952 unsigned short dosDate, dosTime, expDosDate, expDosTime;
2953 INT res;
2955 dosTime = dosDate = 0;
2956 expDosDate = MKDOSDATE(d,m,y);
2957 expDosTime = MKDOSTIME(h,mn,s);
2958 res = pVariantTimeToDosDateTime(dt, &dosDate, &dosTime);
2959 ok_(__FILE__,line)(r == res && (!r || (dosTime == expDosTime && dosDate == expDosDate)),
2960 "%g: expected %d,%d(%d/%d/%d),%d(%d:%d:%d) got %d,%d(%d/%d/%d),%d(%d:%d:%d)\n",
2961 dt, r, expDosDate, expDosDate & 0x1f,
2962 (expDosDate >> 5) & 0xf, 1980 + (expDosDate >> 9),
2963 expDosTime, expDosTime >> 11, (expDosTime >> 5) & 0x3f,
2964 (expDosTime & 0x1f),
2965 res, dosDate, dosDate & 0x1f, (dosDate >> 5) & 0xf,
2966 1980 + (dosDate >> 9), dosTime, dosTime >> 11,
2967 (dosTime >> 5) & 0x3f, (dosTime & 0x1f));
2969 #define DT2DOS(dt,r,d,m,y,h,mn,s) test_dt2dos(__LINE__,dt,r,d,m,y,h,mn,s)
2971 static void test_VariantTimeToDosDateTime(void)
2973 CHECKPTR(VariantTimeToDosDateTime);
2975 /* Date */
2976 DT2DOS(29221.0,1,1,1,1980,0,0,0); /* 1/1/1980 */
2977 DT2DOS(73050.0,1,31,12,2099,0,0,0); /* 31/12/2099 */
2978 DT2DOS(29220.0,0,0,0,0,0,0,0); /* 31/12/1979 - out of range */
2979 DT2DOS(73415.0,0,0,0,0,0,0,0); /* 31/12/2100 - out of range */
2981 /* Time */
2982 DT2DOS(29221.00032407407,1,1,1,1980,0,0,29); /* 1/1/1980 12:00:28 AM */
2983 DT2DOS(29221.00034722222,1,1,1,1980,0,0,31); /* 1/1/1980 12:00:30 AM */
2984 DT2DOS(29221.04097222222,1,1,1,1980,0,59,0); /* 1/1/1980 12:59:00 AM */
2985 DT2DOS(29221.95833333333,1,1,1,1980,23,0,0); /* 1/1/1980 11:00:00 PM */
2988 static HRESULT (WINAPI *pVarAbs)(LPVARIANT,LPVARIANT);
2990 #define VARABS(vt,val,rvt,rval) \
2991 V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
2992 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
2993 test_var_call1( __LINE__, pVarAbs, &v, &exp )
2995 static void test_VarAbs(void)
2997 static WCHAR szNum[] = {'-','1','.','1','\0' };
2998 char buff[8];
2999 HRESULT hres;
3000 VARIANT v, vDst, exp;
3001 size_t i;
3003 CHECKPTR(VarAbs);
3005 /* Test all possible V_VT values.
3007 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
3009 VARTYPE vt;
3011 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
3013 HRESULT hExpected = DISP_E_BADVARTYPE;
3015 SKIPTESTS(vt);
3017 memset(&v, 0, sizeof(v));
3018 V_VT(&v) = vt | ExtraFlags[i];
3019 V_VT(&vDst) = VT_EMPTY;
3021 hres = pVarAbs(&v,&vDst);
3022 if (ExtraFlags[i] & VT_ARRAY ||
3023 (!ExtraFlags[i] && (vt == VT_UNKNOWN || vt == VT_BSTR ||
3024 vt == VT_DISPATCH || vt == VT_ERROR || vt == VT_RECORD)))
3026 hExpected = DISP_E_TYPEMISMATCH;
3028 else if (ExtraFlags[i] || vt >= VT_CLSID || vt == VT_VARIANT)
3030 hExpected = DISP_E_BADVARTYPE;
3032 else if (IsValidVariantClearVT(vt, ExtraFlags[i]))
3033 hExpected = S_OK;
3035 /* Native always fails on some vartypes that should be valid. don't
3036 * check that Wine does the same; these are bugs in native.
3038 if (vt == VT_I8 || vt == VT_UI8 || vt == VT_INT || vt == VT_UINT ||
3039 vt == VT_I1 || vt == VT_UI2 || vt == VT_UI4)
3040 continue;
3041 ok(hres == hExpected, "VarAbs: expected 0x%X, got 0x%X for vt %d | 0x%X\n",
3042 hExpected, hres, vt, ExtraFlags[i]);
3046 /* BOOL->I2, BSTR->R8, all others remain the same */
3047 VARABS(BOOL,VARIANT_TRUE,I2,-VARIANT_TRUE);
3048 VARABS(BOOL,VARIANT_FALSE,I2,VARIANT_FALSE);
3049 VARABS(EMPTY,0,I2,0);
3050 VARABS(EMPTY,1,I2,0);
3051 VARABS(NULL,0,NULL,0);
3052 VARABS(NULL,1,NULL,0);
3053 VARABS(I2,1,I2,1);
3054 VARABS(I2,-1,I2,1);
3055 VARABS(I4,1,I4,1);
3056 VARABS(I4,-1,I4,1);
3057 VARABS(UI1,1,UI1,1);
3058 VARABS(R4,1,R4,1);
3059 VARABS(R4,-1,R4,1);
3060 VARABS(R8,1,R8,1);
3061 VARABS(R8,-1,R8,1);
3062 VARABS(DATE,1,DATE,1);
3063 VARABS(DATE,-1,DATE,1);
3064 V_VT(&v) = VT_CY;
3065 V_CY(&v).int64 = -10000;
3066 memset(&vDst,0,sizeof(vDst));
3067 hres = pVarAbs(&v,&vDst);
3068 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == 10000,
3069 "VarAbs(CY): expected 0x0 got 0x%X\n", hres);
3070 GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, ARRAY_SIZE(buff));
3071 if (buff[1])
3073 trace("Skipping VarAbs(BSTR) as decimal separator is '%s'\n", buff);
3074 return;
3075 } else {
3076 szNum[2] = buff[0];
3078 V_VT(&v) = VT_BSTR;
3079 V_BSTR(&v) = (BSTR)szNum;
3080 memset(&vDst,0,sizeof(vDst));
3081 hres = pVarAbs(&v,&vDst);
3082 ok(hres == S_OK && V_VT(&vDst) == VT_R8 && V_R8(&vDst) == 1.1,
3083 "VarAbs: expected 0x0,%d,%g, got 0x%X,%d,%g\n", VT_R8, 1.1, hres, V_VT(&vDst), V_R8(&vDst));
3086 static HRESULT (WINAPI *pVarNot)(LPVARIANT,LPVARIANT);
3088 #define VARNOT(vt,val,rvt,rval) \
3089 V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
3090 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
3091 test_var_call1( __LINE__, pVarNot, &v, &exp )
3093 static void test_VarNot(void)
3095 static const WCHAR szNum0[] = {'0','\0' };
3096 static const WCHAR szNum1[] = {'1','\0' };
3097 static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
3098 static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
3099 HRESULT hres;
3100 VARIANT v, exp, vDst;
3101 DECIMAL *pdec = &V_DECIMAL(&v);
3102 CY *pcy = &V_CY(&v);
3103 size_t i;
3105 CHECKPTR(VarNot);
3107 /* Test all possible V_VT values */
3108 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
3110 VARTYPE vt;
3112 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
3114 HRESULT hExpected = DISP_E_BADVARTYPE;
3116 SKIPTESTS(vt);
3118 memset(&v, 0, sizeof(v));
3119 V_VT(&v) = vt | ExtraFlags[i];
3120 V_VT(&vDst) = VT_EMPTY;
3122 switch (V_VT(&v))
3124 case VT_I1: case VT_UI1: case VT_I2: case VT_UI2:
3125 case VT_INT: case VT_UINT: case VT_I4: case VT_UI4:
3126 case VT_R4: case VT_R8:
3127 case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
3128 case VT_DATE: case VT_CY:
3129 hExpected = S_OK;
3130 break;
3131 case VT_I8: case VT_UI8:
3132 if (has_i8)
3133 hExpected = S_OK;
3134 break;
3135 case VT_RECORD:
3136 hExpected = DISP_E_TYPEMISMATCH;
3137 break;
3138 case VT_UNKNOWN: case VT_BSTR: case VT_DISPATCH: case VT_ERROR:
3139 hExpected = DISP_E_TYPEMISMATCH;
3140 break;
3141 default:
3142 if (IsValidVariantClearVT(vt, ExtraFlags[i]) && vt != VT_CLSID)
3143 hExpected = DISP_E_TYPEMISMATCH;
3144 break;
3147 hres = pVarNot(&v,&vDst);
3148 ok(hres == hExpected, "VarNot: expected 0x%X, got 0x%X vt %d|0x%X\n",
3149 hExpected, hres, vt, ExtraFlags[i]);
3152 /* Test the values returned by all cases that can succeed */
3153 VARNOT(EMPTY,0,I2,-1);
3154 VARNOT(EMPTY,1,I2,-1);
3155 VARNOT(NULL,0,NULL,0);
3156 VARNOT(NULL,1,NULL,0);
3157 VARNOT(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE);
3158 VARNOT(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE);
3159 VARNOT(I1,-1,I4,0);
3160 VARNOT(I1,0,I4,-1);
3161 VARNOT(I2,-1,I2,0);
3162 VARNOT(I2,0,I2,-1);
3163 VARNOT(I2,1,I2,-2);
3164 VARNOT(I4,1,I4,-2);
3165 VARNOT(I4,0,I4,-1);
3166 VARNOT(UI1,1,UI1,254);
3167 VARNOT(UI1,0,UI1,255);
3168 VARNOT(UI2,0,I4,-1);
3169 VARNOT(UI2,1,I4,-2);
3170 VARNOT(UI4,0,I4,-1);
3171 VARNOT(UI4,1,I4,-2);
3172 VARNOT(INT,0,I4,-1);
3173 VARNOT(INT,1,I4,-2);
3174 VARNOT(UINT,0,I4,-1);
3175 VARNOT(UINT,1,I4,-2);
3176 if (has_i8)
3178 VARNOT(I8,1,I8,-2);
3179 VARNOT(I8,0,I8,-1);
3180 VARNOT(UI8,0,I4,-1);
3181 VARNOT(UI8,1,I4,-2);
3183 VARNOT(R4,1,I4,-2);
3184 VARNOT(R4,0,I4,-1);
3185 VARNOT(R8,1,I4,-2);
3186 VARNOT(R8,0,I4,-1);
3187 VARNOT(DATE,1,I4,-2);
3188 VARNOT(DATE,0,I4,-1);
3189 VARNOT(BSTR,(BSTR)szNum0,I4,-1);
3190 ok(V_VT(&v) == VT_BSTR && V_BSTR(&v) == szNum0, "VarNot(0): changed input\n");
3191 VARNOT(BSTR,(BSTR)szNum1,I4,-2);
3192 ok(V_VT(&v) == VT_BSTR && V_BSTR(&v) == szNum1, "VarNot(1): changed input\n");
3193 VARNOT(BSTR, (BSTR)szTrue, BOOL, VARIANT_FALSE);
3194 VARNOT(BSTR, (BSTR)szFalse, BOOL, VARIANT_TRUE);
3196 S(U(*pdec)).sign = DECIMAL_NEG;
3197 S(U(*pdec)).scale = 0;
3198 pdec->Hi32 = 0;
3199 S1(U1(*pdec)).Mid32 = 0;
3200 S1(U1(*pdec)).Lo32 = 1;
3201 VARNOT(DECIMAL,*pdec,I4,0);
3203 pcy->int64 = 10000;
3204 VARNOT(CY,*pcy,I4,-2);
3206 pcy->int64 = 0;
3207 VARNOT(CY,*pcy,I4,-1);
3209 pcy->int64 = -1;
3210 VARNOT(CY,*pcy,I4,-1);
3213 static HRESULT (WINAPI *pVarSub)(LPVARIANT,LPVARIANT,LPVARIANT);
3215 #define VARSUB(vt1,val1,vt2,val2,rvt,rval) \
3216 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
3217 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
3218 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
3219 test_var_call2( __LINE__, pVarSub, &left, &right, &exp )
3221 static void test_VarSub(void)
3223 VARIANT left, right, exp, result, cy, dec;
3224 VARTYPE i;
3225 BSTR lbstr, rbstr;
3226 HRESULT hres, expectedhres;
3227 double r;
3229 CHECKPTR(VarSub);
3231 lbstr = SysAllocString(sz12);
3232 rbstr = SysAllocString(sz12);
3234 VariantInit(&left);
3235 VariantInit(&right);
3236 VariantInit(&result);
3238 /* Test all possible flag/vt combinations & the resulting vt type */
3239 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
3242 VARTYPE leftvt, rightvt, resvt;
3244 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
3247 SKIPTESTS(leftvt);
3249 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
3252 SKIPTESTS(rightvt);
3253 expectedhres = S_OK;
3255 memset(&left, 0, sizeof(left));
3256 memset(&right, 0, sizeof(right));
3257 V_VT(&left) = leftvt | ExtraFlags[i];
3258 if (leftvt == VT_BSTR)
3259 V_BSTR(&left) = lbstr;
3260 V_VT(&right) = rightvt | ExtraFlags[i];
3261 if (rightvt == VT_BSTR)
3262 V_BSTR(&right) = rbstr;
3263 V_VT(&result) = VT_EMPTY;
3265 /* All extra flags produce errors */
3266 if (ExtraFlags[i] == (VT_VECTOR|VT_BYREF|VT_RESERVED) ||
3267 ExtraFlags[i] == (VT_VECTOR|VT_RESERVED) ||
3268 ExtraFlags[i] == (VT_VECTOR|VT_BYREF) ||
3269 ExtraFlags[i] == (VT_BYREF|VT_RESERVED) ||
3270 ExtraFlags[i] == VT_VECTOR ||
3271 ExtraFlags[i] == VT_BYREF ||
3272 ExtraFlags[i] == VT_RESERVED)
3274 expectedhres = DISP_E_BADVARTYPE;
3275 resvt = VT_EMPTY;
3277 else if (ExtraFlags[i] >= VT_ARRAY)
3279 expectedhres = DISP_E_TYPEMISMATCH;
3280 resvt = VT_EMPTY;
3282 /* Native VarSub cannot handle: VT_I1, VT_UI2, VT_UI4,
3283 VT_INT, VT_UINT and VT_UI8. Tested with WinXP */
3284 else if (!IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
3285 !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
3286 leftvt == VT_CLSID || rightvt == VT_CLSID ||
3287 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
3288 leftvt == VT_I1 || rightvt == VT_I1 ||
3289 leftvt == VT_UI2 || rightvt == VT_UI2 ||
3290 leftvt == VT_UI4 || rightvt == VT_UI4 ||
3291 leftvt == VT_UI8 || rightvt == VT_UI8 ||
3292 leftvt == VT_INT || rightvt == VT_INT ||
3293 leftvt == VT_UINT || rightvt == VT_UINT ||
3294 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN ||
3295 leftvt == VT_RECORD || rightvt == VT_RECORD)
3297 if (leftvt == VT_RECORD && rightvt == VT_I8)
3299 if (has_i8)
3300 expectedhres = DISP_E_TYPEMISMATCH;
3301 else
3302 expectedhres = DISP_E_BADVARTYPE;
3304 else if (leftvt < VT_UI1 && rightvt == VT_RECORD)
3305 expectedhres = DISP_E_TYPEMISMATCH;
3306 else if (leftvt >= VT_UI1 && rightvt == VT_RECORD)
3307 expectedhres = DISP_E_TYPEMISMATCH;
3308 else if (leftvt == VT_RECORD && rightvt <= VT_UI1)
3309 expectedhres = DISP_E_TYPEMISMATCH;
3310 else if (leftvt == VT_RECORD && rightvt > VT_UI1)
3311 expectedhres = DISP_E_BADVARTYPE;
3312 else
3313 expectedhres = DISP_E_BADVARTYPE;
3314 resvt = VT_EMPTY;
3316 else if ((leftvt == VT_NULL && rightvt == VT_DISPATCH) ||
3317 (leftvt == VT_DISPATCH && rightvt == VT_NULL))
3318 resvt = VT_NULL;
3319 else if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
3320 leftvt == VT_ERROR || rightvt == VT_ERROR)
3322 resvt = VT_EMPTY;
3323 expectedhres = DISP_E_TYPEMISMATCH;
3325 else if (leftvt == VT_NULL || rightvt == VT_NULL)
3326 resvt = VT_NULL;
3327 else if ((leftvt == VT_EMPTY && rightvt == VT_BSTR) ||
3328 (leftvt == VT_DATE && rightvt == VT_DATE) ||
3329 (leftvt == VT_BSTR && rightvt == VT_EMPTY) ||
3330 (leftvt == VT_BSTR && rightvt == VT_BSTR))
3331 resvt = VT_R8;
3332 else if (leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
3333 resvt = VT_DECIMAL;
3334 else if (leftvt == VT_DATE || rightvt == VT_DATE)
3335 resvt = VT_DATE;
3336 else if (leftvt == VT_CY || rightvt == VT_CY)
3337 resvt = VT_CY;
3338 else if (leftvt == VT_R8 || rightvt == VT_R8)
3339 resvt = VT_R8;
3340 else if (leftvt == VT_BSTR || rightvt == VT_BSTR) {
3341 resvt = VT_R8;
3342 } else if (leftvt == VT_R4 || rightvt == VT_R4) {
3343 if (leftvt == VT_I4 || rightvt == VT_I4 ||
3344 leftvt == VT_I8 || rightvt == VT_I8)
3345 resvt = VT_R8;
3346 else
3347 resvt = VT_R4;
3349 else if (leftvt == VT_I8 || rightvt == VT_I8)
3350 resvt = VT_I8;
3351 else if (leftvt == VT_I4 || rightvt == VT_I4)
3352 resvt = VT_I4;
3353 else if (leftvt == VT_I2 || rightvt == VT_I2 ||
3354 leftvt == VT_BOOL || rightvt == VT_BOOL ||
3355 (leftvt == VT_EMPTY && rightvt == VT_EMPTY))
3356 resvt = VT_I2;
3357 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
3358 resvt = VT_UI1;
3359 else
3361 resvt = VT_EMPTY;
3362 expectedhres = DISP_E_TYPEMISMATCH;
3365 hres = pVarSub(&left, &right, &result);
3367 ok(hres == expectedhres && V_VT(&result) == resvt,
3368 "VarSub: %d|0x%X, %d|0x%X: Expected failure 0x%X, "
3369 "got 0x%X, expected vt %d got vt %d\n",
3370 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i],
3371 expectedhres, hres, resvt, V_VT(&result));
3376 /* Test returned values */
3377 VARSUB(I4,4,I4,2,I4,2);
3378 VARSUB(I2,4,I2,2,I2,2);
3379 VARSUB(I2,-13,I4,5,I4,-18);
3380 VARSUB(I4,-13,I4,5,I4,-18);
3381 VARSUB(I2,7,R4,0.5f,R4,6.5f);
3382 VARSUB(R4,0.5f,I4,5,R8,-4.5);
3383 VARSUB(R8,7.1,BOOL,0,R8,7.1);
3384 VARSUB(BSTR,lbstr,I2,4,R8,8);
3385 VARSUB(BSTR,lbstr,BOOL,1,R8,11);
3386 VARSUB(BSTR,lbstr,R4,0.1f,R8,11.9);
3387 VARSUB(R4,0.2f,BSTR,rbstr,R8,-11.8);
3388 VARSUB(DATE,2.25,I4,7,DATE,-4.75);
3389 VARSUB(DATE,1.25,R4,-1.7f,DATE,2.95);
3391 VARSUB(UI1, UI1_MAX, UI1, UI1_MAX, UI1, 0);
3392 VARSUB(I2, I2_MAX, I2, I2_MAX, I2, 0);
3393 VARSUB(I2, I2_MIN, I2, I2_MIN, I2, 0);
3394 VARSUB(I4, I4_MAX, I4, I4_MAX, I4, 0);
3395 VARSUB(I4, I4_MIN, I4, I4_MIN, I4, 0);
3396 VARSUB(R4, R4_MAX, R4, R4_MAX, R4, 0.0f);
3397 VARSUB(R4, R4_MAX, R4, R4_MIN, R4, R4_MAX - R4_MIN);
3398 VARSUB(R4, R4_MIN, R4, R4_MIN, R4, 0.0f);
3399 VARSUB(R8, R8_MAX, R8, R8_MIN, R8, R8_MAX - R8_MIN);
3400 VARSUB(R8, R8_MIN, R8, R8_MIN, R8, 0.0);
3402 /* Manually test BSTR + BSTR */
3403 V_VT(&left) = VT_BSTR;
3404 V_BSTR(&left) = lbstr;
3405 V_VT(&right) = VT_BSTR;
3406 V_BSTR(&right) = rbstr;
3407 hres = pVarSub(&left, &right, &result);
3408 ok(hres == S_OK && V_VT(&result) == VT_R8,
3409 "VarSub: expected coerced type VT_R8, got %s!\n", vtstr(V_VT(&result)));
3410 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 0.0),
3411 "VarSub: BSTR + BSTR, expected %f got %f\n", 0.0, V_R8(&result));
3413 /* Manually test some VT_CY and VT_DECIMAL variants */
3414 V_VT(&cy) = VT_CY;
3415 hres = VarCyFromI4(4711, &V_CY(&cy));
3416 ok(hres == S_OK, "VarCyFromI4 failed!\n");
3417 V_VT(&dec) = VT_DECIMAL;
3418 hres = VarDecFromR8(-4.2, &V_DECIMAL(&dec));
3419 ok(hres == S_OK, "VarDecFromR4 failed!\n");
3420 memset(&left, 0, sizeof(left));
3421 memset(&right, 0, sizeof(right));
3422 V_VT(&left) = VT_I4;
3423 V_I4(&left) = -11;
3424 V_VT(&right) = VT_UI1;
3425 V_UI1(&right) = 9;
3427 hres = pVarSub(&cy, &right, &result);
3428 ok(hres == S_OK && V_VT(&result) == VT_CY,
3429 "VarSub: expected coerced type VT_CY, got %s!\n", vtstr(V_VT(&result)));
3430 hres = VarR8FromCy(V_CY(&result), &r);
3431 ok(hres == S_OK && EQ_DOUBLE(r, 4702.0), "VarSub: CY value %f, expected %f\n", r, 4720.0);
3433 hres = pVarSub(&left, &dec, &result);
3434 ok(hres == S_OK && V_VT(&result) == VT_DECIMAL,
3435 "VarSub: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
3436 hres = VarR8FromDec(&V_DECIMAL(&result), &r);
3437 ok(hres == S_OK && EQ_DOUBLE(r, -6.8), "VarSub: DECIMAL value %f, expected %f\n", r, -6.8);
3439 SysFreeString(lbstr);
3440 SysFreeString(rbstr);
3443 static HRESULT (WINAPI *pVarMod)(LPVARIANT,LPVARIANT,LPVARIANT);
3445 static void test_Mod( int line, VARIANT *left, VARIANT *right, VARIANT *expected, HRESULT expres )
3447 VARIANT result;
3448 HRESULT hres;
3450 memset( &result, 0, sizeof(result) );
3451 hres = pVarMod( left, right, &result );
3452 ok_(__FILE__,line)( hres == expres, "wrong result %x/%x\n", hres, expres );
3453 if (hres == S_OK)
3454 ok_(__FILE__,line)( is_expected_variant( &result, expected ),
3455 "got %s expected %s\n", variantstr(&result), variantstr(expected) );
3458 #define VARMOD(vt1,vt2,val1,val2,rvt,rval) \
3459 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
3460 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
3461 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
3462 test_var_call2( __LINE__, pVarMod, &left, &right, &exp )
3464 #define VARMOD2(vt1,vt2,val1,val2,rvt,rval,hexpected) \
3465 V_VT(&left) = VT_##vt1; V_I4(&left) = val1; \
3466 V_VT(&right) = VT_##vt2; V_I4(&right) = val2; \
3467 V_VT(&exp) = VT_##rvt; V_I4(&exp) = rval; \
3468 test_Mod( __LINE__, &left, &right, &exp, hexpected )
3470 static void test_VarMod(void)
3472 VARIANT v1, v2, vDst, left, right, exp;
3473 HRESULT hres;
3474 HRESULT hexpected = 0;
3475 static const WCHAR szNum0[] = {'1','2','5','\0'};
3476 static const WCHAR szNum1[] = {'1','0','\0'};
3477 int l, r;
3478 BOOL lFound, rFound;
3479 BOOL lValid;
3480 BSTR strNum0, strNum1;
3482 CHECKPTR(VarMod);
3484 VARMOD(I1,BOOL,100,10,I4,0);
3485 VARMOD(I1,I1,100,10,I4,0);
3486 VARMOD(I1,UI1,100,10,I4,0);
3487 VARMOD(I1,I2,100,10,I4,0);
3488 VARMOD(I1,UI2,100,10,I4,0);
3489 VARMOD(I1,I4,100,10,I4,0);
3490 VARMOD(I1,UI4,100,10,I4,0);
3491 VARMOD(I1,R4,100,10,I4,0);
3492 VARMOD(I1,R8,100,10,I4,0);
3494 VARMOD(UI1,BOOL,100,10,I2,0);
3495 VARMOD(UI1,I1,100,10,I4,0);
3496 VARMOD(UI1,UI1,100,10,UI1,0);
3497 VARMOD(UI1,I2,100,10,I2,0);
3498 VARMOD(UI1,UI2,100,10,I4,0);
3499 VARMOD(UI1,I4,100,10,I4,0);
3500 VARMOD(UI1,UI4,100,10,I4,0);
3501 VARMOD(UI1,R4,100,10,I4,0);
3502 VARMOD(UI1,R8,100,10,I4,0);
3504 VARMOD(I2,BOOL,100,10,I2,0);
3505 VARMOD(I2,I1,100,10,I4,0);
3506 VARMOD(I2,UI1,100,10,I2,0);
3507 VARMOD(I2,I2,100,10,I2,0);
3508 VARMOD(I2,UI2,100,10,I4,0);
3509 VARMOD(I2,I4,100,10,I4,0);
3510 VARMOD(I2,UI4,100,10,I4,0);
3511 VARMOD(I2,R4,100,10,I4,0);
3512 VARMOD(I2,R8,100,10,I4,0);
3514 VARMOD(I4,BOOL,100,10,I4,0);
3515 VARMOD(I4,I1,100,10,I4,0);
3516 VARMOD(I4,UI1,100,10,I4,0);
3517 VARMOD(I4,I2,100,10,I4,0);
3518 VARMOD(I4,UI2,100,10,I4,0);
3519 VARMOD(I4,I4,100,10,I4,0);
3520 VARMOD(I4,UI4,100,10,I4,0);
3521 VARMOD(I4,R4,100,10,I4,0);
3522 VARMOD(I4,R8,100,10,I4,0);
3523 VARMOD(UI4,BOOL,100,10,I4,0);
3524 VARMOD(UI4,I1,100,10,I4,0);
3525 VARMOD(UI4,UI1,100,10,I4,0);
3526 VARMOD(UI4,I2,100,10,I4,0);
3527 VARMOD(UI4,UI2,100,10,I4,0);
3528 VARMOD(UI4,I4,100,10,I4,0);
3529 VARMOD(UI4,UI4,100,10,I4,0);
3530 VARMOD(UI4,R4,100,10,I4,0);
3531 VARMOD(UI4,R8,100,10,I4,0);
3532 VARMOD(R4,BOOL,100,10,I4,0);
3533 VARMOD(R4,I1,100,10,I4,0);
3534 VARMOD(R4,UI1,100,10,I4,0);
3535 VARMOD(R4,I2,100,10,I4,0);
3536 VARMOD(R4,UI2,100,10,I4,0);
3537 VARMOD(R4,I4,100,10,I4,0);
3538 VARMOD(R4,UI4,100,10,I4,0);
3539 VARMOD(R4,R4,100,10,I4,0);
3540 VARMOD(R4,R8,100,10,I4,0);
3541 VARMOD(R8,BOOL,100,10,I4,0);
3542 VARMOD(R8,I1,100,10,I4,0);
3543 VARMOD(R8,UI1,100,10,I4,0);
3544 VARMOD(R8,I2,100,10,I4,0);
3545 VARMOD(R8,UI2,100,10,I4,0);
3546 VARMOD(R8,I4,100,10,I4,0);
3547 VARMOD(R8,UI4,100,10,I4,0);
3548 VARMOD(R8,R4,100,10,I4,0);
3549 VARMOD(R8,R8,100,10,I4,0);
3551 VARMOD(INT,INT,100,10,I4,0);
3552 VARMOD(INT,UINT,100,10,I4,0);
3554 VARMOD(BOOL,BOOL,100,10,I2,0);
3555 VARMOD(BOOL,I1,100,10,I4,0);
3556 VARMOD(BOOL,UI1,100,10,I2,0);
3557 VARMOD(BOOL,I2,100,10,I2,0);
3558 VARMOD(BOOL,UI2,100,10,I4,0);
3559 VARMOD(BOOL,I4,100,10,I4,0);
3560 VARMOD(BOOL,UI4,100,10,I4,0);
3561 VARMOD(BOOL,R4,100,10,I4,0);
3562 VARMOD(BOOL,R8,100,10,I4,0);
3563 VARMOD(BOOL,DATE,100,10,I4,0);
3565 VARMOD(DATE,BOOL,100,10,I4,0);
3566 VARMOD(DATE,I1,100,10,I4,0);
3567 VARMOD(DATE,UI1,100,10,I4,0);
3568 VARMOD(DATE,I2,100,10,I4,0);
3569 VARMOD(DATE,UI2,100,10,I4,0);
3570 VARMOD(DATE,I4,100,10,I4,0);
3571 VARMOD(DATE,UI4,100,10,I4,0);
3572 VARMOD(DATE,R4,100,10,I4,0);
3573 VARMOD(DATE,R8,100,10,I4,0);
3574 VARMOD(DATE,DATE,100,10,I4,0);
3576 strNum0 = SysAllocString(szNum0);
3577 strNum1 = SysAllocString(szNum1);
3578 VARMOD(BSTR,BSTR,strNum0,strNum1,I4,5);
3579 VARMOD(BSTR,I1,strNum0,10,I4,5);
3580 VARMOD(BSTR,I2,strNum0,10,I4,5);
3581 VARMOD(BSTR,I4,strNum0,10,I4,5);
3582 VARMOD(BSTR,R4,strNum0,10,I4,5);
3583 VARMOD(BSTR,R8,strNum0,10,I4,5);
3584 VARMOD(I4,BSTR,125,strNum1,I4,5);
3586 if (has_i8)
3588 VARMOD(BOOL,I8,100,10,I8,0);
3589 VARMOD(I1,I8,100,10,I8,0);
3590 VARMOD(UI1,I8,100,10,I8,0);
3591 VARMOD(I2,I8,100,10,I8,0);
3592 VARMOD(I4,I8,100,10,I8,0);
3593 VARMOD(UI4,I8,100,10,I8,0);
3594 VARMOD(R4,I8,100,10,I8,0);
3595 VARMOD(R8,I8,100,10,I8,0);
3596 VARMOD(DATE,I8,100,10,I8,0);
3598 VARMOD(I8,BOOL,100,10,I8,0);
3599 VARMOD(I8,I1,100,10,I8,0);
3600 VARMOD(I8,UI1,100,10,I8,0);
3601 VARMOD(I8,I2,100,10,I8,0);
3602 VARMOD(I8,UI2,100,10,I8,0);
3603 VARMOD(I8,I4,100,10,I8,0);
3604 VARMOD(I8,UI4,100,10,I8,0);
3605 VARMOD(I8,R4,100,10,I8,0);
3606 VARMOD(I8,R8,100,10,I8,0);
3607 VARMOD(I8,I8,100,10,I8,0);
3609 VARMOD(BSTR,I8,strNum0,10,I8,5);
3612 /* test all combinations of types */
3613 for(l = 0; l < VT_BSTR_BLOB; l++)
3615 SKIPTESTS(l);
3617 for(r = 0; r < VT_BSTR_BLOB; r++)
3619 SKIPTESTS(r);
3621 if(l == VT_BSTR) continue;
3622 if(l == VT_DISPATCH) continue;
3623 if(r == VT_BSTR) continue;
3624 if(r == VT_DISPATCH) continue;
3626 lFound = TRUE;
3627 lValid = TRUE;
3628 switch(l)
3630 case VT_EMPTY:
3631 case VT_NULL:
3632 case VT_I1:
3633 case VT_UI1:
3634 case VT_I2:
3635 case VT_UI2:
3636 case VT_I4:
3637 case VT_I8:
3638 case VT_UI4:
3639 case VT_UI8:
3640 case VT_INT:
3641 case VT_UINT:
3642 case VT_R4:
3643 case VT_R8:
3644 case VT_BOOL:
3645 case VT_DATE:
3646 case VT_CY:
3647 case VT_DECIMAL:
3648 hexpected = S_OK;
3649 break;
3650 case VT_ERROR:
3651 case VT_VARIANT:
3652 case VT_UNKNOWN:
3653 case VT_RECORD:
3654 lValid = FALSE;
3655 break;
3656 default:
3657 lFound = FALSE;
3658 hexpected = DISP_E_BADVARTYPE;
3659 break;
3662 rFound = TRUE;
3663 switch(r)
3665 case VT_EMPTY:
3666 case VT_NULL:
3667 case VT_I1:
3668 case VT_UI1:
3669 case VT_I2:
3670 case VT_UI2:
3671 case VT_I4:
3672 case VT_I8:
3673 case VT_UI4:
3674 case VT_UI8:
3675 case VT_INT:
3676 case VT_UINT:
3677 case VT_R4:
3678 case VT_R8:
3679 case VT_BOOL:
3680 case VT_DATE:
3681 case VT_DECIMAL:
3682 case VT_CY:
3683 hexpected = S_OK;
3684 break;
3685 case VT_ERROR:
3686 case VT_VARIANT:
3687 case VT_UNKNOWN:
3688 case VT_RECORD:
3689 break;
3690 default:
3691 rFound = FALSE;
3692 break;
3695 if(((l == VT_I8) && (r == VT_INT)) || ((l == VT_INT) && (r == VT_I8)))
3697 hexpected = DISP_E_TYPEMISMATCH;
3698 } else if((l == VT_EMPTY) && (r == VT_NULL))
3700 hexpected = S_OK;
3701 } else if((l == VT_NULL) && (r == VT_EMPTY))
3703 hexpected = S_OK;
3704 } else if((l == VT_EMPTY) && (r == VT_CY))
3706 hexpected = S_OK;
3707 } else if((l == VT_EMPTY) && (r == VT_RECORD))
3709 hexpected = DISP_E_TYPEMISMATCH;
3710 } else if((r == VT_EMPTY) && lFound && lValid)
3712 hexpected = DISP_E_DIVBYZERO;
3713 } else if((l == VT_ERROR) || ((r == VT_ERROR) && lFound && lValid))
3715 hexpected = DISP_E_TYPEMISMATCH;
3716 } else if((l == VT_NULL) && (r == VT_NULL))
3718 hexpected = S_OK;
3719 } else if((l == VT_VARIANT) || ((r == VT_VARIANT) && lFound && lValid))
3721 hexpected = DISP_E_TYPEMISMATCH;
3722 } else if((l == VT_NULL) && (r == VT_RECORD))
3724 hexpected = DISP_E_TYPEMISMATCH;
3725 } else if((l == VT_I8) && (r == VT_DECIMAL))
3727 hexpected = S_OK;
3728 } else if((l == VT_DECIMAL) && (r == VT_I8))
3730 hexpected = S_OK;
3731 } else if((l == VT_UNKNOWN) || ((r == VT_UNKNOWN) && lFound && lValid))
3733 hexpected = DISP_E_TYPEMISMATCH;
3734 } else if((l == VT_NULL) && rFound)
3736 hexpected = S_OK;
3737 } else if(l == VT_RECORD)
3739 hexpected = DISP_E_TYPEMISMATCH;
3740 } else if((r == VT_RECORD) && lValid && lFound)
3742 hexpected = DISP_E_TYPEMISMATCH;
3743 } else if((l == VT_EMPTY) && (r == VT_EMPTY))
3745 hexpected = DISP_E_DIVBYZERO;
3746 } else if((l == VT_CY) && !rFound)
3748 hexpected = DISP_E_BADVARTYPE;
3749 } else if(lFound && !rFound)
3751 hexpected = DISP_E_BADVARTYPE;
3752 } else if(!lFound && rFound)
3754 hexpected = DISP_E_BADVARTYPE;
3755 } else if((r == VT_NULL) && lFound && lValid)
3757 hexpected = S_OK;
3758 } else if((l == VT_NULL) || (r == VT_NULL))
3760 hexpected = DISP_E_BADVARTYPE;
3761 } else if((l == VT_VARIANT) || (r == VT_VARIANT))
3763 hexpected = DISP_E_BADVARTYPE;
3764 } else if(!lFound && !rFound)
3766 hexpected = DISP_E_BADVARTYPE;
3769 V_VT(&v1) = l;
3770 V_VT(&v2) = r;
3772 if(l == VT_CY)
3773 V_CY(&v1).int64 = 1000000;
3774 else if(l == VT_R4)
3775 V_R4(&v1) = 100;
3776 else if(l == VT_R8)
3777 V_R8(&v1) = 100;
3778 else if(l == VT_UI8)
3779 V_UI8(&v1) = 100;
3780 else if(l == VT_I8)
3781 V_I8(&v1) = 100;
3782 else if(l == VT_DATE)
3783 V_DATE(&v1) = 1000;
3784 else if (l == VT_DECIMAL)
3786 V_DECIMAL(&v1).Hi32 = 0;
3787 U1(V_DECIMAL(&v1)).Lo64 = 100;
3788 U(V_DECIMAL(&v1)).signscale = 0;
3790 else
3791 V_I4(&v1) = 10000;
3793 if(r == VT_CY)
3794 V_CY(&v2).int64 = 10000;
3795 else if(r == VT_R4)
3796 V_R4(&v2) = 100;
3797 else if(r == VT_R8)
3798 V_R8(&v2) = 100;
3799 else if(r == VT_UI8)
3800 V_UI8(&v2) = 100;
3801 else if(r == VT_I8)
3802 V_I8(&v2) = 100;
3803 else if(r == VT_DATE)
3804 V_DATE(&v2) = 1000;
3805 else if (r == VT_DECIMAL)
3807 V_DECIMAL(&v2).Hi32 = 0;
3808 U1(V_DECIMAL(&v2)).Lo64 = 100;
3809 U(V_DECIMAL(&v2)).signscale = 0;
3811 else
3812 V_I4(&v2) = 10000;
3814 if ((l != VT_I8 && l != VT_UI8 && r != VT_I8 && r != VT_UI8) || has_i8)
3816 hres = pVarMod(&v1,&v2,&vDst);
3817 ok(hres == hexpected,
3818 "VarMod: expected 0x%x, got 0x%X for l type of %d, r type of %d,\n", hexpected, hres, l, r);
3824 /****************************/
3825 /* test some bad parameters */
3826 VARMOD(I4,I4,-1,-1,I4,0);
3828 /* test modulus with zero */
3829 VARMOD2(I4,I4,100,0,EMPTY,0,DISP_E_DIVBYZERO);
3831 VARMOD(I4,I4,0,10,I4,0); /* test 0 mod 10 */
3833 /* right parameter is type empty */
3834 VARMOD2(I4,EMPTY,100,10,EMPTY,0,DISP_E_DIVBYZERO);
3836 /* left parameter is type empty */
3837 VARMOD2(EMPTY,I4,100,10,I4,0,S_OK);
3839 /* mod with a null left value */
3840 VARMOD2(NULL,I4,125,10,NULL,0,S_OK);
3842 /* mod with a null right value */
3843 VARMOD2(I4,NULL,100,10,NULL,0,S_OK);
3845 /* void left value */
3846 VARMOD2(VOID,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3848 /* void right value */
3849 VARMOD2(I4,VOID,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3851 /* null left value, void right value */
3852 VARMOD2(NULL,VOID,100,10,EMPTY, 0, DISP_E_BADVARTYPE);
3854 /* void left value, null right value */
3855 VARMOD2(VOID,NULL,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3857 /* some currencies */
3858 V_VT(&v1) = VT_CY;
3859 V_VT(&v2) = VT_CY;
3860 V_CY(&v1).int64 = 100000;
3861 V_CY(&v2).int64 = 100000;
3862 hres = pVarMod(&v1,&v2,&vDst);
3863 ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == 0,
3864 "VarMod: expected 0x%x,%d,%d, got 0x%X,%d,%d\n", S_OK, VT_I4, 0, hres, V_VT(&vDst), V_I4(&vDst));
3866 V_VT(&v1) = VT_I4;
3867 V_VT(&v2) = VT_CY;
3868 V_I4(&v1) = 100;
3869 V_CY(&v2).int64 = 100000;
3870 hres = pVarMod(&v1,&v2,&vDst);
3871 ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == 0,
3872 "VarMod: expected 0x%x,%d,%d, got 0x%X,%d,%d\n", S_OK, VT_I4, 0, hres, V_VT(&vDst), V_I4(&vDst));
3874 /* some decimals */
3875 V_VT(&v1) = VT_DECIMAL;
3876 V_VT(&v2) = VT_DECIMAL;
3877 VarDecFromI4(100, &V_DECIMAL(&v1));
3878 VarDecFromI4(10, &V_DECIMAL(&v2));
3879 hres = pVarMod(&v1,&v2,&vDst);
3880 ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == 0,
3881 "VarMod: expected 0x%x,%d,%d, got 0x%X,%d,%d\n", S_OK, VT_I4, 0, hres, V_VT(&vDst), V_I4(&vDst));
3883 V_VT(&v1) = VT_I4;
3884 V_VT(&v2) = VT_DECIMAL;
3885 V_I4(&v1) = 100;
3886 VarDecFromI4(10, &V_DECIMAL(&v2));
3887 hres = pVarMod(&v1,&v2,&vDst);
3888 ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == 0,
3889 "VarMod: expected 0x%x,%d,%d, got 0x%X,%d,%d\n", S_OK, VT_I4, 0, hres, V_VT(&vDst), V_I4(&vDst));
3891 VARMOD2(UINT,I4,100,10,I4,0,S_OK);
3893 /* test that an error results in the type of the result changing but not its value */
3894 V_VT(&v1) = VT_UNKNOWN;
3895 V_VT(&v2) = VT_EMPTY;
3896 V_I4(&v1) = 100;
3897 V_CY(&v2).int64 = 100000;
3898 V_VT(&vDst) = VT_I4;
3899 V_I4(&vDst) = 1231;
3900 hres = pVarMod(&v1,&v2,&vDst);
3901 ok(hres == DISP_E_TYPEMISMATCH && V_VT(&vDst) == VT_EMPTY && V_I4(&vDst) == 1231,
3902 "VarMod: expected 0x%x,%d,%d, got 0x%X,%d,%d\n", DISP_E_TYPEMISMATCH, VT_EMPTY, 1231, hres, V_VT(&vDst), V_I4(&vDst));
3905 /* test some invalid types */
3906 /*TODO: not testing VT_DISPATCH */
3907 if (has_i8)
3909 VARMOD2(I8,INT,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
3911 VARMOD2(ERROR,I4,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
3912 VARMOD2(VARIANT,I4,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
3913 VARMOD2(UNKNOWN,I4,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
3914 VARMOD2(VOID,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3915 VARMOD2(HRESULT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3916 VARMOD2(PTR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3917 VARMOD2(SAFEARRAY,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3918 VARMOD2(CARRAY,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3919 VARMOD2(USERDEFINED,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3920 VARMOD2(LPSTR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3921 VARMOD2(LPWSTR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3922 VARMOD2(RECORD,I4,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
3923 VARMOD2(FILETIME,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3924 VARMOD2(BLOB,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3925 VARMOD2(STREAM,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3926 VARMOD2(STORAGE,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3927 VARMOD2(STREAMED_OBJECT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3928 VARMOD2(STORED_OBJECT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3929 VARMOD2(BLOB_OBJECT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3930 VARMOD2(CF,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3931 VARMOD2(CLSID,CLSID,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3932 VARMOD2(VECTOR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3933 VARMOD2(ARRAY,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3934 VARMOD2(BYREF,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3936 /* test some more invalid types */
3937 V_VT(&v1) = 456;
3938 V_VT(&v2) = 234;
3939 V_I4(&v1) = 100;
3940 V_I4(&v2)= 10;
3941 hres = pVarMod(&v1,&v2,&vDst);
3942 ok(hres == DISP_E_BADVARTYPE && V_VT(&vDst) == VT_EMPTY,
3943 "VarMod: expected 0x%x,%d, got 0x%X,%d\n", DISP_E_BADVARTYPE, VT_EMPTY, hres, V_VT(&vDst));
3945 SysFreeString(strNum0);
3946 SysFreeString(strNum1);
3949 static HRESULT (WINAPI *pVarFix)(LPVARIANT,LPVARIANT);
3951 #define VARFIX(vt,val,rvt,rval) \
3952 V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
3953 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
3954 test_var_call1( __LINE__, pVarFix, &v, &exp )
3956 static void test_VarFix(void)
3958 static const WCHAR szNumMinus1[] = {'-','1','\0' };
3959 HRESULT hres;
3960 VARIANT v, exp, vDst;
3961 DECIMAL *pdec = &V_DECIMAL(&v);
3962 CY *pcy = &V_CY(&v);
3963 size_t i;
3965 CHECKPTR(VarFix);
3967 /* Test all possible V_VT values */
3968 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
3970 VARTYPE vt;
3972 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
3974 BOOL bFail = TRUE;
3976 SKIPTESTS(vt);
3978 memset(&v, 0, sizeof(v));
3979 V_VT(&v) = vt | ExtraFlags[i];
3980 V_VT(&vDst) = VT_EMPTY;
3982 switch (V_VT(&v))
3984 case VT_UI1: case VT_I2: case VT_I4: case VT_R4: case VT_R8:
3985 case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
3986 case VT_DATE: case VT_CY:
3987 bFail = FALSE;
3988 break;
3989 case VT_I8:
3990 if (has_i8)
3991 bFail = FALSE;
3992 break;
3995 hres = pVarFix(&v,&vDst);
3996 if (bFail)
3997 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
3998 "VarFix: expected failure, got 0x%X vt %d|0x%X\n",
3999 hres, vt, ExtraFlags[i]);
4000 else
4001 ok(hres == S_OK, "VarFix: expected S_OK, got 0x%X vt %d|0x%X\n",
4002 hres, vt, ExtraFlags[i]);
4006 VARFIX(BOOL,VARIANT_TRUE,I2,VARIANT_TRUE);
4007 VARFIX(BOOL,VARIANT_FALSE,I2,0);
4008 VARFIX(BOOL,1,I2,1);
4009 VARFIX(UI1,1,UI1,1);
4010 VARFIX(I2,-1,I2,-1);
4011 VARFIX(I4,-1,I4,-1);
4012 if (has_i8)
4014 VARFIX(I8,-1,I8,-1);
4016 VARFIX(R4,1.4f,R4,1);
4017 VARFIX(R4,1.5f,R4,1);
4018 VARFIX(R4,1.6f,R4,1);
4019 VARFIX(R4,-1.4f,R4,-1);
4020 VARFIX(R4,-1.5f,R4,-1);
4021 VARFIX(R4,-1.6f,R4,-1);
4022 /* DATE & R8 round as for R4 */
4023 VARFIX(DATE,-1,DATE,-1);
4024 VARFIX(R8,-1,R8,-1);
4025 VARFIX(BSTR,(BSTR)szNumMinus1,R8,-1);
4027 V_VT(&v) = VT_EMPTY;
4028 hres = pVarFix(&v,&vDst);
4029 ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
4030 "VarFix: expected 0x0,%d,0 got 0x%X,%d,%d\n", VT_EMPTY,
4031 hres, V_VT(&vDst), V_I2(&vDst));
4033 V_VT(&v) = VT_NULL;
4034 hres = pVarFix(&v,&vDst);
4035 ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
4036 "VarFix: expected 0x0,%d got 0x%X,%d\n", VT_NULL, hres, V_VT(&vDst));
4038 V_VT(&v) = VT_DECIMAL;
4039 S(U(*pdec)).sign = DECIMAL_NEG;
4040 S(U(*pdec)).scale = 0;
4041 pdec->Hi32 = 0;
4042 S1(U1(*pdec)).Mid32 = 0;
4043 S1(U1(*pdec)).Lo32 = 1;
4044 hres = pVarFix(&v,&vDst);
4045 ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL && !memcmp(&V_DECIMAL(&v), &V_DECIMAL(&vDst), sizeof(DECIMAL)),
4046 "VarFix: expected 0x0,%d,identical, got 0x%X,%d\n", VT_DECIMAL,
4047 hres, V_VT(&vDst));
4049 /* FIXME: Test some fractional decimals when VarDecFix is implemented */
4051 V_VT(&v) = VT_CY;
4052 pcy->int64 = -10000;
4053 hres = pVarFix(&v,&vDst);
4054 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
4055 "VarFix: VT_CY wrong, hres=0x%X\n", hres);
4057 V_VT(&v) = VT_CY;
4058 pcy->int64 = -16000;
4059 hres = pVarFix(&v,&vDst);
4060 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
4061 "VarFix: VT_CY wrong, hres=0x%X\n", hres);
4064 static HRESULT (WINAPI *pVarInt)(LPVARIANT,LPVARIANT);
4066 #define VARINT(vt,val,rvt,rval) \
4067 V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
4068 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
4069 test_var_call1( __LINE__, pVarInt, &v, &exp )
4071 static void test_VarInt(void)
4073 static const WCHAR szNumMinus1[] = {'-','1','\0' };
4074 HRESULT hres;
4075 VARIANT v, exp, vDst;
4076 DECIMAL *pdec = &V_DECIMAL(&v);
4077 CY *pcy = &V_CY(&v);
4078 size_t i;
4080 CHECKPTR(VarInt);
4082 /* Test all possible V_VT values */
4083 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
4085 VARTYPE vt;
4087 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
4089 BOOL bFail = TRUE;
4091 SKIPTESTS(vt);
4093 memset(&v, 0, sizeof(v));
4094 V_VT(&v) = vt | ExtraFlags[i];
4095 V_VT(&vDst) = VT_EMPTY;
4097 switch (V_VT(&v))
4099 case VT_UI1: case VT_I2: case VT_I4: case VT_R4: case VT_R8:
4100 case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
4101 case VT_DATE: case VT_CY:
4102 bFail = FALSE;
4103 break;
4104 case VT_I8:
4105 if (has_i8)
4106 bFail = FALSE;
4107 break;
4110 hres = pVarInt(&v,&vDst);
4111 if (bFail)
4112 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
4113 "VarInt: expected failure, got 0x%X vt %d|0x%X\n",
4114 hres, vt, ExtraFlags[i]);
4115 else
4116 ok(hres == S_OK, "VarInt: expected S_OK, got 0x%X vt %d|0x%X\n",
4117 hres, vt, ExtraFlags[i]);
4121 VARINT(BOOL,VARIANT_TRUE,I2,VARIANT_TRUE);
4122 VARINT(BOOL,VARIANT_FALSE,I2,0);
4123 VARINT(BOOL,1,I2,1);
4124 VARINT(UI1,1,UI1,1);
4125 VARINT(I2,-1,I2,-1);
4126 VARINT(I4,-1,I4,-1);
4127 if (has_i8)
4129 VARINT(I8,-1,I8,-1);
4131 VARINT(R4,1.4f,R4,1);
4132 VARINT(R4,1.5f,R4,1);
4133 VARINT(R4,1.6f,R4,1);
4134 VARINT(R4,-1.4f,R4,-2); /* Note these 3 are different from VarFix */
4135 VARINT(R4,-1.5f,R4,-2);
4136 VARINT(R4,-1.6f,R4,-2);
4137 /* DATE & R8 round as for R4 */
4138 VARINT(DATE,-1,DATE,-1);
4139 VARINT(R8,-1,R8,-1);
4140 VARINT(BSTR,(BSTR)szNumMinus1,R8,-1);
4142 V_VT(&v) = VT_EMPTY;
4143 hres = pVarInt(&v,&vDst);
4144 ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
4145 "VarInt: expected 0x0,%d,0 got 0x%X,%d,%d\n", VT_EMPTY,
4146 hres, V_VT(&vDst), V_I2(&vDst));
4148 V_VT(&v) = VT_NULL;
4149 hres = pVarInt(&v,&vDst);
4150 ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
4151 "VarInt: expected 0x0,%d got 0x%X,%d\n", VT_NULL, hres, V_VT(&vDst));
4153 V_VT(&v) = VT_DECIMAL;
4154 S(U(*pdec)).sign = DECIMAL_NEG;
4155 S(U(*pdec)).scale = 0;
4156 pdec->Hi32 = 0;
4157 S1(U1(*pdec)).Mid32 = 0;
4158 S1(U1(*pdec)).Lo32 = 1;
4159 hres = pVarInt(&v,&vDst);
4160 ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL && !memcmp(&V_DECIMAL(&v), &V_DECIMAL(&vDst), sizeof(DECIMAL)),
4161 "VarInt: expected 0x0,%d,identical, got 0x%X,%d\n", VT_DECIMAL,
4162 hres, V_VT(&vDst));
4164 /* FIXME: Test some fractional decimals when VarDecInt is implemented */
4166 V_VT(&v) = VT_CY;
4167 pcy->int64 = -10000;
4168 hres = pVarInt(&v,&vDst);
4169 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
4170 "VarInt: VT_CY wrong, hres=0x%X\n", hres);
4172 V_VT(&v) = VT_CY;
4173 pcy->int64 = -11000;
4174 hres = pVarInt(&v,&vDst);
4175 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -20000,
4176 "VarInt: VT_CY wrong, hres=0x%X 0x%x%08x\n",
4177 hres, (DWORD)(V_CY(&vDst).int64 >> 32), (DWORD)V_CY(&vDst).int64);
4180 static HRESULT (WINAPI *pVarNeg)(LPVARIANT,LPVARIANT);
4182 #define VARNEG(vt,val,rvt,rval) \
4183 V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
4184 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
4185 test_var_call1( __LINE__, pVarNeg, &v, &exp )
4187 static void test_VarNeg(void)
4189 static const WCHAR szNumMinus1[] = {'-','1','\0' };
4190 static const WCHAR szNum1[] = {'1','\0' };
4191 HRESULT hres;
4192 VARIANT v, exp, vDst;
4193 DECIMAL *pdec = &V_DECIMAL(&v);
4194 CY *pcy = &V_CY(&v);
4195 size_t i;
4197 CHECKPTR(VarNeg);
4199 /* Test all possible V_VT values. But don't test the exact return values
4200 * except for success/failure, since M$ made a hash of them in the
4201 * native version. This at least ensures (as with all tests here) that
4202 * we will notice if/when new vtypes/flags are added in native.
4204 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
4206 VARTYPE vt;
4208 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
4210 BOOL bFail = TRUE;
4212 SKIPTESTS(vt);
4214 memset(&v, 0, sizeof(v));
4215 V_VT(&v) = vt | ExtraFlags[i];
4216 V_VT(&vDst) = VT_EMPTY;
4218 switch (V_VT(&v))
4220 case VT_UI1: case VT_I2: case VT_I4:
4221 case VT_R4: case VT_R8:
4222 case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
4223 case VT_DATE: case VT_CY:
4224 bFail = FALSE;
4225 break;
4226 case VT_I8:
4227 if (has_i8)
4228 bFail = FALSE;
4231 hres = pVarNeg(&v,&vDst);
4232 if (bFail)
4233 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
4234 "VarNeg: expected failure, got 0x%X vt %d|0x%X\n",
4235 hres, vt, ExtraFlags[i]);
4236 else
4237 ok(hres == S_OK, "VarNeg: expected S_OK, got 0x%X vt %d|0x%X\n",
4238 hres, vt, ExtraFlags[i]);
4242 VARNEG(BOOL,VARIANT_TRUE,I2,1);
4243 VARNEG(BOOL,VARIANT_FALSE,I2,0);
4244 VARNEG(BOOL,1,I2,-1);
4245 VARNEG(UI1,1,I2,-1);
4246 VARNEG(UI1,254,I2,-254);
4247 VARNEG(I2,-32768,I4,32768);
4248 VARNEG(I2,-1,I2,1);
4249 VARNEG(I2,1,I2,-1);
4250 VARNEG(I4,-((int)(~0u >> 1)) - 1,R8,-2147483648u);
4251 VARNEG(I4,-1,I4,1);
4252 VARNEG(I4,1,I4,-1);
4253 if (has_i8)
4255 VARNEG(I8,1,I8,-1);
4256 VARNEG(I8,-1,I8,1);
4258 VARNEG(R4,1,R4,-1);
4259 VARNEG(R4,-1,R4,1);
4260 VARNEG(DATE,1,DATE,-1);
4261 VARNEG(DATE,-1,DATE,1);
4262 VARNEG(R8,1,R8,-1);
4263 VARNEG(R8,-1,R8,1);
4264 VARNEG(BSTR,(BSTR)szNumMinus1,R8,1);
4265 VARNEG(BSTR,(BSTR)szNum1,R8,-1);
4267 V_VT(&v) = VT_EMPTY;
4268 hres = pVarNeg(&v,&vDst);
4269 ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
4270 "VarNeg: expected 0x0,%d,0 got 0x%X,%d,%d\n", VT_EMPTY,
4271 hres, V_VT(&vDst), V_I2(&vDst));
4273 V_VT(&v) = VT_NULL;
4274 hres = pVarNeg(&v,&vDst);
4275 ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
4276 "VarNeg: expected 0x0,%d got 0x%X,%d\n", VT_NULL, hres, V_VT(&vDst));
4278 V_VT(&v) = VT_DECIMAL;
4279 S(U(*pdec)).sign = DECIMAL_NEG;
4280 S(U(*pdec)).scale = 0;
4281 pdec->Hi32 = 0;
4282 S1(U1(*pdec)).Mid32 = 0;
4283 S1(U1(*pdec)).Lo32 = 1;
4284 hres = pVarNeg(&v,&vDst);
4285 ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
4286 S(U(V_DECIMAL(&vDst))).sign == 0,
4287 "VarNeg: expected 0x0,%d,0x00, got 0x%X,%d,%02x\n", VT_DECIMAL,
4288 hres, V_VT(&vDst), S(U(V_DECIMAL(&vDst))).sign);
4290 S(U(*pdec)).sign = 0;
4291 hres = pVarNeg(&v,&vDst);
4292 ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
4293 S(U(V_DECIMAL(&vDst))).sign == DECIMAL_NEG,
4294 "VarNeg: expected 0x0,%d,0x7f, got 0x%X,%d,%02x\n", VT_DECIMAL,
4295 hres, V_VT(&vDst), S(U(V_DECIMAL(&vDst))).sign);
4297 V_VT(&v) = VT_CY;
4298 pcy->int64 = -10000;
4299 hres = pVarNeg(&v,&vDst);
4300 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == 10000,
4301 "VarNeg: VT_CY wrong, hres=0x%X\n", hres);
4304 static HRESULT (WINAPI *pVarRound)(LPVARIANT,int,LPVARIANT);
4306 static void test_Round( int line, VARIANT *arg, int deci, VARIANT *expected )
4308 VARIANT result;
4309 HRESULT hres;
4311 memset( &result, 0, sizeof(result) );
4312 hres = pVarRound( arg, deci, &result );
4313 ok_(__FILE__,line)( hres == S_OK, "wrong result %x\n", hres );
4314 if (hres == S_OK)
4315 ok_(__FILE__,line)( is_expected_variant( &result, expected ),
4316 "got %s expected %s\n", variantstr(&result), variantstr(expected) );
4318 #define VARROUND(vt,val,deci,rvt,rval) \
4319 V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
4320 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
4321 test_Round( __LINE__, &v, deci, &exp )
4323 struct decimal_t {
4324 BYTE scale;
4325 BYTE sign;
4326 ULONG Hi32;
4327 ULONG Mid32;
4328 ULONG Lo32;
4331 struct decimal_round_t {
4332 struct decimal_t source;
4333 struct decimal_t ret;
4334 int dec;
4337 static const struct decimal_round_t decimal_round_data[] = {
4338 {{ 0, DECIMAL_NEG, 0, 0, 1 }, { 0, DECIMAL_NEG, 0, 0, 1 }, 0},
4339 {{ 0, 0, 0, 0, 1 }, { 0, 0, 0, 0, 1 }, 0},
4340 {{ 2, 0, 0, 0, 155 }, { 0, 0, 0, 0, 16 }, 1},
4341 {{ 2, 0, 0, 0, 155 }, { 1, 0, 0, 0, 2 }, 0},
4342 {{ 2, 0, 0, 0, 199 }, { 1, 0, 0, 0, 20 }, 1},
4343 {{ 2, 0, 0, 0, 199 }, { 2, 0, 0, 0, 199 }, 2},
4344 {{ 2, DECIMAL_NEG, 0, 0, 199 }, { 2, DECIMAL_NEG, 0, 0, 199 }, 2},
4345 {{ 2, DECIMAL_NEG, 0, 0, 55 }, { 2, DECIMAL_NEG, 0, 0, 6 }, 1},
4346 {{ 2, 0, 0, 0, 55 }, { 2, 0, 0, 0, 6 }, 1},
4347 {{ 2, 0, 0, 0, 1999 }, { 1, 0, 0, 0, 200 }, 1},
4350 static void test_VarRound(void)
4352 static WCHAR szNumMin[] = {'-','1','.','4','4','9','\0' };
4353 static WCHAR szNum[] = {'1','.','4','5','1','\0' };
4354 HRESULT hres;
4355 VARIANT v, exp, vDst;
4356 CY *pcy = &V_CY(&v);
4357 char buff[8];
4358 int i;
4360 CHECKPTR(VarRound);
4362 /* first check valid integer types */
4363 VARROUND(BOOL,VARIANT_TRUE,0,I2,-1);
4364 VARROUND(BOOL,VARIANT_FALSE,0,I2,0);
4365 VARROUND(BOOL,1,0,I2,1);
4366 VARROUND(UI1,1,0,UI1,1);
4367 VARROUND(UI1,254,0,UI1,254);
4368 VARROUND(I2,-32768,0,I2,-32768);
4369 VARROUND(I2,-1,0,I2,-1);
4370 VARROUND(I2,1,0,I2,1);
4371 VARROUND(I4,-((int)(~0u >> 1)) - 1,0,I4,-((int)(~0u >> 1)) - 1);
4372 VARROUND(I4,-1,0,I4,-1);
4373 VARROUND(I4,1,0,I4,1);
4376 /* MSDN states that rounding of R4/R8 is dependent on the underlying
4377 * bit pattern of the number and so is architecture dependent. In this
4378 * case Wine returns .2 (which is more correct) and Native returns .3
4381 VARROUND(R4,1.0f,0,R4,1.0f);
4382 VARROUND(R4,-1.0f,0,R4,-1.0f);
4383 VARROUND(R8,1.0,0,R8,1.0);
4384 VARROUND(R8,-1.0,0,R8,-1.0);
4386 /* floating point numbers aren't exactly equal and we can't just
4387 * compare the first few digits. */
4388 VARROUND(DATE,1.451,1,DATE,1.5);
4389 VARROUND(DATE,-1.449,1,DATE,-1.4);
4391 /* replace the decimal separator */
4392 GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, ARRAY_SIZE(buff));
4393 if (!buff[1]) {
4394 szNumMin[2] = buff[0];
4395 szNum[1] = buff[0];
4396 VARROUND(BSTR,(BSTR)szNumMin,1,R8,-1.40);
4397 VARROUND(BSTR,(BSTR)szNum,1,R8,1.50);
4398 } else {
4399 skip("Skipping VarRound(BSTR) as decimal separator is '%s'\n", buff);
4402 VARROUND(R4,1.23456f,0,R4,1.0f);
4403 VARROUND(R4,1.23456f,1,R4,1.2f);
4404 VARROUND(R4,1.23456f,2,R4,1.23f);
4405 VARROUND(R4,1.23456f,3,R4,1.235f);
4406 VARROUND(R4,1.23456f,4,R4,1.2346f);
4407 VARROUND(R4,-1.23456f,0,R4,-1.0f);
4408 VARROUND(R4,-1.23456f,1,R4,-1.2f);
4409 VARROUND(R4,-1.23456f,2,R4,-1.23f);
4410 VARROUND(R4,-1.23456f,3,R4,-1.235f);
4411 VARROUND(R4,-1.23456f,4,R4,-1.2346f);
4413 VARROUND(R8,1.23456,0,R8,1.0);
4414 VARROUND(R8,1.23456,1,R8,1.2);
4415 VARROUND(R8,1.23456,2,R8,1.23);
4416 VARROUND(R8,1.23456,3,R8,1.235);
4417 VARROUND(R8,1.23456,4,R8,1.2346);
4418 VARROUND(R8,-1.23456,0,R8,-1.0);
4419 VARROUND(R8,-1.23456,1,R8,-1.2);
4420 VARROUND(R8,-1.23456,2,R8,-1.23);
4421 VARROUND(R8,-1.23456,3,R8,-1.235);
4422 VARROUND(R8,-1.23456,4,R8,-1.2346);
4424 V_VT(&v) = VT_EMPTY;
4425 hres = pVarRound(&v,0,&vDst);
4426 ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
4427 "VarRound: expected 0x0,%d,0 got 0x%X,%d,%d\n", VT_EMPTY,
4428 hres, V_VT(&vDst), V_I2(&vDst));
4430 V_VT(&v) = VT_NULL;
4431 hres = pVarRound(&v,0,&vDst);
4432 ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
4433 "VarRound: expected 0x0,%d got 0x%X,%d\n", VT_NULL, hres, V_VT(&vDst));
4435 /* VT_DECIMAL */
4436 for (i = 0; i < ARRAY_SIZE(decimal_round_data); i++)
4438 const struct decimal_round_t *ptr = &decimal_round_data[i];
4439 DECIMAL *pdec;
4441 pdec = &V_DECIMAL(&v);
4442 V_VT(&v) = VT_DECIMAL;
4443 S(U(*pdec)).sign = ptr->source.sign;
4444 S(U(*pdec)).scale = ptr->source.scale;
4445 pdec->Hi32 = ptr->source.Hi32;
4446 S1(U1(*pdec)).Mid32 = ptr->source.Mid32;
4447 S1(U1(*pdec)).Lo32 = ptr->source.Lo32;
4448 VariantInit(&vDst);
4449 hres = pVarRound(&v, ptr->dec, &vDst);
4450 ok(hres == S_OK, "%d: got 0x%08x\n", i, hres);
4451 if (hres == S_OK)
4453 ok(V_VT(&vDst) == VT_DECIMAL, "%d: got VT %d, expected VT_DECIMAL\n", i, V_VT(&vDst));
4454 ok(S(U(V_DECIMAL(&vDst))).sign == ptr->ret.sign, "%d: got sign 0x%02x, expected 0x%02x\n",
4455 i, S(U(V_DECIMAL(&vDst))).sign, ptr->ret.sign);
4456 ok(V_DECIMAL(&vDst).Hi32 == ptr->ret.Hi32, "%d: got Hi32 %d, expected %d\n",
4457 i, V_DECIMAL(&vDst).Hi32, ptr->ret.Hi32);
4458 ok(S1(U1(V_DECIMAL(&vDst))).Mid32 == ptr->ret.Mid32, "%d: got Mid32 %d, expected %d\n",
4459 i, S1(U1(V_DECIMAL(&vDst))).Mid32, ptr->ret.Mid32);
4460 ok(S1(U1(V_DECIMAL(&vDst))).Lo32 == ptr->ret.Lo32, "%d: got Lo32 %d, expected %d\n",
4461 i, S1(U1(V_DECIMAL(&vDst))).Lo32, ptr->ret.Lo32);
4465 /* VT_CY */
4466 V_VT(&v) = VT_CY;
4467 pcy->int64 = 10000;
4468 hres = pVarRound(&v,0,&vDst);
4469 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == 10000,
4470 "VarRound: VT_CY wrong, hres=0x%X\n", hres);
4474 static HRESULT (WINAPI *pVarXor)(LPVARIANT,LPVARIANT,LPVARIANT);
4476 #define VARXOR(vt1,val1,vt2,val2,rvt,rval) \
4477 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
4478 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
4479 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
4480 test_var_call2( __LINE__, pVarXor, &left, &right, &exp )
4482 #define VARXORCY(vt1,val1,val2,rvt,rval) \
4483 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
4484 V_VT(&right) = VT_CY; V_CY(&right).int64 = val2; \
4485 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
4486 test_var_call2( __LINE__, pVarXor, &left, &right, &exp )
4488 static void test_VarXor(void)
4490 static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
4491 static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
4492 VARIANT left, right, exp, result;
4493 BSTR lbstr, rbstr;
4494 VARTYPE i;
4495 HRESULT hres;
4497 CHECKPTR(VarXor);
4499 /* Test all possible flag/vt combinations & the resulting vt type */
4500 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
4502 VARTYPE leftvt, rightvt, resvt;
4504 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
4507 SKIPTESTS(leftvt);
4509 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
4511 BOOL bFail = FALSE;
4513 SKIPTESTS(rightvt);
4515 if (leftvt == VT_BSTR || rightvt == VT_BSTR ||
4516 leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
4517 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN)
4518 continue;
4520 memset(&left, 0, sizeof(left));
4521 memset(&right, 0, sizeof(right));
4522 V_VT(&left) = leftvt | ExtraFlags[i];
4523 V_VT(&right) = rightvt | ExtraFlags[i];
4524 V_VT(&result) = VT_EMPTY;
4525 resvt = VT_I4;
4527 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
4528 !IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
4529 !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
4530 leftvt == VT_CLSID || rightvt == VT_CLSID ||
4531 leftvt == VT_RECORD || rightvt == VT_RECORD ||
4532 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
4533 leftvt == VT_ERROR || rightvt == VT_ERROR)
4535 bFail = TRUE;
4537 if (leftvt == VT_EMPTY || rightvt == VT_EMPTY)
4539 if (leftvt == rightvt ||
4540 leftvt == VT_I2 || rightvt == VT_I2 ||
4541 leftvt == VT_UI1 || rightvt == VT_UI1 ||
4542 leftvt == VT_BOOL || rightvt == VT_BOOL)
4543 resvt = VT_I2;
4544 else if (leftvt == VT_NULL || rightvt == VT_NULL)
4545 resvt = VT_NULL;
4546 else if (leftvt == VT_I8 || rightvt == VT_I8)
4547 resvt = VT_I8;
4549 else if (leftvt == VT_NULL || rightvt == VT_NULL)
4551 resvt = VT_NULL;
4553 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
4555 if (leftvt == rightvt)
4556 resvt = VT_UI1;
4557 else if (leftvt == rightvt ||
4558 leftvt == VT_I2 || rightvt == VT_I2 ||
4559 leftvt == VT_BOOL || rightvt == VT_BOOL)
4561 resvt = VT_I2;
4563 else if (leftvt == VT_I8 || rightvt == VT_I8)
4564 resvt = VT_I8;
4566 else if (leftvt == VT_I2 || rightvt == VT_I2)
4568 if (leftvt == rightvt ||
4569 leftvt == VT_BOOL || rightvt == VT_BOOL)
4570 resvt = VT_I2;
4571 else if (leftvt == VT_I8 || rightvt == VT_I8)
4572 resvt = VT_I8;
4574 else if (leftvt == VT_BOOL && rightvt == VT_BOOL)
4576 resvt = VT_BOOL;
4578 else if (leftvt == VT_I8 || rightvt == VT_I8)
4580 if (leftvt == VT_INT || rightvt == VT_INT)
4581 bFail = TRUE;
4582 else
4583 resvt = VT_I8;
4585 hres = pVarXor(&left, &right, &result);
4586 if (bFail)
4587 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
4588 "VarXor: %d|0x%X, %d|0x%X: Expected failure, got 0x%X vt %d\n",
4589 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres,
4590 V_VT(&result));
4591 else
4592 ok(hres == S_OK && V_VT(&result) == resvt,
4593 "VarXor: %d|0x%X, %d|0x%X: expected S_OK, vt %d, got 0x%X vt %d\n",
4594 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], resvt, hres,
4595 V_VT(&result));
4600 /* Test returned values
4601 * FIXME: Test VT_DECIMAL/VT_DISPATCH
4603 VARXOR(EMPTY,0,EMPTY,0,I2,0);
4604 VARXOR(EMPTY,1,EMPTY,0,I2,0);
4605 VARXOR(EMPTY,0,NULL,0,NULL,0);
4606 VARXOR(EMPTY,0,I1,0,I4,0);
4607 VARXOR(EMPTY,0,I1,1,I4,1);
4608 VARXOR(EMPTY,0,UI1,0,I2,0);
4609 VARXOR(EMPTY,0,UI1,1,I2,1);
4610 VARXOR(EMPTY,0,I2,0,I2,0);
4611 VARXOR(EMPTY,0,I2,1,I2,1);
4612 VARXOR(EMPTY,0,UI2,0,I4,0);
4613 VARXOR(EMPTY,0,UI2,1,I4,1);
4614 VARXOR(EMPTY,0,I4,0,I4,0);
4615 VARXOR(EMPTY,0,I4,1,I4,1);
4616 VARXOR(EMPTY,0,UI4,0,I4,0);
4617 VARXOR(EMPTY,0,UI4,1,I4,1);
4618 if (has_i8)
4620 VARXOR(EMPTY,0,I8,0,I8,0);
4621 VARXOR(EMPTY,0,I8,1,I8,1);
4622 VARXOR(EMPTY,0,UI8,0,I4,0);
4623 VARXOR(EMPTY,0,UI8,1,I4,1);
4625 VARXOR(EMPTY,0,INT,0,I4,0);
4626 VARXOR(EMPTY,0,INT,1,I4,1);
4627 VARXOR(EMPTY,0,UINT,0,I4,0);
4628 VARXOR(EMPTY,0,UINT,1,I4,1);
4629 VARXOR(EMPTY,0,BOOL,0,I2,0);
4630 VARXOR(EMPTY,0,BOOL,1,I2,1);
4631 VARXOR(EMPTY,0,R4,0,I4,0);
4632 VARXOR(EMPTY,0,R4,1,I4,1);
4633 VARXOR(EMPTY,0,R8,0,I4,0);
4634 VARXOR(EMPTY,0,R8,1,I4,1);
4635 rbstr = SysAllocString(szFalse);
4636 VARXOR(EMPTY,0,BSTR,rbstr,I2,0);
4637 SysFreeString(rbstr);
4638 rbstr = SysAllocString(szTrue);
4639 VARXOR(EMPTY,0,BSTR,rbstr,I2,-1);
4640 VARXORCY(EMPTY,0,10000,I4,1);
4641 SysFreeString(rbstr);
4643 /* NULL OR 0 = NULL. NULL OR n = n */
4644 VARXOR(NULL,0,NULL,0,NULL,0);
4645 VARXOR(NULL,1,NULL,0,NULL,0);
4646 VARXOR(NULL,0,I1,0,NULL,0);
4647 VARXOR(NULL,0,I1,1,NULL,0);
4648 VARXOR(NULL,0,UI1,0,NULL,0);
4649 VARXOR(NULL,0,UI1,1,NULL,0);
4650 VARXOR(NULL,0,I2,0,NULL,0);
4651 VARXOR(NULL,0,I2,1,NULL,0);
4652 VARXOR(NULL,0,UI2,0,NULL,0);
4653 VARXOR(NULL,0,UI2,1,NULL,0);
4654 VARXOR(NULL,0,I4,0,NULL,0);
4655 VARXOR(NULL,0,I4,1,NULL,0);
4656 VARXOR(NULL,0,UI4,0,NULL,0);
4657 VARXOR(NULL,0,UI4,1,NULL,0);
4658 if (has_i8)
4660 VARXOR(NULL,0,I8,0,NULL,0);
4661 VARXOR(NULL,0,I8,1,NULL,0);
4662 VARXOR(NULL,0,UI8,0,NULL,0);
4663 VARXOR(NULL,0,UI8,1,NULL,0);
4665 VARXOR(NULL,0,INT,0,NULL,0);
4666 VARXOR(NULL,0,INT,1,NULL,0);
4667 VARXOR(NULL,0,UINT,0,NULL,0);
4668 VARXOR(NULL,0,UINT,1,NULL,0);
4669 VARXOR(NULL,0,BOOL,0,NULL,0);
4670 VARXOR(NULL,0,BOOL,1,NULL,0);
4671 VARXOR(NULL,0,R4,0,NULL,0);
4672 VARXOR(NULL,0,R4,1,NULL,0);
4673 VARXOR(NULL,0,R8,0,NULL,0);
4674 VARXOR(NULL,0,R8,1,NULL,0);
4675 rbstr = SysAllocString(szFalse);
4676 VARXOR(NULL,0,BSTR,rbstr,NULL,0);
4677 SysFreeString(rbstr);
4678 rbstr = SysAllocString(szTrue);
4679 VARXOR(NULL,0,BSTR,rbstr,NULL,0);
4680 SysFreeString(rbstr);
4681 VARXORCY(NULL,0,10000,NULL,0);
4682 VARXORCY(NULL,0,0,NULL,0);
4684 VARXOR(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE);
4685 VARXOR(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE);
4686 VARXOR(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
4687 VARXOR(BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE);
4688 /* Assume x,y & y,x are the same from now on to reduce the number of tests */
4689 VARXOR(BOOL,VARIANT_TRUE,I1,-1,I4,0);
4690 VARXOR(BOOL,VARIANT_TRUE,I1,0,I4,-1);
4691 VARXOR(BOOL,VARIANT_FALSE,I1,0,I4,0);
4692 VARXOR(BOOL,VARIANT_TRUE,UI1,255,I2,-256);
4693 VARXOR(BOOL,VARIANT_TRUE,UI1,0,I2,-1);
4694 VARXOR(BOOL,VARIANT_FALSE,UI1,0,I2,0);
4695 VARXOR(BOOL,VARIANT_TRUE,I2,-1,I2,0);
4696 VARXOR(BOOL,VARIANT_TRUE,I2,0,I2,-1);
4697 VARXOR(BOOL,VARIANT_FALSE,I2,0,I2,0);
4698 VARXOR(BOOL,VARIANT_TRUE,UI2,65535,I4,-65536);
4699 VARXOR(BOOL,VARIANT_TRUE,UI2,0,I4,-1);
4700 VARXOR(BOOL,VARIANT_FALSE,UI2,0,I4,0);
4701 VARXOR(BOOL,VARIANT_TRUE,I4,-1,I4,0);
4702 VARXOR(BOOL,VARIANT_TRUE,I4,0,I4,-1);
4703 VARXOR(BOOL,VARIANT_FALSE,I4,0,I4,0);
4704 VARXOR(BOOL,VARIANT_TRUE,UI4,0xffffffff,I4,0);
4705 VARXOR(BOOL,VARIANT_TRUE,UI4,0,I4,-1);
4706 VARXOR(BOOL,VARIANT_FALSE,UI4,0,I4,0);
4707 VARXOR(BOOL,VARIANT_TRUE,R4,-1,I4,0);
4708 VARXOR(BOOL,VARIANT_TRUE,R4,0,I4,-1);
4709 VARXOR(BOOL,VARIANT_FALSE,R4,0,I4,0);
4710 VARXOR(BOOL,VARIANT_TRUE,R8,-1,I4,0);
4711 VARXOR(BOOL,VARIANT_TRUE,R8,0,I4,-1);
4712 VARXOR(BOOL,VARIANT_FALSE,R8,0,I4,0);
4713 VARXOR(BOOL,VARIANT_TRUE,DATE,-1,I4,0);
4714 VARXOR(BOOL,VARIANT_TRUE,DATE,0,I4,-1);
4715 VARXOR(BOOL,VARIANT_FALSE,DATE,0,I4,0);
4716 if (has_i8)
4718 VARXOR(BOOL,VARIANT_TRUE,I8,-1,I8,0);
4719 VARXOR(BOOL,VARIANT_TRUE,I8,0,I8,-1);
4720 VARXOR(BOOL,VARIANT_FALSE,I8,0,I8,0);
4721 /* This returns DISP_E_OVERFLOW which indicates that a conversion
4722 * to I4 is performed.
4724 /* VARXOR(BOOL,VARIANT_TRUE,UI8,-1,I4,-1); */
4725 VARXOR(BOOL,VARIANT_TRUE,UI8,0,I4,-1);
4726 VARXOR(BOOL,VARIANT_FALSE,UI8,0,I4,0);
4728 VARXOR(BOOL,VARIANT_TRUE,INT,-1,I4,0);
4729 VARXOR(BOOL,VARIANT_TRUE,INT,0,I4,-1);
4730 VARXOR(BOOL,VARIANT_FALSE,INT,0,I4,0);
4731 VARXOR(BOOL,VARIANT_TRUE,UINT,0xffffffff,I4,0);
4732 VARXOR(BOOL,VARIANT_TRUE,UINT,0,I4,-1);
4733 VARXOR(BOOL,VARIANT_FALSE,UINT,0,I4,0);
4734 rbstr = SysAllocString(szFalse);
4735 VARXOR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_FALSE);
4736 VARXOR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_TRUE);
4737 SysFreeString(rbstr);
4738 rbstr = SysAllocString(szTrue);
4739 VARXOR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_TRUE);
4740 VARXOR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_FALSE);
4741 SysFreeString(rbstr);
4742 VARXORCY(BOOL,VARIANT_TRUE,10000,I4,-2);
4743 VARXORCY(BOOL,VARIANT_TRUE,0,I4,-1);
4744 VARXORCY(BOOL,VARIANT_FALSE,0,I4,0);
4746 VARXOR(I1,-1,I1,-1,I4,0);
4747 VARXOR(I1,-1,I1,0,I4,-1);
4748 VARXOR(I1,0,I1,0,I4,0);
4749 VARXOR(I1,-1,UI1,255,I4,-256);
4750 VARXOR(I1,-1,UI1,0,I4,-1);
4751 VARXOR(I1,0,UI1,0,I4,0);
4752 VARXOR(I1,-1,I2,-1,I4,0);
4753 VARXOR(I1,-1,I2,0,I4,-1);
4754 VARXOR(I1,0,I2,0,I4,0);
4755 VARXOR(I1,-1,UI2,65535,I4,-65536);
4756 VARXOR(I1,-1,UI2,0,I4,-1);
4757 VARXOR(I1,0,UI2,0,I4,0);
4758 VARXOR(I1,-1,I4,-1,I4,0);
4759 VARXOR(I1,-1,I4,0,I4,-1);
4760 VARXOR(I1,0,I4,0,I4,0);
4761 VARXOR(I1,-1,UI4,0xffffffff,I4,0);
4762 VARXOR(I1,-1,UI4,0,I4,-1);
4763 VARXOR(I1,0,UI4,0,I4,0);
4764 VARXOR(I1,-1,R4,-1,I4,0);
4765 VARXOR(I1,-1,R4,0,I4,-1);
4766 VARXOR(I1,0,R4,0,I4,0);
4767 VARXOR(I1,-1,R8,-1,I4,0);
4768 VARXOR(I1,-1,R8,0,I4,-1);
4769 VARXOR(I1,0,R8,0,I4,0);
4770 VARXOR(I1,-1,DATE,-1,I4,0);
4771 VARXOR(I1,-1,DATE,0,I4,-1);
4772 VARXOR(I1,0,DATE,0,I4,0);
4773 if (has_i8)
4775 VARXOR(I1,-1,I8,-1,I8,0);
4776 VARXOR(I1,-1,I8,0,I8,-1);
4777 VARXOR(I1,0,I8,0,I8,0);
4778 VARXOR(I1,-1,UI8,0,I4,-1);
4779 VARXOR(I1,0,UI8,0,I4,0);
4781 VARXOR(I1,-1,INT,-1,I4,0);
4782 VARXOR(I1,-1,INT,0,I4,-1);
4783 VARXOR(I1,0,INT,0,I4,0);
4784 VARXOR(I1,-1,UINT,0xffffffff,I4,0);
4785 VARXOR(I1,-1,UINT,0,I4,-1);
4786 VARXOR(I1,0,UINT,0,I4,0);
4787 rbstr = SysAllocString(szFalse);
4788 VARXOR(I1,0,BSTR,rbstr,I4,0);
4789 VARXOR(I1,-1,BSTR,rbstr,I4,-1);
4790 SysFreeString(rbstr);
4791 rbstr = SysAllocString(szTrue);
4792 VARXOR(I1,0,BSTR,rbstr,I4,-1);
4793 VARXOR(I1,-1,BSTR,rbstr,I4,0);
4794 SysFreeString(rbstr);
4795 VARXORCY(I1,-1,10000,I4,-2);
4796 VARXORCY(I1,-1,0,I4,-1);
4797 VARXORCY(I1,0,0,I4,0);
4799 VARXOR(UI1,255,UI1,255,UI1,0);
4800 VARXOR(UI1,255,UI1,0,UI1,255);
4801 VARXOR(UI1,0,UI1,0,UI1,0);
4802 VARXOR(UI1,255,I2,-1,I2,-256);
4803 VARXOR(UI1,255,I2,0,I2,255);
4804 VARXOR(UI1,0,I2,0,I2,0);
4805 VARXOR(UI1,255,UI2,65535,I4,65280);
4806 VARXOR(UI1,255,UI2,0,I4,255);
4807 VARXOR(UI1,0,UI2,0,I4,0);
4808 VARXOR(UI1,255,I4,-1,I4,-256);
4809 VARXOR(UI1,255,I4,0,I4,255);
4810 VARXOR(UI1,0,I4,0,I4,0);
4811 VARXOR(UI1,255,UI4,0xffffffff,I4,-256);
4812 VARXOR(UI1,255,UI4,0,I4,255);
4813 VARXOR(UI1,0,UI4,0,I4,0);
4814 VARXOR(UI1,255,R4,-1,I4,-256);
4815 VARXOR(UI1,255,R4,0,I4,255);
4816 VARXOR(UI1,0,R4,0,I4,0);
4817 VARXOR(UI1,255,R8,-1,I4,-256);
4818 VARXOR(UI1,255,R8,0,I4,255);
4819 VARXOR(UI1,0,R8,0,I4,0);
4820 VARXOR(UI1,255,DATE,-1,I4,-256);
4821 VARXOR(UI1,255,DATE,0,I4,255);
4822 VARXOR(UI1,0,DATE,0,I4,0);
4823 if (has_i8)
4825 VARXOR(UI1,255,I8,-1,I8,-256);
4826 VARXOR(UI1,255,I8,0,I8,255);
4827 VARXOR(UI1,0,I8,0,I8,0);
4828 VARXOR(UI1,255,UI8,0,I4,255);
4829 VARXOR(UI1,0,UI8,0,I4,0);
4831 VARXOR(UI1,255,INT,-1,I4,-256);
4832 VARXOR(UI1,255,INT,0,I4,255);
4833 VARXOR(UI1,0,INT,0,I4,0);
4834 VARXOR(UI1,255,UINT,0xffffffff,I4,-256);
4835 VARXOR(UI1,255,UINT,0,I4,255);
4836 VARXOR(UI1,0,UINT,0,I4,0);
4837 rbstr = SysAllocString(szFalse);
4838 VARXOR(UI1,0,BSTR,rbstr,I2,0);
4839 VARXOR(UI1,255,BSTR,rbstr,I2,255);
4840 SysFreeString(rbstr);
4841 rbstr = SysAllocString(szTrue);
4842 VARXOR(UI1,0,BSTR,rbstr,I2,-1);
4843 VARXOR(UI1,255,BSTR,rbstr,I2,-256);
4844 SysFreeString(rbstr);
4845 VARXORCY(UI1,255,10000,I4,254);
4846 VARXORCY(UI1,255,0,I4,255);
4847 VARXORCY(UI1,0,0,I4,0);
4849 VARXOR(I2,-1,I2,-1,I2,0);
4850 VARXOR(I2,-1,I2,0,I2,-1);
4851 VARXOR(I2,0,I2,0,I2,0);
4852 VARXOR(I2,-1,UI2,65535,I4,-65536);
4853 VARXOR(I2,-1,UI2,0,I4,-1);
4854 VARXOR(I2,0,UI2,0,I4,0);
4855 VARXOR(I2,-1,I4,-1,I4,0);
4856 VARXOR(I2,-1,I4,0,I4,-1);
4857 VARXOR(I2,0,I4,0,I4,0);
4858 VARXOR(I2,-1,UI4,0xffffffff,I4,0);
4859 VARXOR(I2,-1,UI4,0,I4,-1);
4860 VARXOR(I2,0,UI4,0,I4,0);
4861 VARXOR(I2,-1,R4,-1,I4,0);
4862 VARXOR(I2,-1,R4,0,I4,-1);
4863 VARXOR(I2,0,R4,0,I4,0);
4864 VARXOR(I2,-1,R8,-1,I4,0);
4865 VARXOR(I2,-1,R8,0,I4,-1);
4866 VARXOR(I2,0,R8,0,I4,0);
4867 VARXOR(I2,-1,DATE,-1,I4,0);
4868 VARXOR(I2,-1,DATE,0,I4,-1);
4869 VARXOR(I2,0,DATE,0,I4,0);
4870 if (has_i8)
4872 VARXOR(I2,-1,I8,-1,I8,0);
4873 VARXOR(I2,-1,I8,0,I8,-1);
4874 VARXOR(I2,0,I8,0,I8,0);
4875 VARXOR(I2,-1,UI8,0,I4,-1);
4876 VARXOR(I2,0,UI8,0,I4,0);
4878 VARXOR(I2,-1,INT,-1,I4,0);
4879 VARXOR(I2,-1,INT,0,I4,-1);
4880 VARXOR(I2,0,INT,0,I4,0);
4881 VARXOR(I2,-1,UINT,0xffffffff,I4,0);
4882 VARXOR(I2,-1,UINT,0,I4,-1);
4883 VARXOR(I2,0,UINT,0,I4,0);
4884 rbstr = SysAllocString(szFalse);
4885 VARXOR(I2,0,BSTR,rbstr,I2,0);
4886 VARXOR(I2,-1,BSTR,rbstr,I2,-1);
4887 SysFreeString(rbstr);
4888 rbstr = SysAllocString(szTrue);
4889 VARXOR(I2,0,BSTR,rbstr,I2,-1);
4890 VARXOR(I2,-1,BSTR,rbstr,I2,0);
4891 SysFreeString(rbstr);
4892 VARXORCY(I2,-1,10000,I4,-2);
4893 VARXORCY(I2,-1,0,I4,-1);
4894 VARXORCY(I2,0,0,I4,0);
4896 VARXOR(UI2,65535,UI2,65535,I4,0);
4897 VARXOR(UI2,65535,UI2,0,I4,65535);
4898 VARXOR(UI2,0,UI2,0,I4,0);
4899 VARXOR(UI2,65535,I4,-1,I4,-65536);
4900 VARXOR(UI2,65535,I4,0,I4,65535);
4901 VARXOR(UI2,0,I4,0,I4,0);
4902 VARXOR(UI2,65535,UI4,0xffffffff,I4,-65536);
4903 VARXOR(UI2,65535,UI4,0,I4,65535);
4904 VARXOR(UI2,0,UI4,0,I4,0);
4905 VARXOR(UI2,65535,R4,-1,I4,-65536);
4906 VARXOR(UI2,65535,R4,0,I4,65535);
4907 VARXOR(UI2,0,R4,0,I4,0);
4908 VARXOR(UI2,65535,R8,-1,I4,-65536);
4909 VARXOR(UI2,65535,R8,0,I4,65535);
4910 VARXOR(UI2,0,R8,0,I4,0);
4911 VARXOR(UI2,65535,DATE,-1,I4,-65536);
4912 VARXOR(UI2,65535,DATE,0,I4,65535);
4913 VARXOR(UI2,0,DATE,0,I4,0);
4914 if (has_i8)
4916 VARXOR(UI2,65535,I8,-1,I8,-65536);
4917 VARXOR(UI2,65535,I8,0,I8,65535);
4918 VARXOR(UI2,0,I8,0,I8,0);
4919 VARXOR(UI2,65535,UI8,0,I4,65535);
4920 VARXOR(UI2,0,UI8,0,I4,0);
4922 VARXOR(UI2,65535,INT,-1,I4,-65536);
4923 VARXOR(UI2,65535,INT,0,I4,65535);
4924 VARXOR(UI2,0,INT,0,I4,0);
4925 VARXOR(UI2,65535,UINT,0xffffffff,I4,-65536);
4926 VARXOR(UI2,65535,UINT,0,I4,65535);
4927 VARXOR(UI2,0,UINT,0,I4,0);
4928 rbstr = SysAllocString(szFalse);
4929 VARXOR(UI2,0,BSTR,rbstr,I4,0);
4930 VARXOR(UI2,65535,BSTR,rbstr,I4,65535);
4931 SysFreeString(rbstr);
4932 rbstr = SysAllocString(szTrue);
4933 VARXOR(UI2,0,BSTR,rbstr,I4,-1);
4934 VARXOR(UI2,65535,BSTR,rbstr,I4,-65536);
4935 SysFreeString(rbstr);
4936 VARXORCY(UI2,65535,10000,I4,65534);
4937 VARXORCY(UI2,65535,0,I4,65535);
4938 VARXORCY(UI2,0,0,I4,0);
4940 VARXOR(I4,-1,I4,-1,I4,0);
4941 VARXOR(I4,-1,I4,0,I4,-1);
4942 VARXOR(I4,0,I4,0,I4,0);
4943 VARXOR(I4,-1,UI4,0xffffffff,I4,0);
4944 VARXOR(I4,-1,UI4,0,I4,-1);
4945 VARXOR(I4,0,UI4,0,I4,0);
4946 VARXOR(I4,-1,R4,-1,I4,0);
4947 VARXOR(I4,-1,R4,0,I4,-1);
4948 VARXOR(I4,0,R4,0,I4,0);
4949 VARXOR(I4,-1,R8,-1,I4,0);
4950 VARXOR(I4,-1,R8,0,I4,-1);
4951 VARXOR(I4,0,R8,0,I4,0);
4952 VARXOR(I4,-1,DATE,-1,I4,0);
4953 VARXOR(I4,-1,DATE,0,I4,-1);
4954 VARXOR(I4,0,DATE,0,I4,0);
4955 if (has_i8)
4957 VARXOR(I4,-1,I8,-1,I8,0);
4958 VARXOR(I4,-1,I8,0,I8,-1);
4959 VARXOR(I4,0,I8,0,I8,0);
4960 VARXOR(I4,-1,UI8,0,I4,-1);
4961 VARXOR(I4,0,UI8,0,I4,0);
4963 VARXOR(I4,-1,INT,-1,I4,0);
4964 VARXOR(I4,-1,INT,0,I4,-1);
4965 VARXOR(I4,0,INT,0,I4,0);
4966 VARXOR(I4,-1,UINT,0xffffffff,I4,0);
4967 VARXOR(I4,-1,UINT,0,I4,-1);
4968 VARXOR(I4,0,UINT,0,I4,0);
4969 rbstr = SysAllocString(szFalse);
4970 VARXOR(I4,0,BSTR,rbstr,I4,0);
4971 VARXOR(I4,-1,BSTR,rbstr,I4,-1);
4972 SysFreeString(rbstr);
4973 rbstr = SysAllocString(szTrue);
4974 VARXOR(I4,0,BSTR,rbstr,I4,-1);
4975 VARXOR(I4,-1,BSTR,rbstr,I4,0);
4976 SysFreeString(rbstr);
4977 VARXORCY(I4,-1,10000,I4,-2);
4978 VARXORCY(I4,-1,0,I4,-1);
4979 VARXORCY(I4,0,0,I4,0);
4981 VARXOR(UI4,0xffffffff,UI4,0xffffffff,I4,0);
4982 VARXOR(UI4,0xffffffff,UI4,0,I4,-1);
4983 VARXOR(UI4,0,UI4,0,I4,0);
4984 VARXOR(UI4,0xffffffff,R4,-1,I4,0);
4985 VARXOR(UI4,0xffffffff,R4,0,I4,-1);
4986 VARXOR(UI4,0,R4,0,I4,0);
4987 VARXOR(UI4,0xffffffff,R8,-1,I4,0);
4988 VARXOR(UI4,0xffffffff,R8,0,I4,-1);
4989 VARXOR(UI4,0,R8,0,I4,0);
4990 VARXOR(UI4,0xffffffff,DATE,-1,I4,0);
4991 VARXOR(UI4,0xffffffff,DATE,0,I4,-1);
4992 VARXOR(UI4,0,DATE,0,I4,0);
4993 if (has_i8)
4995 VARXOR(UI4,0xffffffff,I8,0,I8,0xffffffff);
4996 VARXOR(UI4,VARIANT_FALSE,I8,VARIANT_FALSE,I8,0);
4997 VARXOR(UI4,0,I8,0,I8,0);
4998 VARXOR(UI4,0xffffffff,UI8,0,I4,-1);
4999 VARXOR(UI4,0,UI8,0,I4,0);
5001 VARXOR(UI4,0xffffffff,INT,-1,I4,0);
5002 VARXOR(UI4,0xffffffff,INT,0,I4,-1);
5003 VARXOR(UI4,0,INT,0,I4,0);
5004 VARXOR(UI4,0xffffffff,UINT,0xffffffff,I4,0);
5005 VARXOR(UI4,0xffffffff,UINT,0,I4,-1);
5006 VARXOR(UI4,0,UINT,0,I4,0);
5007 rbstr = SysAllocString(szFalse);
5008 VARXOR(UI4,0,BSTR,rbstr,I4,0);
5009 VARXOR(UI4,0xffffffff,BSTR,rbstr,I4,-1);
5010 SysFreeString(rbstr);
5011 rbstr = SysAllocString(szTrue);
5012 VARXOR(UI4,0,BSTR,rbstr,I4,-1);
5013 VARXOR(UI4,0xffffffff,BSTR,rbstr,I4,0);
5014 SysFreeString(rbstr);
5015 VARXORCY(UI4,0xffffffff,10000,I4,-2);
5016 VARXORCY(UI4,0xffffffff,0,I4,-1);
5017 VARXORCY(UI4,0,0,I4,0);
5019 VARXOR(R4,-1,R4,-1,I4,0);
5020 VARXOR(R4,-1,R4,0,I4,-1);
5021 VARXOR(R4,0,R4,0,I4,0);
5022 VARXOR(R4,-1,R8,-1,I4,0);
5023 VARXOR(R4,-1,R8,0,I4,-1);
5024 VARXOR(R4,0,R8,0,I4,0);
5025 VARXOR(R4,-1,DATE,-1,I4,0);
5026 VARXOR(R4,-1,DATE,0,I4,-1);
5027 VARXOR(R4,0,DATE,0,I4,0);
5028 if (has_i8)
5030 VARXOR(R4,-1,I8,-1,I8,0);
5031 VARXOR(R4,-1,I8,0,I8,-1);
5032 VARXOR(R4,0,I8,0,I8,0);
5033 VARXOR(R4,-1,UI8,0,I4,-1);
5034 VARXOR(R4,0,UI8,0,I4,0);
5036 VARXOR(R4,-1,INT,-1,I4,0);
5037 VARXOR(R4,-1,INT,0,I4,-1);
5038 VARXOR(R4,0,INT,0,I4,0);
5039 VARXOR(R4,-1,UINT,0xffffffff,I4,0);
5040 VARXOR(R4,-1,UINT,0,I4,-1);
5041 VARXOR(R4,0,UINT,0,I4,0);
5042 rbstr = SysAllocString(szFalse);
5043 VARXOR(R4,0,BSTR,rbstr,I4,0);
5044 VARXOR(R4,-1,BSTR,rbstr,I4,-1);
5045 SysFreeString(rbstr);
5046 rbstr = SysAllocString(szTrue);
5047 VARXOR(R4,0,BSTR,rbstr,I4,-1);
5048 VARXOR(R4,-1,BSTR,rbstr,I4,0);
5049 SysFreeString(rbstr);
5050 VARXORCY(R4,-1,10000,I4,-2);
5051 VARXORCY(R4,-1,0,I4,-1);
5052 VARXORCY(R4,0,0,I4,0);
5054 VARXOR(R8,-1,R8,-1,I4,0);
5055 VARXOR(R8,-1,R8,0,I4,-1);
5056 VARXOR(R8,0,R8,0,I4,0);
5057 VARXOR(R8,-1,DATE,-1,I4,0);
5058 VARXOR(R8,-1,DATE,0,I4,-1);
5059 VARXOR(R8,0,DATE,0,I4,0);
5060 if (has_i8)
5062 VARXOR(R8,-1,I8,-1,I8,0);
5063 VARXOR(R8,-1,I8,0,I8,-1);
5064 VARXOR(R8,0,I8,0,I8,0);
5065 VARXOR(R8,-1,UI8,0,I4,-1);
5066 VARXOR(R8,0,UI8,0,I4,0);
5068 VARXOR(R8,-1,INT,-1,I4,0);
5069 VARXOR(R8,-1,INT,0,I4,-1);
5070 VARXOR(R8,0,INT,0,I4,0);
5071 VARXOR(R8,-1,UINT,0xffffffff,I4,0);
5072 VARXOR(R8,-1,UINT,0,I4,-1);
5073 VARXOR(R8,0,UINT,0,I4,0);
5074 rbstr = SysAllocString(szFalse);
5075 VARXOR(R8,0,BSTR,rbstr,I4,0);
5076 VARXOR(R8,-1,BSTR,rbstr,I4,-1);
5077 SysFreeString(rbstr);
5078 rbstr = SysAllocString(szTrue);
5079 VARXOR(R8,0,BSTR,rbstr,I4,-1);
5080 VARXOR(R8,-1,BSTR,rbstr,I4,0);
5081 SysFreeString(rbstr);
5082 VARXORCY(R8,-1,10000,I4,-2);
5083 VARXORCY(R8,-1,0,I4,-1);
5084 VARXORCY(R8,0,0,I4,0);
5086 VARXOR(DATE,-1,DATE,-1,I4,0);
5087 VARXOR(DATE,-1,DATE,0,I4,-1);
5088 VARXOR(DATE,0,DATE,0,I4,0);
5089 if (has_i8)
5091 VARXOR(DATE,-1,I8,-1,I8,0);
5092 VARXOR(DATE,-1,I8,0,I8,-1);
5093 VARXOR(DATE,0,I8,0,I8,0);
5094 VARXOR(DATE,-1,UI8,0,I4,-1);
5095 VARXOR(DATE,0,UI8,0,I4,0);
5097 VARXOR(DATE,-1,INT,-1,I4,0);
5098 VARXOR(DATE,-1,INT,0,I4,-1);
5099 VARXOR(DATE,0,INT,0,I4,0);
5100 VARXOR(DATE,-1,UINT,0xffffffff,I4,0);
5101 VARXOR(DATE,-1,UINT,0,I4,-1);
5102 VARXOR(DATE,0,UINT,0,I4,0);
5103 rbstr = SysAllocString(szFalse);
5104 VARXOR(DATE,0,BSTR,rbstr,I4,0);
5105 VARXOR(DATE,-1,BSTR,rbstr,I4,-1);
5106 SysFreeString(rbstr);
5107 rbstr = SysAllocString(szTrue);
5108 VARXOR(DATE,0,BSTR,rbstr,I4,-1);
5109 VARXOR(DATE,-1,BSTR,rbstr,I4,0);
5110 SysFreeString(rbstr);
5111 VARXORCY(DATE,-1,10000,I4,-2);
5112 VARXORCY(DATE,-1,0,I4,-1);
5113 VARXORCY(DATE,0,0,I4,0);
5115 if (has_i8)
5117 VARXOR(I8,-1,I8,-1,I8,0);
5118 VARXOR(I8,-1,I8,0,I8,-1);
5119 VARXOR(I8,0,I8,0,I8,0);
5120 VARXOR(I8,-1,UI8,0,I8,-1);
5121 VARXOR(I8,0,UI8,0,I8,0);
5122 VARXOR(I8,-1,UINT,0,I8,-1);
5123 VARXOR(I8,0,UINT,0,I8,0);
5124 rbstr = SysAllocString(szFalse);
5125 VARXOR(I8,0,BSTR,rbstr,I8,0);
5126 VARXOR(I8,-1,BSTR,rbstr,I8,-1);
5127 SysFreeString(rbstr);
5128 rbstr = SysAllocString(szTrue);
5129 VARXOR(I8,0,BSTR,rbstr,I8,-1);
5130 VARXOR(I8,-1,BSTR,rbstr,I8,0);
5131 SysFreeString(rbstr);
5132 VARXORCY(I8,-1,10000,I8,-2);
5133 VARXORCY(I8,-1,0,I8,-1);
5134 VARXORCY(I8,0,0,I8,0);
5136 VARXOR(UI8,0xffff,UI8,0xffff,I4,0);
5137 VARXOR(UI8,0xffff,UI8,0,I4,0xffff);
5138 VARXOR(UI8,0,UI8,0,I4,0);
5139 VARXOR(UI8,0xffff,INT,-1,I4,-65536);
5140 VARXOR(UI8,0xffff,INT,0,I4,0xffff);
5141 VARXOR(UI8,0,INT,0,I4,0);
5142 VARXOR(UI8,0xffff,UINT,0xffff,I4,0);
5143 VARXOR(UI8,0xffff,UINT,0,I4,0xffff);
5144 VARXOR(UI8,0,UINT,0,I4,0);
5145 rbstr = SysAllocString(szFalse);
5146 VARXOR(UI8,0,BSTR,rbstr,I4,0);
5147 VARXOR(UI8,0xffff,BSTR,rbstr,I4,0xffff);
5148 SysFreeString(rbstr);
5149 rbstr = SysAllocString(szTrue);
5150 VARXOR(UI8,0,BSTR,rbstr,I4,-1);
5151 VARXOR(UI8,0xffff,BSTR,rbstr,I4,-65536);
5152 SysFreeString(rbstr);
5153 VARXORCY(UI8,0xffff,10000,I4,65534);
5154 VARXORCY(UI8,0xffff,0,I4,0xffff);
5155 VARXORCY(UI8,0,0,I4,0);
5158 VARXOR(INT,-1,INT,-1,I4,0);
5159 VARXOR(INT,-1,INT,0,I4,-1);
5160 VARXOR(INT,0,INT,0,I4,0);
5161 VARXOR(INT,-1,UINT,0xffff,I4,-65536);
5162 VARXOR(INT,-1,UINT,0,I4,-1);
5163 VARXOR(INT,0,UINT,0,I4,0);
5164 rbstr = SysAllocString(szFalse);
5165 VARXOR(INT,0,BSTR,rbstr,I4,0);
5166 VARXOR(INT,-1,BSTR,rbstr,I4,-1);
5167 SysFreeString(rbstr);
5168 rbstr = SysAllocString(szTrue);
5169 VARXOR(INT,0,BSTR,rbstr,I4,-1);
5170 VARXOR(INT,-1,BSTR,rbstr,I4,0);
5171 SysFreeString(rbstr);
5172 VARXORCY(INT,-1,10000,I4,-2);
5173 VARXORCY(INT,-1,0,I4,-1);
5174 VARXORCY(INT,0,0,I4,0);
5176 VARXOR(UINT,0xffff,UINT,0xffff,I4,0);
5177 VARXOR(UINT,0xffff,UINT,0,I4,0xffff);
5178 VARXOR(UINT,0,UINT,0,I4,0);
5179 rbstr = SysAllocString(szFalse);
5180 VARXOR(UINT,0,BSTR,rbstr,I4,0);
5181 VARXOR(UINT,0xffff,BSTR,rbstr,I4,0xffff);
5182 SysFreeString(rbstr);
5183 rbstr = SysAllocString(szTrue);
5184 VARXOR(UINT,0,BSTR,rbstr,I4,-1);
5185 VARXOR(UINT,0xffff,BSTR,rbstr,I4,-65536);
5186 SysFreeString(rbstr);
5187 VARXORCY(UINT,0xffff,10000,I4,65534);
5188 VARXORCY(UINT,0xffff,0,I4,0xffff);
5189 VARXORCY(UINT,0,0,I4,0);
5191 lbstr = SysAllocString(szFalse);
5192 rbstr = SysAllocString(szFalse);
5193 VARXOR(BSTR,lbstr,BSTR,rbstr,BOOL,0);
5194 SysFreeString(rbstr);
5195 rbstr = SysAllocString(szTrue);
5196 VARXOR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_TRUE);
5197 SysFreeString(lbstr);
5198 lbstr = SysAllocString(szTrue);
5199 VARXOR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_FALSE);
5200 VARXORCY(BSTR,lbstr,10000,I4,-2);
5201 SysFreeString(lbstr);
5202 lbstr = SysAllocString(szFalse);
5203 VARXORCY(BSTR,lbstr,10000,I4,1);
5204 SysFreeString(lbstr);
5205 SysFreeString(rbstr);
5208 static HRESULT (WINAPI *pVarOr)(LPVARIANT,LPVARIANT,LPVARIANT);
5210 #define VAROR(vt1,val1,vt2,val2,rvt,rval) \
5211 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
5212 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
5213 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
5214 test_var_call2( __LINE__, pVarOr, &left, &right, &exp )
5216 #define VARORCY(vt1,val1,val2,rvt,rval) \
5217 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
5218 V_VT(&right) = VT_CY; V_CY(&right).int64 = val2; \
5219 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
5220 test_var_call2( __LINE__, pVarOr, &left, &right, &exp )
5222 static void test_VarOr(void)
5224 static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
5225 static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
5226 VARIANT left, right, exp, result;
5227 BSTR lbstr, rbstr;
5228 VARTYPE i;
5229 HRESULT hres;
5231 CHECKPTR(VarOr);
5233 /* Test all possible flag/vt combinations & the resulting vt type */
5234 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
5236 VARTYPE leftvt, rightvt, resvt;
5238 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
5241 SKIPTESTS(leftvt);
5243 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
5245 BOOL bFail = FALSE;
5247 SKIPTESTS(rightvt);
5249 if (leftvt == VT_BSTR || rightvt == VT_BSTR ||
5250 leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
5251 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN)
5252 continue;
5254 memset(&left, 0, sizeof(left));
5255 memset(&right, 0, sizeof(right));
5256 V_VT(&left) = leftvt | ExtraFlags[i];
5257 V_VT(&right) = rightvt | ExtraFlags[i];
5258 V_VT(&result) = VT_EMPTY;
5259 resvt = VT_I4;
5261 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
5262 !IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
5263 !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
5264 leftvt == VT_CLSID || rightvt == VT_CLSID ||
5265 leftvt == VT_RECORD || rightvt == VT_RECORD ||
5266 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
5267 leftvt == VT_ERROR || rightvt == VT_ERROR)
5269 bFail = TRUE;
5271 if (leftvt == VT_EMPTY || rightvt == VT_EMPTY)
5273 if (leftvt == rightvt ||
5274 leftvt == VT_I2 || rightvt == VT_I2 ||
5275 leftvt == VT_UI1 || rightvt == VT_UI1 ||
5276 leftvt == VT_BOOL || rightvt == VT_BOOL)
5277 resvt = VT_I2;
5278 else if (leftvt == VT_NULL || rightvt == VT_NULL)
5279 resvt = VT_NULL;
5280 else if (leftvt == VT_I8 || rightvt == VT_I8)
5281 resvt = VT_I8;
5283 else if (leftvt == VT_NULL || rightvt == VT_NULL)
5285 resvt = VT_NULL;
5287 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
5289 if (leftvt == rightvt)
5290 resvt = VT_UI1;
5291 else if (leftvt == rightvt ||
5292 leftvt == VT_I2 || rightvt == VT_I2 ||
5293 leftvt == VT_BOOL || rightvt == VT_BOOL)
5295 resvt = VT_I2;
5297 else if (leftvt == VT_I8 || rightvt == VT_I8)
5298 resvt = VT_I8;
5300 else if (leftvt == VT_I2 || rightvt == VT_I2)
5302 if (leftvt == rightvt ||
5303 leftvt == VT_BOOL || rightvt == VT_BOOL)
5304 resvt = VT_I2;
5305 else if (leftvt == VT_I8 || rightvt == VT_I8)
5306 resvt = VT_I8;
5308 else if (leftvt == VT_BOOL && rightvt == VT_BOOL)
5310 resvt = VT_BOOL;
5312 else if (leftvt == VT_I8 || rightvt == VT_I8)
5314 if (leftvt == VT_INT || rightvt == VT_INT)
5315 bFail = TRUE;
5316 else
5317 resvt = VT_I8;
5319 hres = pVarOr(&left, &right, &result);
5320 if (bFail)
5321 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
5322 "VarOr: %d|0x%X, %d|0x%X: Expected failure, got 0x%X vt %d\n",
5323 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres,
5324 V_VT(&result));
5325 else
5326 ok(hres == S_OK && V_VT(&result) == resvt,
5327 "VarOr: %d|0x%X, %d|0x%X: expected S_OK, vt %d, got 0x%X vt %d\n",
5328 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], resvt, hres,
5329 V_VT(&result));
5334 /* Test returned values. Since we know the returned type is correct
5335 * and that we handle all combinations of invalid types, just check
5336 * that good type combinations produce the desired value.
5337 * FIXME: Test VT_DECIMAL/VT_DISPATCH
5339 VAROR(EMPTY,0,EMPTY,0,I2,0);
5340 VAROR(EMPTY,1,EMPTY,0,I2,0);
5341 VAROR(EMPTY,0,NULL,0,NULL,0);
5342 VAROR(EMPTY,0,I1,0,I4,0);
5343 VAROR(EMPTY,0,I1,1,I4,1);
5344 VAROR(EMPTY,0,UI1,0,I2,0);
5345 VAROR(EMPTY,0,UI1,1,I2,1);
5346 VAROR(EMPTY,0,I2,0,I2,0);
5347 VAROR(EMPTY,0,I2,1,I2,1);
5348 VAROR(EMPTY,0,UI2,0,I4,0);
5349 VAROR(EMPTY,0,UI2,1,I4,1);
5350 VAROR(EMPTY,0,I4,0,I4,0);
5351 VAROR(EMPTY,0,I4,1,I4,1);
5352 VAROR(EMPTY,0,UI4,0,I4,0);
5353 VAROR(EMPTY,0,UI4,1,I4,1);
5354 if (has_i8)
5356 VAROR(EMPTY,0,I8,0,I8,0);
5357 VAROR(EMPTY,0,I8,1,I8,1);
5358 VAROR(EMPTY,0,UI8,0,I4,0);
5359 VAROR(EMPTY,0,UI8,1,I4,1);
5361 VAROR(EMPTY,0,INT,0,I4,0);
5362 VAROR(EMPTY,0,INT,1,I4,1);
5363 VAROR(EMPTY,0,UINT,0,I4,0);
5364 VAROR(EMPTY,0,UINT,1,I4,1);
5365 VAROR(EMPTY,0,BOOL,0,I2,0);
5366 VAROR(EMPTY,0,BOOL,1,I2,1);
5367 VAROR(EMPTY,0,R4,0,I4,0);
5368 VAROR(EMPTY,0,R4,1,I4,1);
5369 VAROR(EMPTY,0,R8,0,I4,0);
5370 VAROR(EMPTY,0,R8,1,I4,1);
5371 rbstr = SysAllocString(szFalse);
5372 VAROR(EMPTY,0,BSTR,rbstr,I2,0);
5373 SysFreeString(rbstr);
5374 rbstr = SysAllocString(szTrue);
5375 VAROR(EMPTY,0,BSTR,rbstr,I2,-1);
5376 SysFreeString(rbstr);
5377 VARORCY(EMPTY,0,10000,I4,1);
5379 /* NULL OR 0 = NULL. NULL OR n = n */
5380 VAROR(NULL,0,NULL,0,NULL,0);
5381 VAROR(NULL,1,NULL,0,NULL,0);
5382 VAROR(NULL,0,I1,0,NULL,0);
5383 VAROR(NULL,0,I1,1,I4,1);
5384 VAROR(NULL,0,UI1,0,NULL,0);
5385 VAROR(NULL,0,UI1,1,UI1,1);
5386 VAROR(NULL,0,I2,0,NULL,0);
5387 VAROR(NULL,0,I2,1,I2,1);
5388 VAROR(NULL,0,UI2,0,NULL,0);
5389 VAROR(NULL,0,UI2,1,I4,1);
5390 VAROR(NULL,0,I4,0,NULL,0);
5391 VAROR(NULL,0,I4,1,I4,1);
5392 VAROR(NULL,0,UI4,0,NULL,0);
5393 VAROR(NULL,0,UI4,1,I4,1);
5394 if (has_i8)
5396 VAROR(NULL,0,I8,0,NULL,0);
5397 VAROR(NULL,0,I8,1,I8,1);
5398 VAROR(NULL,0,UI8,0,NULL,0);
5399 VAROR(NULL,0,UI8,1,I4,1);
5401 VAROR(NULL,0,INT,0,NULL,0);
5402 VAROR(NULL,0,INT,1,I4,1);
5403 VAROR(NULL,0,UINT,0,NULL,0);
5404 VAROR(NULL,0,UINT,1,I4,1);
5405 VAROR(NULL,0,BOOL,0,NULL,0);
5406 VAROR(NULL,0,BOOL,1,BOOL,1);
5407 VAROR(NULL,0,R4,0,NULL,0);
5408 VAROR(NULL,0,R4,1,I4,1);
5409 VAROR(NULL,0,R8,0,NULL,0);
5410 VAROR(NULL,0,R8,1,I4,1);
5411 rbstr = SysAllocString(szFalse);
5412 VAROR(NULL,0,BSTR,rbstr,NULL,0);
5413 SysFreeString(rbstr);
5414 rbstr = SysAllocString(szTrue);
5415 VAROR(NULL,0,BSTR,rbstr,BOOL,VARIANT_TRUE);
5416 SysFreeString(rbstr);
5417 VARORCY(NULL,0,10000,I4,1);
5418 VARORCY(NULL,0,0,NULL,0);
5420 VAROR(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
5421 VAROR(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE);
5422 VAROR(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
5423 VAROR(BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE);
5424 /* Assume x,y & y,x are the same from now on to reduce the number of tests */
5425 VAROR(BOOL,VARIANT_TRUE,I1,-1,I4,-1);
5426 VAROR(BOOL,VARIANT_TRUE,I1,0,I4,-1);
5427 VAROR(BOOL,VARIANT_FALSE,I1,0,I4,0);
5428 VAROR(BOOL,VARIANT_TRUE,UI1,255,I2,-1);
5429 VAROR(BOOL,VARIANT_TRUE,UI1,0,I2,-1);
5430 VAROR(BOOL,VARIANT_FALSE,UI1,0,I2,0);
5431 VAROR(BOOL,VARIANT_TRUE,I2,-1,I2,-1);
5432 VAROR(BOOL,VARIANT_TRUE,I2,0,I2,-1);
5433 VAROR(BOOL,VARIANT_FALSE,I2,0,I2,0);
5434 VAROR(BOOL,VARIANT_TRUE,UI2,65535,I4,-1);
5435 VAROR(BOOL,VARIANT_TRUE,UI2,0,I4,-1);
5436 VAROR(BOOL,VARIANT_FALSE,UI2,0,I4,0);
5437 VAROR(BOOL,VARIANT_TRUE,I4,-1,I4,-1);
5438 VAROR(BOOL,VARIANT_TRUE,I4,0,I4,-1);
5439 VAROR(BOOL,VARIANT_FALSE,I4,0,I4,0);
5440 VAROR(BOOL,VARIANT_TRUE,UI4,0xffffffff,I4,-1);
5441 VAROR(BOOL,VARIANT_TRUE,UI4,0,I4,-1);
5442 VAROR(BOOL,VARIANT_FALSE,UI4,0,I4,0);
5443 VAROR(BOOL,VARIANT_TRUE,R4,-1,I4,-1);
5444 VAROR(BOOL,VARIANT_TRUE,R4,0,I4,-1);
5445 VAROR(BOOL,VARIANT_FALSE,R4,0,I4,0);
5446 VAROR(BOOL,VARIANT_TRUE,R8,-1,I4,-1);
5447 VAROR(BOOL,VARIANT_TRUE,R8,0,I4,-1);
5448 VAROR(BOOL,VARIANT_FALSE,R8,0,I4,0);
5449 VAROR(BOOL,VARIANT_TRUE,DATE,-1,I4,-1);
5450 VAROR(BOOL,VARIANT_TRUE,DATE,0,I4,-1);
5451 VAROR(BOOL,VARIANT_FALSE,DATE,0,I4,0);
5452 if (has_i8)
5454 VAROR(BOOL,VARIANT_TRUE,I8,-1,I8,-1);
5455 VAROR(BOOL,VARIANT_TRUE,I8,0,I8,-1);
5456 VAROR(BOOL,VARIANT_FALSE,I8,0,I8,0);
5457 /* This returns DISP_E_OVERFLOW which indicates that a conversion
5458 * to I4 is performed.
5460 /* VAROR(BOOL,VARIANT_TRUE,UI8,-1,I4,-1); */
5461 VAROR(BOOL,VARIANT_TRUE,UI8,0,I4,-1);
5462 VAROR(BOOL,VARIANT_FALSE,UI8,0,I4,0);
5464 VAROR(BOOL,VARIANT_TRUE,INT,-1,I4,-1);
5465 VAROR(BOOL,VARIANT_TRUE,INT,0,I4,-1);
5466 VAROR(BOOL,VARIANT_FALSE,INT,0,I4,0);
5467 VAROR(BOOL,VARIANT_TRUE,UINT,0xffffffff,I4,-1);
5468 VAROR(BOOL,VARIANT_TRUE,UINT,0,I4,-1);
5469 VAROR(BOOL,VARIANT_FALSE,UINT,0,I4,0);
5470 rbstr = SysAllocString(szFalse);
5471 VAROR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_FALSE);
5472 VAROR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_TRUE);
5473 SysFreeString(rbstr);
5474 rbstr = SysAllocString(szTrue);
5475 VAROR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_TRUE);
5476 VAROR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_TRUE);
5477 SysFreeString(rbstr);
5478 VARORCY(BOOL,VARIANT_TRUE,10000,I4,-1);
5479 VARORCY(BOOL,VARIANT_TRUE,0,I4,-1);
5480 VARORCY(BOOL,VARIANT_FALSE,0,I4,0);
5482 VAROR(I1,-1,I1,-1,I4,-1);
5483 VAROR(I1,-1,I1,0,I4,-1);
5484 VAROR(I1,0,I1,0,I4,0);
5485 VAROR(I1,-1,UI1,255,I4,-1);
5486 VAROR(I1,-1,UI1,0,I4,-1);
5487 VAROR(I1,0,UI1,0,I4,0);
5488 VAROR(I1,-1,I2,-1,I4,-1);
5489 VAROR(I1,-1,I2,0,I4,-1);
5490 VAROR(I1,0,I2,0,I4,0);
5491 VAROR(I1,-1,UI2,65535,I4,-1);
5492 VAROR(I1,-1,UI2,0,I4,-1);
5493 VAROR(I1,0,UI2,0,I4,0);
5494 VAROR(I1,-1,I4,-1,I4,-1);
5495 VAROR(I1,-1,I4,0,I4,-1);
5496 VAROR(I1,0,I4,0,I4,0);
5497 VAROR(I1,-1,UI4,0xffffffff,I4,-1);
5498 VAROR(I1,-1,UI4,0,I4,-1);
5499 VAROR(I1,0,UI4,0,I4,0);
5500 VAROR(I1,-1,R4,-1,I4,-1);
5501 VAROR(I1,-1,R4,0,I4,-1);
5502 VAROR(I1,0,R4,0,I4,0);
5503 VAROR(I1,-1,R8,-1,I4,-1);
5504 VAROR(I1,-1,R8,0,I4,-1);
5505 VAROR(I1,0,R8,0,I4,0);
5506 VAROR(I1,-1,DATE,-1,I4,-1);
5507 VAROR(I1,-1,DATE,0,I4,-1);
5508 VAROR(I1,0,DATE,0,I4,0);
5509 if (has_i8)
5511 VAROR(I1,-1,I8,-1,I8,-1);
5512 VAROR(I1,-1,I8,0,I8,-1);
5513 VAROR(I1,0,I8,0,I8,0);
5514 VAROR(I1,-1,UI8,0,I4,-1);
5515 VAROR(I1,0,UI8,0,I4,0);
5517 VAROR(I1,-1,INT,-1,I4,-1);
5518 VAROR(I1,-1,INT,0,I4,-1);
5519 VAROR(I1,0,INT,0,I4,0);
5520 VAROR(I1,-1,UINT,0xffffffff,I4,-1);
5521 VAROR(I1,-1,UINT,0,I4,-1);
5522 VAROR(I1,0,UINT,0,I4,0);
5523 rbstr = SysAllocString(szFalse);
5524 VAROR(I1,0,BSTR,rbstr,I4,0);
5525 VAROR(I1,-1,BSTR,rbstr,I4,-1);
5526 SysFreeString(rbstr);
5527 rbstr = SysAllocString(szTrue);
5528 VAROR(I1,0,BSTR,rbstr,I4,-1);
5529 VAROR(I1,-1,BSTR,rbstr,I4,-1);
5530 SysFreeString(rbstr);
5531 VARORCY(I1,-1,10000,I4,-1);
5532 VARORCY(I1,-1,0,I4,-1);
5533 VARORCY(I1,0,0,I4,0);
5535 VAROR(UI1,255,UI1,255,UI1,255);
5536 VAROR(UI1,255,UI1,0,UI1,255);
5537 VAROR(UI1,0,UI1,0,UI1,0);
5538 VAROR(UI1,255,I2,-1,I2,-1);
5539 VAROR(UI1,255,I2,0,I2,255);
5540 VAROR(UI1,0,I2,0,I2,0);
5541 VAROR(UI1,255,UI2,65535,I4,65535);
5542 VAROR(UI1,255,UI2,0,I4,255);
5543 VAROR(UI1,0,UI2,0,I4,0);
5544 VAROR(UI1,255,I4,-1,I4,-1);
5545 VAROR(UI1,255,I4,0,I4,255);
5546 VAROR(UI1,0,I4,0,I4,0);
5547 VAROR(UI1,255,UI4,0xffffffff,I4,-1);
5548 VAROR(UI1,255,UI4,0,I4,255);
5549 VAROR(UI1,0,UI4,0,I4,0);
5550 VAROR(UI1,255,R4,-1,I4,-1);
5551 VAROR(UI1,255,R4,0,I4,255);
5552 VAROR(UI1,0,R4,0,I4,0);
5553 VAROR(UI1,255,R8,-1,I4,-1);
5554 VAROR(UI1,255,R8,0,I4,255);
5555 VAROR(UI1,0,R8,0,I4,0);
5556 VAROR(UI1,255,DATE,-1,I4,-1);
5557 VAROR(UI1,255,DATE,0,I4,255);
5558 VAROR(UI1,0,DATE,0,I4,0);
5559 if (has_i8)
5561 VAROR(UI1,255,I8,-1,I8,-1);
5562 VAROR(UI1,255,I8,0,I8,255);
5563 VAROR(UI1,0,I8,0,I8,0);
5564 VAROR(UI1,255,UI8,0,I4,255);
5565 VAROR(UI1,0,UI8,0,I4,0);
5567 VAROR(UI1,255,INT,-1,I4,-1);
5568 VAROR(UI1,255,INT,0,I4,255);
5569 VAROR(UI1,0,INT,0,I4,0);
5570 VAROR(UI1,255,UINT,0xffffffff,I4,-1);
5571 VAROR(UI1,255,UINT,0,I4,255);
5572 VAROR(UI1,0,UINT,0,I4,0);
5573 rbstr = SysAllocString(szFalse);
5574 VAROR(UI1,0,BSTR,rbstr,I2,0);
5575 VAROR(UI1,255,BSTR,rbstr,I2,255);
5576 SysFreeString(rbstr);
5577 rbstr = SysAllocString(szTrue);
5578 VAROR(UI1,0,BSTR,rbstr,I2,-1);
5579 VAROR(UI1,255,BSTR,rbstr,I2,-1);
5580 SysFreeString(rbstr);
5581 VARORCY(UI1,255,10000,I4,255);
5582 VARORCY(UI1,255,0,I4,255);
5583 VARORCY(UI1,0,0,I4,0);
5585 VAROR(I2,-1,I2,-1,I2,-1);
5586 VAROR(I2,-1,I2,0,I2,-1);
5587 VAROR(I2,0,I2,0,I2,0);
5588 VAROR(I2,-1,UI2,65535,I4,-1);
5589 VAROR(I2,-1,UI2,0,I4,-1);
5590 VAROR(I2,0,UI2,0,I4,0);
5591 VAROR(I2,-1,I4,-1,I4,-1);
5592 VAROR(I2,-1,I4,0,I4,-1);
5593 VAROR(I2,0,I4,0,I4,0);
5594 VAROR(I2,-1,UI4,0xffffffff,I4,-1);
5595 VAROR(I2,-1,UI4,0,I4,-1);
5596 VAROR(I2,0,UI4,0,I4,0);
5597 VAROR(I2,-1,R4,-1,I4,-1);
5598 VAROR(I2,-1,R4,0,I4,-1);
5599 VAROR(I2,0,R4,0,I4,0);
5600 VAROR(I2,-1,R8,-1,I4,-1);
5601 VAROR(I2,-1,R8,0,I4,-1);
5602 VAROR(I2,0,R8,0,I4,0);
5603 VAROR(I2,-1,DATE,-1,I4,-1);
5604 VAROR(I2,-1,DATE,0,I4,-1);
5605 VAROR(I2,0,DATE,0,I4,0);
5606 if (has_i8)
5608 VAROR(I2,-1,I8,-1,I8,-1);
5609 VAROR(I2,-1,I8,0,I8,-1);
5610 VAROR(I2,0,I8,0,I8,0);
5611 VAROR(I2,-1,UI8,0,I4,-1);
5612 VAROR(I2,0,UI8,0,I4,0);
5614 VAROR(I2,-1,INT,-1,I4,-1);
5615 VAROR(I2,-1,INT,0,I4,-1);
5616 VAROR(I2,0,INT,0,I4,0);
5617 VAROR(I2,-1,UINT,0xffffffff,I4,-1);
5618 VAROR(I2,-1,UINT,0,I4,-1);
5619 VAROR(I2,0,UINT,0,I4,0);
5620 rbstr = SysAllocString(szFalse);
5621 VAROR(I2,0,BSTR,rbstr,I2,0);
5622 VAROR(I2,-1,BSTR,rbstr,I2,-1);
5623 SysFreeString(rbstr);
5624 rbstr = SysAllocString(szTrue);
5625 VAROR(I2,0,BSTR,rbstr,I2,-1);
5626 VAROR(I2,-1,BSTR,rbstr,I2,-1);
5627 SysFreeString(rbstr);
5628 VARORCY(I2,-1,10000,I4,-1);
5629 VARORCY(I2,-1,0,I4,-1);
5630 VARORCY(I2,0,0,I4,0);
5632 VAROR(UI2,65535,UI2,65535,I4,65535);
5633 VAROR(UI2,65535,UI2,0,I4,65535);
5634 VAROR(UI2,0,UI2,0,I4,0);
5635 VAROR(UI2,65535,I4,-1,I4,-1);
5636 VAROR(UI2,65535,I4,0,I4,65535);
5637 VAROR(UI2,0,I4,0,I4,0);
5638 VAROR(UI2,65535,UI4,0xffffffff,I4,-1);
5639 VAROR(UI2,65535,UI4,0,I4,65535);
5640 VAROR(UI2,0,UI4,0,I4,0);
5641 VAROR(UI2,65535,R4,-1,I4,-1);
5642 VAROR(UI2,65535,R4,0,I4,65535);
5643 VAROR(UI2,0,R4,0,I4,0);
5644 VAROR(UI2,65535,R8,-1,I4,-1);
5645 VAROR(UI2,65535,R8,0,I4,65535);
5646 VAROR(UI2,0,R8,0,I4,0);
5647 VAROR(UI2,65535,DATE,-1,I4,-1);
5648 VAROR(UI2,65535,DATE,0,I4,65535);
5649 VAROR(UI2,0,DATE,0,I4,0);
5650 if (has_i8)
5652 VAROR(UI2,65535,I8,-1,I8,-1);
5653 VAROR(UI2,65535,I8,0,I8,65535);
5654 VAROR(UI2,0,I8,0,I8,0);
5655 VAROR(UI2,65535,UI8,0,I4,65535);
5656 VAROR(UI2,0,UI8,0,I4,0);
5658 VAROR(UI2,65535,INT,-1,I4,-1);
5659 VAROR(UI2,65535,INT,0,I4,65535);
5660 VAROR(UI2,0,INT,0,I4,0);
5661 VAROR(UI2,65535,UINT,0xffffffff,I4,-1);
5662 VAROR(UI2,65535,UINT,0,I4,65535);
5663 VAROR(UI2,0,UINT,0,I4,0);
5664 rbstr = SysAllocString(szFalse);
5665 VAROR(UI2,0,BSTR,rbstr,I4,0);
5666 VAROR(UI2,65535,BSTR,rbstr,I4,65535);
5667 SysFreeString(rbstr);
5668 rbstr = SysAllocString(szTrue);
5669 VAROR(UI2,0,BSTR,rbstr,I4,-1);
5670 VAROR(UI2,65535,BSTR,rbstr,I4,-1);
5671 SysFreeString(rbstr);
5672 VARORCY(UI2,65535,10000,I4,65535);
5673 VARORCY(UI2,65535,0,I4,65535);
5674 VARORCY(UI2,0,0,I4,0);
5676 VAROR(I4,-1,I4,-1,I4,-1);
5677 VAROR(I4,-1,I4,0,I4,-1);
5678 VAROR(I4,0,I4,0,I4,0);
5679 VAROR(I4,-1,UI4,0xffffffff,I4,-1);
5680 VAROR(I4,-1,UI4,0,I4,-1);
5681 VAROR(I4,0,UI4,0,I4,0);
5682 VAROR(I4,-1,R4,-1,I4,-1);
5683 VAROR(I4,-1,R4,0,I4,-1);
5684 VAROR(I4,0,R4,0,I4,0);
5685 VAROR(I4,-1,R8,-1,I4,-1);
5686 VAROR(I4,-1,R8,0,I4,-1);
5687 VAROR(I4,0,R8,0,I4,0);
5688 VAROR(I4,-1,DATE,-1,I4,-1);
5689 VAROR(I4,-1,DATE,0,I4,-1);
5690 VAROR(I4,0,DATE,0,I4,0);
5691 if (has_i8)
5693 VAROR(I4,-1,I8,-1,I8,-1);
5694 VAROR(I4,-1,I8,0,I8,-1);
5695 VAROR(I4,0,I8,0,I8,0);
5696 VAROR(I4,-1,UI8,0,I4,-1);
5697 VAROR(I4,0,UI8,0,I4,0);
5699 VAROR(I4,-1,INT,-1,I4,-1);
5700 VAROR(I4,-1,INT,0,I4,-1);
5701 VAROR(I4,0,INT,0,I4,0);
5702 VAROR(I4,-1,UINT,0xffffffff,I4,-1);
5703 VAROR(I4,-1,UINT,0,I4,-1);
5704 VAROR(I4,0,UINT,0,I4,0);
5705 rbstr = SysAllocString(szFalse);
5706 VAROR(I4,0,BSTR,rbstr,I4,0);
5707 VAROR(I4,-1,BSTR,rbstr,I4,-1);
5708 SysFreeString(rbstr);
5709 rbstr = SysAllocString(szTrue);
5710 VAROR(I4,0,BSTR,rbstr,I4,-1);
5711 VAROR(I4,-1,BSTR,rbstr,I4,-1);
5712 SysFreeString(rbstr);
5713 VARORCY(I4,-1,10000,I4,-1);
5714 VARORCY(I4,-1,0,I4,-1);
5715 VARORCY(I4,0,0,I4,0);
5717 VAROR(UI4,0xffffffff,UI4,0xffffffff,I4,-1);
5718 VAROR(UI4,0xffffffff,UI4,0,I4,-1);
5719 VAROR(UI4,0,UI4,0,I4,0);
5720 VAROR(UI4,0xffffffff,R4,-1,I4,-1);
5721 VAROR(UI4,0xffffffff,R4,0,I4,-1);
5722 VAROR(UI4,0,R4,0,I4,0);
5723 VAROR(UI4,0xffffffff,R8,-1,I4,-1);
5724 VAROR(UI4,0xffffffff,R8,0,I4,-1);
5725 VAROR(UI4,0,R8,0,I4,0);
5726 VAROR(UI4,0xffffffff,DATE,-1,I4,-1);
5727 VAROR(UI4,0xffffffff,DATE,0,I4,-1);
5728 VAROR(UI4,0,DATE,0,I4,0);
5729 if (has_i8)
5731 VAROR(UI4,0xffffffff,I8,-1,I8,-1);
5732 VAROR(UI4,0xffffffff,I8,0,I8,0xffffffff);
5733 VAROR(UI4,0,I8,0,I8,0);
5734 VAROR(UI4,0xffffffff,UI8,0,I4,-1);
5735 VAROR(UI4,0,UI8,0,I4,0);
5737 VAROR(UI4,0xffffffff,INT,-1,I4,-1);
5738 VAROR(UI4,0xffffffff,INT,0,I4,-1);
5739 VAROR(UI4,0,INT,0,I4,0);
5740 VAROR(UI4,0xffffffff,UINT,0xffffffff,I4,-1);
5741 VAROR(UI4,0xffffffff,UINT,0,I4,-1);
5742 VAROR(UI4,0,UINT,0,I4,0);
5743 rbstr = SysAllocString(szFalse);
5744 VAROR(UI4,0,BSTR,rbstr,I4,0);
5745 VAROR(UI4,0xffffffff,BSTR,rbstr,I4,-1);
5746 SysFreeString(rbstr);
5747 rbstr = SysAllocString(szTrue);
5748 VAROR(UI4,0,BSTR,rbstr,I4,-1);
5749 VAROR(UI4,0xffffffff,BSTR,rbstr,I4,-1);
5750 SysFreeString(rbstr);
5751 VARORCY(UI4,0xffffffff,10000,I4,-1);
5752 VARORCY(UI4,0xffffffff,0,I4,-1);
5753 VARORCY(UI4,0,0,I4,0);
5755 VAROR(R4,-1,R4,-1,I4,-1);
5756 VAROR(R4,-1,R4,0,I4,-1);
5757 VAROR(R4,0,R4,0,I4,0);
5758 VAROR(R4,-1,R8,-1,I4,-1);
5759 VAROR(R4,-1,R8,0,I4,-1);
5760 VAROR(R4,0,R8,0,I4,0);
5761 VAROR(R4,-1,DATE,-1,I4,-1);
5762 VAROR(R4,-1,DATE,0,I4,-1);
5763 VAROR(R4,0,DATE,0,I4,0);
5764 if (has_i8)
5766 VAROR(R4,-1,I8,-1,I8,-1);
5767 VAROR(R4,-1,I8,0,I8,-1);
5768 VAROR(R4,0,I8,0,I8,0);
5769 VAROR(R4,-1,UI8,0,I4,-1);
5770 VAROR(R4,0,UI8,0,I4,0);
5772 VAROR(R4,-1,INT,-1,I4,-1);
5773 VAROR(R4,-1,INT,0,I4,-1);
5774 VAROR(R4,0,INT,0,I4,0);
5775 VAROR(R4,-1,UINT,0xffffffff,I4,-1);
5776 VAROR(R4,-1,UINT,0,I4,-1);
5777 VAROR(R4,0,UINT,0,I4,0);
5778 rbstr = SysAllocString(szFalse);
5779 VAROR(R4,0,BSTR,rbstr,I4,0);
5780 VAROR(R4,-1,BSTR,rbstr,I4,-1);
5781 SysFreeString(rbstr);
5782 rbstr = SysAllocString(szTrue);
5783 VAROR(R4,0,BSTR,rbstr,I4,-1);
5784 VAROR(R4,-1,BSTR,rbstr,I4,-1);
5785 SysFreeString(rbstr);
5786 VARORCY(R4,-1,10000,I4,-1);
5787 VARORCY(R4,-1,0,I4,-1);
5788 VARORCY(R4,0,0,I4,0);
5790 VAROR(R8,-1,R8,-1,I4,-1);
5791 VAROR(R8,-1,R8,0,I4,-1);
5792 VAROR(R8,0,R8,0,I4,0);
5793 VAROR(R8,-1,DATE,-1,I4,-1);
5794 VAROR(R8,-1,DATE,0,I4,-1);
5795 VAROR(R8,0,DATE,0,I4,0);
5796 if (has_i8)
5798 VAROR(R8,-1,I8,-1,I8,-1);
5799 VAROR(R8,-1,I8,0,I8,-1);
5800 VAROR(R8,0,I8,0,I8,0);
5801 VAROR(R8,-1,UI8,0,I4,-1);
5802 VAROR(R8,0,UI8,0,I4,0);
5804 VAROR(R8,-1,INT,-1,I4,-1);
5805 VAROR(R8,-1,INT,0,I4,-1);
5806 VAROR(R8,0,INT,0,I4,0);
5807 VAROR(R8,-1,UINT,0xffffffff,I4,-1);
5808 VAROR(R8,-1,UINT,0,I4,-1);
5809 VAROR(R8,0,UINT,0,I4,0);
5810 rbstr = SysAllocString(szFalse);
5811 VAROR(R8,0,BSTR,rbstr,I4,0);
5812 VAROR(R8,-1,BSTR,rbstr,I4,-1);
5813 SysFreeString(rbstr);
5814 rbstr = SysAllocString(szTrue);
5815 VAROR(R8,0,BSTR,rbstr,I4,-1);
5816 VAROR(R8,-1,BSTR,rbstr,I4,-1);
5817 SysFreeString(rbstr);
5818 VARORCY(R8,-1,10000,I4,-1);
5819 VARORCY(R8,-1,0,I4,-1);
5820 VARORCY(R8,0,0,I4,0);
5822 VAROR(DATE,-1,DATE,-1,I4,-1);
5823 VAROR(DATE,-1,DATE,0,I4,-1);
5824 VAROR(DATE,0,DATE,0,I4,0);
5825 if (has_i8)
5827 VAROR(DATE,-1,I8,-1,I8,-1);
5828 VAROR(DATE,-1,I8,0,I8,-1);
5829 VAROR(DATE,0,I8,0,I8,0);
5830 VAROR(DATE,-1,UI8,0,I4,-1);
5831 VAROR(DATE,0,UI8,0,I4,0);
5833 VAROR(DATE,-1,INT,-1,I4,-1);
5834 VAROR(DATE,-1,INT,0,I4,-1);
5835 VAROR(DATE,0,INT,0,I4,0);
5836 VAROR(DATE,-1,UINT,0xffffffff,I4,-1);
5837 VAROR(DATE,-1,UINT,0,I4,-1);
5838 VAROR(DATE,0,UINT,0,I4,0);
5839 rbstr = SysAllocString(szFalse);
5840 VAROR(DATE,0,BSTR,rbstr,I4,0);
5841 VAROR(DATE,-1,BSTR,rbstr,I4,-1);
5842 SysFreeString(rbstr);
5843 rbstr = SysAllocString(szTrue);
5844 VAROR(DATE,0,BSTR,rbstr,I4,-1);
5845 VAROR(DATE,-1,BSTR,rbstr,I4,-1);
5846 SysFreeString(rbstr);
5847 VARORCY(DATE,-1,10000,I4,-1);
5848 VARORCY(DATE,-1,0,I4,-1);
5849 VARORCY(DATE,0,0,I4,0);
5851 if (has_i8)
5853 VAROR(I8,-1,I8,-1,I8,-1);
5854 VAROR(I8,-1,I8,0,I8,-1);
5855 VAROR(I8,0,I8,0,I8,0);
5856 VAROR(I8,-1,UI8,0,I8,-1);
5857 VAROR(I8,0,UI8,0,I8,0);
5858 /* These overflow under native and Wine
5859 VAROR(I8,-1,INT,-1,I4,-1);
5860 VAROR(I8,-1,INT,0,I4,-1);
5861 VAROR(I8,0,INT,0,I4,0); */
5862 VAROR(I8,-1,UINT,0xffffffff,I8,-1);
5863 VAROR(I8,-1,UINT,0,I8,-1);
5864 VAROR(I8,0,UINT,0,I8,0);
5865 rbstr = SysAllocString(szFalse);
5866 VAROR(I8,0,BSTR,rbstr,I8,0);
5867 VAROR(I8,-1,BSTR,rbstr,I8,-1);
5868 SysFreeString(rbstr);
5869 rbstr = SysAllocString(szTrue);
5870 VAROR(I8,0,BSTR,rbstr,I8,-1);
5871 VAROR(I8,-1,BSTR,rbstr,I8,-1);
5872 SysFreeString(rbstr);
5873 VARORCY(I8,-1,10000,I8,-1);
5874 VARORCY(I8,-1,0,I8,-1);
5875 VARORCY(I8,0,0,I8,0);
5877 VAROR(UI8,0xffff,UI8,0xffff,I4,0xffff);
5878 VAROR(UI8,0xffff,UI8,0,I4,0xffff);
5879 VAROR(UI8,0,UI8,0,I4,0);
5880 VAROR(UI8,0xffff,INT,-1,I4,-1);
5881 VAROR(UI8,0xffff,INT,0,I4,0xffff);
5882 VAROR(UI8,0,INT,0,I4,0);
5883 VAROR(UI8,0xffff,UINT,0xffff,I4,0xffff);
5884 VAROR(UI8,0xffff,UINT,0,I4,0xffff);
5885 VAROR(UI8,0,UINT,0,I4,0);
5886 rbstr = SysAllocString(szFalse);
5887 VAROR(UI8,0,BSTR,rbstr,I4,0);
5888 VAROR(UI8,0xffff,BSTR,rbstr,I4,0xffff);
5889 SysFreeString(rbstr);
5890 rbstr = SysAllocString(szTrue);
5891 VAROR(UI8,0,BSTR,rbstr,I4,-1);
5892 VAROR(UI8,0xffff,BSTR,rbstr,I4,-1);
5893 SysFreeString(rbstr);
5894 VARORCY(UI8,0xffff,10000,I4,0xffff);
5895 VARORCY(UI8,0xffff,0,I4,0xffff);
5896 VARORCY(UI8,0,0,I4,0);
5899 VAROR(INT,-1,INT,-1,I4,-1);
5900 VAROR(INT,-1,INT,0,I4,-1);
5901 VAROR(INT,0,INT,0,I4,0);
5902 VAROR(INT,-1,UINT,0xffff,I4,-1);
5903 VAROR(INT,-1,UINT,0,I4,-1);
5904 VAROR(INT,0,UINT,0,I4,0);
5905 rbstr = SysAllocString(szFalse);
5906 VAROR(INT,0,BSTR,rbstr,I4,0);
5907 VAROR(INT,-1,BSTR,rbstr,I4,-1);
5908 SysFreeString(rbstr);
5909 rbstr = SysAllocString(szTrue);
5910 VAROR(INT,0,BSTR,rbstr,I4,-1);
5911 VAROR(INT,-1,BSTR,rbstr,I4,-1);
5912 SysFreeString(rbstr);
5913 VARORCY(INT,-1,10000,I4,-1);
5914 VARORCY(INT,-1,0,I4,-1);
5915 VARORCY(INT,0,0,I4,0);
5917 VAROR(UINT,0xffff,UINT,0xffff,I4,0xffff);
5918 VAROR(UINT,0xffff,UINT,0,I4,0xffff);
5919 VAROR(UINT,0,UINT,0,I4,0);
5920 rbstr = SysAllocString(szFalse);
5921 VAROR(UINT,0,BSTR,rbstr,I4,0);
5922 VAROR(UINT,0xffff,BSTR,rbstr,I4,0xffff);
5923 SysFreeString(rbstr);
5924 rbstr = SysAllocString(szTrue);
5925 VAROR(UINT,0,BSTR,rbstr,I4,-1);
5926 VAROR(UINT,0xffff,BSTR,rbstr,I4,-1);
5927 SysFreeString(rbstr);
5928 VARORCY(UINT,0xffff,10000,I4,0xffff);
5929 VARORCY(UINT,0xffff,0,I4,0xffff);
5930 VARORCY(UINT,0,0,I4,0);
5932 lbstr = SysAllocString(szFalse);
5933 rbstr = SysAllocString(szFalse);
5934 VAROR(BSTR,lbstr,BSTR,rbstr,BOOL,0);
5935 SysFreeString(rbstr);
5936 rbstr = SysAllocString(szTrue);
5937 VAROR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_TRUE);
5938 SysFreeString(lbstr);
5939 lbstr = SysAllocString(szTrue);
5940 VAROR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_TRUE);
5941 VARORCY(BSTR,lbstr,10000,I4,-1);
5942 SysFreeString(lbstr);
5943 lbstr = SysAllocString(szFalse);
5944 VARORCY(BSTR,lbstr,10000,I4,1);
5945 SysFreeString(lbstr);
5946 SysFreeString(rbstr);
5949 static HRESULT (WINAPI *pVarEqv)(LPVARIANT,LPVARIANT,LPVARIANT);
5951 #define VAREQV(vt1,val1,vt2,val2,rvt,rval) \
5952 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
5953 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
5954 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
5955 test_var_call2( __LINE__, pVarEqv, &left, &right, &exp )
5957 static void test_VarEqv(void)
5959 VARIANT left, right, exp, result;
5960 VARTYPE i;
5961 HRESULT hres;
5963 CHECKPTR(VarEqv);
5965 /* Test all possible flag/vt combinations & the resulting vt type */
5966 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
5968 VARTYPE leftvt, rightvt, resvt;
5970 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
5972 SKIPTESTS(leftvt);
5974 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
5976 BOOL bFail = FALSE;
5978 SKIPTESTS(rightvt);
5980 if (leftvt == VT_BSTR || rightvt == VT_BSTR ||
5981 leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
5982 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN)
5983 continue;
5985 memset(&left, 0, sizeof(left));
5986 memset(&right, 0, sizeof(right));
5987 V_VT(&left) = leftvt | ExtraFlags[i];
5988 V_VT(&right) = rightvt | ExtraFlags[i];
5989 V_VT(&result) = VT_EMPTY;
5990 resvt = VT_I4;
5992 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
5993 !IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
5994 !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
5995 leftvt == VT_CLSID || rightvt == VT_CLSID ||
5996 leftvt == VT_RECORD || rightvt == VT_RECORD ||
5997 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
5998 leftvt == VT_ERROR || rightvt == VT_ERROR)
6000 bFail = TRUE;
6002 if (leftvt == VT_EMPTY || rightvt == VT_EMPTY)
6004 if (leftvt == rightvt ||
6005 leftvt == VT_I2 || rightvt == VT_I2 ||
6006 leftvt == VT_UI1 || rightvt == VT_UI1 ||
6007 leftvt == VT_BOOL || rightvt == VT_BOOL)
6008 resvt = VT_I2;
6009 else if (leftvt == VT_NULL || rightvt == VT_NULL)
6010 resvt = VT_NULL;
6011 else if (leftvt == VT_I8 || rightvt == VT_I8)
6012 resvt = VT_I8;
6014 else if (leftvt == VT_NULL || rightvt == VT_NULL)
6016 resvt = VT_NULL;
6018 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
6020 if (leftvt == rightvt)
6021 resvt = VT_UI1;
6022 else if (leftvt == rightvt ||
6023 leftvt == VT_I2 || rightvt == VT_I2 ||
6024 leftvt == VT_BOOL || rightvt == VT_BOOL)
6026 resvt = VT_I2;
6028 else if (leftvt == VT_I8 || rightvt == VT_I8)
6029 resvt = VT_I8;
6031 else if (leftvt == VT_I2 || rightvt == VT_I2)
6033 if (leftvt == rightvt ||
6034 leftvt == VT_BOOL || rightvt == VT_BOOL)
6035 resvt = VT_I2;
6036 else if (leftvt == VT_I8 || rightvt == VT_I8)
6037 resvt = VT_I8;
6039 else if (leftvt == VT_BOOL && rightvt == VT_BOOL)
6041 resvt = VT_BOOL;
6043 else if (leftvt == VT_I8 || rightvt == VT_I8)
6045 if (leftvt == VT_INT || rightvt == VT_INT)
6046 bFail = TRUE;
6047 else
6048 resvt = VT_I8;
6050 hres = pVarEqv(&left, &right, &result);
6051 if (bFail)
6052 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
6053 "VarEqv: %d|0x%X, %d|0x%X: Expected failure, got 0x%X vt %d\n",
6054 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres,
6055 V_VT(&result));
6056 else
6057 ok(hres == S_OK && V_VT(&result) == resvt,
6058 "VarEqv: %d|0x%X, %d|0x%X: expected S_OK, vt %d, got 0x%X vt %d\n",
6059 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], resvt, hres,
6060 V_VT(&result));
6065 /* Test returned values */
6066 VAREQV(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
6067 VAREQV(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE);
6068 VAREQV(BOOL,TRUE,BOOL,TRUE,BOOL,VARIANT_TRUE);
6069 VAREQV(BOOL,FALSE,BOOL,FALSE,BOOL,VARIANT_TRUE);
6070 VAREQV(BOOL,TRUE,BOOL,FALSE,BOOL,-2);
6071 VAREQV(BOOL,FALSE,BOOL,TRUE,BOOL,-2);
6072 VAREQV(BOOL,6,BOOL,7,BOOL,-2);
6073 VAREQV(BOOL,6,BOOL,6,BOOL,VARIANT_TRUE);
6074 VAREQV(BOOL,VARIANT_TRUE,I2,VARIANT_TRUE,I2,VARIANT_TRUE);
6075 VAREQV(BOOL,VARIANT_TRUE,I2,VARIANT_FALSE,I2,VARIANT_FALSE);
6076 VAREQV(BOOL,6,I2,7,I2,-2);
6077 VAREQV(UI1,1,UI1,1,UI1,255);
6078 VAREQV(UI1,1,UI1,0,UI1,254);
6079 VAREQV(UI1,0,UI1,1,UI1,254);
6080 if (has_i8)
6082 VAREQV(UI4,VARIANT_FALSE,I8,VARIANT_FALSE,I8,-1);
6083 VAREQV(UI4,5,I8,19,I8,-23);
6084 VAREQV(UI4,VARIANT_FALSE,UI8,VARIANT_FALSE,I4,-1);
6088 static HRESULT (WINAPI *pVarMul)(LPVARIANT,LPVARIANT,LPVARIANT);
6090 #define VARMUL(vt1,val1,vt2,val2,rvt,rval) \
6091 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
6092 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
6093 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
6094 test_var_call2( __LINE__, pVarMul, &left, &right, &exp )
6096 static void test_VarMul(void)
6098 VARIANT left, right, exp, result, cy, dec;
6099 VARTYPE i;
6100 BSTR lbstr, rbstr;
6101 HRESULT hres;
6102 double r;
6104 CHECKPTR(VarMul);
6106 lbstr = SysAllocString(sz12);
6107 rbstr = SysAllocString(sz12);
6109 /* Test all possible flag/vt combinations & the resulting vt type */
6110 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
6112 VARTYPE leftvt, rightvt, resvt;
6114 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
6117 SKIPTESTS(leftvt);
6119 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
6121 BOOL bFail = FALSE;
6123 SKIPTESTS(rightvt);
6125 if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
6126 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN)
6127 continue;
6129 memset(&left, 0, sizeof(left));
6130 memset(&right, 0, sizeof(right));
6131 V_VT(&left) = leftvt | ExtraFlags[i];
6132 if (leftvt == VT_BSTR)
6133 V_BSTR(&left) = lbstr;
6134 V_VT(&right) = rightvt | ExtraFlags[i];
6135 if (rightvt == VT_BSTR)
6136 V_BSTR(&right) = rbstr;
6137 V_VT(&result) = VT_EMPTY;
6138 resvt = VT_UNKNOWN;
6140 /* Don't ask me why but native VarMul cannot handle:
6141 VT_I1, VT_UI2, VT_UI4, VT_INT, VT_UINT and VT_UI8.
6142 Tested with DCOM98, Win2k, WinXP */
6143 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
6144 !IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
6145 !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
6146 leftvt == VT_CLSID || rightvt == VT_CLSID ||
6147 leftvt == VT_RECORD || rightvt == VT_RECORD ||
6148 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
6149 leftvt == VT_ERROR || rightvt == VT_ERROR ||
6150 leftvt == VT_I1 || rightvt == VT_I1 ||
6151 leftvt == VT_UI2 || rightvt == VT_UI2 ||
6152 leftvt == VT_UI4 || rightvt == VT_UI4 ||
6153 leftvt == VT_UI8 || rightvt == VT_UI8 ||
6154 leftvt == VT_INT || rightvt == VT_INT ||
6155 leftvt == VT_UINT || rightvt == VT_UINT) {
6156 bFail = TRUE;
6159 if (leftvt == VT_NULL || rightvt == VT_NULL)
6160 resvt = VT_NULL;
6161 else if (leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
6162 resvt = VT_DECIMAL;
6163 else if (leftvt == VT_R8 || rightvt == VT_R8 ||
6164 leftvt == VT_BSTR || rightvt == VT_BSTR ||
6165 leftvt == VT_DATE || rightvt == VT_DATE)
6166 resvt = VT_R8;
6167 else if (leftvt == VT_R4 || rightvt == VT_R4) {
6168 if (leftvt == VT_I4 || rightvt == VT_I4 ||
6169 leftvt == VT_I8 || rightvt == VT_I8 ||
6170 leftvt == VT_CY || rightvt == VT_CY)
6171 resvt = VT_R8;
6172 else
6173 resvt = VT_R4;
6174 } else if (leftvt == VT_CY || rightvt == VT_CY)
6175 resvt = VT_CY;
6176 else if (leftvt == VT_I8 || rightvt == VT_I8)
6177 resvt = VT_I8;
6178 else if (leftvt == VT_I4 || rightvt == VT_I4)
6179 resvt = VT_I4;
6180 else if (leftvt == VT_I2 || rightvt == VT_I2 ||
6181 leftvt == VT_BOOL || rightvt == VT_BOOL ||
6182 (leftvt == VT_EMPTY && rightvt == VT_EMPTY))
6183 resvt = VT_I2;
6184 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
6185 resvt = VT_UI1;
6187 hres = pVarMul(&left, &right, &result);
6188 if (bFail) {
6189 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
6190 "VarMul: %d|0x%X, %d|0x%X: Expected failure, got 0x%X vt %d\n",
6191 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres,
6192 V_VT(&result));
6193 } else {
6194 ok(hres == S_OK && V_VT(&result) == resvt,
6195 "VarMul: %d|0x%X, %d|0x%X: expected S_OK, vt %d, got 0x%X vt %d\n",
6196 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], resvt, hres,
6197 V_VT(&result));
6203 /* Test returned values */
6204 VARMUL(I4,4,I4,2,I4,8);
6205 VARMUL(I2,4,I2,2,I2,8);
6206 VARMUL(I2,-13,I4,5,I4,-65);
6207 VARMUL(I4,-13,I4,5,I4,-65);
6208 VARMUL(I2,7,R4,0.5f,R4,3.5f);
6209 VARMUL(R4,0.5f,I4,5,R8,2.5);
6210 VARMUL(R8,7.1,BOOL,0,R8,0);
6211 VARMUL(BSTR,lbstr,I2,4,R8,48);
6212 VARMUL(BSTR,lbstr,BOOL,1,R8,12);
6213 VARMUL(BSTR,lbstr,R4,0.1f,R8,1.2);
6214 VARMUL(BSTR,lbstr,BSTR,rbstr,R8,144);
6215 VARMUL(R4,0.2f,BSTR,rbstr,R8,2.4);
6216 VARMUL(DATE,2.25,I4,7,R8,15.75);
6218 VARMUL(UI1, UI1_MAX, UI1, UI1_MAX, I4, UI1_MAX * UI1_MAX);
6219 VARMUL(I2, I2_MAX, I2, I2_MAX, I4, I2_MAX * I2_MAX);
6220 VARMUL(I2, I2_MAX, I2, I2_MIN, I4, I2_MAX * I2_MIN);
6221 VARMUL(I2, I2_MIN, I2, I2_MIN, I4, I2_MIN * I2_MIN);
6222 VARMUL(I4, I4_MAX, I4, I4_MAX, R8, (double)I4_MAX * I4_MAX);
6223 VARMUL(I4, I4_MAX, I4, I4_MIN, R8, (double)I4_MAX * I4_MIN);
6224 VARMUL(I4, I4_MIN, I4, I4_MIN, R8, (double)I4_MIN * I4_MIN);
6225 VARMUL(R4, R4_MAX, R4, R4_MAX, R8, (double)R4_MAX * R4_MAX);
6226 VARMUL(R4, R4_MAX, R4, R4_MIN, R4, R4_MAX * R4_MIN);
6227 VARMUL(R4, R4_MIN, R4, R4_MIN, R4, R4_MIN * R4_MIN);
6228 VARMUL(R8, R8_MAX, R8, R8_MIN, R8, R8_MAX * R8_MIN);
6229 VARMUL(R8, R8_MIN, R8, R8_MIN, R8, R8_MIN * R8_MIN);
6231 /* Manuly test some VT_CY and VT_DECIMAL variants */
6232 V_VT(&cy) = VT_CY;
6233 hres = VarCyFromI4(4711, &V_CY(&cy));
6234 ok(hres == S_OK, "VarCyFromI4 failed!\n");
6235 V_VT(&dec) = VT_DECIMAL;
6236 hres = VarDecFromR8(-4.2, &V_DECIMAL(&dec));
6237 ok(hres == S_OK, "VarDecFromR4 failed!\n");
6238 memset(&left, 0, sizeof(left));
6239 memset(&right, 0, sizeof(right));
6240 V_VT(&left) = VT_I4;
6241 V_I4(&left) = -11;
6242 V_VT(&right) = VT_UI1;
6243 V_UI1(&right) = 9;
6245 hres = pVarMul(&cy, &right, &result);
6246 ok(hres == S_OK && V_VT(&result) == VT_CY, "VarMul: expected coerced type VT_CY, got %s!\n", vtstr(V_VT(&result)));
6247 hres = VarR8FromCy(V_CY(&result), &r);
6248 ok(hres == S_OK && EQ_DOUBLE(r, 42399.0), "VarMul: CY value %f, expected %f\n", r, 42399.0);
6250 hres = pVarMul(&left, &dec, &result);
6251 ok(hres == S_OK && V_VT(&result) == VT_DECIMAL, "VarMul: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
6252 hres = VarR8FromDec(&V_DECIMAL(&result), &r);
6253 ok(hres == S_OK && EQ_DOUBLE(r, 46.2), "VarMul: DECIMAL value %f, expected %f\n", r, 46.2);
6255 SysFreeString(lbstr);
6256 SysFreeString(rbstr);
6259 static HRESULT (WINAPI *pVarAdd)(LPVARIANT,LPVARIANT,LPVARIANT);
6261 #define VARADD(vt1,val1,vt2,val2,rvt,rval) \
6262 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
6263 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
6264 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
6265 test_var_call2( __LINE__, pVarAdd, &left, &right, &exp )
6267 static void test_VarAdd(void)
6269 VARIANT left, right, exp, result, cy, dec;
6270 VARTYPE i;
6271 BSTR lbstr, rbstr;
6272 HRESULT hres;
6273 double r;
6275 CHECKPTR(VarAdd);
6277 lbstr = SysAllocString(sz12);
6278 rbstr = SysAllocString(sz12);
6280 /* Test all possible flag/vt combinations & the resulting vt type */
6281 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
6283 VARTYPE leftvt, rightvt, resvt;
6285 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
6288 SKIPTESTS(leftvt);
6290 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
6292 BOOL bFail = FALSE;
6294 SKIPTESTS(rightvt);
6296 if (leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN)
6297 continue;
6299 memset(&left, 0, sizeof(left));
6300 memset(&right, 0, sizeof(right));
6301 V_VT(&left) = leftvt | ExtraFlags[i];
6302 if (leftvt == VT_BSTR)
6303 V_BSTR(&left) = lbstr;
6304 V_VT(&right) = rightvt | ExtraFlags[i];
6305 if (rightvt == VT_BSTR)
6306 V_BSTR(&right) = rbstr;
6307 V_VT(&result) = VT_EMPTY;
6308 resvt = VT_ERROR;
6310 /* Don't ask me why but native VarAdd cannot handle:
6311 VT_I1, VT_UI2, VT_UI4, VT_INT, VT_UINT and VT_UI8.
6312 Tested with DCOM98, Win2k, WinXP */
6313 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
6314 !IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
6315 !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
6316 leftvt == VT_CLSID || rightvt == VT_CLSID ||
6317 leftvt == VT_RECORD || rightvt == VT_RECORD ||
6318 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
6319 leftvt == VT_ERROR || rightvt == VT_ERROR ||
6320 leftvt == VT_I1 || rightvt == VT_I1 ||
6321 leftvt == VT_UI2 || rightvt == VT_UI2 ||
6322 leftvt == VT_UI4 || rightvt == VT_UI4 ||
6323 leftvt == VT_UI8 || rightvt == VT_UI8 ||
6324 leftvt == VT_INT || rightvt == VT_INT ||
6325 leftvt == VT_UINT || rightvt == VT_UINT) {
6326 bFail = TRUE;
6329 if (leftvt == VT_NULL || rightvt == VT_NULL)
6330 resvt = VT_NULL;
6331 else if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH)
6332 bFail = TRUE;
6333 else if (leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
6334 resvt = VT_DECIMAL;
6335 else if (leftvt == VT_DATE || rightvt == VT_DATE)
6336 resvt = VT_DATE;
6337 else if (leftvt == VT_CY || rightvt == VT_CY)
6338 resvt = VT_CY;
6339 else if (leftvt == VT_R8 || rightvt == VT_R8)
6340 resvt = VT_R8;
6341 else if (leftvt == VT_BSTR || rightvt == VT_BSTR) {
6342 if ((leftvt == VT_BSTR && rightvt == VT_BSTR) ||
6343 leftvt == VT_EMPTY || rightvt == VT_EMPTY)
6344 resvt = VT_BSTR;
6345 else
6346 resvt = VT_R8;
6347 } else if (leftvt == VT_R4 || rightvt == VT_R4) {
6348 if (leftvt == VT_I4 || rightvt == VT_I4 ||
6349 leftvt == VT_I8 || rightvt == VT_I8)
6350 resvt = VT_R8;
6351 else
6352 resvt = VT_R4;
6354 else if (leftvt == VT_I8 || rightvt == VT_I8)
6355 resvt = VT_I8;
6356 else if (leftvt == VT_I4 || rightvt == VT_I4)
6357 resvt = VT_I4;
6358 else if (leftvt == VT_I2 || rightvt == VT_I2 ||
6359 leftvt == VT_BOOL || rightvt == VT_BOOL ||
6360 (leftvt == VT_EMPTY && rightvt == VT_EMPTY))
6361 resvt = VT_I2;
6362 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
6363 resvt = VT_UI1;
6365 hres = pVarAdd(&left, &right, &result);
6366 if (bFail) {
6367 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
6368 "VarAdd: %d|0x%X, %d|0x%X: Expected failure, got 0x%X vt %d\n",
6369 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres,
6370 V_VT(&result));
6371 } else {
6372 ok(hres == S_OK && V_VT(&result) == resvt,
6373 "VarAdd: %d|0x%X, %d|0x%X: expected S_OK, vt %d, got 0x%X vt %d\n",
6374 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], resvt, hres,
6375 V_VT(&result));
6377 /* Note, we don't clear left/right deliberately here */
6378 VariantClear(&result);
6383 /* Test returned values */
6384 VARADD(I4,4,I4,2,I4,6);
6385 VARADD(I2,4,I2,2,I2,6);
6386 VARADD(I2,-13,I4,5,I4,-8);
6387 VARADD(I4,-13,I4,5,I4,-8);
6388 VARADD(I2,7,R4,0.5f,R4,7.5f);
6389 VARADD(R4,0.5f,I4,5,R8,5.5);
6390 VARADD(R8,7.1,BOOL,0,R8,7.1);
6391 VARADD(BSTR,lbstr,I2,4,R8,16);
6392 VARADD(BSTR,lbstr,BOOL,1,R8,13);
6393 VARADD(BSTR,lbstr,R4,0.1f,R8,12.1);
6394 VARADD(R4,0.2f,BSTR,rbstr,R8,12.2);
6395 VARADD(DATE,2.25,I4,7,DATE,9.25);
6396 VARADD(DATE,1.25,R4,-1.7f,DATE,-0.45);
6398 VARADD(UI1, UI1_MAX, UI1, UI1_MAX, I2, UI1_MAX + UI1_MAX);
6399 VARADD(I2, I2_MAX, I2, I2_MAX, I4, I2_MAX + I2_MAX);
6400 VARADD(I2, I2_MAX, I2, I2_MIN, I2, I2_MAX + I2_MIN);
6401 VARADD(I2, I2_MIN, I2, I2_MIN, I4, I2_MIN + I2_MIN);
6402 VARADD(I4, I4_MAX, I4, I4_MIN, I4, I4_MAX + I4_MIN);
6403 VARADD(I4, I4_MAX, I4, I4_MAX, R8, (double)I4_MAX + I4_MAX);
6404 VARADD(I4, I4_MIN, I4, I4_MIN, R8, (double)I4_MIN + I4_MIN);
6405 VARADD(R4, R4_MAX, R4, R4_MAX, R8, (double)R4_MAX + R4_MAX);
6406 VARADD(R4, R4_MAX, R4, R4_MIN, R4, R4_MAX + R4_MIN);
6407 VARADD(R4, R4_MIN, R4, R4_MIN, R4, R4_MIN + R4_MIN);
6408 VARADD(R8, R8_MAX, R8, R8_MIN, R8, R8_MAX + R8_MIN);
6409 VARADD(R8, R8_MIN, R8, R8_MIN, R8, R8_MIN + R8_MIN);
6411 /* Manually test BSTR + BSTR */
6412 V_VT(&left) = VT_BSTR;
6413 V_BSTR(&left) = lbstr;
6414 V_VT(&right) = VT_BSTR;
6415 V_BSTR(&right) = rbstr;
6416 hres = pVarAdd(&left, &right, &result);
6417 ok(hres == S_OK && V_VT(&result) == VT_BSTR, "VarAdd: expected coerced type VT_BSTR, got %s!\n", vtstr(V_VT(&result)));
6418 hres = VarR8FromStr(V_BSTR(&result), 0, 0, &r);
6419 ok(hres == S_OK && EQ_DOUBLE(r, 1212.0), "VarAdd: BSTR value %f, expected %f\n", r, 1212.0);
6420 VariantClear(&result);
6422 /* Manuly test some VT_CY and VT_DECIMAL variants */
6423 V_VT(&cy) = VT_CY;
6424 hres = VarCyFromI4(4711, &V_CY(&cy));
6425 ok(hres == S_OK, "VarCyFromI4 failed!\n");
6426 V_VT(&dec) = VT_DECIMAL;
6427 hres = VarDecFromR8(-4.2, &V_DECIMAL(&dec));
6428 ok(hres == S_OK, "VarDecFromR4 failed!\n");
6429 memset(&left, 0, sizeof(left));
6430 memset(&right, 0, sizeof(right));
6431 V_VT(&left) = VT_I4;
6432 V_I4(&left) = -11;
6433 V_VT(&right) = VT_UI1;
6434 V_UI1(&right) = 9;
6436 hres = pVarAdd(&cy, &right, &result);
6437 ok(hres == S_OK && V_VT(&result) == VT_CY, "VarAdd: expected coerced type VT_CY, got %s!\n", vtstr(V_VT(&result)));
6438 hres = VarR8FromCy(V_CY(&result), &r);
6439 ok(hres == S_OK && EQ_DOUBLE(r, 4720.0), "VarAdd: CY value %f, expected %f\n", r, 4720.0);
6441 hres = pVarAdd(&left, &dec, &result);
6442 ok(hres == S_OK && V_VT(&result) == VT_DECIMAL, "VarAdd: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
6443 hres = VarR8FromDec(&V_DECIMAL(&result), &r);
6444 ok(hres == S_OK && EQ_DOUBLE(r, -15.2), "VarAdd: DECIMAL value %f, expected %f\n", r, -15.2);
6445 VariantClear(&result);
6447 SysFreeString(lbstr);
6448 SysFreeString(rbstr);
6451 static HRESULT (WINAPI *pVarCmp)(LPVARIANT,LPVARIANT,LCID,ULONG);
6452 static HRESULT (WINAPI *pVarCat)(LPVARIANT,LPVARIANT,LPVARIANT);
6454 static void test_VarCat(void)
6456 LCID lcid;
6457 VARIANT left, right, result, expected, expected_broken;
6458 static const WCHAR sz34[] = {'3','4','\0'};
6459 static const WCHAR sz1234[] = {'1','2','3','4','\0'};
6460 static const WCHAR date_sz12[] = {'9','/','3','0','/','1','9','8','0','1','2','\0'};
6461 static const WCHAR date_sz12_broken[] = {'9','/','3','0','/','8','0','1','2','\0'};
6462 static const WCHAR sz12_date[] = {'1','2','9','/','3','0','/','1','9','8','0','\0'};
6463 static const WCHAR sz12_date_broken[] = {'1','2','9','/','3','0','/','8','0','\0'};
6464 static const WCHAR sz_empty[] = {'\0'};
6465 CHAR orig_date_format[128];
6466 VARTYPE leftvt, rightvt, resultvt;
6467 HRESULT hres;
6468 HRESULT expected_error_num;
6469 int cmp;
6470 DummyDispatch dispatch;
6472 CHECKPTR(VarCat);
6474 /* Set date format for testing */
6475 lcid = LOCALE_USER_DEFAULT;
6476 GetLocaleInfoA(lcid,LOCALE_SSHORTDATE,orig_date_format,128);
6477 SetLocaleInfoA(lcid,LOCALE_SSHORTDATE,"M/d/yyyy");
6479 VariantInit(&left);
6480 VariantInit(&right);
6481 VariantInit(&result);
6482 VariantInit(&expected);
6484 /* Check expected types for all combinations */
6485 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
6488 SKIPTESTS(leftvt);
6490 /* Check if we need/have support for I8 and/or UI8 */
6491 if ((leftvt == VT_I8 || leftvt == VT_UI8) && !has_i8)
6492 continue;
6494 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
6497 SKIPTESTS(rightvt);
6498 expected_error_num = S_OK;
6499 resultvt = VT_EMPTY;
6501 if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
6502 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN ||
6503 leftvt == VT_RECORD || rightvt == VT_RECORD ||
6504 leftvt == 15 || rightvt == 15 /* Undefined type */)
6505 continue;
6507 /* Check if we need/have support for I8 and/or UI8 */
6508 if ((rightvt == VT_I8 || rightvt == VT_UI8) && !has_i8)
6509 continue;
6511 if (leftvt == VT_NULL && rightvt == VT_NULL)
6512 resultvt = VT_NULL;
6513 else if (leftvt == VT_VARIANT && (rightvt == VT_ERROR ||
6514 rightvt == VT_DATE || rightvt == VT_DECIMAL))
6515 expected_error_num = DISP_E_TYPEMISMATCH;
6516 else if ((leftvt == VT_I2 || leftvt == VT_I4 ||
6517 leftvt == VT_R4 || leftvt == VT_R8 ||
6518 leftvt == VT_CY || leftvt == VT_BOOL ||
6519 leftvt == VT_BSTR || leftvt == VT_I1 ||
6520 leftvt == VT_UI1 || leftvt == VT_UI2 ||
6521 leftvt == VT_UI4 || leftvt == VT_I8 ||
6522 leftvt == VT_UI8 || leftvt == VT_INT ||
6523 leftvt == VT_UINT || leftvt == VT_EMPTY ||
6524 leftvt == VT_NULL || leftvt == VT_DECIMAL ||
6525 leftvt == VT_DATE)
6527 (rightvt == VT_I2 || rightvt == VT_I4 ||
6528 rightvt == VT_R4 || rightvt == VT_R8 ||
6529 rightvt == VT_CY || rightvt == VT_BOOL ||
6530 rightvt == VT_BSTR || rightvt == VT_I1 ||
6531 rightvt == VT_UI1 || rightvt == VT_UI2 ||
6532 rightvt == VT_UI4 || rightvt == VT_I8 ||
6533 rightvt == VT_UI8 || rightvt == VT_INT ||
6534 rightvt == VT_UINT || rightvt == VT_EMPTY ||
6535 rightvt == VT_NULL || rightvt == VT_DECIMAL ||
6536 rightvt == VT_DATE))
6537 resultvt = VT_BSTR;
6538 else if (rightvt == VT_ERROR && leftvt < VT_VOID)
6539 expected_error_num = DISP_E_TYPEMISMATCH;
6540 else if (leftvt == VT_ERROR && (rightvt == VT_DATE ||
6541 rightvt == VT_ERROR || rightvt == VT_DECIMAL))
6542 expected_error_num = DISP_E_TYPEMISMATCH;
6543 else if (rightvt == VT_DATE || rightvt == VT_ERROR ||
6544 rightvt == VT_DECIMAL)
6545 expected_error_num = DISP_E_BADVARTYPE;
6546 else if (leftvt == VT_ERROR || rightvt == VT_ERROR)
6547 expected_error_num = DISP_E_TYPEMISMATCH;
6548 else if (leftvt == VT_VARIANT)
6549 expected_error_num = DISP_E_TYPEMISMATCH;
6550 else if (rightvt == VT_VARIANT && (leftvt == VT_EMPTY ||
6551 leftvt == VT_NULL || leftvt == VT_I2 ||
6552 leftvt == VT_I4 || leftvt == VT_R4 ||
6553 leftvt == VT_R8 || leftvt == VT_CY ||
6554 leftvt == VT_DATE || leftvt == VT_BSTR ||
6555 leftvt == VT_BOOL || leftvt == VT_DECIMAL ||
6556 leftvt == VT_I1 || leftvt == VT_UI1 ||
6557 leftvt == VT_UI2 || leftvt == VT_UI4 ||
6558 leftvt == VT_I8 || leftvt == VT_UI8 ||
6559 leftvt == VT_INT || leftvt == VT_UINT
6561 expected_error_num = DISP_E_TYPEMISMATCH;
6562 else
6563 expected_error_num = DISP_E_BADVARTYPE;
6565 V_VT(&left) = leftvt;
6566 V_VT(&right) = rightvt;
6568 switch (leftvt) {
6569 case VT_BSTR:
6570 V_BSTR(&left) = SysAllocString(sz_empty); break;
6571 case VT_DATE:
6572 V_DATE(&left) = 0.0; break;
6573 case VT_DECIMAL:
6574 VarDecFromR8(0.0, &V_DECIMAL(&left)); break;
6575 default:
6576 V_I8(&left) = 0;
6579 switch (rightvt) {
6580 case VT_BSTR:
6581 V_BSTR(&right) = SysAllocString(sz_empty); break;
6582 case VT_DATE:
6583 V_DATE(&right) = 0.0; break;
6584 case VT_DECIMAL:
6585 VarDecFromR8(0.0, &V_DECIMAL(&right)); break;
6586 default:
6587 V_I8(&right) = 0;
6590 hres = pVarCat(&left, &right, &result);
6592 /* Determine the error code for the vt combination */
6593 ok(hres == expected_error_num,
6594 "VarCat: %d, %d returned error, 0x%X expected 0x%X.\n",
6595 leftvt, rightvt, hres, expected_error_num);
6597 /* Check types are correct */
6598 ok(V_VT(&result) == resultvt,
6599 "VarCat: %d, %d: expected vt %d, got vt %d\n",
6600 leftvt, rightvt, resultvt, V_VT(&result));
6602 VariantClear(&left);
6603 VariantClear(&right);
6604 VariantClear(&result);
6608 /* Running single comparison tests to compare outputs */
6610 /* Test concat strings */
6611 V_VT(&left) = VT_BSTR;
6612 V_VT(&right) = VT_BSTR;
6613 V_VT(&expected) = VT_BSTR;
6614 V_BSTR(&left) = SysAllocString(sz12);
6615 V_BSTR(&right) = SysAllocString(sz34);
6616 V_BSTR(&expected) = SysAllocString(sz1234);
6617 hres = pVarCat(&left,&right,&result);
6618 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6619 if (pVarCmp)
6620 ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
6621 "VarCat: VT_BSTR concat with VT_BSTR failed to return correct result\n");
6623 VariantClear(&left);
6624 VariantClear(&right);
6625 VariantClear(&result);
6627 /* Test if expression is VT_ERROR */
6628 V_VT(&left) = VT_ERROR;
6629 V_VT(&right) = VT_BSTR;
6630 V_BSTR(&right) = SysAllocString(sz1234);
6631 hres = pVarCat(&left,&right,&result);
6632 ok(hres == DISP_E_TYPEMISMATCH, "VarCat should have returned DISP_E_TYPEMISMATCH instead of 0x%08x\n", hres);
6633 ok(V_VT(&result) == VT_EMPTY,
6634 "VarCat: VT_ERROR concat with VT_BSTR should have returned VT_EMPTY\n");
6636 VariantClear(&left);
6637 VariantClear(&right);
6638 VariantClear(&result);
6640 V_VT(&left) = VT_BSTR;
6641 V_VT(&right) = VT_ERROR;
6642 V_BSTR(&left) = SysAllocString(sz1234);
6643 hres = pVarCat(&left,&right,&result);
6644 ok(hres == DISP_E_TYPEMISMATCH, "VarCat should have returned DISP_E_TYPEMISMATCH instead of 0x%08x\n", hres);
6645 ok(V_VT(&result) == VT_EMPTY,
6646 "VarCat: VT_BSTR concat with VT_ERROR should have returned VT_EMPTY\n");
6648 VariantClear(&left);
6649 VariantClear(&right);
6650 VariantClear(&result);
6651 VariantClear(&expected);
6653 /* Test combining boolean with number */
6654 V_VT(&left) = VT_INT;
6655 V_VT(&right) = VT_BOOL;
6656 V_VT(&expected) = VT_BSTR;
6657 V_INT(&left) = 12;
6658 V_BOOL(&right) = TRUE;
6659 V_BSTR(&expected) = SysAllocString(sz12_true);
6660 hres = pVarCat(&left,&right,&result);
6661 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6662 if (pVarCmp)
6664 hres = pVarCmp(&result,&expected,lcid,0);
6665 ok(hres == VARCMP_EQ, "Expected VARCMP_EQ, got %08x for %s, %s\n",
6666 hres, variantstr(&result), variantstr(&expected));
6669 VariantClear(&left);
6670 VariantClear(&right);
6671 VariantClear(&result);
6672 VariantClear(&expected);
6674 V_VT(&left) = VT_INT;
6675 V_VT(&right) = VT_BOOL;
6676 V_VT(&expected) = VT_BSTR;
6677 V_INT(&left) = 12;
6678 V_BOOL(&right) = FALSE;
6679 V_BSTR(&expected) = SysAllocString(sz12_false);
6680 hres = pVarCat(&left,&right,&result);
6681 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6682 if (pVarCmp)
6684 hres = pVarCmp(&result,&expected,lcid,0);
6685 ok(hres == VARCMP_EQ, "Expected VARCMP_EQ, got %08x for %s, %s\n",
6686 hres, variantstr(&result), variantstr(&expected));
6689 VariantClear(&left);
6690 VariantClear(&right);
6691 VariantClear(&result);
6692 VariantClear(&expected);
6694 /* Test when both expressions are numeric */
6695 V_VT(&left) = VT_INT;
6696 V_VT(&right) = VT_INT;
6697 V_VT(&expected) = VT_BSTR;
6698 V_INT(&left) = 12;
6699 V_INT(&right) = 34;
6700 V_BSTR(&expected) = SysAllocString(sz1234);
6701 hres = pVarCat(&left,&right,&result);
6702 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6703 if (pVarCmp)
6704 ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
6705 "VarCat: NUMBER concat with NUMBER returned incorrect result\n");
6707 VariantClear(&left);
6708 VariantClear(&right);
6709 VariantClear(&result);
6711 /* Test if one expression is numeric and the other is a string */
6712 V_VT(&left) = VT_INT;
6713 V_VT(&right) = VT_BSTR;
6714 V_INT(&left) = 12;
6715 V_BSTR(&right) = SysAllocString(sz34);
6716 hres = pVarCat(&left,&right,&result);
6717 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6718 if (pVarCmp)
6719 ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
6720 "VarCat: NUMBER concat with VT_BSTR, incorrect result\n");
6722 VariantClear(&left);
6723 VariantClear(&right);
6724 VariantClear(&result);
6726 V_VT(&left) = VT_BSTR;
6727 V_VT(&right) = VT_INT;
6728 V_BSTR(&left) = SysAllocString(sz12);
6729 V_INT(&right) = 34;
6730 hres = pVarCat(&left,&right,&result);
6731 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6732 if (pVarCmp)
6733 ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
6734 "VarCat: VT_BSTR concat with NUMBER, incorrect result\n");
6736 VariantClear(&left);
6737 VariantClear(&right);
6738 VariantClear(&result);
6739 VariantClear(&expected);
6741 /* Test concat dates with strings */
6742 V_VT(&left) = VT_BSTR;
6743 V_VT(&right) = VT_DATE;
6744 V_VT(&expected) = VT_BSTR;
6745 V_VT(&expected_broken) = VT_BSTR;
6746 V_BSTR(&left) = SysAllocString(sz12);
6747 V_DATE(&right) = 29494.0;
6748 V_BSTR(&expected)= SysAllocString(sz12_date);
6749 V_BSTR(&expected_broken)= SysAllocString(sz12_date_broken);
6750 hres = pVarCat(&left,&right,&result);
6751 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6752 if (pVarCmp)
6753 ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ ||
6754 broken(pVarCmp(&result,&expected_broken,lcid,0) == VARCMP_EQ), /* Some W98 and NT4 (intermittent) */
6755 "VarCat: VT_BSTR concat with VT_DATE returned incorrect result\n");
6757 VariantClear(&left);
6758 VariantClear(&right);
6759 VariantClear(&result);
6760 VariantClear(&expected);
6761 VariantClear(&expected_broken);
6763 V_VT(&left) = VT_DATE;
6764 V_VT(&right) = VT_BSTR;
6765 V_VT(&expected) = VT_BSTR;
6766 V_VT(&expected_broken) = VT_BSTR;
6767 V_DATE(&left) = 29494.0;
6768 V_BSTR(&right) = SysAllocString(sz12);
6769 V_BSTR(&expected)= SysAllocString(date_sz12);
6770 V_BSTR(&expected_broken)= SysAllocString(date_sz12_broken);
6771 hres = pVarCat(&left,&right,&result);
6772 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6773 if (pVarCmp)
6774 ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ ||
6775 broken(pVarCmp(&result,&expected_broken,lcid,0) == VARCMP_EQ), /* Some W98 and NT4 (intermittent) */
6776 "VarCat: VT_DATE concat with VT_BSTR returned incorrect result\n");
6778 VariantClear(&left);
6779 VariantClear(&right);
6780 VariantClear(&result);
6781 VariantClear(&expected);
6782 VariantClear(&expected_broken);
6784 /* Test of both expressions are empty */
6785 V_VT(&left) = VT_BSTR;
6786 V_VT(&right) = VT_BSTR;
6787 V_VT(&expected) = VT_BSTR;
6788 V_BSTR(&left) = SysAllocString(sz_empty);
6789 V_BSTR(&right) = SysAllocString(sz_empty);
6790 V_BSTR(&expected)= SysAllocString(sz_empty);
6791 hres = pVarCat(&left,&right,&result);
6792 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6793 if (pVarCmp)
6794 ok(pVarCmp(&result,&left,lcid,0) == VARCMP_EQ,
6795 "VarCat: EMPTY concat with EMPTY did not return empty VT_BSTR\n");
6797 /* Restore original date format settings */
6798 SetLocaleInfoA(lcid,LOCALE_SSHORTDATE,orig_date_format);
6800 VariantClear(&left);
6801 VariantClear(&right);
6802 VariantClear(&result);
6803 VariantClear(&expected);
6805 /* Dispatch conversion */
6806 init_test_dispatch(VT_NULL, &dispatch);
6807 V_VT(&left) = VT_DISPATCH;
6808 V_DISPATCH(&left) = &dispatch.IDispatch_iface;
6810 SET_EXPECT(dispatch_invoke);
6811 hres = VarCat(&left, &right, &result);
6812 ok(hres == S_OK, "got 0x%08x\n", hres);
6813 ok(V_VT(&result) == VT_BSTR, "got %d\n", V_VT(&result));
6814 ok(SysStringLen(V_BSTR(&result)) == 0, "got %d\n", SysStringLen(V_BSTR(&result)));
6815 CHECK_CALLED(dispatch_invoke);
6817 VariantClear(&left);
6818 VariantClear(&right);
6819 VariantClear(&result);
6821 init_test_dispatch(VT_NULL, &dispatch);
6822 V_VT(&right) = VT_DISPATCH;
6823 V_DISPATCH(&right) = &dispatch.IDispatch_iface;
6825 SET_EXPECT(dispatch_invoke);
6826 hres = VarCat(&left, &right, &result);
6827 ok(hres == S_OK, "got 0x%08x\n", hres);
6828 ok(V_VT(&result) == VT_BSTR, "got %d\n", V_VT(&result));
6829 ok(SysStringLen(V_BSTR(&result)) == 0, "got %d\n", SysStringLen(V_BSTR(&result)));
6830 CHECK_CALLED(dispatch_invoke);
6832 VariantClear(&left);
6833 VariantClear(&right);
6834 VariantClear(&result);
6836 init_test_dispatch(VT_UI1, &dispatch);
6837 V_VT(&right) = VT_DISPATCH;
6838 V_DISPATCH(&right) = &dispatch.IDispatch_iface;
6840 V_VT(&left) = VT_BSTR;
6841 V_BSTR(&left) = SysAllocString(sz12);
6842 SET_EXPECT(dispatch_invoke);
6843 hres = pVarCat(&left,&right,&result);
6844 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6845 CHECK_CALLED(dispatch_invoke);
6846 ok(!lstrcmpW(V_BSTR(&result), L"1234"), "got %s\n", wine_dbgstr_w(V_BSTR(&result)));
6848 VariantClear(&left);
6849 VariantClear(&right);
6850 VariantClear(&result);
6852 init_test_dispatch(VT_NULL, &dispatch);
6853 dispatch.result = E_OUTOFMEMORY;
6854 V_VT(&right) = VT_DISPATCH;
6855 V_DISPATCH(&right) = &dispatch.IDispatch_iface;
6857 SET_EXPECT(dispatch_invoke);
6858 hres = VarCat(&left, &right, &result);
6859 ok(hres == E_OUTOFMEMORY, "got 0x%08x\n", hres);
6860 CHECK_CALLED(dispatch_invoke);
6862 VariantClear(&left);
6863 VariantClear(&right);
6864 VariantClear(&result);
6866 init_test_dispatch(VT_NULL, &dispatch);
6867 dispatch.result = DISP_E_TYPEMISMATCH;
6868 V_VT(&right) = VT_DISPATCH;
6869 V_DISPATCH(&right) = &dispatch.IDispatch_iface;
6871 SET_EXPECT(dispatch_invoke);
6872 hres = VarCat(&left, &right, &result);
6873 ok(hres == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hres);
6874 CHECK_CALLED(dispatch_invoke);
6876 VariantClear(&left);
6877 VariantClear(&right);
6878 VariantClear(&result);
6880 /* Test boolean conversion */
6881 V_VT(&left) = VT_BOOL;
6882 V_BOOL(&left) = VARIANT_TRUE;
6883 V_VT(&right) = VT_BSTR;
6884 V_BSTR(&right) = SysAllocStringLen(NULL,0);
6885 hres = pVarCat(&left, &right, &result);
6886 ok(hres == S_OK, "VarCat failed: %08x\n", hres);
6887 VariantClear(&right);
6889 cmp = lstrcmpW(V_BSTR(&result), L"True");
6890 VariantClear(&result);
6891 if(!cmp) {
6892 V_VT(&right) = VT_BOOL;
6893 V_BOOL(&right) = 100;
6894 hres = pVarCat(&left, &right, &result);
6895 ok(hres == S_OK, "VarCat failed: %08x\n", hres);
6896 test_bstr_var(&result, L"TrueTrue");
6897 VariantClear(&result);
6899 V_BOOL(&right) = VARIANT_FALSE;
6900 hres = pVarCat(&left, &right, &result);
6901 ok(hres == S_OK, "VarCat failed: %08x\n", hres);
6902 test_bstr_var(&result, L"TrueFalse");
6903 VariantClear(&result);
6904 }else {
6905 skip("Got %s as True, assuming non-English locale\n", wine_dbgstr_w(V_BSTR(&result)));
6909 static HRESULT (WINAPI *pVarAnd)(LPVARIANT,LPVARIANT,LPVARIANT);
6911 #define VARAND(vt1,val1,vt2,val2,rvt,rval) \
6912 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
6913 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
6914 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
6915 test_var_call2( __LINE__, pVarAnd, &left, &right, &exp )
6917 #define VARANDCY(vt1,val1,val2,rvt,rval) \
6918 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
6919 V_VT(&right) = VT_CY; V_CY(&right).int64 = val2; \
6920 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
6921 test_var_call2( __LINE__, pVarAnd, &left, &right, &exp )
6923 /* Skip any type that is not defined or produces an error for every case */
6924 #define SKIPTESTAND(a) \
6925 if (a == VT_ERROR || a == VT_VARIANT || \
6926 a == VT_DISPATCH || a == VT_UNKNOWN || \
6927 a > VT_UINT || a == 15 /*not defined*/) \
6928 continue
6930 static void test_VarAnd(void)
6932 static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
6933 static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
6934 VARIANT left, right, exp, result;
6935 BSTR false_str, true_str;
6936 VARTYPE i;
6937 HRESULT hres;
6939 CHECKPTR(VarAnd);
6941 true_str = SysAllocString(szTrue);
6942 false_str = SysAllocString(szFalse);
6944 /* Test all possible flag/vt combinations & the resulting vt type */
6945 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
6947 VARTYPE leftvt, rightvt, resvt;
6949 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
6951 SKIPTESTAND(leftvt);
6953 /* Check if we need/have support for I8 and/or UI8 */
6954 if ((leftvt == VT_I8 || leftvt == VT_UI8) && !has_i8)
6955 continue;
6957 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
6959 BOOL bFail = FALSE;
6960 SKIPTESTAND(rightvt);
6962 /* Check if we need/have support for I8 and/or UI8 */
6963 if ((rightvt == VT_I8 || rightvt == VT_UI8) && !has_i8)
6964 continue;
6966 memset(&left, 0, sizeof(left));
6967 memset(&right, 0, sizeof(right));
6968 V_VT(&left) = leftvt | ExtraFlags[i];
6969 V_VT(&right) = rightvt | ExtraFlags[i];
6970 V_VT(&result) = VT_EMPTY;
6971 resvt = VT_EMPTY;
6972 if ((leftvt | ExtraFlags[i]) == VT_BSTR)
6973 V_BSTR(&left) = true_str;
6974 if ((rightvt | ExtraFlags[i]) == VT_BSTR)
6975 V_BSTR(&right) = true_str;
6977 /* Native VarAnd always returns an error when using extra
6978 * flags or if the variant combination is I8 and INT.
6980 if ((leftvt == VT_I8 && rightvt == VT_INT) ||
6981 (leftvt == VT_INT && rightvt == VT_I8) ||
6982 ExtraFlags[i] != 0)
6983 bFail = TRUE;
6985 /* Determine return type */
6986 else if (leftvt == VT_I8 || rightvt == VT_I8)
6987 resvt = VT_I8;
6988 else if (leftvt == VT_I4 || rightvt == VT_I4 ||
6989 leftvt == VT_UINT || rightvt == VT_UINT ||
6990 leftvt == VT_INT || rightvt == VT_INT ||
6991 leftvt == VT_R4 || rightvt == VT_R4 ||
6992 leftvt == VT_R8 || rightvt == VT_R8 ||
6993 leftvt == VT_CY || rightvt == VT_CY ||
6994 leftvt == VT_DATE || rightvt == VT_DATE ||
6995 leftvt == VT_I1 || rightvt == VT_I1 ||
6996 leftvt == VT_UI2 || rightvt == VT_UI2 ||
6997 leftvt == VT_UI4 || rightvt == VT_UI4 ||
6998 leftvt == VT_UI8 || rightvt == VT_UI8 ||
6999 leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
7000 resvt = VT_I4;
7001 else if (leftvt == VT_UI1 || rightvt == VT_UI1 ||
7002 leftvt == VT_I2 || rightvt == VT_I2 ||
7003 leftvt == VT_EMPTY || rightvt == VT_EMPTY)
7004 if ((leftvt == VT_NULL && rightvt == VT_UI1) ||
7005 (leftvt == VT_UI1 && rightvt == VT_NULL) ||
7006 (leftvt == VT_UI1 && rightvt == VT_UI1))
7007 resvt = VT_UI1;
7008 else
7009 resvt = VT_I2;
7010 else if (leftvt == VT_BOOL || rightvt == VT_BOOL ||
7011 (leftvt == VT_BSTR && rightvt == VT_BSTR))
7012 resvt = VT_BOOL;
7013 else if (leftvt == VT_NULL || rightvt == VT_NULL ||
7014 leftvt == VT_BSTR || rightvt == VT_BSTR)
7015 resvt = VT_NULL;
7016 else
7017 bFail = TRUE;
7019 hres = pVarAnd(&left, &right, &result);
7021 /* Check expected HRESULT and if result variant type is correct */
7022 if (bFail)
7023 ok (hres == DISP_E_BADVARTYPE || hres == DISP_E_TYPEMISMATCH,
7024 "VarAnd: %s|0x%X, %s|0x%X: got vt %s hr 0x%X\n",
7025 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i],
7026 vtstr(V_VT(&result)), hres);
7027 else
7028 ok (hres == S_OK && resvt == V_VT(&result),
7029 "VarAnd: %s|0x%X, %s|0x%X: expected vt %s hr 0x%X, got vt %s hr 0x%X\n",
7030 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i], vtstr(resvt),
7031 S_OK, vtstr(V_VT(&result)), hres);
7037 * Test returned values. Since we know the returned type is correct
7038 * and that we handle all combinations of invalid types, just check
7039 * that good type combinations produce the desired value.
7040 * FIXME: Test VT_DECIMAL
7042 VARAND(EMPTY,0,EMPTY,0,I2,0);
7043 VARAND(EMPTY,1,EMPTY,0,I2,0);
7044 VARAND(EMPTY,1,EMPTY,1,I2,0);
7045 VARAND(EMPTY,0,NULL,0,I2,0);
7046 VARAND(EMPTY,1,NULL,0,I2,0);
7047 VARAND(EMPTY,1,NULL,1,I2,0);
7048 VARAND(EMPTY,0,I1,0,I4,0);
7049 VARAND(EMPTY,0,I1,1,I4,0);
7050 VARAND(EMPTY,1,I1,1,I4,0);
7051 VARAND(EMPTY,0,UI1,0,I2,0);
7052 VARAND(EMPTY,0,UI1,1,I2,0);
7053 VARAND(EMPTY,1,UI1,1,I2,0);
7054 VARAND(EMPTY,0,I2,0,I2,0);
7055 VARAND(EMPTY,0,I2,1,I2,0);
7056 VARAND(EMPTY,1,I2,1,I2,0);
7057 VARAND(EMPTY,0,UI2,0,I4,0);
7058 VARAND(EMPTY,0,UI2,1,I4,0);
7059 VARAND(EMPTY,1,UI2,1,I4,0);
7060 VARAND(EMPTY,0,I4,0,I4,0);
7061 VARAND(EMPTY,0,I4,1,I4,0);
7062 VARAND(EMPTY,1,I4,1,I4,0);
7063 VARAND(EMPTY,0,UI4,0,I4,0);
7064 VARAND(EMPTY,0,UI4,1,I4,0);
7065 VARAND(EMPTY,1,UI4,1,I4,0);
7066 if (has_i8)
7068 VARAND(EMPTY,0,I8,0,I8,0);
7069 VARAND(EMPTY,0,I8,1,I8,0);
7070 VARAND(EMPTY,1,I8,1,I8,0);
7071 VARAND(EMPTY,0,UI8,0,I4,0);
7072 VARAND(EMPTY,0,UI8,1,I4,0);
7073 VARAND(EMPTY,1,UI8,1,I4,0);
7075 VARAND(EMPTY,0,INT,0,I4,0);
7076 VARAND(EMPTY,0,INT,1,I4,0);
7077 VARAND(EMPTY,1,INT,1,I4,0);
7078 VARAND(EMPTY,0,UINT,0,I4,0);
7079 VARAND(EMPTY,0,UINT,1,I4,0);
7080 VARAND(EMPTY,1,UINT,1,I4,0);
7081 VARAND(EMPTY,0,BOOL,0,I2,0);
7082 VARAND(EMPTY,0,BOOL,1,I2,0);
7083 VARAND(EMPTY,1,BOOL,1,I2,0);
7084 VARAND(EMPTY,0,R4,0,I4,0);
7085 VARAND(EMPTY,0,R4,1,I4,0);
7086 VARAND(EMPTY,1,R4,1,I4,0);
7087 VARAND(EMPTY,0,R8,0,I4,0);
7088 VARAND(EMPTY,0,R8,1,I4,0);
7089 VARAND(EMPTY,1,R8,1,I4,0);
7090 VARAND(EMPTY,0,BSTR,false_str,I2,0);
7091 VARAND(EMPTY,0,BSTR,true_str,I2,0);
7092 VARANDCY(EMPTY,0,10000,I4,0);
7094 /* NULL OR 0 = NULL. NULL OR n = n */
7095 VARAND(NULL,0,NULL,0,NULL,0);
7096 VARAND(NULL,1,NULL,0,NULL,0);
7097 VARAND(NULL,0,I1,0,I4,0);
7098 VARAND(NULL,0,I1,1,NULL,0);
7099 VARAND(NULL,0,UI1,0,UI1,0);
7100 VARAND(NULL,0,UI1,1,NULL,0);
7101 VARAND(NULL,0,I2,0,I2,0);
7102 VARAND(NULL,0,I2,1,NULL,0);
7103 VARAND(NULL,0,UI2,0,I4,0);
7104 VARAND(NULL,0,UI2,1,NULL,0);
7105 VARAND(NULL,0,I4,0,I4,0);
7106 VARAND(NULL,0,I4,1,NULL,0);
7107 VARAND(NULL,0,UI4,0,I4,0);
7108 VARAND(NULL,0,UI4,1,NULL,0);
7109 if (has_i8)
7111 VARAND(NULL,0,I8,0,I8,0);
7112 VARAND(NULL,0,I8,1,NULL,0);
7113 VARAND(NULL,0,UI8,0,I4,0);
7114 VARAND(NULL,0,UI8,1,NULL,0);
7116 VARAND(NULL,0,INT,0,I4,0);
7117 VARAND(NULL,0,INT,1,NULL,0);
7118 VARAND(NULL,0,UINT,0,I4,0);
7119 VARAND(NULL,0,UINT,1,NULL,0);
7120 VARAND(NULL,0,BOOL,0,BOOL,0);
7121 VARAND(NULL,0,BOOL,1,NULL,0);
7122 VARAND(NULL,0,R4,0,I4,0);
7123 VARAND(NULL,0,R4,1,NULL,0);
7124 VARAND(NULL,0,R8,0,I4,0);
7125 VARAND(NULL,0,R8,1,NULL,0);
7126 VARAND(NULL,0,BSTR,false_str,BOOL,0);
7127 VARAND(NULL,0,BSTR,true_str,NULL,VARIANT_FALSE);
7128 VARANDCY(NULL,0,10000,NULL,0);
7129 VARANDCY(NULL,0,0,I4,0);
7130 VARAND(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
7131 VARAND(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE);
7132 VARAND(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE);
7133 VARAND(BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE);
7135 /* Assume x,y & y,x are the same from now on to reduce the number of tests */
7136 VARAND(BOOL,VARIANT_TRUE,I1,-1,I4,-1);
7137 VARAND(BOOL,VARIANT_TRUE,I1,0,I4,0);
7138 VARAND(BOOL,VARIANT_FALSE,I1,0,I4,0);
7139 VARAND(BOOL,VARIANT_TRUE,UI1,255,I2,255);
7140 VARAND(BOOL,VARIANT_TRUE,UI1,0,I2,0);
7141 VARAND(BOOL,VARIANT_FALSE,UI1,0,I2,0);
7142 VARAND(BOOL,VARIANT_TRUE,I2,-1,I2,-1);
7143 VARAND(BOOL,VARIANT_TRUE,I2,0,I2,0);
7144 VARAND(BOOL,VARIANT_FALSE,I2,0,I2,0);
7145 VARAND(BOOL,VARIANT_TRUE,UI2,65535,I4,65535);
7146 VARAND(BOOL,VARIANT_TRUE,UI2,0,I4,0);
7147 VARAND(BOOL,VARIANT_FALSE,UI2,0,I4,0);
7148 VARAND(BOOL,VARIANT_TRUE,I4,-1,I4,-1);
7149 VARAND(BOOL,VARIANT_TRUE,I4,0,I4,0);
7150 VARAND(BOOL,VARIANT_FALSE,I4,0,I4,0);
7151 VARAND(BOOL,VARIANT_TRUE,UI4,0xffffffff,I4,-1);
7152 VARAND(BOOL,VARIANT_TRUE,UI4,0,I4,0);
7153 VARAND(BOOL,VARIANT_FALSE,UI4,0,I4,0);
7154 VARAND(BOOL,VARIANT_TRUE,R4,-1,I4,-1);
7155 VARAND(BOOL,VARIANT_TRUE,R4,0,I4,0);
7156 VARAND(BOOL,VARIANT_FALSE,R4,0,I4,0);
7157 VARAND(BOOL,VARIANT_TRUE,R8,-1,I4,-1);
7158 VARAND(BOOL,VARIANT_TRUE,R8,0,I4,0);
7159 VARAND(BOOL,VARIANT_FALSE,R8,0,I4,0);
7160 VARAND(BOOL,VARIANT_TRUE,DATE,-1,I4,-1);
7161 VARAND(BOOL,VARIANT_TRUE,DATE,0,I4,0);
7162 VARAND(BOOL,VARIANT_FALSE,DATE,0,I4,0);
7163 if (has_i8)
7165 VARAND(BOOL,VARIANT_TRUE,I8,-1,I8,-1);
7166 VARAND(BOOL,VARIANT_TRUE,I8,0,I8,0);
7167 VARAND(BOOL,VARIANT_FALSE,I8,0,I8,0);
7168 VARAND(BOOL,VARIANT_TRUE,UI8,0,I4,0);
7169 VARAND(BOOL,VARIANT_FALSE,UI8,0,I4,0);
7171 VARAND(BOOL,VARIANT_TRUE,INT,-1,I4,-1);
7172 VARAND(BOOL,VARIANT_TRUE,INT,0,I4,0);
7173 VARAND(BOOL,VARIANT_FALSE,INT,0,I4,0);
7174 VARAND(BOOL,VARIANT_TRUE,UINT,0xffffffff,I4,-1);
7175 VARAND(BOOL,VARIANT_TRUE,UINT,0,I4,0);
7176 VARAND(BOOL,VARIANT_FALSE,UINT,0,I4,0);
7177 VARAND(BOOL,VARIANT_FALSE,BSTR,false_str,BOOL,VARIANT_FALSE);
7178 VARAND(BOOL,VARIANT_TRUE,BSTR,false_str,BOOL,VARIANT_FALSE);
7179 VARAND(BOOL,VARIANT_FALSE,BSTR,true_str,BOOL,VARIANT_FALSE);
7180 VARAND(BOOL,VARIANT_TRUE,BSTR,true_str,BOOL,VARIANT_TRUE);
7181 VARANDCY(BOOL,VARIANT_TRUE,10000,I4,1);
7182 VARANDCY(BOOL,VARIANT_TRUE,0,I4,0);
7183 VARANDCY(BOOL,VARIANT_FALSE,0,I4,0);
7184 VARAND(I1,-1,I1,-1,I4,-1);
7185 VARAND(I1,-1,I1,0,I4,0);
7186 VARAND(I1,0,I1,0,I4,0);
7187 VARAND(I1,-1,UI1,255,I4,255);
7188 VARAND(I1,-1,UI1,0,I4,0);
7189 VARAND(I1,0,UI1,0,I4,0);
7190 VARAND(I1,-1,I2,-1,I4,-1);
7191 VARAND(I1,-1,I2,0,I4,0);
7192 VARAND(I1,0,I2,0,I4,0);
7193 VARAND(I1,-1,UI2,65535,I4,65535);
7194 VARAND(I1,-1,UI2,0,I4,0);
7195 VARAND(I1,0,UI2,0,I4,0);
7196 VARAND(I1,-1,I4,-1,I4,-1);
7197 VARAND(I1,-1,I4,0,I4,0);
7198 VARAND(I1,0,I4,0,I4,0);
7199 VARAND(I1,-1,UI4,0xffffffff,I4,-1);
7200 VARAND(I1,-1,UI4,0,I4,0);
7201 VARAND(I1,0,UI4,0,I4,0);
7202 VARAND(I1,-1,R4,-1,I4,-1);
7203 VARAND(I1,-1,R4,0,I4,0);
7204 VARAND(I1,0,R4,0,I4,0);
7205 VARAND(I1,-1,R8,-1,I4,-1);
7206 VARAND(I1,-1,R8,0,I4,0);
7207 VARAND(I1,0,R8,0,I4,0);
7208 VARAND(I1,-1,DATE,-1,I4,-1);
7209 VARAND(I1,-1,DATE,0,I4,0);
7210 VARAND(I1,0,DATE,0,I4,0);
7211 if (has_i8)
7213 VARAND(I1,-1,I8,-1,I8,-1);
7214 VARAND(I1,-1,I8,0,I8,0);
7215 VARAND(I1,0,I8,0,I8,0);
7216 VARAND(I1,-1,UI8,0,I4,0);
7217 VARAND(I1,0,UI8,0,I4,0);
7219 VARAND(I1,-1,INT,-1,I4,-1);
7220 VARAND(I1,-1,INT,0,I4,0);
7221 VARAND(I1,0,INT,0,I4,0);
7222 VARAND(I1,-1,UINT,0xffffffff,I4,-1);
7223 VARAND(I1,-1,UINT,0,I4,0);
7224 VARAND(I1,0,UINT,0,I4,0);
7225 VARAND(I1,0,BSTR,false_str,I4,0);
7226 VARAND(I1,-1,BSTR,false_str,I4,0);
7227 VARAND(I1,0,BSTR,true_str,I4,0);
7228 VARAND(I1,-1,BSTR,true_str,I4,-1);
7229 VARANDCY(I1,-1,10000,I4,1);
7230 VARANDCY(I1,-1,0,I4,0);
7231 VARANDCY(I1,0,0,I4,0);
7233 VARAND(UI1,255,UI1,255,UI1,255);
7234 VARAND(UI1,255,UI1,0,UI1,0);
7235 VARAND(UI1,0,UI1,0,UI1,0);
7236 VARAND(UI1,255,I2,-1,I2,255);
7237 VARAND(UI1,255,I2,0,I2,0);
7238 VARAND(UI1,0,I2,0,I2,0);
7239 VARAND(UI1,255,UI2,65535,I4,255);
7240 VARAND(UI1,255,UI2,0,I4,0);
7241 VARAND(UI1,0,UI2,0,I4,0);
7242 VARAND(UI1,255,I4,-1,I4,255);
7243 VARAND(UI1,255,I4,0,I4,0);
7244 VARAND(UI1,0,I4,0,I4,0);
7245 VARAND(UI1,255,UI4,0xffffffff,I4,255);
7246 VARAND(UI1,255,UI4,0,I4,0);
7247 VARAND(UI1,0,UI4,0,I4,0);
7248 VARAND(UI1,255,R4,-1,I4,255);
7249 VARAND(UI1,255,R4,0,I4,0);
7250 VARAND(UI1,0,R4,0,I4,0);
7251 VARAND(UI1,255,R8,-1,I4,255);
7252 VARAND(UI1,255,R8,0,I4,0);
7253 VARAND(UI1,0,R8,0,I4,0);
7254 VARAND(UI1,255,DATE,-1,I4,255);
7255 VARAND(UI1,255,DATE,0,I4,0);
7256 VARAND(UI1,0,DATE,0,I4,0);
7257 if (has_i8)
7259 VARAND(UI1,255,I8,-1,I8,255);
7260 VARAND(UI1,255,I8,0,I8,0);
7261 VARAND(UI1,0,I8,0,I8,0);
7262 VARAND(UI1,255,UI8,0,I4,0);
7263 VARAND(UI1,0,UI8,0,I4,0);
7265 VARAND(UI1,255,INT,-1,I4,255);
7266 VARAND(UI1,255,INT,0,I4,0);
7267 VARAND(UI1,0,INT,0,I4,0);
7268 VARAND(UI1,255,UINT,0xffffffff,I4,255);
7269 VARAND(UI1,255,UINT,0,I4,0);
7270 VARAND(UI1,0,UINT,0,I4,0);
7271 VARAND(UI1,0,BSTR,false_str,I2,0);
7272 VARAND(UI1,255,BSTR,false_str,I2,0);
7273 VARAND(UI1,0,BSTR,true_str,I2,0);
7274 VARAND(UI1,255,BSTR,true_str,I2,255);
7275 VARANDCY(UI1,255,10000,I4,1);
7276 VARANDCY(UI1,255,0,I4,0);
7277 VARANDCY(UI1,0,0,I4,0);
7279 VARAND(I2,-1,I2,-1,I2,-1);
7280 VARAND(I2,-1,I2,0,I2,0);
7281 VARAND(I2,0,I2,0,I2,0);
7282 VARAND(I2,-1,UI2,65535,I4,65535);
7283 VARAND(I2,-1,UI2,0,I4,0);
7284 VARAND(I2,0,UI2,0,I4,0);
7285 VARAND(I2,-1,I4,-1,I4,-1);
7286 VARAND(I2,-1,I4,0,I4,0);
7287 VARAND(I2,0,I4,0,I4,0);
7288 VARAND(I2,-1,UI4,0xffffffff,I4,-1);
7289 VARAND(I2,-1,UI4,0,I4,0);
7290 VARAND(I2,0,UI4,0,I4,0);
7291 VARAND(I2,-1,R4,-1,I4,-1);
7292 VARAND(I2,-1,R4,0,I4,0);
7293 VARAND(I2,0,R4,0,I4,0);
7294 VARAND(I2,-1,R8,-1,I4,-1);
7295 VARAND(I2,-1,R8,0,I4,0);
7296 VARAND(I2,0,R8,0,I4,0);
7297 VARAND(I2,-1,DATE,-1,I4,-1);
7298 VARAND(I2,-1,DATE,0,I4,0);
7299 VARAND(I2,0,DATE,0,I4,0);
7300 if (has_i8)
7302 VARAND(I2,-1,I8,-1,I8,-1);
7303 VARAND(I2,-1,I8,0,I8,0);
7304 VARAND(I2,0,I8,0,I8,0);
7305 VARAND(I2,-1,UI8,0,I4,0);
7306 VARAND(I2,0,UI8,0,I4,0);
7308 VARAND(I2,-1,INT,-1,I4,-1);
7309 VARAND(I2,-1,INT,0,I4,0);
7310 VARAND(I2,0,INT,0,I4,0);
7311 VARAND(I2,-1,UINT,0xffffffff,I4,-1);
7312 VARAND(I2,-1,UINT,0,I4,0);
7313 VARAND(I2,0,UINT,0,I4,0);
7314 VARAND(I2,0,BSTR,false_str,I2,0);
7315 VARAND(I2,-1,BSTR,false_str,I2,0);
7316 VARAND(I2,0,BSTR,true_str,I2,0);
7317 VARAND(I2,-1,BSTR,true_str,I2,-1);
7318 VARANDCY(I2,-1,10000,I4,1);
7319 VARANDCY(I2,-1,0,I4,0);
7320 VARANDCY(I2,0,0,I4,0);
7322 VARAND(UI2,65535,UI2,65535,I4,65535);
7323 VARAND(UI2,65535,UI2,0,I4,0);
7324 VARAND(UI2,0,UI2,0,I4,0);
7325 VARAND(UI2,65535,I4,-1,I4,65535);
7326 VARAND(UI2,65535,I4,0,I4,0);
7327 VARAND(UI2,0,I4,0,I4,0);
7328 VARAND(UI2,65535,UI4,0xffffffff,I4,65535);
7329 VARAND(UI2,65535,UI4,0,I4,0);
7330 VARAND(UI2,0,UI4,0,I4,0);
7331 VARAND(UI2,65535,R4,-1,I4,65535);
7332 VARAND(UI2,65535,R4,0,I4,0);
7333 VARAND(UI2,0,R4,0,I4,0);
7334 VARAND(UI2,65535,R8,-1,I4,65535);
7335 VARAND(UI2,65535,R8,0,I4,0);
7336 VARAND(UI2,0,R8,0,I4,0);
7337 VARAND(UI2,65535,DATE,-1,I4,65535);
7338 VARAND(UI2,65535,DATE,0,I4,0);
7339 VARAND(UI2,0,DATE,0,I4,0);
7340 if (has_i8)
7342 VARAND(UI2,65535,I8,-1,I8,65535);
7343 VARAND(UI2,65535,I8,0,I8,0);
7344 VARAND(UI2,0,I8,0,I8,0);
7345 VARAND(UI2,65535,UI8,0,I4,0);
7346 VARAND(UI2,0,UI8,0,I4,0);
7348 VARAND(UI2,65535,INT,-1,I4,65535);
7349 VARAND(UI2,65535,INT,0,I4,0);
7350 VARAND(UI2,0,INT,0,I4,0);
7351 VARAND(UI2,65535,UINT,0xffffffff,I4,65535);
7352 VARAND(UI2,65535,UINT,0,I4,0);
7353 VARAND(UI2,0,UINT,0,I4,0);
7354 VARAND(UI2,0,BSTR,false_str,I4,0);
7355 VARAND(UI2,65535,BSTR,false_str,I4,0);
7356 VARAND(UI2,0,BSTR,true_str,I4,0);
7357 VARAND(UI2,65535,BSTR,true_str,I4,65535);
7358 VARANDCY(UI2,65535,10000,I4,1);
7359 VARANDCY(UI2,65535,0,I4,0);
7360 VARANDCY(UI2,0,0,I4,0);
7362 VARAND(I4,-1,I4,-1,I4,-1);
7363 VARAND(I4,-1,I4,0,I4,0);
7364 VARAND(I4,0,I4,0,I4,0);
7365 VARAND(I4,-1,UI4,0xffffffff,I4,-1);
7366 VARAND(I4,-1,UI4,0,I4,0);
7367 VARAND(I4,0,UI4,0,I4,0);
7368 VARAND(I4,-1,R4,-1,I4,-1);
7369 VARAND(I4,-1,R4,0,I4,0);
7370 VARAND(I4,0,R4,0,I4,0);
7371 VARAND(I4,-1,R8,-1,I4,-1);
7372 VARAND(I4,-1,R8,0,I4,0);
7373 VARAND(I4,0,R8,0,I4,0);
7374 VARAND(I4,-1,DATE,-1,I4,-1);
7375 VARAND(I4,-1,DATE,0,I4,0);
7376 VARAND(I4,0,DATE,0,I4,0);
7377 if (has_i8)
7379 VARAND(I4,-1,I8,-1,I8,-1);
7380 VARAND(I4,-1,I8,0,I8,0);
7381 VARAND(I4,0,I8,0,I8,0);
7382 VARAND(I4,-1,UI8,0,I4,0);
7383 VARAND(I4,0,UI8,0,I4,0);
7385 VARAND(I4,-1,INT,-1,I4,-1);
7386 VARAND(I4,-1,INT,0,I4,0);
7387 VARAND(I4,0,INT,0,I4,0);
7388 VARAND(I4,-1,UINT,0xffffffff,I4,-1);
7389 VARAND(I4,-1,UINT,0,I4,0);
7390 VARAND(I4,0,UINT,0,I4,0);
7391 VARAND(I4,0,BSTR,false_str,I4,0);
7392 VARAND(I4,-1,BSTR,false_str,I4,0);
7393 VARAND(I4,0,BSTR,true_str,I4,0);
7394 VARAND(I4,-1,BSTR,true_str,I4,-1);
7395 VARANDCY(I4,-1,10000,I4,1);
7396 VARANDCY(I4,-1,0,I4,0);
7397 VARANDCY(I4,0,0,I4,0);
7399 VARAND(UI4,0xffffffff,UI4,0xffffffff,I4,-1);
7400 VARAND(UI4,0xffffffff,UI4,0,I4,0);
7401 VARAND(UI4,0,UI4,0,I4,0);
7402 VARAND(UI4,0xffffffff,R4,-1,I4,-1);
7403 VARAND(UI4,0xffffffff,R4,0,I4,0);
7404 VARAND(UI4,0,R4,0,I4,0);
7405 VARAND(UI4,0xffffffff,R8,-1,I4,-1);
7406 VARAND(UI4,0xffffffff,R8,0,I4,0);
7407 VARAND(UI4,0,R8,0,I4,0);
7408 VARAND(UI4,0xffffffff,DATE,-1,I4,-1);
7409 VARAND(UI4,0xffffffff,DATE,0,I4,0);
7410 VARAND(UI4,0,DATE,0,I4,0);
7411 if (has_i8)
7413 VARAND(UI4,0xffffffff,I8,0,I8,0);
7414 VARAND(UI4,0,I8,0,I8,0);
7415 VARAND(UI4,0xffffffff,UI8,0,I4,0);
7416 VARAND(UI4,0,UI8,0,I4,0);
7418 VARAND(UI4,0xffffffff,INT,-1,I4,-1);
7419 VARAND(UI4,0xffffffff,INT,0,I4,0);
7420 VARAND(UI4,0,INT,0,I4,0);
7421 VARAND(UI4,0xffffffff,UINT,0xffffffff,I4,-1);
7422 VARAND(UI4,0xffffffff,UINT,0,I4,0);
7423 VARAND(UI4,0,UINT,0,I4,0);
7424 VARAND(UI4,0,BSTR,false_str,I4,0);
7425 VARAND(UI4,0xffffffff,BSTR,false_str,I4,0);
7426 VARAND(UI4,0,BSTR,true_str,I4,0);
7427 VARAND(UI4,0xffffffff,BSTR,true_str,I4,-1);
7428 VARANDCY(UI4,0xffffffff,10000,I4,1);
7429 VARANDCY(UI4,0xffffffff,0,I4,0);
7430 VARANDCY(UI4,0,0,I4,0);
7432 VARAND(R4,-1,R4,-1,I4,-1);
7433 VARAND(R4,-1,R4,0,I4,0);
7434 VARAND(R4,0,R4,0,I4,0);
7435 VARAND(R4,-1,R8,-1,I4,-1);
7436 VARAND(R4,-1,R8,0,I4,0);
7437 VARAND(R4,0,R8,0,I4,0);
7438 VARAND(R4,-1,DATE,-1,I4,-1);
7439 VARAND(R4,-1,DATE,0,I4,0);
7440 VARAND(R4,0,DATE,0,I4,0);
7441 if (has_i8)
7443 VARAND(R4,-1,I8,-1,I8,-1);
7444 VARAND(R4,-1,I8,0,I8,0);
7445 VARAND(R4,0,I8,0,I8,0);
7446 VARAND(R4,-1,UI8,0,I4,0);
7447 VARAND(R4,0,UI8,0,I4,0);
7449 VARAND(R4,-1,INT,-1,I4,-1);
7450 VARAND(R4,-1,INT,0,I4,0);
7451 VARAND(R4,0,INT,0,I4,0);
7452 VARAND(R4,-1,UINT,0xffffffff,I4,-1);
7453 VARAND(R4,-1,UINT,0,I4,0);
7454 VARAND(R4,0,UINT,0,I4,0);
7455 VARAND(R4,0,BSTR,false_str,I4,0);
7456 VARAND(R4,-1,BSTR,false_str,I4,0);
7457 VARAND(R4,0,BSTR,true_str,I4,0);
7458 VARAND(R4,-1,BSTR,true_str,I4,-1);
7459 VARANDCY(R4,-1,10000,I4,1);
7460 VARANDCY(R4,-1,0,I4,0);
7461 VARANDCY(R4,0,0,I4,0);
7463 VARAND(R8,-1,R8,-1,I4,-1);
7464 VARAND(R8,-1,R8,0,I4,0);
7465 VARAND(R8,0,R8,0,I4,0);
7466 VARAND(R8,-1,DATE,-1,I4,-1);
7467 VARAND(R8,-1,DATE,0,I4,0);
7468 VARAND(R8,0,DATE,0,I4,0);
7469 if (has_i8)
7471 VARAND(R8,-1,I8,-1,I8,-1);
7472 VARAND(R8,-1,I8,0,I8,0);
7473 VARAND(R8,0,I8,0,I8,0);
7474 VARAND(R8,-1,UI8,0,I4,0);
7475 VARAND(R8,0,UI8,0,I4,0);
7477 VARAND(R8,-1,INT,-1,I4,-1);
7478 VARAND(R8,-1,INT,0,I4,0);
7479 VARAND(R8,0,INT,0,I4,0);
7480 VARAND(R8,-1,UINT,0xffffffff,I4,-1);
7481 VARAND(R8,-1,UINT,0,I4,0);
7482 VARAND(R8,0,UINT,0,I4,0);
7483 VARAND(R8,0,BSTR,false_str,I4,0);
7484 VARAND(R8,-1,BSTR,false_str,I4,0);
7485 VARAND(R8,0,BSTR,true_str,I4,0);
7486 VARAND(R8,-1,BSTR,true_str,I4,-1);
7487 VARANDCY(R8,-1,10000,I4,1);
7488 VARANDCY(R8,-1,0,I4,0);
7489 VARANDCY(R8,0,0,I4,0);
7491 VARAND(DATE,-1,DATE,-1,I4,-1);
7492 VARAND(DATE,-1,DATE,0,I4,0);
7493 VARAND(DATE,0,DATE,0,I4,0);
7494 if (has_i8)
7496 VARAND(DATE,-1,I8,-1,I8,-1);
7497 VARAND(DATE,-1,I8,0,I8,0);
7498 VARAND(DATE,0,I8,0,I8,0);
7499 VARAND(DATE,-1,UI8,0,I4,0);
7500 VARAND(DATE,0,UI8,0,I4,0);
7502 VARAND(DATE,-1,INT,-1,I4,-1);
7503 VARAND(DATE,-1,INT,0,I4,0);
7504 VARAND(DATE,0,INT,0,I4,0);
7505 VARAND(DATE,-1,UINT,0xffffffff,I4,-1);
7506 VARAND(DATE,-1,UINT,0,I4,0);
7507 VARAND(DATE,0,UINT,0,I4,0);
7508 VARAND(DATE,0,BSTR,false_str,I4,0);
7509 VARAND(DATE,-1,BSTR,false_str,I4,0);
7510 VARAND(DATE,0,BSTR,true_str,I4,0);
7511 VARAND(DATE,-1,BSTR,true_str,I4,-1);
7512 VARANDCY(DATE,-1,10000,I4,1);
7513 VARANDCY(DATE,-1,0,I4,0);
7514 VARANDCY(DATE,0,0,I4,0);
7516 if (has_i8)
7518 VARAND(I8,-1,I8,-1,I8,-1);
7519 VARAND(I8,-1,I8,0,I8,0);
7520 VARAND(I8,0,I8,0,I8,0);
7521 VARAND(I8,-1,UI8,0,I8,0);
7522 VARAND(I8,0,UI8,0,I8,0);
7523 VARAND(I8,-1,UINT,0,I8,0);
7524 VARAND(I8,0,UINT,0,I8,0);
7525 VARAND(I8,0,BSTR,false_str,I8,0);
7526 VARAND(I8,-1,BSTR,false_str,I8,0);
7527 VARAND(I8,0,BSTR,true_str,I8,0);
7528 VARAND(I8,-1,BSTR,true_str,I8,-1);
7529 VARANDCY(I8,-1,10000,I8,1);
7530 VARANDCY(I8,-1,0,I8,0);
7531 VARANDCY(I8,0,0,I8,0);
7533 VARAND(UI8,0xffff,UI8,0xffff,I4,0xffff);
7534 VARAND(UI8,0xffff,UI8,0,I4,0);
7535 VARAND(UI8,0,UI8,0,I4,0);
7536 VARAND(UI8,0xffff,INT,-1,I4,65535);
7537 VARAND(UI8,0xffff,INT,0,I4,0);
7538 VARAND(UI8,0,INT,0,I4,0);
7539 VARAND(UI8,0xffff,UINT,0xffff,I4,0xffff);
7540 VARAND(UI8,0xffff,UINT,0,I4,0);
7541 VARAND(UI8,0,UINT,0,I4,0);
7542 VARAND(UI8,0,BSTR,false_str,I4,0);
7543 VARAND(UI8,0xffff,BSTR,false_str,I4,0);
7544 VARAND(UI8,0,BSTR,true_str,I4,0);
7545 VARAND(UI8,0xffff,BSTR,true_str,I4,65535);
7546 VARANDCY(UI8,0xffff,10000,I4,1);
7547 VARANDCY(UI8,0xffff,0,I4,0);
7548 VARANDCY(UI8,0,0,I4,0);
7551 VARAND(INT,-1,INT,-1,I4,-1);
7552 VARAND(INT,-1,INT,0,I4,0);
7553 VARAND(INT,0,INT,0,I4,0);
7554 VARAND(INT,-1,UINT,0xffff,I4,65535);
7555 VARAND(INT,-1,UINT,0,I4,0);
7556 VARAND(INT,0,UINT,0,I4,0);
7557 VARAND(INT,0,BSTR,false_str,I4,0);
7558 VARAND(INT,-1,BSTR,false_str,I4,0);
7559 VARAND(INT,0,BSTR,true_str,I4,0);
7560 VARAND(INT,-1,BSTR,true_str,I4,-1);
7561 VARANDCY(INT,-1,10000,I4,1);
7562 VARANDCY(INT,-1,0,I4,0);
7563 VARANDCY(INT,0,0,I4,0);
7565 VARAND(UINT,0xffff,UINT,0xffff,I4,0xffff);
7566 VARAND(UINT,0xffff,UINT,0,I4,0);
7567 VARAND(UINT,0,UINT,0,I4,0);
7568 VARAND(UINT,0,BSTR,false_str,I4,0);
7569 VARAND(UINT,0xffff,BSTR, false_str,I4,0);
7570 VARAND(UINT,0,BSTR,true_str,I4,0);
7571 VARAND(UINT,0xffff,BSTR,true_str,I4,65535);
7572 VARANDCY(UINT,0xffff,10000,I4,1);
7573 VARANDCY(UINT,0xffff,0,I4,0);
7574 VARANDCY(UINT,0,0,I4,0);
7576 VARAND(BSTR,false_str,BSTR,false_str,BOOL,0);
7577 VARAND(BSTR,true_str,BSTR,false_str,BOOL,VARIANT_FALSE);
7578 VARAND(BSTR,true_str,BSTR,true_str,BOOL,VARIANT_TRUE);
7579 VARANDCY(BSTR,true_str,10000,I4,1);
7580 VARANDCY(BSTR,false_str,10000,I4,0);
7582 SysFreeString(true_str);
7583 SysFreeString(false_str);
7586 static void test_cmp( int line, LCID lcid, UINT flags, VARIANT *left, VARIANT *right, HRESULT result )
7588 HRESULT hres;
7590 CHECKPTR(VarCmp);
7592 hres = pVarCmp(left,right,lcid,flags);
7593 ok_(__FILE__,line)(hres == result, "VarCmp(%s,%s): expected 0x%x, got hres=0x%x\n",
7594 variantstr(left), variantstr(right), result, hres );
7596 static void test_cmpex( int line, LCID lcid, VARIANT *left, VARIANT *right,
7597 HRESULT res1, HRESULT res2, HRESULT res3, HRESULT res4 )
7599 test_cmp( line, lcid, 0, left, right, res1 );
7600 V_VT(left) |= VT_RESERVED;
7601 test_cmp( line, lcid, 0, left, right, res2 );
7602 V_VT(left) &= ~VT_RESERVED;
7603 V_VT(right) |= VT_RESERVED;
7604 test_cmp( line, lcid, 0, left, right, res3 );
7605 V_VT(left) |= VT_RESERVED;
7606 test_cmp( line, lcid, 0, left, right, res4 );
7607 ok_(__FILE__,line)(V_VT(left) & V_VT(right) & VT_RESERVED, "VT_RESERVED filtered out\n");
7610 /* ERROR from wingdi.h is interfering here */
7611 #undef ERROR
7612 #define _VARCMP(vt1,val1,vtfl1,vt2,val2,vtfl2,lcid,flags,result) \
7613 V_##vt1(&left) = val1; V_VT(&left) = VT_##vt1 | vtfl1; \
7614 V_##vt2(&right) = val2; V_VT(&right) = VT_##vt2 | vtfl2; \
7615 test_cmp( __LINE__, lcid, flags, &left, &right, result )
7616 #define VARCMPEX(vt1,val1,vt2,val2,res1,res2,res3,res4) \
7617 V_##vt1(&left) = val1; V_VT(&left) = VT_##vt1; \
7618 V_##vt2(&right) = val2; V_VT(&right) = VT_##vt2; \
7619 test_cmpex( __LINE__, lcid, &left, &right, res1, res2, res3, res4 )
7620 #define VARCMP(vt1,val1,vt2,val2,result) \
7621 VARCMPEX(vt1,val1,vt2,val2,result,result,result,result)
7622 /* The above macros do not work for VT_NULL as NULL gets expanded first */
7623 #define V_NULL_ V_NULL
7624 #define VT_NULL_ VT_NULL
7626 static void test_VarCmp(void)
7628 VARIANT left, right;
7629 VARTYPE i;
7630 LCID lcid;
7631 HRESULT hres;
7632 DECIMAL dec;
7633 static const WCHAR szhuh[] = {'h','u','h','?','\0'};
7634 static const WCHAR sz2cents[] = {'2','c','e','n','t','s','\0'};
7635 static const WCHAR szempty[] = {'\0'};
7636 static const WCHAR sz0[] = {'0','\0'};
7637 static const WCHAR sz1[] = {'1','\0'};
7638 static const WCHAR sz7[] = {'7','\0'};
7639 static const WCHAR sz42[] = {'4','2','\0'};
7640 static const WCHAR sz1neg[] = {'-','1','\0'};
7641 static const WCHAR sz666neg[] = {'-','6','6','6','\0'};
7642 static const WCHAR sz1few[] = {'1','.','0','0','0','0','0','0','0','1','\0'};
7643 BSTR bstrhuh, bstrempty, bstr0, bstr1, bstr7, bstr42, bstr1neg, bstr666neg;
7644 BSTR bstr2cents, bstr1few;
7646 CHECKPTR(VarCmp);
7648 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
7649 bstrempty = SysAllocString(szempty);
7650 bstrhuh = SysAllocString(szhuh);
7651 bstr2cents = SysAllocString(sz2cents);
7652 bstr0 = SysAllocString(sz0);
7653 bstr1 = SysAllocString(sz1);
7654 bstr7 = SysAllocString(sz7);
7655 bstr42 = SysAllocString(sz42);
7656 bstr1neg = SysAllocString(sz1neg);
7657 bstr666neg = SysAllocString(sz666neg);
7658 bstr1few = SysAllocString(sz1few);
7660 /* Test all possible flag/vt combinations & the resulting vt type */
7661 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
7663 VARTYPE leftvt, rightvt;
7665 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
7668 SKIPTESTS(leftvt);
7670 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
7672 BOOL bFail = FALSE;
7673 HRESULT expect = VARCMP_EQ;
7675 SKIPTESTS(rightvt);
7677 memset(&left, 0, sizeof(left));
7678 memset(&right, 0, sizeof(right));
7679 V_VT(&left) = leftvt | ExtraFlags[i];
7680 if (leftvt == VT_BSTR) {
7681 V_BSTR(&left) = bstr1neg;
7682 if (ExtraFlags[i] & VT_RESERVED)
7683 expect = VARCMP_LT;
7684 else
7685 expect = VARCMP_GT;
7687 V_VT(&right) = rightvt | ExtraFlags[i];
7688 if (rightvt == VT_BSTR) {
7689 V_BSTR(&right) = bstr1neg;
7690 if (ExtraFlags[i] & VT_RESERVED)
7691 expect = VARCMP_GT;
7692 else
7693 expect = VARCMP_LT;
7696 /* Don't ask me why but native VarCmp cannot handle:
7697 VT_I1, VT_UI2, VT_UI4, VT_UINT and VT_UI8.
7698 VT_INT is only supported as left variant. Go figure.
7699 Tested with DCOM98, Win2k, WinXP */
7700 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
7701 !IsValidVariantClearVT(leftvt, ExtraFlags[i] & ~VT_RESERVED) ||
7702 !IsValidVariantClearVT(rightvt, ExtraFlags[i] & ~VT_RESERVED) ||
7703 leftvt == VT_CLSID || rightvt == VT_CLSID ||
7704 leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
7705 leftvt == VT_ERROR || rightvt == VT_ERROR ||
7706 leftvt == VT_RECORD || rightvt == VT_RECORD ||
7707 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN ||
7708 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
7709 leftvt == VT_I1 || rightvt == VT_I1 ||
7710 leftvt == VT_UI2 || rightvt == VT_UI2 ||
7711 leftvt == VT_UI4 || rightvt == VT_UI4 ||
7712 leftvt == VT_UI8 || rightvt == VT_UI8 ||
7713 rightvt == VT_INT ||
7714 leftvt == VT_UINT || rightvt == VT_UINT) {
7715 bFail = TRUE;
7718 if (leftvt == VT_ERROR && rightvt == VT_ERROR &&
7719 !(ExtraFlags[i] & ~VT_RESERVED)) {
7720 expect = VARCMP_EQ;
7721 bFail = FALSE;
7722 } else if (leftvt == VT_NULL || rightvt == VT_NULL)
7723 expect = VARCMP_NULL;
7724 else if (leftvt == VT_BSTR && rightvt == VT_BSTR)
7725 expect = VARCMP_EQ;
7726 else if (leftvt == VT_BSTR && rightvt == VT_EMPTY)
7727 expect = VARCMP_GT;
7728 else if (leftvt == VT_EMPTY && rightvt == VT_BSTR)
7729 expect = VARCMP_LT;
7731 hres = pVarCmp(&left, &right, LOCALE_USER_DEFAULT, 0);
7732 if (bFail) {
7733 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
7734 "VarCmp: %d|0x%X, %d|0x%X: Expected failure, got 0x%X\n",
7735 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres);
7736 } else {
7737 ok(hres == expect,
7738 "VarCmp: %d|0x%X, %d|0x%X: Expected 0x%X, got 0x%X\n",
7739 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], expect,
7740 hres);
7746 /* VARCMP{,EX} run each 4 tests with a permutation of all possible
7747 input variants with (1) and without (0) VT_RESERVED set. The order
7748 of the permutations is (0,0); (1,0); (0,1); (1,1) */
7749 VARCMP(INT,4711,I2,4711,VARCMP_EQ);
7750 VARCMP(INT,4711,I2,-4711,VARCMP_GT);
7751 VARCMP(ERROR,0,ERROR,0,VARCMP_EQ);
7752 VARCMP(ERROR,0,UI1,0,DISP_E_TYPEMISMATCH);
7753 VARCMP(EMPTY,0,EMPTY,0,VARCMP_EQ);
7754 VARCMP(I4,1,R8,1.0,VARCMP_EQ);
7755 VARCMP(EMPTY,19,I2,0,VARCMP_EQ);
7756 ok(V_EMPTY(&left) == 19, "VT_EMPTY modified!\n");
7757 VARCMP(I4,1,UI1,1,VARCMP_EQ);
7758 VARCMP(I2,2,I2,2,VARCMP_EQ);
7759 VARCMP(I2,1,I2,2,VARCMP_LT);
7760 VARCMP(I2,2,I2,1,VARCMP_GT);
7761 VARCMP(I2,2,EMPTY,1,VARCMP_GT);
7762 VARCMP(I2,2,NULL_,1,VARCMP_NULL);
7764 /* BSTR handling, especially in conjunction with VT_RESERVED */
7765 VARCMP(BSTR,bstr0,NULL_,0,VARCMP_NULL);
7766 VARCMP(BSTR,bstr0,BSTR,bstr0,VARCMP_EQ);
7767 VARCMP(BSTR,bstrempty,BSTR,bstr0,VARCMP_LT);
7768 VARCMP(BSTR,bstr7,BSTR,bstr0,VARCMP_GT);
7769 VARCMP(BSTR,bstr7,BSTR,bstr1neg,VARCMP_GT);
7770 VARCMP(BSTR,bstr0,BSTR,NULL,VARCMP_GT);
7771 VARCMP(BSTR,NULL,BSTR,NULL,VARCMP_EQ);
7772 VARCMP(BSTR,bstrempty,BSTR,NULL,VARCMP_EQ);
7773 VARCMP(BSTR,NULL,EMPTY,0,VARCMP_EQ);
7774 VARCMP(EMPTY,0,BSTR,NULL,VARCMP_EQ);
7775 VARCMP(EMPTY,0,BSTR,bstrempty,VARCMP_EQ);
7776 VARCMP(EMPTY,1,BSTR,bstrempty,VARCMP_EQ);
7777 VARCMP(BSTR,bstr0,EMPTY,0,VARCMP_GT);
7778 VARCMP(BSTR,bstr42,EMPTY,0,VARCMP_GT);
7779 VARCMPEX(BSTR,bstrempty,UI1,0,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7780 VARCMPEX(BSTR,bstrempty,I2,-1,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7781 VARCMPEX(I4,0,BSTR,bstrempty,VARCMP_LT,VARCMP_LT,VARCMP_GT,VARCMP_LT);
7782 VARCMPEX(BSTR,NULL,UI1,0,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7783 VARCMPEX(I4,7,BSTR,NULL,VARCMP_LT,VARCMP_LT,VARCMP_GT,VARCMP_LT);
7784 _VARCMP(BSTR,(BSTR)100,0,I2,100,0,lcid,0,VARCMP_GT);
7785 VARCMPEX(BSTR,bstr0,UI1,0,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_GT);
7786 VARCMPEX(I2,0,BSTR,bstr0,VARCMP_LT,VARCMP_EQ,VARCMP_EQ,VARCMP_LT);
7787 VARCMP(BSTR,bstrhuh,I4,I4_MAX,VARCMP_GT);
7788 VARCMP(BSTR,bstr2cents,I4,2,VARCMP_GT);
7789 VARCMPEX(BSTR,bstr2cents,I4,42,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7790 VARCMP(BSTR,bstr2cents,I4,-1,VARCMP_GT);
7791 VARCMPEX(BSTR,bstr2cents,I4,-666,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7792 VARCMPEX(BSTR,bstr0,I2,0,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_GT);
7793 VARCMPEX(BSTR,bstr0,I4,0,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_GT);
7794 VARCMPEX(BSTR,bstr0,I4,-666,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7795 VARCMP(BSTR,bstr1,I4,0,VARCMP_GT);
7796 VARCMPEX(BSTR,bstr1,I4,1,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_GT);
7797 VARCMPEX(BSTR,bstr1,I4,I4_MAX,VARCMP_GT,VARCMP_LT,VARCMP_LT,VARCMP_GT);
7798 VARCMPEX(BSTR,bstr1,I4,-1,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7799 VARCMP(BSTR,bstr7,I4,1,VARCMP_GT);
7800 VARCMPEX(BSTR,bstr7,I4,7,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_GT);
7801 VARCMPEX(BSTR,bstr7,I4,42,VARCMP_GT,VARCMP_GT,VARCMP_LT,VARCMP_GT);
7802 VARCMPEX(BSTR,bstr42,I4,7,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7803 VARCMPEX(BSTR,bstr42,I4,42,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_GT);
7804 VARCMPEX(BSTR,bstr42,I4,I4_MAX,VARCMP_GT,VARCMP_GT,VARCMP_LT,VARCMP_GT);
7805 VARCMPEX(BSTR,bstr1neg,I4,1,VARCMP_GT,VARCMP_GT,VARCMP_LT,VARCMP_LT);
7806 VARCMPEX(BSTR,bstr1neg,I4,42,VARCMP_GT,VARCMP_LT,VARCMP_LT,VARCMP_LT);
7807 VARCMPEX(BSTR,bstr1neg,I4,-1,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_LT);
7808 VARCMPEX(BSTR,bstr1neg,I4,-666,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_LT);
7809 VARCMPEX(BSTR,bstr666neg,I4,1,VARCMP_GT,VARCMP_GT,VARCMP_LT,VARCMP_LT);
7810 VARCMPEX(BSTR,bstr666neg,I4,7,VARCMP_GT,VARCMP_LT,VARCMP_LT,VARCMP_LT);
7811 VARCMPEX(BSTR,bstr666neg,I4,42,VARCMP_GT,VARCMP_GT,VARCMP_LT,VARCMP_LT);
7812 VARCMPEX(BSTR,bstr666neg,I4,I4_MAX,VARCMP_GT,VARCMP_GT,VARCMP_LT,VARCMP_LT);
7813 VARCMPEX(BSTR,bstr666neg,I4,-1,VARCMP_GT,VARCMP_GT,VARCMP_LT,VARCMP_LT);
7814 VARCMPEX(BSTR,bstr666neg,I4,-666,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_LT);
7815 VARCMPEX(BSTR,bstr7,R8,7.0,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_GT);
7816 VARCMPEX(R8,3.141592,BSTR,NULL,VARCMP_LT,VARCMP_LT,VARCMP_GT,VARCMP_LT);
7817 VARCMP(BSTR,bstr7,BSTR,bstr7,VARCMP_EQ);
7818 VARCMP(BSTR,bstr7,BSTR,bstr42,VARCMP_GT);
7819 VARCMP(BSTR,bstr42,BSTR,bstr7,VARCMP_LT);
7821 /* DECIMAL handling */
7822 setdec(&dec,0,0,0,0);
7823 VARCMPEX(DECIMAL,dec,BSTR,bstr0,VARCMP_LT,VARCMP_EQ,VARCMP_EQ,VARCMP_LT);
7824 setdec64(&dec,0,0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF); /* max DECIMAL */
7825 VARCMP(DECIMAL,dec,R8,R8_MAX,VARCMP_LT); /* R8 has bigger range */
7826 VARCMP(DECIMAL,dec,DATE,R8_MAX,VARCMP_LT); /* DATE has bigger range */
7827 setdec64(&dec,0,0x80,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF);
7828 VARCMP(DECIMAL,dec,R8,-R8_MAX,VARCMP_GT);
7829 setdec64(&dec,20,0,0x5,0x6BC75E2D,0x63100001); /* 1+1e-20 */
7830 VARCMP(DECIMAL,dec,R8,1,VARCMP_GT); /* DECIMAL has higher precision */
7832 /* Show that DATE is handled just as a R8 */
7833 VARCMP(DATE,DATE_MAX,DATE,DATE_MAX+1,VARCMP_LT);
7834 VARCMP(DATE,DATE_MIN,DATE,DATE_MIN-1,VARCMP_GT);
7835 VARCMP(DATE,R8_MIN,R8,R8_MIN,VARCMP_EQ);
7836 VARCMP(DATE,1,DATE,1+1e-15,VARCMP_LT); /* 1e-15 == 8.64e-11 seconds */
7837 VARCMP(DATE,25570.0,DATE,25570.0,VARCMP_EQ);
7838 VARCMP(DATE,25570.0,DATE,25571.0,VARCMP_LT);
7839 VARCMP(DATE,25571.0,DATE,25570.0,VARCMP_GT);
7840 VARCMP(DATE,25570.0,EMPTY,0,VARCMP_GT);
7841 VARCMP(DATE,25570.0,NULL_,0,VARCMP_NULL);
7843 /* R4 precision handling */
7844 VARCMP(R4,1,R8,1+1e-8,VARCMP_EQ);
7845 VARCMP(R8,1+1e-8,R4,1,VARCMP_EQ);
7846 VARCMP(R8,1+1e-8,R8,1,VARCMP_GT);
7847 VARCMP(R8,R4_MAX*1.1,R4,R4_MAX,VARCMP_GT);
7848 VARCMP(R4,R4_MAX,R8,R8_MAX,VARCMP_LT);
7849 VARCMP(R4,1,DATE,1+1e-8,VARCMP_EQ);
7850 VARCMP(R4,1,BSTR,bstr1few,VARCMP_LT); /* bstr1few == 1+1e-8 */
7851 setdec(&dec,8,0,0,0x5F5E101); /* 1+1e-8 */
7852 VARCMP(R4,1,DECIMAL,dec,VARCMP_LT);
7854 SysFreeString(bstrhuh);
7855 SysFreeString(bstrempty);
7856 SysFreeString(bstr0);
7857 SysFreeString(bstr1);
7858 SysFreeString(bstr7);
7859 SysFreeString(bstr42);
7860 SysFreeString(bstr1neg);
7861 SysFreeString(bstr666neg);
7862 SysFreeString(bstr2cents);
7863 SysFreeString(bstr1few);
7866 static HRESULT (WINAPI *pVarPow)(LPVARIANT,LPVARIANT,LPVARIANT);
7868 #define VARPOW(vt1,val1,vt2,val2,rvt,rval) \
7869 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
7870 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
7871 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
7872 test_var_call2( __LINE__, pVarPow, &left, &right, &exp )
7874 /* Skip any type that is not defined or produces an error for every case */
7875 #define SKIPTESTPOW(a) \
7876 if (a == VT_ERROR || a == VT_VARIANT || \
7877 a == VT_DISPATCH || a == VT_UNKNOWN || \
7878 a == VT_RECORD || a > VT_UINT || \
7879 a == 15 /*not defined*/) \
7880 continue
7882 static void test_VarPow(void)
7884 static const WCHAR str2[] = { '2','\0' };
7885 static const WCHAR str3[] = { '3','\0' };
7886 VARIANT left, right, exp, result, cy, dec;
7887 BSTR num2_str, num3_str;
7888 VARTYPE i;
7889 HRESULT hres;
7891 CHECKPTR(VarPow);
7893 num2_str = SysAllocString(str2);
7894 num3_str = SysAllocString(str3);
7896 /* Test all possible flag/vt combinations & the resulting vt type */
7897 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
7899 VARTYPE leftvt, rightvt, resvt;
7901 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
7903 SKIPTESTPOW(leftvt);
7905 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
7907 BOOL bFail = FALSE;
7908 SKIPTESTPOW(rightvt);
7910 /* Native crashes with VT_BYREF */
7911 if (ExtraFlags[i] == VT_BYREF)
7912 continue;
7914 memset(&left, 0, sizeof(left));
7915 memset(&right, 0, sizeof(right));
7916 V_VT(&left) = leftvt | ExtraFlags[i];
7917 V_VT(&right) = rightvt | ExtraFlags[i];
7918 V_VT(&result) = VT_EMPTY;
7919 resvt = VT_EMPTY;
7921 if (leftvt == VT_BSTR)
7922 V_BSTR(&left) = num2_str;
7923 if (rightvt == VT_BSTR)
7924 V_BSTR(&right) = num2_str;
7926 /* Native VarPow always returns an error when using extra flags */
7927 if (ExtraFlags[i] != 0)
7928 bFail = TRUE;
7930 /* Determine return type */
7931 else if ((leftvt == VT_NULL || rightvt == VT_NULL) &&
7932 ((leftvt != VT_I8 && leftvt != VT_UI8 &&
7933 rightvt != VT_I8 && rightvt != VT_UI8) || has_i8))
7934 resvt = VT_NULL;
7935 else if ((leftvt == VT_EMPTY || leftvt == VT_I2 ||
7936 leftvt == VT_I4 || leftvt == VT_R4 ||
7937 leftvt == VT_R8 || leftvt == VT_CY ||
7938 leftvt == VT_DATE || leftvt == VT_BSTR ||
7939 leftvt == VT_BOOL || leftvt == VT_DECIMAL ||
7940 (leftvt >= VT_I1 && leftvt <= VT_UI4) ||
7941 (has_i8 && (leftvt == VT_I8 || leftvt == VT_UI8)) ||
7942 leftvt == VT_INT || leftvt == VT_UINT) &&
7943 (rightvt == VT_EMPTY || rightvt == VT_I2 ||
7944 rightvt == VT_I4 || rightvt == VT_R4 ||
7945 rightvt == VT_R8 || rightvt == VT_CY ||
7946 rightvt == VT_DATE || rightvt == VT_BSTR ||
7947 rightvt == VT_BOOL || rightvt == VT_DECIMAL ||
7948 (rightvt >= VT_I1 && rightvt <= VT_UI4) ||
7949 (has_i8 && (rightvt == VT_I8 || rightvt == VT_UI8)) ||
7950 rightvt == VT_INT || rightvt == VT_UINT))
7951 resvt = VT_R8;
7952 else
7953 bFail = TRUE;
7955 hres = pVarPow(&left, &right, &result);
7957 /* Check expected HRESULT and if result variant type is correct */
7958 if (bFail)
7959 ok (hres == DISP_E_BADVARTYPE || hres == DISP_E_TYPEMISMATCH,
7960 "VarPow: %s|0x%X, %s|0x%X: got vt %s hr 0x%X\n",
7961 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i],
7962 vtstr(V_VT(&result)), hres);
7963 else
7964 ok (hres == S_OK && resvt == V_VT(&result),
7965 "VarPow: %s|0x%X, %s|0x%X: expected vt %s hr 0x%X, got vt %s hr 0x%X\n",
7966 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i], vtstr(resvt),
7967 S_OK, vtstr(V_VT(&result)), hres);
7972 /* Check return values for valid variant type combinations */
7973 VARPOW(EMPTY,0,EMPTY,0,R8,1.0);
7974 VARPOW(EMPTY,0,NULL,0,NULL,0);
7975 VARPOW(EMPTY,0,I2,3,R8,0.0);
7976 VARPOW(EMPTY,0,I4,3,R8,0.0);
7977 VARPOW(EMPTY,0,R4,3.0f,R8,0.0);
7978 VARPOW(EMPTY,0,R8,3.0,R8,0.0);
7979 VARPOW(EMPTY,0,DATE,3,R8,0.0);
7980 VARPOW(EMPTY,0,BSTR,num3_str,R8,0.0);
7981 VARPOW(EMPTY,0,BOOL,VARIANT_FALSE,R8,1.0);
7982 VARPOW(EMPTY,0,I1,3,R8,0.0);
7983 VARPOW(EMPTY,0,UI1,3,R8,0.0);
7984 VARPOW(EMPTY,0,UI2,3,R8,0.0);
7985 VARPOW(EMPTY,0,UI4,3,R8,0.0);
7986 if (has_i8)
7988 VARPOW(EMPTY,0,I8,3,R8,0.0);
7989 VARPOW(EMPTY,0,UI8,3,R8,0.0);
7991 VARPOW(EMPTY,0,INT,3,R8,0.0);
7992 VARPOW(EMPTY,0,UINT,3,R8,0.0);
7993 VARPOW(NULL,0,EMPTY,0,NULL,0);
7994 VARPOW(NULL,0,NULL,0,NULL,0);
7995 VARPOW(NULL,0,I2,3,NULL,0);
7996 VARPOW(NULL,0,I4,3,NULL,0);
7997 VARPOW(NULL,0,R4,3.0f,NULL,0);
7998 VARPOW(NULL,0,R8,3.0,NULL,0);
7999 VARPOW(NULL,0,DATE,3,NULL,0);
8000 VARPOW(NULL,0,BSTR,num3_str,NULL,0);
8001 VARPOW(NULL,0,BOOL,VARIANT_TRUE,NULL,0);
8002 VARPOW(NULL,0,I1,3,NULL,0);
8003 VARPOW(NULL,0,UI1,3,NULL,0);
8004 VARPOW(NULL,0,UI2,3,NULL,0);
8005 VARPOW(NULL,0,UI4,3,NULL,0);
8006 if (has_i8)
8008 VARPOW(NULL,0,I8,3,NULL,0);
8009 VARPOW(NULL,0,UI8,3,NULL,0);
8011 VARPOW(NULL,0,INT,3,NULL,0);
8012 VARPOW(NULL,0,UINT,3,NULL,0);
8013 VARPOW(I2,2,EMPTY,0,R8,1.0);
8014 VARPOW(I2,2,NULL,0,NULL,0);
8015 VARPOW(I2,2,I2,3,R8,8.0);
8016 VARPOW(I2,2,I4,3,R8,8.0);
8017 VARPOW(I2,2,R4,3.0f,R8,8.0);
8018 VARPOW(I2,2,R8,3.0,R8,8.0);
8019 VARPOW(I2,2,DATE,3,R8,8.0);
8020 VARPOW(I2,2,BSTR,num3_str,R8,8.0);
8021 VARPOW(I2,2,BOOL,VARIANT_FALSE,R8,1.0);
8022 VARPOW(I2,2,I1,3,R8,8.0);
8023 VARPOW(I2,2,UI1,3,R8,8.0);
8024 VARPOW(I2,2,UI2,3,R8,8.0);
8025 VARPOW(I2,2,UI4,3,R8,8.0);
8026 if (has_i8)
8028 VARPOW(I2,2,I8,3,R8,8.0);
8029 VARPOW(I2,2,UI8,3,R8,8.0);
8031 VARPOW(I2,2,INT,3,R8,8.0);
8032 VARPOW(I2,2,UINT,3,R8,8.0);
8033 VARPOW(I4,2,EMPTY,0,R8,1.0);
8034 VARPOW(I4,2,NULL,0,NULL,0);
8035 VARPOW(I4,2,I2,3,R8,8.0);
8036 VARPOW(I4,2,I4,3,R8,8.0);
8037 VARPOW(I4,2,R4,3.0f,R8,8.0);
8038 VARPOW(I4,2,R8,3.0,R8,8.0);
8039 VARPOW(I4,2,DATE,3,R8,8.0);
8040 VARPOW(I4,2,BSTR,num3_str,R8,8.0);
8041 VARPOW(I4,2,BOOL,VARIANT_FALSE,R8,1.0);
8042 VARPOW(I4,2,I1,3,R8,8.0);
8043 VARPOW(I4,2,UI1,3,R8,8.0);
8044 VARPOW(I4,2,UI2,3,R8,8.0);
8045 VARPOW(I4,2,UI4,3,R8,8.0);
8046 if (has_i8)
8048 VARPOW(I4,2,I8,3,R8,8.0);
8049 VARPOW(I4,2,UI8,3,R8,8.0);
8051 VARPOW(I4,2,INT,3,R8,8.0);
8052 VARPOW(I4,2,UINT,3,R8,8.0);
8053 VARPOW(R4,2,EMPTY,0,R8,1.0);
8054 VARPOW(R4,2,NULL,0,NULL,0);
8055 VARPOW(R4,2,I2,3,R8,8.0);
8056 VARPOW(R4,2,I4,3,R8,8.0);
8057 VARPOW(R4,2,R4,3.0f,R8,8.0);
8058 VARPOW(R4,2,R8,3.0,R8,8.0);
8059 VARPOW(R4,2,DATE,3,R8,8.0);
8060 VARPOW(R4,2,BSTR,num3_str,R8,8.0);
8061 VARPOW(R4,2,BOOL,VARIANT_FALSE,R8,1.0);
8062 VARPOW(R4,2,I1,3,R8,8.0);
8063 VARPOW(R4,2,UI1,3,R8,8.0);
8064 VARPOW(R4,2,UI2,3,R8,8.0);
8065 VARPOW(R4,2,UI4,3,R8,8.0);
8066 if (has_i8)
8068 VARPOW(R4,2,I8,3,R8,8.0);
8069 VARPOW(R4,2,UI8,3,R8,8.0);
8071 VARPOW(R4,2,INT,3,R8,8.0);
8072 VARPOW(R4,2,UINT,3,R8,8.0);
8073 VARPOW(R8,2,EMPTY,0,R8,1.0);
8074 VARPOW(R8,2,NULL,0,NULL,0);
8075 VARPOW(R8,2,I2,3,R8,8.0);
8076 VARPOW(R8,2,I4,3,R8,8.0);
8077 VARPOW(R8,2,R4,3.0f,R8,8.0);
8078 VARPOW(R8,2,R8,3.0,R8,8.0);
8079 VARPOW(R8,2,DATE,3,R8,8.0);
8080 VARPOW(R8,2,BSTR,num3_str,R8,8.0);
8081 VARPOW(R8,2,BOOL,VARIANT_FALSE,R8,1.0);
8082 VARPOW(R8,2,I1,3,R8,8.0);
8083 VARPOW(R8,2,UI1,3,R8,8.0);
8084 VARPOW(R8,2,UI2,3,R8,8.0);
8085 VARPOW(R8,2,UI4,3,R8,8.0);
8086 if (has_i8)
8088 VARPOW(R8,2,I8,3,R8,8.0);
8089 VARPOW(R8,2,UI8,3,R8,8.0);
8091 VARPOW(R8,2,INT,3,R8,8.0);
8092 VARPOW(R8,2,UINT,3,R8,8.0);
8093 VARPOW(DATE,2,EMPTY,0,R8,1.0);
8094 VARPOW(DATE,2,NULL,0,NULL,0);
8095 VARPOW(DATE,2,I2,3,R8,8.0);
8096 VARPOW(DATE,2,I4,3,R8,8.0);
8097 VARPOW(DATE,2,R4,3.0f,R8,8.0);
8098 VARPOW(DATE,2,R8,3.0,R8,8.0);
8099 VARPOW(DATE,2,DATE,3,R8,8.0);
8100 VARPOW(DATE,2,BSTR,num3_str,R8,8.0);
8101 VARPOW(DATE,2,BOOL,VARIANT_FALSE,R8,1.0);
8102 VARPOW(DATE,2,I1,3,R8,8.0);
8103 VARPOW(DATE,2,UI1,3,R8,8.0);
8104 VARPOW(DATE,2,UI2,3,R8,8.0);
8105 VARPOW(DATE,2,UI4,3,R8,8.0);
8106 if (has_i8)
8108 VARPOW(DATE,2,I8,3,R8,8.0);
8109 VARPOW(DATE,2,UI8,3,R8,8.0);
8111 VARPOW(DATE,2,INT,3,R8,8.0);
8112 VARPOW(DATE,2,UINT,3,R8,8.0);
8113 VARPOW(BSTR,num2_str,EMPTY,0,R8,1.0);
8114 VARPOW(BSTR,num2_str,NULL,0,NULL,0);
8115 VARPOW(BSTR,num2_str,I2,3,R8,8.0);
8116 VARPOW(BSTR,num2_str,I4,3,R8,8.0);
8117 VARPOW(BSTR,num2_str,R4,3.0f,R8,8.0);
8118 VARPOW(BSTR,num2_str,R8,3.0,R8,8.0);
8119 VARPOW(BSTR,num2_str,DATE,3,R8,8.0);
8120 VARPOW(BSTR,num2_str,BSTR,num3_str,R8,8.0);
8121 VARPOW(BSTR,num2_str,BOOL,VARIANT_FALSE,R8,1.0);
8122 VARPOW(BSTR,num2_str,I1,3,R8,8.0);
8123 VARPOW(BSTR,num2_str,UI1,3,R8,8.0);
8124 VARPOW(BSTR,num2_str,UI2,3,R8,8.0);
8125 VARPOW(BSTR,num2_str,UI4,3,R8,8.0);
8126 if (has_i8)
8128 VARPOW(BSTR,num2_str,I8,3,R8,8.0);
8129 VARPOW(BSTR,num2_str,UI8,3,R8,8.0);
8131 VARPOW(BSTR,num2_str,INT,3,R8,8.0);
8132 VARPOW(BSTR,num2_str,UINT,3,R8,8.0);
8133 VARPOW(BOOL,VARIANT_TRUE,EMPTY,0,R8,1.0);
8134 VARPOW(BOOL,VARIANT_TRUE,NULL,0,NULL,0);
8135 VARPOW(BOOL,VARIANT_TRUE,I2,3,R8,-1.0);
8136 VARPOW(BOOL,VARIANT_TRUE,I4,3,R8,-1.0);
8137 VARPOW(BOOL,VARIANT_TRUE,R4,3.0f,R8,-1.0);
8138 VARPOW(BOOL,VARIANT_TRUE,R8,3.0,R8,-1.0);
8139 VARPOW(BOOL,VARIANT_TRUE,DATE,3,R8,-1.0);
8140 VARPOW(BOOL,VARIANT_TRUE,BSTR,num3_str,R8,-1.0);
8141 VARPOW(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,R8,-1.0);
8142 VARPOW(BOOL,VARIANT_TRUE,I1,3,R8,-1.0);
8143 VARPOW(BOOL,VARIANT_TRUE,UI1,3,R8,-1.0);
8144 VARPOW(BOOL,VARIANT_TRUE,UI2,3,R8,-1.0);
8145 VARPOW(BOOL,VARIANT_TRUE,UI4,3,R8,-1.0);
8146 if (has_i8)
8148 VARPOW(BOOL,VARIANT_TRUE,I8,3,R8,-1.0);
8149 VARPOW(BOOL,VARIANT_TRUE,UI8,3,R8,-1.0);
8151 VARPOW(BOOL,VARIANT_TRUE,INT,3,R8,-1.0);
8152 VARPOW(BOOL,VARIANT_TRUE,UINT,3,R8,-1.0);
8153 VARPOW(I1,2,EMPTY,0,R8,1.0);
8154 VARPOW(I1,2,NULL,0,NULL,0);
8155 VARPOW(I1,2,I2,3,R8,8.0);
8156 VARPOW(I1,2,I4,3,R8,8.0);
8157 VARPOW(I1,2,R4,3.0f,R8,8.0);
8158 VARPOW(I1,2,R8,3.0,R8,8.0);
8159 VARPOW(I1,2,DATE,3,R8,8.0);
8160 VARPOW(I1,2,BSTR,num3_str,R8,8.0);
8161 VARPOW(I1,2,BOOL,VARIANT_FALSE,R8,1.0);
8162 VARPOW(I1,2,I1,3,R8,8.0);
8163 VARPOW(I1,2,UI1,3,R8,8.0);
8164 VARPOW(I1,2,UI2,3,R8,8.0);
8165 VARPOW(I1,2,UI4,3,R8,8.0);
8166 if (has_i8)
8168 VARPOW(I1,2,I8,3,R8,8.0);
8169 VARPOW(I1,2,UI8,3,R8,8.0);
8171 VARPOW(I1,2,INT,3,R8,8.0);
8172 VARPOW(I1,2,UINT,3,R8,8.0);
8173 VARPOW(UI1,2,EMPTY,0,R8,1.0);
8174 VARPOW(UI1,2,NULL,0,NULL,0);
8175 VARPOW(UI1,2,I2,3,R8,8.0);
8176 VARPOW(UI1,2,I4,3,R8,8.0);
8177 VARPOW(UI1,2,R4,3.0f,R8,8.0);
8178 VARPOW(UI1,2,R8,3.0,R8,8.0);
8179 VARPOW(UI1,2,DATE,3,R8,8.0);
8180 VARPOW(UI1,2,BSTR,num3_str,R8,8.0);
8181 VARPOW(UI1,2,BOOL,VARIANT_FALSE,R8,1.0);
8182 VARPOW(UI1,2,I1,3,R8,8.0);
8183 VARPOW(UI1,2,UI1,3,R8,8.0);
8184 VARPOW(UI1,2,UI2,3,R8,8.0);
8185 VARPOW(UI1,2,UI4,3,R8,8.0);
8186 if (has_i8)
8188 VARPOW(UI1,2,I8,3,R8,8.0);
8189 VARPOW(UI1,2,UI8,3,R8,8.0);
8191 VARPOW(UI1,2,INT,3,R8,8.0);
8192 VARPOW(UI1,2,UINT,3,R8,8.0);
8193 VARPOW(UI2,2,EMPTY,0,R8,1.0);
8194 VARPOW(UI2,2,NULL,0,NULL,0);
8195 VARPOW(UI2,2,I2,3,R8,8.0);
8196 VARPOW(UI2,2,I4,3,R8,8.0);
8197 VARPOW(UI2,2,R4,3.0f,R8,8.0);
8198 VARPOW(UI2,2,R8,3.0,R8,8.0);
8199 VARPOW(UI2,2,DATE,3,R8,8.0);
8200 VARPOW(UI2,2,BSTR,num3_str,R8,8.0);
8201 VARPOW(UI2,2,BOOL,VARIANT_FALSE,R8,1.0);
8202 VARPOW(UI2,2,I1,3,R8,8.0);
8203 VARPOW(UI2,2,UI1,3,R8,8.0);
8204 VARPOW(UI2,2,UI2,3,R8,8.0);
8205 VARPOW(UI2,2,UI4,3,R8,8.0);
8206 if (has_i8)
8208 VARPOW(UI2,2,I8,3,R8,8.0);
8209 VARPOW(UI2,2,UI8,3,R8,8.0);
8211 VARPOW(UI2,2,INT,3,R8,8.0);
8212 VARPOW(UI2,2,UINT,3,R8,8.0);
8213 VARPOW(UI4,2,EMPTY,0,R8,1.0);
8214 VARPOW(UI4,2,NULL,0,NULL,0);
8215 VARPOW(UI4,2,I2,3,R8,8.0);
8216 VARPOW(UI4,2,I4,3,R8,8.0);
8217 VARPOW(UI4,2,R4,3.0f,R8,8.0);
8218 VARPOW(UI4,2,R8,3.0,R8,8.0);
8219 VARPOW(UI4,2,DATE,3,R8,8.0);
8220 VARPOW(UI4,2,BSTR,num3_str,R8,8.0);
8221 VARPOW(UI4,2,BOOL,VARIANT_FALSE,R8,1.0);
8222 VARPOW(UI4,2,I1,3,R8,8.0);
8223 VARPOW(UI4,2,UI1,3,R8,8.0);
8224 VARPOW(UI4,2,UI2,3,R8,8.0);
8225 VARPOW(UI4,2,UI4,3,R8,8.0);
8226 if (has_i8)
8228 VARPOW(UI4,2,I8,3,R8,8.0);
8229 VARPOW(UI4,2,UI8,3,R8,8.0);
8231 VARPOW(UI4,2,INT,3,R8,8.0);
8232 VARPOW(UI4,2,UINT,3,R8,8.0);
8233 if (has_i8)
8235 VARPOW(I8,2,EMPTY,0,R8,1.0);
8236 VARPOW(I8,2,NULL,0,NULL,0);
8237 VARPOW(I8,2,I2,3,R8,8.0);
8238 VARPOW(I8,2,I4,3,R8,8.0);
8239 VARPOW(I8,2,R4,3.0f,R8,8.0);
8240 VARPOW(I8,2,R8,3.0,R8,8.0);
8241 VARPOW(I8,2,DATE,3,R8,8.0);
8242 VARPOW(I8,2,BSTR,num3_str,R8,8.0);
8243 VARPOW(I8,2,BOOL,VARIANT_FALSE,R8,1.0);
8244 VARPOW(I8,2,I1,3,R8,8.0);
8245 VARPOW(I8,2,UI1,3,R8,8.0);
8246 VARPOW(I8,2,UI2,3,R8,8.0);
8247 VARPOW(I8,2,UI4,3,R8,8.0);
8248 VARPOW(I8,2,I8,3,R8,8.0);
8249 VARPOW(I8,2,UI8,3,R8,8.0);
8250 VARPOW(I8,2,INT,3,R8,8.0);
8251 VARPOW(I8,2,UINT,3,R8,8.0);
8252 VARPOW(UI8,2,EMPTY,0,R8,1.0);
8253 VARPOW(UI8,2,NULL,0,NULL,0);
8254 VARPOW(UI8,2,I2,3,R8,8.0);
8255 VARPOW(UI8,2,I4,3,R8,8.0);
8256 VARPOW(UI8,2,R4,3.0f,R8,8.0);
8257 VARPOW(UI8,2,R8,3.0,R8,8.0);
8258 VARPOW(UI8,2,DATE,3,R8,8.0);
8259 VARPOW(UI8,2,BSTR,num3_str,R8,8.0);
8260 VARPOW(UI8,2,I1,3,R8,8.0);
8261 VARPOW(UI8,2,UI1,3,R8,8.0);
8262 VARPOW(UI8,2,UI2,3,R8,8.0);
8263 VARPOW(UI8,2,UI4,3,R8,8.0);
8264 VARPOW(UI8,2,I8,3,R8,8.0);
8265 VARPOW(UI8,2,UI8,3,R8,8.0);
8266 VARPOW(UI8,2,INT,3,R8,8.0);
8267 VARPOW(UI8,2,UINT,3,R8,8.0);
8269 VARPOW(INT,2,EMPTY,0,R8,1.0);
8270 VARPOW(INT,2,NULL,0,NULL,0);
8271 VARPOW(INT,2,I2,3,R8,8.0);
8272 VARPOW(INT,2,I4,3,R8,8.0);
8273 VARPOW(INT,2,R4,3.0f,R8,8.0);
8274 VARPOW(INT,2,R8,3.0,R8,8.0);
8275 VARPOW(INT,2,DATE,3,R8,8.0);
8276 VARPOW(INT,2,BSTR,num3_str,R8,8.0);
8277 VARPOW(INT,2,BOOL,VARIANT_FALSE,R8,1.0);
8278 VARPOW(INT,2,I1,3,R8,8.0);
8279 VARPOW(INT,2,UI1,3,R8,8.0);
8280 VARPOW(INT,2,UI2,3,R8,8.0);
8281 VARPOW(INT,2,UI4,3,R8,8.0);
8282 if (has_i8)
8284 VARPOW(INT,2,I8,3,R8,8.0);
8285 VARPOW(INT,2,UI8,3,R8,8.0);
8287 VARPOW(INT,2,INT,3,R8,8.0);
8288 VARPOW(INT,2,UINT,3,R8,8.0);
8289 VARPOW(UINT,2,EMPTY,0,R8,1.0);
8290 VARPOW(UINT,2,NULL,0,NULL,0);
8291 VARPOW(UINT,2,I2,3,R8,8.0);
8292 VARPOW(UINT,2,I4,3,R8,8.0);
8293 VARPOW(UINT,2,R4,3.0f,R8,8.0);
8294 VARPOW(UINT,2,R8,3.0,R8,8.0);
8295 VARPOW(UINT,2,DATE,3,R8,8.0);
8296 VARPOW(UINT,2,BSTR,num3_str,R8,8.0);
8297 VARPOW(UINT,2,BOOL,VARIANT_FALSE,R8,1.0);
8298 VARPOW(UINT,2,I1,3,R8,8.0);
8299 VARPOW(UINT,2,UI1,3,R8,8.0);
8300 VARPOW(UINT,2,UI2,3,R8,8.0);
8301 VARPOW(UINT,2,UI4,3,R8,8.0);
8302 if (has_i8)
8304 VARPOW(UINT,2,I8,3,R8,8.0);
8305 VARPOW(UINT,2,UI8,3,R8,8.0);
8307 VARPOW(UINT,2,INT,3,R8,8.0);
8308 VARPOW(UINT,2,UINT,3,R8,8.0);
8310 /* Manually test some VT_CY, VT_DECIMAL variants */
8311 V_VT(&cy) = VT_CY;
8312 hres = VarCyFromI4(2, &V_CY(&cy));
8313 ok(hres == S_OK, "VarCyFromI4 failed!\n");
8314 V_VT(&dec) = VT_DECIMAL;
8315 hres = VarDecFromR8(2.0, &V_DECIMAL(&dec));
8316 ok(hres == S_OK, "VarDecFromR4 failed!\n");
8317 memset(&left, 0, sizeof(left));
8318 memset(&right, 0, sizeof(right));
8319 V_VT(&left) = VT_I4;
8320 V_I4(&left) = 100;
8321 V_VT(&right) = VT_I8;
8322 V_UI1(&right) = 2;
8324 hres = pVarPow(&cy, &cy, &result);
8325 ok(hres == S_OK && V_VT(&result) == VT_R8,
8326 "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
8327 S_OK, hres, vtstr(V_VT(&result)));
8328 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 4.0),
8329 "VARPOW: CY value %f, expected %f\n", V_R8(&result), 4.0);
8331 hres = pVarPow(&cy, &right, &result);
8332 if (hres == S_OK)
8334 ok(V_VT(&result) == VT_R8,
8335 "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
8336 S_OK, hres, vtstr(V_VT(&result)));
8337 ok(EQ_DOUBLE(V_R8(&result), 4.0),
8338 "VARPOW: CY value %f, expected %f\n", V_R8(&result), 4.0);
8340 else
8342 ok(hres == DISP_E_BADVARTYPE && V_VT(&result) == VT_EMPTY,
8343 "VARPOW: expected coerced hres 0x%X type VT_EMPTY, got hres 0x%X type %s!\n",
8344 DISP_E_BADVARTYPE, hres, vtstr(V_VT(&result)));
8347 hres = pVarPow(&left, &cy, &result);
8348 ok(hres == S_OK && V_VT(&result) == VT_R8,
8349 "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
8350 S_OK, hres, vtstr(V_VT(&result)));
8351 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 10000.0),
8352 "VARPOW: CY value %f, expected %f\n", V_R8(&result), 10000.0);
8354 hres = pVarPow(&left, &dec, &result);
8355 ok(hres == S_OK && V_VT(&result) == VT_R8,
8356 "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
8357 S_OK, hres, vtstr(V_VT(&result)));
8358 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result),10000.0),
8359 "VARPOW: DECIMAL value %f, expected %f\n", V_R8(&result), 10000.0);
8361 hres = pVarPow(&dec, &dec, &result);
8362 ok(hres == S_OK && V_VT(&result) == VT_R8,
8363 "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
8364 S_OK, hres, vtstr(V_VT(&result)));
8365 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 4.0),
8366 "VARPOW: DECIMAL value %f, expected %f\n", V_R8(&result), 4.0);
8368 hres = pVarPow(&dec, &right, &result);
8369 if (hres == S_OK)
8371 ok(V_VT(&result) == VT_R8,
8372 "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
8373 S_OK, hres, vtstr(V_VT(&result)));
8374 ok(EQ_DOUBLE(V_R8(&result), 4.0),
8375 "VARPOW: DECIMAL value %f, expected %f\n", V_R8(&result), 4.0);
8377 else
8379 ok(hres == DISP_E_BADVARTYPE && V_VT(&result) == VT_EMPTY,
8380 "VARPOW: expected coerced hres 0x%X type VT_EMPTY, got hres 0x%X type %s!\n",
8381 DISP_E_BADVARTYPE, hres, vtstr(V_VT(&result)));
8384 SysFreeString(num2_str);
8385 SysFreeString(num3_str);
8388 static HRESULT (WINAPI *pVarDiv)(LPVARIANT,LPVARIANT,LPVARIANT);
8390 #define VARDIV(vt1,val1,vt2,val2,rvt,rval) \
8391 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
8392 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
8393 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
8394 test_var_call2( __LINE__, pVarDiv, &left, &right, &exp )
8396 /* Skip any type that is not defined or produces an error for every case */
8397 #define SKIPTESTDIV(a) \
8398 if (a == VT_ERROR || a == VT_VARIANT || \
8399 a == VT_DISPATCH || a == VT_UNKNOWN || \
8400 a == VT_RECORD || a > VT_UINT || \
8401 a == VT_I1 || a == VT_UI8 || \
8402 a == VT_INT || a == VT_UINT || \
8403 a == VT_UI2 || a == VT_UI4 || \
8404 a == 15 /*not defined*/) \
8405 continue
8407 static void test_VarDiv(void)
8409 static const WCHAR str1[] = { '1','\0' };
8410 static const WCHAR str2[] = { '2','\0' };
8411 VARIANT left, right, exp, result, cy, dec;
8412 BSTR num1_str, num2_str;
8413 VARTYPE i;
8414 HRESULT hres;
8415 double r;
8417 CHECKPTR(VarDiv);
8419 num1_str = SysAllocString(str1);
8420 num2_str = SysAllocString(str2);
8422 /* Test all possible flag/vt combinations & the resulting vt type */
8423 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
8425 VARTYPE leftvt, rightvt, resvt;
8427 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
8429 SKIPTESTDIV(leftvt);
8431 /* Check if we need/have support for I8 */
8432 if (leftvt == VT_I8 && !has_i8)
8433 continue;
8435 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
8437 BOOL bFail = FALSE;
8438 SKIPTESTDIV(rightvt);
8440 /* Check if we need/have support for I8 */
8441 if (rightvt == VT_I8 && !has_i8)
8442 continue;
8444 /* Native crashes with VT_BYREF */
8445 if (ExtraFlags[i] == VT_BYREF)
8446 continue;
8448 memset(&left, 0, sizeof(left));
8449 memset(&right, 0, sizeof(right));
8450 V_VT(&left) = leftvt | ExtraFlags[i];
8451 V_VT(&right) = rightvt | ExtraFlags[i];
8452 V_VT(&result) = VT_EMPTY;
8453 resvt = VT_EMPTY;
8455 if (leftvt == VT_BSTR)
8456 V_BSTR(&left) = num2_str;
8457 else if (leftvt == VT_DECIMAL)
8459 VarDecFromR8(2.0, &V_DECIMAL(&left));
8460 V_VT(&left) = leftvt | ExtraFlags[i];
8463 /* Division by 0 is undefined */
8464 switch(rightvt)
8466 case VT_BSTR:
8467 V_BSTR(&right) = num2_str;
8468 break;
8469 case VT_DECIMAL:
8470 VarDecFromR8(2.0, &V_DECIMAL(&right));
8471 V_VT(&right) = rightvt | ExtraFlags[i];
8472 break;
8473 case VT_BOOL:
8474 V_BOOL(&right) = VARIANT_TRUE;
8475 break;
8476 case VT_I2: V_I2(&right) = 2; break;
8477 case VT_I4: V_I4(&right) = 2; break;
8478 case VT_R4: V_R4(&right) = 2.0f; break;
8479 case VT_R8: V_R8(&right) = 2.0; break;
8480 case VT_CY: V_CY(&right).int64 = 2; break;
8481 case VT_DATE: V_DATE(&right) = 2; break;
8482 case VT_UI1: V_UI1(&right) = 2; break;
8483 case VT_I8: V_I8(&right) = 2; break;
8484 default: break;
8487 /* Determine return type */
8488 if (rightvt != VT_EMPTY)
8490 if (leftvt == VT_NULL || rightvt == VT_NULL)
8491 resvt = VT_NULL;
8492 else if (leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
8493 resvt = VT_DECIMAL;
8494 else if (leftvt == VT_I8 || rightvt == VT_I8 ||
8495 leftvt == VT_CY || rightvt == VT_CY ||
8496 leftvt == VT_DATE || rightvt == VT_DATE ||
8497 leftvt == VT_I4 || rightvt == VT_I4 ||
8498 leftvt == VT_BSTR || rightvt == VT_BSTR ||
8499 leftvt == VT_I2 || rightvt == VT_I2 ||
8500 leftvt == VT_BOOL || rightvt == VT_BOOL ||
8501 leftvt == VT_R8 || rightvt == VT_R8 ||
8502 leftvt == VT_UI1 || rightvt == VT_UI1)
8504 if ((leftvt == VT_UI1 && rightvt == VT_R4) ||
8505 (leftvt == VT_R4 && rightvt == VT_UI1))
8506 resvt = VT_R4;
8507 else if ((leftvt == VT_R4 && (rightvt == VT_BOOL ||
8508 rightvt == VT_I2)) || (rightvt == VT_R4 &&
8509 (leftvt == VT_BOOL || leftvt == VT_I2)))
8510 resvt = VT_R4;
8511 else
8512 resvt = VT_R8;
8514 else if (leftvt == VT_R4 || rightvt == VT_R4)
8515 resvt = VT_R4;
8517 else if (leftvt == VT_NULL)
8518 resvt = VT_NULL;
8519 else
8520 bFail = TRUE;
8522 /* Native VarDiv always returns an error when using extra flags */
8523 if (ExtraFlags[i] != 0)
8524 bFail = TRUE;
8526 hres = pVarDiv(&left, &right, &result);
8528 /* Check expected HRESULT and if result variant type is correct */
8529 if (bFail)
8530 ok (hres == DISP_E_BADVARTYPE || hres == DISP_E_TYPEMISMATCH ||
8531 hres == DISP_E_OVERFLOW || hres == DISP_E_DIVBYZERO,
8532 "VarDiv: %s|0x%X, %s|0x%X: got vt %s hr 0x%X\n",
8533 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i],
8534 vtstr(V_VT(&result)), hres);
8535 else
8536 ok (hres == S_OK && resvt == V_VT(&result),
8537 "VarDiv: %s|0x%X, %s|0x%X: expected vt %s hr 0x%X, got vt %s hr 0x%X\n",
8538 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i], vtstr(resvt),
8539 S_OK, vtstr(V_VT(&result)), hres);
8544 /* Test return values for all the good cases */
8545 VARDIV(EMPTY,0,NULL,0,NULL,0);
8546 VARDIV(EMPTY,0,I2,2,R8,0.0);
8547 VARDIV(EMPTY,0,I4,2,R8,0.0);
8548 VARDIV(EMPTY,0,R4,2.0f,R4,0.0f);
8549 VARDIV(EMPTY,0,R8,2.0,R8,0.0);
8550 VARDIV(EMPTY,0,DATE,2.0,R8,0.0);
8551 VARDIV(EMPTY,0,BSTR,num2_str,R8,0.0);
8552 VARDIV(EMPTY,0,BOOL,VARIANT_TRUE,R8,0.0);
8553 VARDIV(EMPTY,0,UI1,2,R8,0.0);
8554 if (has_i8)
8556 VARDIV(EMPTY,0,I8,2,R8,0.0);
8558 VARDIV(NULL,0,EMPTY,0,NULL,0);
8559 VARDIV(NULL,0,NULL,0,NULL,0);
8560 VARDIV(NULL,0,I2,2,NULL,0);
8561 VARDIV(NULL,0,I4,2,NULL,0);
8562 VARDIV(NULL,0,R4,2.0f,NULL,0);
8563 VARDIV(NULL,0,R8,2.0,NULL,0);
8564 VARDIV(NULL,0,DATE,2,NULL,0);
8565 VARDIV(NULL,0,BSTR,num2_str,NULL,0);
8566 VARDIV(NULL,0,BOOL,VARIANT_TRUE,NULL,0);
8567 VARDIV(NULL,0,UI1,2,NULL,0);
8568 if (has_i8)
8570 VARDIV(NULL,0,I8,2,NULL,0);
8572 VARDIV(I2,2,NULL,0,NULL,0);
8573 VARDIV(I2,1,I2,2,R8,0.5);
8574 VARDIV(I2,1,I4,2,R8,0.5);
8575 VARDIV(I2,1,R4,2,R4,0.5f);
8576 VARDIV(I2,1,R8,2.0,R8,0.5);
8577 VARDIV(I2,1,DATE,2,R8,0.5);
8578 VARDIV(I2,1,BOOL,VARIANT_TRUE,R8,-1.0);
8579 VARDIV(I2,1,UI1,2,R8,0.5);
8580 if (has_i8)
8582 VARDIV(I2,1,I8,2,R8,0.5);
8584 VARDIV(I4,1,NULL,0,NULL,0);
8585 VARDIV(I4,1,I2,2,R8,0.5);
8586 VARDIV(I4,1,I4,2,R8,0.5);
8587 VARDIV(I4,1,R4,2.0f,R8,0.5);
8588 VARDIV(I4,1,R8,2.0,R8,0.5);
8589 VARDIV(I4,1,DATE,2,R8,0.5);
8590 VARDIV(I4,1,BSTR,num2_str,R8,0.5);
8591 VARDIV(I4,1,BOOL,VARIANT_TRUE,R8,-1.0);
8592 VARDIV(I4,1,UI1,2,R8,0.5);
8593 if (has_i8)
8595 VARDIV(I4,1,I8,2,R8,0.5);
8597 VARDIV(R4,1.0f,NULL,0,NULL,0);
8598 VARDIV(R4,1.0f,I2,2,R4,0.5f);
8599 VARDIV(R4,1.0f,I4,2,R8,0.5);
8600 VARDIV(R4,1.0f,R4,2.0f,R4,0.5f);
8601 VARDIV(R4,1.0f,R8,2.0,R8,0.5);
8602 VARDIV(R4,1.0f,DATE,2,R8,0.5);
8603 VARDIV(R4,1.0f,BSTR,num2_str,R8,0.5);
8604 VARDIV(R4,1.0f,BOOL,VARIANT_TRUE,R4,-1);
8605 VARDIV(R4,1.0f,UI1,2,R4,0.5f);
8606 if (has_i8)
8608 VARDIV(R4,1.0f,I8,2,R8,0.5);
8610 VARDIV(R8,1.0,NULL,0,NULL,0);
8611 VARDIV(R8,1.0,I2,2,R8,0.5);
8612 VARDIV(R8,1.0,I4,2,R8,0.5);
8613 VARDIV(R8,1.0,R4,2.0f,R8,0.5);
8614 VARDIV(R8,1.0,R8,2.0,R8,0.5);
8615 VARDIV(R8,1.0,DATE,2,R8,0.5);
8616 VARDIV(R8,1.0,BSTR,num2_str,R8,0.5);
8617 VARDIV(R8,1.0,BOOL,VARIANT_TRUE,R8,-1.0);
8618 VARDIV(R8,1.0,UI1,2,R8,0.5);
8619 if (has_i8)
8621 VARDIV(R8,1.0,I8,2,R8,0.5);
8623 VARDIV(DATE,1,NULL,0,NULL,0);
8624 VARDIV(DATE,1,I2,2,R8,0.5);
8625 VARDIV(DATE,1,I4,2,R8,0.5);
8626 VARDIV(DATE,1,R4,2.0f,R8,0.5);
8627 VARDIV(DATE,1,R8,2.0,R8,0.5);
8628 VARDIV(DATE,1,DATE,2,R8,0.5);
8629 VARDIV(DATE,1,BSTR,num2_str,R8,0.5);
8630 VARDIV(DATE,1,BOOL,VARIANT_TRUE,R8,-1.0);
8631 VARDIV(DATE,1,UI1,2,R8,0.5);
8632 if (has_i8)
8634 VARDIV(DATE,1,I8,2,R8,0.5);
8636 VARDIV(BSTR,num1_str,NULL,0,NULL,0);
8637 VARDIV(BSTR,num1_str,I2,2,R8,0.5);
8638 VARDIV(BSTR,num1_str,I4,2,R8,0.5);
8639 VARDIV(BSTR,num1_str,R4,2.0f,R8,0.5);
8640 VARDIV(BSTR,num1_str,R8,2.0,R8,0.5);
8641 VARDIV(BSTR,num1_str,DATE,2,R8,0.5);
8642 VARDIV(BSTR,num1_str,BSTR,num2_str,R8,0.5);
8643 VARDIV(BSTR,num1_str,BOOL,VARIANT_TRUE,R8,-1);
8644 VARDIV(BSTR,num1_str,UI1,2,R8,0.5);
8645 if (has_i8)
8647 VARDIV(BSTR,num1_str,I8,2,R8,0.5);
8649 VARDIV(BOOL,VARIANT_TRUE,NULL,0,NULL,0);
8650 VARDIV(BOOL,VARIANT_TRUE,I2,1,R8,-1.0);
8651 VARDIV(BOOL,VARIANT_FALSE,I2,1,R8,0.0);
8652 VARDIV(BOOL,VARIANT_TRUE,I4,1,R8,-1.0);
8653 VARDIV(BOOL,VARIANT_FALSE,I4,1,R8,0.0);
8654 VARDIV(BOOL,VARIANT_TRUE,R4,1,R4,-1.0f);
8655 VARDIV(BOOL,VARIANT_FALSE,R4,1,R4,0.0f);
8656 VARDIV(BOOL,VARIANT_TRUE,R8,1.0,R8,-1.0);
8657 VARDIV(BOOL,VARIANT_FALSE,R8,1.0,R8,0.0);
8658 VARDIV(BOOL,VARIANT_FALSE,DATE,2,R8,0.0);
8659 VARDIV(BOOL,VARIANT_FALSE,BSTR,num2_str,R8,0.0);
8660 VARDIV(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,R8,1.0);
8661 VARDIV(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE,R8,0.0);
8662 VARDIV(BOOL,VARIANT_TRUE,UI1,1,R8,-1.0);
8663 if (has_i8)
8665 VARDIV(BOOL,VARIANT_TRUE,I8,1,R8,-1.0);
8667 VARDIV(UI1,1,NULL,0,NULL,0);
8668 VARDIV(UI1,1,I2,2,R8,0.5);
8669 VARDIV(UI1,1,I4,2,R8,0.5);
8670 VARDIV(UI1,1,R4,2.0f,R4,0.5f);
8671 VARDIV(UI1,1,R8,2.0,R8,0.5);
8672 VARDIV(UI1,1,DATE,2,R8,0.5);
8673 VARDIV(UI1,1,BSTR,num2_str,R8,0.5);
8674 VARDIV(UI1,1,BOOL,VARIANT_TRUE,R8,-1);
8675 VARDIV(UI1,1,UI1,2,R8,0.5);
8676 if (has_i8)
8678 VARDIV(UI1,1,I8,2,R8,0.5);
8679 VARDIV(I8,1,NULL,0,NULL,0);
8680 VARDIV(I8,1,I2,2,R8,0.5);
8681 VARDIV(I8,1,I4,2,R8,0.5);
8682 VARDIV(I8,1,R4,2.0f,R8,0.5);
8683 VARDIV(I8,1,R8,2.0,R8,0.5);
8684 VARDIV(I8,1,DATE,2,R8,0.5);
8685 VARDIV(I8,1,BSTR,num2_str,R8,0.5);
8686 VARDIV(I8,1,BOOL,VARIANT_TRUE,R8,-1);
8687 VARDIV(I8,1,UI1,2,R8,0.5);
8688 VARDIV(I8,1,I8,2,R8,0.5);
8691 /* Manually test some VT_CY, VT_DECIMAL variants */
8692 V_VT(&cy) = VT_CY;
8693 hres = VarCyFromI4(10000, &V_CY(&cy));
8694 ok(hres == S_OK, "VarCyFromI4 failed!\n");
8695 V_VT(&dec) = VT_DECIMAL;
8696 hres = VarDecFromR8(2.0, &V_DECIMAL(&dec));
8697 ok(hres == S_OK, "VarDecFromR4 failed!\n");
8698 memset(&left, 0, sizeof(left));
8699 memset(&right, 0, sizeof(right));
8700 V_VT(&left) = VT_I4;
8701 V_I4(&left) = 100;
8702 V_VT(&right) = VT_UI1;
8703 V_UI1(&right) = 2;
8705 hres = pVarDiv(&cy, &cy, &result);
8706 ok(hres == S_OK && V_VT(&result) == VT_R8,
8707 "VARDIV: expected coerced type VT_R8, got %s!\n", vtstr(V_VT(&result)));
8708 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 1.0),
8709 "VARDIV: CY value %f, expected %f\n", V_R8(&result), 1.0);
8711 hres = pVarDiv(&cy, &right, &result);
8712 ok(hres == S_OK && V_VT(&result) == VT_R8,
8713 "VARDIV: expected coerced type VT_R8, got %s!\n", vtstr(V_VT(&result)));
8714 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 5000.0),
8715 "VARDIV: CY value %f, expected %f\n", V_R8(&result), 5000.0);
8717 hres = pVarDiv(&left, &cy, &result);
8718 ok(hres == S_OK && V_VT(&result) == VT_R8,
8719 "VARDIV: expected coerced type VT_R8, got %s!\n", vtstr(V_VT(&result)));
8720 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 0.01),
8721 "VARDIV: CY value %f, expected %f\n", V_R8(&result), 0.01);
8723 hres = pVarDiv(&left, &dec, &result);
8724 ok(hres == S_OK && V_VT(&result) == VT_DECIMAL,
8725 "VARDIV: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
8726 hres = VarR8FromDec(&V_DECIMAL(&result), &r);
8727 ok(hres == S_OK && EQ_DOUBLE(r, 50.0), "VARDIV: DECIMAL value %f, expected %f\n", r, 50.0);
8729 hres = pVarDiv(&dec, &dec, &result);
8730 ok(hres == S_OK && V_VT(&result) == VT_DECIMAL,
8731 "VARDIV: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
8732 hres = VarR8FromDec(&V_DECIMAL(&result), &r);
8733 ok(hres == S_OK && EQ_DOUBLE(r, 1.0), "VARDIV: DECIMAL value %f, expected %f\n", r, 1.0);
8735 hres = pVarDiv(&dec, &right, &result);
8736 ok(hres == S_OK && V_VT(&result) == VT_DECIMAL,
8737 "VARDIV: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
8738 hres = VarR8FromDec(&V_DECIMAL(&result), &r);
8739 ok(hres == S_OK && EQ_DOUBLE(r, 1.0), "VARDIV: DECIMAL value %f, expected %f\n", r, 1.0);
8741 /* Check for division by zero and overflow */
8742 V_VT(&left) = VT_R8;
8743 V_I4(&left) = 1;
8744 V_VT(&right) = VT_R8;
8745 V_I4(&right) = 0;
8746 hres = pVarDiv(&left, &right, &result);
8747 ok(hres == DISP_E_DIVBYZERO && V_VT(&result) == VT_EMPTY,
8748 "VARDIV: Division by (1.0/0.0) should result in DISP_E_DIVBYZERO but got 0x%X\n", hres);
8750 V_VT(&left) = VT_R8;
8751 V_I4(&left) = 0;
8752 V_VT(&right) = VT_R8;
8753 V_I4(&right) = 0;
8754 hres = pVarDiv(&left, &right, &result);
8755 ok(hres == DISP_E_OVERFLOW && V_VT(&result) == VT_EMPTY,
8756 "VARDIV: Division by (0.0/0.0) should result in DISP_E_OVERFLOW but got 0x%X\n", hres);
8758 SysFreeString(num1_str);
8759 SysFreeString(num2_str);
8762 static HRESULT (WINAPI *pVarIdiv)(LPVARIANT,LPVARIANT,LPVARIANT);
8764 #define VARIDIV(vt1,val1,vt2,val2,rvt,rval) \
8765 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
8766 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
8767 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
8768 test_var_call2( __LINE__, pVarIdiv, &left, &right, &exp )
8770 /* Skip any type that is not defined or produces an error for every case */
8771 #define SKIPTESTIDIV(a) \
8772 if (a == VT_ERROR || a == VT_VARIANT || \
8773 a == VT_DISPATCH || a == VT_UNKNOWN || \
8774 a == VT_RECORD || a > VT_UINT || \
8775 a == 15 /*not defined*/) \
8776 continue
8778 static void test_VarIdiv(void)
8780 static const WCHAR str1[] = { '1','\0' };
8781 static const WCHAR str2[] = { '2','\0' };
8782 VARIANT left, right, exp, result, cy, dec;
8783 BSTR num1_str, num2_str;
8784 VARTYPE i;
8785 HRESULT hres;
8787 CHECKPTR(VarIdiv);
8789 num1_str = SysAllocString(str1);
8790 num2_str = SysAllocString(str2);
8792 /* Test all possible flag/vt combinations & the resulting vt type */
8793 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
8795 VARTYPE leftvt, rightvt, resvt;
8797 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
8799 SKIPTESTIDIV(leftvt);
8801 /* Check if we need/have support for I8 and/or UI8 */
8802 if ((leftvt == VT_I8 || leftvt == VT_UI8) && !has_i8)
8803 continue;
8805 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
8807 BOOL bFail = FALSE;
8808 SKIPTESTIDIV(rightvt);
8810 /* Native crashes with extra flag VT_BYREF */
8811 if (ExtraFlags[i] == VT_BYREF)
8812 continue;
8814 /* Check if we need/have support for I8 and/or UI8 */
8815 if ((rightvt == VT_I8 || rightvt == VT_UI8) && !has_i8)
8816 continue;
8818 memset(&left, 0, sizeof(left));
8819 memset(&right, 0, sizeof(right));
8820 V_VT(&left) = leftvt | ExtraFlags[i];
8821 V_VT(&right) = rightvt | ExtraFlags[i];
8822 V_VT(&result) = VT_EMPTY;
8823 resvt = VT_EMPTY;
8825 if (leftvt == VT_BSTR)
8826 V_BSTR(&left) = num2_str;
8827 else if (leftvt == VT_DECIMAL)
8829 VarDecFromR8(2.0, &V_DECIMAL(&left));
8830 V_VT(&left) = leftvt | ExtraFlags[i];
8833 /* Division by 0 is undefined */
8834 switch(rightvt)
8836 case VT_BSTR:
8837 V_BSTR(&right) = num2_str;
8838 break;
8839 case VT_DECIMAL:
8840 VarDecFromR8(2.0, &V_DECIMAL(&right));
8841 V_VT(&right) = rightvt | ExtraFlags[i];
8842 break;
8843 case VT_BOOL:
8844 V_BOOL(&right) = VARIANT_TRUE;
8845 break;
8846 case VT_CY:
8847 VarCyFromI4(10000, &V_CY(&right));
8848 V_VT(&right) = rightvt | ExtraFlags[i];
8849 break;
8850 case VT_I2: V_I2(&right) = 2; break;
8851 case VT_I4: V_I4(&right) = 2; break;
8852 case VT_R4: V_R4(&right) = 2.0f; break;
8853 case VT_R8: V_R8(&right) = 2.0; break;
8854 case VT_DATE: V_DATE(&right) = 2; break;
8855 case VT_I1: V_I1(&right) = 2; break;
8856 case VT_UI1: V_UI1(&right) = 2; break;
8857 case VT_UI2: V_UI2(&right) = 2; break;
8858 case VT_UI4: V_UI4(&right) = 2; break;
8859 case VT_I8: V_I8(&right) = 2; break;
8860 case VT_UI8: V_UI8(&right) = 2; break;
8861 case VT_INT: V_INT(&right) = 2; break;
8862 case VT_UINT: V_UINT(&right) = 2; break;
8863 default: break;
8866 /* Native VarIdiv always returns an error when using extra
8867 * flags or if the variant combination is I8 and INT.
8869 if ((leftvt == VT_I8 && rightvt == VT_INT) ||
8870 (leftvt == VT_INT && rightvt == VT_I8) ||
8871 (rightvt == VT_EMPTY && leftvt != VT_NULL) ||
8872 ExtraFlags[i] != 0)
8873 bFail = TRUE;
8875 /* Determine variant type */
8876 else if (leftvt == VT_NULL || rightvt == VT_NULL)
8877 resvt = VT_NULL;
8878 else if (leftvt == VT_I8 || rightvt == VT_I8)
8879 resvt = VT_I8;
8880 else if (leftvt == VT_I4 || rightvt == VT_I4 ||
8881 leftvt == VT_INT || rightvt == VT_INT ||
8882 leftvt == VT_UINT || rightvt == VT_UINT ||
8883 leftvt == VT_UI8 || rightvt == VT_UI8 ||
8884 leftvt == VT_UI4 || rightvt == VT_UI4 ||
8885 leftvt == VT_UI2 || rightvt == VT_UI2 ||
8886 leftvt == VT_I1 || rightvt == VT_I1 ||
8887 leftvt == VT_BSTR || rightvt == VT_BSTR ||
8888 leftvt == VT_DATE || rightvt == VT_DATE ||
8889 leftvt == VT_CY || rightvt == VT_CY ||
8890 leftvt == VT_DECIMAL || rightvt == VT_DECIMAL ||
8891 leftvt == VT_R8 || rightvt == VT_R8 ||
8892 leftvt == VT_R4 || rightvt == VT_R4)
8893 resvt = VT_I4;
8894 else if (leftvt == VT_I2 || rightvt == VT_I2 ||
8895 leftvt == VT_BOOL || rightvt == VT_BOOL ||
8896 leftvt == VT_EMPTY)
8897 resvt = VT_I2;
8898 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
8899 resvt = VT_UI1;
8900 else
8901 bFail = TRUE;
8903 hres = pVarIdiv(&left, &right, &result);
8905 /* Check expected HRESULT and if result variant type is correct */
8906 if (bFail)
8907 ok (hres == DISP_E_BADVARTYPE || hres == DISP_E_TYPEMISMATCH ||
8908 hres == DISP_E_DIVBYZERO,
8909 "VarIdiv: %s|0x%X, %s|0x%X: got vt %s hr 0x%X\n",
8910 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i],
8911 vtstr(V_VT(&result)), hres);
8912 else
8913 ok (hres == S_OK && resvt == V_VT(&result),
8914 "VarIdiv: %s|0x%X, %s|0x%X: expected vt %s hr 0x%X, got vt %s hr 0x%X\n",
8915 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i], vtstr(resvt),
8916 S_OK, vtstr(V_VT(&result)), hres);
8921 /* Test return values for all the good cases */
8922 VARIDIV(EMPTY,0,NULL,0,NULL,0);
8923 VARIDIV(EMPTY,0,I2,1,I2,0);
8924 VARIDIV(EMPTY,0,I4,1,I4,0);
8925 VARIDIV(EMPTY,0,R4,1.0f,I4,0);
8926 VARIDIV(EMPTY,0,R8,1.0,I4,0);
8927 VARIDIV(EMPTY,0,DATE,1.0,I4,0);
8928 VARIDIV(EMPTY,0,BSTR,num1_str,I4,0);
8929 VARIDIV(EMPTY,0,BOOL,VARIANT_TRUE,I2,0);
8930 VARIDIV(EMPTY,0,I1,1,I4,0);
8931 VARIDIV(EMPTY,0,UI1,1,I2,0);
8932 VARIDIV(EMPTY,0,UI2,1,I4,0);
8933 VARIDIV(EMPTY,0,UI4,1,I4,0);
8934 if (has_i8)
8936 VARIDIV(EMPTY,0,I8,1,I8,0);
8937 VARIDIV(EMPTY,0,UI8,1,I4,0);
8939 VARIDIV(EMPTY,0,INT,1,I4,0);
8940 VARIDIV(EMPTY,0,UINT,1,I4,0);
8941 VARIDIV(NULL,0,EMPTY,0,NULL,0);
8942 VARIDIV(NULL,0,NULL,0,NULL,0);
8943 VARIDIV(NULL,0,I2,1,NULL,0);
8944 VARIDIV(NULL,0,I4,1,NULL,0);
8945 VARIDIV(NULL,0,R4,1,NULL,0);
8946 VARIDIV(NULL,0,R8,1,NULL,0);
8947 VARIDIV(NULL,0,DATE,1,NULL,0);
8948 VARIDIV(NULL,0,BSTR,num1_str,NULL,0);
8949 VARIDIV(NULL,0,BOOL,VARIANT_TRUE,NULL,0);
8950 VARIDIV(NULL,0,I1,1,NULL,0);
8951 VARIDIV(NULL,0,UI1,1,NULL,0);
8952 VARIDIV(NULL,0,UI2,1,NULL,0);
8953 VARIDIV(NULL,0,UI4,1,NULL,0);
8954 if (has_i8)
8956 VARIDIV(NULL,0,I8,1,NULL,0);
8957 VARIDIV(NULL,0,UI8,1,NULL,0);
8959 VARIDIV(NULL,0,INT,1,NULL,0);
8960 VARIDIV(NULL,0,UINT,1,NULL,0);
8961 VARIDIV(I2,2,NULL,0,NULL,0);
8962 VARIDIV(I2,2,I2,1,I2,2);
8963 VARIDIV(I2,2,I4,1,I4,2);
8964 VARIDIV(I2,2,R4,1,I4,2);
8965 VARIDIV(I2,2,R8,1,I4,2);
8966 VARIDIV(I2,2,DATE,1,I4,2);
8967 VARIDIV(I2,2,BSTR,num1_str,I4,2);
8968 VARIDIV(I2,2,BOOL,VARIANT_TRUE,I2,-2);
8969 VARIDIV(I2,2,I1,1,I4,2);
8970 VARIDIV(I2,2,UI1,1,I2,2);
8971 VARIDIV(I2,2,UI2,1,I4,2);
8972 VARIDIV(I2,2,UI4,1,I4,2);
8973 if (has_i8)
8975 VARIDIV(I2,2,I8,1,I8,2);
8976 VARIDIV(I2,2,UI8,1,I4,2);
8978 VARIDIV(I2,2,INT,1,I4,2);
8979 VARIDIV(I2,2,UINT,1,I4,2);
8980 VARIDIV(I4,2,NULL,0,NULL,0);
8981 VARIDIV(I4,2,I2,1,I4,2);
8982 VARIDIV(I4,2,I4,1,I4,2);
8983 VARIDIV(I4,2,R4,1,I4,2);
8984 VARIDIV(I4,2,R8,1,I4,2);
8985 VARIDIV(I4,2,DATE,1,I4,2);
8986 VARIDIV(I4,2,BSTR,num1_str,I4,2);
8987 VARIDIV(I4,2,BOOL,VARIANT_TRUE,I4,-2);
8988 VARIDIV(I4,2,I1,1,I4,2);
8989 VARIDIV(I4,2,UI1,1,I4,2);
8990 VARIDIV(I4,2,UI2,1,I4,2);
8991 VARIDIV(I4,2,UI4,1,I4,2);
8992 if (has_i8)
8994 VARIDIV(I4,2,I8,1,I8,2);
8995 VARIDIV(I4,2,UI8,1,I4,2);
8997 VARIDIV(I4,2,INT,1,I4,2);
8998 VARIDIV(I4,2,UINT,1,I4,2);
8999 VARIDIV(R4,2.0f,NULL,0,NULL,0);
9000 VARIDIV(R4,2.0f,I2,1,I4,2);
9001 VARIDIV(R4,2.0f,I4,1,I4,2);
9002 VARIDIV(R4,2.0f,R4,1.0f,I4,2);
9003 VARIDIV(R4,2.0f,R8,1.0,I4,2);
9004 VARIDIV(R4,2.0f,DATE,1,I4,2);
9005 VARIDIV(R4,2.0f,BSTR,num1_str,I4,2);
9006 VARIDIV(R4,2.0f,BOOL,VARIANT_TRUE,I4,-2);
9007 VARIDIV(R4,2.0f,I1,1,I4,2);
9008 VARIDIV(R4,2.0f,UI1,1,I4,2);
9009 VARIDIV(R4,2.0f,UI2,1,I4,2);
9010 VARIDIV(R4,2.0f,UI4,1,I4,2);
9011 if (has_i8)
9013 VARIDIV(R4,2.0f,I8,1,I8,2);
9014 VARIDIV(R4,2.0f,UI8,1,I4,2);
9016 VARIDIV(R4,2.0f,INT,1,I4,2);
9017 VARIDIV(R4,2.0f,UINT,1,I4,2);
9018 VARIDIV(R8,2.0,NULL,0,NULL,0);
9019 VARIDIV(R8,2.0,I2,1,I4,2);
9020 VARIDIV(R8,2.0,I4,1,I4,2);
9021 VARIDIV(R8,2.0,R4,1,I4,2);
9022 VARIDIV(R8,2.0,R8,1,I4,2);
9023 VARIDIV(R8,2.0,DATE,1,I4,2);
9024 VARIDIV(R8,2.0,BSTR,num1_str,I4,2);
9025 VARIDIV(R8,2.0,BOOL,VARIANT_TRUE,I4,-2);
9026 VARIDIV(R8,2.0,I1,1,I4,2);
9027 VARIDIV(R8,2.0,UI1,1,I4,2);
9028 VARIDIV(R8,2.0,UI2,1,I4,2);
9029 VARIDIV(R8,2.0,UI4,1,I4,2);
9030 if (has_i8)
9032 VARIDIV(R8,2.0,I8,1,I8,2);
9033 VARIDIV(R8,2.0,UI8,1,I4,2);
9035 VARIDIV(R8,2.0,INT,1,I4,2);
9036 VARIDIV(R8,2.0,UINT,1,I4,2);
9037 VARIDIV(DATE,2,NULL,0,NULL,0);
9038 VARIDIV(DATE,2,I2,1,I4,2);
9039 VARIDIV(DATE,2,I4,1,I4,2);
9040 VARIDIV(DATE,2,R4,1,I4,2);
9041 VARIDIV(DATE,2,R8,1,I4,2);
9042 VARIDIV(DATE,2,DATE,1,I4,2);
9043 VARIDIV(DATE,2,BSTR,num1_str,I4,2);
9044 VARIDIV(DATE,2,BOOL,VARIANT_TRUE,I4,-2);
9045 VARIDIV(DATE,2,I1,1,I4,2);
9046 VARIDIV(DATE,2,UI1,1,I4,2);
9047 VARIDIV(DATE,2,UI2,1,I4,2);
9048 VARIDIV(DATE,2,UI4,1,I4,2);
9049 if (has_i8)
9051 VARIDIV(DATE,2,I8,1,I8,2);
9052 VARIDIV(DATE,2,UI8,1,I4,2);
9054 VARIDIV(DATE,2,INT,1,I4,2);
9055 VARIDIV(DATE,2,UINT,1,I4,2);
9056 VARIDIV(BSTR,num2_str,NULL,0,NULL,0);
9057 VARIDIV(BSTR,num2_str,I2,1,I4,2);
9058 VARIDIV(BSTR,num2_str,I4,1,I4,2);
9059 VARIDIV(BSTR,num2_str,R4,1.0f,I4,2);
9060 VARIDIV(BSTR,num2_str,R8,1.0,I4,2);
9061 VARIDIV(BSTR,num2_str,DATE,1,I4,2);
9062 VARIDIV(BSTR,num2_str,BSTR,num1_str,I4,2);
9063 VARIDIV(BSTR,num2_str,BOOL,VARIANT_TRUE,I4,-2);
9064 VARIDIV(BSTR,num2_str,I1,1,I4,2);
9065 VARIDIV(BSTR,num2_str,UI1,1,I4,2);
9066 VARIDIV(BSTR,num2_str,UI2,1,I4,2);
9067 VARIDIV(BSTR,num2_str,UI4,1,I4,2);
9068 if (has_i8)
9070 VARIDIV(BSTR,num2_str,I8,1,I8,2);
9071 VARIDIV(BSTR,num2_str,UI8,1,I4,2);
9073 VARIDIV(BSTR,num2_str,INT,1,I4,2);
9074 VARIDIV(BSTR,num2_str,UINT,1,I4,2);
9075 VARIDIV(BOOL,VARIANT_TRUE,NULL,0,NULL,0);
9076 VARIDIV(BOOL,VARIANT_TRUE,I2,1,I2,-1);
9077 VARIDIV(BOOL,VARIANT_TRUE,I4,1,I4,-1);
9078 VARIDIV(BOOL,VARIANT_TRUE,R4,1.0f,I4,-1);
9079 VARIDIV(BOOL,VARIANT_TRUE,R8,1.0,I4,-1);
9080 VARIDIV(BOOL,VARIANT_TRUE,DATE,1,I4,-1);
9081 VARIDIV(BOOL,VARIANT_TRUE,BSTR,num1_str,I4,-1);
9082 VARIDIV(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,I2,1);
9083 VARIDIV(BOOL,VARIANT_TRUE,I1,1,I4,-1);
9084 VARIDIV(BOOL,VARIANT_TRUE,UI1,1,I2,-1);
9085 VARIDIV(BOOL,VARIANT_TRUE,UI2,1,I4,-1);
9086 VARIDIV(BOOL,VARIANT_TRUE,UI4,1,I4,-1);
9087 if (has_i8)
9089 VARIDIV(BOOL,VARIANT_TRUE,I8,1,I8,-1);
9090 VARIDIV(BOOL,VARIANT_TRUE,UI8,1,I4,-1);
9092 VARIDIV(BOOL,VARIANT_TRUE,INT,1,I4,-1);
9093 VARIDIV(BOOL,VARIANT_TRUE,UINT,1,I4,-1);
9094 VARIDIV(I1,2,NULL,0,NULL,0);
9095 VARIDIV(I1,2,I2,1,I4,2);
9096 VARIDIV(I1,2,I4,1,I4,2);
9097 VARIDIV(I1,2,R4,1.0f,I4,2);
9098 VARIDIV(I1,2,R8,1.0,I4,2);
9099 VARIDIV(I1,2,DATE,1,I4,2);
9100 VARIDIV(I1,2,BSTR,num1_str,I4,2);
9101 VARIDIV(I1,2,BOOL,VARIANT_TRUE,I4,-2);
9102 VARIDIV(I1,2,I1,1,I4,2);
9103 VARIDIV(I1,2,UI1,1,I4,2);
9104 VARIDIV(I1,2,UI2,1,I4,2);
9105 VARIDIV(I1,2,UI4,1,I4,2);
9106 if (has_i8)
9108 VARIDIV(I1,2,I8,1,I8,2);
9109 VARIDIV(I1,2,UI8,1,I4,2);
9111 VARIDIV(I1,2,INT,1,I4,2);
9112 VARIDIV(I1,2,UINT,1,I4,2);
9113 VARIDIV(UI1,2,NULL,0,NULL,0);
9114 VARIDIV(UI1,2,I2,1,I2,2);
9115 VARIDIV(UI1,2,I4,1,I4,2);
9116 VARIDIV(UI1,2,R4,1.0f,I4,2);
9117 VARIDIV(UI1,2,R8,1.0,I4,2);
9118 VARIDIV(UI1,2,DATE,1,I4,2);
9119 VARIDIV(UI1,2,BSTR,num1_str,I4,2);
9120 VARIDIV(UI1,2,BOOL,VARIANT_TRUE,I2,-2);
9121 VARIDIV(UI1,2,I1,1,I4,2);
9122 VARIDIV(UI1,2,UI1,1,UI1,2);
9123 VARIDIV(UI1,2,UI2,1,I4,2);
9124 VARIDIV(UI1,2,UI4,1,I4,2);
9125 if (has_i8)
9127 VARIDIV(UI1,2,I8,1,I8,2);
9128 VARIDIV(UI1,2,UI8,1,I4,2);
9130 VARIDIV(UI1,2,INT,1,I4,2);
9131 VARIDIV(UI1,2,UINT,1,I4,2);
9132 VARIDIV(UI2,2,NULL,0,NULL,0);
9133 VARIDIV(UI2,2,I2,1,I4,2);
9134 VARIDIV(UI2,2,I4,1,I4,2);
9135 VARIDIV(UI2,2,R4,1.0f,I4,2);
9136 VARIDIV(UI2,2,R8,1.0,I4,2);
9137 VARIDIV(UI2,2,DATE,1,I4,2);
9138 VARIDIV(UI2,2,BSTR,num1_str,I4,2);
9139 VARIDIV(UI2,2,BOOL,VARIANT_TRUE,I4,-2);
9140 VARIDIV(UI2,2,I1,1,I4,2);
9141 VARIDIV(UI2,2,UI1,1,I4,2);
9142 VARIDIV(UI2,2,UI2,1,I4,2);
9143 VARIDIV(UI2,2,UI4,1,I4,2);
9144 if (has_i8)
9146 VARIDIV(UI2,2,I8,1,I8,2);
9147 VARIDIV(UI2,2,UI8,1,I4,2);
9149 VARIDIV(UI2,2,INT,1,I4,2);
9150 VARIDIV(UI2,2,UINT,1,I4,2);
9151 VARIDIV(UI4,2,NULL,0,NULL,0);
9152 VARIDIV(UI4,2,I2,1,I4,2);
9153 VARIDIV(UI4,2,I4,1,I4,2);
9154 VARIDIV(UI4,2,R4,1.0f,I4,2);
9155 VARIDIV(UI4,2,R8,1.0,I4,2);
9156 VARIDIV(UI4,2,DATE,1,I4,2);
9157 VARIDIV(UI4,2,BSTR,num1_str,I4,2);
9158 VARIDIV(UI4,2,BOOL,VARIANT_TRUE,I4,-2);
9159 VARIDIV(UI4,2,I1,1,I4,2);
9160 VARIDIV(UI4,2,UI1,1,I4,2);
9161 VARIDIV(UI4,2,UI2,1,I4,2);
9162 VARIDIV(UI4,2,UI4,1,I4,2);
9163 if (has_i8)
9165 VARIDIV(UI4,2,I8,1,I8,2);
9166 VARIDIV(UI4,2,UI8,1,I4,2);
9168 VARIDIV(UI4,2,INT,1,I4,2);
9169 VARIDIV(UI4,2,UINT,1,I4,2);
9170 if (has_i8)
9172 VARIDIV(I8,2,NULL,0,NULL,0);
9173 VARIDIV(I8,2,I2,1,I8,2);
9174 VARIDIV(I8,2,I4,1,I8,2);
9175 VARIDIV(I8,2,R4,1.0f,I8,2);
9176 VARIDIV(I8,2,R8,1.0,I8,2);
9177 VARIDIV(I8,2,DATE,1,I8,2);
9178 VARIDIV(I8,2,BSTR,num1_str,I8,2);
9179 VARIDIV(I8,2,BOOL,1,I8,2);
9180 VARIDIV(I8,2,I1,1,I8,2);
9181 VARIDIV(I8,2,UI1,1,I8,2);
9182 VARIDIV(I8,2,UI2,1,I8,2);
9183 VARIDIV(I8,2,UI4,1,I8,2);
9184 VARIDIV(I8,2,I8,1,I8,2);
9185 VARIDIV(I8,2,UI8,1,I8,2);
9186 VARIDIV(I8,2,UINT,1,I8,2);
9187 VARIDIV(UI8,2,NULL,0,NULL,0);
9188 VARIDIV(UI8,2,I2,1,I4,2);
9189 VARIDIV(UI8,2,I4,1,I4,2);
9190 VARIDIV(UI8,2,R4,1.0f,I4,2);
9191 VARIDIV(UI8,2,R8,1.0,I4,2);
9192 VARIDIV(UI8,2,DATE,1,I4,2);
9193 VARIDIV(UI8,2,BSTR,num1_str,I4,2);
9194 VARIDIV(UI8,2,BOOL,VARIANT_TRUE,I4,-2);
9195 VARIDIV(UI8,2,I1,1,I4,2);
9196 VARIDIV(UI8,2,UI1,1,I4,2);
9197 VARIDIV(UI8,2,UI2,1,I4,2);
9198 VARIDIV(UI8,2,UI4,1,I4,2);
9199 VARIDIV(UI8,2,I8,1,I8,2);
9200 VARIDIV(UI8,2,UI8,1,I4,2);
9201 VARIDIV(UI8,2,INT,1,I4,2);
9202 VARIDIV(UI8,2,UINT,1,I4,2);
9204 VARIDIV(INT,2,NULL,0,NULL,0);
9205 VARIDIV(INT,2,I2,1,I4,2);
9206 VARIDIV(INT,2,I4,1,I4,2);
9207 VARIDIV(INT,2,R4,1.0f,I4,2);
9208 VARIDIV(INT,2,R8,1.0,I4,2);
9209 VARIDIV(INT,2,DATE,1,I4,2);
9210 VARIDIV(INT,2,BSTR,num1_str,I4,2);
9211 VARIDIV(INT,2,BOOL,VARIANT_TRUE,I4,-2);
9212 VARIDIV(INT,2,I1,1,I4,2);
9213 VARIDIV(INT,2,UI1,1,I4,2);
9214 VARIDIV(INT,2,UI2,1,I4,2);
9215 VARIDIV(INT,2,UI4,1,I4,2);
9216 if (has_i8)
9218 VARIDIV(INT,2,UI8,1,I4,2);
9220 VARIDIV(INT,2,INT,1,I4,2);
9221 VARIDIV(INT,2,UINT,1,I4,2);
9222 VARIDIV(UINT,2,NULL,0,NULL,0);
9223 VARIDIV(UINT,2,I2,1,I4,2);
9224 VARIDIV(UINT,2,I4,1,I4,2);
9225 VARIDIV(UINT,2,R4,1.0f,I4,2);
9226 VARIDIV(UINT,2,R8,1.0,I4,2);
9227 VARIDIV(UINT,2,DATE,1,I4,2);
9228 VARIDIV(UINT,2,BSTR,num1_str,I4,2);
9229 VARIDIV(UINT,2,BOOL,VARIANT_TRUE,I4,-2);
9230 VARIDIV(UINT,2,I1,1,I4,2);
9231 VARIDIV(UINT,2,UI1,1,I4,2);
9232 VARIDIV(UINT,2,UI2,1,I4,2);
9233 VARIDIV(UINT,2,UI4,1,I4,2);
9234 if (has_i8)
9236 VARIDIV(UINT,2,I8,1,I8,2);
9237 VARIDIV(UINT,2,UI8,1,I4,2);
9239 VARIDIV(UINT,2,INT,1,I4,2);
9240 VARIDIV(UINT,2,UINT,1,I4,2);
9242 /* Manually test some VT_CY, VT_DECIMAL variants */
9243 V_VT(&cy) = VT_CY;
9244 hres = VarCyFromI4(10000, &V_CY(&cy));
9245 ok(hres == S_OK, "VarCyFromI4 failed!\n");
9246 V_VT(&dec) = VT_DECIMAL;
9247 hres = VarDecFromR8(2.0, &V_DECIMAL(&dec));
9248 ok(hres == S_OK, "VarDecFromR4 failed!\n");
9249 memset(&left, 0, sizeof(left));
9250 memset(&right, 0, sizeof(right));
9251 V_VT(&left) = VT_I4;
9252 V_I4(&left) = 100;
9253 V_VT(&right) = VT_I8;
9254 V_UI1(&right) = 2;
9256 hres = pVarIdiv(&cy, &cy, &result);
9257 ok(hres == S_OK && V_VT(&result) == VT_I4,
9258 "VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9259 S_OK, hres, vtstr(V_VT(&result)));
9260 ok(hres == S_OK && V_I4(&result) == 1,
9261 "VARIDIV: CY value %d, expected %d\n", V_I4(&result), 1);
9263 if (has_i8)
9265 hres = pVarIdiv(&cy, &right, &result);
9266 ok(hres == S_OK && V_VT(&result) == VT_I8,
9267 "VARIDIV: expected coerced hres 0x%X type VT_I8, got hres 0x%X type %s!\n",
9268 S_OK, hres, vtstr(V_VT(&result)));
9269 ok(hres == S_OK && V_I8(&result) == 5000,
9270 "VARIDIV: CY value 0x%x%08x, expected 0x%x\n",
9271 (DWORD)(V_I8(&result) >>32), (DWORD)V_I8(&result), 5000);
9274 hres = pVarIdiv(&left, &cy, &result);
9275 ok(hres == S_OK && V_VT(&result) == VT_I4,
9276 "VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9277 S_OK, hres, vtstr(V_VT(&result)));
9278 ok(hres == S_OK && V_I4(&result) == 0,
9279 "VARIDIV: CY value %d, expected %d\n", V_I4(&result), 0);
9281 hres = pVarIdiv(&left, &dec, &result);
9282 ok(hres == S_OK && V_VT(&result) == VT_I4,
9283 "VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9284 S_OK, hres, vtstr(V_VT(&result)));
9285 ok(hres == S_OK && V_I4(&result) == 50,
9286 "VARIDIV: DECIMAL value %d, expected %d\n", V_I4(&result), 50);
9288 hres = pVarIdiv(&dec, &dec, &result);
9289 ok(hres == S_OK && V_VT(&result) == VT_I4,
9290 "VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9291 S_OK, hres, vtstr(V_VT(&result)));
9292 ok(hres == S_OK && V_I4(&result) == 1,
9293 "VARIDIV: DECIMAL value %d, expected %d\n", V_I4(&result), 1);
9295 if (has_i8)
9297 hres = pVarIdiv(&dec, &right, &result);
9298 ok(hres == S_OK && V_VT(&result) == VT_I8,
9299 "VARIDIV: expected coerced hres 0x%X type VT_I8, got hres 0x%X type %s!\n",
9300 S_OK, hres, vtstr(V_VT(&result)));
9301 ok(hres == S_OK && V_I8(&result) == 1,
9302 "VARIDIV: DECIMAL value 0x%x%08x, expected %d\n",
9303 (DWORD)(V_I8(&result) >> 32), (DWORD)V_I8(&result), 1);
9306 /* Check for division by zero */
9307 V_VT(&left) = VT_INT;
9308 V_I4(&left) = 1;
9309 V_VT(&right) = VT_INT;
9310 V_I4(&right) = 0;
9311 hres = pVarIdiv(&left, &right, &result);
9312 ok(hres == DISP_E_DIVBYZERO && V_VT(&result) == VT_EMPTY,
9313 "VARIDIV: Division by 0 should result in DISP_E_DIVBYZERO but got 0x%X\n", hres);
9315 V_VT(&left) = VT_INT;
9316 V_I4(&left) = 0;
9317 V_VT(&right) = VT_INT;
9318 V_I4(&right) = 0;
9319 hres = pVarIdiv(&left, &right, &result);
9320 ok(hres == DISP_E_DIVBYZERO && V_VT(&result) == VT_EMPTY,
9321 "VARIDIV: Division by 0 should result in DISP_E_DIVBYZERO but got 0x%X\n", hres);
9323 SysFreeString(num1_str);
9324 SysFreeString(num2_str);
9328 static HRESULT (WINAPI *pVarImp)(LPVARIANT,LPVARIANT,LPVARIANT);
9330 #define VARIMP(vt1,val1,vt2,val2,rvt,rval) \
9331 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
9332 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
9333 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
9334 test_var_call2( __LINE__, pVarImp, &left, &right, &exp )
9336 /* Skip any type that is not defined or produces an error for every case */
9337 #define SKIPTESTIMP(a) \
9338 if (a == VT_ERROR || a == VT_VARIANT || \
9339 a == VT_DISPATCH || a == VT_UNKNOWN || \
9340 a == VT_RECORD || a > VT_UINT || \
9341 a == 15 /*not defined*/) \
9342 continue
9344 static void test_VarImp(void)
9346 static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
9347 static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
9348 VARIANT left, right, exp, result, cy, dec;
9349 BSTR true_str, false_str;
9350 VARTYPE i;
9351 HRESULT hres;
9353 CHECKPTR(VarImp);
9355 true_str = SysAllocString(szTrue);
9356 false_str = SysAllocString(szFalse);
9358 /* Test all possible flag/vt combinations & the resulting vt type */
9359 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
9361 VARTYPE leftvt, rightvt, resvt;
9363 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
9365 SKIPTESTIMP(leftvt);
9367 /* Check if we need/have support for I8 and/or UI8 */
9368 if ((leftvt == VT_I8 || leftvt == VT_UI8) && !has_i8)
9369 continue;
9371 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
9373 BOOL bFail = FALSE;
9374 SKIPTESTIMP(rightvt);
9376 /* Native crashes when using the extra flag VT_BYREF
9377 * or with the following VT combinations
9379 if ((leftvt == VT_UI4 && rightvt == VT_BSTR) ||
9380 (leftvt == VT_UI8 && rightvt == VT_BSTR) ||
9381 ExtraFlags[i] == VT_BYREF)
9382 continue;
9384 /* Check if we need/have support for I8 and/or UI8 */
9385 if ((rightvt == VT_I8 || rightvt == VT_UI8) && !has_i8)
9386 continue;
9388 memset(&left, 0, sizeof(left));
9389 memset(&right, 0, sizeof(right));
9390 V_VT(&left) = leftvt | ExtraFlags[i];
9391 V_VT(&right) = rightvt | ExtraFlags[i];
9392 V_VT(&result) = VT_EMPTY;
9393 resvt = VT_EMPTY;
9395 if (leftvt == VT_BSTR)
9396 V_BSTR(&left) = true_str;
9398 /* This allows us to test return types that are not NULL
9399 * (NULL Imp value = n, NULL Imp 0 = NULL)
9401 switch(rightvt)
9403 case VT_BSTR:
9404 V_BSTR(&right) = true_str;
9405 break;
9406 case VT_DECIMAL:
9407 VarDecFromR8(2.0, &V_DECIMAL(&right));
9408 V_VT(&right) = rightvt | ExtraFlags[i];
9409 break;
9410 case VT_BOOL:
9411 V_BOOL(&right) = VARIANT_TRUE;
9412 break;
9413 case VT_I1: V_I1(&right) = 2; break;
9414 case VT_I2: V_I2(&right) = 2; break;
9415 case VT_I4: V_I4(&right) = 2; break;
9416 case VT_R4: V_R4(&right) = 2.0f; break;
9417 case VT_R8: V_R8(&right) = 2.0; break;
9418 case VT_CY: V_CY(&right).int64 = 10000; break;
9419 case VT_DATE: V_DATE(&right) = 2; break;
9420 case VT_I8: V_I8(&right) = 2; break;
9421 case VT_INT: V_INT(&right) = 2; break;
9422 case VT_UINT: V_UINT(&right) = 2; break;
9423 case VT_UI1: V_UI1(&right) = 2; break;
9424 case VT_UI2: V_UI2(&right) = 2; break;
9425 case VT_UI4: V_UI4(&right) = 2; break;
9426 case VT_UI8: V_UI8(&right) = 2; break;
9427 default: break;
9430 /* Native VarImp always returns an error when using extra
9431 * flags or if the variants are I8 and INT.
9433 if ((leftvt == VT_I8 && rightvt == VT_INT) ||
9434 ExtraFlags[i] != 0)
9435 bFail = TRUE;
9437 /* Determine result type */
9438 else if ((leftvt == VT_BSTR && rightvt == VT_NULL) ||
9439 (leftvt == VT_NULL && rightvt == VT_NULL) ||
9440 (leftvt == VT_NULL && rightvt == VT_EMPTY))
9441 resvt = VT_NULL;
9442 else if (leftvt == VT_I8 || rightvt == VT_I8)
9443 resvt = VT_I8;
9444 else if (leftvt == VT_I4 || rightvt == VT_I4 ||
9445 leftvt == VT_INT || rightvt == VT_INT ||
9446 leftvt == VT_UINT || rightvt == VT_UINT ||
9447 leftvt == VT_UI4 || rightvt == VT_UI4 ||
9448 leftvt == VT_UI8 || rightvt == VT_UI8 ||
9449 leftvt == VT_UI2 || rightvt == VT_UI2 ||
9450 leftvt == VT_DECIMAL || rightvt == VT_DECIMAL ||
9451 leftvt == VT_DATE || rightvt == VT_DATE ||
9452 leftvt == VT_CY || rightvt == VT_CY ||
9453 leftvt == VT_R8 || rightvt == VT_R8 ||
9454 leftvt == VT_R4 || rightvt == VT_R4 ||
9455 leftvt == VT_I1 || rightvt == VT_I1)
9456 resvt = VT_I4;
9457 else if ((leftvt == VT_UI1 && rightvt == VT_UI1) ||
9458 (leftvt == VT_UI1 && rightvt == VT_NULL) ||
9459 (leftvt == VT_NULL && rightvt == VT_UI1))
9460 resvt = VT_UI1;
9461 else if (leftvt == VT_EMPTY || rightvt == VT_EMPTY ||
9462 leftvt == VT_I2 || rightvt == VT_I2 ||
9463 leftvt == VT_UI1 || rightvt == VT_UI1)
9464 resvt = VT_I2;
9465 else if (leftvt == VT_BOOL || rightvt == VT_BOOL ||
9466 leftvt == VT_BSTR || rightvt == VT_BSTR)
9467 resvt = VT_BOOL;
9469 hres = pVarImp(&left, &right, &result);
9471 /* Check expected HRESULT and if result variant type is correct */
9472 if (bFail)
9473 ok (hres == DISP_E_BADVARTYPE || hres == DISP_E_TYPEMISMATCH,
9474 "VarImp: %s|0x%X, %s|0x%X: got vt %s hr 0x%X\n",
9475 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i],
9476 vtstr(V_VT(&result)), hres);
9477 else
9478 ok (hres == S_OK && resvt == V_VT(&result),
9479 "VarImp: %s|0x%X, %s|0x%X: expected vt %s hr 0x%X, got vt %s hr 0x%X\n",
9480 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i], vtstr(resvt),
9481 S_OK, vtstr(V_VT(&result)), hres);
9486 VARIMP(EMPTY,0,EMPTY,0,I2,-1);
9487 VARIMP(EMPTY,0,NULL,0,I2,-1);
9488 VARIMP(EMPTY,0,I2,-1,I2,-1);
9489 VARIMP(EMPTY,0,I4,-1,I4,-1);
9490 VARIMP(EMPTY,0,R4,0.0f,I4,-1);
9491 VARIMP(EMPTY,0,R8,-1.0,I4,-1);
9492 VARIMP(EMPTY,0,DATE,0,I4,-1);
9493 VARIMP(EMPTY,0,BSTR,true_str,I2,-1);
9494 VARIMP(EMPTY,0,BOOL,VARIANT_FALSE,I2,-1);
9495 VARIMP(EMPTY,0,I1,0,I4,-1);
9496 VARIMP(EMPTY,0,UI1,1,I2,-1);
9497 VARIMP(EMPTY,0,UI2,1,I4,-1);
9498 VARIMP(EMPTY,0,UI4,1,I4,-1);
9499 if (has_i8)
9501 VARIMP(EMPTY,0,I8,1,I8,-1);
9502 VARIMP(EMPTY,0,UI8,1,I4,-1);
9504 VARIMP(EMPTY,0,INT,-1,I4,-1);
9505 VARIMP(EMPTY,0,UINT,1,I4,-1);
9506 VARIMP(NULL,0,EMPTY,0,NULL,0);
9507 VARIMP(NULL,0,NULL,0,NULL,0);
9508 VARIMP(NULL,0,I2,-1,I2,-1);
9509 VARIMP(NULL,0,I4,-1,I4,-1);
9510 VARIMP(NULL,0,R4,0.0f,NULL,0);
9511 VARIMP(NULL,0,R8,-1.0,I4,-1);
9512 VARIMP(NULL,0,DATE,0,NULL,0);
9513 VARIMP(NULL,0,BSTR,true_str,BOOL,-1);
9514 VARIMP(NULL,0,BOOL,VARIANT_FALSE,NULL,0);
9515 VARIMP(NULL,0,I1,0,NULL,0);
9516 VARIMP(NULL,0,UI1,1,UI1,1);
9517 VARIMP(NULL,0,UI2,1,I4,1);
9518 VARIMP(NULL,0,UI4,1,I4,1);
9519 if (has_i8)
9521 VARIMP(NULL,0,I8,1,I8,1);
9522 VARIMP(NULL,0,UI8,1,I4,1);
9524 VARIMP(NULL,0,INT,-1,I4,-1);
9525 VARIMP(NULL,0,UINT,1,I4,1);
9526 VARIMP(I2,-1,EMPTY,0,I2,0);
9527 VARIMP(I2,-1,I2,-1,I2,-1);
9528 VARIMP(I2,-1,I4,-1,I4,-1);
9529 VARIMP(I2,-1,R4,0.0f,I4,0);
9530 VARIMP(I2,-1,R8,-1.0,I4,-1);
9531 VARIMP(I2,-1,DATE,0,I4,0);
9532 VARIMP(I2,-1,BSTR,true_str,I2,-1);
9533 VARIMP(I2,-1,BOOL,VARIANT_FALSE,I2,0);
9534 VARIMP(I2,-1,I1,0,I4,0);
9535 VARIMP(I2,-1,UI1,1,I2,1);
9536 VARIMP(I2,-1,UI2,1,I4,1);
9537 VARIMP(I2,-1,UI4,1,I4,1);
9538 if (has_i8)
9540 VARIMP(I2,-1,I8,1,I8,1);
9541 VARIMP(I2,-1,UI8,1,I4,1);
9543 VARIMP(I2,-1,INT,-1,I4,-1);
9544 VARIMP(I2,-1,UINT,1,I4,1);
9545 VARIMP(I4,2,EMPTY,0,I4,-3);
9546 VARIMP(I4,2,NULL,0,I4,-3);
9547 VARIMP(I4,2,I2,-1,I4,-1);
9548 VARIMP(I4,2,I4,-1,I4,-1);
9549 VARIMP(I4,2,R4,0.0f,I4,-3);
9550 VARIMP(I4,2,R8,-1.0,I4,-1);
9551 VARIMP(I4,2,DATE,0,I4,-3);
9552 VARIMP(I4,2,BSTR,true_str,I4,-1);
9553 VARIMP(I4,2,BOOL,VARIANT_FALSE,I4,-3);
9554 VARIMP(I4,2,I1,0,I4,-3);
9555 VARIMP(I4,2,UI1,1,I4,-3);
9556 VARIMP(I4,2,UI2,1,I4,-3);
9557 VARIMP(I4,2,UI4,1,I4,-3);
9558 if (has_i8)
9560 VARIMP(I4,2,I8,1,I8,-3);
9561 VARIMP(I4,2,UI8,1,I4,-3);
9563 VARIMP(I4,2,INT,-1,I4,-1);
9564 VARIMP(I4,2,UINT,1,I4,-3);
9565 VARIMP(R4,-1.0f,EMPTY,0,I4,0);
9566 VARIMP(R4,-1.0f,NULL,0,NULL,0);
9567 VARIMP(R4,-1.0f,I2,-1,I4,-1);
9568 VARIMP(R4,-1.0f,I4,-1,I4,-1);
9569 VARIMP(R4,-1.0f,R4,0.0f,I4,0);
9570 VARIMP(R4,-1.0f,R8,-1.0,I4,-1);
9571 VARIMP(R4,-1.0f,DATE,1,I4,1);
9572 VARIMP(R4,-1.0f,BSTR,true_str,I4,-1);
9573 VARIMP(R4,-1.0f,BOOL,VARIANT_FALSE,I4,0);
9574 VARIMP(R4,-1.0f,I1,0,I4,0);
9575 VARIMP(R4,-1.0f,UI1,1,I4,1);
9576 VARIMP(R4,-1.0f,UI2,1,I4,1);
9577 VARIMP(R4,-1.0f,UI4,1,I4,1);
9578 if (has_i8)
9580 VARIMP(R4,-1.0f,I8,1,I8,1);
9581 VARIMP(R4,-1.0f,UI8,1,I4,1);
9583 VARIMP(R4,-1.0f,INT,-1,I4,-1);
9584 VARIMP(R4,-1.0f,UINT,1,I4,1);
9585 VARIMP(R8,1.0,EMPTY,0,I4,-2);
9586 VARIMP(R8,1.0,NULL,0,I4,-2);
9587 VARIMP(R8,1.0,I2,-1,I4,-1);
9588 VARIMP(R8,1.0,I4,-1,I4,-1);
9589 VARIMP(R8,1.0,R4,0.0f,I4,-2);
9590 VARIMP(R8,1.0,R8,-1.0,I4,-1);
9591 VARIMP(R8,1.0,DATE,0,I4,-2);
9592 VARIMP(R8,1.0,BSTR,true_str,I4,-1);
9593 VARIMP(R8,1.0,BOOL,VARIANT_FALSE,I4,-2);
9594 VARIMP(R8,1.0,I1,0,I4,-2);
9595 VARIMP(R8,1.0,UI1,1,I4,-1);
9596 VARIMP(R8,1.0,UI2,1,I4,-1);
9597 VARIMP(R8,1.0,UI4,1,I4,-1);
9598 if (has_i8)
9600 VARIMP(R8,1.0,I8,1,I8,-1);
9601 VARIMP(R8,1.0,UI8,1,I4,-1);
9603 VARIMP(R8,1.0,INT,-1,I4,-1);
9604 VARIMP(R8,1.0,UINT,1,I4,-1);
9605 VARIMP(DATE,0,EMPTY,0,I4,-1);
9606 VARIMP(DATE,0,NULL,0,I4,-1);
9607 VARIMP(DATE,0,I2,-1,I4,-1);
9608 VARIMP(DATE,0,I4,-1,I4,-1);
9609 VARIMP(DATE,0,R4,0.0f,I4,-1);
9610 VARIMP(DATE,0,R8,-1.0,I4,-1);
9611 VARIMP(DATE,0,DATE,0,I4,-1);
9612 VARIMP(DATE,0,BSTR,true_str,I4,-1);
9613 VARIMP(DATE,0,BOOL,VARIANT_FALSE,I4,-1);
9614 VARIMP(DATE,0,I1,0,I4,-1);
9615 VARIMP(DATE,0,UI1,1,I4,-1);
9616 VARIMP(DATE,0,UI2,1,I4,-1);
9617 VARIMP(DATE,0,UI4,1,I4,-1);
9618 if (has_i8)
9620 VARIMP(DATE,0,I8,1,I8,-1);
9621 VARIMP(DATE,0,UI8,1,I4,-1);
9623 VARIMP(DATE,0,INT,-1,I4,-1);
9624 VARIMP(DATE,0,UINT,1,I4,-1);
9625 VARIMP(BSTR,false_str,EMPTY,0,I2,-1);
9626 VARIMP(BSTR,false_str,NULL,0,BOOL,-1);
9627 VARIMP(BSTR,false_str,I2,-1,I2,-1);
9628 VARIMP(BSTR,false_str,I4,-1,I4,-1);
9629 VARIMP(BSTR,false_str,R4,0.0f,I4,-1);
9630 VARIMP(BSTR,false_str,R8,-1.0,I4,-1);
9631 VARIMP(BSTR,false_str,DATE,0,I4,-1);
9632 VARIMP(BSTR,false_str,BSTR,true_str,BOOL,-1);
9633 VARIMP(BSTR,false_str,BOOL,VARIANT_FALSE,BOOL,-1);
9634 VARIMP(BSTR,false_str,I1,0,I4,-1);
9635 VARIMP(BSTR,false_str,UI1,1,I2,-1);
9636 VARIMP(BSTR,false_str,UI2,1,I4,-1);
9637 VARIMP(BSTR,false_str,UI4,1,I4,-1);
9638 if (has_i8)
9640 VARIMP(BSTR,false_str,I8,1,I8,-1);
9641 VARIMP(BSTR,false_str,UI8,1,I4,-1);
9643 VARIMP(BSTR,false_str,INT,-1,I4,-1);
9644 VARIMP(BSTR,false_str,UINT,1,I4,-1);
9645 VARIMP(BOOL,VARIANT_TRUE,EMPTY,0,I2,0);
9646 VARIMP(BOOL,VARIANT_TRUE,NULL,0,NULL,0);
9647 VARIMP(BOOL,VARIANT_TRUE,I2,-1,I2,-1);
9648 VARIMP(BOOL,VARIANT_TRUE,I4,-1,I4,-1);
9649 VARIMP(BOOL,VARIANT_TRUE,R4,0.0f,I4,0);
9650 VARIMP(BOOL,VARIANT_TRUE,R8,-1.0,I4,-1);
9651 VARIMP(BOOL,VARIANT_TRUE,DATE,0,I4,0);
9652 VARIMP(BOOL,VARIANT_TRUE,BSTR,true_str,BOOL,-1);
9653 VARIMP(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE,BOOL,0);
9654 VARIMP(BOOL,VARIANT_TRUE,I1,0,I4,0);
9655 VARIMP(BOOL,VARIANT_TRUE,UI1,1,I2,1);
9656 VARIMP(BOOL,VARIANT_TRUE,UI2,1,I4,1);
9657 VARIMP(BOOL,VARIANT_TRUE,UI4,1,I4,1);
9658 if (has_i8)
9660 VARIMP(BOOL,VARIANT_TRUE,I8,1,I8,1);
9661 VARIMP(BOOL,VARIANT_TRUE,UI8,1,I4,1);
9663 VARIMP(BOOL,VARIANT_TRUE,INT,-1,I4,-1);
9664 VARIMP(BOOL,VARIANT_TRUE,UINT,1,I4,1);
9665 VARIMP(I1,-1,EMPTY,0,I4,0);
9666 VARIMP(I1,-1,NULL,0,NULL,0);
9667 VARIMP(I1,-1,I2,-1,I4,-1);
9668 VARIMP(I1,-1,I4,-1,I4,-1);
9669 VARIMP(I1,-1,R4,0.0f,I4,0);
9670 VARIMP(I1,-1,R8,-1.0,I4,-1);
9671 VARIMP(I1,-1,DATE,0,I4,0);
9672 VARIMP(I1,-1,BSTR,true_str,I4,-1);
9673 VARIMP(I1,-1,BOOL,VARIANT_FALSE,I4,0);
9674 VARIMP(I1,-1,I1,0,I4,0);
9675 VARIMP(I1,-1,UI1,1,I4,1);
9676 VARIMP(I1,-1,UI2,1,I4,1);
9677 VARIMP(I1,-1,UI4,1,I4,1);
9678 if (has_i8)
9680 VARIMP(I1,-1,I8,1,I8,1);
9681 VARIMP(I1,-1,UI8,1,I4,1);
9683 VARIMP(I1,-1,INT,-1,I4,-1);
9684 VARIMP(I1,-1,UINT,1,I4,1);
9685 VARIMP(UI1,0,EMPTY,0,I2,-1);
9686 VARIMP(UI1,0,NULL,0,UI1,255);
9687 VARIMP(UI1,0,I2,-1,I2,-1);
9688 VARIMP(UI1,0,I4,-1,I4,-1);
9689 VARIMP(UI1,0,R4,0.0f,I4,-1);
9690 VARIMP(UI1,0,R8,-1.0,I4,-1);
9691 VARIMP(UI1,0,DATE,0,I4,-1);
9692 VARIMP(UI1,0,BSTR,true_str,I2,-1);
9693 VARIMP(UI1,0,BOOL,VARIANT_FALSE,I2,-1);
9694 VARIMP(UI1,0,I1,0,I4,-1);
9695 VARIMP(UI1,0,UI1,1,UI1,255);
9696 VARIMP(UI1,0,UI2,1,I4,-1);
9697 VARIMP(UI1,0,UI4,1,I4,-1);
9698 if (has_i8)
9700 VARIMP(UI1,0,I8,1,I8,-1);
9701 VARIMP(UI1,0,UI8,1,I4,-1);
9703 VARIMP(UI1,0,INT,-1,I4,-1);
9704 VARIMP(UI1,0,UINT,1,I4,-1);
9705 VARIMP(UI2,0,EMPTY,0,I4,-1);
9706 VARIMP(UI2,0,NULL,0,I4,-1);
9707 VARIMP(UI2,0,I2,-1,I4,-1);
9708 VARIMP(UI2,0,I4,-1,I4,-1);
9709 VARIMP(UI2,0,R4,0.0f,I4,-1);
9710 VARIMP(UI2,0,R8,-1.0,I4,-1);
9711 VARIMP(UI2,0,DATE,0,I4,-1);
9712 VARIMP(UI2,0,BSTR,true_str,I4,-1);
9713 VARIMP(UI2,0,BOOL,VARIANT_FALSE,I4,-1);
9714 VARIMP(UI2,0,I1,0,I4,-1);
9715 VARIMP(UI2,0,UI1,1,I4,-1);
9716 VARIMP(UI2,0,UI2,1,I4,-1);
9717 VARIMP(UI2,0,UI4,1,I4,-1);
9718 if (has_i8)
9720 VARIMP(UI2,0,I8,1,I8,-1);
9721 VARIMP(UI2,0,UI8,1,I4,-1);
9723 VARIMP(UI2,0,INT,-1,I4,-1);
9724 VARIMP(UI2,0,UINT,1,I4,-1);
9725 VARIMP(UI4,0,EMPTY,0,I4,-1);
9726 VARIMP(UI4,0,NULL,0,I4,-1);
9727 VARIMP(UI4,0,I2,-1,I4,-1);
9728 VARIMP(UI4,0,I4,-1,I4,-1);
9729 VARIMP(UI4,0,R4,0.0f,I4,-1);
9730 VARIMP(UI4,0,R8,-1.0,I4,-1);
9731 VARIMP(UI4,0,DATE,0,I4,-1);
9732 VARIMP(UI4,0,BSTR,true_str,I4,-1);
9733 VARIMP(UI4,0,BOOL,VARIANT_FALSE,I4,-1);
9734 VARIMP(UI4,0,I1,0,I4,-1);
9735 VARIMP(UI4,0,UI1,1,I4,-1);
9736 VARIMP(UI4,0,UI2,1,I4,-1);
9737 VARIMP(UI4,0,UI4,1,I4,-1);
9738 if (has_i8)
9740 VARIMP(UI4,0,I8,1,I8,-1);
9741 VARIMP(UI4,0,UI8,1,I4,-1);
9743 VARIMP(UI4,0,INT,-1,I4,-1);
9744 VARIMP(UI4,0,UINT,1,I4,-1);
9745 if (has_i8)
9747 VARIMP(I8,-1,EMPTY,0,I8,0);
9748 VARIMP(I8,-1,NULL,0,NULL,0);
9749 VARIMP(I8,-1,I2,-1,I8,-1);
9750 VARIMP(I8,-1,I4,-1,I8,-1);
9751 VARIMP(I8,-1,R4,0.0f,I8,0);
9752 VARIMP(I8,-1,R8,-1.0,I8,-1);
9753 VARIMP(I8,-1,DATE,0,I8,0);
9754 VARIMP(I8,-1,BSTR,true_str,I8,-1);
9755 VARIMP(I8,-1,BOOL,VARIANT_FALSE,I8,0);
9756 VARIMP(I8,-1,I1,0,I8,0);
9757 VARIMP(I8,-1,UI1,1,I8,1);
9758 VARIMP(I8,-1,UI2,1,I8,1);
9759 VARIMP(I8,-1,UI4,1,I8,1);
9760 VARIMP(I8,-1,I8,1,I8,1);
9761 VARIMP(I8,-1,UI8,1,I8,1);
9762 VARIMP(I8,-1,UINT,1,I8,1);
9763 VARIMP(UI8,0,EMPTY,0,I4,-1);
9764 VARIMP(UI8,0,NULL,0,I4,-1);
9765 VARIMP(UI8,0,I2,-1,I4,-1);
9766 VARIMP(UI8,0,I4,-1,I4,-1);
9767 VARIMP(UI8,0,R4,0.0f,I4,-1);
9768 VARIMP(UI8,0,R8,-1.0,I4,-1);
9769 VARIMP(UI8,0,DATE,0,I4,-1);
9770 VARIMP(UI8,0,BSTR,true_str,I4,-1);
9771 VARIMP(UI8,0,BOOL,VARIANT_FALSE,I4,-1);
9772 VARIMP(UI8,0,I1,0,I4,-1);
9773 VARIMP(UI8,0,UI1,1,I4,-1);
9774 VARIMP(UI8,0,UI2,1,I4,-1);
9775 VARIMP(UI8,0,UI4,1,I4,-1);
9776 VARIMP(UI8,0,I8,1,I8,-1);
9777 VARIMP(UI8,0,UI8,1,I4,-1);
9778 VARIMP(UI8,0,INT,-1,I4,-1);
9779 VARIMP(UI8,0,UINT,1,I4,-1);
9781 VARIMP(INT,-1,EMPTY,0,I4,0);
9782 VARIMP(INT,-1,NULL,0,NULL,0);
9783 VARIMP(INT,-1,I2,-1,I4,-1);
9784 VARIMP(INT,-1,I4,-1,I4,-1);
9785 VARIMP(INT,-1,R4,0.0f,I4,0);
9786 VARIMP(INT,-1,R8,-1.0,I4,-1);
9787 VARIMP(INT,-1,DATE,0,I4,0);
9788 VARIMP(INT,-1,BSTR,true_str,I4,-1);
9789 VARIMP(INT,-1,BOOL,VARIANT_FALSE,I4,0);
9790 VARIMP(INT,-1,I1,0,I4,0);
9791 VARIMP(INT,-1,UI1,1,I4,1);
9792 VARIMP(INT,-1,UI2,1,I4,1);
9793 VARIMP(INT,-1,UI4,1,I4,1);
9794 if (has_i8)
9796 VARIMP(INT,-1,I8,1,I8,1);
9797 VARIMP(INT,-1,UI8,1,I4,1);
9799 VARIMP(INT,-1,INT,-1,I4,-1);
9800 VARIMP(INT,-1,UINT,1,I4,1);
9801 VARIMP(UINT,1,EMPTY,0,I4,-2);
9802 VARIMP(UINT,1,NULL,0,I4,-2);
9803 VARIMP(UINT,1,I2,-1,I4,-1);
9804 VARIMP(UINT,1,I4,-1,I4,-1);
9805 VARIMP(UINT,1,R4,0.0f,I4,-2);
9806 VARIMP(UINT,1,R8,-1.0,I4,-1);
9807 VARIMP(UINT,1,DATE,0,I4,-2);
9808 VARIMP(UINT,1,BSTR,true_str,I4,-1);
9809 VARIMP(UINT,1,BOOL,VARIANT_FALSE,I4,-2);
9810 VARIMP(UINT,1,I1,0,I4,-2);
9811 VARIMP(UINT,1,UI1,1,I4,-1);
9812 VARIMP(UINT,1,UI2,1,I4,-1);
9813 VARIMP(UINT,1,UI4,1,I4,-1);
9814 if (has_i8)
9816 VARIMP(UINT,1,I8,1,I8,-1);
9817 VARIMP(UINT,1,UI8,1,I4,-1);
9819 VARIMP(UINT,1,INT,-1,I4,-1);
9820 VARIMP(UINT,1,UINT,1,I4,-1);
9822 /* Manually test some VT_CY, VT_DECIMAL variants */
9823 V_VT(&cy) = VT_CY;
9824 hres = VarCyFromI4(1, &V_CY(&cy));
9825 ok(hres == S_OK, "VarCyFromI4 failed!\n");
9826 V_VT(&dec) = VT_DECIMAL;
9827 hres = VarDecFromR8(2.0, &V_DECIMAL(&dec));
9828 ok(hres == S_OK, "VarDecFromR4 failed!\n");
9829 memset(&left, 0, sizeof(left));
9830 memset(&right, 0, sizeof(right));
9831 V_VT(&left) = VT_I4;
9832 V_I4(&left) = 0;
9833 V_VT(&right) = VT_I8;
9834 V_UI1(&right) = 0;
9836 hres = pVarImp(&cy, &cy, &result);
9837 ok(hres == S_OK && V_VT(&result) == VT_I4,
9838 "VARIMP: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9839 S_OK, hres, vtstr(V_VT(&result)));
9840 ok(hres == S_OK && V_I4(&result) == -1,
9841 "VARIMP: CY value %d, expected %d\n", V_I4(&result), -1);
9843 if (has_i8)
9845 hres = pVarImp(&cy, &right, &result);
9846 ok(hres == S_OK && V_VT(&result) == VT_I8,
9847 "VARIMP: expected coerced hres 0x%X type VT_I8, got hres 0x%X type %s!\n",
9848 S_OK, hres, vtstr(V_VT(&result)));
9849 ok(hres == S_OK && V_I8(&result) == -2,
9850 "VARIMP: CY value %x%08x, expected %d\n",
9851 (DWORD)((V_I8(&result)) >> 32), (DWORD)(V_I8(&result)), -2);
9854 hres = pVarImp(&left, &cy, &result);
9855 ok(hres == S_OK && V_VT(&result) == VT_I4,
9856 "VARIMP: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9857 S_OK, hres, vtstr(V_VT(&result)));
9858 ok(hres == S_OK && V_I4(&result) == -1,
9859 "VARIMP: CY value %d, expected %d\n", V_I4(&result), -1);
9861 hres = pVarImp(&left, &dec, &result);
9862 ok(hres == S_OK && V_VT(&result) == VT_I4,
9863 "VARIMP: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9864 S_OK, hres, vtstr(V_VT(&result)));
9865 ok(hres == S_OK && V_I4(&result) == -1,
9866 "VARIMP: DECIMAL value %d, expected %d\n", V_I4(&result), -1);
9868 hres = pVarImp(&dec, &dec, &result);
9869 ok(hres == S_OK && V_VT(&result) == VT_I4,
9870 "VARIMP: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9871 S_OK, hres, vtstr(V_VT(&result)));
9872 ok(hres == S_OK && V_I4(&result) == -1,
9873 "VARIMP: DECIMAL value %d, expected %d\n", V_I4(&result), -1);
9875 if (has_i8)
9877 hres = pVarImp(&dec, &right, &result);
9878 ok(hres == S_OK && V_VT(&result) == VT_I8,
9879 "VARIMP: expected coerced hres 0x%X type VT_I8, got hres 0x%X type %s!\n",
9880 S_OK, hres, vtstr(V_VT(&result)));
9881 ok(hres == S_OK && V_I8(&result) == -3,
9882 "VARIMP: DECIMAL value 0x%x%08x, expected %d\n",
9883 (DWORD)(V_I8(&result) >>32), (DWORD)V_I8(&result), -3);
9886 SysFreeString(false_str);
9887 SysFreeString(true_str);
9890 START_TEST(vartest)
9892 init();
9894 test_VariantInit();
9895 test_VariantClear();
9896 test_VariantCopy();
9897 test_VariantCopyInd();
9898 test_VarParseNumFromStrEn();
9899 test_VarParseNumFromStrFr();
9900 test_VarParseNumFromStrMisc();
9901 test_VarNumFromParseNum();
9902 test_VarUdateFromDate();
9903 test_VarDateFromUdate();
9904 test_SystemTimeToVariantTime();
9905 test_VariantTimeToSystemTime();
9906 test_DosDateTimeToVariantTime();
9907 test_VariantTimeToDosDateTime();
9908 test_VarAbs();
9909 test_VarNot();
9910 test_VarSub();
9911 test_VarMod();
9912 test_VarFix();
9913 test_VarInt();
9914 test_VarNeg();
9915 test_VarRound();
9916 test_VarXor();
9917 test_VarOr();
9918 test_VarPow();
9919 test_VarEqv();
9920 test_VarMul();
9921 test_VarAdd();
9922 test_VarCmp(); /* Before test_VarCat() which needs VarCmp() */
9923 test_VarCat();
9924 test_VarAnd();
9925 test_VarDiv();
9926 test_VarIdiv();
9927 test_VarImp();