oleaut32: Do not skip the first decimal digit in VarParseNumFromStr().
[wine.git] / dlls / oleaut32 / tests / vartest.c
bloba4e2700c7df5331e7aaf3bd94e17f77cb3fd740c
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, v2, v3;
678 memset(&v, -1, sizeof(v));
679 memset(&v2, 0, sizeof(v2));
680 memset(&v3, -1, sizeof(v3));
681 V_VT(&v3) = VT_EMPTY;
683 VariantInit(&v);
684 ok(!memcmp(&v, &v2, sizeof(v)) ||
685 broken(!memcmp(&v, &v3, sizeof(v3)) /* pre Win8 */), "Unexpected contents.\n");
688 /* All possible combinations of extra V_VT() flags */
689 static const VARTYPE ExtraFlags[16] =
692 VT_VECTOR,
693 VT_ARRAY,
694 VT_BYREF,
695 VT_RESERVED,
696 VT_VECTOR|VT_ARRAY,
697 VT_VECTOR|VT_BYREF,
698 VT_VECTOR|VT_RESERVED,
699 VT_VECTOR|VT_ARRAY|VT_BYREF,
700 VT_VECTOR|VT_ARRAY|VT_RESERVED,
701 VT_VECTOR|VT_BYREF|VT_RESERVED,
702 VT_VECTOR|VT_ARRAY|VT_BYREF|VT_RESERVED,
703 VT_ARRAY|VT_BYREF,
704 VT_ARRAY|VT_RESERVED,
705 VT_ARRAY|VT_BYREF|VT_RESERVED,
706 VT_BYREF|VT_RESERVED,
709 /* Determine if a vt is valid for VariantClear() */
710 static BOOL IsValidVariantClearVT(VARTYPE vt, VARTYPE extraFlags)
712 BOOL ret = FALSE;
714 /* Only the following flags/types are valid */
715 if ((vt <= VT_LPWSTR || vt == VT_RECORD || vt == VT_CLSID) &&
716 vt != (VARTYPE)15 &&
717 (vt < (VARTYPE)24 || vt > (VARTYPE)31) &&
718 (!(extraFlags & (VT_BYREF|VT_ARRAY)) || vt > VT_NULL) &&
719 (extraFlags == 0 || extraFlags == VT_BYREF || extraFlags == VT_ARRAY ||
720 extraFlags == (VT_ARRAY|VT_BYREF)))
721 ret = TRUE; /* ok */
723 if (!has_i8 && (vt == VT_I8 || vt == VT_UI8))
724 ret = FALSE; /* Old versions of oleaut32 */
725 return ret;
728 typedef struct
730 IUnknown IUnknown_iface;
731 LONG ref;
732 LONG events;
733 } test_VariantClearImpl;
735 static inline test_VariantClearImpl *impl_from_IUnknown(IUnknown *iface)
737 return CONTAINING_RECORD(iface, test_VariantClearImpl, IUnknown_iface);
740 static HRESULT WINAPI VC_QueryInterface(LPUNKNOWN iface,REFIID riid,LPVOID *ppobj)
742 test_VariantClearImpl *This = impl_from_IUnknown(iface);
743 This->events |= 0x1;
744 return E_NOINTERFACE;
747 static ULONG WINAPI VC_AddRef(LPUNKNOWN iface) {
748 test_VariantClearImpl *This = impl_from_IUnknown(iface);
749 This->events |= 0x2;
750 return InterlockedIncrement(&This->ref);
753 static ULONG WINAPI VC_Release(LPUNKNOWN iface) {
754 test_VariantClearImpl *This = impl_from_IUnknown(iface);
755 /* static class, won't be freed */
756 This->events |= 0x4;
757 return InterlockedDecrement(&This->ref);
760 static const IUnknownVtbl test_VariantClear_vtbl = {
761 VC_QueryInterface,
762 VC_AddRef,
763 VC_Release,
766 static test_VariantClearImpl test_myVariantClearImpl = {{&test_VariantClear_vtbl}, 1, 0};
768 static void test_VariantClear(void)
770 struct __tagBRECORD *rec;
771 IRecordInfoImpl *recinfo;
772 HRESULT hres;
773 VARIANTARG v;
774 VARIANT v2;
775 size_t i;
776 LONG i4;
777 IUnknown *punk;
779 /* Crashes: Native does not test input for NULL, so neither does Wine */
780 if (0)
781 VariantClear(NULL);
783 /* Only the type field is set, to VT_EMPTY */
784 V_VT(&v) = VT_UI4;
785 V_UI4(&v) = ~0u;
786 hres = VariantClear(&v);
787 ok((hres == S_OK && V_VT(&v) == VT_EMPTY),
788 "VariantClear: Type set to %d, res %08x\n", V_VT(&v), hres);
789 ok(V_UI4(&v) == ~0u, "VariantClear: Overwrote value\n");
791 /* Test all possible V_VT values.
792 * Also demonstrates that null pointers in 'v' are not dereferenced.
793 * Individual variant tests should test VariantClear() with non-NULL values.
795 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
797 VARTYPE vt;
799 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
801 HRESULT hExpected = DISP_E_BADVARTYPE;
803 SKIPTESTS(vt);
805 memset(&v, 0, sizeof(v));
806 V_VT(&v) = vt | ExtraFlags[i];
808 hres = VariantClear(&v);
810 if (IsValidVariantClearVT(vt, ExtraFlags[i]))
811 hExpected = S_OK;
813 ok(hres == hExpected, "VariantClear: expected 0x%X, got 0x%X for vt %d | 0x%X\n",
814 hExpected, hres, vt, ExtraFlags[i]);
818 /* Some BYREF tests with non-NULL ptrs */
820 /* VARIANT BYREF */
821 V_VT(&v2) = VT_I4;
822 V_I4(&v2) = 0x1234;
823 V_VT(&v) = VT_VARIANT | VT_BYREF;
824 V_VARIANTREF(&v) = &v2;
826 hres = VariantClear(&v);
827 ok(hres == S_OK, "ret %08x\n", hres);
828 ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
829 ok(V_VARIANTREF(&v) == &v2, "variant ref %p\n", V_VARIANTREF(&v2));
830 ok(V_VT(&v2) == VT_I4, "vt %04x\n", V_VT(&v2));
831 ok(V_I4(&v2) == 0x1234, "i4 %04x\n", V_I4(&v2));
833 /* I4 BYREF */
834 i4 = 0x4321;
835 V_VT(&v) = VT_I4 | VT_BYREF;
836 V_I4REF(&v) = &i4;
838 hres = VariantClear(&v);
839 ok(hres == S_OK, "ret %08x\n", hres);
840 ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
841 ok(V_I4REF(&v) == &i4, "i4 ref %p\n", V_I4REF(&v2));
842 ok(i4 == 0x4321, "i4 changed %08x\n", i4);
845 /* UNKNOWN */
846 V_VT(&v) = VT_UNKNOWN;
847 V_UNKNOWN(&v) = &test_myVariantClearImpl.IUnknown_iface;
848 test_myVariantClearImpl.events = 0;
849 hres = VariantClear(&v);
850 ok(hres == S_OK, "ret %08x\n", hres);
851 ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
852 ok(V_UNKNOWN(&v) == &test_myVariantClearImpl.IUnknown_iface, "unknown %p\n", V_UNKNOWN(&v));
853 /* Check that Release got called, but nothing else */
854 ok(test_myVariantClearImpl.events == 0x4, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
856 /* UNKNOWN BYREF */
857 punk = &test_myVariantClearImpl.IUnknown_iface;
858 V_VT(&v) = VT_UNKNOWN | VT_BYREF;
859 V_UNKNOWNREF(&v) = &punk;
860 test_myVariantClearImpl.events = 0;
861 hres = VariantClear(&v);
862 ok(hres == S_OK, "ret %08x\n", hres);
863 ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
864 ok(V_UNKNOWNREF(&v) == &punk, "unknown ref %p\n", V_UNKNOWNREF(&v));
865 /* Check that nothing got called */
866 ok(test_myVariantClearImpl.events == 0, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
868 /* DISPATCH */
869 V_VT(&v) = VT_DISPATCH;
870 V_DISPATCH(&v) = (IDispatch*)&test_myVariantClearImpl.IUnknown_iface;
871 test_myVariantClearImpl.events = 0;
872 hres = VariantClear(&v);
873 ok(hres == S_OK, "ret %08x\n", hres);
874 ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
875 ok(V_DISPATCH(&v) == (IDispatch*)&test_myVariantClearImpl.IUnknown_iface,
876 "dispatch %p\n", V_DISPATCH(&v));
877 /* Check that Release got called, but nothing else */
878 ok(test_myVariantClearImpl.events == 0x4, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
880 /* DISPATCH BYREF */
881 punk = &test_myVariantClearImpl.IUnknown_iface;
882 V_VT(&v) = VT_DISPATCH | VT_BYREF;
883 V_DISPATCHREF(&v) = (IDispatch**)&punk;
884 test_myVariantClearImpl.events = 0;
885 hres = VariantClear(&v);
886 ok(hres == S_OK, "ret %08x\n", hres);
887 ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
888 ok(V_DISPATCHREF(&v) == (IDispatch**)&punk, "dispatch ref %p\n", V_DISPATCHREF(&v));
889 /* Check that nothing got called */
890 ok(test_myVariantClearImpl.events == 0, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
892 /* RECORD */
893 recinfo = get_test_recordinfo();
894 V_VT(&v) = VT_RECORD;
895 rec = &V_UNION(&v, brecVal);
896 rec->pRecInfo = &recinfo->IRecordInfo_iface;
897 rec->pvRecord = (void*)0xdeadbeef;
898 recinfo->recordclear = 0;
899 recinfo->ref = 2;
900 recinfo->rec = rec;
901 hres = VariantClear(&v);
902 ok(hres == S_OK, "ret %08x\n", hres);
903 ok(rec->pvRecord == NULL, "got %p\n", rec->pvRecord);
904 ok(recinfo->recordclear == 1, "got %d\n", recinfo->recordclear);
905 ok(recinfo->ref == 1, "got %d\n", recinfo->ref);
906 IRecordInfo_Release(&recinfo->IRecordInfo_iface);
909 static void test_VariantCopy(void)
911 struct __tagBRECORD *rec;
912 IRecordInfoImpl *recinfo;
913 VARIANTARG vSrc, vDst;
914 VARTYPE vt;
915 size_t i;
916 HRESULT hres, hExpected;
918 /* Establish that the failure/other cases are dealt with. Individual tests
919 * for each type should verify that data is copied correctly, references
920 * are updated, etc.
923 /* vSrc == vDst */
924 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
926 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
928 SKIPTESTS(vt);
930 memset(&vSrc, 0, sizeof(vSrc));
931 V_VT(&vSrc) = vt | ExtraFlags[i];
933 hExpected = DISP_E_BADVARTYPE;
934 /* src is allowed to be a VT_CLSID */
935 if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
936 hExpected = S_OK;
938 hres = VariantCopy(&vSrc, &vSrc);
940 ok(hres == hExpected,
941 "Copy(src==dst): expected 0x%X, got 0x%X for src==dest vt %d|0x%X\n",
942 hExpected, hres, vt, ExtraFlags[i]);
946 /* Test that if VariantClear() fails on dest, the function fails. This also
947 * shows that dest is in fact cleared and not just overwritten
949 memset(&vSrc, 0, sizeof(vSrc));
950 V_VT(&vSrc) = VT_UI1;
952 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
954 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
956 SKIPTESTS(vt);
958 hExpected = DISP_E_BADVARTYPE;
960 memset(&vDst, 0, sizeof(vDst));
961 V_VT(&vDst) = vt | ExtraFlags[i];
963 if (IsValidVariantClearVT(vt, ExtraFlags[i]))
964 hExpected = S_OK;
966 hres = VariantCopy(&vDst, &vSrc);
968 ok(hres == hExpected,
969 "Copy(bad dst): expected 0x%X, got 0x%X for dest vt %d|0x%X\n",
970 hExpected, hres, vt, ExtraFlags[i]);
971 if (hres == S_OK)
972 ok(V_VT(&vDst) == VT_UI1,
973 "Copy(bad dst): expected vt = VT_UI1, got %d\n", V_VT(&vDst));
977 /* Test that VariantClear() checks vSrc for validity before copying */
978 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
980 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
982 SKIPTESTS(vt);
984 hExpected = DISP_E_BADVARTYPE;
986 memset(&vDst, 0, sizeof(vDst));
987 V_VT(&vDst) = VT_EMPTY;
989 memset(&vSrc, 0, sizeof(vSrc));
990 V_VT(&vSrc) = vt | ExtraFlags[i];
992 /* src is allowed to be a VT_CLSID */
993 if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
994 hExpected = S_OK;
996 hres = VariantCopy(&vDst, &vSrc);
998 ok(hres == hExpected,
999 "Copy(bad src): expected 0x%X, got 0x%X for src vt %d|0x%X\n",
1000 hExpected, hres, vt, ExtraFlags[i]);
1001 if (hres == S_OK)
1003 ok(V_VT(&vDst) == (vt|ExtraFlags[i]),
1004 "Copy(bad src): expected vt = %d, got %d\n",
1005 vt | ExtraFlags[i], V_VT(&vDst));
1006 VariantClear(&vDst);
1011 /* Test that copying a NULL BSTR results in an empty BSTR */
1012 memset(&vDst, 0, sizeof(vDst));
1013 V_VT(&vDst) = VT_EMPTY;
1014 memset(&vSrc, 0, sizeof(vSrc));
1015 V_VT(&vSrc) = VT_BSTR;
1016 hres = VariantCopy(&vDst, &vSrc);
1017 ok(hres == S_OK, "Copy(NULL BSTR): Failed to copy a NULL BSTR\n");
1018 if (hres == S_OK)
1020 ok((V_VT(&vDst) == VT_BSTR) && V_BSTR(&vDst),
1021 "Copy(NULL BSTR): should have non-NULL result\n");
1022 if ((V_VT(&vDst) == VT_BSTR) && V_BSTR(&vDst))
1024 ok(*V_BSTR(&vDst) == 0, "Copy(NULL BSTR): result not empty\n");
1026 VariantClear(&vDst);
1029 /* copy RECORD */
1030 recinfo = get_test_recordinfo();
1032 memset(&vDst, 0, sizeof(vDst));
1033 V_VT(&vDst) = VT_EMPTY;
1035 V_VT(&vSrc) = VT_RECORD;
1036 rec = &V_UNION(&vSrc, brecVal);
1037 rec->pRecInfo = &recinfo->IRecordInfo_iface;
1038 rec->pvRecord = (void*)0xdeadbeef;
1040 recinfo->recordclear = 0;
1041 recinfo->recordcopy = 0;
1042 recinfo->getsize = 0;
1043 recinfo->rec = rec;
1044 hres = VariantCopy(&vDst, &vSrc);
1045 ok(hres == S_OK, "ret %08x\n", hres);
1047 rec = &V_UNION(&vDst, brecVal);
1048 ok(rec->pvRecord != (void*)0xdeadbeef && rec->pvRecord != NULL, "got %p\n", rec->pvRecord);
1049 ok(rec->pRecInfo == &recinfo->IRecordInfo_iface, "got %p\n", rec->pRecInfo);
1050 ok(recinfo->getsize == 1, "got %d\n", recinfo->recordclear);
1051 ok(recinfo->recordcopy == 1, "got %d\n", recinfo->recordclear);
1053 VariantClear(&vDst);
1054 VariantClear(&vSrc);
1057 /* Determine if a vt is valid for VariantCopyInd() */
1058 static BOOL IsValidVariantCopyIndVT(VARTYPE vt, VARTYPE extraFlags)
1060 BOOL ret = FALSE;
1062 if ((extraFlags & VT_ARRAY) ||
1063 (vt > VT_NULL && vt != (VARTYPE)15 && vt < VT_VOID &&
1064 !(extraFlags & (VT_VECTOR|VT_RESERVED))))
1066 ret = TRUE; /* ok */
1068 return ret;
1071 static void test_VariantCopyInd(void)
1073 VARIANTARG vSrc, vDst, vRef, vRef2;
1074 VARTYPE vt;
1075 size_t i;
1076 BYTE buffer[64];
1077 HRESULT hres, hExpected;
1079 memset(buffer, 0, sizeof(buffer));
1081 /* vSrc == vDst */
1082 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
1084 if (ExtraFlags[i] & VT_ARRAY)
1085 continue; /* Native crashes on NULL safearray */
1087 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
1089 SKIPTESTS(vt);
1091 memset(&vSrc, 0, sizeof(vSrc));
1092 V_VT(&vSrc) = vt | ExtraFlags[i];
1094 hExpected = DISP_E_BADVARTYPE;
1095 if (!(ExtraFlags[i] & VT_BYREF))
1097 /* if src is not by-reference, acts as VariantCopy() */
1098 if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
1099 hExpected = S_OK;
1101 else
1103 if (vt == VT_SAFEARRAY || vt == VT_BSTR || vt == VT_UNKNOWN ||
1104 vt == VT_DISPATCH || vt == VT_RECORD)
1105 continue; /* Need valid ptrs for deep copies */
1107 V_BYREF(&vSrc) = &buffer;
1108 hExpected = E_INVALIDARG;
1110 if ((vt == VT_I8 || vt == VT_UI8) &&
1111 ExtraFlags[i] == VT_BYREF)
1113 if (has_i8)
1114 hExpected = S_OK; /* Only valid if I8 is a known type */
1116 else if (IsValidVariantCopyIndVT(vt, ExtraFlags[i]))
1117 hExpected = S_OK;
1120 hres = VariantCopyInd(&vSrc, &vSrc);
1122 ok(hres == hExpected,
1123 "CopyInd(src==dst): expected 0x%X, got 0x%X for src==dst vt %d|0x%X\n",
1124 hExpected, hres, vt, ExtraFlags[i]);
1128 /* Bad dest */
1129 memset(&vSrc, 0, sizeof(vSrc));
1130 V_VT(&vSrc) = VT_UI1|VT_BYREF;
1131 V_BYREF(&vSrc) = &buffer;
1133 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
1135 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
1137 SKIPTESTS(vt);
1139 memset(&vDst, 0, sizeof(vDst));
1140 V_VT(&vDst) = vt | ExtraFlags[i];
1142 hExpected = DISP_E_BADVARTYPE;
1144 if (IsValidVariantClearVT(vt, ExtraFlags[i]))
1145 hExpected = S_OK;
1147 hres = VariantCopyInd(&vDst, &vSrc);
1149 ok(hres == hExpected,
1150 "CopyInd(bad dst): expected 0x%X, got 0x%X for dst vt %d|0x%X\n",
1151 hExpected, hres, vt, ExtraFlags[i]);
1152 if (hres == S_OK)
1153 ok(V_VT(&vDst) == VT_UI1,
1154 "CopyInd(bad dst): expected vt = VT_UI1, got %d\n", V_VT(&vDst));
1158 /* bad src */
1159 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
1161 if (ExtraFlags[i] & VT_ARRAY)
1162 continue; /* Native crashes on NULL safearray */
1164 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
1166 SKIPTESTS(vt);
1168 memset(&vDst, 0, sizeof(vDst));
1169 V_VT(&vDst) = VT_EMPTY;
1171 memset(&vSrc, 0, sizeof(vSrc));
1172 V_VT(&vSrc) = vt | ExtraFlags[i];
1174 hExpected = DISP_E_BADVARTYPE;
1175 if (!(ExtraFlags[i] & VT_BYREF))
1177 /* if src is not by-reference, acts as VariantCopy() */
1178 if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
1179 hExpected = S_OK;
1181 else
1183 if (vt == VT_SAFEARRAY || vt == VT_BSTR || vt == VT_UNKNOWN ||
1184 vt == VT_DISPATCH || vt == VT_RECORD)
1185 continue; /* Need valid ptrs for deep copies, see vartype.c */
1187 V_BYREF(&vSrc) = &buffer;
1189 hExpected = E_INVALIDARG;
1191 if ((vt == VT_I8 || vt == VT_UI8) &&
1192 ExtraFlags[i] == VT_BYREF)
1194 if (has_i8)
1195 hExpected = S_OK; /* Only valid if I8 is a known type */
1197 else if (IsValidVariantCopyIndVT(vt, ExtraFlags[i]))
1198 hExpected = S_OK;
1201 hres = VariantCopyInd(&vDst, &vSrc);
1203 ok(hres == hExpected,
1204 "CopyInd(bad src): expected 0x%X, got 0x%X for src vt %d|0x%X\n",
1205 hExpected, hres, vt, ExtraFlags[i]);
1206 if (hres == S_OK)
1208 if (vt == VT_VARIANT && ExtraFlags[i] == VT_BYREF)
1210 /* Type of vDst should be the type of the referenced variant.
1211 * Since we set the buffer to all zeros, its type should be
1212 * VT_EMPTY.
1214 ok(V_VT(&vDst) == VT_EMPTY,
1215 "CopyInd(bad src): expected dst vt = VT_EMPTY, got %d|0x%X\n",
1216 V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK);
1218 else
1220 ok(V_VT(&vDst) == (vt|(ExtraFlags[i] & ~VT_BYREF)),
1221 "CopyInd(bad src): expected dst vt = %d|0x%X, got %d|0x%X\n",
1222 vt, ExtraFlags[i] & ~VT_BYREF,
1223 V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK);
1225 VariantClear(&vDst);
1230 /* By-reference variants are dereferenced */
1231 V_VT(&vRef) = VT_UI1;
1232 V_UI1(&vRef) = 0x77;
1233 V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
1234 V_VARIANTREF(&vSrc) = &vRef;
1235 VariantInit(&vDst);
1237 hres = VariantCopyInd(&vDst, &vSrc);
1238 ok(hres == S_OK, "VariantCopyInd failed: 0x%08x\n", hres);
1239 ok(V_VT(&vDst) == VT_UI1 && V_UI1(&vDst) == 0x77,
1240 "CopyInd(deref): expected dst vt = VT_UI1, val 0x77, got %d|0x%X, 0x%2X\n",
1241 V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK, V_UI1(&vDst));
1243 /* By-reference variant to a by-reference type succeeds */
1244 V_VT(&vRef) = VT_UI1|VT_BYREF;
1245 V_UI1REF(&vRef) = buffer; buffer[0] = 0x88;
1246 V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
1247 V_VARIANTREF(&vSrc) = &vRef;
1248 VariantInit(&vDst);
1250 hres = VariantCopyInd(&vDst, &vSrc);
1251 ok(hres == S_OK, "VariantCopyInd failed: 0x%08x\n", hres);
1252 ok(V_VT(&vDst) == VT_UI1 && V_UI1(&vDst) == 0x88,
1253 "CopyInd(deref): expected dst vt = VT_UI1, val 0x77, got %d|0x%X, 0x%2X\n",
1254 V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK, V_UI1(&vDst));
1256 /* But a by-reference variant to a by-reference variant fails */
1257 V_VT(&vRef2) = VT_UI1;
1258 V_UI1(&vRef2) = 0x77;
1259 V_VT(&vRef) = VT_VARIANT|VT_BYREF;
1260 V_VARIANTREF(&vRef) = &vRef2;
1261 V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
1262 V_VARIANTREF(&vSrc) = &vRef;
1263 VariantInit(&vDst);
1265 hres = VariantCopyInd(&vDst, &vSrc);
1266 ok(hres == E_INVALIDARG,
1267 "CopyInd(ref->ref): expected E_INVALIDARG, got 0x%08x\n", hres);
1270 static HRESULT (WINAPI *pVarParseNumFromStr)(const OLECHAR*,LCID,ULONG,NUMPARSE*,BYTE*);
1272 /* Macros for converting and testing the result of VarParseNumFromStr */
1273 #define FAILDIG 255
1275 static HRESULT wconvert_str( const OLECHAR *str, INT dig, ULONG npflags,
1276 NUMPARSE *np, BYTE rgb[128], LCID lcid, ULONG flags)
1278 memset( rgb, FAILDIG, 128 );
1279 memset( np, 255, sizeof(*np) );
1280 np->cDig = dig;
1281 np->dwInFlags = npflags;
1282 return pVarParseNumFromStr( str, lcid, flags, np, rgb);
1285 static HRESULT convert_str( const char *str, INT dig, ULONG flags,
1286 NUMPARSE *np, BYTE rgb[128], LCID lcid )
1288 OLECHAR buff[128];
1289 MultiByteToWideChar( CP_ACP,0, str, -1, buff, ARRAY_SIZE( buff ));
1290 return wconvert_str(buff, dig, flags, np, rgb, lcid, LOCALE_NOUSEROVERRIDE);
1293 static void expect_NumFromStr( int line, HRESULT hres, NUMPARSE *np, INT a, ULONG b, ULONG c,
1294 INT d, INT e, INT f )
1296 ok_(__FILE__,line)(hres == S_OK, "returned %08x\n", hres);
1297 if (hres == S_OK)
1299 ok_(__FILE__,line)(np->cDig == a, "Expected cDig = %d, got %d\n", a, np->cDig);
1300 ok_(__FILE__,line)(np->dwInFlags == b, "Expected dwInFlags = 0x%x, got 0x%x\n", b, np->dwInFlags);
1301 ok_(__FILE__,line)(np->dwOutFlags == c, "Expected dwOutFlags = 0x%x, got 0x%x\n", c, np->dwOutFlags);
1302 ok_(__FILE__,line)(np->cchUsed == d, "Expected cchUsed = %d, got %d\n", d, np->cchUsed);
1303 ok_(__FILE__,line)(np->nBaseShift == e, "Expected nBaseShift = %d, got %d\n", e, np->nBaseShift);
1304 ok_(__FILE__,line)(np->nPwr10 == f, "Expected nPwr10 = %d, got %d\n", f, np->nPwr10);
1308 #define WCONVERTN(str,dig,flags) hres = wconvert_str( str, dig, flags, &np, rgb, lcid, LOCALE_NOUSEROVERRIDE )
1309 #define WCONVERT(str,flags) WCONVERTN(str,sizeof(rgb),flags)
1310 #define CONVERTN(str,dig,flags) hres = convert_str( str, dig, flags, &np, rgb, lcid )
1311 #define CONVERT(str,flags) CONVERTN(str,sizeof(rgb),flags)
1312 #define EXPECT(a,b,c,d,e,f) expect_NumFromStr( __LINE__, hres, &np, a, b, c, d, e, f )
1313 #define EXPECTRGB(a,b) ok(rgb[a] == b, "Digit[%d], expected %d, got %d\n", a, b, rgb[a])
1314 #define EXPECTFAIL ok(hres == DISP_E_TYPEMISMATCH, "Call succeeded, hres = %08x\n", hres)
1315 #define EXPECT2(a,b) EXPECTRGB(0,a); EXPECTRGB(1,b)
1317 static void test_VarParseNumFromStrEn(void)
1319 HRESULT hres;
1320 /* Ensure all tests are using the same locale characters for '$', ',' etc */
1321 LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
1322 NUMPARSE np;
1323 BYTE rgb[128];
1324 OLECHAR wstr[128];
1325 OLECHAR spaces[] = L" \xa0\f\n\r\t\v"; /* man isspace() */
1326 int i;
1328 /** No flags **/
1330 CHECKPTR(VarParseNumFromStr);
1332 /* Consume an empty string */
1333 CONVERT("", 0);
1334 EXPECTFAIL;
1336 /* Consume a single digit */
1337 CONVERT("7", 0);
1338 EXPECT(1,0,0,1,0,0);
1339 EXPECT2(7,FAILDIG);
1341 /* cDig is not literal digits - zeros are suppressed and nPwr10 is increased */
1342 CONVERT("10", 0);
1343 EXPECT(1,0,0,2,0,1);
1344 /* Note: Win32 writes the trailing zeros if they are within cDig's limits,
1345 * but then excludes them from the returned cDig count.
1346 * In our implementation we don't bother writing them at all.
1348 EXPECTRGB(0, 1);
1350 /* if cDig is too small and numbers follow, sets INEXACT */
1351 CONVERTN("11",1, 0);
1352 EXPECT(1,0,NUMPRS_INEXACT,2,0,1);
1353 EXPECT2(1,FAILDIG);
1355 /* Strips leading zeros */
1356 CONVERT("01", 0);
1357 EXPECT(1,0,0,2,0,0);
1358 EXPECT2(1,FAILDIG);
1360 /* Strips leading zeros */
1361 CONVERTN("01",1, 0);
1362 EXPECT(1,0,0,2,0,0);
1363 EXPECT2(1,FAILDIG);
1366 /* Fails on non digits */
1367 CONVERT("a", 0);
1368 EXPECTFAIL;
1369 EXPECTRGB(0,FAILDIG);
1371 /** NUMPRS_LEADING_WHITE/NUMPRS_TRAILING_WHITE **/
1373 /* Without flag, fails on whitespace */
1374 CONVERT(" 0", 0);
1375 EXPECTFAIL;
1376 EXPECTRGB(0,FAILDIG);
1379 /* With flag, consumes any type of space */
1380 for (i = 0; i < ARRAY_SIZE(spaces)-1; i++)
1382 winetest_push_context("%d", i);
1384 wsprintfW(wstr, L"%c0", spaces[i]);
1385 WCONVERT(wstr, NUMPRS_LEADING_WHITE);
1386 EXPECT(1,NUMPRS_LEADING_WHITE,NUMPRS_LEADING_WHITE,2,0,0);
1387 EXPECT2(0,FAILDIG);
1389 winetest_pop_context();
1392 /* Doesn't pick up trailing whitespace without flag */
1393 CONVERT("0 ", 0);
1394 EXPECT(1,0,0,1,0,0);
1395 EXPECT2(0,FAILDIG);
1397 /* With flag, consumes trailing whitespace */
1398 CONVERT("0 ", NUMPRS_TRAILING_WHITE);
1399 EXPECT(1,NUMPRS_TRAILING_WHITE,NUMPRS_TRAILING_WHITE,2,0,0);
1400 EXPECT2(0,FAILDIG);
1402 /* Leading flag only consumes leading */
1403 CONVERT(" 0 ", NUMPRS_LEADING_WHITE);
1404 EXPECT(1,NUMPRS_LEADING_WHITE,NUMPRS_LEADING_WHITE,2,0,0);
1405 EXPECT2(0,FAILDIG);
1407 /* Both flags consumes both */
1408 CONVERT(" 0 ", NUMPRS_LEADING_WHITE|NUMPRS_TRAILING_WHITE);
1409 EXPECT(1,NUMPRS_LEADING_WHITE|NUMPRS_TRAILING_WHITE,NUMPRS_LEADING_WHITE|NUMPRS_TRAILING_WHITE,3,0,0);
1410 EXPECT2(0,FAILDIG);
1412 /** NUMPRS_LEADING_PLUS/NUMPRS_TRAILING_PLUS **/
1414 /* Without flag, fails on + */
1415 CONVERT("+0", 0);
1416 EXPECTFAIL;
1417 EXPECTRGB(0,FAILDIG);
1419 /* With flag, consumes + */
1420 CONVERT("+0", NUMPRS_LEADING_PLUS);
1421 EXPECT(1,NUMPRS_LEADING_PLUS,NUMPRS_LEADING_PLUS,2,0,0);
1422 EXPECT2(0,FAILDIG);
1424 /* Without flag, doesn't consume trailing + */
1425 CONVERT("0+", 0);
1426 EXPECT(1,0,0,1,0,0);
1427 EXPECT2(0,FAILDIG);
1429 /* With flag, consumes trailing + */
1430 CONVERT("0+", NUMPRS_TRAILING_PLUS);
1431 EXPECT(1,NUMPRS_TRAILING_PLUS,NUMPRS_TRAILING_PLUS,2,0,0);
1432 EXPECT2(0,FAILDIG);
1434 /* With leading flag, doesn't consume trailing + */
1435 CONVERT("+0+", NUMPRS_LEADING_PLUS);
1436 EXPECT(1,NUMPRS_LEADING_PLUS,NUMPRS_LEADING_PLUS,2,0,0);
1437 EXPECT2(0,FAILDIG);
1439 /* Trailing + doesn't get consumed if we specify both (unlike whitespace) */
1440 CONVERT("+0+", NUMPRS_LEADING_PLUS|NUMPRS_TRAILING_PLUS);
1441 EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_TRAILING_PLUS,NUMPRS_LEADING_PLUS,2,0,0);
1442 EXPECT2(0,FAILDIG);
1444 /** NUMPRS_LEADING_MINUS/NUMPRS_TRAILING_MINUS **/
1446 /* Without flag, fails on - */
1447 CONVERT("-0", 0);
1448 EXPECTFAIL;
1449 EXPECTRGB(0,FAILDIG);
1451 /* With flag, consumes - */
1452 CONVERT("-0", NUMPRS_LEADING_MINUS);
1453 EXPECT(1,NUMPRS_LEADING_MINUS,NUMPRS_NEG|NUMPRS_LEADING_MINUS,2,0,0);
1454 EXPECT2(0,FAILDIG);
1456 /* Without flag, doesn't consume trailing - */
1457 CONVERT("0-", 0);
1458 EXPECT(1,0,0,1,0,0);
1459 EXPECT2(0,FAILDIG);
1461 /* With flag, consumes trailing - */
1462 CONVERT("0-", NUMPRS_TRAILING_MINUS);
1463 EXPECT(1,NUMPRS_TRAILING_MINUS,NUMPRS_NEG|NUMPRS_TRAILING_MINUS,2,0,0);
1464 EXPECT2(0,FAILDIG);
1466 /* With leading flag, doesn't consume trailing - */
1467 CONVERT("-0-", NUMPRS_LEADING_MINUS);
1468 EXPECT(1,NUMPRS_LEADING_MINUS,NUMPRS_NEG|NUMPRS_LEADING_MINUS,2,0,0);
1469 EXPECT2(0,FAILDIG);
1471 /* Trailing - doesn't get consumed if we specify both (unlike whitespace) */
1472 CONVERT("-0-", NUMPRS_LEADING_MINUS|NUMPRS_TRAILING_MINUS);
1473 EXPECT(1,NUMPRS_LEADING_MINUS|NUMPRS_TRAILING_MINUS,NUMPRS_NEG|NUMPRS_LEADING_MINUS,2,0,0);
1474 EXPECT2(0,FAILDIG);
1476 /** NUMPRS_HEX_OCT **/
1478 /* Could be hex, octal or decimal - With flag reads as decimal */
1479 CONVERT("0", NUMPRS_HEX_OCT);
1480 EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
1481 EXPECT2(0,FAILDIG);
1483 /* Doesn't recognise hex in .asm syntax */
1484 CONVERT("0h", NUMPRS_HEX_OCT);
1485 EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
1486 EXPECT2(0,FAILDIG);
1488 /* Doesn't fail with valid leading string but no digits */
1489 CONVERT("0x", NUMPRS_HEX_OCT);
1490 EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
1491 EXPECT2(0,FAILDIG);
1493 /* Doesn't recognise hex format numbers at all! */
1494 CONVERT("0x0", NUMPRS_HEX_OCT);
1495 EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
1496 EXPECT2(0,FAILDIG);
1498 /* Doesn't recognise plain hex digits either */
1499 CONVERT("FE", NUMPRS_HEX_OCT);
1500 EXPECTFAIL;
1501 EXPECTRGB(0,FAILDIG);
1503 /* A leading 0 does not an octal number make */
1504 CONVERT("0100", NUMPRS_HEX_OCT);
1505 EXPECT(1,NUMPRS_HEX_OCT,0,4,0,2);
1506 EXPECTRGB(0,1);
1507 EXPECTRGB(1,0);
1508 EXPECTRGB(2,0);
1509 EXPECTRGB(3,FAILDIG);
1511 /* VB hex */
1512 CONVERT("&HF800", NUMPRS_HEX_OCT);
1513 EXPECT(4,NUMPRS_HEX_OCT,NUMPRS_HEX_OCT,6,4,0);
1514 EXPECTRGB(0,15);
1515 EXPECTRGB(1,8);
1516 EXPECTRGB(2,0);
1517 EXPECTRGB(3,0);
1518 EXPECTRGB(4,FAILDIG);
1520 /* VB hex lower case and leading zero */
1521 CONVERT("&h0abcdef", NUMPRS_HEX_OCT);
1522 EXPECT(6,NUMPRS_HEX_OCT,NUMPRS_HEX_OCT,9,4,0);
1523 EXPECTRGB(0,10);
1524 EXPECTRGB(1,11);
1525 EXPECTRGB(2,12);
1526 EXPECTRGB(3,13);
1527 EXPECTRGB(4,14);
1528 EXPECTRGB(5,15);
1529 EXPECTRGB(6,FAILDIG);
1531 /* VB oct */
1532 CONVERT("&O300", NUMPRS_HEX_OCT);
1533 EXPECT(3,NUMPRS_HEX_OCT,NUMPRS_HEX_OCT,5,3,0);
1534 EXPECTRGB(0,3);
1535 EXPECTRGB(1,0);
1536 EXPECTRGB(2,0);
1537 EXPECTRGB(3,FAILDIG);
1539 /* VB oct lower case and leading zero */
1540 CONVERT("&o0777", NUMPRS_HEX_OCT);
1541 EXPECT(3,NUMPRS_HEX_OCT,NUMPRS_HEX_OCT,6,3,0);
1542 EXPECTRGB(0,7);
1543 EXPECTRGB(1,7);
1544 EXPECTRGB(2,7);
1545 EXPECTRGB(3,FAILDIG);
1547 /* VB oct char bigger than 7 */
1548 CONVERT("&o128", NUMPRS_HEX_OCT);
1549 EXPECT(2,NUMPRS_HEX_OCT,NUMPRS_HEX_OCT,4,3,0);
1550 EXPECTRGB(0,1);
1551 EXPECTRGB(1,2);
1552 EXPECTRGB(3,FAILDIG);
1554 /* Only integers are allowed when using an alternative radix */
1555 CONVERT("&ha.2", NUMPRS_HEX_OCT|NUMPRS_DECIMAL);
1556 EXPECT(1,NUMPRS_HEX_OCT|NUMPRS_DECIMAL,NUMPRS_HEX_OCT,3,4,0);
1557 EXPECT2(10,FAILDIG);
1559 /* Except if it looks like a plain decimal number */
1560 CONVERT("01.2", NUMPRS_HEX_OCT|NUMPRS_DECIMAL);
1561 EXPECT(2,NUMPRS_HEX_OCT|NUMPRS_DECIMAL,NUMPRS_DECIMAL,4,0,-1);
1562 EXPECT2(1,2);
1563 EXPECTRGB(3,FAILDIG);
1565 /** NUMPRS_PARENS **/
1567 /* Empty parens = error */
1568 CONVERT("()", NUMPRS_PARENS);
1569 EXPECTFAIL;
1570 EXPECTRGB(0,FAILDIG);
1572 /* With flag, trailing parens not consumed */
1573 CONVERT("0()", NUMPRS_PARENS);
1574 EXPECT(1,NUMPRS_PARENS,0,1,0,0);
1575 EXPECT2(0,FAILDIG);
1577 /* With flag, Number in parens made negative and parens consumed */
1578 CONVERT("(0)", NUMPRS_PARENS);
1579 EXPECT(1,NUMPRS_PARENS,NUMPRS_NEG|NUMPRS_PARENS,3,0,0);
1580 EXPECT2(0,FAILDIG);
1582 /** NUMPRS_THOUSANDS **/
1584 /* With flag, thousands sep. not needed */
1585 CONVERT("0", NUMPRS_THOUSANDS);
1586 EXPECT(1,NUMPRS_THOUSANDS,0,1,0,0);
1587 EXPECT2(0,FAILDIG);
1589 /* Without flag stop at thousands separator */
1590 CONVERT("1,000", 0);
1591 EXPECT(1,0,0,1,0,0);
1592 EXPECT2(1,FAILDIG);
1594 /* With flag, thousands sep. and following digits consumed */
1595 CONVERT("1,000", NUMPRS_THOUSANDS);
1596 EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,3);
1597 EXPECTRGB(0,1);
1598 /* VarParseNumFromStr() may have added more digits to rgb but they are not
1599 * part of the returned value. So consider that an implementation detail.
1601 EXPECTRGB(4,FAILDIG);
1603 /* With flag, thousands sep. and following digits consumed */
1604 CONVERT("&h1,000", NUMPRS_HEX_OCT|NUMPRS_THOUSANDS);
1605 EXPECT(1,NUMPRS_HEX_OCT|NUMPRS_THOUSANDS,NUMPRS_HEX_OCT,3,4,0);
1606 EXPECTRGB(1,FAILDIG);
1608 /* With flag and decimal point, thousands sep. but not decimals consumed */
1609 CONVERT("1,001.0", NUMPRS_THOUSANDS);
1610 EXPECT(4,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,0);
1611 EXPECT2(1,0);
1612 EXPECTRGB(2,0);
1613 EXPECTRGB(3,1);
1614 EXPECTRGB(4,FAILDIG);
1616 /* With flag, consecutive thousands separators are allowed */
1617 CONVERT("1,,000", NUMPRS_THOUSANDS);
1618 EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,6,0,3);
1619 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
1620 EXPECTRGB(4,FAILDIG);
1622 /* With flag, thousands separators can be sprinkled at random */
1623 CONVERT("1,00,0,,", NUMPRS_THOUSANDS);
1624 EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,8,0,3);
1625 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
1626 EXPECTRGB(4,FAILDIG);
1628 /* With flag, but leading thousands separators are not allowed */
1629 CONVERT(",1,000", NUMPRS_THOUSANDS);
1630 EXPECTFAIL;
1632 /* With flag, thousands separator not needed but still reported */
1633 CONVERT("1,", NUMPRS_THOUSANDS);
1634 EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,2,0,0);
1635 EXPECT2(1,FAILDIG);
1637 /** NUMPRS_CURRENCY **/
1639 /* Without flag, chokes on currency sign */
1640 CONVERT("$11", 0);
1641 EXPECTFAIL;
1642 EXPECTRGB(0,FAILDIG);
1644 /* With flag, allows having no currency sign */
1645 CONVERT("11", NUMPRS_CURRENCY);
1646 EXPECT(2,NUMPRS_CURRENCY,0,2,0,0);
1647 EXPECT2(1,1);
1648 EXPECTRGB(2,FAILDIG);
1650 /* With flag, does not allow a lone currency sign */
1651 CONVERT("$", NUMPRS_CURRENCY);
1652 EXPECTFAIL;
1654 /* With flag, consumes currency sign */
1655 CONVERT("$11", NUMPRS_CURRENCY);
1656 EXPECT(2,NUMPRS_CURRENCY,NUMPRS_CURRENCY,3,0,0);
1657 EXPECT2(1,1);
1658 EXPECTRGB(2,FAILDIG);
1660 /* With flag, currency amounts cannot be in hexadecimal */
1661 CONVERT("$&ha", NUMPRS_HEX_OCT|NUMPRS_CURRENCY);
1662 EXPECTFAIL;
1664 CONVERT("&ha$", NUMPRS_HEX_OCT|NUMPRS_CURRENCY);
1665 EXPECT(1,NUMPRS_HEX_OCT|NUMPRS_CURRENCY,NUMPRS_HEX_OCT,3,4,0);
1666 EXPECTRGB(0,10);
1667 EXPECTRGB(1,FAILDIG);
1669 /* With flag, the sign cannot be repeated before the amount */
1670 CONVERT("$$11", NUMPRS_CURRENCY);
1671 EXPECTFAIL;
1673 /* With flag, but is allowed after the amount and can even be repeated! */
1674 CONVERT("$11$$", NUMPRS_CURRENCY|NUMPRS_USE_ALL);
1675 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_CURRENCY,5,0,0);
1676 EXPECT2(1,1);
1677 EXPECTRGB(2,FAILDIG);
1679 /* With flag, the British Pound is not allowed "1L" */
1680 WCONVERT(L"\x31\xa3", NUMPRS_CURRENCY|NUMPRS_USE_ALL);
1681 EXPECTFAIL;
1683 /* With flag, minus can go after the currency sign */
1684 CONVERT("$-11", NUMPRS_CURRENCY|NUMPRS_LEADING_MINUS);
1685 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_LEADING_MINUS,NUMPRS_CURRENCY|NUMPRS_LEADING_MINUS|NUMPRS_NEG,4,0,0);
1686 EXPECT2(1,1);
1687 EXPECTRGB(2,FAILDIG);
1689 /* With flag, or before */
1690 CONVERT("-$11", NUMPRS_CURRENCY|NUMPRS_LEADING_MINUS);
1691 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_LEADING_MINUS,NUMPRS_CURRENCY|NUMPRS_LEADING_MINUS|NUMPRS_NEG,4,0,0);
1692 EXPECT2(1,1);
1693 EXPECTRGB(2,FAILDIG);
1695 for (i = 0; i < ARRAY_SIZE(spaces)-1; i++)
1697 winetest_push_context("%d", i);
1699 /* With flag, no space is allowed after the currency sign */
1700 wsprintfW(wstr, L"$%c11", spaces[i]);
1701 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_USE_ALL);
1702 EXPECTFAIL;
1704 /* With flag, unless explicitly allowed before the digits */
1705 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_LEADING_WHITE);
1706 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_LEADING_WHITE,NUMPRS_CURRENCY|NUMPRS_LEADING_WHITE,4,0,0);
1707 EXPECT2(1,1);
1708 EXPECTRGB(2,FAILDIG);
1710 /* With flag, no space is allowed before the trailing currency sign */
1711 wsprintfW(wstr, L"11%c$", spaces[i]);
1712 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_USE_ALL);
1713 EXPECTFAIL;
1715 /* With flag, even with thousands flag (see the French situation) */
1716 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_USE_ALL);
1717 EXPECTFAIL;
1719 /* With flag, unless explicitly allowed */
1720 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_TRAILING_WHITE|NUMPRS_USE_ALL);
1721 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_TRAILING_WHITE|NUMPRS_USE_ALL,NUMPRS_CURRENCY|NUMPRS_TRAILING_WHITE,4,0,0);
1722 EXPECT2(1,1);
1723 EXPECTRGB(2,FAILDIG);
1725 winetest_pop_context();
1728 /* With flag only, doesn't consume decimal point */
1729 CONVERT("$11.1", NUMPRS_CURRENCY);
1730 EXPECT(2,NUMPRS_CURRENCY,NUMPRS_CURRENCY,3,0,0);
1731 EXPECT2(1,1);
1732 EXPECTRGB(2,FAILDIG);
1734 /* With flag and decimal flag, consumes decimal point and following digits */
1735 CONVERT("$11.1", NUMPRS_CURRENCY|NUMPRS_DECIMAL);
1736 EXPECT(3,NUMPRS_CURRENCY|NUMPRS_DECIMAL,NUMPRS_CURRENCY|NUMPRS_DECIMAL,5,0,-1);
1737 EXPECT2(1,1);
1738 EXPECTRGB(2,1);
1739 EXPECTRGB(3,FAILDIG);
1741 /* With flag, the currency cannot replace the decimal sign (see comment about
1742 * the Cape Verdean escudo).
1744 CONVERT("1$99", NUMPRS_CURRENCY|NUMPRS_DECIMAL);
1745 EXPECT(1,NUMPRS_CURRENCY|NUMPRS_DECIMAL,NUMPRS_CURRENCY,2,0,0);
1746 EXPECT2(1,FAILDIG);
1748 /* Thousands flag can also be used with currency */
1749 CONVERT("$1,234", NUMPRS_CURRENCY|NUMPRS_THOUSANDS);
1750 EXPECT(4,NUMPRS_CURRENCY|NUMPRS_THOUSANDS,NUMPRS_CURRENCY|NUMPRS_THOUSANDS,6,0,0);
1751 EXPECT2(1,2);
1752 EXPECTRGB(2,3);
1753 EXPECTRGB(3,4);
1754 EXPECTRGB(4,FAILDIG);
1756 /* Thousands flag can also be used with currency and decimal numbers */
1757 CONVERT("$1,234.5", NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_DECIMAL);
1758 EXPECT(5,NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_DECIMAL,NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_DECIMAL,8,0,-1);
1759 EXPECT2(1,2);
1760 EXPECTRGB(2,3);
1761 EXPECTRGB(3,4);
1762 EXPECTRGB(4,5);
1763 EXPECTRGB(5,FAILDIG);
1765 /** NUMPRS_DECIMAL **/
1767 /* With flag, consumes decimal point */
1768 CONVERT("1.1", NUMPRS_DECIMAL);
1769 EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL,3,0,-1);
1770 EXPECT2(1,1);
1771 EXPECTRGB(2,FAILDIG);
1773 /* With flag, consumes decimal point. Skipping the decimal part is not an error */
1774 CONVERT("1.", NUMPRS_DECIMAL);
1775 EXPECT(1,NUMPRS_DECIMAL,NUMPRS_DECIMAL,2,0,0);
1776 EXPECT2(1,FAILDIG);
1778 /* Skipping the integer part is not an error */
1779 CONVERT(".2", NUMPRS_DECIMAL);
1780 EXPECT(1,NUMPRS_DECIMAL,NUMPRS_DECIMAL,2,0,-1);
1781 EXPECT2(2,FAILDIG);
1783 /* Even zero gets an exponent (it sort of indicates 'precision') */
1784 CONVERT(".0", NUMPRS_DECIMAL);
1785 EXPECT(1,NUMPRS_DECIMAL,NUMPRS_DECIMAL,2,0,-1);
1786 EXPECT2(0,FAILDIG);
1788 CONVERT(".000", NUMPRS_DECIMAL);
1789 EXPECT(1,NUMPRS_DECIMAL,NUMPRS_DECIMAL,4,0,-3);
1790 EXPECTRGB(0,0);
1791 EXPECTRGB(3,FAILDIG);
1793 CONVERT("$.02", NUMPRS_CURRENCY|NUMPRS_DECIMAL);
1794 EXPECT(1,NUMPRS_CURRENCY|NUMPRS_DECIMAL,NUMPRS_CURRENCY|NUMPRS_DECIMAL,4,0,-2);
1795 EXPECT2(2,FAILDIG);
1797 CONVERT(".001", NUMPRS_DECIMAL);
1798 EXPECT(1,NUMPRS_DECIMAL,NUMPRS_DECIMAL,4,0,-3);
1799 EXPECT2(1,FAILDIG);
1801 CONVERT(".101", NUMPRS_DECIMAL);
1802 EXPECT(3,NUMPRS_DECIMAL,NUMPRS_DECIMAL,4,0,-3);
1803 EXPECT2(1,0);
1804 EXPECTRGB(2,1);
1805 EXPECTRGB(3,FAILDIG);
1807 CONVERT(".30", NUMPRS_DECIMAL);
1808 EXPECT(1,NUMPRS_DECIMAL,NUMPRS_DECIMAL,3,0,-1);
1809 /* See the NUMPRS_THOUSANDS comment about trailing zeroes */
1810 EXPECTRGB(0,3);
1811 EXPECTRGB(2,FAILDIG);
1813 /* But skipping both the integer and decimal part is not allowed */
1814 CONVERT(".", NUMPRS_DECIMAL);
1815 EXPECTFAIL;
1817 /* Consumes only one decimal point */
1818 CONVERT("1.1.", NUMPRS_DECIMAL);
1819 EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL,3,0,-1);
1820 EXPECT2(1,1);
1821 EXPECTRGB(2,FAILDIG);
1823 /* With flag, including if they are consecutive */
1824 CONVERT("1..1", NUMPRS_DECIMAL);
1825 EXPECT(1,NUMPRS_DECIMAL,NUMPRS_DECIMAL,2,0,0);
1826 EXPECT2(1,FAILDIG);
1828 /** NUMPRS_EXPONENT **/
1830 /* Without flag, doesn't consume exponent */
1831 CONVERT("1e1", 0);
1832 EXPECT(1,0,0,1,0,0);
1833 EXPECT2(1,FAILDIG);
1835 /* With flag, consumes exponent */
1836 CONVERT("1e1", NUMPRS_EXPONENT);
1837 EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,3,0,1);
1838 EXPECT2(1,FAILDIG);
1840 /* With flag, incompatible with NUMPRS_HEX_OCT */
1841 CONVERT("&o1e1", NUMPRS_HEX_OCT|NUMPRS_EXPONENT);
1842 EXPECT(1,NUMPRS_HEX_OCT|NUMPRS_EXPONENT,NUMPRS_HEX_OCT,3,3,0);
1843 EXPECT2(1,FAILDIG);
1845 /* With flag, even if it sort of looks like an exponent */
1846 CONVERT("&h1e2", NUMPRS_HEX_OCT|NUMPRS_EXPONENT);
1847 EXPECT(3,NUMPRS_HEX_OCT|NUMPRS_EXPONENT,NUMPRS_HEX_OCT,5,4,0);
1848 EXPECT2(1,0xe);
1849 EXPECTRGB(2,2);
1850 EXPECTRGB(3,FAILDIG);
1852 /* Negative exponents are accepted without flags */
1853 CONVERT("1e-1", NUMPRS_EXPONENT);
1854 EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,4,0,-1);
1855 EXPECT2(1,FAILDIG);
1857 /* As are positive exponents and leading exponent 0s */
1858 CONVERT("1e+01", NUMPRS_EXPONENT);
1859 EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,5,0,1);
1860 EXPECT2(1,FAILDIG);
1862 /* The same for zero exponents */
1863 CONVERT("1e0", NUMPRS_EXPONENT);
1864 EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,3,0,0);
1865 EXPECT2(1,FAILDIG);
1867 /* Sign on a zero exponent doesn't matter */
1868 CONVERT("1e+0", NUMPRS_EXPONENT);
1869 EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,4,0,0);
1870 EXPECT2(1,FAILDIG);
1872 CONVERT("1e-0", NUMPRS_EXPONENT);
1873 EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,4,0,0);
1874 EXPECT2(1,FAILDIG);
1876 /* Doesn't consume a real number exponent */
1877 CONVERT("1e1.", NUMPRS_EXPONENT);
1878 EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,3,0,1);
1879 EXPECT2(1,FAILDIG);
1881 /* Powers of 10 are calculated from the position of any decimal point */
1882 CONVERT("1.5e20", NUMPRS_EXPONENT|NUMPRS_DECIMAL);
1883 EXPECT(2,NUMPRS_EXPONENT|NUMPRS_DECIMAL,NUMPRS_EXPONENT|NUMPRS_DECIMAL,6,0,19);
1884 EXPECT2(1,5);
1886 CONVERT("1.5e-20", NUMPRS_EXPONENT|NUMPRS_DECIMAL);
1887 EXPECT(2,NUMPRS_EXPONENT|NUMPRS_DECIMAL,NUMPRS_EXPONENT|NUMPRS_DECIMAL,7,0,-21);
1888 EXPECT2(1,5);
1890 /** NUMPRS_USE_ALL **/
1892 /* Flag expects all digits */
1893 CONVERT("0", NUMPRS_USE_ALL);
1894 EXPECT(1,NUMPRS_USE_ALL,0,1,0,0);
1895 EXPECT2(0,FAILDIG);
1897 /* Rejects anything trailing */
1898 CONVERT("0 ", NUMPRS_USE_ALL);
1899 EXPECTFAIL;
1900 EXPECT2(0,FAILDIG);
1902 /* Unless consumed by trailing flag */
1903 CONVERT("0 ", NUMPRS_USE_ALL|NUMPRS_TRAILING_WHITE);
1904 EXPECT(1,NUMPRS_USE_ALL|NUMPRS_TRAILING_WHITE,NUMPRS_TRAILING_WHITE,2,0,0);
1905 EXPECT2(0,FAILDIG);
1907 /** Combinations **/
1909 /* Leading whitespace and plus, doesn't consume trailing whitespace */
1910 CONVERT("+ 0 ", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
1911 EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,3,0,0);
1912 EXPECT2(0,FAILDIG);
1914 /* Order of whitespace and plus is unimportant */
1915 CONVERT(" +0", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
1916 EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,3,0,0);
1917 EXPECT2(0,FAILDIG);
1919 /* Leading whitespace can be repeated */
1920 CONVERT(" + 0", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
1921 EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,4,0,0);
1922 EXPECT2(0,FAILDIG);
1924 /* But plus/minus etc. cannot */
1925 CONVERT("+ +0", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
1926 EXPECTFAIL;
1927 EXPECTRGB(0,FAILDIG);
1929 /* Inexact is not set if trailing zeros are removed */
1930 CONVERTN("10", 1, 0);
1931 EXPECT(1,0,0,2,0,1);
1932 EXPECT2(1,FAILDIG);
1934 /* Make sure a leading 0 is stripped but decimals after it get read */
1935 CONVERT("-0.51", NUMPRS_STD);
1936 EXPECT(2,NUMPRS_STD,NUMPRS_NEG|NUMPRS_DECIMAL|NUMPRS_LEADING_MINUS,5,0,-2);
1937 EXPECT2(5,1);
1939 /* Keep trailing zeros on whole number part of a decimal */
1940 CONVERT("10.1", NUMPRS_STD);
1941 EXPECT(3,NUMPRS_STD,NUMPRS_DECIMAL,4,0,-1);
1942 EXPECT2(1,0);
1943 EXPECTRGB(2,1);
1945 /* Zeros after decimal sign */
1946 CONVERT("0.01", NUMPRS_STD);
1947 EXPECT(1,NUMPRS_STD,NUMPRS_DECIMAL,4,0,-2);
1948 EXPECT2(1,FAILDIG);
1950 /* Trailing zeros after decimal part */
1951 CONVERT("0.10", NUMPRS_STD);
1952 EXPECT(1,NUMPRS_STD,NUMPRS_DECIMAL,4,0,-1);
1953 EXPECT2(1,0);
1955 /* Arabic numerals are not allowed "0" */
1956 WCONVERT(L"\x660", NUMPRS_STD);
1957 EXPECTFAIL;
1960 static void test_VarParseNumFromStrFr(void)
1962 HRESULT hres;
1963 /* Test some aspects that are different in a non-English locale */
1964 LCID lcid = MAKELCID(MAKELANGID(LANG_FRENCH,SUBLANG_FRENCH),SORT_DEFAULT);
1965 NUMPARSE np;
1966 BYTE rgb[128];
1967 OLECHAR wstr[128];
1968 OLECHAR spaces[] = L" \xa0\f\n\r\t\v"; /* man isspace() */
1969 int i;
1971 CHECKPTR(VarParseNumFromStr);
1973 /** White spaces **/
1975 for (i = 0; i < ARRAY_SIZE(spaces)-1; i++)
1977 winetest_push_context("%d", i);
1979 /* Leading spaces must be explicitly allowed */
1980 wsprintfW(wstr, L"%c2", spaces[i]);
1981 WCONVERT(wstr, NUMPRS_USE_ALL);
1982 EXPECTFAIL;
1984 WCONVERT(wstr, NUMPRS_LEADING_WHITE|NUMPRS_USE_ALL);
1985 EXPECT(1,NUMPRS_LEADING_WHITE|NUMPRS_USE_ALL,NUMPRS_LEADING_WHITE,2,0,0);
1986 EXPECT2(2,FAILDIG);
1988 /* But trailing spaces... */
1989 wsprintfW(wstr, L"3%c", spaces[i]);
1990 WCONVERT(wstr, NUMPRS_TRAILING_WHITE|NUMPRS_USE_ALL);
1991 if (spaces[i] == ' ' || spaces[i] == 0xa0 /* non-breaking space */)
1993 /* Spaces aliased to the thousands separator are never allowed! */
1994 EXPECTFAIL;
1996 else
1998 /* The others behave normally */
1999 EXPECT(1,NUMPRS_TRAILING_WHITE|NUMPRS_USE_ALL,NUMPRS_TRAILING_WHITE,2,0,0);
2000 EXPECT2(3,FAILDIG);
2003 WCONVERT(wstr, NUMPRS_THOUSANDS|NUMPRS_USE_ALL);
2004 if (spaces[i] == ' ' || spaces[i] == 0xa0 /* non-breaking space */)
2006 /* Trailing thousands separators are allowed as usual */
2007 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,2,0,0);
2008 EXPECT2(3,FAILDIG);
2010 else
2012 /* But not other spaces */
2013 EXPECTFAIL;
2016 winetest_pop_context();
2020 /** NUMPRS_PARENS **/
2022 /* With flag, Number in parens made negative and parens consumed */
2023 CONVERT("(0)", NUMPRS_PARENS);
2024 EXPECT(1,NUMPRS_PARENS,NUMPRS_NEG|NUMPRS_PARENS,3,0,0);
2025 EXPECT2(0,FAILDIG);
2027 /** NUMPRS_THOUSANDS **/
2029 for (i = 0; i < ARRAY_SIZE(spaces)-1; i++)
2031 winetest_push_context("%d", i);
2033 /* With flag, thousands separator and following digits consumed */
2034 wsprintfW(wstr, L"1%c000", spaces[i]);
2035 WCONVERT(wstr, NUMPRS_THOUSANDS|NUMPRS_USE_ALL);
2036 if (spaces[i] == ' ' || spaces[i] == 0xa0 /* non-breaking space */)
2038 /* Non-breaking space and regular spaces work */
2039 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,5,0,3);
2040 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2041 EXPECTRGB(4,FAILDIG);
2043 else
2045 /* But not other spaces */
2046 EXPECTFAIL;
2049 winetest_pop_context();
2052 /* With flag and decimal point, thousands sep. but not decimals consumed */
2053 CONVERT("1 001,0", NUMPRS_THOUSANDS);
2054 EXPECT(4,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,0);
2055 EXPECT2(1,0);
2056 EXPECTRGB(2,0);
2057 EXPECTRGB(3,1);
2058 EXPECTRGB(4,FAILDIG);
2060 /* With flag, consecutive thousands separators are allowed */
2061 CONVERT("1 000", NUMPRS_THOUSANDS|NUMPRS_USE_ALL);
2062 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,6,0,3);
2063 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2064 EXPECTRGB(4,FAILDIG);
2066 /* With flag, thousands separators can be sprinkled at random */
2067 CONVERT("1 00 0 ", NUMPRS_THOUSANDS|NUMPRS_USE_ALL);
2068 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,8,0,3);
2069 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2070 EXPECTRGB(4,FAILDIG);
2072 /* With flag, but leading thousands separators are not allowed */
2073 CONVERT(" 1 000", NUMPRS_THOUSANDS);
2074 EXPECTFAIL;
2076 /* With flag, thousands separator not needed but still reported */
2077 CONVERT("1 ", NUMPRS_THOUSANDS|NUMPRS_USE_ALL);
2078 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,2,0,0);
2079 EXPECT2(1,FAILDIG);
2082 /** NUMPRS_CURRENCY **/
2084 /* With flag, consumes currency sign "E12" */
2085 WCONVERT(L"\x20ac\x31\x32", NUMPRS_CURRENCY);
2086 EXPECT(2,NUMPRS_CURRENCY,NUMPRS_CURRENCY,3,0,0);
2087 EXPECT2(1,2);
2088 EXPECTRGB(2,FAILDIG);
2090 /* With flag, consumes all currency signs! "E12EE" */
2091 WCONVERT(L"\x20ac\x31\x32\x20ac\x20ac", NUMPRS_CURRENCY|NUMPRS_USE_ALL);
2092 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_CURRENCY,5,0,0);
2093 EXPECT2(1,2);
2094 EXPECTRGB(2,FAILDIG);
2096 /* The presence of a trailing currency sign changes nothing for spaces */
2097 for (i = 0; i < ARRAY_SIZE(spaces)-1; i++)
2099 winetest_push_context("%d", i);
2101 /* With flag, no space is allowed before the currency sign "12 E" */
2102 wsprintfW(wstr, L"12%c\x20ac", spaces[i]);
2103 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_USE_ALL);
2104 EXPECTFAIL;
2106 /* With flag, even if explicitly allowed "12 E" */
2107 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_TRAILING_WHITE|NUMPRS_USE_ALL);
2108 if (spaces[i] == ' ' || spaces[i] == 0xa0 /* non-breaking space */)
2110 /* Spaces aliased to thousands separator are never allowed! */
2111 EXPECTFAIL;
2113 else
2115 /* The others behave normally */
2116 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_TRAILING_WHITE|NUMPRS_USE_ALL,NUMPRS_CURRENCY|NUMPRS_TRAILING_WHITE,4,0,0);
2117 EXPECT2(1,2);
2118 EXPECTRGB(2,FAILDIG);
2121 WCONVERT(wstr, NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_USE_ALL);
2122 if (spaces[i] == ' ' || spaces[i] == 0xa0 /* non-breaking space */)
2124 /* Spaces aliased to thousands separator are never allowed! */
2125 EXPECT(2,NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_USE_ALL,NUMPRS_CURRENCY|NUMPRS_THOUSANDS,4,0,0);
2126 EXPECT2(1,2);
2127 EXPECTRGB(2,FAILDIG);
2129 else
2131 /* The others behave normally */
2132 EXPECTFAIL;
2135 winetest_pop_context();
2138 /* With flag only, doesn't consume decimal point */
2139 WCONVERT(L"12,1\x20ac", NUMPRS_CURRENCY);
2140 EXPECT(2,NUMPRS_CURRENCY,0,2,0,0);
2141 EXPECT2(1,2);
2142 EXPECTRGB(2,FAILDIG);
2144 /* With flag and decimal flag, consumes decimal point and following digits */
2145 WCONVERT(L"12,1\x20ac", NUMPRS_CURRENCY|NUMPRS_DECIMAL|NUMPRS_USE_ALL);
2146 EXPECT(3,NUMPRS_CURRENCY|NUMPRS_DECIMAL|NUMPRS_USE_ALL,NUMPRS_CURRENCY|NUMPRS_DECIMAL,5,0,-1);
2147 EXPECT2(1,2);
2148 EXPECTRGB(2,1);
2149 EXPECTRGB(3,FAILDIG);
2151 /* Thousands flag can also be used with currency */
2152 WCONVERT(L"1 234,5 \x20ac", NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_USE_ALL);
2153 EXPECT(5,NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_USE_ALL,NUMPRS_CURRENCY|NUMPRS_THOUSANDS|NUMPRS_DECIMAL,9,0,-1);
2154 EXPECT2(1,2);
2155 EXPECTRGB(2,3);
2156 EXPECTRGB(3,4);
2157 EXPECTRGB(4,5);
2158 EXPECTRGB(5,FAILDIG);
2161 /** NUMPRS_DECIMAL **/
2163 /* With flag, consumes decimal point */
2164 CONVERT("1,2", NUMPRS_DECIMAL);
2165 EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL,3,0,-1);
2166 EXPECT2(1,2);
2167 EXPECTRGB(2,FAILDIG);
2169 /* With flag, but not regular point */
2170 CONVERT("1.2", NUMPRS_DECIMAL);
2171 EXPECT(1,NUMPRS_DECIMAL,0,1,0,0);
2172 EXPECT2(1,FAILDIG);
2174 /* The integer part can still be omitted */
2175 CONVERT(",2", NUMPRS_DECIMAL);
2176 EXPECT(1,NUMPRS_DECIMAL,NUMPRS_DECIMAL,2,0,-1);
2177 EXPECT2(2,FAILDIG);
2179 CONVERT(".2", NUMPRS_DECIMAL);
2180 EXPECTFAIL;
2183 static void test_VarParseNumFromStrMisc(void)
2185 HRESULT hres;
2186 LCID lcid;
2187 NUMPARSE np;
2188 BYTE rgb[128];
2189 OLECHAR currency[8], t1000[8], mont1000[8], dec[8], mondec[8];
2191 CHECKPTR(VarParseNumFromStr);
2193 /* Customize the regional settings to perform extra tests */
2195 if (GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, currency, ARRAY_SIZE(currency)) &&
2196 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, t1000, ARRAY_SIZE(t1000)) &&
2197 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, mont1000, ARRAY_SIZE(mont1000)) &&
2198 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, dec, ARRAY_SIZE(dec)) &&
2199 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, mondec, ARRAY_SIZE(mondec)))
2201 /* Start from a known configuration */
2202 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, L"$");
2203 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L",");
2204 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L",");
2205 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, L".");
2206 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L".");
2208 /* SCURRENCY defaults to '$' */
2209 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, L"");
2210 hres = wconvert_str(L"$1", ARRAY_SIZE(rgb), NUMPRS_CURRENCY, &np, rgb, LOCALE_USER_DEFAULT, 0);
2211 EXPECT(1,NUMPRS_CURRENCY,NUMPRS_CURRENCY,2,0,0);
2212 EXPECT2(1,FAILDIG);
2213 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, L"$");
2215 /* STHOUSAND has no default */
2216 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L"~");
2217 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L"");
2218 hres = wconvert_str(L"1,000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2219 EXPECTFAIL;
2220 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L"~");
2222 /* But SMONTHOUSANDSEP defaults to ','! */
2223 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L"");
2224 hres = wconvert_str(L"$1,000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY, &np, rgb, LOCALE_USER_DEFAULT, 0);
2225 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,6,0,3);
2226 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2227 EXPECTRGB(4,FAILDIG);
2228 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L",");
2229 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L",");
2231 /* SDECIMAL defaults to '.' */
2232 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L"~");
2233 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, L"");
2234 hres = wconvert_str(L"4.2", ARRAY_SIZE(rgb), NUMPRS_DECIMAL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2235 EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL,3,0,-1);
2236 EXPECT2(4,2);
2237 EXPECTRGB(2,FAILDIG);
2238 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, L"~");
2240 /* But SMONDECIMALSEP has no default! */
2241 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L"");
2242 hres = wconvert_str(L"3.9", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2243 EXPECTFAIL;
2244 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, L".");
2245 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L".");
2247 /* Non-breaking spaces are not allowed if sThousand is a regular space */
2248 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L" ");
2250 hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS, &np, rgb, LOCALE_USER_DEFAULT, 0);
2251 EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,3);
2252 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2253 EXPECTRGB(4,FAILDIG);
2255 hres = wconvert_str(L"1\xa0\x30\x30\x30", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2256 EXPECTFAIL;
2259 /* Show that NUMPRS_THOUSANDS activates sThousand and that
2260 * NUMPRS_THOUSANDS+NUMPRS_CURRENCY activates sMonThousandSep
2261 * whether a currency sign is present or not. Also the presence of
2262 * sMonThousandSep flags the value as being a currency.
2264 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L"|");
2265 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L" ");
2267 hres = wconvert_str(L"1|000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS, &np, rgb, LOCALE_USER_DEFAULT, 0);
2268 EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,3);
2269 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2270 EXPECTRGB(4,FAILDIG);
2272 hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2273 EXPECTFAIL;
2275 hres = wconvert_str(L"1|000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY, &np, rgb, LOCALE_USER_DEFAULT, 0);
2276 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,NUMPRS_THOUSANDS,5,0,3);
2277 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2278 EXPECTRGB(4,FAILDIG);
2280 hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2281 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,5,0,3);
2282 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2283 EXPECTRGB(4,FAILDIG);
2286 /* Leading sMonThousandSep are not allowed (same as sThousand) */
2287 hres = wconvert_str(L" 1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2288 EXPECTFAIL;
2290 /* But trailing ones are allowed (same as sThousand) */
2291 hres = wconvert_str(L"1 000 ", 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|NUMPRS_CURRENCY,6,0,3);
2293 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2294 EXPECTRGB(4,FAILDIG);
2296 /* And they break NUMPRS_TRAILING_WHITE (same as sThousand) */
2297 hres = wconvert_str(L"1000 ", ARRAY_SIZE(rgb), NUMPRS_TRAILING_WHITE|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2298 EXPECTFAIL;
2301 /* NUMPRS_CURRENCY is not enough for sMonThousandSep */
2302 hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2303 EXPECTFAIL;
2306 /* Even with a currency sign, the regular thousands separator works */
2307 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, L"$");
2308 /* Make sure SMONDECIMALSEP is not the currency sign (see the
2309 * Cape Verdean escudo comment).
2311 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L"/");
2312 hres = wconvert_str(L"$1|000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2313 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,6,0,3);
2314 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2315 EXPECTRGB(4,FAILDIG);
2317 /* Mixing both thousands separators is allowed */
2318 hres = wconvert_str(L"1 000|000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2319 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,9,0,6);
2320 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2321 EXPECTRGB(7,FAILDIG);
2324 /* SMONTHOUSANDSEP does not consider regular spaces to be equivalent to
2325 * non-breaking spaces!
2327 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L"\xa0");
2328 hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2329 EXPECTFAIL;
2331 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L"\xa0");
2332 hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2333 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,5,0,3);
2334 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2335 EXPECTRGB(4,FAILDIG);
2338 /* Regular thousands separators also have precedence over the currency ones */
2339 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);
2340 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,5,0,3);
2341 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2342 EXPECTRGB(4,FAILDIG);
2345 /* Show that the decimal separator masks the thousands one in all
2346 * positions, sometimes even without NUMPRS_DECIMAL.
2348 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L",");
2349 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L"~");
2350 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, L",");
2351 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L"~");
2353 hres = wconvert_str(L",1", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_DECIMAL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2354 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_DECIMAL,NUMPRS_DECIMAL,2,0,-1);
2355 EXPECT2(1,FAILDIG);
2357 hres = wconvert_str(L"1,000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2358 EXPECTFAIL;
2360 hres = wconvert_str(L"1,", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2361 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_USE_ALL,NUMPRS_DECIMAL,2,0,0);
2362 EXPECT2(1,FAILDIG);
2364 /* But not for their monetary equivalents */
2365 hres = wconvert_str(L"~1", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_CURRENCY, &np, rgb, LOCALE_USER_DEFAULT, 0);
2366 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_CURRENCY,NUMPRS_DECIMAL|NUMPRS_CURRENCY,2,0,-1);
2367 EXPECT2(1,FAILDIG);
2369 hres = wconvert_str(L"1~", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2370 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,2,0,0);
2371 EXPECT2(1,FAILDIG);
2374 /* Only the first sThousand character is used (sigh of relief) */
2375 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, L" \xa0");
2376 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, L" \xa0");
2378 hres = wconvert_str(L"1 000", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2379 EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_USE_ALL,NUMPRS_THOUSANDS,5,0,3);
2380 EXPECTRGB(0,1); /* Don't test extra digits, see "1,000" test */
2381 EXPECTRGB(4,FAILDIG);
2383 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);
2384 EXPECTFAIL;
2386 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);
2387 EXPECTFAIL;
2390 /* Show that the currency decimal separator is active even without
2391 * NUMPRS_CURRENCY.
2393 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, L".");
2394 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L",");
2396 hres = wconvert_str(L"1.2", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2397 EXPECT(2,NUMPRS_DECIMAL|NUMPRS_USE_ALL,NUMPRS_DECIMAL,3,0,-1);
2398 EXPECT2(1,2);
2399 EXPECTRGB(2,FAILDIG);
2401 hres = wconvert_str(L"1,2", ARRAY_SIZE(rgb), NUMPRS_DECIMAL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2402 EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL|NUMPRS_CURRENCY,3,0,-1);
2403 EXPECT2(1,2);
2404 EXPECTRGB(2,FAILDIG);
2406 hres = wconvert_str(L"1.2", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2407 EXPECT(2,NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_DECIMAL,3,0,-1);
2408 EXPECT2(1,2);
2409 EXPECTRGB(2,FAILDIG);
2411 hres = wconvert_str(L"1,2", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2412 EXPECT(2,NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_DECIMAL|NUMPRS_CURRENCY,3,0,-1);
2413 EXPECT2(1,2);
2414 EXPECTRGB(2,FAILDIG);
2416 hres = wconvert_str(L"1.2,3", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_CURRENCY, &np, rgb, LOCALE_USER_DEFAULT, 0);
2417 EXPECT(2,NUMPRS_DECIMAL|NUMPRS_CURRENCY,NUMPRS_DECIMAL,3,0,-1);
2418 EXPECT2(1,2);
2419 EXPECTRGB(2,FAILDIG);
2421 hres = wconvert_str(L"1,2.3", ARRAY_SIZE(rgb), NUMPRS_DECIMAL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2422 EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL|NUMPRS_CURRENCY,3,0,-1);
2423 EXPECT2(1,2);
2424 EXPECTRGB(2,FAILDIG);
2427 /* In some locales the decimal separator is the currency sign.
2428 * For instance the Cape Verdean escudo.
2430 SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L"$");
2431 hres = wconvert_str(L"1$99", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
2432 EXPECT(3,NUMPRS_DECIMAL|NUMPRS_USE_ALL,NUMPRS_DECIMAL|NUMPRS_CURRENCY,4,0,-2);
2433 EXPECT2(1,9);
2434 EXPECTRGB(2,9);
2435 EXPECTRGB(3,FAILDIG);
2438 /* Restore all the settings */
2439 ok(SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SCURRENCY, currency), "Restoring SCURRENCY failed\n");
2440 ok(SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, t1000), "Restoring STHOUSAND failed\n");
2441 ok(SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, mont1000), "Restoring SMONTHOUSANDSEP failed\n");
2442 ok(SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, dec), "Restoring SDECIMAL failed\n");
2443 ok(SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, mondec), "Restoring SMONDECIMALSEP failed\n");
2447 /* Test currencies of various lengths */
2449 /* 2 Polish zloty */
2450 lcid = MAKELCID(MAKELANGID(LANG_POLISH,SUBLANG_POLISH_POLAND),SORT_DEFAULT);
2451 WCONVERT(L"z\x142\x32", NUMPRS_CURRENCY|NUMPRS_USE_ALL);
2452 EXPECT(1,NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_CURRENCY,3,0,0);
2453 EXPECT2(2,FAILDIG);
2455 /* Multi-character currencies can be repeated too "zl2zlzl" */
2456 WCONVERT(L"z\x142\x32z\x142z\x142", NUMPRS_CURRENCY|NUMPRS_USE_ALL);
2457 EXPECT(1,NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_CURRENCY,7,0,0);
2458 EXPECT2(2,FAILDIG);
2460 lcid = MAKELCID(MAKELANGID(LANG_FRENCH,SUBLANG_FRENCH_SWISS),SORT_DEFAULT);
2461 WCONVERT(L"3CHF", NUMPRS_CURRENCY|NUMPRS_USE_ALL);
2462 /* Windows <= 8.1 uses an old currency symbol: "fr. 5" */
2463 todo_wine ok(hres == S_OK || broken(hres == DISP_E_TYPEMISMATCH), "returned %08x\n", hres);
2464 if (hres == S_OK)
2466 todo_wine EXPECT(1,NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_CURRENCY,4,0,0);
2467 EXPECT2(3,FAILDIG);
2470 /* 5 Moroccan dirham */
2471 lcid = MAKELCID(MAKELANGID(LANG_ARABIC,SUBLANG_ARABIC_MOROCCO),SORT_DEFAULT);
2472 WCONVERT(L"5\x62f.\x645.\x200f", NUMPRS_CURRENCY|NUMPRS_USE_ALL);
2473 /* Windows 8.1 incorrectly doubles the right-to-left mark:
2474 * "\x62f.\x645.\x200f\x200f 5"
2476 ok(hres == S_OK || broken(hres == DISP_E_TYPEMISMATCH), "returned %08x\n", hres);
2477 if (hres == S_OK)
2479 EXPECT(1,NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_CURRENCY,6,0,0);
2480 EXPECT2(5,FAILDIG);
2484 /* Test Arabic numerals in an Arabic locale */
2486 lcid = MAKELCID(MAKELANGID(LANG_ARABIC,SUBLANG_ARABIC_MOROCCO),SORT_DEFAULT);
2487 WCONVERT(L"\x660", NUMPRS_STD);
2488 EXPECTFAIL;
2491 static HRESULT (WINAPI *pVarNumFromParseNum)(NUMPARSE*,BYTE*,ULONG,VARIANT*);
2493 /* Macros for converting and testing the result of VarNumFromParseNum */
2494 #define SETRGB(indx,val) if (!indx) memset(rgb, FAILDIG, sizeof(rgb)); rgb[indx] = val
2495 #undef CONVERT
2496 #define CONVERT(a,b,c,d,e,f,bits) \
2497 np.cDig = (a); np.dwInFlags = (b); np.dwOutFlags = (c); np.cchUsed = (d); \
2498 np.nBaseShift = (e); np.nPwr10 = (f); hres = pVarNumFromParseNum(&np, rgb, bits, &vOut)
2499 static const char *szFailOverflow = "Expected overflow, hres = %08x\n";
2500 #define EXPECT_OVERFLOW ok(hres == DISP_E_OVERFLOW, szFailOverflow, hres)
2501 static const char *szFailOk = "Call failed, hres = %08x\n";
2502 #define EXPECT_OK ok(hres == S_OK, szFailOk, hres); \
2503 if (hres == S_OK)
2504 #define EXPECT_TYPE(typ) ok(V_VT(&vOut) == typ,"Expected Type = " #typ ", got %d\n", V_VT(&vOut))
2505 #define EXPECT_I1(val) EXPECT_OK { EXPECT_TYPE(VT_I1); \
2506 ok(V_I1(&vOut) == val, "Expected i1 = %d, got %d\n", (signed char)val, V_I1(&vOut)); }
2507 #define EXPECT_UI1(val) EXPECT_OK { EXPECT_TYPE(VT_UI1); \
2508 ok(V_UI1(&vOut) == val, "Expected ui1 = %d, got %d\n", (BYTE)val, V_UI1(&vOut)); }
2509 #define EXPECT_I2(val) EXPECT_OK { EXPECT_TYPE(VT_I2); \
2510 ok(V_I2(&vOut) == val, "Expected i2 = %d, got %d\n", (SHORT)val, V_I2(&vOut)); }
2511 #define EXPECT_UI2(val) EXPECT_OK { EXPECT_TYPE(VT_UI2); \
2512 ok(V_UI2(&vOut) == val, "Expected ui2 = %d, got %d\n", (USHORT)val, V_UI2(&vOut)); }
2513 #define EXPECT_I4(val) EXPECT_OK { EXPECT_TYPE(VT_I4); \
2514 ok(V_I4(&vOut) == val, "Expected i4 = %d, got %d\n", (LONG)val, V_I4(&vOut)); }
2515 #define EXPECT_UI4(val) EXPECT_OK { EXPECT_TYPE(VT_UI4); \
2516 ok(V_UI4(&vOut) == val, "Expected ui4 = %d, got %d\n", (ULONG)val, V_UI4(&vOut)); }
2517 #define EXPECT_I8(high,low) EXPECT_OK { EXPECT_TYPE(VT_I8); \
2518 ok(V_I8(&vOut) == ((((ULONG64)(high))<<32)|(low)), "Expected i8 = %x%08x, got %x%08x\n", \
2519 (LONG)(high), (LONG)(low), (LONG)(V_I8(&vOut)>>32), (LONG)V_I8(&vOut) ); }
2520 #define EXPECT_UI8(val) EXPECT_OK { EXPECT_TYPE(VT_UI8); \
2521 ok(V_UI8(&vOut) == val, "Expected ui8 = 0x%x%08x, got 0x%x%08x\n", \
2522 (DWORD)((ULONG64)val >> 32), (DWORD)(ULONG64)val, (DWORD)(V_UI8(&vOut) >> 32), (DWORD)V_UI8(&vOut)); }
2523 #define EXPECT_R4(val) EXPECT_OK { EXPECT_TYPE(VT_R4); \
2524 ok(V_R4(&vOut) == val, "Expected r4 = %f, got %f\n", val, V_R4(&vOut)); }
2525 #define EXPECT_R8(val) EXPECT_OK { EXPECT_TYPE(VT_R8); \
2526 ok(V_R8(&vOut) == val, "Expected r8 = %g, got %g\n", val, V_R8(&vOut)); }
2527 #define CY_MULTIPLIER 10000
2528 #define EXPECT_CY(val) EXPECT_OK { EXPECT_TYPE(VT_CY); \
2529 ok(V_CY(&vOut).int64 == (LONG64)(val * CY_MULTIPLIER), "Expected r8 = 0x%x%08x, got 0x%x%08x\n", \
2530 (DWORD)((LONG64)val >> 23), (DWORD)(LONG64)val, (DWORD)(V_CY(&vOut).int64 >>32), (DWORD)V_CY(&vOut).int64); }
2531 #define EXPECT_DECIMAL(valHi, valMid, valLo) EXPECT_OK { EXPECT_TYPE(VT_DECIMAL); \
2532 ok((V_DECIMAL(&vOut).Hi32 == valHi) && (S1(U1(V_DECIMAL(&vOut))).Mid32 == valMid) && \
2533 (S1(U1(V_DECIMAL(&vOut))).Lo32 == valLo), \
2534 "Expected decimal = %x/0x%x%08x, got %x/0x%x%08x\n", valHi, valMid, valLo, \
2535 V_DECIMAL(&vOut).Hi32, S1(U1(V_DECIMAL(&vOut))).Mid32, S1(U1(V_DECIMAL(&vOut))).Lo32); }
2537 static void test_VarNumFromParseNum(void)
2539 HRESULT hres;
2540 NUMPARSE np;
2541 BYTE rgb[128];
2542 VARIANT vOut;
2544 CHECKPTR(VarNumFromParseNum);
2546 /* Convert the number 1 to different types */
2547 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I1); EXPECT_I1(1);
2548 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_UI1); EXPECT_UI1(1);
2549 /* Prefers a signed type to unsigned of the same size */
2550 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I1|VTBIT_UI1); EXPECT_I1(1);
2551 /* But takes the smaller size if possible */
2552 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I2|VTBIT_UI1); EXPECT_UI1(1);
2554 /* Try different integer sizes */
2555 #define INTEGER_VTBITS (VTBIT_I1|VTBIT_UI1|VTBIT_I2|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|VTBIT_I8|VTBIT_UI8)
2557 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, INTEGER_VTBITS); EXPECT_I1(1);
2558 /* 127 */
2559 SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 7);
2560 CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_I1(127);
2561 /* 128 */
2562 SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 8);
2563 CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_UI1(128);
2564 /* 255 */
2565 SETRGB(0, 2); SETRGB(1, 5); SETRGB(2, 5);
2566 CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_UI1(255);
2567 /* 256 */
2568 SETRGB(0, 2); SETRGB(1, 5); SETRGB(2, 6);
2569 CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_I2(256);
2570 /* 32767 */
2571 SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 7);
2572 CONVERT(5,0,0,5,0,0, INTEGER_VTBITS); EXPECT_I2(32767);
2573 /* 32768 */
2574 SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 8);
2575 CONVERT(5,0,0,5,0,0, INTEGER_VTBITS); EXPECT_UI2(32768);
2577 /* Assume the above pattern holds for remaining positive integers; test negative */
2579 /* -128 */
2580 SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 8);
2581 CONVERT(3,0,NUMPRS_NEG,3,0,0, INTEGER_VTBITS); EXPECT_I1(-128);
2582 /* -129 */
2583 SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 9);
2584 CONVERT(3,0,NUMPRS_NEG,3,0,0, INTEGER_VTBITS); EXPECT_I2(-129);
2585 /* -32768 */
2586 SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 8);
2587 CONVERT(5,0,NUMPRS_NEG,5,0,0, INTEGER_VTBITS); EXPECT_I2(-32768);
2588 /* -32768 */
2589 SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 9);
2590 CONVERT(5,0,NUMPRS_NEG,5,0,0, INTEGER_VTBITS); EXPECT_I4(-32769);
2592 /* Assume the above pattern holds for remaining negative integers */
2594 /* Test hexadecimal conversions */
2595 SETRGB(0, 1); CONVERT(1,0,0,1,4,0, INTEGER_VTBITS); EXPECT_I1(0x01);
2596 /* 0x7f */
2597 SETRGB(0, 7); SETRGB(1, 0xf);
2598 CONVERT(2,0,0,2,4,0, INTEGER_VTBITS); EXPECT_I1(0x7f);
2599 SETRGB(0, 7); SETRGB(1, 0xf);
2600 CONVERT(2,0,0,2,4,0, VTBIT_DECIMAL); EXPECT_DECIMAL(0,0,0x7f);
2601 /* 0x7fff */
2602 SETRGB(0, 7); SETRGB(1, 0xf); SETRGB(2, 0xf); SETRGB(3, 0xf);
2603 CONVERT(4,0,0,4,4,0, INTEGER_VTBITS); EXPECT_I2(0x7fff);
2604 /* 0x7fffffff */
2605 SETRGB(0, 7); SETRGB(1, 0xf); SETRGB(2, 0xf); SETRGB(3, 0xf);
2606 SETRGB(4, 0xf); SETRGB(5, 0xf); SETRGB(6, 0xf); SETRGB(7, 0xf);
2607 CONVERT(8,0,0,8,4,0, INTEGER_VTBITS); EXPECT_I4(0x7fffffffL);
2608 /* 0x7fffffffffffffff (64 bits) */
2609 SETRGB(0, 7); SETRGB(1, 0xf); SETRGB(2, 0xf); SETRGB(3, 0xf);
2610 SETRGB(4, 0xf); SETRGB(5, 0xf); SETRGB(6, 0xf); SETRGB(7, 0xf);
2611 SETRGB(8, 0xf); SETRGB(9, 0xf); SETRGB(10, 0xf); SETRGB(11, 0xf);
2612 SETRGB(12, 0xf); SETRGB(13, 0xf); SETRGB(14, 0xf); SETRGB(15, 0xf);
2613 if (has_i8)
2615 /* We cannot use INTEGER_VTBITS as WinXP and Win2003 are broken(?). They
2616 truncate the number to the smallest integer size requested:
2617 CONVERT(16,0,0,16,4,0, INTEGER_VTBITS); EXPECT_I1((signed char)0xff); */
2618 CONVERT(16,0,0,16,4,0, VTBIT_I8); EXPECT_I8(0x7fffffff,0xffffffff);
2621 /* Assume the above pattern holds for numbers without hi-bit set, test (preservation of) hi-bit */
2622 /* 0x82 */
2623 SETRGB(0, 8); SETRGB(1, 2);
2624 CONVERT(2,0,0,2,4,0, INTEGER_VTBITS);
2625 EXPECT_I1((signed char)0x82);
2626 /* 0x8002 */
2627 SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 2);
2628 CONVERT(4,0,0,4,4,0, INTEGER_VTBITS);
2629 EXPECT_I2((signed short)0x8002);
2630 /* 0x80000002 */
2631 SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 0);
2632 SETRGB(4, 0); SETRGB(5, 0); SETRGB(6, 0); SETRGB(7, 2);
2633 CONVERT(8,0,0,8,4,0, INTEGER_VTBITS); EXPECT_I4(0x80000002);
2634 /* 0x8000000000000002 (64 bits) */
2635 SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 0);
2636 SETRGB(4, 0); SETRGB(5, 0); SETRGB(6, 0); SETRGB(7, 0);
2637 SETRGB(8, 0); SETRGB(9, 0); SETRGB(10, 0); SETRGB(11, 0);
2638 SETRGB(12, 0); SETRGB(13, 0); SETRGB(14, 0); SETRGB(15, 2);
2639 if (has_i8)
2641 /* We cannot use INTEGER_VTBITS as WinXP and Win2003 are broken(?). They
2642 truncate the number to the smallest integer size requested:
2643 CONVERT(16,0,0,16,4,0, INTEGER_VTBITS & ~VTBIT_I1);
2644 EXPECT_I2((signed short)0x0002); */
2645 CONVERT(16,0,0,16,4,0, VTBIT_I8); EXPECT_I8(0x80000000,0x00000002);
2648 /* Test (preservation of) hi-bit with STRICT type requesting */
2649 /* 0x82 */
2650 SETRGB(0, 8); SETRGB(1, 2);
2651 CONVERT(2,0,0,2,4,0, VTBIT_I1);
2652 EXPECT_I1((signed char)0x82);
2653 /* 0x8002 */
2654 SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 2);
2655 CONVERT(4,0,0,4,4,0, VTBIT_I2);
2656 EXPECT_I2((signed short)0x8002);
2657 /* 0x80000002 */
2658 SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 0);
2659 SETRGB(4, 0); SETRGB(5, 0); SETRGB(6, 0); SETRGB(7, 2);
2660 CONVERT(8,0,0,8,4,0, VTBIT_I4); EXPECT_I4(0x80000002);
2661 /* 0x8000000000000002 (64 bits) */
2662 SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 0);
2663 SETRGB(4, 0); SETRGB(5, 0); SETRGB(6, 0); SETRGB(7, 0);
2664 SETRGB(8, 0); SETRGB(9, 0); SETRGB(10, 0); SETRGB(11, 0);
2665 SETRGB(12, 0); SETRGB(13, 0); SETRGB(14, 0); SETRGB(15, 2);
2666 if (has_i8)
2668 CONVERT(16,0,0,16,4,0, VTBIT_I8); EXPECT_I8(0x80000000,0x00000002);
2670 /* Assume the above pattern holds for numbers with hi-bit set */
2672 /* Negative numbers overflow if we have only unsigned outputs */
2673 /* -1 */
2674 SETRGB(0, 1); CONVERT(1,0,NUMPRS_NEG,1,0,0, VTBIT_UI1); EXPECT_OVERFLOW;
2675 /* -0.6 */
2676 SETRGB(0, 6); CONVERT(1,0,NUMPRS_NEG,1,0,~0u, VTBIT_UI1); EXPECT_OVERFLOW;
2678 /* Except that rounding is done first, so -0.5 to 0 are accepted as 0 */
2679 /* -0.5 */
2680 SETRGB(0, 5); CONVERT(1,0,NUMPRS_NEG,1,0,~0u, VTBIT_UI1); EXPECT_UI1(0);
2682 /* Floating point zero is OK */
2683 /* 0.00000000E0 */
2684 SETRGB(0, 0); CONVERT(1,0,NUMPRS_DECIMAL|NUMPRS_EXPONENT,12,0,-8, VTBIT_R8);
2685 EXPECT_R8(0.0);
2687 /* Float is acceptable for an integer input value */
2688 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R4); EXPECT_R4(1.0f);
2689 /* As is double */
2690 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R8); EXPECT_R8(1.0);
2691 /* As is currency */
2692 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_CY); EXPECT_CY(1);
2694 /* Float is preferred over double */
2695 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R4|VTBIT_R8); EXPECT_R4(1.0f);
2697 /* Double is preferred over currency */
2698 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R8|VTBIT_CY); EXPECT_R8(1.0);
2700 /* Currency is preferred over decimal */
2701 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_CY|VTBIT_DECIMAL); EXPECT_CY(1);
2703 /* Underflow test */
2704 SETRGB(0, 1); CONVERT(1,0,NUMPRS_EXPONENT,1,0,-94938484, VTBIT_R4); EXPECT_R4(0.0);
2705 SETRGB(0, 1); CONVERT(1,0,NUMPRS_EXPONENT,1,0,-94938484, VTBIT_R8); EXPECT_R8(0.0);
2706 SETRGB(0, 1); CONVERT(1,0,NUMPRS_EXPONENT,1,0,-94938484, VTBIT_CY); EXPECT_CY(0);
2710 static void test_UdateFromDate( int line, DATE dt, ULONG flags, HRESULT r, WORD d, WORD m, WORD y,
2711 WORD h, WORD mn, WORD s, WORD ms, WORD dw, WORD dy)
2713 UDATE ud;
2714 HRESULT res;
2716 memset(&ud, 0, sizeof(ud));
2717 res = pVarUdateFromDate(dt, flags, &ud);
2718 ok_(__FILE__,line)(r == res && (res != S_OK || (ud.st.wYear == y && ud.st.wMonth == m && ud.st.wDay == d &&
2719 ud.st.wHour == h && ud.st.wMinute == mn && ud.st.wSecond == s &&
2720 ud.st.wMilliseconds == ms && ud.st.wDayOfWeek == dw && ud.wDayOfYear == dy)),
2721 "%.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",
2722 dt, r, d, m, y, h, mn, s, ms, dw, dy,
2723 res, ud.st.wDay, ud.st.wMonth, ud.st.wYear, ud.st.wHour, ud.st.wMinute,
2724 ud.st.wSecond, ud.st.wMilliseconds, ud.st.wDayOfWeek, ud.wDayOfYear );
2726 #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)
2728 static void test_VarUdateFromDate(void)
2730 CHECKPTR(VarUdateFromDate);
2731 DT2UD(29221.0,0,S_OK,1,1,1980,0,0,0,0,2,1); /* 1 Jan 1980 */
2732 DT2UD(29222.0,0,S_OK,2,1,1980,0,0,0,0,3,2); /* 2 Jan 1980 */
2733 DT2UD(33238.0,0,S_OK,31,12,1990,0,0,0,0,1,365); /* 31 Dec 1990 */
2734 DT2UD(0.0,0,S_OK,30,12,1899,0,0,0,0,6,364); /* 30 Dec 1899 - VT_DATE 0.0 */
2735 DT2UD(-657434.0,0,S_OK,1,1,100,0,0,0,0,5,1); /* 1 Jan 100 - Min */
2736 DT2UD(-657435.0,0,E_INVALIDARG,0,0,0,0,0,0,0,0,0); /* < 1 Jan 100 => err */
2737 DT2UD(2958465.0,0,S_OK,31,12,9999,0,0,0,0,5,365); /* 31 Dec 9999 - Max */
2738 DT2UD(2958466.0,0,E_INVALIDARG,0,0,0,0,0,0,0,0,0); /* > 31 Dec 9999 => err */
2740 /* VAR_VALIDDATE doesn't prevent upper and lower bounds being checked */
2741 DT2UD(-657435.0,VAR_VALIDDATE,E_INVALIDARG,0,0,0,0,0,0,0,0,0);
2742 DT2UD(2958466.0,VAR_VALIDDATE,E_INVALIDARG,0,0,0,0,0,0,0,0,0);
2744 /* Times */
2745 DT2UD(29221.25,0,S_OK,1,1,1980,6,0,0,0,2,1); /* 6 AM */
2746 DT2UD(29221.33333333,0,S_OK,1,1,1980,8,0,0,0,2,1); /* 8 AM */
2747 DT2UD(29221.5,0,S_OK,1,1,1980,12,0,0,0,2,1); /* 12 AM */
2748 DT2UD(29221.9888884444,0,S_OK,1,1,1980,23,44,0,0,2,1); /* 11:44 PM */
2749 DT2UD(29221.7508765432,0,S_OK,1,1,1980,18,1,16,0,2,1); /* 6:18:02 PM */
2751 /* Test handling of times on dates prior to the epoch */
2752 DT2UD(-5.25,0,S_OK,25,12,1899,6,0,0,0,1,359);
2753 DT2UD(-5.9999884259259,0,S_OK,25,12,1899,23,59,59,0,1,359);
2754 /* This just demonstrates the non-linear nature of values prior to the epoch */
2755 DT2UD(-4.0,0,S_OK,26,12,1899,0,0,0,0,2,360);
2756 /* Numerical oddity: for 0.0 < x < 1.0, x and -x represent the same datetime */
2757 DT2UD(-0.25,0,S_OK,30,12,1899,6,0,0,0,6,364);
2758 DT2UD(0.25,0,S_OK,30,12,1899,6,0,0,0,6,364);
2762 static void test_DateFromUDate( int line, WORD d, WORD m, WORD y, WORD h, WORD mn, WORD s, WORD ms,
2763 WORD dw, WORD dy, ULONG flags, HRESULT r, DATE dt )
2765 UDATE ud;
2766 double out;
2767 HRESULT res;
2769 ud.st.wYear = y;
2770 ud.st.wMonth = m;
2771 ud.st.wDay = d;
2772 ud.st.wHour = h;
2773 ud.st.wMinute = mn;
2774 ud.st.wSecond = s;
2775 ud.st.wMilliseconds = ms;
2776 ud.st.wDayOfWeek = dw;
2777 ud.wDayOfYear = dy;
2778 res = pVarDateFromUdate(&ud, flags, &out);
2779 ok_(__FILE__,line)(r == res && (r != S_OK || EQ_DOUBLE(out, dt)),
2780 "expected %x, %.16g, got %x, %.16g\n", r, dt, res, out);
2782 #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)
2784 static void test_VarDateFromUdate(void)
2786 CHECKPTR(VarDateFromUdate);
2787 UD2T(1,1,1980,0,0,0,0,2,1,0,S_OK,29221.0); /* 1 Jan 1980 */
2788 UD2T(2,1,1980,0,0,0,0,3,2,0,S_OK,29222.0); /* 2 Jan 1980 */
2789 UD2T(2,1,1980,0,0,0,0,4,5,0,S_OK,29222.0); /* 2 Jan 1980 */
2790 UD2T(31,12,1990,0,0,0,0,0,0,0,S_OK,33238.0); /* 31 Dec 1990 */
2791 UD2T(31,12,90,0,0,0,0,0,0,0,S_OK,33238.0); /* year < 100 is 1900+year! */
2792 UD2T(30,12,1899,0,0,0,0,6,364,0,S_OK,0.0); /* 30 Dec 1899 - VT_DATE 0.0 */
2793 UD2T(1,1,100,0,0,0,0,0,0,0,S_OK,-657434.0); /* 1 Jan 100 - Min */
2794 UD2T(31,12,9999,0,0,0,0,0,0,0,S_OK,2958465.0); /* 31 Dec 9999 - Max */
2795 UD2T(1,1,10000,0,0,0,0,0,0,0,E_INVALIDARG,0.0); /* > 31 Dec 9999 => err */
2796 UD2T(1,1,-10000,0,0,0,0,0,0,0,E_INVALIDARG,0.0);/* < -9999 => err */
2798 UD2T(30,12,1899,0,0,0,0,0,0,0,S_OK,0.0); /* 30 Dec 1899 0:00:00 */
2799 UD2T(30,12,1899,0,0,0,999,0,0,0,S_OK,0.0); /* Ignore milliseconds */
2801 UD2T(1,1,1980,18,1,16,0,2,1,0,S_OK,29221.75087962963); /* 6:18:02 PM */
2802 UD2T(1,300,1980,18,1,16,0,2,1,0,S_OK,38322.75087962963); /* Test fwdrolled month */
2803 UD2T(300,1,1980,18,1,16,0,2,1,0,S_OK,29520.75087962963); /* Test fwdrolled days */
2804 UD2T(0,1,1980,42,1,16,0,2,1,0,S_OK,29221.75087962963); /* Test fwdrolled hours */
2805 UD2T(1,1,1980,17,61,16,0,2,1,0,S_OK,29221.75087962963); /* Test fwdrolled minutes */
2806 UD2T(1,1,1980,18,0,76,0,2,1,0,S_OK,29221.75087962963); /* Test fwdrolled seconds */
2807 UD2T(1,-300,1980,18,1,16,0,2,1,0,S_OK,20059.75087962963); /* Test backrolled month */
2808 UD2T(-300,1,1980,18,1,16,0,2,1,0,S_OK,28920.75087962963); /* Test backrolled days */
2809 UD2T(3,1,1980,-30,1,16,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled hours */
2810 UD2T(1,1,1980,20,-119,16,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled minutes */
2811 UD2T(1,1,1980,18,3,-104,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled seconds */
2812 UD2T(1,12001,-1020,18,1,16,0,0,0,0,S_OK,29221.75087962963); /* Test rolled year and month */
2813 UD2T(1,-23,1982,18,1,16,0,0,0,0,S_OK,29221.75087962963); /* Test backrolled month */
2814 UD2T(-59,3,1980,18,1,16,0,0,0,0,S_OK,29221.75087962963); /* Test backrolled days */
2815 UD2T(1,1,0,0,0,0,0,0,0,0,S_OK,36526); /* Test zero year */
2816 UD2T(0,0,1980,0,0,0,0,0,0,0,S_OK,29189); /* Test zero day and month */
2817 UD2T(0,1,1980,0,0,0,0,2,1,0,S_OK,29220.0); /* Test zero day = LastDayOfMonth */
2818 UD2T(-1,1,1980,18,1,16,0,0,0,0,S_OK,29219.75087962963); /* Test day -1 = LastDayOfMonth - 1 */
2819 UD2T(1,1,-1,18,1,16,0,0,0,0,S_OK,36161.75087962963); /* Test year -1 = 1999 */
2820 UD2T(1,-1,1980,18,1,16,0,0,0,0,S_OK,29160.7508796296); /* Test month -1 = 11 */
2821 UD2T(1,13,1980,0,0,0,0,2,1,0,S_OK,29587.0); /* Rolls fwd to 1/1/1981 */
2823 /* Test handling of times on dates prior to the epoch */
2824 UD2T(25,12,1899,6,0,0,0,1,359,0,S_OK,-5.25);
2825 UD2T(25,12,1899,23,59,59,0,1,359,0,S_OK,-5.9999884259259);
2826 /* This just demonstrates the non-linear nature of values prior to the epoch */
2827 UD2T(26,12,1899,0,0,0,0,2,360,0,S_OK,-4.0);
2828 /* for DATE values 0.0 < x < 1.0, x and -x represent the same datetime */
2829 /* but when converting to DATE, prefer the positive versions */
2830 UD2T(30,12,1899,6,0,0,0,6,364,0,S_OK,0.25);
2832 UD2T(1,1,1980,18,1,16,0,2,1,VAR_TIMEVALUEONLY,S_OK,0.7508796296296296);
2833 UD2T(1,1,1980,18,1,16,0,2,1,VAR_DATEVALUEONLY,S_OK,29221.0);
2834 UD2T(25,12,1899,6,0,0,0,1,359,VAR_TIMEVALUEONLY,S_OK,0.25);
2835 UD2T(25,12,1899,6,0,0,0,1,359,VAR_DATEVALUEONLY,S_OK,-5.0);
2836 UD2T(1,-1,1980,18,1,16,0,0,0,VAR_TIMEVALUEONLY|VAR_DATEVALUEONLY,S_OK,0.7508796296296296);
2839 static void test_st2dt(int line, WORD d, WORD m, WORD y, WORD h, WORD mn,
2840 WORD s, WORD ms, INT r, double dt, double dt2)
2842 SYSTEMTIME st;
2843 double out;
2844 INT res;
2846 st.wYear = y;
2847 st.wMonth = m;
2848 st.wDay = d;
2849 st.wHour = h;
2850 st.wMinute = mn;
2851 st.wSecond = s;
2852 st.wMilliseconds = ms;
2853 st.wDayOfWeek = 0;
2854 res = pSystemTimeToVariantTime(&st, &out);
2855 ok_(__FILE__,line)(r == res, "expected %d, got %d\n", r, res);
2856 if (r && res)
2857 ok_(__FILE__,line)(EQ_DOUBLE(out, dt) || (dt2 && broken(EQ_DOUBLE(out, dt2))),
2858 "expected %.16g or %.16g, got %.16g\n", dt, dt2, out);
2860 #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)
2862 static void test_SystemTimeToVariantTime(void)
2864 CHECKPTR(SystemTimeToVariantTime);
2865 ST2DT(1,1,1980,0,0,0,0,TRUE,29221.0,0.0);
2866 ST2DT(2,1,1980,0,0,0,0,TRUE,29222.0,0.0);
2867 ST2DT(0,1,1980,0,0,0,0,TRUE,29220.0,0.0); /* Rolls back to 31 Dec 1899 */
2868 ST2DT(1,13,1980,0,0,0,0,FALSE,0.0,0.0); /* Fails on invalid month */
2869 ST2DT(32,1,1980,0,0,0,0,FALSE,0.0,0.0); /* Fails on invalid day */
2870 ST2DT(1,1,-1,0,0,0,0,FALSE,0.0,0.0); /* Fails on invalid year */
2871 ST2DT(1,1,10000,0,0,0,0,FALSE,0.0,0.0); /* Fails on invalid year */
2872 ST2DT(1,1,9999,0,0,0,0,TRUE,2958101.0,0.0); /* 9999 is last valid year */
2874 /* Old Windows versions use 29 as the Y2K cutoff:
2875 * years 00-29 map to 2000-2029 while years 30-99 map to 1930-1999
2877 ST2DT(1,1,0,0,0,0,0,TRUE,36526.0,0.0);
2878 ST2DT(1,1,29,0,0,0,0,TRUE,47119.0,0.0);
2879 ST2DT(1,1,30,0,0,0,0,TRUE,47484.0,10959.0);
2880 /* But Windows 1903+ uses 49 as the Y2K cutoff */
2881 ST2DT(1,1,49,0,0,0,0,TRUE,54424.0,17899.0);
2882 ST2DT(1,1,50,0,0,0,0,TRUE,18264.0,0.0);
2883 ST2DT(31,12,99,0,0,0,0,TRUE,36525.0,0.0);
2886 static void test_dt2st(int line, double dt, INT r, WORD d, WORD m, WORD y,
2887 WORD h, WORD mn, WORD s, WORD ms)
2889 SYSTEMTIME st;
2890 INT res;
2892 memset(&st, 0, sizeof(st));
2893 res = pVariantTimeToSystemTime(dt, &st);
2894 ok_(__FILE__,line)(r == res &&
2895 (!r || (st.wYear == y && st.wMonth == m && st.wDay == d &&
2896 st.wHour == h && st.wMinute == mn &&
2897 st.wSecond == s && st.wMilliseconds == ms)),
2898 "%.16g expected %d, %d,%d,%d,%d,%d,%d,%d, got %d, %d,%d,%d,%d,%d,%d,%d\n",
2899 dt, r, d, m, y, h, mn, s, ms, res, st.wDay, st.wMonth,
2900 st.wYear, st.wHour, st.wMinute, st.wSecond,
2901 st.wMilliseconds);
2903 #define DT2ST(dt,r,d,m,y,h,mn,s,ms) test_dt2st(__LINE__,dt,r,d,m,y,h,mn,s,ms)
2905 static void test_VariantTimeToSystemTime(void)
2907 CHECKPTR(VariantTimeToSystemTime);
2908 DT2ST(29221.0,1,1,1,1980,0,0,0,0);
2909 DT2ST(29222.0,1,2,1,1980,0,0,0,0);
2912 #define MKDOSDATE(d,m,y) ((d & 0x1f) | ((m & 0xf) << 5) | (((y-1980) & 0x7f) << 9))
2913 #define MKDOSTIME(h,m,s) (((s>>1) & 0x1f) | ((m & 0x3f) << 5) | ((h & 0x1f) << 11))
2915 static void test_dos2dt(int line, WORD d, WORD m, WORD y, WORD h, WORD mn,
2916 WORD s, INT r, double dt)
2918 unsigned short dosDate, dosTime;
2919 double out;
2920 INT res;
2922 out = 0.0;
2923 dosDate = MKDOSDATE(d, m, y);
2924 dosTime = MKDOSTIME(h, mn, s);
2925 res = pDosDateTimeToVariantTime(dosDate, dosTime, &out);
2926 ok_(__FILE__,line)(r == res && (!r || EQ_DOUBLE(out, dt)),
2927 "expected %d, %.16g, got %d, %.16g\n", r, dt, res, out);
2929 #define DOS2DT(d,m,y,h,mn,s,r,dt) test_dos2dt(__LINE__,d,m,y,h,mn,s,r,dt)
2931 static void test_DosDateTimeToVariantTime(void)
2933 CHECKPTR(DosDateTimeToVariantTime);
2935 /* Date */
2936 DOS2DT(1,1,1980,0,0,0,1,29221.0); /* 1/1/1980 */
2937 DOS2DT(31,12,2099,0,0,0,1,73050.0); /* 31/12/2099 */
2938 /* Dates are limited to the dos date max of 31/12/2099 */
2939 DOS2DT(31,12,2100,0,0,0,0,0.0); /* 31/12/2100 */
2940 /* Days and months of 0 cause date to roll back 1 day or month */
2941 DOS2DT(0,1,1980,0,0,0,1,29220.0); /* 0 Day => 31/12/1979 */
2942 DOS2DT(1,0,1980,0,0,0,1,29190.0); /* 0 Mth => 1/12/1979 */
2943 DOS2DT(0,0,1980,0,0,0,1,29189.0); /* 0 D/M => 30/11/1979 */
2944 /* Days > days in the month cause date to roll forward 1 month */
2945 DOS2DT(29,2,1981,0,0,0,1,29646.0); /* 29/2/1981 -> 3/1/1980 */
2946 DOS2DT(30,2,1981,0,0,0,1,29647.0); /* 30/2/1981 -> 4/1/1980 */
2947 /* Takes leap years into account when rolling forward */
2948 DOS2DT(29,2,1980,0,0,0,1,29280.0); /* 2/29/1980 */
2949 /* Months > 12 cause an error */
2950 DOS2DT(2,13,1980,0,0,0,0,0.0);
2952 /* Time */
2953 DOS2DT(1,1,1980,0,0,29,1,29221.00032407407); /* 1/1/1980 12:00:28 AM */
2954 DOS2DT(1,1,1980,0,0,31,1,29221.00034722222); /* 1/1/1980 12:00:30 AM */
2955 DOS2DT(1,1,1980,0,59,0,1,29221.04097222222); /* 1/1/1980 12:59:00 AM */
2956 DOS2DT(1,1,1980,0,60,0,0,0.0); /* Invalid minutes */
2957 DOS2DT(1,1,1980,0,0,60,0,0.0); /* Invalid seconds */
2958 DOS2DT(1,1,1980,23,0,0,1,29221.95833333333); /* 1/1/1980 11:00:00 PM */
2959 DOS2DT(1,1,1980,24,0,0,0,0.0); /* Invalid hours */
2961 DOS2DT(1,1,1980,0,0,1,1,29221.0);
2962 DOS2DT(2,1,1980,0,0,0,1,29222.0);
2963 DOS2DT(2,1,1980,0,0,0,1,29222.0);
2964 DOS2DT(31,12,1990,0,0,0,1,33238.0);
2965 DOS2DT(31,12,90,0,0,0,1,40543.0);
2966 DOS2DT(30,12,1899,0,0,0,1,46751.0);
2967 DOS2DT(1,1,100,0,0,0,1,43831.0);
2968 DOS2DT(31,12,9999,0,0,0,1,59901.0);
2969 DOS2DT(1,1,10000,0,0,0,1,59902.0);
2970 DOS2DT(1,1,-10000,0,0,0,1,48214.0);
2972 DOS2DT(30,12,1899,0,0,0,1,46751.0);
2973 DOS2DT(30,12,1899,0,0,1,1,46751.0);
2975 DOS2DT(1,1,1980,18,1,16,1,29221.75087962963);
2976 DOS2DT(1,300,1980,18,1,16,1,29556.75087962963);
2977 DOS2DT(300,1,1980,18,1,16,1,29232.75087962963);
2978 DOS2DT(0,1,1980,42,1,16,1,29220.4175462963);
2979 DOS2DT(1,1,1980,17,61,16,0,0.0);
2980 DOS2DT(1,1,1980,18,0,76,1,29221.75013888889);
2981 DOS2DT(1,-300,1980,18,1,16,1,29312.75087962963);
2982 DOS2DT(-300,1,1980,18,1,16,1,29240.75087962963);
2983 DOS2DT(3,1,1980,-30,1,16,1,29223.08421296296);
2984 DOS2DT(1,1,1980,20,-119,16,1,29221.83976851852);
2985 DOS2DT(1,1,1980,18,3,-104,1,29221.75236111111);
2986 DOS2DT(1,12001,-1020,18,1,16,1,55519.75087962963);
2987 DOS2DT(1,-23,1982,18,1,16,1,30195.75087962963);
2988 DOS2DT(-59,3,1980,18,1,16,1,29285.75087962963);
2989 DOS2DT(1,1,0,0,0,0,1,54058.0);
2990 DOS2DT(0,0,1980,0,0,0,1,29189.0);
2991 DOS2DT(0,1,1980,0,0,0,1,29220.0);
2992 DOS2DT(-1,1,1980,18,1,16,1,29251.75087962963);
2993 DOS2DT(1,1,-1,18,1,16,1,53693.75087962963);
2994 DOS2DT(1,-1,1980,18,1,16,0,0);
2997 static void test_dt2dos(int line, double dt, INT r, WORD d, WORD m, WORD y,
2998 WORD h, WORD mn, WORD s)
3000 unsigned short dosDate, dosTime, expDosDate, expDosTime;
3001 INT res;
3003 dosTime = dosDate = 0;
3004 expDosDate = MKDOSDATE(d,m,y);
3005 expDosTime = MKDOSTIME(h,mn,s);
3006 res = pVariantTimeToDosDateTime(dt, &dosDate, &dosTime);
3007 ok_(__FILE__,line)(r == res && (!r || (dosTime == expDosTime && dosDate == expDosDate)),
3008 "%g: expected %d,%d(%d/%d/%d),%d(%d:%d:%d) got %d,%d(%d/%d/%d),%d(%d:%d:%d)\n",
3009 dt, r, expDosDate, expDosDate & 0x1f,
3010 (expDosDate >> 5) & 0xf, 1980 + (expDosDate >> 9),
3011 expDosTime, expDosTime >> 11, (expDosTime >> 5) & 0x3f,
3012 (expDosTime & 0x1f),
3013 res, dosDate, dosDate & 0x1f, (dosDate >> 5) & 0xf,
3014 1980 + (dosDate >> 9), dosTime, dosTime >> 11,
3015 (dosTime >> 5) & 0x3f, (dosTime & 0x1f));
3017 #define DT2DOS(dt,r,d,m,y,h,mn,s) test_dt2dos(__LINE__,dt,r,d,m,y,h,mn,s)
3019 static void test_VariantTimeToDosDateTime(void)
3021 CHECKPTR(VariantTimeToDosDateTime);
3023 /* Date */
3024 DT2DOS(29221.0,1,1,1,1980,0,0,0); /* 1/1/1980 */
3025 DT2DOS(73050.0,1,31,12,2099,0,0,0); /* 31/12/2099 */
3026 DT2DOS(29220.0,0,0,0,0,0,0,0); /* 31/12/1979 - out of range */
3027 DT2DOS(73415.0,0,0,0,0,0,0,0); /* 31/12/2100 - out of range */
3029 /* Time */
3030 DT2DOS(29221.00032407407,1,1,1,1980,0,0,29); /* 1/1/1980 12:00:28 AM */
3031 DT2DOS(29221.00034722222,1,1,1,1980,0,0,31); /* 1/1/1980 12:00:30 AM */
3032 DT2DOS(29221.04097222222,1,1,1,1980,0,59,0); /* 1/1/1980 12:59:00 AM */
3033 DT2DOS(29221.95833333333,1,1,1,1980,23,0,0); /* 1/1/1980 11:00:00 PM */
3036 static HRESULT (WINAPI *pVarAbs)(LPVARIANT,LPVARIANT);
3038 #define VARABS(vt,val,rvt,rval) \
3039 V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
3040 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
3041 test_var_call1( __LINE__, pVarAbs, &v, &exp )
3043 static void test_VarAbs(void)
3045 static WCHAR szNum[] = {'-','1','.','1','\0' };
3046 char buff[8];
3047 HRESULT hres;
3048 VARIANT v, vDst, exp;
3049 size_t i;
3051 CHECKPTR(VarAbs);
3053 /* Test all possible V_VT values.
3055 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
3057 VARTYPE vt;
3059 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
3061 HRESULT hExpected = DISP_E_BADVARTYPE;
3063 SKIPTESTS(vt);
3065 memset(&v, 0, sizeof(v));
3066 V_VT(&v) = vt | ExtraFlags[i];
3067 V_VT(&vDst) = VT_EMPTY;
3069 hres = pVarAbs(&v,&vDst);
3070 if (ExtraFlags[i] & VT_ARRAY ||
3071 (!ExtraFlags[i] && (vt == VT_UNKNOWN || vt == VT_BSTR ||
3072 vt == VT_DISPATCH || vt == VT_ERROR || vt == VT_RECORD)))
3074 hExpected = DISP_E_TYPEMISMATCH;
3076 else if (ExtraFlags[i] || vt >= VT_CLSID || vt == VT_VARIANT)
3078 hExpected = DISP_E_BADVARTYPE;
3080 else if (IsValidVariantClearVT(vt, ExtraFlags[i]))
3081 hExpected = S_OK;
3083 /* Native always fails on some vartypes that should be valid. don't
3084 * check that Wine does the same; these are bugs in native.
3086 if (vt == VT_I8 || vt == VT_UI8 || vt == VT_INT || vt == VT_UINT ||
3087 vt == VT_I1 || vt == VT_UI2 || vt == VT_UI4)
3088 continue;
3089 ok(hres == hExpected, "VarAbs: expected 0x%X, got 0x%X for vt %d | 0x%X\n",
3090 hExpected, hres, vt, ExtraFlags[i]);
3094 /* BOOL->I2, BSTR->R8, all others remain the same */
3095 VARABS(BOOL,VARIANT_TRUE,I2,-VARIANT_TRUE);
3096 VARABS(BOOL,VARIANT_FALSE,I2,VARIANT_FALSE);
3097 VARABS(EMPTY,0,I2,0);
3098 VARABS(EMPTY,1,I2,0);
3099 VARABS(NULL,0,NULL,0);
3100 VARABS(NULL,1,NULL,0);
3101 VARABS(I2,1,I2,1);
3102 VARABS(I2,-1,I2,1);
3103 VARABS(I4,1,I4,1);
3104 VARABS(I4,-1,I4,1);
3105 VARABS(UI1,1,UI1,1);
3106 VARABS(R4,1,R4,1);
3107 VARABS(R4,-1,R4,1);
3108 VARABS(R8,1,R8,1);
3109 VARABS(R8,-1,R8,1);
3110 VARABS(DATE,1,DATE,1);
3111 VARABS(DATE,-1,DATE,1);
3112 V_VT(&v) = VT_CY;
3113 V_CY(&v).int64 = -10000;
3114 memset(&vDst,0,sizeof(vDst));
3115 hres = pVarAbs(&v,&vDst);
3116 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == 10000,
3117 "VarAbs(CY): expected 0x0 got 0x%X\n", hres);
3118 GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, ARRAY_SIZE(buff));
3119 if (buff[1])
3121 trace("Skipping VarAbs(BSTR) as decimal separator is '%s'\n", buff);
3122 return;
3123 } else {
3124 szNum[2] = buff[0];
3126 V_VT(&v) = VT_BSTR;
3127 V_BSTR(&v) = (BSTR)szNum;
3128 memset(&vDst,0,sizeof(vDst));
3129 hres = pVarAbs(&v,&vDst);
3130 ok(hres == S_OK && V_VT(&vDst) == VT_R8 && V_R8(&vDst) == 1.1,
3131 "VarAbs: expected 0x0,%d,%g, got 0x%X,%d,%g\n", VT_R8, 1.1, hres, V_VT(&vDst), V_R8(&vDst));
3134 static HRESULT (WINAPI *pVarNot)(LPVARIANT,LPVARIANT);
3136 #define VARNOT(vt,val,rvt,rval) \
3137 V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
3138 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
3139 test_var_call1( __LINE__, pVarNot, &v, &exp )
3141 static void test_VarNot(void)
3143 static const WCHAR szNum0[] = {'0','\0' };
3144 static const WCHAR szNum1[] = {'1','\0' };
3145 static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
3146 static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
3147 HRESULT hres;
3148 VARIANT v, exp, vDst;
3149 DECIMAL *pdec = &V_DECIMAL(&v);
3150 CY *pcy = &V_CY(&v);
3151 size_t i;
3153 CHECKPTR(VarNot);
3155 /* Test all possible V_VT values */
3156 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
3158 VARTYPE vt;
3160 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
3162 HRESULT hExpected = DISP_E_BADVARTYPE;
3164 SKIPTESTS(vt);
3166 memset(&v, 0, sizeof(v));
3167 V_VT(&v) = vt | ExtraFlags[i];
3168 V_VT(&vDst) = VT_EMPTY;
3170 switch (V_VT(&v))
3172 case VT_I1: case VT_UI1: case VT_I2: case VT_UI2:
3173 case VT_INT: case VT_UINT: case VT_I4: case VT_UI4:
3174 case VT_R4: case VT_R8:
3175 case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
3176 case VT_DATE: case VT_CY:
3177 hExpected = S_OK;
3178 break;
3179 case VT_I8: case VT_UI8:
3180 if (has_i8)
3181 hExpected = S_OK;
3182 break;
3183 case VT_RECORD:
3184 hExpected = DISP_E_TYPEMISMATCH;
3185 break;
3186 case VT_UNKNOWN: case VT_BSTR: case VT_DISPATCH: case VT_ERROR:
3187 hExpected = DISP_E_TYPEMISMATCH;
3188 break;
3189 default:
3190 if (IsValidVariantClearVT(vt, ExtraFlags[i]) && vt != VT_CLSID)
3191 hExpected = DISP_E_TYPEMISMATCH;
3192 break;
3195 hres = pVarNot(&v,&vDst);
3196 ok(hres == hExpected, "VarNot: expected 0x%X, got 0x%X vt %d|0x%X\n",
3197 hExpected, hres, vt, ExtraFlags[i]);
3200 /* Test the values returned by all cases that can succeed */
3201 VARNOT(EMPTY,0,I2,-1);
3202 VARNOT(EMPTY,1,I2,-1);
3203 VARNOT(NULL,0,NULL,0);
3204 VARNOT(NULL,1,NULL,0);
3205 VARNOT(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE);
3206 VARNOT(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE);
3207 VARNOT(I1,-1,I4,0);
3208 VARNOT(I1,0,I4,-1);
3209 VARNOT(I2,-1,I2,0);
3210 VARNOT(I2,0,I2,-1);
3211 VARNOT(I2,1,I2,-2);
3212 VARNOT(I4,1,I4,-2);
3213 VARNOT(I4,0,I4,-1);
3214 VARNOT(UI1,1,UI1,254);
3215 VARNOT(UI1,0,UI1,255);
3216 VARNOT(UI2,0,I4,-1);
3217 VARNOT(UI2,1,I4,-2);
3218 VARNOT(UI4,0,I4,-1);
3219 VARNOT(UI4,1,I4,-2);
3220 VARNOT(INT,0,I4,-1);
3221 VARNOT(INT,1,I4,-2);
3222 VARNOT(UINT,0,I4,-1);
3223 VARNOT(UINT,1,I4,-2);
3224 if (has_i8)
3226 VARNOT(I8,1,I8,-2);
3227 VARNOT(I8,0,I8,-1);
3228 VARNOT(UI8,0,I4,-1);
3229 VARNOT(UI8,1,I4,-2);
3231 VARNOT(R4,1,I4,-2);
3232 VARNOT(R4,0,I4,-1);
3233 VARNOT(R8,1,I4,-2);
3234 VARNOT(R8,0,I4,-1);
3235 VARNOT(DATE,1,I4,-2);
3236 VARNOT(DATE,0,I4,-1);
3237 VARNOT(BSTR,(BSTR)szNum0,I4,-1);
3238 ok(V_VT(&v) == VT_BSTR && V_BSTR(&v) == szNum0, "VarNot(0): changed input\n");
3239 VARNOT(BSTR,(BSTR)szNum1,I4,-2);
3240 ok(V_VT(&v) == VT_BSTR && V_BSTR(&v) == szNum1, "VarNot(1): changed input\n");
3241 VARNOT(BSTR, (BSTR)szTrue, BOOL, VARIANT_FALSE);
3242 VARNOT(BSTR, (BSTR)szFalse, BOOL, VARIANT_TRUE);
3244 S(U(*pdec)).sign = DECIMAL_NEG;
3245 S(U(*pdec)).scale = 0;
3246 pdec->Hi32 = 0;
3247 S1(U1(*pdec)).Mid32 = 0;
3248 S1(U1(*pdec)).Lo32 = 1;
3249 VARNOT(DECIMAL,*pdec,I4,0);
3251 pcy->int64 = 10000;
3252 VARNOT(CY,*pcy,I4,-2);
3254 pcy->int64 = 0;
3255 VARNOT(CY,*pcy,I4,-1);
3257 pcy->int64 = -1;
3258 VARNOT(CY,*pcy,I4,-1);
3261 static HRESULT (WINAPI *pVarSub)(LPVARIANT,LPVARIANT,LPVARIANT);
3263 #define VARSUB(vt1,val1,vt2,val2,rvt,rval) \
3264 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
3265 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
3266 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
3267 test_var_call2( __LINE__, pVarSub, &left, &right, &exp )
3269 static void test_VarSub(void)
3271 VARIANT left, right, exp, result, cy, dec;
3272 VARTYPE i;
3273 BSTR lbstr, rbstr;
3274 HRESULT hres, expectedhres;
3275 double r;
3277 CHECKPTR(VarSub);
3279 lbstr = SysAllocString(sz12);
3280 rbstr = SysAllocString(sz12);
3282 VariantInit(&left);
3283 VariantInit(&right);
3284 VariantInit(&result);
3286 /* Test all possible flag/vt combinations & the resulting vt type */
3287 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
3290 VARTYPE leftvt, rightvt, resvt;
3292 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
3295 SKIPTESTS(leftvt);
3297 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
3300 SKIPTESTS(rightvt);
3301 expectedhres = S_OK;
3303 memset(&left, 0, sizeof(left));
3304 memset(&right, 0, sizeof(right));
3305 V_VT(&left) = leftvt | ExtraFlags[i];
3306 if (leftvt == VT_BSTR)
3307 V_BSTR(&left) = lbstr;
3308 V_VT(&right) = rightvt | ExtraFlags[i];
3309 if (rightvt == VT_BSTR)
3310 V_BSTR(&right) = rbstr;
3311 V_VT(&result) = VT_EMPTY;
3313 /* All extra flags produce errors */
3314 if (ExtraFlags[i] == (VT_VECTOR|VT_BYREF|VT_RESERVED) ||
3315 ExtraFlags[i] == (VT_VECTOR|VT_RESERVED) ||
3316 ExtraFlags[i] == (VT_VECTOR|VT_BYREF) ||
3317 ExtraFlags[i] == (VT_BYREF|VT_RESERVED) ||
3318 ExtraFlags[i] == VT_VECTOR ||
3319 ExtraFlags[i] == VT_BYREF ||
3320 ExtraFlags[i] == VT_RESERVED)
3322 expectedhres = DISP_E_BADVARTYPE;
3323 resvt = VT_EMPTY;
3325 else if (ExtraFlags[i] >= VT_ARRAY)
3327 expectedhres = DISP_E_TYPEMISMATCH;
3328 resvt = VT_EMPTY;
3330 /* Native VarSub cannot handle: VT_I1, VT_UI2, VT_UI4,
3331 VT_INT, VT_UINT and VT_UI8. Tested with WinXP */
3332 else if (!IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
3333 !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
3334 leftvt == VT_CLSID || rightvt == VT_CLSID ||
3335 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
3336 leftvt == VT_I1 || rightvt == VT_I1 ||
3337 leftvt == VT_UI2 || rightvt == VT_UI2 ||
3338 leftvt == VT_UI4 || rightvt == VT_UI4 ||
3339 leftvt == VT_UI8 || rightvt == VT_UI8 ||
3340 leftvt == VT_INT || rightvt == VT_INT ||
3341 leftvt == VT_UINT || rightvt == VT_UINT ||
3342 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN ||
3343 leftvt == VT_RECORD || rightvt == VT_RECORD)
3345 if (leftvt == VT_RECORD && rightvt == VT_I8)
3347 if (has_i8)
3348 expectedhres = DISP_E_TYPEMISMATCH;
3349 else
3350 expectedhres = DISP_E_BADVARTYPE;
3352 else if (leftvt < VT_UI1 && rightvt == VT_RECORD)
3353 expectedhres = DISP_E_TYPEMISMATCH;
3354 else if (leftvt >= VT_UI1 && rightvt == VT_RECORD)
3355 expectedhres = DISP_E_TYPEMISMATCH;
3356 else if (leftvt == VT_RECORD && rightvt <= VT_UI1)
3357 expectedhres = DISP_E_TYPEMISMATCH;
3358 else if (leftvt == VT_RECORD && rightvt > VT_UI1)
3359 expectedhres = DISP_E_BADVARTYPE;
3360 else
3361 expectedhres = DISP_E_BADVARTYPE;
3362 resvt = VT_EMPTY;
3364 else if ((leftvt == VT_NULL && rightvt == VT_DISPATCH) ||
3365 (leftvt == VT_DISPATCH && rightvt == VT_NULL))
3366 resvt = VT_NULL;
3367 else if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
3368 leftvt == VT_ERROR || rightvt == VT_ERROR)
3370 resvt = VT_EMPTY;
3371 expectedhres = DISP_E_TYPEMISMATCH;
3373 else if (leftvt == VT_NULL || rightvt == VT_NULL)
3374 resvt = VT_NULL;
3375 else if ((leftvt == VT_EMPTY && rightvt == VT_BSTR) ||
3376 (leftvt == VT_DATE && rightvt == VT_DATE) ||
3377 (leftvt == VT_BSTR && rightvt == VT_EMPTY) ||
3378 (leftvt == VT_BSTR && rightvt == VT_BSTR))
3379 resvt = VT_R8;
3380 else if (leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
3381 resvt = VT_DECIMAL;
3382 else if (leftvt == VT_DATE || rightvt == VT_DATE)
3383 resvt = VT_DATE;
3384 else if (leftvt == VT_CY || rightvt == VT_CY)
3385 resvt = VT_CY;
3386 else if (leftvt == VT_R8 || rightvt == VT_R8)
3387 resvt = VT_R8;
3388 else if (leftvt == VT_BSTR || rightvt == VT_BSTR) {
3389 resvt = VT_R8;
3390 } else if (leftvt == VT_R4 || rightvt == VT_R4) {
3391 if (leftvt == VT_I4 || rightvt == VT_I4 ||
3392 leftvt == VT_I8 || rightvt == VT_I8)
3393 resvt = VT_R8;
3394 else
3395 resvt = VT_R4;
3397 else if (leftvt == VT_I8 || rightvt == VT_I8)
3398 resvt = VT_I8;
3399 else if (leftvt == VT_I4 || rightvt == VT_I4)
3400 resvt = VT_I4;
3401 else if (leftvt == VT_I2 || rightvt == VT_I2 ||
3402 leftvt == VT_BOOL || rightvt == VT_BOOL ||
3403 (leftvt == VT_EMPTY && rightvt == VT_EMPTY))
3404 resvt = VT_I2;
3405 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
3406 resvt = VT_UI1;
3407 else
3409 resvt = VT_EMPTY;
3410 expectedhres = DISP_E_TYPEMISMATCH;
3413 hres = pVarSub(&left, &right, &result);
3415 ok(hres == expectedhres && V_VT(&result) == resvt,
3416 "VarSub: %d|0x%X, %d|0x%X: Expected failure 0x%X, "
3417 "got 0x%X, expected vt %d got vt %d\n",
3418 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i],
3419 expectedhres, hres, resvt, V_VT(&result));
3424 /* Test returned values */
3425 VARSUB(I4,4,I4,2,I4,2);
3426 VARSUB(I2,4,I2,2,I2,2);
3427 VARSUB(I2,-13,I4,5,I4,-18);
3428 VARSUB(I4,-13,I4,5,I4,-18);
3429 VARSUB(I2,7,R4,0.5f,R4,6.5f);
3430 VARSUB(R4,0.5f,I4,5,R8,-4.5);
3431 VARSUB(R8,7.1,BOOL,0,R8,7.1);
3432 VARSUB(BSTR,lbstr,I2,4,R8,8);
3433 VARSUB(BSTR,lbstr,BOOL,1,R8,11);
3434 VARSUB(BSTR,lbstr,R4,0.1f,R8,11.9);
3435 VARSUB(R4,0.2f,BSTR,rbstr,R8,-11.8);
3436 VARSUB(DATE,2.25,I4,7,DATE,-4.75);
3437 VARSUB(DATE,1.25,R4,-1.7f,DATE,2.95);
3439 VARSUB(UI1, UI1_MAX, UI1, UI1_MAX, UI1, 0);
3440 VARSUB(I2, I2_MAX, I2, I2_MAX, I2, 0);
3441 VARSUB(I2, I2_MIN, I2, I2_MIN, I2, 0);
3442 VARSUB(I4, I4_MAX, I4, I4_MAX, I4, 0);
3443 VARSUB(I4, I4_MIN, I4, I4_MIN, I4, 0);
3444 VARSUB(R4, R4_MAX, R4, R4_MAX, R4, 0.0f);
3445 VARSUB(R4, R4_MAX, R4, R4_MIN, R4, R4_MAX - R4_MIN);
3446 VARSUB(R4, R4_MIN, R4, R4_MIN, R4, 0.0f);
3447 VARSUB(R8, R8_MAX, R8, R8_MIN, R8, R8_MAX - R8_MIN);
3448 VARSUB(R8, R8_MIN, R8, R8_MIN, R8, 0.0);
3450 /* Manually test BSTR + BSTR */
3451 V_VT(&left) = VT_BSTR;
3452 V_BSTR(&left) = lbstr;
3453 V_VT(&right) = VT_BSTR;
3454 V_BSTR(&right) = rbstr;
3455 hres = pVarSub(&left, &right, &result);
3456 ok(hres == S_OK && V_VT(&result) == VT_R8,
3457 "VarSub: expected coerced type VT_R8, got %s!\n", vtstr(V_VT(&result)));
3458 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 0.0),
3459 "VarSub: BSTR + BSTR, expected %f got %f\n", 0.0, V_R8(&result));
3461 /* Manually test some VT_CY and VT_DECIMAL variants */
3462 V_VT(&cy) = VT_CY;
3463 hres = VarCyFromI4(4711, &V_CY(&cy));
3464 ok(hres == S_OK, "VarCyFromI4 failed!\n");
3465 V_VT(&dec) = VT_DECIMAL;
3466 hres = VarDecFromR8(-4.2, &V_DECIMAL(&dec));
3467 ok(hres == S_OK, "VarDecFromR4 failed!\n");
3468 memset(&left, 0, sizeof(left));
3469 memset(&right, 0, sizeof(right));
3470 V_VT(&left) = VT_I4;
3471 V_I4(&left) = -11;
3472 V_VT(&right) = VT_UI1;
3473 V_UI1(&right) = 9;
3475 hres = pVarSub(&cy, &right, &result);
3476 ok(hres == S_OK && V_VT(&result) == VT_CY,
3477 "VarSub: expected coerced type VT_CY, got %s!\n", vtstr(V_VT(&result)));
3478 hres = VarR8FromCy(V_CY(&result), &r);
3479 ok(hres == S_OK && EQ_DOUBLE(r, 4702.0), "VarSub: CY value %f, expected %f\n", r, 4720.0);
3481 hres = pVarSub(&left, &dec, &result);
3482 ok(hres == S_OK && V_VT(&result) == VT_DECIMAL,
3483 "VarSub: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
3484 hres = VarR8FromDec(&V_DECIMAL(&result), &r);
3485 ok(hres == S_OK && EQ_DOUBLE(r, -6.8), "VarSub: DECIMAL value %f, expected %f\n", r, -6.8);
3487 SysFreeString(lbstr);
3488 SysFreeString(rbstr);
3491 static HRESULT (WINAPI *pVarMod)(LPVARIANT,LPVARIANT,LPVARIANT);
3493 static void test_Mod( int line, VARIANT *left, VARIANT *right, VARIANT *expected, HRESULT expres )
3495 VARIANT result;
3496 HRESULT hres;
3498 memset( &result, 0, sizeof(result) );
3499 hres = pVarMod( left, right, &result );
3500 ok_(__FILE__,line)( hres == expres, "wrong result %x/%x\n", hres, expres );
3501 if (hres == S_OK)
3502 ok_(__FILE__,line)( is_expected_variant( &result, expected ),
3503 "got %s expected %s\n", variantstr(&result), variantstr(expected) );
3506 #define VARMOD(vt1,vt2,val1,val2,rvt,rval) \
3507 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
3508 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
3509 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
3510 test_var_call2( __LINE__, pVarMod, &left, &right, &exp )
3512 #define VARMOD2(vt1,vt2,val1,val2,rvt,rval,hexpected) \
3513 V_VT(&left) = VT_##vt1; V_I4(&left) = val1; \
3514 V_VT(&right) = VT_##vt2; V_I4(&right) = val2; \
3515 V_VT(&exp) = VT_##rvt; V_I4(&exp) = rval; \
3516 test_Mod( __LINE__, &left, &right, &exp, hexpected )
3518 static void test_VarMod(void)
3520 VARIANT v1, v2, vDst, left, right, exp;
3521 HRESULT hres;
3522 HRESULT hexpected = 0;
3523 static const WCHAR szNum0[] = {'1','2','5','\0'};
3524 static const WCHAR szNum1[] = {'1','0','\0'};
3525 int l, r;
3526 BOOL lFound, rFound;
3527 BOOL lValid;
3528 BSTR strNum0, strNum1;
3530 CHECKPTR(VarMod);
3532 VARMOD(I1,BOOL,100,10,I4,0);
3533 VARMOD(I1,I1,100,10,I4,0);
3534 VARMOD(I1,UI1,100,10,I4,0);
3535 VARMOD(I1,I2,100,10,I4,0);
3536 VARMOD(I1,UI2,100,10,I4,0);
3537 VARMOD(I1,I4,100,10,I4,0);
3538 VARMOD(I1,UI4,100,10,I4,0);
3539 VARMOD(I1,R4,100,10,I4,0);
3540 VARMOD(I1,R8,100,10,I4,0);
3542 VARMOD(UI1,BOOL,100,10,I2,0);
3543 VARMOD(UI1,I1,100,10,I4,0);
3544 VARMOD(UI1,UI1,100,10,UI1,0);
3545 VARMOD(UI1,I2,100,10,I2,0);
3546 VARMOD(UI1,UI2,100,10,I4,0);
3547 VARMOD(UI1,I4,100,10,I4,0);
3548 VARMOD(UI1,UI4,100,10,I4,0);
3549 VARMOD(UI1,R4,100,10,I4,0);
3550 VARMOD(UI1,R8,100,10,I4,0);
3552 VARMOD(I2,BOOL,100,10,I2,0);
3553 VARMOD(I2,I1,100,10,I4,0);
3554 VARMOD(I2,UI1,100,10,I2,0);
3555 VARMOD(I2,I2,100,10,I2,0);
3556 VARMOD(I2,UI2,100,10,I4,0);
3557 VARMOD(I2,I4,100,10,I4,0);
3558 VARMOD(I2,UI4,100,10,I4,0);
3559 VARMOD(I2,R4,100,10,I4,0);
3560 VARMOD(I2,R8,100,10,I4,0);
3562 VARMOD(I4,BOOL,100,10,I4,0);
3563 VARMOD(I4,I1,100,10,I4,0);
3564 VARMOD(I4,UI1,100,10,I4,0);
3565 VARMOD(I4,I2,100,10,I4,0);
3566 VARMOD(I4,UI2,100,10,I4,0);
3567 VARMOD(I4,I4,100,10,I4,0);
3568 VARMOD(I4,UI4,100,10,I4,0);
3569 VARMOD(I4,R4,100,10,I4,0);
3570 VARMOD(I4,R8,100,10,I4,0);
3571 VARMOD(UI4,BOOL,100,10,I4,0);
3572 VARMOD(UI4,I1,100,10,I4,0);
3573 VARMOD(UI4,UI1,100,10,I4,0);
3574 VARMOD(UI4,I2,100,10,I4,0);
3575 VARMOD(UI4,UI2,100,10,I4,0);
3576 VARMOD(UI4,I4,100,10,I4,0);
3577 VARMOD(UI4,UI4,100,10,I4,0);
3578 VARMOD(UI4,R4,100,10,I4,0);
3579 VARMOD(UI4,R8,100,10,I4,0);
3580 VARMOD(R4,BOOL,100,10,I4,0);
3581 VARMOD(R4,I1,100,10,I4,0);
3582 VARMOD(R4,UI1,100,10,I4,0);
3583 VARMOD(R4,I2,100,10,I4,0);
3584 VARMOD(R4,UI2,100,10,I4,0);
3585 VARMOD(R4,I4,100,10,I4,0);
3586 VARMOD(R4,UI4,100,10,I4,0);
3587 VARMOD(R4,R4,100,10,I4,0);
3588 VARMOD(R4,R8,100,10,I4,0);
3589 VARMOD(R8,BOOL,100,10,I4,0);
3590 VARMOD(R8,I1,100,10,I4,0);
3591 VARMOD(R8,UI1,100,10,I4,0);
3592 VARMOD(R8,I2,100,10,I4,0);
3593 VARMOD(R8,UI2,100,10,I4,0);
3594 VARMOD(R8,I4,100,10,I4,0);
3595 VARMOD(R8,UI4,100,10,I4,0);
3596 VARMOD(R8,R4,100,10,I4,0);
3597 VARMOD(R8,R8,100,10,I4,0);
3599 VARMOD(INT,INT,100,10,I4,0);
3600 VARMOD(INT,UINT,100,10,I4,0);
3602 VARMOD(BOOL,BOOL,100,10,I2,0);
3603 VARMOD(BOOL,I1,100,10,I4,0);
3604 VARMOD(BOOL,UI1,100,10,I2,0);
3605 VARMOD(BOOL,I2,100,10,I2,0);
3606 VARMOD(BOOL,UI2,100,10,I4,0);
3607 VARMOD(BOOL,I4,100,10,I4,0);
3608 VARMOD(BOOL,UI4,100,10,I4,0);
3609 VARMOD(BOOL,R4,100,10,I4,0);
3610 VARMOD(BOOL,R8,100,10,I4,0);
3611 VARMOD(BOOL,DATE,100,10,I4,0);
3613 VARMOD(DATE,BOOL,100,10,I4,0);
3614 VARMOD(DATE,I1,100,10,I4,0);
3615 VARMOD(DATE,UI1,100,10,I4,0);
3616 VARMOD(DATE,I2,100,10,I4,0);
3617 VARMOD(DATE,UI2,100,10,I4,0);
3618 VARMOD(DATE,I4,100,10,I4,0);
3619 VARMOD(DATE,UI4,100,10,I4,0);
3620 VARMOD(DATE,R4,100,10,I4,0);
3621 VARMOD(DATE,R8,100,10,I4,0);
3622 VARMOD(DATE,DATE,100,10,I4,0);
3624 strNum0 = SysAllocString(szNum0);
3625 strNum1 = SysAllocString(szNum1);
3626 VARMOD(BSTR,BSTR,strNum0,strNum1,I4,5);
3627 VARMOD(BSTR,I1,strNum0,10,I4,5);
3628 VARMOD(BSTR,I2,strNum0,10,I4,5);
3629 VARMOD(BSTR,I4,strNum0,10,I4,5);
3630 VARMOD(BSTR,R4,strNum0,10,I4,5);
3631 VARMOD(BSTR,R8,strNum0,10,I4,5);
3632 VARMOD(I4,BSTR,125,strNum1,I4,5);
3634 if (has_i8)
3636 VARMOD(BOOL,I8,100,10,I8,0);
3637 VARMOD(I1,I8,100,10,I8,0);
3638 VARMOD(UI1,I8,100,10,I8,0);
3639 VARMOD(I2,I8,100,10,I8,0);
3640 VARMOD(I4,I8,100,10,I8,0);
3641 VARMOD(UI4,I8,100,10,I8,0);
3642 VARMOD(R4,I8,100,10,I8,0);
3643 VARMOD(R8,I8,100,10,I8,0);
3644 VARMOD(DATE,I8,100,10,I8,0);
3646 VARMOD(I8,BOOL,100,10,I8,0);
3647 VARMOD(I8,I1,100,10,I8,0);
3648 VARMOD(I8,UI1,100,10,I8,0);
3649 VARMOD(I8,I2,100,10,I8,0);
3650 VARMOD(I8,UI2,100,10,I8,0);
3651 VARMOD(I8,I4,100,10,I8,0);
3652 VARMOD(I8,UI4,100,10,I8,0);
3653 VARMOD(I8,R4,100,10,I8,0);
3654 VARMOD(I8,R8,100,10,I8,0);
3655 VARMOD(I8,I8,100,10,I8,0);
3657 VARMOD(BSTR,I8,strNum0,10,I8,5);
3660 /* test all combinations of types */
3661 for(l = 0; l < VT_BSTR_BLOB; l++)
3663 SKIPTESTS(l);
3665 for(r = 0; r < VT_BSTR_BLOB; r++)
3667 SKIPTESTS(r);
3669 if(l == VT_BSTR) continue;
3670 if(l == VT_DISPATCH) continue;
3671 if(r == VT_BSTR) continue;
3672 if(r == VT_DISPATCH) continue;
3674 lFound = TRUE;
3675 lValid = TRUE;
3676 switch(l)
3678 case VT_EMPTY:
3679 case VT_NULL:
3680 case VT_I1:
3681 case VT_UI1:
3682 case VT_I2:
3683 case VT_UI2:
3684 case VT_I4:
3685 case VT_I8:
3686 case VT_UI4:
3687 case VT_UI8:
3688 case VT_INT:
3689 case VT_UINT:
3690 case VT_R4:
3691 case VT_R8:
3692 case VT_BOOL:
3693 case VT_DATE:
3694 case VT_CY:
3695 case VT_DECIMAL:
3696 hexpected = S_OK;
3697 break;
3698 case VT_ERROR:
3699 case VT_VARIANT:
3700 case VT_UNKNOWN:
3701 case VT_RECORD:
3702 lValid = FALSE;
3703 break;
3704 default:
3705 lFound = FALSE;
3706 hexpected = DISP_E_BADVARTYPE;
3707 break;
3710 rFound = TRUE;
3711 switch(r)
3713 case VT_EMPTY:
3714 case VT_NULL:
3715 case VT_I1:
3716 case VT_UI1:
3717 case VT_I2:
3718 case VT_UI2:
3719 case VT_I4:
3720 case VT_I8:
3721 case VT_UI4:
3722 case VT_UI8:
3723 case VT_INT:
3724 case VT_UINT:
3725 case VT_R4:
3726 case VT_R8:
3727 case VT_BOOL:
3728 case VT_DATE:
3729 case VT_DECIMAL:
3730 case VT_CY:
3731 hexpected = S_OK;
3732 break;
3733 case VT_ERROR:
3734 case VT_VARIANT:
3735 case VT_UNKNOWN:
3736 case VT_RECORD:
3737 break;
3738 default:
3739 rFound = FALSE;
3740 break;
3743 if(((l == VT_I8) && (r == VT_INT)) || ((l == VT_INT) && (r == VT_I8)))
3745 hexpected = DISP_E_TYPEMISMATCH;
3746 } else if((l == VT_EMPTY) && (r == VT_NULL))
3748 hexpected = S_OK;
3749 } else if((l == VT_NULL) && (r == VT_EMPTY))
3751 hexpected = S_OK;
3752 } else if((l == VT_EMPTY) && (r == VT_CY))
3754 hexpected = S_OK;
3755 } else if((l == VT_EMPTY) && (r == VT_RECORD))
3757 hexpected = DISP_E_TYPEMISMATCH;
3758 } else if((r == VT_EMPTY) && lFound && lValid)
3760 hexpected = DISP_E_DIVBYZERO;
3761 } else if((l == VT_ERROR) || ((r == VT_ERROR) && lFound && lValid))
3763 hexpected = DISP_E_TYPEMISMATCH;
3764 } else if((l == VT_NULL) && (r == VT_NULL))
3766 hexpected = S_OK;
3767 } else if((l == VT_VARIANT) || ((r == VT_VARIANT) && lFound && lValid))
3769 hexpected = DISP_E_TYPEMISMATCH;
3770 } else if((l == VT_NULL) && (r == VT_RECORD))
3772 hexpected = DISP_E_TYPEMISMATCH;
3773 } else if((l == VT_I8) && (r == VT_DECIMAL))
3775 hexpected = S_OK;
3776 } else if((l == VT_DECIMAL) && (r == VT_I8))
3778 hexpected = S_OK;
3779 } else if((l == VT_UNKNOWN) || ((r == VT_UNKNOWN) && lFound && lValid))
3781 hexpected = DISP_E_TYPEMISMATCH;
3782 } else if((l == VT_NULL) && rFound)
3784 hexpected = S_OK;
3785 } else if(l == VT_RECORD)
3787 hexpected = DISP_E_TYPEMISMATCH;
3788 } else if((r == VT_RECORD) && lValid && lFound)
3790 hexpected = DISP_E_TYPEMISMATCH;
3791 } else if((l == VT_EMPTY) && (r == VT_EMPTY))
3793 hexpected = DISP_E_DIVBYZERO;
3794 } else if((l == VT_CY) && !rFound)
3796 hexpected = DISP_E_BADVARTYPE;
3797 } else if(lFound && !rFound)
3799 hexpected = DISP_E_BADVARTYPE;
3800 } else if(!lFound && rFound)
3802 hexpected = DISP_E_BADVARTYPE;
3803 } else if((r == VT_NULL) && lFound && lValid)
3805 hexpected = S_OK;
3806 } else if((l == VT_NULL) || (r == VT_NULL))
3808 hexpected = DISP_E_BADVARTYPE;
3809 } else if((l == VT_VARIANT) || (r == VT_VARIANT))
3811 hexpected = DISP_E_BADVARTYPE;
3812 } else if(!lFound && !rFound)
3814 hexpected = DISP_E_BADVARTYPE;
3817 V_VT(&v1) = l;
3818 V_VT(&v2) = r;
3820 if(l == VT_CY)
3821 V_CY(&v1).int64 = 1000000;
3822 else if(l == VT_R4)
3823 V_R4(&v1) = 100;
3824 else if(l == VT_R8)
3825 V_R8(&v1) = 100;
3826 else if(l == VT_UI8)
3827 V_UI8(&v1) = 100;
3828 else if(l == VT_I8)
3829 V_I8(&v1) = 100;
3830 else if(l == VT_DATE)
3831 V_DATE(&v1) = 1000;
3832 else if (l == VT_DECIMAL)
3834 V_DECIMAL(&v1).Hi32 = 0;
3835 U1(V_DECIMAL(&v1)).Lo64 = 100;
3836 U(V_DECIMAL(&v1)).signscale = 0;
3838 else
3839 V_I4(&v1) = 10000;
3841 if(r == VT_CY)
3842 V_CY(&v2).int64 = 10000;
3843 else if(r == VT_R4)
3844 V_R4(&v2) = 100;
3845 else if(r == VT_R8)
3846 V_R8(&v2) = 100;
3847 else if(r == VT_UI8)
3848 V_UI8(&v2) = 100;
3849 else if(r == VT_I8)
3850 V_I8(&v2) = 100;
3851 else if(r == VT_DATE)
3852 V_DATE(&v2) = 1000;
3853 else if (r == VT_DECIMAL)
3855 V_DECIMAL(&v2).Hi32 = 0;
3856 U1(V_DECIMAL(&v2)).Lo64 = 100;
3857 U(V_DECIMAL(&v2)).signscale = 0;
3859 else
3860 V_I4(&v2) = 10000;
3862 if ((l != VT_I8 && l != VT_UI8 && r != VT_I8 && r != VT_UI8) || has_i8)
3864 hres = pVarMod(&v1,&v2,&vDst);
3865 ok(hres == hexpected,
3866 "VarMod: expected 0x%x, got 0x%X for l type of %d, r type of %d,\n", hexpected, hres, l, r);
3872 /****************************/
3873 /* test some bad parameters */
3874 VARMOD(I4,I4,-1,-1,I4,0);
3876 /* test modulus with zero */
3877 VARMOD2(I4,I4,100,0,EMPTY,0,DISP_E_DIVBYZERO);
3879 VARMOD(I4,I4,0,10,I4,0); /* test 0 mod 10 */
3881 /* right parameter is type empty */
3882 VARMOD2(I4,EMPTY,100,10,EMPTY,0,DISP_E_DIVBYZERO);
3884 /* left parameter is type empty */
3885 VARMOD2(EMPTY,I4,100,10,I4,0,S_OK);
3887 /* mod with a null left value */
3888 VARMOD2(NULL,I4,125,10,NULL,0,S_OK);
3890 /* mod with a null right value */
3891 VARMOD2(I4,NULL,100,10,NULL,0,S_OK);
3893 /* void left value */
3894 VARMOD2(VOID,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3896 /* void right value */
3897 VARMOD2(I4,VOID,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3899 /* null left value, void right value */
3900 VARMOD2(NULL,VOID,100,10,EMPTY, 0, DISP_E_BADVARTYPE);
3902 /* void left value, null right value */
3903 VARMOD2(VOID,NULL,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3905 /* some currencies */
3906 V_VT(&v1) = VT_CY;
3907 V_VT(&v2) = VT_CY;
3908 V_CY(&v1).int64 = 100000;
3909 V_CY(&v2).int64 = 100000;
3910 hres = pVarMod(&v1,&v2,&vDst);
3911 ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == 0,
3912 "VarMod: expected 0x%x,%d,%d, got 0x%X,%d,%d\n", S_OK, VT_I4, 0, hres, V_VT(&vDst), V_I4(&vDst));
3914 V_VT(&v1) = VT_I4;
3915 V_VT(&v2) = VT_CY;
3916 V_I4(&v1) = 100;
3917 V_CY(&v2).int64 = 100000;
3918 hres = pVarMod(&v1,&v2,&vDst);
3919 ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == 0,
3920 "VarMod: expected 0x%x,%d,%d, got 0x%X,%d,%d\n", S_OK, VT_I4, 0, hres, V_VT(&vDst), V_I4(&vDst));
3922 /* some decimals */
3923 V_VT(&v1) = VT_DECIMAL;
3924 V_VT(&v2) = VT_DECIMAL;
3925 VarDecFromI4(100, &V_DECIMAL(&v1));
3926 VarDecFromI4(10, &V_DECIMAL(&v2));
3927 hres = pVarMod(&v1,&v2,&vDst);
3928 ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == 0,
3929 "VarMod: expected 0x%x,%d,%d, got 0x%X,%d,%d\n", S_OK, VT_I4, 0, hres, V_VT(&vDst), V_I4(&vDst));
3931 V_VT(&v1) = VT_I4;
3932 V_VT(&v2) = VT_DECIMAL;
3933 V_I4(&v1) = 100;
3934 VarDecFromI4(10, &V_DECIMAL(&v2));
3935 hres = pVarMod(&v1,&v2,&vDst);
3936 ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == 0,
3937 "VarMod: expected 0x%x,%d,%d, got 0x%X,%d,%d\n", S_OK, VT_I4, 0, hres, V_VT(&vDst), V_I4(&vDst));
3939 VARMOD2(UINT,I4,100,10,I4,0,S_OK);
3941 /* test that an error results in the type of the result changing but not its value */
3942 V_VT(&v1) = VT_UNKNOWN;
3943 V_VT(&v2) = VT_EMPTY;
3944 V_I4(&v1) = 100;
3945 V_CY(&v2).int64 = 100000;
3946 V_VT(&vDst) = VT_I4;
3947 V_I4(&vDst) = 1231;
3948 hres = pVarMod(&v1,&v2,&vDst);
3949 ok(hres == DISP_E_TYPEMISMATCH && V_VT(&vDst) == VT_EMPTY && V_I4(&vDst) == 1231,
3950 "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));
3953 /* test some invalid types */
3954 /*TODO: not testing VT_DISPATCH */
3955 if (has_i8)
3957 VARMOD2(I8,INT,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
3959 VARMOD2(ERROR,I4,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
3960 VARMOD2(VARIANT,I4,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
3961 VARMOD2(UNKNOWN,I4,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
3962 VARMOD2(VOID,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3963 VARMOD2(HRESULT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3964 VARMOD2(PTR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3965 VARMOD2(SAFEARRAY,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3966 VARMOD2(CARRAY,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3967 VARMOD2(USERDEFINED,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3968 VARMOD2(LPSTR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3969 VARMOD2(LPWSTR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3970 VARMOD2(RECORD,I4,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
3971 VARMOD2(FILETIME,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3972 VARMOD2(BLOB,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3973 VARMOD2(STREAM,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3974 VARMOD2(STORAGE,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3975 VARMOD2(STREAMED_OBJECT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3976 VARMOD2(STORED_OBJECT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3977 VARMOD2(BLOB_OBJECT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3978 VARMOD2(CF,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3979 VARMOD2(CLSID,CLSID,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3980 VARMOD2(VECTOR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3981 VARMOD2(ARRAY,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3982 VARMOD2(BYREF,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3984 /* test some more invalid types */
3985 V_VT(&v1) = 456;
3986 V_VT(&v2) = 234;
3987 V_I4(&v1) = 100;
3988 V_I4(&v2)= 10;
3989 hres = pVarMod(&v1,&v2,&vDst);
3990 ok(hres == DISP_E_BADVARTYPE && V_VT(&vDst) == VT_EMPTY,
3991 "VarMod: expected 0x%x,%d, got 0x%X,%d\n", DISP_E_BADVARTYPE, VT_EMPTY, hres, V_VT(&vDst));
3993 SysFreeString(strNum0);
3994 SysFreeString(strNum1);
3997 static HRESULT (WINAPI *pVarFix)(LPVARIANT,LPVARIANT);
3999 #define VARFIX(vt,val,rvt,rval) \
4000 V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
4001 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
4002 test_var_call1( __LINE__, pVarFix, &v, &exp )
4004 static void test_VarFix(void)
4006 static const WCHAR szNumMinus1[] = {'-','1','\0' };
4007 HRESULT hres;
4008 VARIANT v, exp, vDst;
4009 DECIMAL *pdec = &V_DECIMAL(&v);
4010 CY *pcy = &V_CY(&v);
4011 size_t i;
4013 CHECKPTR(VarFix);
4015 /* Test all possible V_VT values */
4016 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
4018 VARTYPE vt;
4020 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
4022 BOOL bFail = TRUE;
4024 SKIPTESTS(vt);
4026 memset(&v, 0, sizeof(v));
4027 V_VT(&v) = vt | ExtraFlags[i];
4028 V_VT(&vDst) = VT_EMPTY;
4030 switch (V_VT(&v))
4032 case VT_UI1: case VT_I2: case VT_I4: case VT_R4: case VT_R8:
4033 case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
4034 case VT_DATE: case VT_CY:
4035 bFail = FALSE;
4036 break;
4037 case VT_I8:
4038 if (has_i8)
4039 bFail = FALSE;
4040 break;
4043 hres = pVarFix(&v,&vDst);
4044 if (bFail)
4045 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
4046 "VarFix: expected failure, got 0x%X vt %d|0x%X\n",
4047 hres, vt, ExtraFlags[i]);
4048 else
4049 ok(hres == S_OK, "VarFix: expected S_OK, got 0x%X vt %d|0x%X\n",
4050 hres, vt, ExtraFlags[i]);
4054 VARFIX(BOOL,VARIANT_TRUE,I2,VARIANT_TRUE);
4055 VARFIX(BOOL,VARIANT_FALSE,I2,0);
4056 VARFIX(BOOL,1,I2,1);
4057 VARFIX(UI1,1,UI1,1);
4058 VARFIX(I2,-1,I2,-1);
4059 VARFIX(I4,-1,I4,-1);
4060 if (has_i8)
4062 VARFIX(I8,-1,I8,-1);
4064 VARFIX(R4,1.4f,R4,1);
4065 VARFIX(R4,1.5f,R4,1);
4066 VARFIX(R4,1.6f,R4,1);
4067 VARFIX(R4,-1.4f,R4,-1);
4068 VARFIX(R4,-1.5f,R4,-1);
4069 VARFIX(R4,-1.6f,R4,-1);
4070 /* DATE & R8 round as for R4 */
4071 VARFIX(DATE,-1,DATE,-1);
4072 VARFIX(R8,-1,R8,-1);
4073 VARFIX(BSTR,(BSTR)szNumMinus1,R8,-1);
4075 V_VT(&v) = VT_EMPTY;
4076 hres = pVarFix(&v,&vDst);
4077 ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
4078 "VarFix: expected 0x0,%d,0 got 0x%X,%d,%d\n", VT_EMPTY,
4079 hres, V_VT(&vDst), V_I2(&vDst));
4081 V_VT(&v) = VT_NULL;
4082 hres = pVarFix(&v,&vDst);
4083 ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
4084 "VarFix: expected 0x0,%d got 0x%X,%d\n", VT_NULL, hres, V_VT(&vDst));
4086 V_VT(&v) = VT_DECIMAL;
4087 S(U(*pdec)).sign = DECIMAL_NEG;
4088 S(U(*pdec)).scale = 0;
4089 pdec->Hi32 = 0;
4090 S1(U1(*pdec)).Mid32 = 0;
4091 S1(U1(*pdec)).Lo32 = 1;
4092 hres = pVarFix(&v,&vDst);
4093 ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL && !memcmp(&V_DECIMAL(&v), &V_DECIMAL(&vDst), sizeof(DECIMAL)),
4094 "VarFix: expected 0x0,%d,identical, got 0x%X,%d\n", VT_DECIMAL,
4095 hres, V_VT(&vDst));
4097 /* FIXME: Test some fractional decimals when VarDecFix is implemented */
4099 V_VT(&v) = VT_CY;
4100 pcy->int64 = -10000;
4101 hres = pVarFix(&v,&vDst);
4102 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
4103 "VarFix: VT_CY wrong, hres=0x%X\n", hres);
4105 V_VT(&v) = VT_CY;
4106 pcy->int64 = -16000;
4107 hres = pVarFix(&v,&vDst);
4108 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
4109 "VarFix: VT_CY wrong, hres=0x%X\n", hres);
4112 static HRESULT (WINAPI *pVarInt)(LPVARIANT,LPVARIANT);
4114 #define VARINT(vt,val,rvt,rval) \
4115 V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
4116 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
4117 test_var_call1( __LINE__, pVarInt, &v, &exp )
4119 static void test_VarInt(void)
4121 static const WCHAR szNumMinus1[] = {'-','1','\0' };
4122 HRESULT hres;
4123 VARIANT v, exp, vDst;
4124 DECIMAL *pdec = &V_DECIMAL(&v);
4125 CY *pcy = &V_CY(&v);
4126 size_t i;
4128 CHECKPTR(VarInt);
4130 /* Test all possible V_VT values */
4131 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
4133 VARTYPE vt;
4135 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
4137 BOOL bFail = TRUE;
4139 SKIPTESTS(vt);
4141 memset(&v, 0, sizeof(v));
4142 V_VT(&v) = vt | ExtraFlags[i];
4143 V_VT(&vDst) = VT_EMPTY;
4145 switch (V_VT(&v))
4147 case VT_UI1: case VT_I2: case VT_I4: case VT_R4: case VT_R8:
4148 case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
4149 case VT_DATE: case VT_CY:
4150 bFail = FALSE;
4151 break;
4152 case VT_I8:
4153 if (has_i8)
4154 bFail = FALSE;
4155 break;
4158 hres = pVarInt(&v,&vDst);
4159 if (bFail)
4160 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
4161 "VarInt: expected failure, got 0x%X vt %d|0x%X\n",
4162 hres, vt, ExtraFlags[i]);
4163 else
4164 ok(hres == S_OK, "VarInt: expected S_OK, got 0x%X vt %d|0x%X\n",
4165 hres, vt, ExtraFlags[i]);
4169 VARINT(BOOL,VARIANT_TRUE,I2,VARIANT_TRUE);
4170 VARINT(BOOL,VARIANT_FALSE,I2,0);
4171 VARINT(BOOL,1,I2,1);
4172 VARINT(UI1,1,UI1,1);
4173 VARINT(I2,-1,I2,-1);
4174 VARINT(I4,-1,I4,-1);
4175 if (has_i8)
4177 VARINT(I8,-1,I8,-1);
4179 VARINT(R4,1.4f,R4,1);
4180 VARINT(R4,1.5f,R4,1);
4181 VARINT(R4,1.6f,R4,1);
4182 VARINT(R4,-1.4f,R4,-2); /* Note these 3 are different from VarFix */
4183 VARINT(R4,-1.5f,R4,-2);
4184 VARINT(R4,-1.6f,R4,-2);
4185 /* DATE & R8 round as for R4 */
4186 VARINT(DATE,-1,DATE,-1);
4187 VARINT(R8,-1,R8,-1);
4188 VARINT(BSTR,(BSTR)szNumMinus1,R8,-1);
4190 V_VT(&v) = VT_EMPTY;
4191 hres = pVarInt(&v,&vDst);
4192 ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
4193 "VarInt: expected 0x0,%d,0 got 0x%X,%d,%d\n", VT_EMPTY,
4194 hres, V_VT(&vDst), V_I2(&vDst));
4196 V_VT(&v) = VT_NULL;
4197 hres = pVarInt(&v,&vDst);
4198 ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
4199 "VarInt: expected 0x0,%d got 0x%X,%d\n", VT_NULL, hres, V_VT(&vDst));
4201 V_VT(&v) = VT_DECIMAL;
4202 S(U(*pdec)).sign = DECIMAL_NEG;
4203 S(U(*pdec)).scale = 0;
4204 pdec->Hi32 = 0;
4205 S1(U1(*pdec)).Mid32 = 0;
4206 S1(U1(*pdec)).Lo32 = 1;
4207 hres = pVarInt(&v,&vDst);
4208 ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL && !memcmp(&V_DECIMAL(&v), &V_DECIMAL(&vDst), sizeof(DECIMAL)),
4209 "VarInt: expected 0x0,%d,identical, got 0x%X,%d\n", VT_DECIMAL,
4210 hres, V_VT(&vDst));
4212 /* FIXME: Test some fractional decimals when VarDecInt is implemented */
4214 V_VT(&v) = VT_CY;
4215 pcy->int64 = -10000;
4216 hres = pVarInt(&v,&vDst);
4217 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
4218 "VarInt: VT_CY wrong, hres=0x%X\n", hres);
4220 V_VT(&v) = VT_CY;
4221 pcy->int64 = -11000;
4222 hres = pVarInt(&v,&vDst);
4223 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -20000,
4224 "VarInt: VT_CY wrong, hres=0x%X 0x%x%08x\n",
4225 hres, (DWORD)(V_CY(&vDst).int64 >> 32), (DWORD)V_CY(&vDst).int64);
4228 static HRESULT (WINAPI *pVarNeg)(LPVARIANT,LPVARIANT);
4230 #define VARNEG(vt,val,rvt,rval) \
4231 V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
4232 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
4233 test_var_call1( __LINE__, pVarNeg, &v, &exp )
4235 static void test_VarNeg(void)
4237 static const WCHAR szNumMinus1[] = {'-','1','\0' };
4238 static const WCHAR szNum1[] = {'1','\0' };
4239 HRESULT hres;
4240 VARIANT v, exp, vDst;
4241 DECIMAL *pdec = &V_DECIMAL(&v);
4242 CY *pcy = &V_CY(&v);
4243 size_t i;
4245 CHECKPTR(VarNeg);
4247 /* Test all possible V_VT values. But don't test the exact return values
4248 * except for success/failure, since M$ made a hash of them in the
4249 * native version. This at least ensures (as with all tests here) that
4250 * we will notice if/when new vtypes/flags are added in native.
4252 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
4254 VARTYPE vt;
4256 for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
4258 BOOL bFail = TRUE;
4260 SKIPTESTS(vt);
4262 memset(&v, 0, sizeof(v));
4263 V_VT(&v) = vt | ExtraFlags[i];
4264 V_VT(&vDst) = VT_EMPTY;
4266 switch (V_VT(&v))
4268 case VT_UI1: case VT_I2: case VT_I4:
4269 case VT_R4: case VT_R8:
4270 case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
4271 case VT_DATE: case VT_CY:
4272 bFail = FALSE;
4273 break;
4274 case VT_I8:
4275 if (has_i8)
4276 bFail = FALSE;
4279 hres = pVarNeg(&v,&vDst);
4280 if (bFail)
4281 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
4282 "VarNeg: expected failure, got 0x%X vt %d|0x%X\n",
4283 hres, vt, ExtraFlags[i]);
4284 else
4285 ok(hres == S_OK, "VarNeg: expected S_OK, got 0x%X vt %d|0x%X\n",
4286 hres, vt, ExtraFlags[i]);
4290 VARNEG(BOOL,VARIANT_TRUE,I2,1);
4291 VARNEG(BOOL,VARIANT_FALSE,I2,0);
4292 VARNEG(BOOL,1,I2,-1);
4293 VARNEG(UI1,1,I2,-1);
4294 VARNEG(UI1,254,I2,-254);
4295 VARNEG(I2,-32768,I4,32768);
4296 VARNEG(I2,-1,I2,1);
4297 VARNEG(I2,1,I2,-1);
4298 VARNEG(I4,-((int)(~0u >> 1)) - 1,R8,-2147483648u);
4299 VARNEG(I4,-1,I4,1);
4300 VARNEG(I4,1,I4,-1);
4301 if (has_i8)
4303 VARNEG(I8,1,I8,-1);
4304 VARNEG(I8,-1,I8,1);
4306 VARNEG(R4,1,R4,-1);
4307 VARNEG(R4,-1,R4,1);
4308 VARNEG(DATE,1,DATE,-1);
4309 VARNEG(DATE,-1,DATE,1);
4310 VARNEG(R8,1,R8,-1);
4311 VARNEG(R8,-1,R8,1);
4312 VARNEG(BSTR,(BSTR)szNumMinus1,R8,1);
4313 VARNEG(BSTR,(BSTR)szNum1,R8,-1);
4315 V_VT(&v) = VT_EMPTY;
4316 hres = pVarNeg(&v,&vDst);
4317 ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
4318 "VarNeg: expected 0x0,%d,0 got 0x%X,%d,%d\n", VT_EMPTY,
4319 hres, V_VT(&vDst), V_I2(&vDst));
4321 V_VT(&v) = VT_NULL;
4322 hres = pVarNeg(&v,&vDst);
4323 ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
4324 "VarNeg: expected 0x0,%d got 0x%X,%d\n", VT_NULL, hres, V_VT(&vDst));
4326 V_VT(&v) = VT_DECIMAL;
4327 S(U(*pdec)).sign = DECIMAL_NEG;
4328 S(U(*pdec)).scale = 0;
4329 pdec->Hi32 = 0;
4330 S1(U1(*pdec)).Mid32 = 0;
4331 S1(U1(*pdec)).Lo32 = 1;
4332 hres = pVarNeg(&v,&vDst);
4333 ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
4334 S(U(V_DECIMAL(&vDst))).sign == 0,
4335 "VarNeg: expected 0x0,%d,0x00, got 0x%X,%d,%02x\n", VT_DECIMAL,
4336 hres, V_VT(&vDst), S(U(V_DECIMAL(&vDst))).sign);
4338 S(U(*pdec)).sign = 0;
4339 hres = pVarNeg(&v,&vDst);
4340 ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
4341 S(U(V_DECIMAL(&vDst))).sign == DECIMAL_NEG,
4342 "VarNeg: expected 0x0,%d,0x7f, got 0x%X,%d,%02x\n", VT_DECIMAL,
4343 hres, V_VT(&vDst), S(U(V_DECIMAL(&vDst))).sign);
4345 V_VT(&v) = VT_CY;
4346 pcy->int64 = -10000;
4347 hres = pVarNeg(&v,&vDst);
4348 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == 10000,
4349 "VarNeg: VT_CY wrong, hres=0x%X\n", hres);
4352 static HRESULT (WINAPI *pVarRound)(LPVARIANT,int,LPVARIANT);
4354 static void test_Round( int line, VARIANT *arg, int deci, VARIANT *expected )
4356 VARIANT result;
4357 HRESULT hres;
4359 memset( &result, 0, sizeof(result) );
4360 hres = pVarRound( arg, deci, &result );
4361 ok_(__FILE__,line)( hres == S_OK, "wrong result %x\n", hres );
4362 if (hres == S_OK)
4363 ok_(__FILE__,line)( is_expected_variant( &result, expected ),
4364 "got %s expected %s\n", variantstr(&result), variantstr(expected) );
4366 #define VARROUND(vt,val,deci,rvt,rval) \
4367 V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
4368 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
4369 test_Round( __LINE__, &v, deci, &exp )
4371 struct decimal_t {
4372 BYTE scale;
4373 BYTE sign;
4374 ULONG Hi32;
4375 ULONG Mid32;
4376 ULONG Lo32;
4379 struct decimal_round_t {
4380 struct decimal_t source;
4381 struct decimal_t ret;
4382 int dec;
4385 static const struct decimal_round_t decimal_round_data[] = {
4386 {{ 0, DECIMAL_NEG, 0, 0, 1 }, { 0, DECIMAL_NEG, 0, 0, 1 }, 0},
4387 {{ 0, 0, 0, 0, 1 }, { 0, 0, 0, 0, 1 }, 0},
4388 {{ 2, 0, 0, 0, 155 }, { 0, 0, 0, 0, 16 }, 1},
4389 {{ 2, 0, 0, 0, 155 }, { 1, 0, 0, 0, 2 }, 0},
4390 {{ 2, 0, 0, 0, 199 }, { 1, 0, 0, 0, 20 }, 1},
4391 {{ 2, 0, 0, 0, 199 }, { 2, 0, 0, 0, 199 }, 2},
4392 {{ 2, DECIMAL_NEG, 0, 0, 199 }, { 2, DECIMAL_NEG, 0, 0, 199 }, 2},
4393 {{ 2, DECIMAL_NEG, 0, 0, 55 }, { 2, DECIMAL_NEG, 0, 0, 6 }, 1},
4394 {{ 2, 0, 0, 0, 55 }, { 2, 0, 0, 0, 6 }, 1},
4395 {{ 2, 0, 0, 0, 1999 }, { 1, 0, 0, 0, 200 }, 1},
4398 static void test_VarRound(void)
4400 static WCHAR szNumMin[] = {'-','1','.','4','4','9','\0' };
4401 static WCHAR szNum[] = {'1','.','4','5','1','\0' };
4402 HRESULT hres;
4403 VARIANT v, exp, vDst;
4404 CY *pcy = &V_CY(&v);
4405 char buff[8];
4406 int i;
4408 CHECKPTR(VarRound);
4410 /* first check valid integer types */
4411 VARROUND(BOOL,VARIANT_TRUE,0,I2,-1);
4412 VARROUND(BOOL,VARIANT_FALSE,0,I2,0);
4413 VARROUND(BOOL,1,0,I2,1);
4414 VARROUND(UI1,1,0,UI1,1);
4415 VARROUND(UI1,254,0,UI1,254);
4416 VARROUND(I2,-32768,0,I2,-32768);
4417 VARROUND(I2,-1,0,I2,-1);
4418 VARROUND(I2,1,0,I2,1);
4419 VARROUND(I4,-((int)(~0u >> 1)) - 1,0,I4,-((int)(~0u >> 1)) - 1);
4420 VARROUND(I4,-1,0,I4,-1);
4421 VARROUND(I4,1,0,I4,1);
4424 /* MSDN states that rounding of R4/R8 is dependent on the underlying
4425 * bit pattern of the number and so is architecture dependent. In this
4426 * case Wine returns .2 (which is more correct) and Native returns .3
4429 VARROUND(R4,1.0f,0,R4,1.0f);
4430 VARROUND(R4,-1.0f,0,R4,-1.0f);
4431 VARROUND(R8,1.0,0,R8,1.0);
4432 VARROUND(R8,-1.0,0,R8,-1.0);
4434 /* floating point numbers aren't exactly equal and we can't just
4435 * compare the first few digits. */
4436 VARROUND(DATE,1.451,1,DATE,1.5);
4437 VARROUND(DATE,-1.449,1,DATE,-1.4);
4439 /* replace the decimal separator */
4440 GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, ARRAY_SIZE(buff));
4441 if (!buff[1]) {
4442 szNumMin[2] = buff[0];
4443 szNum[1] = buff[0];
4444 VARROUND(BSTR,(BSTR)szNumMin,1,R8,-1.40);
4445 VARROUND(BSTR,(BSTR)szNum,1,R8,1.50);
4446 } else {
4447 skip("Skipping VarRound(BSTR) as decimal separator is '%s'\n", buff);
4450 VARROUND(R4,1.23456f,0,R4,1.0f);
4451 VARROUND(R4,1.23456f,1,R4,1.2f);
4452 VARROUND(R4,1.23456f,2,R4,1.23f);
4453 VARROUND(R4,1.23456f,3,R4,1.235f);
4454 VARROUND(R4,1.23456f,4,R4,1.2346f);
4455 VARROUND(R4,-1.23456f,0,R4,-1.0f);
4456 VARROUND(R4,-1.23456f,1,R4,-1.2f);
4457 VARROUND(R4,-1.23456f,2,R4,-1.23f);
4458 VARROUND(R4,-1.23456f,3,R4,-1.235f);
4459 VARROUND(R4,-1.23456f,4,R4,-1.2346f);
4461 VARROUND(R8,1.23456,0,R8,1.0);
4462 VARROUND(R8,1.23456,1,R8,1.2);
4463 VARROUND(R8,1.23456,2,R8,1.23);
4464 VARROUND(R8,1.23456,3,R8,1.235);
4465 VARROUND(R8,1.23456,4,R8,1.2346);
4466 VARROUND(R8,-1.23456,0,R8,-1.0);
4467 VARROUND(R8,-1.23456,1,R8,-1.2);
4468 VARROUND(R8,-1.23456,2,R8,-1.23);
4469 VARROUND(R8,-1.23456,3,R8,-1.235);
4470 VARROUND(R8,-1.23456,4,R8,-1.2346);
4472 V_VT(&v) = VT_EMPTY;
4473 hres = pVarRound(&v,0,&vDst);
4474 ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
4475 "VarRound: expected 0x0,%d,0 got 0x%X,%d,%d\n", VT_EMPTY,
4476 hres, V_VT(&vDst), V_I2(&vDst));
4478 V_VT(&v) = VT_NULL;
4479 hres = pVarRound(&v,0,&vDst);
4480 ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
4481 "VarRound: expected 0x0,%d got 0x%X,%d\n", VT_NULL, hres, V_VT(&vDst));
4483 /* VT_DECIMAL */
4484 for (i = 0; i < ARRAY_SIZE(decimal_round_data); i++)
4486 const struct decimal_round_t *ptr = &decimal_round_data[i];
4487 DECIMAL *pdec;
4489 pdec = &V_DECIMAL(&v);
4490 V_VT(&v) = VT_DECIMAL;
4491 S(U(*pdec)).sign = ptr->source.sign;
4492 S(U(*pdec)).scale = ptr->source.scale;
4493 pdec->Hi32 = ptr->source.Hi32;
4494 S1(U1(*pdec)).Mid32 = ptr->source.Mid32;
4495 S1(U1(*pdec)).Lo32 = ptr->source.Lo32;
4496 VariantInit(&vDst);
4497 hres = pVarRound(&v, ptr->dec, &vDst);
4498 ok(hres == S_OK, "%d: got 0x%08x\n", i, hres);
4499 if (hres == S_OK)
4501 ok(V_VT(&vDst) == VT_DECIMAL, "%d: got VT %d, expected VT_DECIMAL\n", i, V_VT(&vDst));
4502 ok(S(U(V_DECIMAL(&vDst))).sign == ptr->ret.sign, "%d: got sign 0x%02x, expected 0x%02x\n",
4503 i, S(U(V_DECIMAL(&vDst))).sign, ptr->ret.sign);
4504 ok(V_DECIMAL(&vDst).Hi32 == ptr->ret.Hi32, "%d: got Hi32 %d, expected %d\n",
4505 i, V_DECIMAL(&vDst).Hi32, ptr->ret.Hi32);
4506 ok(S1(U1(V_DECIMAL(&vDst))).Mid32 == ptr->ret.Mid32, "%d: got Mid32 %d, expected %d\n",
4507 i, S1(U1(V_DECIMAL(&vDst))).Mid32, ptr->ret.Mid32);
4508 ok(S1(U1(V_DECIMAL(&vDst))).Lo32 == ptr->ret.Lo32, "%d: got Lo32 %d, expected %d\n",
4509 i, S1(U1(V_DECIMAL(&vDst))).Lo32, ptr->ret.Lo32);
4513 /* VT_CY */
4514 V_VT(&v) = VT_CY;
4515 pcy->int64 = 10000;
4516 hres = pVarRound(&v,0,&vDst);
4517 ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == 10000,
4518 "VarRound: VT_CY wrong, hres=0x%X\n", hres);
4522 static HRESULT (WINAPI *pVarXor)(LPVARIANT,LPVARIANT,LPVARIANT);
4524 #define VARXOR(vt1,val1,vt2,val2,rvt,rval) \
4525 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
4526 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
4527 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
4528 test_var_call2( __LINE__, pVarXor, &left, &right, &exp )
4530 #define VARXORCY(vt1,val1,val2,rvt,rval) \
4531 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
4532 V_VT(&right) = VT_CY; V_CY(&right).int64 = val2; \
4533 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
4534 test_var_call2( __LINE__, pVarXor, &left, &right, &exp )
4536 static void test_VarXor(void)
4538 static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
4539 static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
4540 VARIANT left, right, exp, result;
4541 BSTR lbstr, rbstr;
4542 VARTYPE i;
4543 HRESULT hres;
4545 CHECKPTR(VarXor);
4547 /* Test all possible flag/vt combinations & the resulting vt type */
4548 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
4550 VARTYPE leftvt, rightvt, resvt;
4552 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
4555 SKIPTESTS(leftvt);
4557 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
4559 BOOL bFail = FALSE;
4561 SKIPTESTS(rightvt);
4563 if (leftvt == VT_BSTR || rightvt == VT_BSTR ||
4564 leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
4565 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN)
4566 continue;
4568 memset(&left, 0, sizeof(left));
4569 memset(&right, 0, sizeof(right));
4570 V_VT(&left) = leftvt | ExtraFlags[i];
4571 V_VT(&right) = rightvt | ExtraFlags[i];
4572 V_VT(&result) = VT_EMPTY;
4573 resvt = VT_I4;
4575 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
4576 !IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
4577 !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
4578 leftvt == VT_CLSID || rightvt == VT_CLSID ||
4579 leftvt == VT_RECORD || rightvt == VT_RECORD ||
4580 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
4581 leftvt == VT_ERROR || rightvt == VT_ERROR)
4583 bFail = TRUE;
4585 if (leftvt == VT_EMPTY || rightvt == VT_EMPTY)
4587 if (leftvt == rightvt ||
4588 leftvt == VT_I2 || rightvt == VT_I2 ||
4589 leftvt == VT_UI1 || rightvt == VT_UI1 ||
4590 leftvt == VT_BOOL || rightvt == VT_BOOL)
4591 resvt = VT_I2;
4592 else if (leftvt == VT_NULL || rightvt == VT_NULL)
4593 resvt = VT_NULL;
4594 else if (leftvt == VT_I8 || rightvt == VT_I8)
4595 resvt = VT_I8;
4597 else if (leftvt == VT_NULL || rightvt == VT_NULL)
4599 resvt = VT_NULL;
4601 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
4603 if (leftvt == rightvt)
4604 resvt = VT_UI1;
4605 else if (leftvt == rightvt ||
4606 leftvt == VT_I2 || rightvt == VT_I2 ||
4607 leftvt == VT_BOOL || rightvt == VT_BOOL)
4609 resvt = VT_I2;
4611 else if (leftvt == VT_I8 || rightvt == VT_I8)
4612 resvt = VT_I8;
4614 else if (leftvt == VT_I2 || rightvt == VT_I2)
4616 if (leftvt == rightvt ||
4617 leftvt == VT_BOOL || rightvt == VT_BOOL)
4618 resvt = VT_I2;
4619 else if (leftvt == VT_I8 || rightvt == VT_I8)
4620 resvt = VT_I8;
4622 else if (leftvt == VT_BOOL && rightvt == VT_BOOL)
4624 resvt = VT_BOOL;
4626 else if (leftvt == VT_I8 || rightvt == VT_I8)
4628 if (leftvt == VT_INT || rightvt == VT_INT)
4629 bFail = TRUE;
4630 else
4631 resvt = VT_I8;
4633 hres = pVarXor(&left, &right, &result);
4634 if (bFail)
4635 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
4636 "VarXor: %d|0x%X, %d|0x%X: Expected failure, got 0x%X vt %d\n",
4637 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres,
4638 V_VT(&result));
4639 else
4640 ok(hres == S_OK && V_VT(&result) == resvt,
4641 "VarXor: %d|0x%X, %d|0x%X: expected S_OK, vt %d, got 0x%X vt %d\n",
4642 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], resvt, hres,
4643 V_VT(&result));
4648 /* Test returned values
4649 * FIXME: Test VT_DECIMAL/VT_DISPATCH
4651 VARXOR(EMPTY,0,EMPTY,0,I2,0);
4652 VARXOR(EMPTY,1,EMPTY,0,I2,0);
4653 VARXOR(EMPTY,0,NULL,0,NULL,0);
4654 VARXOR(EMPTY,0,I1,0,I4,0);
4655 VARXOR(EMPTY,0,I1,1,I4,1);
4656 VARXOR(EMPTY,0,UI1,0,I2,0);
4657 VARXOR(EMPTY,0,UI1,1,I2,1);
4658 VARXOR(EMPTY,0,I2,0,I2,0);
4659 VARXOR(EMPTY,0,I2,1,I2,1);
4660 VARXOR(EMPTY,0,UI2,0,I4,0);
4661 VARXOR(EMPTY,0,UI2,1,I4,1);
4662 VARXOR(EMPTY,0,I4,0,I4,0);
4663 VARXOR(EMPTY,0,I4,1,I4,1);
4664 VARXOR(EMPTY,0,UI4,0,I4,0);
4665 VARXOR(EMPTY,0,UI4,1,I4,1);
4666 if (has_i8)
4668 VARXOR(EMPTY,0,I8,0,I8,0);
4669 VARXOR(EMPTY,0,I8,1,I8,1);
4670 VARXOR(EMPTY,0,UI8,0,I4,0);
4671 VARXOR(EMPTY,0,UI8,1,I4,1);
4673 VARXOR(EMPTY,0,INT,0,I4,0);
4674 VARXOR(EMPTY,0,INT,1,I4,1);
4675 VARXOR(EMPTY,0,UINT,0,I4,0);
4676 VARXOR(EMPTY,0,UINT,1,I4,1);
4677 VARXOR(EMPTY,0,BOOL,0,I2,0);
4678 VARXOR(EMPTY,0,BOOL,1,I2,1);
4679 VARXOR(EMPTY,0,R4,0,I4,0);
4680 VARXOR(EMPTY,0,R4,1,I4,1);
4681 VARXOR(EMPTY,0,R8,0,I4,0);
4682 VARXOR(EMPTY,0,R8,1,I4,1);
4683 rbstr = SysAllocString(szFalse);
4684 VARXOR(EMPTY,0,BSTR,rbstr,I2,0);
4685 SysFreeString(rbstr);
4686 rbstr = SysAllocString(szTrue);
4687 VARXOR(EMPTY,0,BSTR,rbstr,I2,-1);
4688 VARXORCY(EMPTY,0,10000,I4,1);
4689 SysFreeString(rbstr);
4691 /* NULL OR 0 = NULL. NULL OR n = n */
4692 VARXOR(NULL,0,NULL,0,NULL,0);
4693 VARXOR(NULL,1,NULL,0,NULL,0);
4694 VARXOR(NULL,0,I1,0,NULL,0);
4695 VARXOR(NULL,0,I1,1,NULL,0);
4696 VARXOR(NULL,0,UI1,0,NULL,0);
4697 VARXOR(NULL,0,UI1,1,NULL,0);
4698 VARXOR(NULL,0,I2,0,NULL,0);
4699 VARXOR(NULL,0,I2,1,NULL,0);
4700 VARXOR(NULL,0,UI2,0,NULL,0);
4701 VARXOR(NULL,0,UI2,1,NULL,0);
4702 VARXOR(NULL,0,I4,0,NULL,0);
4703 VARXOR(NULL,0,I4,1,NULL,0);
4704 VARXOR(NULL,0,UI4,0,NULL,0);
4705 VARXOR(NULL,0,UI4,1,NULL,0);
4706 if (has_i8)
4708 VARXOR(NULL,0,I8,0,NULL,0);
4709 VARXOR(NULL,0,I8,1,NULL,0);
4710 VARXOR(NULL,0,UI8,0,NULL,0);
4711 VARXOR(NULL,0,UI8,1,NULL,0);
4713 VARXOR(NULL,0,INT,0,NULL,0);
4714 VARXOR(NULL,0,INT,1,NULL,0);
4715 VARXOR(NULL,0,UINT,0,NULL,0);
4716 VARXOR(NULL,0,UINT,1,NULL,0);
4717 VARXOR(NULL,0,BOOL,0,NULL,0);
4718 VARXOR(NULL,0,BOOL,1,NULL,0);
4719 VARXOR(NULL,0,R4,0,NULL,0);
4720 VARXOR(NULL,0,R4,1,NULL,0);
4721 VARXOR(NULL,0,R8,0,NULL,0);
4722 VARXOR(NULL,0,R8,1,NULL,0);
4723 rbstr = SysAllocString(szFalse);
4724 VARXOR(NULL,0,BSTR,rbstr,NULL,0);
4725 SysFreeString(rbstr);
4726 rbstr = SysAllocString(szTrue);
4727 VARXOR(NULL,0,BSTR,rbstr,NULL,0);
4728 SysFreeString(rbstr);
4729 VARXORCY(NULL,0,10000,NULL,0);
4730 VARXORCY(NULL,0,0,NULL,0);
4732 VARXOR(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE);
4733 VARXOR(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE);
4734 VARXOR(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
4735 VARXOR(BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE);
4736 /* Assume x,y & y,x are the same from now on to reduce the number of tests */
4737 VARXOR(BOOL,VARIANT_TRUE,I1,-1,I4,0);
4738 VARXOR(BOOL,VARIANT_TRUE,I1,0,I4,-1);
4739 VARXOR(BOOL,VARIANT_FALSE,I1,0,I4,0);
4740 VARXOR(BOOL,VARIANT_TRUE,UI1,255,I2,-256);
4741 VARXOR(BOOL,VARIANT_TRUE,UI1,0,I2,-1);
4742 VARXOR(BOOL,VARIANT_FALSE,UI1,0,I2,0);
4743 VARXOR(BOOL,VARIANT_TRUE,I2,-1,I2,0);
4744 VARXOR(BOOL,VARIANT_TRUE,I2,0,I2,-1);
4745 VARXOR(BOOL,VARIANT_FALSE,I2,0,I2,0);
4746 VARXOR(BOOL,VARIANT_TRUE,UI2,65535,I4,-65536);
4747 VARXOR(BOOL,VARIANT_TRUE,UI2,0,I4,-1);
4748 VARXOR(BOOL,VARIANT_FALSE,UI2,0,I4,0);
4749 VARXOR(BOOL,VARIANT_TRUE,I4,-1,I4,0);
4750 VARXOR(BOOL,VARIANT_TRUE,I4,0,I4,-1);
4751 VARXOR(BOOL,VARIANT_FALSE,I4,0,I4,0);
4752 VARXOR(BOOL,VARIANT_TRUE,UI4,0xffffffff,I4,0);
4753 VARXOR(BOOL,VARIANT_TRUE,UI4,0,I4,-1);
4754 VARXOR(BOOL,VARIANT_FALSE,UI4,0,I4,0);
4755 VARXOR(BOOL,VARIANT_TRUE,R4,-1,I4,0);
4756 VARXOR(BOOL,VARIANT_TRUE,R4,0,I4,-1);
4757 VARXOR(BOOL,VARIANT_FALSE,R4,0,I4,0);
4758 VARXOR(BOOL,VARIANT_TRUE,R8,-1,I4,0);
4759 VARXOR(BOOL,VARIANT_TRUE,R8,0,I4,-1);
4760 VARXOR(BOOL,VARIANT_FALSE,R8,0,I4,0);
4761 VARXOR(BOOL,VARIANT_TRUE,DATE,-1,I4,0);
4762 VARXOR(BOOL,VARIANT_TRUE,DATE,0,I4,-1);
4763 VARXOR(BOOL,VARIANT_FALSE,DATE,0,I4,0);
4764 if (has_i8)
4766 VARXOR(BOOL,VARIANT_TRUE,I8,-1,I8,0);
4767 VARXOR(BOOL,VARIANT_TRUE,I8,0,I8,-1);
4768 VARXOR(BOOL,VARIANT_FALSE,I8,0,I8,0);
4769 /* This returns DISP_E_OVERFLOW which indicates that a conversion
4770 * to I4 is performed.
4772 /* VARXOR(BOOL,VARIANT_TRUE,UI8,-1,I4,-1); */
4773 VARXOR(BOOL,VARIANT_TRUE,UI8,0,I4,-1);
4774 VARXOR(BOOL,VARIANT_FALSE,UI8,0,I4,0);
4776 VARXOR(BOOL,VARIANT_TRUE,INT,-1,I4,0);
4777 VARXOR(BOOL,VARIANT_TRUE,INT,0,I4,-1);
4778 VARXOR(BOOL,VARIANT_FALSE,INT,0,I4,0);
4779 VARXOR(BOOL,VARIANT_TRUE,UINT,0xffffffff,I4,0);
4780 VARXOR(BOOL,VARIANT_TRUE,UINT,0,I4,-1);
4781 VARXOR(BOOL,VARIANT_FALSE,UINT,0,I4,0);
4782 rbstr = SysAllocString(szFalse);
4783 VARXOR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_FALSE);
4784 VARXOR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_TRUE);
4785 SysFreeString(rbstr);
4786 rbstr = SysAllocString(szTrue);
4787 VARXOR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_TRUE);
4788 VARXOR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_FALSE);
4789 SysFreeString(rbstr);
4790 VARXORCY(BOOL,VARIANT_TRUE,10000,I4,-2);
4791 VARXORCY(BOOL,VARIANT_TRUE,0,I4,-1);
4792 VARXORCY(BOOL,VARIANT_FALSE,0,I4,0);
4794 VARXOR(I1,-1,I1,-1,I4,0);
4795 VARXOR(I1,-1,I1,0,I4,-1);
4796 VARXOR(I1,0,I1,0,I4,0);
4797 VARXOR(I1,-1,UI1,255,I4,-256);
4798 VARXOR(I1,-1,UI1,0,I4,-1);
4799 VARXOR(I1,0,UI1,0,I4,0);
4800 VARXOR(I1,-1,I2,-1,I4,0);
4801 VARXOR(I1,-1,I2,0,I4,-1);
4802 VARXOR(I1,0,I2,0,I4,0);
4803 VARXOR(I1,-1,UI2,65535,I4,-65536);
4804 VARXOR(I1,-1,UI2,0,I4,-1);
4805 VARXOR(I1,0,UI2,0,I4,0);
4806 VARXOR(I1,-1,I4,-1,I4,0);
4807 VARXOR(I1,-1,I4,0,I4,-1);
4808 VARXOR(I1,0,I4,0,I4,0);
4809 VARXOR(I1,-1,UI4,0xffffffff,I4,0);
4810 VARXOR(I1,-1,UI4,0,I4,-1);
4811 VARXOR(I1,0,UI4,0,I4,0);
4812 VARXOR(I1,-1,R4,-1,I4,0);
4813 VARXOR(I1,-1,R4,0,I4,-1);
4814 VARXOR(I1,0,R4,0,I4,0);
4815 VARXOR(I1,-1,R8,-1,I4,0);
4816 VARXOR(I1,-1,R8,0,I4,-1);
4817 VARXOR(I1,0,R8,0,I4,0);
4818 VARXOR(I1,-1,DATE,-1,I4,0);
4819 VARXOR(I1,-1,DATE,0,I4,-1);
4820 VARXOR(I1,0,DATE,0,I4,0);
4821 if (has_i8)
4823 VARXOR(I1,-1,I8,-1,I8,0);
4824 VARXOR(I1,-1,I8,0,I8,-1);
4825 VARXOR(I1,0,I8,0,I8,0);
4826 VARXOR(I1,-1,UI8,0,I4,-1);
4827 VARXOR(I1,0,UI8,0,I4,0);
4829 VARXOR(I1,-1,INT,-1,I4,0);
4830 VARXOR(I1,-1,INT,0,I4,-1);
4831 VARXOR(I1,0,INT,0,I4,0);
4832 VARXOR(I1,-1,UINT,0xffffffff,I4,0);
4833 VARXOR(I1,-1,UINT,0,I4,-1);
4834 VARXOR(I1,0,UINT,0,I4,0);
4835 rbstr = SysAllocString(szFalse);
4836 VARXOR(I1,0,BSTR,rbstr,I4,0);
4837 VARXOR(I1,-1,BSTR,rbstr,I4,-1);
4838 SysFreeString(rbstr);
4839 rbstr = SysAllocString(szTrue);
4840 VARXOR(I1,0,BSTR,rbstr,I4,-1);
4841 VARXOR(I1,-1,BSTR,rbstr,I4,0);
4842 SysFreeString(rbstr);
4843 VARXORCY(I1,-1,10000,I4,-2);
4844 VARXORCY(I1,-1,0,I4,-1);
4845 VARXORCY(I1,0,0,I4,0);
4847 VARXOR(UI1,255,UI1,255,UI1,0);
4848 VARXOR(UI1,255,UI1,0,UI1,255);
4849 VARXOR(UI1,0,UI1,0,UI1,0);
4850 VARXOR(UI1,255,I2,-1,I2,-256);
4851 VARXOR(UI1,255,I2,0,I2,255);
4852 VARXOR(UI1,0,I2,0,I2,0);
4853 VARXOR(UI1,255,UI2,65535,I4,65280);
4854 VARXOR(UI1,255,UI2,0,I4,255);
4855 VARXOR(UI1,0,UI2,0,I4,0);
4856 VARXOR(UI1,255,I4,-1,I4,-256);
4857 VARXOR(UI1,255,I4,0,I4,255);
4858 VARXOR(UI1,0,I4,0,I4,0);
4859 VARXOR(UI1,255,UI4,0xffffffff,I4,-256);
4860 VARXOR(UI1,255,UI4,0,I4,255);
4861 VARXOR(UI1,0,UI4,0,I4,0);
4862 VARXOR(UI1,255,R4,-1,I4,-256);
4863 VARXOR(UI1,255,R4,0,I4,255);
4864 VARXOR(UI1,0,R4,0,I4,0);
4865 VARXOR(UI1,255,R8,-1,I4,-256);
4866 VARXOR(UI1,255,R8,0,I4,255);
4867 VARXOR(UI1,0,R8,0,I4,0);
4868 VARXOR(UI1,255,DATE,-1,I4,-256);
4869 VARXOR(UI1,255,DATE,0,I4,255);
4870 VARXOR(UI1,0,DATE,0,I4,0);
4871 if (has_i8)
4873 VARXOR(UI1,255,I8,-1,I8,-256);
4874 VARXOR(UI1,255,I8,0,I8,255);
4875 VARXOR(UI1,0,I8,0,I8,0);
4876 VARXOR(UI1,255,UI8,0,I4,255);
4877 VARXOR(UI1,0,UI8,0,I4,0);
4879 VARXOR(UI1,255,INT,-1,I4,-256);
4880 VARXOR(UI1,255,INT,0,I4,255);
4881 VARXOR(UI1,0,INT,0,I4,0);
4882 VARXOR(UI1,255,UINT,0xffffffff,I4,-256);
4883 VARXOR(UI1,255,UINT,0,I4,255);
4884 VARXOR(UI1,0,UINT,0,I4,0);
4885 rbstr = SysAllocString(szFalse);
4886 VARXOR(UI1,0,BSTR,rbstr,I2,0);
4887 VARXOR(UI1,255,BSTR,rbstr,I2,255);
4888 SysFreeString(rbstr);
4889 rbstr = SysAllocString(szTrue);
4890 VARXOR(UI1,0,BSTR,rbstr,I2,-1);
4891 VARXOR(UI1,255,BSTR,rbstr,I2,-256);
4892 SysFreeString(rbstr);
4893 VARXORCY(UI1,255,10000,I4,254);
4894 VARXORCY(UI1,255,0,I4,255);
4895 VARXORCY(UI1,0,0,I4,0);
4897 VARXOR(I2,-1,I2,-1,I2,0);
4898 VARXOR(I2,-1,I2,0,I2,-1);
4899 VARXOR(I2,0,I2,0,I2,0);
4900 VARXOR(I2,-1,UI2,65535,I4,-65536);
4901 VARXOR(I2,-1,UI2,0,I4,-1);
4902 VARXOR(I2,0,UI2,0,I4,0);
4903 VARXOR(I2,-1,I4,-1,I4,0);
4904 VARXOR(I2,-1,I4,0,I4,-1);
4905 VARXOR(I2,0,I4,0,I4,0);
4906 VARXOR(I2,-1,UI4,0xffffffff,I4,0);
4907 VARXOR(I2,-1,UI4,0,I4,-1);
4908 VARXOR(I2,0,UI4,0,I4,0);
4909 VARXOR(I2,-1,R4,-1,I4,0);
4910 VARXOR(I2,-1,R4,0,I4,-1);
4911 VARXOR(I2,0,R4,0,I4,0);
4912 VARXOR(I2,-1,R8,-1,I4,0);
4913 VARXOR(I2,-1,R8,0,I4,-1);
4914 VARXOR(I2,0,R8,0,I4,0);
4915 VARXOR(I2,-1,DATE,-1,I4,0);
4916 VARXOR(I2,-1,DATE,0,I4,-1);
4917 VARXOR(I2,0,DATE,0,I4,0);
4918 if (has_i8)
4920 VARXOR(I2,-1,I8,-1,I8,0);
4921 VARXOR(I2,-1,I8,0,I8,-1);
4922 VARXOR(I2,0,I8,0,I8,0);
4923 VARXOR(I2,-1,UI8,0,I4,-1);
4924 VARXOR(I2,0,UI8,0,I4,0);
4926 VARXOR(I2,-1,INT,-1,I4,0);
4927 VARXOR(I2,-1,INT,0,I4,-1);
4928 VARXOR(I2,0,INT,0,I4,0);
4929 VARXOR(I2,-1,UINT,0xffffffff,I4,0);
4930 VARXOR(I2,-1,UINT,0,I4,-1);
4931 VARXOR(I2,0,UINT,0,I4,0);
4932 rbstr = SysAllocString(szFalse);
4933 VARXOR(I2,0,BSTR,rbstr,I2,0);
4934 VARXOR(I2,-1,BSTR,rbstr,I2,-1);
4935 SysFreeString(rbstr);
4936 rbstr = SysAllocString(szTrue);
4937 VARXOR(I2,0,BSTR,rbstr,I2,-1);
4938 VARXOR(I2,-1,BSTR,rbstr,I2,0);
4939 SysFreeString(rbstr);
4940 VARXORCY(I2,-1,10000,I4,-2);
4941 VARXORCY(I2,-1,0,I4,-1);
4942 VARXORCY(I2,0,0,I4,0);
4944 VARXOR(UI2,65535,UI2,65535,I4,0);
4945 VARXOR(UI2,65535,UI2,0,I4,65535);
4946 VARXOR(UI2,0,UI2,0,I4,0);
4947 VARXOR(UI2,65535,I4,-1,I4,-65536);
4948 VARXOR(UI2,65535,I4,0,I4,65535);
4949 VARXOR(UI2,0,I4,0,I4,0);
4950 VARXOR(UI2,65535,UI4,0xffffffff,I4,-65536);
4951 VARXOR(UI2,65535,UI4,0,I4,65535);
4952 VARXOR(UI2,0,UI4,0,I4,0);
4953 VARXOR(UI2,65535,R4,-1,I4,-65536);
4954 VARXOR(UI2,65535,R4,0,I4,65535);
4955 VARXOR(UI2,0,R4,0,I4,0);
4956 VARXOR(UI2,65535,R8,-1,I4,-65536);
4957 VARXOR(UI2,65535,R8,0,I4,65535);
4958 VARXOR(UI2,0,R8,0,I4,0);
4959 VARXOR(UI2,65535,DATE,-1,I4,-65536);
4960 VARXOR(UI2,65535,DATE,0,I4,65535);
4961 VARXOR(UI2,0,DATE,0,I4,0);
4962 if (has_i8)
4964 VARXOR(UI2,65535,I8,-1,I8,-65536);
4965 VARXOR(UI2,65535,I8,0,I8,65535);
4966 VARXOR(UI2,0,I8,0,I8,0);
4967 VARXOR(UI2,65535,UI8,0,I4,65535);
4968 VARXOR(UI2,0,UI8,0,I4,0);
4970 VARXOR(UI2,65535,INT,-1,I4,-65536);
4971 VARXOR(UI2,65535,INT,0,I4,65535);
4972 VARXOR(UI2,0,INT,0,I4,0);
4973 VARXOR(UI2,65535,UINT,0xffffffff,I4,-65536);
4974 VARXOR(UI2,65535,UINT,0,I4,65535);
4975 VARXOR(UI2,0,UINT,0,I4,0);
4976 rbstr = SysAllocString(szFalse);
4977 VARXOR(UI2,0,BSTR,rbstr,I4,0);
4978 VARXOR(UI2,65535,BSTR,rbstr,I4,65535);
4979 SysFreeString(rbstr);
4980 rbstr = SysAllocString(szTrue);
4981 VARXOR(UI2,0,BSTR,rbstr,I4,-1);
4982 VARXOR(UI2,65535,BSTR,rbstr,I4,-65536);
4983 SysFreeString(rbstr);
4984 VARXORCY(UI2,65535,10000,I4,65534);
4985 VARXORCY(UI2,65535,0,I4,65535);
4986 VARXORCY(UI2,0,0,I4,0);
4988 VARXOR(I4,-1,I4,-1,I4,0);
4989 VARXOR(I4,-1,I4,0,I4,-1);
4990 VARXOR(I4,0,I4,0,I4,0);
4991 VARXOR(I4,-1,UI4,0xffffffff,I4,0);
4992 VARXOR(I4,-1,UI4,0,I4,-1);
4993 VARXOR(I4,0,UI4,0,I4,0);
4994 VARXOR(I4,-1,R4,-1,I4,0);
4995 VARXOR(I4,-1,R4,0,I4,-1);
4996 VARXOR(I4,0,R4,0,I4,0);
4997 VARXOR(I4,-1,R8,-1,I4,0);
4998 VARXOR(I4,-1,R8,0,I4,-1);
4999 VARXOR(I4,0,R8,0,I4,0);
5000 VARXOR(I4,-1,DATE,-1,I4,0);
5001 VARXOR(I4,-1,DATE,0,I4,-1);
5002 VARXOR(I4,0,DATE,0,I4,0);
5003 if (has_i8)
5005 VARXOR(I4,-1,I8,-1,I8,0);
5006 VARXOR(I4,-1,I8,0,I8,-1);
5007 VARXOR(I4,0,I8,0,I8,0);
5008 VARXOR(I4,-1,UI8,0,I4,-1);
5009 VARXOR(I4,0,UI8,0,I4,0);
5011 VARXOR(I4,-1,INT,-1,I4,0);
5012 VARXOR(I4,-1,INT,0,I4,-1);
5013 VARXOR(I4,0,INT,0,I4,0);
5014 VARXOR(I4,-1,UINT,0xffffffff,I4,0);
5015 VARXOR(I4,-1,UINT,0,I4,-1);
5016 VARXOR(I4,0,UINT,0,I4,0);
5017 rbstr = SysAllocString(szFalse);
5018 VARXOR(I4,0,BSTR,rbstr,I4,0);
5019 VARXOR(I4,-1,BSTR,rbstr,I4,-1);
5020 SysFreeString(rbstr);
5021 rbstr = SysAllocString(szTrue);
5022 VARXOR(I4,0,BSTR,rbstr,I4,-1);
5023 VARXOR(I4,-1,BSTR,rbstr,I4,0);
5024 SysFreeString(rbstr);
5025 VARXORCY(I4,-1,10000,I4,-2);
5026 VARXORCY(I4,-1,0,I4,-1);
5027 VARXORCY(I4,0,0,I4,0);
5029 VARXOR(UI4,0xffffffff,UI4,0xffffffff,I4,0);
5030 VARXOR(UI4,0xffffffff,UI4,0,I4,-1);
5031 VARXOR(UI4,0,UI4,0,I4,0);
5032 VARXOR(UI4,0xffffffff,R4,-1,I4,0);
5033 VARXOR(UI4,0xffffffff,R4,0,I4,-1);
5034 VARXOR(UI4,0,R4,0,I4,0);
5035 VARXOR(UI4,0xffffffff,R8,-1,I4,0);
5036 VARXOR(UI4,0xffffffff,R8,0,I4,-1);
5037 VARXOR(UI4,0,R8,0,I4,0);
5038 VARXOR(UI4,0xffffffff,DATE,-1,I4,0);
5039 VARXOR(UI4,0xffffffff,DATE,0,I4,-1);
5040 VARXOR(UI4,0,DATE,0,I4,0);
5041 if (has_i8)
5043 VARXOR(UI4,0xffffffff,I8,0,I8,0xffffffff);
5044 VARXOR(UI4,VARIANT_FALSE,I8,VARIANT_FALSE,I8,0);
5045 VARXOR(UI4,0,I8,0,I8,0);
5046 VARXOR(UI4,0xffffffff,UI8,0,I4,-1);
5047 VARXOR(UI4,0,UI8,0,I4,0);
5049 VARXOR(UI4,0xffffffff,INT,-1,I4,0);
5050 VARXOR(UI4,0xffffffff,INT,0,I4,-1);
5051 VARXOR(UI4,0,INT,0,I4,0);
5052 VARXOR(UI4,0xffffffff,UINT,0xffffffff,I4,0);
5053 VARXOR(UI4,0xffffffff,UINT,0,I4,-1);
5054 VARXOR(UI4,0,UINT,0,I4,0);
5055 rbstr = SysAllocString(szFalse);
5056 VARXOR(UI4,0,BSTR,rbstr,I4,0);
5057 VARXOR(UI4,0xffffffff,BSTR,rbstr,I4,-1);
5058 SysFreeString(rbstr);
5059 rbstr = SysAllocString(szTrue);
5060 VARXOR(UI4,0,BSTR,rbstr,I4,-1);
5061 VARXOR(UI4,0xffffffff,BSTR,rbstr,I4,0);
5062 SysFreeString(rbstr);
5063 VARXORCY(UI4,0xffffffff,10000,I4,-2);
5064 VARXORCY(UI4,0xffffffff,0,I4,-1);
5065 VARXORCY(UI4,0,0,I4,0);
5067 VARXOR(R4,-1,R4,-1,I4,0);
5068 VARXOR(R4,-1,R4,0,I4,-1);
5069 VARXOR(R4,0,R4,0,I4,0);
5070 VARXOR(R4,-1,R8,-1,I4,0);
5071 VARXOR(R4,-1,R8,0,I4,-1);
5072 VARXOR(R4,0,R8,0,I4,0);
5073 VARXOR(R4,-1,DATE,-1,I4,0);
5074 VARXOR(R4,-1,DATE,0,I4,-1);
5075 VARXOR(R4,0,DATE,0,I4,0);
5076 if (has_i8)
5078 VARXOR(R4,-1,I8,-1,I8,0);
5079 VARXOR(R4,-1,I8,0,I8,-1);
5080 VARXOR(R4,0,I8,0,I8,0);
5081 VARXOR(R4,-1,UI8,0,I4,-1);
5082 VARXOR(R4,0,UI8,0,I4,0);
5084 VARXOR(R4,-1,INT,-1,I4,0);
5085 VARXOR(R4,-1,INT,0,I4,-1);
5086 VARXOR(R4,0,INT,0,I4,0);
5087 VARXOR(R4,-1,UINT,0xffffffff,I4,0);
5088 VARXOR(R4,-1,UINT,0,I4,-1);
5089 VARXOR(R4,0,UINT,0,I4,0);
5090 rbstr = SysAllocString(szFalse);
5091 VARXOR(R4,0,BSTR,rbstr,I4,0);
5092 VARXOR(R4,-1,BSTR,rbstr,I4,-1);
5093 SysFreeString(rbstr);
5094 rbstr = SysAllocString(szTrue);
5095 VARXOR(R4,0,BSTR,rbstr,I4,-1);
5096 VARXOR(R4,-1,BSTR,rbstr,I4,0);
5097 SysFreeString(rbstr);
5098 VARXORCY(R4,-1,10000,I4,-2);
5099 VARXORCY(R4,-1,0,I4,-1);
5100 VARXORCY(R4,0,0,I4,0);
5102 VARXOR(R8,-1,R8,-1,I4,0);
5103 VARXOR(R8,-1,R8,0,I4,-1);
5104 VARXOR(R8,0,R8,0,I4,0);
5105 VARXOR(R8,-1,DATE,-1,I4,0);
5106 VARXOR(R8,-1,DATE,0,I4,-1);
5107 VARXOR(R8,0,DATE,0,I4,0);
5108 if (has_i8)
5110 VARXOR(R8,-1,I8,-1,I8,0);
5111 VARXOR(R8,-1,I8,0,I8,-1);
5112 VARXOR(R8,0,I8,0,I8,0);
5113 VARXOR(R8,-1,UI8,0,I4,-1);
5114 VARXOR(R8,0,UI8,0,I4,0);
5116 VARXOR(R8,-1,INT,-1,I4,0);
5117 VARXOR(R8,-1,INT,0,I4,-1);
5118 VARXOR(R8,0,INT,0,I4,0);
5119 VARXOR(R8,-1,UINT,0xffffffff,I4,0);
5120 VARXOR(R8,-1,UINT,0,I4,-1);
5121 VARXOR(R8,0,UINT,0,I4,0);
5122 rbstr = SysAllocString(szFalse);
5123 VARXOR(R8,0,BSTR,rbstr,I4,0);
5124 VARXOR(R8,-1,BSTR,rbstr,I4,-1);
5125 SysFreeString(rbstr);
5126 rbstr = SysAllocString(szTrue);
5127 VARXOR(R8,0,BSTR,rbstr,I4,-1);
5128 VARXOR(R8,-1,BSTR,rbstr,I4,0);
5129 SysFreeString(rbstr);
5130 VARXORCY(R8,-1,10000,I4,-2);
5131 VARXORCY(R8,-1,0,I4,-1);
5132 VARXORCY(R8,0,0,I4,0);
5134 VARXOR(DATE,-1,DATE,-1,I4,0);
5135 VARXOR(DATE,-1,DATE,0,I4,-1);
5136 VARXOR(DATE,0,DATE,0,I4,0);
5137 if (has_i8)
5139 VARXOR(DATE,-1,I8,-1,I8,0);
5140 VARXOR(DATE,-1,I8,0,I8,-1);
5141 VARXOR(DATE,0,I8,0,I8,0);
5142 VARXOR(DATE,-1,UI8,0,I4,-1);
5143 VARXOR(DATE,0,UI8,0,I4,0);
5145 VARXOR(DATE,-1,INT,-1,I4,0);
5146 VARXOR(DATE,-1,INT,0,I4,-1);
5147 VARXOR(DATE,0,INT,0,I4,0);
5148 VARXOR(DATE,-1,UINT,0xffffffff,I4,0);
5149 VARXOR(DATE,-1,UINT,0,I4,-1);
5150 VARXOR(DATE,0,UINT,0,I4,0);
5151 rbstr = SysAllocString(szFalse);
5152 VARXOR(DATE,0,BSTR,rbstr,I4,0);
5153 VARXOR(DATE,-1,BSTR,rbstr,I4,-1);
5154 SysFreeString(rbstr);
5155 rbstr = SysAllocString(szTrue);
5156 VARXOR(DATE,0,BSTR,rbstr,I4,-1);
5157 VARXOR(DATE,-1,BSTR,rbstr,I4,0);
5158 SysFreeString(rbstr);
5159 VARXORCY(DATE,-1,10000,I4,-2);
5160 VARXORCY(DATE,-1,0,I4,-1);
5161 VARXORCY(DATE,0,0,I4,0);
5163 if (has_i8)
5165 VARXOR(I8,-1,I8,-1,I8,0);
5166 VARXOR(I8,-1,I8,0,I8,-1);
5167 VARXOR(I8,0,I8,0,I8,0);
5168 VARXOR(I8,-1,UI8,0,I8,-1);
5169 VARXOR(I8,0,UI8,0,I8,0);
5170 VARXOR(I8,-1,UINT,0,I8,-1);
5171 VARXOR(I8,0,UINT,0,I8,0);
5172 rbstr = SysAllocString(szFalse);
5173 VARXOR(I8,0,BSTR,rbstr,I8,0);
5174 VARXOR(I8,-1,BSTR,rbstr,I8,-1);
5175 SysFreeString(rbstr);
5176 rbstr = SysAllocString(szTrue);
5177 VARXOR(I8,0,BSTR,rbstr,I8,-1);
5178 VARXOR(I8,-1,BSTR,rbstr,I8,0);
5179 SysFreeString(rbstr);
5180 VARXORCY(I8,-1,10000,I8,-2);
5181 VARXORCY(I8,-1,0,I8,-1);
5182 VARXORCY(I8,0,0,I8,0);
5184 VARXOR(UI8,0xffff,UI8,0xffff,I4,0);
5185 VARXOR(UI8,0xffff,UI8,0,I4,0xffff);
5186 VARXOR(UI8,0,UI8,0,I4,0);
5187 VARXOR(UI8,0xffff,INT,-1,I4,-65536);
5188 VARXOR(UI8,0xffff,INT,0,I4,0xffff);
5189 VARXOR(UI8,0,INT,0,I4,0);
5190 VARXOR(UI8,0xffff,UINT,0xffff,I4,0);
5191 VARXOR(UI8,0xffff,UINT,0,I4,0xffff);
5192 VARXOR(UI8,0,UINT,0,I4,0);
5193 rbstr = SysAllocString(szFalse);
5194 VARXOR(UI8,0,BSTR,rbstr,I4,0);
5195 VARXOR(UI8,0xffff,BSTR,rbstr,I4,0xffff);
5196 SysFreeString(rbstr);
5197 rbstr = SysAllocString(szTrue);
5198 VARXOR(UI8,0,BSTR,rbstr,I4,-1);
5199 VARXOR(UI8,0xffff,BSTR,rbstr,I4,-65536);
5200 SysFreeString(rbstr);
5201 VARXORCY(UI8,0xffff,10000,I4,65534);
5202 VARXORCY(UI8,0xffff,0,I4,0xffff);
5203 VARXORCY(UI8,0,0,I4,0);
5206 VARXOR(INT,-1,INT,-1,I4,0);
5207 VARXOR(INT,-1,INT,0,I4,-1);
5208 VARXOR(INT,0,INT,0,I4,0);
5209 VARXOR(INT,-1,UINT,0xffff,I4,-65536);
5210 VARXOR(INT,-1,UINT,0,I4,-1);
5211 VARXOR(INT,0,UINT,0,I4,0);
5212 rbstr = SysAllocString(szFalse);
5213 VARXOR(INT,0,BSTR,rbstr,I4,0);
5214 VARXOR(INT,-1,BSTR,rbstr,I4,-1);
5215 SysFreeString(rbstr);
5216 rbstr = SysAllocString(szTrue);
5217 VARXOR(INT,0,BSTR,rbstr,I4,-1);
5218 VARXOR(INT,-1,BSTR,rbstr,I4,0);
5219 SysFreeString(rbstr);
5220 VARXORCY(INT,-1,10000,I4,-2);
5221 VARXORCY(INT,-1,0,I4,-1);
5222 VARXORCY(INT,0,0,I4,0);
5224 VARXOR(UINT,0xffff,UINT,0xffff,I4,0);
5225 VARXOR(UINT,0xffff,UINT,0,I4,0xffff);
5226 VARXOR(UINT,0,UINT,0,I4,0);
5227 rbstr = SysAllocString(szFalse);
5228 VARXOR(UINT,0,BSTR,rbstr,I4,0);
5229 VARXOR(UINT,0xffff,BSTR,rbstr,I4,0xffff);
5230 SysFreeString(rbstr);
5231 rbstr = SysAllocString(szTrue);
5232 VARXOR(UINT,0,BSTR,rbstr,I4,-1);
5233 VARXOR(UINT,0xffff,BSTR,rbstr,I4,-65536);
5234 SysFreeString(rbstr);
5235 VARXORCY(UINT,0xffff,10000,I4,65534);
5236 VARXORCY(UINT,0xffff,0,I4,0xffff);
5237 VARXORCY(UINT,0,0,I4,0);
5239 lbstr = SysAllocString(szFalse);
5240 rbstr = SysAllocString(szFalse);
5241 VARXOR(BSTR,lbstr,BSTR,rbstr,BOOL,0);
5242 SysFreeString(rbstr);
5243 rbstr = SysAllocString(szTrue);
5244 VARXOR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_TRUE);
5245 SysFreeString(lbstr);
5246 lbstr = SysAllocString(szTrue);
5247 VARXOR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_FALSE);
5248 VARXORCY(BSTR,lbstr,10000,I4,-2);
5249 SysFreeString(lbstr);
5250 lbstr = SysAllocString(szFalse);
5251 VARXORCY(BSTR,lbstr,10000,I4,1);
5252 SysFreeString(lbstr);
5253 SysFreeString(rbstr);
5256 static HRESULT (WINAPI *pVarOr)(LPVARIANT,LPVARIANT,LPVARIANT);
5258 #define VAROR(vt1,val1,vt2,val2,rvt,rval) \
5259 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
5260 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
5261 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
5262 test_var_call2( __LINE__, pVarOr, &left, &right, &exp )
5264 #define VARORCY(vt1,val1,val2,rvt,rval) \
5265 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
5266 V_VT(&right) = VT_CY; V_CY(&right).int64 = val2; \
5267 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
5268 test_var_call2( __LINE__, pVarOr, &left, &right, &exp )
5270 static void test_VarOr(void)
5272 static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
5273 static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
5274 VARIANT left, right, exp, result;
5275 BSTR lbstr, rbstr;
5276 VARTYPE i;
5277 HRESULT hres;
5279 CHECKPTR(VarOr);
5281 /* Test all possible flag/vt combinations & the resulting vt type */
5282 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
5284 VARTYPE leftvt, rightvt, resvt;
5286 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
5289 SKIPTESTS(leftvt);
5291 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
5293 BOOL bFail = FALSE;
5295 SKIPTESTS(rightvt);
5297 if (leftvt == VT_BSTR || rightvt == VT_BSTR ||
5298 leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
5299 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN)
5300 continue;
5302 memset(&left, 0, sizeof(left));
5303 memset(&right, 0, sizeof(right));
5304 V_VT(&left) = leftvt | ExtraFlags[i];
5305 V_VT(&right) = rightvt | ExtraFlags[i];
5306 V_VT(&result) = VT_EMPTY;
5307 resvt = VT_I4;
5309 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
5310 !IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
5311 !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
5312 leftvt == VT_CLSID || rightvt == VT_CLSID ||
5313 leftvt == VT_RECORD || rightvt == VT_RECORD ||
5314 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
5315 leftvt == VT_ERROR || rightvt == VT_ERROR)
5317 bFail = TRUE;
5319 if (leftvt == VT_EMPTY || rightvt == VT_EMPTY)
5321 if (leftvt == rightvt ||
5322 leftvt == VT_I2 || rightvt == VT_I2 ||
5323 leftvt == VT_UI1 || rightvt == VT_UI1 ||
5324 leftvt == VT_BOOL || rightvt == VT_BOOL)
5325 resvt = VT_I2;
5326 else if (leftvt == VT_NULL || rightvt == VT_NULL)
5327 resvt = VT_NULL;
5328 else if (leftvt == VT_I8 || rightvt == VT_I8)
5329 resvt = VT_I8;
5331 else if (leftvt == VT_NULL || rightvt == VT_NULL)
5333 resvt = VT_NULL;
5335 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
5337 if (leftvt == rightvt)
5338 resvt = VT_UI1;
5339 else if (leftvt == rightvt ||
5340 leftvt == VT_I2 || rightvt == VT_I2 ||
5341 leftvt == VT_BOOL || rightvt == VT_BOOL)
5343 resvt = VT_I2;
5345 else if (leftvt == VT_I8 || rightvt == VT_I8)
5346 resvt = VT_I8;
5348 else if (leftvt == VT_I2 || rightvt == VT_I2)
5350 if (leftvt == rightvt ||
5351 leftvt == VT_BOOL || rightvt == VT_BOOL)
5352 resvt = VT_I2;
5353 else if (leftvt == VT_I8 || rightvt == VT_I8)
5354 resvt = VT_I8;
5356 else if (leftvt == VT_BOOL && rightvt == VT_BOOL)
5358 resvt = VT_BOOL;
5360 else if (leftvt == VT_I8 || rightvt == VT_I8)
5362 if (leftvt == VT_INT || rightvt == VT_INT)
5363 bFail = TRUE;
5364 else
5365 resvt = VT_I8;
5367 hres = pVarOr(&left, &right, &result);
5368 if (bFail)
5369 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
5370 "VarOr: %d|0x%X, %d|0x%X: Expected failure, got 0x%X vt %d\n",
5371 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres,
5372 V_VT(&result));
5373 else
5374 ok(hres == S_OK && V_VT(&result) == resvt,
5375 "VarOr: %d|0x%X, %d|0x%X: expected S_OK, vt %d, got 0x%X vt %d\n",
5376 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], resvt, hres,
5377 V_VT(&result));
5382 /* Test returned values. Since we know the returned type is correct
5383 * and that we handle all combinations of invalid types, just check
5384 * that good type combinations produce the desired value.
5385 * FIXME: Test VT_DECIMAL/VT_DISPATCH
5387 VAROR(EMPTY,0,EMPTY,0,I2,0);
5388 VAROR(EMPTY,1,EMPTY,0,I2,0);
5389 VAROR(EMPTY,0,NULL,0,NULL,0);
5390 VAROR(EMPTY,0,I1,0,I4,0);
5391 VAROR(EMPTY,0,I1,1,I4,1);
5392 VAROR(EMPTY,0,UI1,0,I2,0);
5393 VAROR(EMPTY,0,UI1,1,I2,1);
5394 VAROR(EMPTY,0,I2,0,I2,0);
5395 VAROR(EMPTY,0,I2,1,I2,1);
5396 VAROR(EMPTY,0,UI2,0,I4,0);
5397 VAROR(EMPTY,0,UI2,1,I4,1);
5398 VAROR(EMPTY,0,I4,0,I4,0);
5399 VAROR(EMPTY,0,I4,1,I4,1);
5400 VAROR(EMPTY,0,UI4,0,I4,0);
5401 VAROR(EMPTY,0,UI4,1,I4,1);
5402 if (has_i8)
5404 VAROR(EMPTY,0,I8,0,I8,0);
5405 VAROR(EMPTY,0,I8,1,I8,1);
5406 VAROR(EMPTY,0,UI8,0,I4,0);
5407 VAROR(EMPTY,0,UI8,1,I4,1);
5409 VAROR(EMPTY,0,INT,0,I4,0);
5410 VAROR(EMPTY,0,INT,1,I4,1);
5411 VAROR(EMPTY,0,UINT,0,I4,0);
5412 VAROR(EMPTY,0,UINT,1,I4,1);
5413 VAROR(EMPTY,0,BOOL,0,I2,0);
5414 VAROR(EMPTY,0,BOOL,1,I2,1);
5415 VAROR(EMPTY,0,R4,0,I4,0);
5416 VAROR(EMPTY,0,R4,1,I4,1);
5417 VAROR(EMPTY,0,R8,0,I4,0);
5418 VAROR(EMPTY,0,R8,1,I4,1);
5419 rbstr = SysAllocString(szFalse);
5420 VAROR(EMPTY,0,BSTR,rbstr,I2,0);
5421 SysFreeString(rbstr);
5422 rbstr = SysAllocString(szTrue);
5423 VAROR(EMPTY,0,BSTR,rbstr,I2,-1);
5424 SysFreeString(rbstr);
5425 VARORCY(EMPTY,0,10000,I4,1);
5427 /* NULL OR 0 = NULL. NULL OR n = n */
5428 VAROR(NULL,0,NULL,0,NULL,0);
5429 VAROR(NULL,1,NULL,0,NULL,0);
5430 VAROR(NULL,0,I1,0,NULL,0);
5431 VAROR(NULL,0,I1,1,I4,1);
5432 VAROR(NULL,0,UI1,0,NULL,0);
5433 VAROR(NULL,0,UI1,1,UI1,1);
5434 VAROR(NULL,0,I2,0,NULL,0);
5435 VAROR(NULL,0,I2,1,I2,1);
5436 VAROR(NULL,0,UI2,0,NULL,0);
5437 VAROR(NULL,0,UI2,1,I4,1);
5438 VAROR(NULL,0,I4,0,NULL,0);
5439 VAROR(NULL,0,I4,1,I4,1);
5440 VAROR(NULL,0,UI4,0,NULL,0);
5441 VAROR(NULL,0,UI4,1,I4,1);
5442 if (has_i8)
5444 VAROR(NULL,0,I8,0,NULL,0);
5445 VAROR(NULL,0,I8,1,I8,1);
5446 VAROR(NULL,0,UI8,0,NULL,0);
5447 VAROR(NULL,0,UI8,1,I4,1);
5449 VAROR(NULL,0,INT,0,NULL,0);
5450 VAROR(NULL,0,INT,1,I4,1);
5451 VAROR(NULL,0,UINT,0,NULL,0);
5452 VAROR(NULL,0,UINT,1,I4,1);
5453 VAROR(NULL,0,BOOL,0,NULL,0);
5454 VAROR(NULL,0,BOOL,1,BOOL,1);
5455 VAROR(NULL,0,R4,0,NULL,0);
5456 VAROR(NULL,0,R4,1,I4,1);
5457 VAROR(NULL,0,R8,0,NULL,0);
5458 VAROR(NULL,0,R8,1,I4,1);
5459 rbstr = SysAllocString(szFalse);
5460 VAROR(NULL,0,BSTR,rbstr,NULL,0);
5461 SysFreeString(rbstr);
5462 rbstr = SysAllocString(szTrue);
5463 VAROR(NULL,0,BSTR,rbstr,BOOL,VARIANT_TRUE);
5464 SysFreeString(rbstr);
5465 VARORCY(NULL,0,10000,I4,1);
5466 VARORCY(NULL,0,0,NULL,0);
5468 VAROR(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
5469 VAROR(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE);
5470 VAROR(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
5471 VAROR(BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE);
5472 /* Assume x,y & y,x are the same from now on to reduce the number of tests */
5473 VAROR(BOOL,VARIANT_TRUE,I1,-1,I4,-1);
5474 VAROR(BOOL,VARIANT_TRUE,I1,0,I4,-1);
5475 VAROR(BOOL,VARIANT_FALSE,I1,0,I4,0);
5476 VAROR(BOOL,VARIANT_TRUE,UI1,255,I2,-1);
5477 VAROR(BOOL,VARIANT_TRUE,UI1,0,I2,-1);
5478 VAROR(BOOL,VARIANT_FALSE,UI1,0,I2,0);
5479 VAROR(BOOL,VARIANT_TRUE,I2,-1,I2,-1);
5480 VAROR(BOOL,VARIANT_TRUE,I2,0,I2,-1);
5481 VAROR(BOOL,VARIANT_FALSE,I2,0,I2,0);
5482 VAROR(BOOL,VARIANT_TRUE,UI2,65535,I4,-1);
5483 VAROR(BOOL,VARIANT_TRUE,UI2,0,I4,-1);
5484 VAROR(BOOL,VARIANT_FALSE,UI2,0,I4,0);
5485 VAROR(BOOL,VARIANT_TRUE,I4,-1,I4,-1);
5486 VAROR(BOOL,VARIANT_TRUE,I4,0,I4,-1);
5487 VAROR(BOOL,VARIANT_FALSE,I4,0,I4,0);
5488 VAROR(BOOL,VARIANT_TRUE,UI4,0xffffffff,I4,-1);
5489 VAROR(BOOL,VARIANT_TRUE,UI4,0,I4,-1);
5490 VAROR(BOOL,VARIANT_FALSE,UI4,0,I4,0);
5491 VAROR(BOOL,VARIANT_TRUE,R4,-1,I4,-1);
5492 VAROR(BOOL,VARIANT_TRUE,R4,0,I4,-1);
5493 VAROR(BOOL,VARIANT_FALSE,R4,0,I4,0);
5494 VAROR(BOOL,VARIANT_TRUE,R8,-1,I4,-1);
5495 VAROR(BOOL,VARIANT_TRUE,R8,0,I4,-1);
5496 VAROR(BOOL,VARIANT_FALSE,R8,0,I4,0);
5497 VAROR(BOOL,VARIANT_TRUE,DATE,-1,I4,-1);
5498 VAROR(BOOL,VARIANT_TRUE,DATE,0,I4,-1);
5499 VAROR(BOOL,VARIANT_FALSE,DATE,0,I4,0);
5500 if (has_i8)
5502 VAROR(BOOL,VARIANT_TRUE,I8,-1,I8,-1);
5503 VAROR(BOOL,VARIANT_TRUE,I8,0,I8,-1);
5504 VAROR(BOOL,VARIANT_FALSE,I8,0,I8,0);
5505 /* This returns DISP_E_OVERFLOW which indicates that a conversion
5506 * to I4 is performed.
5508 /* VAROR(BOOL,VARIANT_TRUE,UI8,-1,I4,-1); */
5509 VAROR(BOOL,VARIANT_TRUE,UI8,0,I4,-1);
5510 VAROR(BOOL,VARIANT_FALSE,UI8,0,I4,0);
5512 VAROR(BOOL,VARIANT_TRUE,INT,-1,I4,-1);
5513 VAROR(BOOL,VARIANT_TRUE,INT,0,I4,-1);
5514 VAROR(BOOL,VARIANT_FALSE,INT,0,I4,0);
5515 VAROR(BOOL,VARIANT_TRUE,UINT,0xffffffff,I4,-1);
5516 VAROR(BOOL,VARIANT_TRUE,UINT,0,I4,-1);
5517 VAROR(BOOL,VARIANT_FALSE,UINT,0,I4,0);
5518 rbstr = SysAllocString(szFalse);
5519 VAROR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_FALSE);
5520 VAROR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_TRUE);
5521 SysFreeString(rbstr);
5522 rbstr = SysAllocString(szTrue);
5523 VAROR(BOOL,VARIANT_FALSE,BSTR,rbstr,BOOL,VARIANT_TRUE);
5524 VAROR(BOOL,VARIANT_TRUE,BSTR,rbstr,BOOL,VARIANT_TRUE);
5525 SysFreeString(rbstr);
5526 VARORCY(BOOL,VARIANT_TRUE,10000,I4,-1);
5527 VARORCY(BOOL,VARIANT_TRUE,0,I4,-1);
5528 VARORCY(BOOL,VARIANT_FALSE,0,I4,0);
5530 VAROR(I1,-1,I1,-1,I4,-1);
5531 VAROR(I1,-1,I1,0,I4,-1);
5532 VAROR(I1,0,I1,0,I4,0);
5533 VAROR(I1,-1,UI1,255,I4,-1);
5534 VAROR(I1,-1,UI1,0,I4,-1);
5535 VAROR(I1,0,UI1,0,I4,0);
5536 VAROR(I1,-1,I2,-1,I4,-1);
5537 VAROR(I1,-1,I2,0,I4,-1);
5538 VAROR(I1,0,I2,0,I4,0);
5539 VAROR(I1,-1,UI2,65535,I4,-1);
5540 VAROR(I1,-1,UI2,0,I4,-1);
5541 VAROR(I1,0,UI2,0,I4,0);
5542 VAROR(I1,-1,I4,-1,I4,-1);
5543 VAROR(I1,-1,I4,0,I4,-1);
5544 VAROR(I1,0,I4,0,I4,0);
5545 VAROR(I1,-1,UI4,0xffffffff,I4,-1);
5546 VAROR(I1,-1,UI4,0,I4,-1);
5547 VAROR(I1,0,UI4,0,I4,0);
5548 VAROR(I1,-1,R4,-1,I4,-1);
5549 VAROR(I1,-1,R4,0,I4,-1);
5550 VAROR(I1,0,R4,0,I4,0);
5551 VAROR(I1,-1,R8,-1,I4,-1);
5552 VAROR(I1,-1,R8,0,I4,-1);
5553 VAROR(I1,0,R8,0,I4,0);
5554 VAROR(I1,-1,DATE,-1,I4,-1);
5555 VAROR(I1,-1,DATE,0,I4,-1);
5556 VAROR(I1,0,DATE,0,I4,0);
5557 if (has_i8)
5559 VAROR(I1,-1,I8,-1,I8,-1);
5560 VAROR(I1,-1,I8,0,I8,-1);
5561 VAROR(I1,0,I8,0,I8,0);
5562 VAROR(I1,-1,UI8,0,I4,-1);
5563 VAROR(I1,0,UI8,0,I4,0);
5565 VAROR(I1,-1,INT,-1,I4,-1);
5566 VAROR(I1,-1,INT,0,I4,-1);
5567 VAROR(I1,0,INT,0,I4,0);
5568 VAROR(I1,-1,UINT,0xffffffff,I4,-1);
5569 VAROR(I1,-1,UINT,0,I4,-1);
5570 VAROR(I1,0,UINT,0,I4,0);
5571 rbstr = SysAllocString(szFalse);
5572 VAROR(I1,0,BSTR,rbstr,I4,0);
5573 VAROR(I1,-1,BSTR,rbstr,I4,-1);
5574 SysFreeString(rbstr);
5575 rbstr = SysAllocString(szTrue);
5576 VAROR(I1,0,BSTR,rbstr,I4,-1);
5577 VAROR(I1,-1,BSTR,rbstr,I4,-1);
5578 SysFreeString(rbstr);
5579 VARORCY(I1,-1,10000,I4,-1);
5580 VARORCY(I1,-1,0,I4,-1);
5581 VARORCY(I1,0,0,I4,0);
5583 VAROR(UI1,255,UI1,255,UI1,255);
5584 VAROR(UI1,255,UI1,0,UI1,255);
5585 VAROR(UI1,0,UI1,0,UI1,0);
5586 VAROR(UI1,255,I2,-1,I2,-1);
5587 VAROR(UI1,255,I2,0,I2,255);
5588 VAROR(UI1,0,I2,0,I2,0);
5589 VAROR(UI1,255,UI2,65535,I4,65535);
5590 VAROR(UI1,255,UI2,0,I4,255);
5591 VAROR(UI1,0,UI2,0,I4,0);
5592 VAROR(UI1,255,I4,-1,I4,-1);
5593 VAROR(UI1,255,I4,0,I4,255);
5594 VAROR(UI1,0,I4,0,I4,0);
5595 VAROR(UI1,255,UI4,0xffffffff,I4,-1);
5596 VAROR(UI1,255,UI4,0,I4,255);
5597 VAROR(UI1,0,UI4,0,I4,0);
5598 VAROR(UI1,255,R4,-1,I4,-1);
5599 VAROR(UI1,255,R4,0,I4,255);
5600 VAROR(UI1,0,R4,0,I4,0);
5601 VAROR(UI1,255,R8,-1,I4,-1);
5602 VAROR(UI1,255,R8,0,I4,255);
5603 VAROR(UI1,0,R8,0,I4,0);
5604 VAROR(UI1,255,DATE,-1,I4,-1);
5605 VAROR(UI1,255,DATE,0,I4,255);
5606 VAROR(UI1,0,DATE,0,I4,0);
5607 if (has_i8)
5609 VAROR(UI1,255,I8,-1,I8,-1);
5610 VAROR(UI1,255,I8,0,I8,255);
5611 VAROR(UI1,0,I8,0,I8,0);
5612 VAROR(UI1,255,UI8,0,I4,255);
5613 VAROR(UI1,0,UI8,0,I4,0);
5615 VAROR(UI1,255,INT,-1,I4,-1);
5616 VAROR(UI1,255,INT,0,I4,255);
5617 VAROR(UI1,0,INT,0,I4,0);
5618 VAROR(UI1,255,UINT,0xffffffff,I4,-1);
5619 VAROR(UI1,255,UINT,0,I4,255);
5620 VAROR(UI1,0,UINT,0,I4,0);
5621 rbstr = SysAllocString(szFalse);
5622 VAROR(UI1,0,BSTR,rbstr,I2,0);
5623 VAROR(UI1,255,BSTR,rbstr,I2,255);
5624 SysFreeString(rbstr);
5625 rbstr = SysAllocString(szTrue);
5626 VAROR(UI1,0,BSTR,rbstr,I2,-1);
5627 VAROR(UI1,255,BSTR,rbstr,I2,-1);
5628 SysFreeString(rbstr);
5629 VARORCY(UI1,255,10000,I4,255);
5630 VARORCY(UI1,255,0,I4,255);
5631 VARORCY(UI1,0,0,I4,0);
5633 VAROR(I2,-1,I2,-1,I2,-1);
5634 VAROR(I2,-1,I2,0,I2,-1);
5635 VAROR(I2,0,I2,0,I2,0);
5636 VAROR(I2,-1,UI2,65535,I4,-1);
5637 VAROR(I2,-1,UI2,0,I4,-1);
5638 VAROR(I2,0,UI2,0,I4,0);
5639 VAROR(I2,-1,I4,-1,I4,-1);
5640 VAROR(I2,-1,I4,0,I4,-1);
5641 VAROR(I2,0,I4,0,I4,0);
5642 VAROR(I2,-1,UI4,0xffffffff,I4,-1);
5643 VAROR(I2,-1,UI4,0,I4,-1);
5644 VAROR(I2,0,UI4,0,I4,0);
5645 VAROR(I2,-1,R4,-1,I4,-1);
5646 VAROR(I2,-1,R4,0,I4,-1);
5647 VAROR(I2,0,R4,0,I4,0);
5648 VAROR(I2,-1,R8,-1,I4,-1);
5649 VAROR(I2,-1,R8,0,I4,-1);
5650 VAROR(I2,0,R8,0,I4,0);
5651 VAROR(I2,-1,DATE,-1,I4,-1);
5652 VAROR(I2,-1,DATE,0,I4,-1);
5653 VAROR(I2,0,DATE,0,I4,0);
5654 if (has_i8)
5656 VAROR(I2,-1,I8,-1,I8,-1);
5657 VAROR(I2,-1,I8,0,I8,-1);
5658 VAROR(I2,0,I8,0,I8,0);
5659 VAROR(I2,-1,UI8,0,I4,-1);
5660 VAROR(I2,0,UI8,0,I4,0);
5662 VAROR(I2,-1,INT,-1,I4,-1);
5663 VAROR(I2,-1,INT,0,I4,-1);
5664 VAROR(I2,0,INT,0,I4,0);
5665 VAROR(I2,-1,UINT,0xffffffff,I4,-1);
5666 VAROR(I2,-1,UINT,0,I4,-1);
5667 VAROR(I2,0,UINT,0,I4,0);
5668 rbstr = SysAllocString(szFalse);
5669 VAROR(I2,0,BSTR,rbstr,I2,0);
5670 VAROR(I2,-1,BSTR,rbstr,I2,-1);
5671 SysFreeString(rbstr);
5672 rbstr = SysAllocString(szTrue);
5673 VAROR(I2,0,BSTR,rbstr,I2,-1);
5674 VAROR(I2,-1,BSTR,rbstr,I2,-1);
5675 SysFreeString(rbstr);
5676 VARORCY(I2,-1,10000,I4,-1);
5677 VARORCY(I2,-1,0,I4,-1);
5678 VARORCY(I2,0,0,I4,0);
5680 VAROR(UI2,65535,UI2,65535,I4,65535);
5681 VAROR(UI2,65535,UI2,0,I4,65535);
5682 VAROR(UI2,0,UI2,0,I4,0);
5683 VAROR(UI2,65535,I4,-1,I4,-1);
5684 VAROR(UI2,65535,I4,0,I4,65535);
5685 VAROR(UI2,0,I4,0,I4,0);
5686 VAROR(UI2,65535,UI4,0xffffffff,I4,-1);
5687 VAROR(UI2,65535,UI4,0,I4,65535);
5688 VAROR(UI2,0,UI4,0,I4,0);
5689 VAROR(UI2,65535,R4,-1,I4,-1);
5690 VAROR(UI2,65535,R4,0,I4,65535);
5691 VAROR(UI2,0,R4,0,I4,0);
5692 VAROR(UI2,65535,R8,-1,I4,-1);
5693 VAROR(UI2,65535,R8,0,I4,65535);
5694 VAROR(UI2,0,R8,0,I4,0);
5695 VAROR(UI2,65535,DATE,-1,I4,-1);
5696 VAROR(UI2,65535,DATE,0,I4,65535);
5697 VAROR(UI2,0,DATE,0,I4,0);
5698 if (has_i8)
5700 VAROR(UI2,65535,I8,-1,I8,-1);
5701 VAROR(UI2,65535,I8,0,I8,65535);
5702 VAROR(UI2,0,I8,0,I8,0);
5703 VAROR(UI2,65535,UI8,0,I4,65535);
5704 VAROR(UI2,0,UI8,0,I4,0);
5706 VAROR(UI2,65535,INT,-1,I4,-1);
5707 VAROR(UI2,65535,INT,0,I4,65535);
5708 VAROR(UI2,0,INT,0,I4,0);
5709 VAROR(UI2,65535,UINT,0xffffffff,I4,-1);
5710 VAROR(UI2,65535,UINT,0,I4,65535);
5711 VAROR(UI2,0,UINT,0,I4,0);
5712 rbstr = SysAllocString(szFalse);
5713 VAROR(UI2,0,BSTR,rbstr,I4,0);
5714 VAROR(UI2,65535,BSTR,rbstr,I4,65535);
5715 SysFreeString(rbstr);
5716 rbstr = SysAllocString(szTrue);
5717 VAROR(UI2,0,BSTR,rbstr,I4,-1);
5718 VAROR(UI2,65535,BSTR,rbstr,I4,-1);
5719 SysFreeString(rbstr);
5720 VARORCY(UI2,65535,10000,I4,65535);
5721 VARORCY(UI2,65535,0,I4,65535);
5722 VARORCY(UI2,0,0,I4,0);
5724 VAROR(I4,-1,I4,-1,I4,-1);
5725 VAROR(I4,-1,I4,0,I4,-1);
5726 VAROR(I4,0,I4,0,I4,0);
5727 VAROR(I4,-1,UI4,0xffffffff,I4,-1);
5728 VAROR(I4,-1,UI4,0,I4,-1);
5729 VAROR(I4,0,UI4,0,I4,0);
5730 VAROR(I4,-1,R4,-1,I4,-1);
5731 VAROR(I4,-1,R4,0,I4,-1);
5732 VAROR(I4,0,R4,0,I4,0);
5733 VAROR(I4,-1,R8,-1,I4,-1);
5734 VAROR(I4,-1,R8,0,I4,-1);
5735 VAROR(I4,0,R8,0,I4,0);
5736 VAROR(I4,-1,DATE,-1,I4,-1);
5737 VAROR(I4,-1,DATE,0,I4,-1);
5738 VAROR(I4,0,DATE,0,I4,0);
5739 if (has_i8)
5741 VAROR(I4,-1,I8,-1,I8,-1);
5742 VAROR(I4,-1,I8,0,I8,-1);
5743 VAROR(I4,0,I8,0,I8,0);
5744 VAROR(I4,-1,UI8,0,I4,-1);
5745 VAROR(I4,0,UI8,0,I4,0);
5747 VAROR(I4,-1,INT,-1,I4,-1);
5748 VAROR(I4,-1,INT,0,I4,-1);
5749 VAROR(I4,0,INT,0,I4,0);
5750 VAROR(I4,-1,UINT,0xffffffff,I4,-1);
5751 VAROR(I4,-1,UINT,0,I4,-1);
5752 VAROR(I4,0,UINT,0,I4,0);
5753 rbstr = SysAllocString(szFalse);
5754 VAROR(I4,0,BSTR,rbstr,I4,0);
5755 VAROR(I4,-1,BSTR,rbstr,I4,-1);
5756 SysFreeString(rbstr);
5757 rbstr = SysAllocString(szTrue);
5758 VAROR(I4,0,BSTR,rbstr,I4,-1);
5759 VAROR(I4,-1,BSTR,rbstr,I4,-1);
5760 SysFreeString(rbstr);
5761 VARORCY(I4,-1,10000,I4,-1);
5762 VARORCY(I4,-1,0,I4,-1);
5763 VARORCY(I4,0,0,I4,0);
5765 VAROR(UI4,0xffffffff,UI4,0xffffffff,I4,-1);
5766 VAROR(UI4,0xffffffff,UI4,0,I4,-1);
5767 VAROR(UI4,0,UI4,0,I4,0);
5768 VAROR(UI4,0xffffffff,R4,-1,I4,-1);
5769 VAROR(UI4,0xffffffff,R4,0,I4,-1);
5770 VAROR(UI4,0,R4,0,I4,0);
5771 VAROR(UI4,0xffffffff,R8,-1,I4,-1);
5772 VAROR(UI4,0xffffffff,R8,0,I4,-1);
5773 VAROR(UI4,0,R8,0,I4,0);
5774 VAROR(UI4,0xffffffff,DATE,-1,I4,-1);
5775 VAROR(UI4,0xffffffff,DATE,0,I4,-1);
5776 VAROR(UI4,0,DATE,0,I4,0);
5777 if (has_i8)
5779 VAROR(UI4,0xffffffff,I8,-1,I8,-1);
5780 VAROR(UI4,0xffffffff,I8,0,I8,0xffffffff);
5781 VAROR(UI4,0,I8,0,I8,0);
5782 VAROR(UI4,0xffffffff,UI8,0,I4,-1);
5783 VAROR(UI4,0,UI8,0,I4,0);
5785 VAROR(UI4,0xffffffff,INT,-1,I4,-1);
5786 VAROR(UI4,0xffffffff,INT,0,I4,-1);
5787 VAROR(UI4,0,INT,0,I4,0);
5788 VAROR(UI4,0xffffffff,UINT,0xffffffff,I4,-1);
5789 VAROR(UI4,0xffffffff,UINT,0,I4,-1);
5790 VAROR(UI4,0,UINT,0,I4,0);
5791 rbstr = SysAllocString(szFalse);
5792 VAROR(UI4,0,BSTR,rbstr,I4,0);
5793 VAROR(UI4,0xffffffff,BSTR,rbstr,I4,-1);
5794 SysFreeString(rbstr);
5795 rbstr = SysAllocString(szTrue);
5796 VAROR(UI4,0,BSTR,rbstr,I4,-1);
5797 VAROR(UI4,0xffffffff,BSTR,rbstr,I4,-1);
5798 SysFreeString(rbstr);
5799 VARORCY(UI4,0xffffffff,10000,I4,-1);
5800 VARORCY(UI4,0xffffffff,0,I4,-1);
5801 VARORCY(UI4,0,0,I4,0);
5803 VAROR(R4,-1,R4,-1,I4,-1);
5804 VAROR(R4,-1,R4,0,I4,-1);
5805 VAROR(R4,0,R4,0,I4,0);
5806 VAROR(R4,-1,R8,-1,I4,-1);
5807 VAROR(R4,-1,R8,0,I4,-1);
5808 VAROR(R4,0,R8,0,I4,0);
5809 VAROR(R4,-1,DATE,-1,I4,-1);
5810 VAROR(R4,-1,DATE,0,I4,-1);
5811 VAROR(R4,0,DATE,0,I4,0);
5812 if (has_i8)
5814 VAROR(R4,-1,I8,-1,I8,-1);
5815 VAROR(R4,-1,I8,0,I8,-1);
5816 VAROR(R4,0,I8,0,I8,0);
5817 VAROR(R4,-1,UI8,0,I4,-1);
5818 VAROR(R4,0,UI8,0,I4,0);
5820 VAROR(R4,-1,INT,-1,I4,-1);
5821 VAROR(R4,-1,INT,0,I4,-1);
5822 VAROR(R4,0,INT,0,I4,0);
5823 VAROR(R4,-1,UINT,0xffffffff,I4,-1);
5824 VAROR(R4,-1,UINT,0,I4,-1);
5825 VAROR(R4,0,UINT,0,I4,0);
5826 rbstr = SysAllocString(szFalse);
5827 VAROR(R4,0,BSTR,rbstr,I4,0);
5828 VAROR(R4,-1,BSTR,rbstr,I4,-1);
5829 SysFreeString(rbstr);
5830 rbstr = SysAllocString(szTrue);
5831 VAROR(R4,0,BSTR,rbstr,I4,-1);
5832 VAROR(R4,-1,BSTR,rbstr,I4,-1);
5833 SysFreeString(rbstr);
5834 VARORCY(R4,-1,10000,I4,-1);
5835 VARORCY(R4,-1,0,I4,-1);
5836 VARORCY(R4,0,0,I4,0);
5838 VAROR(R8,-1,R8,-1,I4,-1);
5839 VAROR(R8,-1,R8,0,I4,-1);
5840 VAROR(R8,0,R8,0,I4,0);
5841 VAROR(R8,-1,DATE,-1,I4,-1);
5842 VAROR(R8,-1,DATE,0,I4,-1);
5843 VAROR(R8,0,DATE,0,I4,0);
5844 if (has_i8)
5846 VAROR(R8,-1,I8,-1,I8,-1);
5847 VAROR(R8,-1,I8,0,I8,-1);
5848 VAROR(R8,0,I8,0,I8,0);
5849 VAROR(R8,-1,UI8,0,I4,-1);
5850 VAROR(R8,0,UI8,0,I4,0);
5852 VAROR(R8,-1,INT,-1,I4,-1);
5853 VAROR(R8,-1,INT,0,I4,-1);
5854 VAROR(R8,0,INT,0,I4,0);
5855 VAROR(R8,-1,UINT,0xffffffff,I4,-1);
5856 VAROR(R8,-1,UINT,0,I4,-1);
5857 VAROR(R8,0,UINT,0,I4,0);
5858 rbstr = SysAllocString(szFalse);
5859 VAROR(R8,0,BSTR,rbstr,I4,0);
5860 VAROR(R8,-1,BSTR,rbstr,I4,-1);
5861 SysFreeString(rbstr);
5862 rbstr = SysAllocString(szTrue);
5863 VAROR(R8,0,BSTR,rbstr,I4,-1);
5864 VAROR(R8,-1,BSTR,rbstr,I4,-1);
5865 SysFreeString(rbstr);
5866 VARORCY(R8,-1,10000,I4,-1);
5867 VARORCY(R8,-1,0,I4,-1);
5868 VARORCY(R8,0,0,I4,0);
5870 VAROR(DATE,-1,DATE,-1,I4,-1);
5871 VAROR(DATE,-1,DATE,0,I4,-1);
5872 VAROR(DATE,0,DATE,0,I4,0);
5873 if (has_i8)
5875 VAROR(DATE,-1,I8,-1,I8,-1);
5876 VAROR(DATE,-1,I8,0,I8,-1);
5877 VAROR(DATE,0,I8,0,I8,0);
5878 VAROR(DATE,-1,UI8,0,I4,-1);
5879 VAROR(DATE,0,UI8,0,I4,0);
5881 VAROR(DATE,-1,INT,-1,I4,-1);
5882 VAROR(DATE,-1,INT,0,I4,-1);
5883 VAROR(DATE,0,INT,0,I4,0);
5884 VAROR(DATE,-1,UINT,0xffffffff,I4,-1);
5885 VAROR(DATE,-1,UINT,0,I4,-1);
5886 VAROR(DATE,0,UINT,0,I4,0);
5887 rbstr = SysAllocString(szFalse);
5888 VAROR(DATE,0,BSTR,rbstr,I4,0);
5889 VAROR(DATE,-1,BSTR,rbstr,I4,-1);
5890 SysFreeString(rbstr);
5891 rbstr = SysAllocString(szTrue);
5892 VAROR(DATE,0,BSTR,rbstr,I4,-1);
5893 VAROR(DATE,-1,BSTR,rbstr,I4,-1);
5894 SysFreeString(rbstr);
5895 VARORCY(DATE,-1,10000,I4,-1);
5896 VARORCY(DATE,-1,0,I4,-1);
5897 VARORCY(DATE,0,0,I4,0);
5899 if (has_i8)
5901 VAROR(I8,-1,I8,-1,I8,-1);
5902 VAROR(I8,-1,I8,0,I8,-1);
5903 VAROR(I8,0,I8,0,I8,0);
5904 VAROR(I8,-1,UI8,0,I8,-1);
5905 VAROR(I8,0,UI8,0,I8,0);
5906 /* These overflow under native and Wine
5907 VAROR(I8,-1,INT,-1,I4,-1);
5908 VAROR(I8,-1,INT,0,I4,-1);
5909 VAROR(I8,0,INT,0,I4,0); */
5910 VAROR(I8,-1,UINT,0xffffffff,I8,-1);
5911 VAROR(I8,-1,UINT,0,I8,-1);
5912 VAROR(I8,0,UINT,0,I8,0);
5913 rbstr = SysAllocString(szFalse);
5914 VAROR(I8,0,BSTR,rbstr,I8,0);
5915 VAROR(I8,-1,BSTR,rbstr,I8,-1);
5916 SysFreeString(rbstr);
5917 rbstr = SysAllocString(szTrue);
5918 VAROR(I8,0,BSTR,rbstr,I8,-1);
5919 VAROR(I8,-1,BSTR,rbstr,I8,-1);
5920 SysFreeString(rbstr);
5921 VARORCY(I8,-1,10000,I8,-1);
5922 VARORCY(I8,-1,0,I8,-1);
5923 VARORCY(I8,0,0,I8,0);
5925 VAROR(UI8,0xffff,UI8,0xffff,I4,0xffff);
5926 VAROR(UI8,0xffff,UI8,0,I4,0xffff);
5927 VAROR(UI8,0,UI8,0,I4,0);
5928 VAROR(UI8,0xffff,INT,-1,I4,-1);
5929 VAROR(UI8,0xffff,INT,0,I4,0xffff);
5930 VAROR(UI8,0,INT,0,I4,0);
5931 VAROR(UI8,0xffff,UINT,0xffff,I4,0xffff);
5932 VAROR(UI8,0xffff,UINT,0,I4,0xffff);
5933 VAROR(UI8,0,UINT,0,I4,0);
5934 rbstr = SysAllocString(szFalse);
5935 VAROR(UI8,0,BSTR,rbstr,I4,0);
5936 VAROR(UI8,0xffff,BSTR,rbstr,I4,0xffff);
5937 SysFreeString(rbstr);
5938 rbstr = SysAllocString(szTrue);
5939 VAROR(UI8,0,BSTR,rbstr,I4,-1);
5940 VAROR(UI8,0xffff,BSTR,rbstr,I4,-1);
5941 SysFreeString(rbstr);
5942 VARORCY(UI8,0xffff,10000,I4,0xffff);
5943 VARORCY(UI8,0xffff,0,I4,0xffff);
5944 VARORCY(UI8,0,0,I4,0);
5947 VAROR(INT,-1,INT,-1,I4,-1);
5948 VAROR(INT,-1,INT,0,I4,-1);
5949 VAROR(INT,0,INT,0,I4,0);
5950 VAROR(INT,-1,UINT,0xffff,I4,-1);
5951 VAROR(INT,-1,UINT,0,I4,-1);
5952 VAROR(INT,0,UINT,0,I4,0);
5953 rbstr = SysAllocString(szFalse);
5954 VAROR(INT,0,BSTR,rbstr,I4,0);
5955 VAROR(INT,-1,BSTR,rbstr,I4,-1);
5956 SysFreeString(rbstr);
5957 rbstr = SysAllocString(szTrue);
5958 VAROR(INT,0,BSTR,rbstr,I4,-1);
5959 VAROR(INT,-1,BSTR,rbstr,I4,-1);
5960 SysFreeString(rbstr);
5961 VARORCY(INT,-1,10000,I4,-1);
5962 VARORCY(INT,-1,0,I4,-1);
5963 VARORCY(INT,0,0,I4,0);
5965 VAROR(UINT,0xffff,UINT,0xffff,I4,0xffff);
5966 VAROR(UINT,0xffff,UINT,0,I4,0xffff);
5967 VAROR(UINT,0,UINT,0,I4,0);
5968 rbstr = SysAllocString(szFalse);
5969 VAROR(UINT,0,BSTR,rbstr,I4,0);
5970 VAROR(UINT,0xffff,BSTR,rbstr,I4,0xffff);
5971 SysFreeString(rbstr);
5972 rbstr = SysAllocString(szTrue);
5973 VAROR(UINT,0,BSTR,rbstr,I4,-1);
5974 VAROR(UINT,0xffff,BSTR,rbstr,I4,-1);
5975 SysFreeString(rbstr);
5976 VARORCY(UINT,0xffff,10000,I4,0xffff);
5977 VARORCY(UINT,0xffff,0,I4,0xffff);
5978 VARORCY(UINT,0,0,I4,0);
5980 lbstr = SysAllocString(szFalse);
5981 rbstr = SysAllocString(szFalse);
5982 VAROR(BSTR,lbstr,BSTR,rbstr,BOOL,0);
5983 SysFreeString(rbstr);
5984 rbstr = SysAllocString(szTrue);
5985 VAROR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_TRUE);
5986 SysFreeString(lbstr);
5987 lbstr = SysAllocString(szTrue);
5988 VAROR(BSTR,lbstr,BSTR,rbstr,BOOL,VARIANT_TRUE);
5989 VARORCY(BSTR,lbstr,10000,I4,-1);
5990 SysFreeString(lbstr);
5991 lbstr = SysAllocString(szFalse);
5992 VARORCY(BSTR,lbstr,10000,I4,1);
5993 SysFreeString(lbstr);
5994 SysFreeString(rbstr);
5997 static HRESULT (WINAPI *pVarEqv)(LPVARIANT,LPVARIANT,LPVARIANT);
5999 #define VAREQV(vt1,val1,vt2,val2,rvt,rval) \
6000 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
6001 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
6002 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
6003 test_var_call2( __LINE__, pVarEqv, &left, &right, &exp )
6005 static void test_VarEqv(void)
6007 VARIANT left, right, exp, result;
6008 VARTYPE i;
6009 HRESULT hres;
6011 CHECKPTR(VarEqv);
6013 /* Test all possible flag/vt combinations & the resulting vt type */
6014 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
6016 VARTYPE leftvt, rightvt, resvt;
6018 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
6020 SKIPTESTS(leftvt);
6022 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
6024 BOOL bFail = FALSE;
6026 SKIPTESTS(rightvt);
6028 if (leftvt == VT_BSTR || rightvt == VT_BSTR ||
6029 leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
6030 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN)
6031 continue;
6033 memset(&left, 0, sizeof(left));
6034 memset(&right, 0, sizeof(right));
6035 V_VT(&left) = leftvt | ExtraFlags[i];
6036 V_VT(&right) = rightvt | ExtraFlags[i];
6037 V_VT(&result) = VT_EMPTY;
6038 resvt = VT_I4;
6040 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
6041 !IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
6042 !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
6043 leftvt == VT_CLSID || rightvt == VT_CLSID ||
6044 leftvt == VT_RECORD || rightvt == VT_RECORD ||
6045 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
6046 leftvt == VT_ERROR || rightvt == VT_ERROR)
6048 bFail = TRUE;
6050 if (leftvt == VT_EMPTY || rightvt == VT_EMPTY)
6052 if (leftvt == rightvt ||
6053 leftvt == VT_I2 || rightvt == VT_I2 ||
6054 leftvt == VT_UI1 || rightvt == VT_UI1 ||
6055 leftvt == VT_BOOL || rightvt == VT_BOOL)
6056 resvt = VT_I2;
6057 else if (leftvt == VT_NULL || rightvt == VT_NULL)
6058 resvt = VT_NULL;
6059 else if (leftvt == VT_I8 || rightvt == VT_I8)
6060 resvt = VT_I8;
6062 else if (leftvt == VT_NULL || rightvt == VT_NULL)
6064 resvt = VT_NULL;
6066 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
6068 if (leftvt == rightvt)
6069 resvt = VT_UI1;
6070 else if (leftvt == rightvt ||
6071 leftvt == VT_I2 || rightvt == VT_I2 ||
6072 leftvt == VT_BOOL || rightvt == VT_BOOL)
6074 resvt = VT_I2;
6076 else if (leftvt == VT_I8 || rightvt == VT_I8)
6077 resvt = VT_I8;
6079 else if (leftvt == VT_I2 || rightvt == VT_I2)
6081 if (leftvt == rightvt ||
6082 leftvt == VT_BOOL || rightvt == VT_BOOL)
6083 resvt = VT_I2;
6084 else if (leftvt == VT_I8 || rightvt == VT_I8)
6085 resvt = VT_I8;
6087 else if (leftvt == VT_BOOL && rightvt == VT_BOOL)
6089 resvt = VT_BOOL;
6091 else if (leftvt == VT_I8 || rightvt == VT_I8)
6093 if (leftvt == VT_INT || rightvt == VT_INT)
6094 bFail = TRUE;
6095 else
6096 resvt = VT_I8;
6098 hres = pVarEqv(&left, &right, &result);
6099 if (bFail)
6100 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
6101 "VarEqv: %d|0x%X, %d|0x%X: Expected failure, got 0x%X vt %d\n",
6102 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres,
6103 V_VT(&result));
6104 else
6105 ok(hres == S_OK && V_VT(&result) == resvt,
6106 "VarEqv: %d|0x%X, %d|0x%X: expected S_OK, vt %d, got 0x%X vt %d\n",
6107 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], resvt, hres,
6108 V_VT(&result));
6113 /* Test returned values */
6114 VAREQV(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
6115 VAREQV(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE);
6116 VAREQV(BOOL,TRUE,BOOL,TRUE,BOOL,VARIANT_TRUE);
6117 VAREQV(BOOL,FALSE,BOOL,FALSE,BOOL,VARIANT_TRUE);
6118 VAREQV(BOOL,TRUE,BOOL,FALSE,BOOL,-2);
6119 VAREQV(BOOL,FALSE,BOOL,TRUE,BOOL,-2);
6120 VAREQV(BOOL,6,BOOL,7,BOOL,-2);
6121 VAREQV(BOOL,6,BOOL,6,BOOL,VARIANT_TRUE);
6122 VAREQV(BOOL,VARIANT_TRUE,I2,VARIANT_TRUE,I2,VARIANT_TRUE);
6123 VAREQV(BOOL,VARIANT_TRUE,I2,VARIANT_FALSE,I2,VARIANT_FALSE);
6124 VAREQV(BOOL,6,I2,7,I2,-2);
6125 VAREQV(UI1,1,UI1,1,UI1,255);
6126 VAREQV(UI1,1,UI1,0,UI1,254);
6127 VAREQV(UI1,0,UI1,1,UI1,254);
6128 if (has_i8)
6130 VAREQV(UI4,VARIANT_FALSE,I8,VARIANT_FALSE,I8,-1);
6131 VAREQV(UI4,5,I8,19,I8,-23);
6132 VAREQV(UI4,VARIANT_FALSE,UI8,VARIANT_FALSE,I4,-1);
6136 static HRESULT (WINAPI *pVarMul)(LPVARIANT,LPVARIANT,LPVARIANT);
6138 #define VARMUL(vt1,val1,vt2,val2,rvt,rval) \
6139 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
6140 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
6141 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
6142 test_var_call2( __LINE__, pVarMul, &left, &right, &exp )
6144 static void test_VarMul(void)
6146 VARIANT left, right, exp, result, cy, dec;
6147 VARTYPE i;
6148 BSTR lbstr, rbstr;
6149 HRESULT hres;
6150 double r;
6152 CHECKPTR(VarMul);
6154 lbstr = SysAllocString(sz12);
6155 rbstr = SysAllocString(sz12);
6157 /* Test all possible flag/vt combinations & the resulting vt type */
6158 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
6160 VARTYPE leftvt, rightvt, resvt;
6162 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
6165 SKIPTESTS(leftvt);
6167 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
6169 BOOL bFail = FALSE;
6171 SKIPTESTS(rightvt);
6173 if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
6174 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN)
6175 continue;
6177 memset(&left, 0, sizeof(left));
6178 memset(&right, 0, sizeof(right));
6179 V_VT(&left) = leftvt | ExtraFlags[i];
6180 if (leftvt == VT_BSTR)
6181 V_BSTR(&left) = lbstr;
6182 V_VT(&right) = rightvt | ExtraFlags[i];
6183 if (rightvt == VT_BSTR)
6184 V_BSTR(&right) = rbstr;
6185 V_VT(&result) = VT_EMPTY;
6186 resvt = VT_UNKNOWN;
6188 /* Don't ask me why but native VarMul cannot handle:
6189 VT_I1, VT_UI2, VT_UI4, VT_INT, VT_UINT and VT_UI8.
6190 Tested with DCOM98, Win2k, WinXP */
6191 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
6192 !IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
6193 !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
6194 leftvt == VT_CLSID || rightvt == VT_CLSID ||
6195 leftvt == VT_RECORD || rightvt == VT_RECORD ||
6196 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
6197 leftvt == VT_ERROR || rightvt == VT_ERROR ||
6198 leftvt == VT_I1 || rightvt == VT_I1 ||
6199 leftvt == VT_UI2 || rightvt == VT_UI2 ||
6200 leftvt == VT_UI4 || rightvt == VT_UI4 ||
6201 leftvt == VT_UI8 || rightvt == VT_UI8 ||
6202 leftvt == VT_INT || rightvt == VT_INT ||
6203 leftvt == VT_UINT || rightvt == VT_UINT) {
6204 bFail = TRUE;
6207 if (leftvt == VT_NULL || rightvt == VT_NULL)
6208 resvt = VT_NULL;
6209 else if (leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
6210 resvt = VT_DECIMAL;
6211 else if (leftvt == VT_R8 || rightvt == VT_R8 ||
6212 leftvt == VT_BSTR || rightvt == VT_BSTR ||
6213 leftvt == VT_DATE || rightvt == VT_DATE)
6214 resvt = VT_R8;
6215 else if (leftvt == VT_R4 || rightvt == VT_R4) {
6216 if (leftvt == VT_I4 || rightvt == VT_I4 ||
6217 leftvt == VT_I8 || rightvt == VT_I8 ||
6218 leftvt == VT_CY || rightvt == VT_CY)
6219 resvt = VT_R8;
6220 else
6221 resvt = VT_R4;
6222 } else if (leftvt == VT_CY || rightvt == VT_CY)
6223 resvt = VT_CY;
6224 else if (leftvt == VT_I8 || rightvt == VT_I8)
6225 resvt = VT_I8;
6226 else if (leftvt == VT_I4 || rightvt == VT_I4)
6227 resvt = VT_I4;
6228 else if (leftvt == VT_I2 || rightvt == VT_I2 ||
6229 leftvt == VT_BOOL || rightvt == VT_BOOL ||
6230 (leftvt == VT_EMPTY && rightvt == VT_EMPTY))
6231 resvt = VT_I2;
6232 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
6233 resvt = VT_UI1;
6235 hres = pVarMul(&left, &right, &result);
6236 if (bFail) {
6237 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
6238 "VarMul: %d|0x%X, %d|0x%X: Expected failure, got 0x%X vt %d\n",
6239 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres,
6240 V_VT(&result));
6241 } else {
6242 ok(hres == S_OK && V_VT(&result) == resvt,
6243 "VarMul: %d|0x%X, %d|0x%X: expected S_OK, vt %d, got 0x%X vt %d\n",
6244 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], resvt, hres,
6245 V_VT(&result));
6251 /* Test returned values */
6252 VARMUL(I4,4,I4,2,I4,8);
6253 VARMUL(I2,4,I2,2,I2,8);
6254 VARMUL(I2,-13,I4,5,I4,-65);
6255 VARMUL(I4,-13,I4,5,I4,-65);
6256 VARMUL(I2,7,R4,0.5f,R4,3.5f);
6257 VARMUL(R4,0.5f,I4,5,R8,2.5);
6258 VARMUL(R8,7.1,BOOL,0,R8,0);
6259 VARMUL(BSTR,lbstr,I2,4,R8,48);
6260 VARMUL(BSTR,lbstr,BOOL,1,R8,12);
6261 VARMUL(BSTR,lbstr,R4,0.1f,R8,1.2);
6262 VARMUL(BSTR,lbstr,BSTR,rbstr,R8,144);
6263 VARMUL(R4,0.2f,BSTR,rbstr,R8,2.4);
6264 VARMUL(DATE,2.25,I4,7,R8,15.75);
6266 VARMUL(UI1, UI1_MAX, UI1, UI1_MAX, I4, UI1_MAX * UI1_MAX);
6267 VARMUL(I2, I2_MAX, I2, I2_MAX, I4, I2_MAX * I2_MAX);
6268 VARMUL(I2, I2_MAX, I2, I2_MIN, I4, I2_MAX * I2_MIN);
6269 VARMUL(I2, I2_MIN, I2, I2_MIN, I4, I2_MIN * I2_MIN);
6270 VARMUL(I4, I4_MAX, I4, I4_MAX, R8, (double)I4_MAX * I4_MAX);
6271 VARMUL(I4, I4_MAX, I4, I4_MIN, R8, (double)I4_MAX * I4_MIN);
6272 VARMUL(I4, I4_MIN, I4, I4_MIN, R8, (double)I4_MIN * I4_MIN);
6273 VARMUL(R4, R4_MAX, R4, R4_MAX, R8, (double)R4_MAX * R4_MAX);
6274 VARMUL(R4, R4_MAX, R4, R4_MIN, R4, R4_MAX * R4_MIN);
6275 VARMUL(R4, R4_MIN, R4, R4_MIN, R4, R4_MIN * R4_MIN);
6276 VARMUL(R8, R8_MAX, R8, R8_MIN, R8, R8_MAX * R8_MIN);
6277 VARMUL(R8, R8_MIN, R8, R8_MIN, R8, R8_MIN * R8_MIN);
6279 /* Manuly test some VT_CY and VT_DECIMAL variants */
6280 V_VT(&cy) = VT_CY;
6281 hres = VarCyFromI4(4711, &V_CY(&cy));
6282 ok(hres == S_OK, "VarCyFromI4 failed!\n");
6283 V_VT(&dec) = VT_DECIMAL;
6284 hres = VarDecFromR8(-4.2, &V_DECIMAL(&dec));
6285 ok(hres == S_OK, "VarDecFromR4 failed!\n");
6286 memset(&left, 0, sizeof(left));
6287 memset(&right, 0, sizeof(right));
6288 V_VT(&left) = VT_I4;
6289 V_I4(&left) = -11;
6290 V_VT(&right) = VT_UI1;
6291 V_UI1(&right) = 9;
6293 hres = pVarMul(&cy, &right, &result);
6294 ok(hres == S_OK && V_VT(&result) == VT_CY, "VarMul: expected coerced type VT_CY, got %s!\n", vtstr(V_VT(&result)));
6295 hres = VarR8FromCy(V_CY(&result), &r);
6296 ok(hres == S_OK && EQ_DOUBLE(r, 42399.0), "VarMul: CY value %f, expected %f\n", r, 42399.0);
6298 hres = pVarMul(&left, &dec, &result);
6299 ok(hres == S_OK && V_VT(&result) == VT_DECIMAL, "VarMul: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
6300 hres = VarR8FromDec(&V_DECIMAL(&result), &r);
6301 ok(hres == S_OK && EQ_DOUBLE(r, 46.2), "VarMul: DECIMAL value %f, expected %f\n", r, 46.2);
6303 SysFreeString(lbstr);
6304 SysFreeString(rbstr);
6307 static HRESULT (WINAPI *pVarAdd)(LPVARIANT,LPVARIANT,LPVARIANT);
6309 #define VARADD(vt1,val1,vt2,val2,rvt,rval) \
6310 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
6311 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
6312 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
6313 test_var_call2( __LINE__, pVarAdd, &left, &right, &exp )
6315 static void test_VarAdd(void)
6317 VARIANT left, right, exp, result, cy, dec;
6318 VARTYPE i;
6319 BSTR lbstr, rbstr;
6320 HRESULT hres;
6321 double r;
6323 CHECKPTR(VarAdd);
6325 lbstr = SysAllocString(sz12);
6326 rbstr = SysAllocString(sz12);
6328 /* Test all possible flag/vt combinations & the resulting vt type */
6329 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
6331 VARTYPE leftvt, rightvt, resvt;
6333 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
6336 SKIPTESTS(leftvt);
6338 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
6340 BOOL bFail = FALSE;
6342 SKIPTESTS(rightvt);
6344 if (leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN)
6345 continue;
6347 memset(&left, 0, sizeof(left));
6348 memset(&right, 0, sizeof(right));
6349 V_VT(&left) = leftvt | ExtraFlags[i];
6350 if (leftvt == VT_BSTR)
6351 V_BSTR(&left) = lbstr;
6352 V_VT(&right) = rightvt | ExtraFlags[i];
6353 if (rightvt == VT_BSTR)
6354 V_BSTR(&right) = rbstr;
6355 V_VT(&result) = VT_EMPTY;
6356 resvt = VT_ERROR;
6358 /* Don't ask me why but native VarAdd cannot handle:
6359 VT_I1, VT_UI2, VT_UI4, VT_INT, VT_UINT and VT_UI8.
6360 Tested with DCOM98, Win2k, WinXP */
6361 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
6362 !IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
6363 !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
6364 leftvt == VT_CLSID || rightvt == VT_CLSID ||
6365 leftvt == VT_RECORD || rightvt == VT_RECORD ||
6366 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
6367 leftvt == VT_ERROR || rightvt == VT_ERROR ||
6368 leftvt == VT_I1 || rightvt == VT_I1 ||
6369 leftvt == VT_UI2 || rightvt == VT_UI2 ||
6370 leftvt == VT_UI4 || rightvt == VT_UI4 ||
6371 leftvt == VT_UI8 || rightvt == VT_UI8 ||
6372 leftvt == VT_INT || rightvt == VT_INT ||
6373 leftvt == VT_UINT || rightvt == VT_UINT) {
6374 bFail = TRUE;
6377 if (leftvt == VT_NULL || rightvt == VT_NULL)
6378 resvt = VT_NULL;
6379 else if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH)
6380 bFail = TRUE;
6381 else if (leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
6382 resvt = VT_DECIMAL;
6383 else if (leftvt == VT_DATE || rightvt == VT_DATE)
6384 resvt = VT_DATE;
6385 else if (leftvt == VT_CY || rightvt == VT_CY)
6386 resvt = VT_CY;
6387 else if (leftvt == VT_R8 || rightvt == VT_R8)
6388 resvt = VT_R8;
6389 else if (leftvt == VT_BSTR || rightvt == VT_BSTR) {
6390 if ((leftvt == VT_BSTR && rightvt == VT_BSTR) ||
6391 leftvt == VT_EMPTY || rightvt == VT_EMPTY)
6392 resvt = VT_BSTR;
6393 else
6394 resvt = VT_R8;
6395 } else if (leftvt == VT_R4 || rightvt == VT_R4) {
6396 if (leftvt == VT_I4 || rightvt == VT_I4 ||
6397 leftvt == VT_I8 || rightvt == VT_I8)
6398 resvt = VT_R8;
6399 else
6400 resvt = VT_R4;
6402 else if (leftvt == VT_I8 || rightvt == VT_I8)
6403 resvt = VT_I8;
6404 else if (leftvt == VT_I4 || rightvt == VT_I4)
6405 resvt = VT_I4;
6406 else if (leftvt == VT_I2 || rightvt == VT_I2 ||
6407 leftvt == VT_BOOL || rightvt == VT_BOOL ||
6408 (leftvt == VT_EMPTY && rightvt == VT_EMPTY))
6409 resvt = VT_I2;
6410 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
6411 resvt = VT_UI1;
6413 hres = pVarAdd(&left, &right, &result);
6414 if (bFail) {
6415 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
6416 "VarAdd: %d|0x%X, %d|0x%X: Expected failure, got 0x%X vt %d\n",
6417 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres,
6418 V_VT(&result));
6419 } else {
6420 ok(hres == S_OK && V_VT(&result) == resvt,
6421 "VarAdd: %d|0x%X, %d|0x%X: expected S_OK, vt %d, got 0x%X vt %d\n",
6422 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], resvt, hres,
6423 V_VT(&result));
6425 /* Note, we don't clear left/right deliberately here */
6426 VariantClear(&result);
6431 /* Test returned values */
6432 VARADD(I4,4,I4,2,I4,6);
6433 VARADD(I2,4,I2,2,I2,6);
6434 VARADD(I2,-13,I4,5,I4,-8);
6435 VARADD(I4,-13,I4,5,I4,-8);
6436 VARADD(I2,7,R4,0.5f,R4,7.5f);
6437 VARADD(R4,0.5f,I4,5,R8,5.5);
6438 VARADD(R8,7.1,BOOL,0,R8,7.1);
6439 VARADD(BSTR,lbstr,I2,4,R8,16);
6440 VARADD(BSTR,lbstr,BOOL,1,R8,13);
6441 VARADD(BSTR,lbstr,R4,0.1f,R8,12.1);
6442 VARADD(R4,0.2f,BSTR,rbstr,R8,12.2);
6443 VARADD(DATE,2.25,I4,7,DATE,9.25);
6444 VARADD(DATE,1.25,R4,-1.7f,DATE,-0.45);
6446 VARADD(UI1, UI1_MAX, UI1, UI1_MAX, I2, UI1_MAX + UI1_MAX);
6447 VARADD(I2, I2_MAX, I2, I2_MAX, I4, I2_MAX + I2_MAX);
6448 VARADD(I2, I2_MAX, I2, I2_MIN, I2, I2_MAX + I2_MIN);
6449 VARADD(I2, I2_MIN, I2, I2_MIN, I4, I2_MIN + I2_MIN);
6450 VARADD(I4, I4_MAX, I4, I4_MIN, I4, I4_MAX + I4_MIN);
6451 VARADD(I4, I4_MAX, I4, I4_MAX, R8, (double)I4_MAX + I4_MAX);
6452 VARADD(I4, I4_MIN, I4, I4_MIN, R8, (double)I4_MIN + I4_MIN);
6453 VARADD(R4, R4_MAX, R4, R4_MAX, R8, (double)R4_MAX + R4_MAX);
6454 VARADD(R4, R4_MAX, R4, R4_MIN, R4, R4_MAX + R4_MIN);
6455 VARADD(R4, R4_MIN, R4, R4_MIN, R4, R4_MIN + R4_MIN);
6456 VARADD(R8, R8_MAX, R8, R8_MIN, R8, R8_MAX + R8_MIN);
6457 VARADD(R8, R8_MIN, R8, R8_MIN, R8, R8_MIN + R8_MIN);
6459 /* Manually test BSTR + BSTR */
6460 V_VT(&left) = VT_BSTR;
6461 V_BSTR(&left) = lbstr;
6462 V_VT(&right) = VT_BSTR;
6463 V_BSTR(&right) = rbstr;
6464 hres = pVarAdd(&left, &right, &result);
6465 ok(hres == S_OK && V_VT(&result) == VT_BSTR, "VarAdd: expected coerced type VT_BSTR, got %s!\n", vtstr(V_VT(&result)));
6466 hres = VarR8FromStr(V_BSTR(&result), 0, 0, &r);
6467 ok(hres == S_OK && EQ_DOUBLE(r, 1212.0), "VarAdd: BSTR value %f, expected %f\n", r, 1212.0);
6468 VariantClear(&result);
6470 /* Manuly test some VT_CY and VT_DECIMAL variants */
6471 V_VT(&cy) = VT_CY;
6472 hres = VarCyFromI4(4711, &V_CY(&cy));
6473 ok(hres == S_OK, "VarCyFromI4 failed!\n");
6474 V_VT(&dec) = VT_DECIMAL;
6475 hres = VarDecFromR8(-4.2, &V_DECIMAL(&dec));
6476 ok(hres == S_OK, "VarDecFromR4 failed!\n");
6477 memset(&left, 0, sizeof(left));
6478 memset(&right, 0, sizeof(right));
6479 V_VT(&left) = VT_I4;
6480 V_I4(&left) = -11;
6481 V_VT(&right) = VT_UI1;
6482 V_UI1(&right) = 9;
6484 hres = pVarAdd(&cy, &right, &result);
6485 ok(hres == S_OK && V_VT(&result) == VT_CY, "VarAdd: expected coerced type VT_CY, got %s!\n", vtstr(V_VT(&result)));
6486 hres = VarR8FromCy(V_CY(&result), &r);
6487 ok(hres == S_OK && EQ_DOUBLE(r, 4720.0), "VarAdd: CY value %f, expected %f\n", r, 4720.0);
6489 hres = pVarAdd(&left, &dec, &result);
6490 ok(hres == S_OK && V_VT(&result) == VT_DECIMAL, "VarAdd: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
6491 hres = VarR8FromDec(&V_DECIMAL(&result), &r);
6492 ok(hres == S_OK && EQ_DOUBLE(r, -15.2), "VarAdd: DECIMAL value %f, expected %f\n", r, -15.2);
6493 VariantClear(&result);
6495 SysFreeString(lbstr);
6496 SysFreeString(rbstr);
6499 static HRESULT (WINAPI *pVarCmp)(LPVARIANT,LPVARIANT,LCID,ULONG);
6500 static HRESULT (WINAPI *pVarCat)(LPVARIANT,LPVARIANT,LPVARIANT);
6502 static void test_VarCat(void)
6504 LCID lcid;
6505 VARIANT left, right, result, expected, expected_broken;
6506 static const WCHAR sz34[] = {'3','4','\0'};
6507 static const WCHAR sz1234[] = {'1','2','3','4','\0'};
6508 static const WCHAR date_sz12[] = {'9','/','3','0','/','1','9','8','0','1','2','\0'};
6509 static const WCHAR date_sz12_broken[] = {'9','/','3','0','/','8','0','1','2','\0'};
6510 static const WCHAR sz12_date[] = {'1','2','9','/','3','0','/','1','9','8','0','\0'};
6511 static const WCHAR sz12_date_broken[] = {'1','2','9','/','3','0','/','8','0','\0'};
6512 static const WCHAR sz_empty[] = {'\0'};
6513 CHAR orig_date_format[128];
6514 VARTYPE leftvt, rightvt, resultvt;
6515 HRESULT hres;
6516 HRESULT expected_error_num;
6517 int cmp;
6518 DummyDispatch dispatch;
6520 CHECKPTR(VarCat);
6522 /* Set date format for testing */
6523 lcid = LOCALE_USER_DEFAULT;
6524 GetLocaleInfoA(lcid,LOCALE_SSHORTDATE,orig_date_format,128);
6525 SetLocaleInfoA(lcid,LOCALE_SSHORTDATE,"M/d/yyyy");
6527 VariantInit(&left);
6528 VariantInit(&right);
6529 VariantInit(&result);
6530 VariantInit(&expected);
6532 /* Check expected types for all combinations */
6533 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
6536 SKIPTESTS(leftvt);
6538 /* Check if we need/have support for I8 and/or UI8 */
6539 if ((leftvt == VT_I8 || leftvt == VT_UI8) && !has_i8)
6540 continue;
6542 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
6545 SKIPTESTS(rightvt);
6546 expected_error_num = S_OK;
6547 resultvt = VT_EMPTY;
6549 if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
6550 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN ||
6551 leftvt == VT_RECORD || rightvt == VT_RECORD ||
6552 leftvt == 15 || rightvt == 15 /* Undefined type */)
6553 continue;
6555 /* Check if we need/have support for I8 and/or UI8 */
6556 if ((rightvt == VT_I8 || rightvt == VT_UI8) && !has_i8)
6557 continue;
6559 if (leftvt == VT_NULL && rightvt == VT_NULL)
6560 resultvt = VT_NULL;
6561 else if (leftvt == VT_VARIANT && (rightvt == VT_ERROR ||
6562 rightvt == VT_DATE || rightvt == VT_DECIMAL))
6563 expected_error_num = DISP_E_TYPEMISMATCH;
6564 else if ((leftvt == VT_I2 || leftvt == VT_I4 ||
6565 leftvt == VT_R4 || leftvt == VT_R8 ||
6566 leftvt == VT_CY || leftvt == VT_BOOL ||
6567 leftvt == VT_BSTR || leftvt == VT_I1 ||
6568 leftvt == VT_UI1 || leftvt == VT_UI2 ||
6569 leftvt == VT_UI4 || leftvt == VT_I8 ||
6570 leftvt == VT_UI8 || leftvt == VT_INT ||
6571 leftvt == VT_UINT || leftvt == VT_EMPTY ||
6572 leftvt == VT_NULL || leftvt == VT_DECIMAL ||
6573 leftvt == VT_DATE)
6575 (rightvt == VT_I2 || rightvt == VT_I4 ||
6576 rightvt == VT_R4 || rightvt == VT_R8 ||
6577 rightvt == VT_CY || rightvt == VT_BOOL ||
6578 rightvt == VT_BSTR || rightvt == VT_I1 ||
6579 rightvt == VT_UI1 || rightvt == VT_UI2 ||
6580 rightvt == VT_UI4 || rightvt == VT_I8 ||
6581 rightvt == VT_UI8 || rightvt == VT_INT ||
6582 rightvt == VT_UINT || rightvt == VT_EMPTY ||
6583 rightvt == VT_NULL || rightvt == VT_DECIMAL ||
6584 rightvt == VT_DATE))
6585 resultvt = VT_BSTR;
6586 else if (rightvt == VT_ERROR && leftvt < VT_VOID)
6587 expected_error_num = DISP_E_TYPEMISMATCH;
6588 else if (leftvt == VT_ERROR && (rightvt == VT_DATE ||
6589 rightvt == VT_ERROR || rightvt == VT_DECIMAL))
6590 expected_error_num = DISP_E_TYPEMISMATCH;
6591 else if (rightvt == VT_DATE || rightvt == VT_ERROR ||
6592 rightvt == VT_DECIMAL)
6593 expected_error_num = DISP_E_BADVARTYPE;
6594 else if (leftvt == VT_ERROR || rightvt == VT_ERROR)
6595 expected_error_num = DISP_E_TYPEMISMATCH;
6596 else if (leftvt == VT_VARIANT)
6597 expected_error_num = DISP_E_TYPEMISMATCH;
6598 else if (rightvt == VT_VARIANT && (leftvt == VT_EMPTY ||
6599 leftvt == VT_NULL || leftvt == VT_I2 ||
6600 leftvt == VT_I4 || leftvt == VT_R4 ||
6601 leftvt == VT_R8 || leftvt == VT_CY ||
6602 leftvt == VT_DATE || leftvt == VT_BSTR ||
6603 leftvt == VT_BOOL || leftvt == VT_DECIMAL ||
6604 leftvt == VT_I1 || leftvt == VT_UI1 ||
6605 leftvt == VT_UI2 || leftvt == VT_UI4 ||
6606 leftvt == VT_I8 || leftvt == VT_UI8 ||
6607 leftvt == VT_INT || leftvt == VT_UINT
6609 expected_error_num = DISP_E_TYPEMISMATCH;
6610 else
6611 expected_error_num = DISP_E_BADVARTYPE;
6613 V_VT(&left) = leftvt;
6614 V_VT(&right) = rightvt;
6616 switch (leftvt) {
6617 case VT_BSTR:
6618 V_BSTR(&left) = SysAllocString(sz_empty); break;
6619 case VT_DATE:
6620 V_DATE(&left) = 0.0; break;
6621 case VT_DECIMAL:
6622 VarDecFromR8(0.0, &V_DECIMAL(&left)); break;
6623 default:
6624 V_I8(&left) = 0;
6627 switch (rightvt) {
6628 case VT_BSTR:
6629 V_BSTR(&right) = SysAllocString(sz_empty); break;
6630 case VT_DATE:
6631 V_DATE(&right) = 0.0; break;
6632 case VT_DECIMAL:
6633 VarDecFromR8(0.0, &V_DECIMAL(&right)); break;
6634 default:
6635 V_I8(&right) = 0;
6638 hres = pVarCat(&left, &right, &result);
6640 /* Determine the error code for the vt combination */
6641 ok(hres == expected_error_num,
6642 "VarCat: %d, %d returned error, 0x%X expected 0x%X.\n",
6643 leftvt, rightvt, hres, expected_error_num);
6645 /* Check types are correct */
6646 ok(V_VT(&result) == resultvt,
6647 "VarCat: %d, %d: expected vt %d, got vt %d\n",
6648 leftvt, rightvt, resultvt, V_VT(&result));
6650 VariantClear(&left);
6651 VariantClear(&right);
6652 VariantClear(&result);
6656 /* Running single comparison tests to compare outputs */
6658 /* Test concat strings */
6659 V_VT(&left) = VT_BSTR;
6660 V_VT(&right) = VT_BSTR;
6661 V_VT(&expected) = VT_BSTR;
6662 V_BSTR(&left) = SysAllocString(sz12);
6663 V_BSTR(&right) = SysAllocString(sz34);
6664 V_BSTR(&expected) = SysAllocString(sz1234);
6665 hres = pVarCat(&left,&right,&result);
6666 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6667 if (pVarCmp)
6668 ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
6669 "VarCat: VT_BSTR concat with VT_BSTR failed to return correct result\n");
6671 VariantClear(&left);
6672 VariantClear(&right);
6673 VariantClear(&result);
6675 /* Test if expression is VT_ERROR */
6676 V_VT(&left) = VT_ERROR;
6677 V_VT(&right) = VT_BSTR;
6678 V_BSTR(&right) = SysAllocString(sz1234);
6679 hres = pVarCat(&left,&right,&result);
6680 ok(hres == DISP_E_TYPEMISMATCH, "VarCat should have returned DISP_E_TYPEMISMATCH instead of 0x%08x\n", hres);
6681 ok(V_VT(&result) == VT_EMPTY,
6682 "VarCat: VT_ERROR concat with VT_BSTR should have returned VT_EMPTY\n");
6684 VariantClear(&left);
6685 VariantClear(&right);
6686 VariantClear(&result);
6688 V_VT(&left) = VT_BSTR;
6689 V_VT(&right) = VT_ERROR;
6690 V_BSTR(&left) = SysAllocString(sz1234);
6691 hres = pVarCat(&left,&right,&result);
6692 ok(hres == DISP_E_TYPEMISMATCH, "VarCat should have returned DISP_E_TYPEMISMATCH instead of 0x%08x\n", hres);
6693 ok(V_VT(&result) == VT_EMPTY,
6694 "VarCat: VT_BSTR concat with VT_ERROR should have returned VT_EMPTY\n");
6696 VariantClear(&left);
6697 VariantClear(&right);
6698 VariantClear(&result);
6699 VariantClear(&expected);
6701 /* Test combining boolean with number */
6702 V_VT(&left) = VT_INT;
6703 V_VT(&right) = VT_BOOL;
6704 V_VT(&expected) = VT_BSTR;
6705 V_INT(&left) = 12;
6706 V_BOOL(&right) = TRUE;
6707 V_BSTR(&expected) = SysAllocString(sz12_true);
6708 hres = pVarCat(&left,&right,&result);
6709 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6710 if (pVarCmp)
6712 hres = pVarCmp(&result,&expected,lcid,0);
6713 ok(hres == VARCMP_EQ, "Expected VARCMP_EQ, got %08x for %s, %s\n",
6714 hres, variantstr(&result), variantstr(&expected));
6717 VariantClear(&left);
6718 VariantClear(&right);
6719 VariantClear(&result);
6720 VariantClear(&expected);
6722 V_VT(&left) = VT_INT;
6723 V_VT(&right) = VT_BOOL;
6724 V_VT(&expected) = VT_BSTR;
6725 V_INT(&left) = 12;
6726 V_BOOL(&right) = FALSE;
6727 V_BSTR(&expected) = SysAllocString(sz12_false);
6728 hres = pVarCat(&left,&right,&result);
6729 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6730 if (pVarCmp)
6732 hres = pVarCmp(&result,&expected,lcid,0);
6733 ok(hres == VARCMP_EQ, "Expected VARCMP_EQ, got %08x for %s, %s\n",
6734 hres, variantstr(&result), variantstr(&expected));
6737 VariantClear(&left);
6738 VariantClear(&right);
6739 VariantClear(&result);
6740 VariantClear(&expected);
6742 /* Test when both expressions are numeric */
6743 V_VT(&left) = VT_INT;
6744 V_VT(&right) = VT_INT;
6745 V_VT(&expected) = VT_BSTR;
6746 V_INT(&left) = 12;
6747 V_INT(&right) = 34;
6748 V_BSTR(&expected) = SysAllocString(sz1234);
6749 hres = pVarCat(&left,&right,&result);
6750 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6751 if (pVarCmp)
6752 ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
6753 "VarCat: NUMBER concat with NUMBER returned incorrect result\n");
6755 VariantClear(&left);
6756 VariantClear(&right);
6757 VariantClear(&result);
6759 /* Test if one expression is numeric and the other is a string */
6760 V_VT(&left) = VT_INT;
6761 V_VT(&right) = VT_BSTR;
6762 V_INT(&left) = 12;
6763 V_BSTR(&right) = SysAllocString(sz34);
6764 hres = pVarCat(&left,&right,&result);
6765 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6766 if (pVarCmp)
6767 ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
6768 "VarCat: NUMBER concat with VT_BSTR, incorrect result\n");
6770 VariantClear(&left);
6771 VariantClear(&right);
6772 VariantClear(&result);
6774 V_VT(&left) = VT_BSTR;
6775 V_VT(&right) = VT_INT;
6776 V_BSTR(&left) = SysAllocString(sz12);
6777 V_INT(&right) = 34;
6778 hres = pVarCat(&left,&right,&result);
6779 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6780 if (pVarCmp)
6781 ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
6782 "VarCat: VT_BSTR concat with NUMBER, incorrect result\n");
6784 VariantClear(&left);
6785 VariantClear(&right);
6786 VariantClear(&result);
6787 VariantClear(&expected);
6789 /* Test concat dates with strings */
6790 V_VT(&left) = VT_BSTR;
6791 V_VT(&right) = VT_DATE;
6792 V_VT(&expected) = VT_BSTR;
6793 V_VT(&expected_broken) = VT_BSTR;
6794 V_BSTR(&left) = SysAllocString(sz12);
6795 V_DATE(&right) = 29494.0;
6796 V_BSTR(&expected)= SysAllocString(sz12_date);
6797 V_BSTR(&expected_broken)= SysAllocString(sz12_date_broken);
6798 hres = pVarCat(&left,&right,&result);
6799 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6800 if (pVarCmp)
6801 ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ ||
6802 broken(pVarCmp(&result,&expected_broken,lcid,0) == VARCMP_EQ), /* Some W98 and NT4 (intermittent) */
6803 "VarCat: VT_BSTR concat with VT_DATE returned incorrect result\n");
6805 VariantClear(&left);
6806 VariantClear(&right);
6807 VariantClear(&result);
6808 VariantClear(&expected);
6809 VariantClear(&expected_broken);
6811 V_VT(&left) = VT_DATE;
6812 V_VT(&right) = VT_BSTR;
6813 V_VT(&expected) = VT_BSTR;
6814 V_VT(&expected_broken) = VT_BSTR;
6815 V_DATE(&left) = 29494.0;
6816 V_BSTR(&right) = SysAllocString(sz12);
6817 V_BSTR(&expected)= SysAllocString(date_sz12);
6818 V_BSTR(&expected_broken)= SysAllocString(date_sz12_broken);
6819 hres = pVarCat(&left,&right,&result);
6820 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6821 if (pVarCmp)
6822 ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ ||
6823 broken(pVarCmp(&result,&expected_broken,lcid,0) == VARCMP_EQ), /* Some W98 and NT4 (intermittent) */
6824 "VarCat: VT_DATE concat with VT_BSTR returned incorrect result\n");
6826 VariantClear(&left);
6827 VariantClear(&right);
6828 VariantClear(&result);
6829 VariantClear(&expected);
6830 VariantClear(&expected_broken);
6832 /* Test of both expressions are empty */
6833 V_VT(&left) = VT_BSTR;
6834 V_VT(&right) = VT_BSTR;
6835 V_VT(&expected) = VT_BSTR;
6836 V_BSTR(&left) = SysAllocString(sz_empty);
6837 V_BSTR(&right) = SysAllocString(sz_empty);
6838 V_BSTR(&expected)= SysAllocString(sz_empty);
6839 hres = pVarCat(&left,&right,&result);
6840 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6841 if (pVarCmp)
6842 ok(pVarCmp(&result,&left,lcid,0) == VARCMP_EQ,
6843 "VarCat: EMPTY concat with EMPTY did not return empty VT_BSTR\n");
6845 /* Restore original date format settings */
6846 SetLocaleInfoA(lcid,LOCALE_SSHORTDATE,orig_date_format);
6848 VariantClear(&left);
6849 VariantClear(&right);
6850 VariantClear(&result);
6851 VariantClear(&expected);
6853 /* Dispatch conversion */
6854 init_test_dispatch(VT_NULL, &dispatch);
6855 V_VT(&left) = VT_DISPATCH;
6856 V_DISPATCH(&left) = &dispatch.IDispatch_iface;
6858 SET_EXPECT(dispatch_invoke);
6859 hres = VarCat(&left, &right, &result);
6860 ok(hres == S_OK, "got 0x%08x\n", hres);
6861 ok(V_VT(&result) == VT_BSTR, "got %d\n", V_VT(&result));
6862 ok(SysStringLen(V_BSTR(&result)) == 0, "got %d\n", SysStringLen(V_BSTR(&result)));
6863 CHECK_CALLED(dispatch_invoke);
6865 VariantClear(&left);
6866 VariantClear(&right);
6867 VariantClear(&result);
6869 init_test_dispatch(VT_NULL, &dispatch);
6870 V_VT(&right) = VT_DISPATCH;
6871 V_DISPATCH(&right) = &dispatch.IDispatch_iface;
6873 SET_EXPECT(dispatch_invoke);
6874 hres = VarCat(&left, &right, &result);
6875 ok(hres == S_OK, "got 0x%08x\n", hres);
6876 ok(V_VT(&result) == VT_BSTR, "got %d\n", V_VT(&result));
6877 ok(SysStringLen(V_BSTR(&result)) == 0, "got %d\n", SysStringLen(V_BSTR(&result)));
6878 CHECK_CALLED(dispatch_invoke);
6880 VariantClear(&left);
6881 VariantClear(&right);
6882 VariantClear(&result);
6884 init_test_dispatch(VT_UI1, &dispatch);
6885 V_VT(&right) = VT_DISPATCH;
6886 V_DISPATCH(&right) = &dispatch.IDispatch_iface;
6888 V_VT(&left) = VT_BSTR;
6889 V_BSTR(&left) = SysAllocString(sz12);
6890 SET_EXPECT(dispatch_invoke);
6891 hres = pVarCat(&left,&right,&result);
6892 ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
6893 CHECK_CALLED(dispatch_invoke);
6894 ok(!lstrcmpW(V_BSTR(&result), L"1234"), "got %s\n", wine_dbgstr_w(V_BSTR(&result)));
6896 VariantClear(&left);
6897 VariantClear(&right);
6898 VariantClear(&result);
6900 init_test_dispatch(VT_NULL, &dispatch);
6901 dispatch.result = E_OUTOFMEMORY;
6902 V_VT(&right) = VT_DISPATCH;
6903 V_DISPATCH(&right) = &dispatch.IDispatch_iface;
6905 SET_EXPECT(dispatch_invoke);
6906 hres = VarCat(&left, &right, &result);
6907 ok(hres == E_OUTOFMEMORY, "got 0x%08x\n", hres);
6908 CHECK_CALLED(dispatch_invoke);
6910 VariantClear(&left);
6911 VariantClear(&right);
6912 VariantClear(&result);
6914 init_test_dispatch(VT_NULL, &dispatch);
6915 dispatch.result = DISP_E_TYPEMISMATCH;
6916 V_VT(&right) = VT_DISPATCH;
6917 V_DISPATCH(&right) = &dispatch.IDispatch_iface;
6919 SET_EXPECT(dispatch_invoke);
6920 hres = VarCat(&left, &right, &result);
6921 ok(hres == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hres);
6922 CHECK_CALLED(dispatch_invoke);
6924 VariantClear(&left);
6925 VariantClear(&right);
6926 VariantClear(&result);
6928 /* Test boolean conversion */
6929 V_VT(&left) = VT_BOOL;
6930 V_BOOL(&left) = VARIANT_TRUE;
6931 V_VT(&right) = VT_BSTR;
6932 V_BSTR(&right) = SysAllocStringLen(NULL,0);
6933 hres = pVarCat(&left, &right, &result);
6934 ok(hres == S_OK, "VarCat failed: %08x\n", hres);
6935 VariantClear(&right);
6937 cmp = lstrcmpW(V_BSTR(&result), L"True");
6938 VariantClear(&result);
6939 if(!cmp) {
6940 V_VT(&right) = VT_BOOL;
6941 V_BOOL(&right) = 100;
6942 hres = pVarCat(&left, &right, &result);
6943 ok(hres == S_OK, "VarCat failed: %08x\n", hres);
6944 test_bstr_var(&result, L"TrueTrue");
6945 VariantClear(&result);
6947 V_BOOL(&right) = VARIANT_FALSE;
6948 hres = pVarCat(&left, &right, &result);
6949 ok(hres == S_OK, "VarCat failed: %08x\n", hres);
6950 test_bstr_var(&result, L"TrueFalse");
6951 VariantClear(&result);
6952 }else {
6953 skip("Got %s as True, assuming non-English locale\n", wine_dbgstr_w(V_BSTR(&result)));
6957 static HRESULT (WINAPI *pVarAnd)(LPVARIANT,LPVARIANT,LPVARIANT);
6959 #define VARAND(vt1,val1,vt2,val2,rvt,rval) \
6960 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
6961 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
6962 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
6963 test_var_call2( __LINE__, pVarAnd, &left, &right, &exp )
6965 #define VARANDCY(vt1,val1,val2,rvt,rval) \
6966 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
6967 V_VT(&right) = VT_CY; V_CY(&right).int64 = val2; \
6968 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
6969 test_var_call2( __LINE__, pVarAnd, &left, &right, &exp )
6971 /* Skip any type that is not defined or produces an error for every case */
6972 #define SKIPTESTAND(a) \
6973 if (a == VT_ERROR || a == VT_VARIANT || \
6974 a == VT_DISPATCH || a == VT_UNKNOWN || \
6975 a > VT_UINT || a == 15 /*not defined*/) \
6976 continue
6978 static void test_VarAnd(void)
6980 static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
6981 static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
6982 VARIANT left, right, exp, result;
6983 BSTR false_str, true_str;
6984 VARTYPE i;
6985 HRESULT hres;
6987 CHECKPTR(VarAnd);
6989 true_str = SysAllocString(szTrue);
6990 false_str = SysAllocString(szFalse);
6992 /* Test all possible flag/vt combinations & the resulting vt type */
6993 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
6995 VARTYPE leftvt, rightvt, resvt;
6997 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
6999 SKIPTESTAND(leftvt);
7001 /* Check if we need/have support for I8 and/or UI8 */
7002 if ((leftvt == VT_I8 || leftvt == VT_UI8) && !has_i8)
7003 continue;
7005 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
7007 BOOL bFail = FALSE;
7008 SKIPTESTAND(rightvt);
7010 /* Check if we need/have support for I8 and/or UI8 */
7011 if ((rightvt == VT_I8 || rightvt == VT_UI8) && !has_i8)
7012 continue;
7014 memset(&left, 0, sizeof(left));
7015 memset(&right, 0, sizeof(right));
7016 V_VT(&left) = leftvt | ExtraFlags[i];
7017 V_VT(&right) = rightvt | ExtraFlags[i];
7018 V_VT(&result) = VT_EMPTY;
7019 resvt = VT_EMPTY;
7020 if ((leftvt | ExtraFlags[i]) == VT_BSTR)
7021 V_BSTR(&left) = true_str;
7022 if ((rightvt | ExtraFlags[i]) == VT_BSTR)
7023 V_BSTR(&right) = true_str;
7025 /* Native VarAnd always returns an error when using extra
7026 * flags or if the variant combination is I8 and INT.
7028 if ((leftvt == VT_I8 && rightvt == VT_INT) ||
7029 (leftvt == VT_INT && rightvt == VT_I8) ||
7030 ExtraFlags[i] != 0)
7031 bFail = TRUE;
7033 /* Determine return type */
7034 else if (leftvt == VT_I8 || rightvt == VT_I8)
7035 resvt = VT_I8;
7036 else if (leftvt == VT_I4 || rightvt == VT_I4 ||
7037 leftvt == VT_UINT || rightvt == VT_UINT ||
7038 leftvt == VT_INT || rightvt == VT_INT ||
7039 leftvt == VT_R4 || rightvt == VT_R4 ||
7040 leftvt == VT_R8 || rightvt == VT_R8 ||
7041 leftvt == VT_CY || rightvt == VT_CY ||
7042 leftvt == VT_DATE || rightvt == VT_DATE ||
7043 leftvt == VT_I1 || rightvt == VT_I1 ||
7044 leftvt == VT_UI2 || rightvt == VT_UI2 ||
7045 leftvt == VT_UI4 || rightvt == VT_UI4 ||
7046 leftvt == VT_UI8 || rightvt == VT_UI8 ||
7047 leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
7048 resvt = VT_I4;
7049 else if (leftvt == VT_UI1 || rightvt == VT_UI1 ||
7050 leftvt == VT_I2 || rightvt == VT_I2 ||
7051 leftvt == VT_EMPTY || rightvt == VT_EMPTY)
7052 if ((leftvt == VT_NULL && rightvt == VT_UI1) ||
7053 (leftvt == VT_UI1 && rightvt == VT_NULL) ||
7054 (leftvt == VT_UI1 && rightvt == VT_UI1))
7055 resvt = VT_UI1;
7056 else
7057 resvt = VT_I2;
7058 else if (leftvt == VT_BOOL || rightvt == VT_BOOL ||
7059 (leftvt == VT_BSTR && rightvt == VT_BSTR))
7060 resvt = VT_BOOL;
7061 else if (leftvt == VT_NULL || rightvt == VT_NULL ||
7062 leftvt == VT_BSTR || rightvt == VT_BSTR)
7063 resvt = VT_NULL;
7064 else
7065 bFail = TRUE;
7067 hres = pVarAnd(&left, &right, &result);
7069 /* Check expected HRESULT and if result variant type is correct */
7070 if (bFail)
7071 ok (hres == DISP_E_BADVARTYPE || hres == DISP_E_TYPEMISMATCH,
7072 "VarAnd: %s|0x%X, %s|0x%X: got vt %s hr 0x%X\n",
7073 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i],
7074 vtstr(V_VT(&result)), hres);
7075 else
7076 ok (hres == S_OK && resvt == V_VT(&result),
7077 "VarAnd: %s|0x%X, %s|0x%X: expected vt %s hr 0x%X, got vt %s hr 0x%X\n",
7078 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i], vtstr(resvt),
7079 S_OK, vtstr(V_VT(&result)), hres);
7085 * Test returned values. Since we know the returned type is correct
7086 * and that we handle all combinations of invalid types, just check
7087 * that good type combinations produce the desired value.
7088 * FIXME: Test VT_DECIMAL
7090 VARAND(EMPTY,0,EMPTY,0,I2,0);
7091 VARAND(EMPTY,1,EMPTY,0,I2,0);
7092 VARAND(EMPTY,1,EMPTY,1,I2,0);
7093 VARAND(EMPTY,0,NULL,0,I2,0);
7094 VARAND(EMPTY,1,NULL,0,I2,0);
7095 VARAND(EMPTY,1,NULL,1,I2,0);
7096 VARAND(EMPTY,0,I1,0,I4,0);
7097 VARAND(EMPTY,0,I1,1,I4,0);
7098 VARAND(EMPTY,1,I1,1,I4,0);
7099 VARAND(EMPTY,0,UI1,0,I2,0);
7100 VARAND(EMPTY,0,UI1,1,I2,0);
7101 VARAND(EMPTY,1,UI1,1,I2,0);
7102 VARAND(EMPTY,0,I2,0,I2,0);
7103 VARAND(EMPTY,0,I2,1,I2,0);
7104 VARAND(EMPTY,1,I2,1,I2,0);
7105 VARAND(EMPTY,0,UI2,0,I4,0);
7106 VARAND(EMPTY,0,UI2,1,I4,0);
7107 VARAND(EMPTY,1,UI2,1,I4,0);
7108 VARAND(EMPTY,0,I4,0,I4,0);
7109 VARAND(EMPTY,0,I4,1,I4,0);
7110 VARAND(EMPTY,1,I4,1,I4,0);
7111 VARAND(EMPTY,0,UI4,0,I4,0);
7112 VARAND(EMPTY,0,UI4,1,I4,0);
7113 VARAND(EMPTY,1,UI4,1,I4,0);
7114 if (has_i8)
7116 VARAND(EMPTY,0,I8,0,I8,0);
7117 VARAND(EMPTY,0,I8,1,I8,0);
7118 VARAND(EMPTY,1,I8,1,I8,0);
7119 VARAND(EMPTY,0,UI8,0,I4,0);
7120 VARAND(EMPTY,0,UI8,1,I4,0);
7121 VARAND(EMPTY,1,UI8,1,I4,0);
7123 VARAND(EMPTY,0,INT,0,I4,0);
7124 VARAND(EMPTY,0,INT,1,I4,0);
7125 VARAND(EMPTY,1,INT,1,I4,0);
7126 VARAND(EMPTY,0,UINT,0,I4,0);
7127 VARAND(EMPTY,0,UINT,1,I4,0);
7128 VARAND(EMPTY,1,UINT,1,I4,0);
7129 VARAND(EMPTY,0,BOOL,0,I2,0);
7130 VARAND(EMPTY,0,BOOL,1,I2,0);
7131 VARAND(EMPTY,1,BOOL,1,I2,0);
7132 VARAND(EMPTY,0,R4,0,I4,0);
7133 VARAND(EMPTY,0,R4,1,I4,0);
7134 VARAND(EMPTY,1,R4,1,I4,0);
7135 VARAND(EMPTY,0,R8,0,I4,0);
7136 VARAND(EMPTY,0,R8,1,I4,0);
7137 VARAND(EMPTY,1,R8,1,I4,0);
7138 VARAND(EMPTY,0,BSTR,false_str,I2,0);
7139 VARAND(EMPTY,0,BSTR,true_str,I2,0);
7140 VARANDCY(EMPTY,0,10000,I4,0);
7142 /* NULL OR 0 = NULL. NULL OR n = n */
7143 VARAND(NULL,0,NULL,0,NULL,0);
7144 VARAND(NULL,1,NULL,0,NULL,0);
7145 VARAND(NULL,0,I1,0,I4,0);
7146 VARAND(NULL,0,I1,1,NULL,0);
7147 VARAND(NULL,0,UI1,0,UI1,0);
7148 VARAND(NULL,0,UI1,1,NULL,0);
7149 VARAND(NULL,0,I2,0,I2,0);
7150 VARAND(NULL,0,I2,1,NULL,0);
7151 VARAND(NULL,0,UI2,0,I4,0);
7152 VARAND(NULL,0,UI2,1,NULL,0);
7153 VARAND(NULL,0,I4,0,I4,0);
7154 VARAND(NULL,0,I4,1,NULL,0);
7155 VARAND(NULL,0,UI4,0,I4,0);
7156 VARAND(NULL,0,UI4,1,NULL,0);
7157 if (has_i8)
7159 VARAND(NULL,0,I8,0,I8,0);
7160 VARAND(NULL,0,I8,1,NULL,0);
7161 VARAND(NULL,0,UI8,0,I4,0);
7162 VARAND(NULL,0,UI8,1,NULL,0);
7164 VARAND(NULL,0,INT,0,I4,0);
7165 VARAND(NULL,0,INT,1,NULL,0);
7166 VARAND(NULL,0,UINT,0,I4,0);
7167 VARAND(NULL,0,UINT,1,NULL,0);
7168 VARAND(NULL,0,BOOL,0,BOOL,0);
7169 VARAND(NULL,0,BOOL,1,NULL,0);
7170 VARAND(NULL,0,R4,0,I4,0);
7171 VARAND(NULL,0,R4,1,NULL,0);
7172 VARAND(NULL,0,R8,0,I4,0);
7173 VARAND(NULL,0,R8,1,NULL,0);
7174 VARAND(NULL,0,BSTR,false_str,BOOL,0);
7175 VARAND(NULL,0,BSTR,true_str,NULL,VARIANT_FALSE);
7176 VARANDCY(NULL,0,10000,NULL,0);
7177 VARANDCY(NULL,0,0,I4,0);
7178 VARAND(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE);
7179 VARAND(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE);
7180 VARAND(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE);
7181 VARAND(BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE,BOOL,VARIANT_FALSE);
7183 /* Assume x,y & y,x are the same from now on to reduce the number of tests */
7184 VARAND(BOOL,VARIANT_TRUE,I1,-1,I4,-1);
7185 VARAND(BOOL,VARIANT_TRUE,I1,0,I4,0);
7186 VARAND(BOOL,VARIANT_FALSE,I1,0,I4,0);
7187 VARAND(BOOL,VARIANT_TRUE,UI1,255,I2,255);
7188 VARAND(BOOL,VARIANT_TRUE,UI1,0,I2,0);
7189 VARAND(BOOL,VARIANT_FALSE,UI1,0,I2,0);
7190 VARAND(BOOL,VARIANT_TRUE,I2,-1,I2,-1);
7191 VARAND(BOOL,VARIANT_TRUE,I2,0,I2,0);
7192 VARAND(BOOL,VARIANT_FALSE,I2,0,I2,0);
7193 VARAND(BOOL,VARIANT_TRUE,UI2,65535,I4,65535);
7194 VARAND(BOOL,VARIANT_TRUE,UI2,0,I4,0);
7195 VARAND(BOOL,VARIANT_FALSE,UI2,0,I4,0);
7196 VARAND(BOOL,VARIANT_TRUE,I4,-1,I4,-1);
7197 VARAND(BOOL,VARIANT_TRUE,I4,0,I4,0);
7198 VARAND(BOOL,VARIANT_FALSE,I4,0,I4,0);
7199 VARAND(BOOL,VARIANT_TRUE,UI4,0xffffffff,I4,-1);
7200 VARAND(BOOL,VARIANT_TRUE,UI4,0,I4,0);
7201 VARAND(BOOL,VARIANT_FALSE,UI4,0,I4,0);
7202 VARAND(BOOL,VARIANT_TRUE,R4,-1,I4,-1);
7203 VARAND(BOOL,VARIANT_TRUE,R4,0,I4,0);
7204 VARAND(BOOL,VARIANT_FALSE,R4,0,I4,0);
7205 VARAND(BOOL,VARIANT_TRUE,R8,-1,I4,-1);
7206 VARAND(BOOL,VARIANT_TRUE,R8,0,I4,0);
7207 VARAND(BOOL,VARIANT_FALSE,R8,0,I4,0);
7208 VARAND(BOOL,VARIANT_TRUE,DATE,-1,I4,-1);
7209 VARAND(BOOL,VARIANT_TRUE,DATE,0,I4,0);
7210 VARAND(BOOL,VARIANT_FALSE,DATE,0,I4,0);
7211 if (has_i8)
7213 VARAND(BOOL,VARIANT_TRUE,I8,-1,I8,-1);
7214 VARAND(BOOL,VARIANT_TRUE,I8,0,I8,0);
7215 VARAND(BOOL,VARIANT_FALSE,I8,0,I8,0);
7216 VARAND(BOOL,VARIANT_TRUE,UI8,0,I4,0);
7217 VARAND(BOOL,VARIANT_FALSE,UI8,0,I4,0);
7219 VARAND(BOOL,VARIANT_TRUE,INT,-1,I4,-1);
7220 VARAND(BOOL,VARIANT_TRUE,INT,0,I4,0);
7221 VARAND(BOOL,VARIANT_FALSE,INT,0,I4,0);
7222 VARAND(BOOL,VARIANT_TRUE,UINT,0xffffffff,I4,-1);
7223 VARAND(BOOL,VARIANT_TRUE,UINT,0,I4,0);
7224 VARAND(BOOL,VARIANT_FALSE,UINT,0,I4,0);
7225 VARAND(BOOL,VARIANT_FALSE,BSTR,false_str,BOOL,VARIANT_FALSE);
7226 VARAND(BOOL,VARIANT_TRUE,BSTR,false_str,BOOL,VARIANT_FALSE);
7227 VARAND(BOOL,VARIANT_FALSE,BSTR,true_str,BOOL,VARIANT_FALSE);
7228 VARAND(BOOL,VARIANT_TRUE,BSTR,true_str,BOOL,VARIANT_TRUE);
7229 VARANDCY(BOOL,VARIANT_TRUE,10000,I4,1);
7230 VARANDCY(BOOL,VARIANT_TRUE,0,I4,0);
7231 VARANDCY(BOOL,VARIANT_FALSE,0,I4,0);
7232 VARAND(I1,-1,I1,-1,I4,-1);
7233 VARAND(I1,-1,I1,0,I4,0);
7234 VARAND(I1,0,I1,0,I4,0);
7235 VARAND(I1,-1,UI1,255,I4,255);
7236 VARAND(I1,-1,UI1,0,I4,0);
7237 VARAND(I1,0,UI1,0,I4,0);
7238 VARAND(I1,-1,I2,-1,I4,-1);
7239 VARAND(I1,-1,I2,0,I4,0);
7240 VARAND(I1,0,I2,0,I4,0);
7241 VARAND(I1,-1,UI2,65535,I4,65535);
7242 VARAND(I1,-1,UI2,0,I4,0);
7243 VARAND(I1,0,UI2,0,I4,0);
7244 VARAND(I1,-1,I4,-1,I4,-1);
7245 VARAND(I1,-1,I4,0,I4,0);
7246 VARAND(I1,0,I4,0,I4,0);
7247 VARAND(I1,-1,UI4,0xffffffff,I4,-1);
7248 VARAND(I1,-1,UI4,0,I4,0);
7249 VARAND(I1,0,UI4,0,I4,0);
7250 VARAND(I1,-1,R4,-1,I4,-1);
7251 VARAND(I1,-1,R4,0,I4,0);
7252 VARAND(I1,0,R4,0,I4,0);
7253 VARAND(I1,-1,R8,-1,I4,-1);
7254 VARAND(I1,-1,R8,0,I4,0);
7255 VARAND(I1,0,R8,0,I4,0);
7256 VARAND(I1,-1,DATE,-1,I4,-1);
7257 VARAND(I1,-1,DATE,0,I4,0);
7258 VARAND(I1,0,DATE,0,I4,0);
7259 if (has_i8)
7261 VARAND(I1,-1,I8,-1,I8,-1);
7262 VARAND(I1,-1,I8,0,I8,0);
7263 VARAND(I1,0,I8,0,I8,0);
7264 VARAND(I1,-1,UI8,0,I4,0);
7265 VARAND(I1,0,UI8,0,I4,0);
7267 VARAND(I1,-1,INT,-1,I4,-1);
7268 VARAND(I1,-1,INT,0,I4,0);
7269 VARAND(I1,0,INT,0,I4,0);
7270 VARAND(I1,-1,UINT,0xffffffff,I4,-1);
7271 VARAND(I1,-1,UINT,0,I4,0);
7272 VARAND(I1,0,UINT,0,I4,0);
7273 VARAND(I1,0,BSTR,false_str,I4,0);
7274 VARAND(I1,-1,BSTR,false_str,I4,0);
7275 VARAND(I1,0,BSTR,true_str,I4,0);
7276 VARAND(I1,-1,BSTR,true_str,I4,-1);
7277 VARANDCY(I1,-1,10000,I4,1);
7278 VARANDCY(I1,-1,0,I4,0);
7279 VARANDCY(I1,0,0,I4,0);
7281 VARAND(UI1,255,UI1,255,UI1,255);
7282 VARAND(UI1,255,UI1,0,UI1,0);
7283 VARAND(UI1,0,UI1,0,UI1,0);
7284 VARAND(UI1,255,I2,-1,I2,255);
7285 VARAND(UI1,255,I2,0,I2,0);
7286 VARAND(UI1,0,I2,0,I2,0);
7287 VARAND(UI1,255,UI2,65535,I4,255);
7288 VARAND(UI1,255,UI2,0,I4,0);
7289 VARAND(UI1,0,UI2,0,I4,0);
7290 VARAND(UI1,255,I4,-1,I4,255);
7291 VARAND(UI1,255,I4,0,I4,0);
7292 VARAND(UI1,0,I4,0,I4,0);
7293 VARAND(UI1,255,UI4,0xffffffff,I4,255);
7294 VARAND(UI1,255,UI4,0,I4,0);
7295 VARAND(UI1,0,UI4,0,I4,0);
7296 VARAND(UI1,255,R4,-1,I4,255);
7297 VARAND(UI1,255,R4,0,I4,0);
7298 VARAND(UI1,0,R4,0,I4,0);
7299 VARAND(UI1,255,R8,-1,I4,255);
7300 VARAND(UI1,255,R8,0,I4,0);
7301 VARAND(UI1,0,R8,0,I4,0);
7302 VARAND(UI1,255,DATE,-1,I4,255);
7303 VARAND(UI1,255,DATE,0,I4,0);
7304 VARAND(UI1,0,DATE,0,I4,0);
7305 if (has_i8)
7307 VARAND(UI1,255,I8,-1,I8,255);
7308 VARAND(UI1,255,I8,0,I8,0);
7309 VARAND(UI1,0,I8,0,I8,0);
7310 VARAND(UI1,255,UI8,0,I4,0);
7311 VARAND(UI1,0,UI8,0,I4,0);
7313 VARAND(UI1,255,INT,-1,I4,255);
7314 VARAND(UI1,255,INT,0,I4,0);
7315 VARAND(UI1,0,INT,0,I4,0);
7316 VARAND(UI1,255,UINT,0xffffffff,I4,255);
7317 VARAND(UI1,255,UINT,0,I4,0);
7318 VARAND(UI1,0,UINT,0,I4,0);
7319 VARAND(UI1,0,BSTR,false_str,I2,0);
7320 VARAND(UI1,255,BSTR,false_str,I2,0);
7321 VARAND(UI1,0,BSTR,true_str,I2,0);
7322 VARAND(UI1,255,BSTR,true_str,I2,255);
7323 VARANDCY(UI1,255,10000,I4,1);
7324 VARANDCY(UI1,255,0,I4,0);
7325 VARANDCY(UI1,0,0,I4,0);
7327 VARAND(I2,-1,I2,-1,I2,-1);
7328 VARAND(I2,-1,I2,0,I2,0);
7329 VARAND(I2,0,I2,0,I2,0);
7330 VARAND(I2,-1,UI2,65535,I4,65535);
7331 VARAND(I2,-1,UI2,0,I4,0);
7332 VARAND(I2,0,UI2,0,I4,0);
7333 VARAND(I2,-1,I4,-1,I4,-1);
7334 VARAND(I2,-1,I4,0,I4,0);
7335 VARAND(I2,0,I4,0,I4,0);
7336 VARAND(I2,-1,UI4,0xffffffff,I4,-1);
7337 VARAND(I2,-1,UI4,0,I4,0);
7338 VARAND(I2,0,UI4,0,I4,0);
7339 VARAND(I2,-1,R4,-1,I4,-1);
7340 VARAND(I2,-1,R4,0,I4,0);
7341 VARAND(I2,0,R4,0,I4,0);
7342 VARAND(I2,-1,R8,-1,I4,-1);
7343 VARAND(I2,-1,R8,0,I4,0);
7344 VARAND(I2,0,R8,0,I4,0);
7345 VARAND(I2,-1,DATE,-1,I4,-1);
7346 VARAND(I2,-1,DATE,0,I4,0);
7347 VARAND(I2,0,DATE,0,I4,0);
7348 if (has_i8)
7350 VARAND(I2,-1,I8,-1,I8,-1);
7351 VARAND(I2,-1,I8,0,I8,0);
7352 VARAND(I2,0,I8,0,I8,0);
7353 VARAND(I2,-1,UI8,0,I4,0);
7354 VARAND(I2,0,UI8,0,I4,0);
7356 VARAND(I2,-1,INT,-1,I4,-1);
7357 VARAND(I2,-1,INT,0,I4,0);
7358 VARAND(I2,0,INT,0,I4,0);
7359 VARAND(I2,-1,UINT,0xffffffff,I4,-1);
7360 VARAND(I2,-1,UINT,0,I4,0);
7361 VARAND(I2,0,UINT,0,I4,0);
7362 VARAND(I2,0,BSTR,false_str,I2,0);
7363 VARAND(I2,-1,BSTR,false_str,I2,0);
7364 VARAND(I2,0,BSTR,true_str,I2,0);
7365 VARAND(I2,-1,BSTR,true_str,I2,-1);
7366 VARANDCY(I2,-1,10000,I4,1);
7367 VARANDCY(I2,-1,0,I4,0);
7368 VARANDCY(I2,0,0,I4,0);
7370 VARAND(UI2,65535,UI2,65535,I4,65535);
7371 VARAND(UI2,65535,UI2,0,I4,0);
7372 VARAND(UI2,0,UI2,0,I4,0);
7373 VARAND(UI2,65535,I4,-1,I4,65535);
7374 VARAND(UI2,65535,I4,0,I4,0);
7375 VARAND(UI2,0,I4,0,I4,0);
7376 VARAND(UI2,65535,UI4,0xffffffff,I4,65535);
7377 VARAND(UI2,65535,UI4,0,I4,0);
7378 VARAND(UI2,0,UI4,0,I4,0);
7379 VARAND(UI2,65535,R4,-1,I4,65535);
7380 VARAND(UI2,65535,R4,0,I4,0);
7381 VARAND(UI2,0,R4,0,I4,0);
7382 VARAND(UI2,65535,R8,-1,I4,65535);
7383 VARAND(UI2,65535,R8,0,I4,0);
7384 VARAND(UI2,0,R8,0,I4,0);
7385 VARAND(UI2,65535,DATE,-1,I4,65535);
7386 VARAND(UI2,65535,DATE,0,I4,0);
7387 VARAND(UI2,0,DATE,0,I4,0);
7388 if (has_i8)
7390 VARAND(UI2,65535,I8,-1,I8,65535);
7391 VARAND(UI2,65535,I8,0,I8,0);
7392 VARAND(UI2,0,I8,0,I8,0);
7393 VARAND(UI2,65535,UI8,0,I4,0);
7394 VARAND(UI2,0,UI8,0,I4,0);
7396 VARAND(UI2,65535,INT,-1,I4,65535);
7397 VARAND(UI2,65535,INT,0,I4,0);
7398 VARAND(UI2,0,INT,0,I4,0);
7399 VARAND(UI2,65535,UINT,0xffffffff,I4,65535);
7400 VARAND(UI2,65535,UINT,0,I4,0);
7401 VARAND(UI2,0,UINT,0,I4,0);
7402 VARAND(UI2,0,BSTR,false_str,I4,0);
7403 VARAND(UI2,65535,BSTR,false_str,I4,0);
7404 VARAND(UI2,0,BSTR,true_str,I4,0);
7405 VARAND(UI2,65535,BSTR,true_str,I4,65535);
7406 VARANDCY(UI2,65535,10000,I4,1);
7407 VARANDCY(UI2,65535,0,I4,0);
7408 VARANDCY(UI2,0,0,I4,0);
7410 VARAND(I4,-1,I4,-1,I4,-1);
7411 VARAND(I4,-1,I4,0,I4,0);
7412 VARAND(I4,0,I4,0,I4,0);
7413 VARAND(I4,-1,UI4,0xffffffff,I4,-1);
7414 VARAND(I4,-1,UI4,0,I4,0);
7415 VARAND(I4,0,UI4,0,I4,0);
7416 VARAND(I4,-1,R4,-1,I4,-1);
7417 VARAND(I4,-1,R4,0,I4,0);
7418 VARAND(I4,0,R4,0,I4,0);
7419 VARAND(I4,-1,R8,-1,I4,-1);
7420 VARAND(I4,-1,R8,0,I4,0);
7421 VARAND(I4,0,R8,0,I4,0);
7422 VARAND(I4,-1,DATE,-1,I4,-1);
7423 VARAND(I4,-1,DATE,0,I4,0);
7424 VARAND(I4,0,DATE,0,I4,0);
7425 if (has_i8)
7427 VARAND(I4,-1,I8,-1,I8,-1);
7428 VARAND(I4,-1,I8,0,I8,0);
7429 VARAND(I4,0,I8,0,I8,0);
7430 VARAND(I4,-1,UI8,0,I4,0);
7431 VARAND(I4,0,UI8,0,I4,0);
7433 VARAND(I4,-1,INT,-1,I4,-1);
7434 VARAND(I4,-1,INT,0,I4,0);
7435 VARAND(I4,0,INT,0,I4,0);
7436 VARAND(I4,-1,UINT,0xffffffff,I4,-1);
7437 VARAND(I4,-1,UINT,0,I4,0);
7438 VARAND(I4,0,UINT,0,I4,0);
7439 VARAND(I4,0,BSTR,false_str,I4,0);
7440 VARAND(I4,-1,BSTR,false_str,I4,0);
7441 VARAND(I4,0,BSTR,true_str,I4,0);
7442 VARAND(I4,-1,BSTR,true_str,I4,-1);
7443 VARANDCY(I4,-1,10000,I4,1);
7444 VARANDCY(I4,-1,0,I4,0);
7445 VARANDCY(I4,0,0,I4,0);
7447 VARAND(UI4,0xffffffff,UI4,0xffffffff,I4,-1);
7448 VARAND(UI4,0xffffffff,UI4,0,I4,0);
7449 VARAND(UI4,0,UI4,0,I4,0);
7450 VARAND(UI4,0xffffffff,R4,-1,I4,-1);
7451 VARAND(UI4,0xffffffff,R4,0,I4,0);
7452 VARAND(UI4,0,R4,0,I4,0);
7453 VARAND(UI4,0xffffffff,R8,-1,I4,-1);
7454 VARAND(UI4,0xffffffff,R8,0,I4,0);
7455 VARAND(UI4,0,R8,0,I4,0);
7456 VARAND(UI4,0xffffffff,DATE,-1,I4,-1);
7457 VARAND(UI4,0xffffffff,DATE,0,I4,0);
7458 VARAND(UI4,0,DATE,0,I4,0);
7459 if (has_i8)
7461 VARAND(UI4,0xffffffff,I8,0,I8,0);
7462 VARAND(UI4,0,I8,0,I8,0);
7463 VARAND(UI4,0xffffffff,UI8,0,I4,0);
7464 VARAND(UI4,0,UI8,0,I4,0);
7466 VARAND(UI4,0xffffffff,INT,-1,I4,-1);
7467 VARAND(UI4,0xffffffff,INT,0,I4,0);
7468 VARAND(UI4,0,INT,0,I4,0);
7469 VARAND(UI4,0xffffffff,UINT,0xffffffff,I4,-1);
7470 VARAND(UI4,0xffffffff,UINT,0,I4,0);
7471 VARAND(UI4,0,UINT,0,I4,0);
7472 VARAND(UI4,0,BSTR,false_str,I4,0);
7473 VARAND(UI4,0xffffffff,BSTR,false_str,I4,0);
7474 VARAND(UI4,0,BSTR,true_str,I4,0);
7475 VARAND(UI4,0xffffffff,BSTR,true_str,I4,-1);
7476 VARANDCY(UI4,0xffffffff,10000,I4,1);
7477 VARANDCY(UI4,0xffffffff,0,I4,0);
7478 VARANDCY(UI4,0,0,I4,0);
7480 VARAND(R4,-1,R4,-1,I4,-1);
7481 VARAND(R4,-1,R4,0,I4,0);
7482 VARAND(R4,0,R4,0,I4,0);
7483 VARAND(R4,-1,R8,-1,I4,-1);
7484 VARAND(R4,-1,R8,0,I4,0);
7485 VARAND(R4,0,R8,0,I4,0);
7486 VARAND(R4,-1,DATE,-1,I4,-1);
7487 VARAND(R4,-1,DATE,0,I4,0);
7488 VARAND(R4,0,DATE,0,I4,0);
7489 if (has_i8)
7491 VARAND(R4,-1,I8,-1,I8,-1);
7492 VARAND(R4,-1,I8,0,I8,0);
7493 VARAND(R4,0,I8,0,I8,0);
7494 VARAND(R4,-1,UI8,0,I4,0);
7495 VARAND(R4,0,UI8,0,I4,0);
7497 VARAND(R4,-1,INT,-1,I4,-1);
7498 VARAND(R4,-1,INT,0,I4,0);
7499 VARAND(R4,0,INT,0,I4,0);
7500 VARAND(R4,-1,UINT,0xffffffff,I4,-1);
7501 VARAND(R4,-1,UINT,0,I4,0);
7502 VARAND(R4,0,UINT,0,I4,0);
7503 VARAND(R4,0,BSTR,false_str,I4,0);
7504 VARAND(R4,-1,BSTR,false_str,I4,0);
7505 VARAND(R4,0,BSTR,true_str,I4,0);
7506 VARAND(R4,-1,BSTR,true_str,I4,-1);
7507 VARANDCY(R4,-1,10000,I4,1);
7508 VARANDCY(R4,-1,0,I4,0);
7509 VARANDCY(R4,0,0,I4,0);
7511 VARAND(R8,-1,R8,-1,I4,-1);
7512 VARAND(R8,-1,R8,0,I4,0);
7513 VARAND(R8,0,R8,0,I4,0);
7514 VARAND(R8,-1,DATE,-1,I4,-1);
7515 VARAND(R8,-1,DATE,0,I4,0);
7516 VARAND(R8,0,DATE,0,I4,0);
7517 if (has_i8)
7519 VARAND(R8,-1,I8,-1,I8,-1);
7520 VARAND(R8,-1,I8,0,I8,0);
7521 VARAND(R8,0,I8,0,I8,0);
7522 VARAND(R8,-1,UI8,0,I4,0);
7523 VARAND(R8,0,UI8,0,I4,0);
7525 VARAND(R8,-1,INT,-1,I4,-1);
7526 VARAND(R8,-1,INT,0,I4,0);
7527 VARAND(R8,0,INT,0,I4,0);
7528 VARAND(R8,-1,UINT,0xffffffff,I4,-1);
7529 VARAND(R8,-1,UINT,0,I4,0);
7530 VARAND(R8,0,UINT,0,I4,0);
7531 VARAND(R8,0,BSTR,false_str,I4,0);
7532 VARAND(R8,-1,BSTR,false_str,I4,0);
7533 VARAND(R8,0,BSTR,true_str,I4,0);
7534 VARAND(R8,-1,BSTR,true_str,I4,-1);
7535 VARANDCY(R8,-1,10000,I4,1);
7536 VARANDCY(R8,-1,0,I4,0);
7537 VARANDCY(R8,0,0,I4,0);
7539 VARAND(DATE,-1,DATE,-1,I4,-1);
7540 VARAND(DATE,-1,DATE,0,I4,0);
7541 VARAND(DATE,0,DATE,0,I4,0);
7542 if (has_i8)
7544 VARAND(DATE,-1,I8,-1,I8,-1);
7545 VARAND(DATE,-1,I8,0,I8,0);
7546 VARAND(DATE,0,I8,0,I8,0);
7547 VARAND(DATE,-1,UI8,0,I4,0);
7548 VARAND(DATE,0,UI8,0,I4,0);
7550 VARAND(DATE,-1,INT,-1,I4,-1);
7551 VARAND(DATE,-1,INT,0,I4,0);
7552 VARAND(DATE,0,INT,0,I4,0);
7553 VARAND(DATE,-1,UINT,0xffffffff,I4,-1);
7554 VARAND(DATE,-1,UINT,0,I4,0);
7555 VARAND(DATE,0,UINT,0,I4,0);
7556 VARAND(DATE,0,BSTR,false_str,I4,0);
7557 VARAND(DATE,-1,BSTR,false_str,I4,0);
7558 VARAND(DATE,0,BSTR,true_str,I4,0);
7559 VARAND(DATE,-1,BSTR,true_str,I4,-1);
7560 VARANDCY(DATE,-1,10000,I4,1);
7561 VARANDCY(DATE,-1,0,I4,0);
7562 VARANDCY(DATE,0,0,I4,0);
7564 if (has_i8)
7566 VARAND(I8,-1,I8,-1,I8,-1);
7567 VARAND(I8,-1,I8,0,I8,0);
7568 VARAND(I8,0,I8,0,I8,0);
7569 VARAND(I8,-1,UI8,0,I8,0);
7570 VARAND(I8,0,UI8,0,I8,0);
7571 VARAND(I8,-1,UINT,0,I8,0);
7572 VARAND(I8,0,UINT,0,I8,0);
7573 VARAND(I8,0,BSTR,false_str,I8,0);
7574 VARAND(I8,-1,BSTR,false_str,I8,0);
7575 VARAND(I8,0,BSTR,true_str,I8,0);
7576 VARAND(I8,-1,BSTR,true_str,I8,-1);
7577 VARANDCY(I8,-1,10000,I8,1);
7578 VARANDCY(I8,-1,0,I8,0);
7579 VARANDCY(I8,0,0,I8,0);
7581 VARAND(UI8,0xffff,UI8,0xffff,I4,0xffff);
7582 VARAND(UI8,0xffff,UI8,0,I4,0);
7583 VARAND(UI8,0,UI8,0,I4,0);
7584 VARAND(UI8,0xffff,INT,-1,I4,65535);
7585 VARAND(UI8,0xffff,INT,0,I4,0);
7586 VARAND(UI8,0,INT,0,I4,0);
7587 VARAND(UI8,0xffff,UINT,0xffff,I4,0xffff);
7588 VARAND(UI8,0xffff,UINT,0,I4,0);
7589 VARAND(UI8,0,UINT,0,I4,0);
7590 VARAND(UI8,0,BSTR,false_str,I4,0);
7591 VARAND(UI8,0xffff,BSTR,false_str,I4,0);
7592 VARAND(UI8,0,BSTR,true_str,I4,0);
7593 VARAND(UI8,0xffff,BSTR,true_str,I4,65535);
7594 VARANDCY(UI8,0xffff,10000,I4,1);
7595 VARANDCY(UI8,0xffff,0,I4,0);
7596 VARANDCY(UI8,0,0,I4,0);
7599 VARAND(INT,-1,INT,-1,I4,-1);
7600 VARAND(INT,-1,INT,0,I4,0);
7601 VARAND(INT,0,INT,0,I4,0);
7602 VARAND(INT,-1,UINT,0xffff,I4,65535);
7603 VARAND(INT,-1,UINT,0,I4,0);
7604 VARAND(INT,0,UINT,0,I4,0);
7605 VARAND(INT,0,BSTR,false_str,I4,0);
7606 VARAND(INT,-1,BSTR,false_str,I4,0);
7607 VARAND(INT,0,BSTR,true_str,I4,0);
7608 VARAND(INT,-1,BSTR,true_str,I4,-1);
7609 VARANDCY(INT,-1,10000,I4,1);
7610 VARANDCY(INT,-1,0,I4,0);
7611 VARANDCY(INT,0,0,I4,0);
7613 VARAND(UINT,0xffff,UINT,0xffff,I4,0xffff);
7614 VARAND(UINT,0xffff,UINT,0,I4,0);
7615 VARAND(UINT,0,UINT,0,I4,0);
7616 VARAND(UINT,0,BSTR,false_str,I4,0);
7617 VARAND(UINT,0xffff,BSTR, false_str,I4,0);
7618 VARAND(UINT,0,BSTR,true_str,I4,0);
7619 VARAND(UINT,0xffff,BSTR,true_str,I4,65535);
7620 VARANDCY(UINT,0xffff,10000,I4,1);
7621 VARANDCY(UINT,0xffff,0,I4,0);
7622 VARANDCY(UINT,0,0,I4,0);
7624 VARAND(BSTR,false_str,BSTR,false_str,BOOL,0);
7625 VARAND(BSTR,true_str,BSTR,false_str,BOOL,VARIANT_FALSE);
7626 VARAND(BSTR,true_str,BSTR,true_str,BOOL,VARIANT_TRUE);
7627 VARANDCY(BSTR,true_str,10000,I4,1);
7628 VARANDCY(BSTR,false_str,10000,I4,0);
7630 SysFreeString(true_str);
7631 SysFreeString(false_str);
7634 static void test_cmp( int line, LCID lcid, UINT flags, VARIANT *left, VARIANT *right, HRESULT result )
7636 HRESULT hres;
7638 CHECKPTR(VarCmp);
7640 hres = pVarCmp(left,right,lcid,flags);
7641 ok_(__FILE__,line)(hres == result, "VarCmp(%s,%s): expected 0x%x, got hres=0x%x\n",
7642 variantstr(left), variantstr(right), result, hres );
7644 static void test_cmpex( int line, LCID lcid, VARIANT *left, VARIANT *right,
7645 HRESULT res1, HRESULT res2, HRESULT res3, HRESULT res4 )
7647 test_cmp( line, lcid, 0, left, right, res1 );
7648 V_VT(left) |= VT_RESERVED;
7649 test_cmp( line, lcid, 0, left, right, res2 );
7650 V_VT(left) &= ~VT_RESERVED;
7651 V_VT(right) |= VT_RESERVED;
7652 test_cmp( line, lcid, 0, left, right, res3 );
7653 V_VT(left) |= VT_RESERVED;
7654 test_cmp( line, lcid, 0, left, right, res4 );
7655 ok_(__FILE__,line)(V_VT(left) & V_VT(right) & VT_RESERVED, "VT_RESERVED filtered out\n");
7658 /* ERROR from wingdi.h is interfering here */
7659 #undef ERROR
7660 #define _VARCMP(vt1,val1,vtfl1,vt2,val2,vtfl2,lcid,flags,result) \
7661 V_##vt1(&left) = val1; V_VT(&left) = VT_##vt1 | vtfl1; \
7662 V_##vt2(&right) = val2; V_VT(&right) = VT_##vt2 | vtfl2; \
7663 test_cmp( __LINE__, lcid, flags, &left, &right, result )
7664 #define VARCMPEX(vt1,val1,vt2,val2,res1,res2,res3,res4) \
7665 V_##vt1(&left) = val1; V_VT(&left) = VT_##vt1; \
7666 V_##vt2(&right) = val2; V_VT(&right) = VT_##vt2; \
7667 test_cmpex( __LINE__, lcid, &left, &right, res1, res2, res3, res4 )
7668 #define VARCMP(vt1,val1,vt2,val2,result) \
7669 VARCMPEX(vt1,val1,vt2,val2,result,result,result,result)
7670 /* The above macros do not work for VT_NULL as NULL gets expanded first */
7671 #define V_NULL_ V_NULL
7672 #define VT_NULL_ VT_NULL
7674 static void test_VarCmp(void)
7676 VARIANT left, right;
7677 VARTYPE i;
7678 LCID lcid;
7679 HRESULT hres;
7680 DECIMAL dec;
7681 static const WCHAR szhuh[] = {'h','u','h','?','\0'};
7682 static const WCHAR sz2cents[] = {'2','c','e','n','t','s','\0'};
7683 static const WCHAR szempty[] = {'\0'};
7684 static const WCHAR sz0[] = {'0','\0'};
7685 static const WCHAR sz1[] = {'1','\0'};
7686 static const WCHAR sz7[] = {'7','\0'};
7687 static const WCHAR sz42[] = {'4','2','\0'};
7688 static const WCHAR sz1neg[] = {'-','1','\0'};
7689 static const WCHAR sz666neg[] = {'-','6','6','6','\0'};
7690 static const WCHAR sz1few[] = {'1','.','0','0','0','0','0','0','0','1','\0'};
7691 BSTR bstrhuh, bstrempty, bstr0, bstr1, bstr7, bstr42, bstr1neg, bstr666neg;
7692 BSTR bstr2cents, bstr1few;
7694 CHECKPTR(VarCmp);
7696 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
7697 bstrempty = SysAllocString(szempty);
7698 bstrhuh = SysAllocString(szhuh);
7699 bstr2cents = SysAllocString(sz2cents);
7700 bstr0 = SysAllocString(sz0);
7701 bstr1 = SysAllocString(sz1);
7702 bstr7 = SysAllocString(sz7);
7703 bstr42 = SysAllocString(sz42);
7704 bstr1neg = SysAllocString(sz1neg);
7705 bstr666neg = SysAllocString(sz666neg);
7706 bstr1few = SysAllocString(sz1few);
7708 /* Test all possible flag/vt combinations & the resulting vt type */
7709 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
7711 VARTYPE leftvt, rightvt;
7713 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
7716 SKIPTESTS(leftvt);
7718 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
7720 BOOL bFail = FALSE;
7721 HRESULT expect = VARCMP_EQ;
7723 SKIPTESTS(rightvt);
7725 memset(&left, 0, sizeof(left));
7726 memset(&right, 0, sizeof(right));
7727 V_VT(&left) = leftvt | ExtraFlags[i];
7728 if (leftvt == VT_BSTR) {
7729 V_BSTR(&left) = bstr1neg;
7730 if (ExtraFlags[i] & VT_RESERVED)
7731 expect = VARCMP_LT;
7732 else
7733 expect = VARCMP_GT;
7735 V_VT(&right) = rightvt | ExtraFlags[i];
7736 if (rightvt == VT_BSTR) {
7737 V_BSTR(&right) = bstr1neg;
7738 if (ExtraFlags[i] & VT_RESERVED)
7739 expect = VARCMP_GT;
7740 else
7741 expect = VARCMP_LT;
7744 /* Don't ask me why but native VarCmp cannot handle:
7745 VT_I1, VT_UI2, VT_UI4, VT_UINT and VT_UI8.
7746 VT_INT is only supported as left variant. Go figure.
7747 Tested with DCOM98, Win2k, WinXP */
7748 if (ExtraFlags[i] & VT_ARRAY || ExtraFlags[i] & VT_BYREF ||
7749 !IsValidVariantClearVT(leftvt, ExtraFlags[i] & ~VT_RESERVED) ||
7750 !IsValidVariantClearVT(rightvt, ExtraFlags[i] & ~VT_RESERVED) ||
7751 leftvt == VT_CLSID || rightvt == VT_CLSID ||
7752 leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
7753 leftvt == VT_ERROR || rightvt == VT_ERROR ||
7754 leftvt == VT_RECORD || rightvt == VT_RECORD ||
7755 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN ||
7756 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
7757 leftvt == VT_I1 || rightvt == VT_I1 ||
7758 leftvt == VT_UI2 || rightvt == VT_UI2 ||
7759 leftvt == VT_UI4 || rightvt == VT_UI4 ||
7760 leftvt == VT_UI8 || rightvt == VT_UI8 ||
7761 rightvt == VT_INT ||
7762 leftvt == VT_UINT || rightvt == VT_UINT) {
7763 bFail = TRUE;
7766 if (leftvt == VT_ERROR && rightvt == VT_ERROR &&
7767 !(ExtraFlags[i] & ~VT_RESERVED)) {
7768 expect = VARCMP_EQ;
7769 bFail = FALSE;
7770 } else if (leftvt == VT_NULL || rightvt == VT_NULL)
7771 expect = VARCMP_NULL;
7772 else if (leftvt == VT_BSTR && rightvt == VT_BSTR)
7773 expect = VARCMP_EQ;
7774 else if (leftvt == VT_BSTR && rightvt == VT_EMPTY)
7775 expect = VARCMP_GT;
7776 else if (leftvt == VT_EMPTY && rightvt == VT_BSTR)
7777 expect = VARCMP_LT;
7779 hres = pVarCmp(&left, &right, LOCALE_USER_DEFAULT, 0);
7780 if (bFail) {
7781 ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
7782 "VarCmp: %d|0x%X, %d|0x%X: Expected failure, got 0x%X\n",
7783 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], hres);
7784 } else {
7785 ok(hres == expect,
7786 "VarCmp: %d|0x%X, %d|0x%X: Expected 0x%X, got 0x%X\n",
7787 leftvt, ExtraFlags[i], rightvt, ExtraFlags[i], expect,
7788 hres);
7794 /* VARCMP{,EX} run each 4 tests with a permutation of all possible
7795 input variants with (1) and without (0) VT_RESERVED set. The order
7796 of the permutations is (0,0); (1,0); (0,1); (1,1) */
7797 VARCMP(INT,4711,I2,4711,VARCMP_EQ);
7798 VARCMP(INT,4711,I2,-4711,VARCMP_GT);
7799 VARCMP(ERROR,0,ERROR,0,VARCMP_EQ);
7800 VARCMP(ERROR,0,UI1,0,DISP_E_TYPEMISMATCH);
7801 VARCMP(EMPTY,0,EMPTY,0,VARCMP_EQ);
7802 VARCMP(I4,1,R8,1.0,VARCMP_EQ);
7803 VARCMP(EMPTY,19,I2,0,VARCMP_EQ);
7804 ok(V_EMPTY(&left) == 19, "VT_EMPTY modified!\n");
7805 VARCMP(I4,1,UI1,1,VARCMP_EQ);
7806 VARCMP(I2,2,I2,2,VARCMP_EQ);
7807 VARCMP(I2,1,I2,2,VARCMP_LT);
7808 VARCMP(I2,2,I2,1,VARCMP_GT);
7809 VARCMP(I2,2,EMPTY,1,VARCMP_GT);
7810 VARCMP(I2,2,NULL_,1,VARCMP_NULL);
7812 /* BSTR handling, especially in conjunction with VT_RESERVED */
7813 VARCMP(BSTR,bstr0,NULL_,0,VARCMP_NULL);
7814 VARCMP(BSTR,bstr0,BSTR,bstr0,VARCMP_EQ);
7815 VARCMP(BSTR,bstrempty,BSTR,bstr0,VARCMP_LT);
7816 VARCMP(BSTR,bstr7,BSTR,bstr0,VARCMP_GT);
7817 VARCMP(BSTR,bstr7,BSTR,bstr1neg,VARCMP_GT);
7818 VARCMP(BSTR,bstr0,BSTR,NULL,VARCMP_GT);
7819 VARCMP(BSTR,NULL,BSTR,NULL,VARCMP_EQ);
7820 VARCMP(BSTR,bstrempty,BSTR,NULL,VARCMP_EQ);
7821 VARCMP(BSTR,NULL,EMPTY,0,VARCMP_EQ);
7822 VARCMP(EMPTY,0,BSTR,NULL,VARCMP_EQ);
7823 VARCMP(EMPTY,0,BSTR,bstrempty,VARCMP_EQ);
7824 VARCMP(EMPTY,1,BSTR,bstrempty,VARCMP_EQ);
7825 VARCMP(BSTR,bstr0,EMPTY,0,VARCMP_GT);
7826 VARCMP(BSTR,bstr42,EMPTY,0,VARCMP_GT);
7827 VARCMPEX(BSTR,bstrempty,UI1,0,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7828 VARCMPEX(BSTR,bstrempty,I2,-1,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7829 VARCMPEX(I4,0,BSTR,bstrempty,VARCMP_LT,VARCMP_LT,VARCMP_GT,VARCMP_LT);
7830 VARCMPEX(BSTR,NULL,UI1,0,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7831 VARCMPEX(I4,7,BSTR,NULL,VARCMP_LT,VARCMP_LT,VARCMP_GT,VARCMP_LT);
7832 _VARCMP(BSTR,(BSTR)100,0,I2,100,0,lcid,0,VARCMP_GT);
7833 VARCMPEX(BSTR,bstr0,UI1,0,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_GT);
7834 VARCMPEX(I2,0,BSTR,bstr0,VARCMP_LT,VARCMP_EQ,VARCMP_EQ,VARCMP_LT);
7835 VARCMP(BSTR,bstrhuh,I4,I4_MAX,VARCMP_GT);
7836 VARCMP(BSTR,bstr2cents,I4,2,VARCMP_GT);
7837 VARCMPEX(BSTR,bstr2cents,I4,42,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7838 VARCMP(BSTR,bstr2cents,I4,-1,VARCMP_GT);
7839 VARCMPEX(BSTR,bstr2cents,I4,-666,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7840 VARCMPEX(BSTR,bstr0,I2,0,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_GT);
7841 VARCMPEX(BSTR,bstr0,I4,0,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_GT);
7842 VARCMPEX(BSTR,bstr0,I4,-666,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7843 VARCMP(BSTR,bstr1,I4,0,VARCMP_GT);
7844 VARCMPEX(BSTR,bstr1,I4,1,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_GT);
7845 VARCMPEX(BSTR,bstr1,I4,I4_MAX,VARCMP_GT,VARCMP_LT,VARCMP_LT,VARCMP_GT);
7846 VARCMPEX(BSTR,bstr1,I4,-1,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7847 VARCMP(BSTR,bstr7,I4,1,VARCMP_GT);
7848 VARCMPEX(BSTR,bstr7,I4,7,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_GT);
7849 VARCMPEX(BSTR,bstr7,I4,42,VARCMP_GT,VARCMP_GT,VARCMP_LT,VARCMP_GT);
7850 VARCMPEX(BSTR,bstr42,I4,7,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_GT);
7851 VARCMPEX(BSTR,bstr42,I4,42,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_GT);
7852 VARCMPEX(BSTR,bstr42,I4,I4_MAX,VARCMP_GT,VARCMP_GT,VARCMP_LT,VARCMP_GT);
7853 VARCMPEX(BSTR,bstr1neg,I4,1,VARCMP_GT,VARCMP_GT,VARCMP_LT,VARCMP_LT);
7854 VARCMPEX(BSTR,bstr1neg,I4,42,VARCMP_GT,VARCMP_LT,VARCMP_LT,VARCMP_LT);
7855 VARCMPEX(BSTR,bstr1neg,I4,-1,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_LT);
7856 VARCMPEX(BSTR,bstr1neg,I4,-666,VARCMP_GT,VARCMP_LT,VARCMP_GT,VARCMP_LT);
7857 VARCMPEX(BSTR,bstr666neg,I4,1,VARCMP_GT,VARCMP_GT,VARCMP_LT,VARCMP_LT);
7858 VARCMPEX(BSTR,bstr666neg,I4,7,VARCMP_GT,VARCMP_LT,VARCMP_LT,VARCMP_LT);
7859 VARCMPEX(BSTR,bstr666neg,I4,42,VARCMP_GT,VARCMP_GT,VARCMP_LT,VARCMP_LT);
7860 VARCMPEX(BSTR,bstr666neg,I4,I4_MAX,VARCMP_GT,VARCMP_GT,VARCMP_LT,VARCMP_LT);
7861 VARCMPEX(BSTR,bstr666neg,I4,-1,VARCMP_GT,VARCMP_GT,VARCMP_LT,VARCMP_LT);
7862 VARCMPEX(BSTR,bstr666neg,I4,-666,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_LT);
7863 VARCMPEX(BSTR,bstr7,R8,7.0,VARCMP_GT,VARCMP_EQ,VARCMP_EQ,VARCMP_GT);
7864 VARCMPEX(R8,3.141592,BSTR,NULL,VARCMP_LT,VARCMP_LT,VARCMP_GT,VARCMP_LT);
7865 VARCMP(BSTR,bstr7,BSTR,bstr7,VARCMP_EQ);
7866 VARCMP(BSTR,bstr7,BSTR,bstr42,VARCMP_GT);
7867 VARCMP(BSTR,bstr42,BSTR,bstr7,VARCMP_LT);
7869 /* DECIMAL handling */
7870 setdec(&dec,0,0,0,0);
7871 VARCMPEX(DECIMAL,dec,BSTR,bstr0,VARCMP_LT,VARCMP_EQ,VARCMP_EQ,VARCMP_LT);
7872 setdec64(&dec,0,0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF); /* max DECIMAL */
7873 VARCMP(DECIMAL,dec,R8,R8_MAX,VARCMP_LT); /* R8 has bigger range */
7874 VARCMP(DECIMAL,dec,DATE,R8_MAX,VARCMP_LT); /* DATE has bigger range */
7875 setdec64(&dec,0,0x80,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF);
7876 VARCMP(DECIMAL,dec,R8,-R8_MAX,VARCMP_GT);
7877 setdec64(&dec,20,0,0x5,0x6BC75E2D,0x63100001); /* 1+1e-20 */
7878 VARCMP(DECIMAL,dec,R8,1,VARCMP_GT); /* DECIMAL has higher precision */
7880 /* Show that DATE is handled just as a R8 */
7881 VARCMP(DATE,DATE_MAX,DATE,DATE_MAX+1,VARCMP_LT);
7882 VARCMP(DATE,DATE_MIN,DATE,DATE_MIN-1,VARCMP_GT);
7883 VARCMP(DATE,R8_MIN,R8,R8_MIN,VARCMP_EQ);
7884 VARCMP(DATE,1,DATE,1+1e-15,VARCMP_LT); /* 1e-15 == 8.64e-11 seconds */
7885 VARCMP(DATE,25570.0,DATE,25570.0,VARCMP_EQ);
7886 VARCMP(DATE,25570.0,DATE,25571.0,VARCMP_LT);
7887 VARCMP(DATE,25571.0,DATE,25570.0,VARCMP_GT);
7888 VARCMP(DATE,25570.0,EMPTY,0,VARCMP_GT);
7889 VARCMP(DATE,25570.0,NULL_,0,VARCMP_NULL);
7891 /* R4 precision handling */
7892 VARCMP(R4,1,R8,1+1e-8,VARCMP_EQ);
7893 VARCMP(R8,1+1e-8,R4,1,VARCMP_EQ);
7894 VARCMP(R8,1+1e-8,R8,1,VARCMP_GT);
7895 VARCMP(R8,R4_MAX*1.1,R4,R4_MAX,VARCMP_GT);
7896 VARCMP(R4,R4_MAX,R8,R8_MAX,VARCMP_LT);
7897 VARCMP(R4,1,DATE,1+1e-8,VARCMP_EQ);
7898 VARCMP(R4,1,BSTR,bstr1few,VARCMP_LT); /* bstr1few == 1+1e-8 */
7899 setdec(&dec,8,0,0,0x5F5E101); /* 1+1e-8 */
7900 VARCMP(R4,1,DECIMAL,dec,VARCMP_LT);
7902 SysFreeString(bstrhuh);
7903 SysFreeString(bstrempty);
7904 SysFreeString(bstr0);
7905 SysFreeString(bstr1);
7906 SysFreeString(bstr7);
7907 SysFreeString(bstr42);
7908 SysFreeString(bstr1neg);
7909 SysFreeString(bstr666neg);
7910 SysFreeString(bstr2cents);
7911 SysFreeString(bstr1few);
7914 static HRESULT (WINAPI *pVarPow)(LPVARIANT,LPVARIANT,LPVARIANT);
7916 #define VARPOW(vt1,val1,vt2,val2,rvt,rval) \
7917 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
7918 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
7919 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
7920 test_var_call2( __LINE__, pVarPow, &left, &right, &exp )
7922 /* Skip any type that is not defined or produces an error for every case */
7923 #define SKIPTESTPOW(a) \
7924 if (a == VT_ERROR || a == VT_VARIANT || \
7925 a == VT_DISPATCH || a == VT_UNKNOWN || \
7926 a == VT_RECORD || a > VT_UINT || \
7927 a == 15 /*not defined*/) \
7928 continue
7930 static void test_VarPow(void)
7932 static const WCHAR str2[] = { '2','\0' };
7933 static const WCHAR str3[] = { '3','\0' };
7934 VARIANT left, right, exp, result, cy, dec;
7935 BSTR num2_str, num3_str;
7936 VARTYPE i;
7937 HRESULT hres;
7939 CHECKPTR(VarPow);
7941 num2_str = SysAllocString(str2);
7942 num3_str = SysAllocString(str3);
7944 /* Test all possible flag/vt combinations & the resulting vt type */
7945 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
7947 VARTYPE leftvt, rightvt, resvt;
7949 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
7951 SKIPTESTPOW(leftvt);
7953 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
7955 BOOL bFail = FALSE;
7956 SKIPTESTPOW(rightvt);
7958 /* Native crashes with VT_BYREF */
7959 if (ExtraFlags[i] == VT_BYREF)
7960 continue;
7962 memset(&left, 0, sizeof(left));
7963 memset(&right, 0, sizeof(right));
7964 V_VT(&left) = leftvt | ExtraFlags[i];
7965 V_VT(&right) = rightvt | ExtraFlags[i];
7966 V_VT(&result) = VT_EMPTY;
7967 resvt = VT_EMPTY;
7969 if (leftvt == VT_BSTR)
7970 V_BSTR(&left) = num2_str;
7971 if (rightvt == VT_BSTR)
7972 V_BSTR(&right) = num2_str;
7974 /* Native VarPow always returns an error when using extra flags */
7975 if (ExtraFlags[i] != 0)
7976 bFail = TRUE;
7978 /* Determine return type */
7979 else if ((leftvt == VT_NULL || rightvt == VT_NULL) &&
7980 ((leftvt != VT_I8 && leftvt != VT_UI8 &&
7981 rightvt != VT_I8 && rightvt != VT_UI8) || has_i8))
7982 resvt = VT_NULL;
7983 else if ((leftvt == VT_EMPTY || leftvt == VT_I2 ||
7984 leftvt == VT_I4 || leftvt == VT_R4 ||
7985 leftvt == VT_R8 || leftvt == VT_CY ||
7986 leftvt == VT_DATE || leftvt == VT_BSTR ||
7987 leftvt == VT_BOOL || leftvt == VT_DECIMAL ||
7988 (leftvt >= VT_I1 && leftvt <= VT_UI4) ||
7989 (has_i8 && (leftvt == VT_I8 || leftvt == VT_UI8)) ||
7990 leftvt == VT_INT || leftvt == VT_UINT) &&
7991 (rightvt == VT_EMPTY || rightvt == VT_I2 ||
7992 rightvt == VT_I4 || rightvt == VT_R4 ||
7993 rightvt == VT_R8 || rightvt == VT_CY ||
7994 rightvt == VT_DATE || rightvt == VT_BSTR ||
7995 rightvt == VT_BOOL || rightvt == VT_DECIMAL ||
7996 (rightvt >= VT_I1 && rightvt <= VT_UI4) ||
7997 (has_i8 && (rightvt == VT_I8 || rightvt == VT_UI8)) ||
7998 rightvt == VT_INT || rightvt == VT_UINT))
7999 resvt = VT_R8;
8000 else
8001 bFail = TRUE;
8003 hres = pVarPow(&left, &right, &result);
8005 /* Check expected HRESULT and if result variant type is correct */
8006 if (bFail)
8007 ok (hres == DISP_E_BADVARTYPE || hres == DISP_E_TYPEMISMATCH,
8008 "VarPow: %s|0x%X, %s|0x%X: got vt %s hr 0x%X\n",
8009 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i],
8010 vtstr(V_VT(&result)), hres);
8011 else
8012 ok (hres == S_OK && resvt == V_VT(&result),
8013 "VarPow: %s|0x%X, %s|0x%X: expected vt %s hr 0x%X, got vt %s hr 0x%X\n",
8014 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i], vtstr(resvt),
8015 S_OK, vtstr(V_VT(&result)), hres);
8020 /* Check return values for valid variant type combinations */
8021 VARPOW(EMPTY,0,EMPTY,0,R8,1.0);
8022 VARPOW(EMPTY,0,NULL,0,NULL,0);
8023 VARPOW(EMPTY,0,I2,3,R8,0.0);
8024 VARPOW(EMPTY,0,I4,3,R8,0.0);
8025 VARPOW(EMPTY,0,R4,3.0f,R8,0.0);
8026 VARPOW(EMPTY,0,R8,3.0,R8,0.0);
8027 VARPOW(EMPTY,0,DATE,3,R8,0.0);
8028 VARPOW(EMPTY,0,BSTR,num3_str,R8,0.0);
8029 VARPOW(EMPTY,0,BOOL,VARIANT_FALSE,R8,1.0);
8030 VARPOW(EMPTY,0,I1,3,R8,0.0);
8031 VARPOW(EMPTY,0,UI1,3,R8,0.0);
8032 VARPOW(EMPTY,0,UI2,3,R8,0.0);
8033 VARPOW(EMPTY,0,UI4,3,R8,0.0);
8034 if (has_i8)
8036 VARPOW(EMPTY,0,I8,3,R8,0.0);
8037 VARPOW(EMPTY,0,UI8,3,R8,0.0);
8039 VARPOW(EMPTY,0,INT,3,R8,0.0);
8040 VARPOW(EMPTY,0,UINT,3,R8,0.0);
8041 VARPOW(NULL,0,EMPTY,0,NULL,0);
8042 VARPOW(NULL,0,NULL,0,NULL,0);
8043 VARPOW(NULL,0,I2,3,NULL,0);
8044 VARPOW(NULL,0,I4,3,NULL,0);
8045 VARPOW(NULL,0,R4,3.0f,NULL,0);
8046 VARPOW(NULL,0,R8,3.0,NULL,0);
8047 VARPOW(NULL,0,DATE,3,NULL,0);
8048 VARPOW(NULL,0,BSTR,num3_str,NULL,0);
8049 VARPOW(NULL,0,BOOL,VARIANT_TRUE,NULL,0);
8050 VARPOW(NULL,0,I1,3,NULL,0);
8051 VARPOW(NULL,0,UI1,3,NULL,0);
8052 VARPOW(NULL,0,UI2,3,NULL,0);
8053 VARPOW(NULL,0,UI4,3,NULL,0);
8054 if (has_i8)
8056 VARPOW(NULL,0,I8,3,NULL,0);
8057 VARPOW(NULL,0,UI8,3,NULL,0);
8059 VARPOW(NULL,0,INT,3,NULL,0);
8060 VARPOW(NULL,0,UINT,3,NULL,0);
8061 VARPOW(I2,2,EMPTY,0,R8,1.0);
8062 VARPOW(I2,2,NULL,0,NULL,0);
8063 VARPOW(I2,2,I2,3,R8,8.0);
8064 VARPOW(I2,2,I4,3,R8,8.0);
8065 VARPOW(I2,2,R4,3.0f,R8,8.0);
8066 VARPOW(I2,2,R8,3.0,R8,8.0);
8067 VARPOW(I2,2,DATE,3,R8,8.0);
8068 VARPOW(I2,2,BSTR,num3_str,R8,8.0);
8069 VARPOW(I2,2,BOOL,VARIANT_FALSE,R8,1.0);
8070 VARPOW(I2,2,I1,3,R8,8.0);
8071 VARPOW(I2,2,UI1,3,R8,8.0);
8072 VARPOW(I2,2,UI2,3,R8,8.0);
8073 VARPOW(I2,2,UI4,3,R8,8.0);
8074 if (has_i8)
8076 VARPOW(I2,2,I8,3,R8,8.0);
8077 VARPOW(I2,2,UI8,3,R8,8.0);
8079 VARPOW(I2,2,INT,3,R8,8.0);
8080 VARPOW(I2,2,UINT,3,R8,8.0);
8081 VARPOW(I4,2,EMPTY,0,R8,1.0);
8082 VARPOW(I4,2,NULL,0,NULL,0);
8083 VARPOW(I4,2,I2,3,R8,8.0);
8084 VARPOW(I4,2,I4,3,R8,8.0);
8085 VARPOW(I4,2,R4,3.0f,R8,8.0);
8086 VARPOW(I4,2,R8,3.0,R8,8.0);
8087 VARPOW(I4,2,DATE,3,R8,8.0);
8088 VARPOW(I4,2,BSTR,num3_str,R8,8.0);
8089 VARPOW(I4,2,BOOL,VARIANT_FALSE,R8,1.0);
8090 VARPOW(I4,2,I1,3,R8,8.0);
8091 VARPOW(I4,2,UI1,3,R8,8.0);
8092 VARPOW(I4,2,UI2,3,R8,8.0);
8093 VARPOW(I4,2,UI4,3,R8,8.0);
8094 if (has_i8)
8096 VARPOW(I4,2,I8,3,R8,8.0);
8097 VARPOW(I4,2,UI8,3,R8,8.0);
8099 VARPOW(I4,2,INT,3,R8,8.0);
8100 VARPOW(I4,2,UINT,3,R8,8.0);
8101 VARPOW(R4,2,EMPTY,0,R8,1.0);
8102 VARPOW(R4,2,NULL,0,NULL,0);
8103 VARPOW(R4,2,I2,3,R8,8.0);
8104 VARPOW(R4,2,I4,3,R8,8.0);
8105 VARPOW(R4,2,R4,3.0f,R8,8.0);
8106 VARPOW(R4,2,R8,3.0,R8,8.0);
8107 VARPOW(R4,2,DATE,3,R8,8.0);
8108 VARPOW(R4,2,BSTR,num3_str,R8,8.0);
8109 VARPOW(R4,2,BOOL,VARIANT_FALSE,R8,1.0);
8110 VARPOW(R4,2,I1,3,R8,8.0);
8111 VARPOW(R4,2,UI1,3,R8,8.0);
8112 VARPOW(R4,2,UI2,3,R8,8.0);
8113 VARPOW(R4,2,UI4,3,R8,8.0);
8114 if (has_i8)
8116 VARPOW(R4,2,I8,3,R8,8.0);
8117 VARPOW(R4,2,UI8,3,R8,8.0);
8119 VARPOW(R4,2,INT,3,R8,8.0);
8120 VARPOW(R4,2,UINT,3,R8,8.0);
8121 VARPOW(R8,2,EMPTY,0,R8,1.0);
8122 VARPOW(R8,2,NULL,0,NULL,0);
8123 VARPOW(R8,2,I2,3,R8,8.0);
8124 VARPOW(R8,2,I4,3,R8,8.0);
8125 VARPOW(R8,2,R4,3.0f,R8,8.0);
8126 VARPOW(R8,2,R8,3.0,R8,8.0);
8127 VARPOW(R8,2,DATE,3,R8,8.0);
8128 VARPOW(R8,2,BSTR,num3_str,R8,8.0);
8129 VARPOW(R8,2,BOOL,VARIANT_FALSE,R8,1.0);
8130 VARPOW(R8,2,I1,3,R8,8.0);
8131 VARPOW(R8,2,UI1,3,R8,8.0);
8132 VARPOW(R8,2,UI2,3,R8,8.0);
8133 VARPOW(R8,2,UI4,3,R8,8.0);
8134 if (has_i8)
8136 VARPOW(R8,2,I8,3,R8,8.0);
8137 VARPOW(R8,2,UI8,3,R8,8.0);
8139 VARPOW(R8,2,INT,3,R8,8.0);
8140 VARPOW(R8,2,UINT,3,R8,8.0);
8141 VARPOW(DATE,2,EMPTY,0,R8,1.0);
8142 VARPOW(DATE,2,NULL,0,NULL,0);
8143 VARPOW(DATE,2,I2,3,R8,8.0);
8144 VARPOW(DATE,2,I4,3,R8,8.0);
8145 VARPOW(DATE,2,R4,3.0f,R8,8.0);
8146 VARPOW(DATE,2,R8,3.0,R8,8.0);
8147 VARPOW(DATE,2,DATE,3,R8,8.0);
8148 VARPOW(DATE,2,BSTR,num3_str,R8,8.0);
8149 VARPOW(DATE,2,BOOL,VARIANT_FALSE,R8,1.0);
8150 VARPOW(DATE,2,I1,3,R8,8.0);
8151 VARPOW(DATE,2,UI1,3,R8,8.0);
8152 VARPOW(DATE,2,UI2,3,R8,8.0);
8153 VARPOW(DATE,2,UI4,3,R8,8.0);
8154 if (has_i8)
8156 VARPOW(DATE,2,I8,3,R8,8.0);
8157 VARPOW(DATE,2,UI8,3,R8,8.0);
8159 VARPOW(DATE,2,INT,3,R8,8.0);
8160 VARPOW(DATE,2,UINT,3,R8,8.0);
8161 VARPOW(BSTR,num2_str,EMPTY,0,R8,1.0);
8162 VARPOW(BSTR,num2_str,NULL,0,NULL,0);
8163 VARPOW(BSTR,num2_str,I2,3,R8,8.0);
8164 VARPOW(BSTR,num2_str,I4,3,R8,8.0);
8165 VARPOW(BSTR,num2_str,R4,3.0f,R8,8.0);
8166 VARPOW(BSTR,num2_str,R8,3.0,R8,8.0);
8167 VARPOW(BSTR,num2_str,DATE,3,R8,8.0);
8168 VARPOW(BSTR,num2_str,BSTR,num3_str,R8,8.0);
8169 VARPOW(BSTR,num2_str,BOOL,VARIANT_FALSE,R8,1.0);
8170 VARPOW(BSTR,num2_str,I1,3,R8,8.0);
8171 VARPOW(BSTR,num2_str,UI1,3,R8,8.0);
8172 VARPOW(BSTR,num2_str,UI2,3,R8,8.0);
8173 VARPOW(BSTR,num2_str,UI4,3,R8,8.0);
8174 if (has_i8)
8176 VARPOW(BSTR,num2_str,I8,3,R8,8.0);
8177 VARPOW(BSTR,num2_str,UI8,3,R8,8.0);
8179 VARPOW(BSTR,num2_str,INT,3,R8,8.0);
8180 VARPOW(BSTR,num2_str,UINT,3,R8,8.0);
8181 VARPOW(BOOL,VARIANT_TRUE,EMPTY,0,R8,1.0);
8182 VARPOW(BOOL,VARIANT_TRUE,NULL,0,NULL,0);
8183 VARPOW(BOOL,VARIANT_TRUE,I2,3,R8,-1.0);
8184 VARPOW(BOOL,VARIANT_TRUE,I4,3,R8,-1.0);
8185 VARPOW(BOOL,VARIANT_TRUE,R4,3.0f,R8,-1.0);
8186 VARPOW(BOOL,VARIANT_TRUE,R8,3.0,R8,-1.0);
8187 VARPOW(BOOL,VARIANT_TRUE,DATE,3,R8,-1.0);
8188 VARPOW(BOOL,VARIANT_TRUE,BSTR,num3_str,R8,-1.0);
8189 VARPOW(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,R8,-1.0);
8190 VARPOW(BOOL,VARIANT_TRUE,I1,3,R8,-1.0);
8191 VARPOW(BOOL,VARIANT_TRUE,UI1,3,R8,-1.0);
8192 VARPOW(BOOL,VARIANT_TRUE,UI2,3,R8,-1.0);
8193 VARPOW(BOOL,VARIANT_TRUE,UI4,3,R8,-1.0);
8194 if (has_i8)
8196 VARPOW(BOOL,VARIANT_TRUE,I8,3,R8,-1.0);
8197 VARPOW(BOOL,VARIANT_TRUE,UI8,3,R8,-1.0);
8199 VARPOW(BOOL,VARIANT_TRUE,INT,3,R8,-1.0);
8200 VARPOW(BOOL,VARIANT_TRUE,UINT,3,R8,-1.0);
8201 VARPOW(I1,2,EMPTY,0,R8,1.0);
8202 VARPOW(I1,2,NULL,0,NULL,0);
8203 VARPOW(I1,2,I2,3,R8,8.0);
8204 VARPOW(I1,2,I4,3,R8,8.0);
8205 VARPOW(I1,2,R4,3.0f,R8,8.0);
8206 VARPOW(I1,2,R8,3.0,R8,8.0);
8207 VARPOW(I1,2,DATE,3,R8,8.0);
8208 VARPOW(I1,2,BSTR,num3_str,R8,8.0);
8209 VARPOW(I1,2,BOOL,VARIANT_FALSE,R8,1.0);
8210 VARPOW(I1,2,I1,3,R8,8.0);
8211 VARPOW(I1,2,UI1,3,R8,8.0);
8212 VARPOW(I1,2,UI2,3,R8,8.0);
8213 VARPOW(I1,2,UI4,3,R8,8.0);
8214 if (has_i8)
8216 VARPOW(I1,2,I8,3,R8,8.0);
8217 VARPOW(I1,2,UI8,3,R8,8.0);
8219 VARPOW(I1,2,INT,3,R8,8.0);
8220 VARPOW(I1,2,UINT,3,R8,8.0);
8221 VARPOW(UI1,2,EMPTY,0,R8,1.0);
8222 VARPOW(UI1,2,NULL,0,NULL,0);
8223 VARPOW(UI1,2,I2,3,R8,8.0);
8224 VARPOW(UI1,2,I4,3,R8,8.0);
8225 VARPOW(UI1,2,R4,3.0f,R8,8.0);
8226 VARPOW(UI1,2,R8,3.0,R8,8.0);
8227 VARPOW(UI1,2,DATE,3,R8,8.0);
8228 VARPOW(UI1,2,BSTR,num3_str,R8,8.0);
8229 VARPOW(UI1,2,BOOL,VARIANT_FALSE,R8,1.0);
8230 VARPOW(UI1,2,I1,3,R8,8.0);
8231 VARPOW(UI1,2,UI1,3,R8,8.0);
8232 VARPOW(UI1,2,UI2,3,R8,8.0);
8233 VARPOW(UI1,2,UI4,3,R8,8.0);
8234 if (has_i8)
8236 VARPOW(UI1,2,I8,3,R8,8.0);
8237 VARPOW(UI1,2,UI8,3,R8,8.0);
8239 VARPOW(UI1,2,INT,3,R8,8.0);
8240 VARPOW(UI1,2,UINT,3,R8,8.0);
8241 VARPOW(UI2,2,EMPTY,0,R8,1.0);
8242 VARPOW(UI2,2,NULL,0,NULL,0);
8243 VARPOW(UI2,2,I2,3,R8,8.0);
8244 VARPOW(UI2,2,I4,3,R8,8.0);
8245 VARPOW(UI2,2,R4,3.0f,R8,8.0);
8246 VARPOW(UI2,2,R8,3.0,R8,8.0);
8247 VARPOW(UI2,2,DATE,3,R8,8.0);
8248 VARPOW(UI2,2,BSTR,num3_str,R8,8.0);
8249 VARPOW(UI2,2,BOOL,VARIANT_FALSE,R8,1.0);
8250 VARPOW(UI2,2,I1,3,R8,8.0);
8251 VARPOW(UI2,2,UI1,3,R8,8.0);
8252 VARPOW(UI2,2,UI2,3,R8,8.0);
8253 VARPOW(UI2,2,UI4,3,R8,8.0);
8254 if (has_i8)
8256 VARPOW(UI2,2,I8,3,R8,8.0);
8257 VARPOW(UI2,2,UI8,3,R8,8.0);
8259 VARPOW(UI2,2,INT,3,R8,8.0);
8260 VARPOW(UI2,2,UINT,3,R8,8.0);
8261 VARPOW(UI4,2,EMPTY,0,R8,1.0);
8262 VARPOW(UI4,2,NULL,0,NULL,0);
8263 VARPOW(UI4,2,I2,3,R8,8.0);
8264 VARPOW(UI4,2,I4,3,R8,8.0);
8265 VARPOW(UI4,2,R4,3.0f,R8,8.0);
8266 VARPOW(UI4,2,R8,3.0,R8,8.0);
8267 VARPOW(UI4,2,DATE,3,R8,8.0);
8268 VARPOW(UI4,2,BSTR,num3_str,R8,8.0);
8269 VARPOW(UI4,2,BOOL,VARIANT_FALSE,R8,1.0);
8270 VARPOW(UI4,2,I1,3,R8,8.0);
8271 VARPOW(UI4,2,UI1,3,R8,8.0);
8272 VARPOW(UI4,2,UI2,3,R8,8.0);
8273 VARPOW(UI4,2,UI4,3,R8,8.0);
8274 if (has_i8)
8276 VARPOW(UI4,2,I8,3,R8,8.0);
8277 VARPOW(UI4,2,UI8,3,R8,8.0);
8279 VARPOW(UI4,2,INT,3,R8,8.0);
8280 VARPOW(UI4,2,UINT,3,R8,8.0);
8281 if (has_i8)
8283 VARPOW(I8,2,EMPTY,0,R8,1.0);
8284 VARPOW(I8,2,NULL,0,NULL,0);
8285 VARPOW(I8,2,I2,3,R8,8.0);
8286 VARPOW(I8,2,I4,3,R8,8.0);
8287 VARPOW(I8,2,R4,3.0f,R8,8.0);
8288 VARPOW(I8,2,R8,3.0,R8,8.0);
8289 VARPOW(I8,2,DATE,3,R8,8.0);
8290 VARPOW(I8,2,BSTR,num3_str,R8,8.0);
8291 VARPOW(I8,2,BOOL,VARIANT_FALSE,R8,1.0);
8292 VARPOW(I8,2,I1,3,R8,8.0);
8293 VARPOW(I8,2,UI1,3,R8,8.0);
8294 VARPOW(I8,2,UI2,3,R8,8.0);
8295 VARPOW(I8,2,UI4,3,R8,8.0);
8296 VARPOW(I8,2,I8,3,R8,8.0);
8297 VARPOW(I8,2,UI8,3,R8,8.0);
8298 VARPOW(I8,2,INT,3,R8,8.0);
8299 VARPOW(I8,2,UINT,3,R8,8.0);
8300 VARPOW(UI8,2,EMPTY,0,R8,1.0);
8301 VARPOW(UI8,2,NULL,0,NULL,0);
8302 VARPOW(UI8,2,I2,3,R8,8.0);
8303 VARPOW(UI8,2,I4,3,R8,8.0);
8304 VARPOW(UI8,2,R4,3.0f,R8,8.0);
8305 VARPOW(UI8,2,R8,3.0,R8,8.0);
8306 VARPOW(UI8,2,DATE,3,R8,8.0);
8307 VARPOW(UI8,2,BSTR,num3_str,R8,8.0);
8308 VARPOW(UI8,2,I1,3,R8,8.0);
8309 VARPOW(UI8,2,UI1,3,R8,8.0);
8310 VARPOW(UI8,2,UI2,3,R8,8.0);
8311 VARPOW(UI8,2,UI4,3,R8,8.0);
8312 VARPOW(UI8,2,I8,3,R8,8.0);
8313 VARPOW(UI8,2,UI8,3,R8,8.0);
8314 VARPOW(UI8,2,INT,3,R8,8.0);
8315 VARPOW(UI8,2,UINT,3,R8,8.0);
8317 VARPOW(INT,2,EMPTY,0,R8,1.0);
8318 VARPOW(INT,2,NULL,0,NULL,0);
8319 VARPOW(INT,2,I2,3,R8,8.0);
8320 VARPOW(INT,2,I4,3,R8,8.0);
8321 VARPOW(INT,2,R4,3.0f,R8,8.0);
8322 VARPOW(INT,2,R8,3.0,R8,8.0);
8323 VARPOW(INT,2,DATE,3,R8,8.0);
8324 VARPOW(INT,2,BSTR,num3_str,R8,8.0);
8325 VARPOW(INT,2,BOOL,VARIANT_FALSE,R8,1.0);
8326 VARPOW(INT,2,I1,3,R8,8.0);
8327 VARPOW(INT,2,UI1,3,R8,8.0);
8328 VARPOW(INT,2,UI2,3,R8,8.0);
8329 VARPOW(INT,2,UI4,3,R8,8.0);
8330 if (has_i8)
8332 VARPOW(INT,2,I8,3,R8,8.0);
8333 VARPOW(INT,2,UI8,3,R8,8.0);
8335 VARPOW(INT,2,INT,3,R8,8.0);
8336 VARPOW(INT,2,UINT,3,R8,8.0);
8337 VARPOW(UINT,2,EMPTY,0,R8,1.0);
8338 VARPOW(UINT,2,NULL,0,NULL,0);
8339 VARPOW(UINT,2,I2,3,R8,8.0);
8340 VARPOW(UINT,2,I4,3,R8,8.0);
8341 VARPOW(UINT,2,R4,3.0f,R8,8.0);
8342 VARPOW(UINT,2,R8,3.0,R8,8.0);
8343 VARPOW(UINT,2,DATE,3,R8,8.0);
8344 VARPOW(UINT,2,BSTR,num3_str,R8,8.0);
8345 VARPOW(UINT,2,BOOL,VARIANT_FALSE,R8,1.0);
8346 VARPOW(UINT,2,I1,3,R8,8.0);
8347 VARPOW(UINT,2,UI1,3,R8,8.0);
8348 VARPOW(UINT,2,UI2,3,R8,8.0);
8349 VARPOW(UINT,2,UI4,3,R8,8.0);
8350 if (has_i8)
8352 VARPOW(UINT,2,I8,3,R8,8.0);
8353 VARPOW(UINT,2,UI8,3,R8,8.0);
8355 VARPOW(UINT,2,INT,3,R8,8.0);
8356 VARPOW(UINT,2,UINT,3,R8,8.0);
8358 /* Manually test some VT_CY, VT_DECIMAL variants */
8359 V_VT(&cy) = VT_CY;
8360 hres = VarCyFromI4(2, &V_CY(&cy));
8361 ok(hres == S_OK, "VarCyFromI4 failed!\n");
8362 V_VT(&dec) = VT_DECIMAL;
8363 hres = VarDecFromR8(2.0, &V_DECIMAL(&dec));
8364 ok(hres == S_OK, "VarDecFromR4 failed!\n");
8365 memset(&left, 0, sizeof(left));
8366 memset(&right, 0, sizeof(right));
8367 V_VT(&left) = VT_I4;
8368 V_I4(&left) = 100;
8369 V_VT(&right) = VT_I8;
8370 V_UI1(&right) = 2;
8372 hres = pVarPow(&cy, &cy, &result);
8373 ok(hres == S_OK && V_VT(&result) == VT_R8,
8374 "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
8375 S_OK, hres, vtstr(V_VT(&result)));
8376 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 4.0),
8377 "VARPOW: CY value %f, expected %f\n", V_R8(&result), 4.0);
8379 hres = pVarPow(&cy, &right, &result);
8380 if (hres == S_OK)
8382 ok(V_VT(&result) == VT_R8,
8383 "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
8384 S_OK, hres, vtstr(V_VT(&result)));
8385 ok(EQ_DOUBLE(V_R8(&result), 4.0),
8386 "VARPOW: CY value %f, expected %f\n", V_R8(&result), 4.0);
8388 else
8390 ok(hres == DISP_E_BADVARTYPE && V_VT(&result) == VT_EMPTY,
8391 "VARPOW: expected coerced hres 0x%X type VT_EMPTY, got hres 0x%X type %s!\n",
8392 DISP_E_BADVARTYPE, hres, vtstr(V_VT(&result)));
8395 hres = pVarPow(&left, &cy, &result);
8396 ok(hres == S_OK && V_VT(&result) == VT_R8,
8397 "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
8398 S_OK, hres, vtstr(V_VT(&result)));
8399 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 10000.0),
8400 "VARPOW: CY value %f, expected %f\n", V_R8(&result), 10000.0);
8402 hres = pVarPow(&left, &dec, &result);
8403 ok(hres == S_OK && V_VT(&result) == VT_R8,
8404 "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
8405 S_OK, hres, vtstr(V_VT(&result)));
8406 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result),10000.0),
8407 "VARPOW: DECIMAL value %f, expected %f\n", V_R8(&result), 10000.0);
8409 hres = pVarPow(&dec, &dec, &result);
8410 ok(hres == S_OK && V_VT(&result) == VT_R8,
8411 "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
8412 S_OK, hres, vtstr(V_VT(&result)));
8413 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 4.0),
8414 "VARPOW: DECIMAL value %f, expected %f\n", V_R8(&result), 4.0);
8416 hres = pVarPow(&dec, &right, &result);
8417 if (hres == S_OK)
8419 ok(V_VT(&result) == VT_R8,
8420 "VARPOW: expected coerced hres 0x%X type VT_R8, got hres 0x%X type %s!\n",
8421 S_OK, hres, vtstr(V_VT(&result)));
8422 ok(EQ_DOUBLE(V_R8(&result), 4.0),
8423 "VARPOW: DECIMAL value %f, expected %f\n", V_R8(&result), 4.0);
8425 else
8427 ok(hres == DISP_E_BADVARTYPE && V_VT(&result) == VT_EMPTY,
8428 "VARPOW: expected coerced hres 0x%X type VT_EMPTY, got hres 0x%X type %s!\n",
8429 DISP_E_BADVARTYPE, hres, vtstr(V_VT(&result)));
8432 SysFreeString(num2_str);
8433 SysFreeString(num3_str);
8436 static HRESULT (WINAPI *pVarDiv)(LPVARIANT,LPVARIANT,LPVARIANT);
8438 #define VARDIV(vt1,val1,vt2,val2,rvt,rval) \
8439 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
8440 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
8441 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
8442 test_var_call2( __LINE__, pVarDiv, &left, &right, &exp )
8444 /* Skip any type that is not defined or produces an error for every case */
8445 #define SKIPTESTDIV(a) \
8446 if (a == VT_ERROR || a == VT_VARIANT || \
8447 a == VT_DISPATCH || a == VT_UNKNOWN || \
8448 a == VT_RECORD || a > VT_UINT || \
8449 a == VT_I1 || a == VT_UI8 || \
8450 a == VT_INT || a == VT_UINT || \
8451 a == VT_UI2 || a == VT_UI4 || \
8452 a == 15 /*not defined*/) \
8453 continue
8455 static void test_VarDiv(void)
8457 static const WCHAR str1[] = { '1','\0' };
8458 static const WCHAR str2[] = { '2','\0' };
8459 VARIANT left, right, exp, result, cy, dec;
8460 BSTR num1_str, num2_str;
8461 VARTYPE i;
8462 HRESULT hres;
8463 double r;
8465 CHECKPTR(VarDiv);
8467 num1_str = SysAllocString(str1);
8468 num2_str = SysAllocString(str2);
8470 /* Test all possible flag/vt combinations & the resulting vt type */
8471 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
8473 VARTYPE leftvt, rightvt, resvt;
8475 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
8477 SKIPTESTDIV(leftvt);
8479 /* Check if we need/have support for I8 */
8480 if (leftvt == VT_I8 && !has_i8)
8481 continue;
8483 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
8485 BOOL bFail = FALSE;
8486 SKIPTESTDIV(rightvt);
8488 /* Check if we need/have support for I8 */
8489 if (rightvt == VT_I8 && !has_i8)
8490 continue;
8492 /* Native crashes with VT_BYREF */
8493 if (ExtraFlags[i] == VT_BYREF)
8494 continue;
8496 memset(&left, 0, sizeof(left));
8497 memset(&right, 0, sizeof(right));
8498 V_VT(&left) = leftvt | ExtraFlags[i];
8499 V_VT(&right) = rightvt | ExtraFlags[i];
8500 V_VT(&result) = VT_EMPTY;
8501 resvt = VT_EMPTY;
8503 if (leftvt == VT_BSTR)
8504 V_BSTR(&left) = num2_str;
8505 else if (leftvt == VT_DECIMAL)
8507 VarDecFromR8(2.0, &V_DECIMAL(&left));
8508 V_VT(&left) = leftvt | ExtraFlags[i];
8511 /* Division by 0 is undefined */
8512 switch(rightvt)
8514 case VT_BSTR:
8515 V_BSTR(&right) = num2_str;
8516 break;
8517 case VT_DECIMAL:
8518 VarDecFromR8(2.0, &V_DECIMAL(&right));
8519 V_VT(&right) = rightvt | ExtraFlags[i];
8520 break;
8521 case VT_BOOL:
8522 V_BOOL(&right) = VARIANT_TRUE;
8523 break;
8524 case VT_I2: V_I2(&right) = 2; break;
8525 case VT_I4: V_I4(&right) = 2; break;
8526 case VT_R4: V_R4(&right) = 2.0f; break;
8527 case VT_R8: V_R8(&right) = 2.0; break;
8528 case VT_CY: V_CY(&right).int64 = 2; break;
8529 case VT_DATE: V_DATE(&right) = 2; break;
8530 case VT_UI1: V_UI1(&right) = 2; break;
8531 case VT_I8: V_I8(&right) = 2; break;
8532 default: break;
8535 /* Determine return type */
8536 if (rightvt != VT_EMPTY)
8538 if (leftvt == VT_NULL || rightvt == VT_NULL)
8539 resvt = VT_NULL;
8540 else if (leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
8541 resvt = VT_DECIMAL;
8542 else if (leftvt == VT_I8 || rightvt == VT_I8 ||
8543 leftvt == VT_CY || rightvt == VT_CY ||
8544 leftvt == VT_DATE || rightvt == VT_DATE ||
8545 leftvt == VT_I4 || rightvt == VT_I4 ||
8546 leftvt == VT_BSTR || rightvt == VT_BSTR ||
8547 leftvt == VT_I2 || rightvt == VT_I2 ||
8548 leftvt == VT_BOOL || rightvt == VT_BOOL ||
8549 leftvt == VT_R8 || rightvt == VT_R8 ||
8550 leftvt == VT_UI1 || rightvt == VT_UI1)
8552 if ((leftvt == VT_UI1 && rightvt == VT_R4) ||
8553 (leftvt == VT_R4 && rightvt == VT_UI1))
8554 resvt = VT_R4;
8555 else if ((leftvt == VT_R4 && (rightvt == VT_BOOL ||
8556 rightvt == VT_I2)) || (rightvt == VT_R4 &&
8557 (leftvt == VT_BOOL || leftvt == VT_I2)))
8558 resvt = VT_R4;
8559 else
8560 resvt = VT_R8;
8562 else if (leftvt == VT_R4 || rightvt == VT_R4)
8563 resvt = VT_R4;
8565 else if (leftvt == VT_NULL)
8566 resvt = VT_NULL;
8567 else
8568 bFail = TRUE;
8570 /* Native VarDiv always returns an error when using extra flags */
8571 if (ExtraFlags[i] != 0)
8572 bFail = TRUE;
8574 hres = pVarDiv(&left, &right, &result);
8576 /* Check expected HRESULT and if result variant type is correct */
8577 if (bFail)
8578 ok (hres == DISP_E_BADVARTYPE || hres == DISP_E_TYPEMISMATCH ||
8579 hres == DISP_E_OVERFLOW || hres == DISP_E_DIVBYZERO,
8580 "VarDiv: %s|0x%X, %s|0x%X: got vt %s hr 0x%X\n",
8581 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i],
8582 vtstr(V_VT(&result)), hres);
8583 else
8584 ok (hres == S_OK && resvt == V_VT(&result),
8585 "VarDiv: %s|0x%X, %s|0x%X: expected vt %s hr 0x%X, got vt %s hr 0x%X\n",
8586 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i], vtstr(resvt),
8587 S_OK, vtstr(V_VT(&result)), hres);
8592 /* Test return values for all the good cases */
8593 VARDIV(EMPTY,0,NULL,0,NULL,0);
8594 VARDIV(EMPTY,0,I2,2,R8,0.0);
8595 VARDIV(EMPTY,0,I4,2,R8,0.0);
8596 VARDIV(EMPTY,0,R4,2.0f,R4,0.0f);
8597 VARDIV(EMPTY,0,R8,2.0,R8,0.0);
8598 VARDIV(EMPTY,0,DATE,2.0,R8,0.0);
8599 VARDIV(EMPTY,0,BSTR,num2_str,R8,0.0);
8600 VARDIV(EMPTY,0,BOOL,VARIANT_TRUE,R8,0.0);
8601 VARDIV(EMPTY,0,UI1,2,R8,0.0);
8602 if (has_i8)
8604 VARDIV(EMPTY,0,I8,2,R8,0.0);
8606 VARDIV(NULL,0,EMPTY,0,NULL,0);
8607 VARDIV(NULL,0,NULL,0,NULL,0);
8608 VARDIV(NULL,0,I2,2,NULL,0);
8609 VARDIV(NULL,0,I4,2,NULL,0);
8610 VARDIV(NULL,0,R4,2.0f,NULL,0);
8611 VARDIV(NULL,0,R8,2.0,NULL,0);
8612 VARDIV(NULL,0,DATE,2,NULL,0);
8613 VARDIV(NULL,0,BSTR,num2_str,NULL,0);
8614 VARDIV(NULL,0,BOOL,VARIANT_TRUE,NULL,0);
8615 VARDIV(NULL,0,UI1,2,NULL,0);
8616 if (has_i8)
8618 VARDIV(NULL,0,I8,2,NULL,0);
8620 VARDIV(I2,2,NULL,0,NULL,0);
8621 VARDIV(I2,1,I2,2,R8,0.5);
8622 VARDIV(I2,1,I4,2,R8,0.5);
8623 VARDIV(I2,1,R4,2,R4,0.5f);
8624 VARDIV(I2,1,R8,2.0,R8,0.5);
8625 VARDIV(I2,1,DATE,2,R8,0.5);
8626 VARDIV(I2,1,BOOL,VARIANT_TRUE,R8,-1.0);
8627 VARDIV(I2,1,UI1,2,R8,0.5);
8628 if (has_i8)
8630 VARDIV(I2,1,I8,2,R8,0.5);
8632 VARDIV(I4,1,NULL,0,NULL,0);
8633 VARDIV(I4,1,I2,2,R8,0.5);
8634 VARDIV(I4,1,I4,2,R8,0.5);
8635 VARDIV(I4,1,R4,2.0f,R8,0.5);
8636 VARDIV(I4,1,R8,2.0,R8,0.5);
8637 VARDIV(I4,1,DATE,2,R8,0.5);
8638 VARDIV(I4,1,BSTR,num2_str,R8,0.5);
8639 VARDIV(I4,1,BOOL,VARIANT_TRUE,R8,-1.0);
8640 VARDIV(I4,1,UI1,2,R8,0.5);
8641 if (has_i8)
8643 VARDIV(I4,1,I8,2,R8,0.5);
8645 VARDIV(R4,1.0f,NULL,0,NULL,0);
8646 VARDIV(R4,1.0f,I2,2,R4,0.5f);
8647 VARDIV(R4,1.0f,I4,2,R8,0.5);
8648 VARDIV(R4,1.0f,R4,2.0f,R4,0.5f);
8649 VARDIV(R4,1.0f,R8,2.0,R8,0.5);
8650 VARDIV(R4,1.0f,DATE,2,R8,0.5);
8651 VARDIV(R4,1.0f,BSTR,num2_str,R8,0.5);
8652 VARDIV(R4,1.0f,BOOL,VARIANT_TRUE,R4,-1);
8653 VARDIV(R4,1.0f,UI1,2,R4,0.5f);
8654 if (has_i8)
8656 VARDIV(R4,1.0f,I8,2,R8,0.5);
8658 VARDIV(R8,1.0,NULL,0,NULL,0);
8659 VARDIV(R8,1.0,I2,2,R8,0.5);
8660 VARDIV(R8,1.0,I4,2,R8,0.5);
8661 VARDIV(R8,1.0,R4,2.0f,R8,0.5);
8662 VARDIV(R8,1.0,R8,2.0,R8,0.5);
8663 VARDIV(R8,1.0,DATE,2,R8,0.5);
8664 VARDIV(R8,1.0,BSTR,num2_str,R8,0.5);
8665 VARDIV(R8,1.0,BOOL,VARIANT_TRUE,R8,-1.0);
8666 VARDIV(R8,1.0,UI1,2,R8,0.5);
8667 if (has_i8)
8669 VARDIV(R8,1.0,I8,2,R8,0.5);
8671 VARDIV(DATE,1,NULL,0,NULL,0);
8672 VARDIV(DATE,1,I2,2,R8,0.5);
8673 VARDIV(DATE,1,I4,2,R8,0.5);
8674 VARDIV(DATE,1,R4,2.0f,R8,0.5);
8675 VARDIV(DATE,1,R8,2.0,R8,0.5);
8676 VARDIV(DATE,1,DATE,2,R8,0.5);
8677 VARDIV(DATE,1,BSTR,num2_str,R8,0.5);
8678 VARDIV(DATE,1,BOOL,VARIANT_TRUE,R8,-1.0);
8679 VARDIV(DATE,1,UI1,2,R8,0.5);
8680 if (has_i8)
8682 VARDIV(DATE,1,I8,2,R8,0.5);
8684 VARDIV(BSTR,num1_str,NULL,0,NULL,0);
8685 VARDIV(BSTR,num1_str,I2,2,R8,0.5);
8686 VARDIV(BSTR,num1_str,I4,2,R8,0.5);
8687 VARDIV(BSTR,num1_str,R4,2.0f,R8,0.5);
8688 VARDIV(BSTR,num1_str,R8,2.0,R8,0.5);
8689 VARDIV(BSTR,num1_str,DATE,2,R8,0.5);
8690 VARDIV(BSTR,num1_str,BSTR,num2_str,R8,0.5);
8691 VARDIV(BSTR,num1_str,BOOL,VARIANT_TRUE,R8,-1);
8692 VARDIV(BSTR,num1_str,UI1,2,R8,0.5);
8693 if (has_i8)
8695 VARDIV(BSTR,num1_str,I8,2,R8,0.5);
8697 VARDIV(BOOL,VARIANT_TRUE,NULL,0,NULL,0);
8698 VARDIV(BOOL,VARIANT_TRUE,I2,1,R8,-1.0);
8699 VARDIV(BOOL,VARIANT_FALSE,I2,1,R8,0.0);
8700 VARDIV(BOOL,VARIANT_TRUE,I4,1,R8,-1.0);
8701 VARDIV(BOOL,VARIANT_FALSE,I4,1,R8,0.0);
8702 VARDIV(BOOL,VARIANT_TRUE,R4,1,R4,-1.0f);
8703 VARDIV(BOOL,VARIANT_FALSE,R4,1,R4,0.0f);
8704 VARDIV(BOOL,VARIANT_TRUE,R8,1.0,R8,-1.0);
8705 VARDIV(BOOL,VARIANT_FALSE,R8,1.0,R8,0.0);
8706 VARDIV(BOOL,VARIANT_FALSE,DATE,2,R8,0.0);
8707 VARDIV(BOOL,VARIANT_FALSE,BSTR,num2_str,R8,0.0);
8708 VARDIV(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,R8,1.0);
8709 VARDIV(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE,R8,0.0);
8710 VARDIV(BOOL,VARIANT_TRUE,UI1,1,R8,-1.0);
8711 if (has_i8)
8713 VARDIV(BOOL,VARIANT_TRUE,I8,1,R8,-1.0);
8715 VARDIV(UI1,1,NULL,0,NULL,0);
8716 VARDIV(UI1,1,I2,2,R8,0.5);
8717 VARDIV(UI1,1,I4,2,R8,0.5);
8718 VARDIV(UI1,1,R4,2.0f,R4,0.5f);
8719 VARDIV(UI1,1,R8,2.0,R8,0.5);
8720 VARDIV(UI1,1,DATE,2,R8,0.5);
8721 VARDIV(UI1,1,BSTR,num2_str,R8,0.5);
8722 VARDIV(UI1,1,BOOL,VARIANT_TRUE,R8,-1);
8723 VARDIV(UI1,1,UI1,2,R8,0.5);
8724 if (has_i8)
8726 VARDIV(UI1,1,I8,2,R8,0.5);
8727 VARDIV(I8,1,NULL,0,NULL,0);
8728 VARDIV(I8,1,I2,2,R8,0.5);
8729 VARDIV(I8,1,I4,2,R8,0.5);
8730 VARDIV(I8,1,R4,2.0f,R8,0.5);
8731 VARDIV(I8,1,R8,2.0,R8,0.5);
8732 VARDIV(I8,1,DATE,2,R8,0.5);
8733 VARDIV(I8,1,BSTR,num2_str,R8,0.5);
8734 VARDIV(I8,1,BOOL,VARIANT_TRUE,R8,-1);
8735 VARDIV(I8,1,UI1,2,R8,0.5);
8736 VARDIV(I8,1,I8,2,R8,0.5);
8739 /* Manually test some VT_CY, VT_DECIMAL variants */
8740 V_VT(&cy) = VT_CY;
8741 hres = VarCyFromI4(10000, &V_CY(&cy));
8742 ok(hres == S_OK, "VarCyFromI4 failed!\n");
8743 V_VT(&dec) = VT_DECIMAL;
8744 hres = VarDecFromR8(2.0, &V_DECIMAL(&dec));
8745 ok(hres == S_OK, "VarDecFromR4 failed!\n");
8746 memset(&left, 0, sizeof(left));
8747 memset(&right, 0, sizeof(right));
8748 V_VT(&left) = VT_I4;
8749 V_I4(&left) = 100;
8750 V_VT(&right) = VT_UI1;
8751 V_UI1(&right) = 2;
8753 hres = pVarDiv(&cy, &cy, &result);
8754 ok(hres == S_OK && V_VT(&result) == VT_R8,
8755 "VARDIV: expected coerced type VT_R8, got %s!\n", vtstr(V_VT(&result)));
8756 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 1.0),
8757 "VARDIV: CY value %f, expected %f\n", V_R8(&result), 1.0);
8759 hres = pVarDiv(&cy, &right, &result);
8760 ok(hres == S_OK && V_VT(&result) == VT_R8,
8761 "VARDIV: expected coerced type VT_R8, got %s!\n", vtstr(V_VT(&result)));
8762 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 5000.0),
8763 "VARDIV: CY value %f, expected %f\n", V_R8(&result), 5000.0);
8765 hres = pVarDiv(&left, &cy, &result);
8766 ok(hres == S_OK && V_VT(&result) == VT_R8,
8767 "VARDIV: expected coerced type VT_R8, got %s!\n", vtstr(V_VT(&result)));
8768 ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 0.01),
8769 "VARDIV: CY value %f, expected %f\n", V_R8(&result), 0.01);
8771 hres = pVarDiv(&left, &dec, &result);
8772 ok(hres == S_OK && V_VT(&result) == VT_DECIMAL,
8773 "VARDIV: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
8774 hres = VarR8FromDec(&V_DECIMAL(&result), &r);
8775 ok(hres == S_OK && EQ_DOUBLE(r, 50.0), "VARDIV: DECIMAL value %f, expected %f\n", r, 50.0);
8777 hres = pVarDiv(&dec, &dec, &result);
8778 ok(hres == S_OK && V_VT(&result) == VT_DECIMAL,
8779 "VARDIV: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
8780 hres = VarR8FromDec(&V_DECIMAL(&result), &r);
8781 ok(hres == S_OK && EQ_DOUBLE(r, 1.0), "VARDIV: DECIMAL value %f, expected %f\n", r, 1.0);
8783 hres = pVarDiv(&dec, &right, &result);
8784 ok(hres == S_OK && V_VT(&result) == VT_DECIMAL,
8785 "VARDIV: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
8786 hres = VarR8FromDec(&V_DECIMAL(&result), &r);
8787 ok(hres == S_OK && EQ_DOUBLE(r, 1.0), "VARDIV: DECIMAL value %f, expected %f\n", r, 1.0);
8789 /* Check for division by zero and overflow */
8790 V_VT(&left) = VT_R8;
8791 V_I4(&left) = 1;
8792 V_VT(&right) = VT_R8;
8793 V_I4(&right) = 0;
8794 hres = pVarDiv(&left, &right, &result);
8795 ok(hres == DISP_E_DIVBYZERO && V_VT(&result) == VT_EMPTY,
8796 "VARDIV: Division by (1.0/0.0) should result in DISP_E_DIVBYZERO but got 0x%X\n", hres);
8798 V_VT(&left) = VT_R8;
8799 V_I4(&left) = 0;
8800 V_VT(&right) = VT_R8;
8801 V_I4(&right) = 0;
8802 hres = pVarDiv(&left, &right, &result);
8803 ok(hres == DISP_E_OVERFLOW && V_VT(&result) == VT_EMPTY,
8804 "VARDIV: Division by (0.0/0.0) should result in DISP_E_OVERFLOW but got 0x%X\n", hres);
8806 SysFreeString(num1_str);
8807 SysFreeString(num2_str);
8810 static HRESULT (WINAPI *pVarIdiv)(LPVARIANT,LPVARIANT,LPVARIANT);
8812 #define VARIDIV(vt1,val1,vt2,val2,rvt,rval) \
8813 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
8814 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
8815 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
8816 test_var_call2( __LINE__, pVarIdiv, &left, &right, &exp )
8818 /* Skip any type that is not defined or produces an error for every case */
8819 #define SKIPTESTIDIV(a) \
8820 if (a == VT_ERROR || a == VT_VARIANT || \
8821 a == VT_DISPATCH || a == VT_UNKNOWN || \
8822 a == VT_RECORD || a > VT_UINT || \
8823 a == 15 /*not defined*/) \
8824 continue
8826 static void test_VarIdiv(void)
8828 static const WCHAR str1[] = { '1','\0' };
8829 static const WCHAR str2[] = { '2','\0' };
8830 VARIANT left, right, exp, result, cy, dec;
8831 BSTR num1_str, num2_str;
8832 VARTYPE i;
8833 HRESULT hres;
8835 CHECKPTR(VarIdiv);
8837 num1_str = SysAllocString(str1);
8838 num2_str = SysAllocString(str2);
8840 /* Test all possible flag/vt combinations & the resulting vt type */
8841 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
8843 VARTYPE leftvt, rightvt, resvt;
8845 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
8847 SKIPTESTIDIV(leftvt);
8849 /* Check if we need/have support for I8 and/or UI8 */
8850 if ((leftvt == VT_I8 || leftvt == VT_UI8) && !has_i8)
8851 continue;
8853 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
8855 BOOL bFail = FALSE;
8856 SKIPTESTIDIV(rightvt);
8858 /* Native crashes with extra flag VT_BYREF */
8859 if (ExtraFlags[i] == VT_BYREF)
8860 continue;
8862 /* Check if we need/have support for I8 and/or UI8 */
8863 if ((rightvt == VT_I8 || rightvt == VT_UI8) && !has_i8)
8864 continue;
8866 memset(&left, 0, sizeof(left));
8867 memset(&right, 0, sizeof(right));
8868 V_VT(&left) = leftvt | ExtraFlags[i];
8869 V_VT(&right) = rightvt | ExtraFlags[i];
8870 V_VT(&result) = VT_EMPTY;
8871 resvt = VT_EMPTY;
8873 if (leftvt == VT_BSTR)
8874 V_BSTR(&left) = num2_str;
8875 else if (leftvt == VT_DECIMAL)
8877 VarDecFromR8(2.0, &V_DECIMAL(&left));
8878 V_VT(&left) = leftvt | ExtraFlags[i];
8881 /* Division by 0 is undefined */
8882 switch(rightvt)
8884 case VT_BSTR:
8885 V_BSTR(&right) = num2_str;
8886 break;
8887 case VT_DECIMAL:
8888 VarDecFromR8(2.0, &V_DECIMAL(&right));
8889 V_VT(&right) = rightvt | ExtraFlags[i];
8890 break;
8891 case VT_BOOL:
8892 V_BOOL(&right) = VARIANT_TRUE;
8893 break;
8894 case VT_CY:
8895 VarCyFromI4(10000, &V_CY(&right));
8896 V_VT(&right) = rightvt | ExtraFlags[i];
8897 break;
8898 case VT_I2: V_I2(&right) = 2; break;
8899 case VT_I4: V_I4(&right) = 2; break;
8900 case VT_R4: V_R4(&right) = 2.0f; break;
8901 case VT_R8: V_R8(&right) = 2.0; break;
8902 case VT_DATE: V_DATE(&right) = 2; break;
8903 case VT_I1: V_I1(&right) = 2; break;
8904 case VT_UI1: V_UI1(&right) = 2; break;
8905 case VT_UI2: V_UI2(&right) = 2; break;
8906 case VT_UI4: V_UI4(&right) = 2; break;
8907 case VT_I8: V_I8(&right) = 2; break;
8908 case VT_UI8: V_UI8(&right) = 2; break;
8909 case VT_INT: V_INT(&right) = 2; break;
8910 case VT_UINT: V_UINT(&right) = 2; break;
8911 default: break;
8914 /* Native VarIdiv always returns an error when using extra
8915 * flags or if the variant combination is I8 and INT.
8917 if ((leftvt == VT_I8 && rightvt == VT_INT) ||
8918 (leftvt == VT_INT && rightvt == VT_I8) ||
8919 (rightvt == VT_EMPTY && leftvt != VT_NULL) ||
8920 ExtraFlags[i] != 0)
8921 bFail = TRUE;
8923 /* Determine variant type */
8924 else if (leftvt == VT_NULL || rightvt == VT_NULL)
8925 resvt = VT_NULL;
8926 else if (leftvt == VT_I8 || rightvt == VT_I8)
8927 resvt = VT_I8;
8928 else if (leftvt == VT_I4 || rightvt == VT_I4 ||
8929 leftvt == VT_INT || rightvt == VT_INT ||
8930 leftvt == VT_UINT || rightvt == VT_UINT ||
8931 leftvt == VT_UI8 || rightvt == VT_UI8 ||
8932 leftvt == VT_UI4 || rightvt == VT_UI4 ||
8933 leftvt == VT_UI2 || rightvt == VT_UI2 ||
8934 leftvt == VT_I1 || rightvt == VT_I1 ||
8935 leftvt == VT_BSTR || rightvt == VT_BSTR ||
8936 leftvt == VT_DATE || rightvt == VT_DATE ||
8937 leftvt == VT_CY || rightvt == VT_CY ||
8938 leftvt == VT_DECIMAL || rightvt == VT_DECIMAL ||
8939 leftvt == VT_R8 || rightvt == VT_R8 ||
8940 leftvt == VT_R4 || rightvt == VT_R4)
8941 resvt = VT_I4;
8942 else if (leftvt == VT_I2 || rightvt == VT_I2 ||
8943 leftvt == VT_BOOL || rightvt == VT_BOOL ||
8944 leftvt == VT_EMPTY)
8945 resvt = VT_I2;
8946 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
8947 resvt = VT_UI1;
8948 else
8949 bFail = TRUE;
8951 hres = pVarIdiv(&left, &right, &result);
8953 /* Check expected HRESULT and if result variant type is correct */
8954 if (bFail)
8955 ok (hres == DISP_E_BADVARTYPE || hres == DISP_E_TYPEMISMATCH ||
8956 hres == DISP_E_DIVBYZERO,
8957 "VarIdiv: %s|0x%X, %s|0x%X: got vt %s hr 0x%X\n",
8958 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i],
8959 vtstr(V_VT(&result)), hres);
8960 else
8961 ok (hres == S_OK && resvt == V_VT(&result),
8962 "VarIdiv: %s|0x%X, %s|0x%X: expected vt %s hr 0x%X, got vt %s hr 0x%X\n",
8963 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i], vtstr(resvt),
8964 S_OK, vtstr(V_VT(&result)), hres);
8969 /* Test return values for all the good cases */
8970 VARIDIV(EMPTY,0,NULL,0,NULL,0);
8971 VARIDIV(EMPTY,0,I2,1,I2,0);
8972 VARIDIV(EMPTY,0,I4,1,I4,0);
8973 VARIDIV(EMPTY,0,R4,1.0f,I4,0);
8974 VARIDIV(EMPTY,0,R8,1.0,I4,0);
8975 VARIDIV(EMPTY,0,DATE,1.0,I4,0);
8976 VARIDIV(EMPTY,0,BSTR,num1_str,I4,0);
8977 VARIDIV(EMPTY,0,BOOL,VARIANT_TRUE,I2,0);
8978 VARIDIV(EMPTY,0,I1,1,I4,0);
8979 VARIDIV(EMPTY,0,UI1,1,I2,0);
8980 VARIDIV(EMPTY,0,UI2,1,I4,0);
8981 VARIDIV(EMPTY,0,UI4,1,I4,0);
8982 if (has_i8)
8984 VARIDIV(EMPTY,0,I8,1,I8,0);
8985 VARIDIV(EMPTY,0,UI8,1,I4,0);
8987 VARIDIV(EMPTY,0,INT,1,I4,0);
8988 VARIDIV(EMPTY,0,UINT,1,I4,0);
8989 VARIDIV(NULL,0,EMPTY,0,NULL,0);
8990 VARIDIV(NULL,0,NULL,0,NULL,0);
8991 VARIDIV(NULL,0,I2,1,NULL,0);
8992 VARIDIV(NULL,0,I4,1,NULL,0);
8993 VARIDIV(NULL,0,R4,1,NULL,0);
8994 VARIDIV(NULL,0,R8,1,NULL,0);
8995 VARIDIV(NULL,0,DATE,1,NULL,0);
8996 VARIDIV(NULL,0,BSTR,num1_str,NULL,0);
8997 VARIDIV(NULL,0,BOOL,VARIANT_TRUE,NULL,0);
8998 VARIDIV(NULL,0,I1,1,NULL,0);
8999 VARIDIV(NULL,0,UI1,1,NULL,0);
9000 VARIDIV(NULL,0,UI2,1,NULL,0);
9001 VARIDIV(NULL,0,UI4,1,NULL,0);
9002 if (has_i8)
9004 VARIDIV(NULL,0,I8,1,NULL,0);
9005 VARIDIV(NULL,0,UI8,1,NULL,0);
9007 VARIDIV(NULL,0,INT,1,NULL,0);
9008 VARIDIV(NULL,0,UINT,1,NULL,0);
9009 VARIDIV(I2,2,NULL,0,NULL,0);
9010 VARIDIV(I2,2,I2,1,I2,2);
9011 VARIDIV(I2,2,I4,1,I4,2);
9012 VARIDIV(I2,2,R4,1,I4,2);
9013 VARIDIV(I2,2,R8,1,I4,2);
9014 VARIDIV(I2,2,DATE,1,I4,2);
9015 VARIDIV(I2,2,BSTR,num1_str,I4,2);
9016 VARIDIV(I2,2,BOOL,VARIANT_TRUE,I2,-2);
9017 VARIDIV(I2,2,I1,1,I4,2);
9018 VARIDIV(I2,2,UI1,1,I2,2);
9019 VARIDIV(I2,2,UI2,1,I4,2);
9020 VARIDIV(I2,2,UI4,1,I4,2);
9021 if (has_i8)
9023 VARIDIV(I2,2,I8,1,I8,2);
9024 VARIDIV(I2,2,UI8,1,I4,2);
9026 VARIDIV(I2,2,INT,1,I4,2);
9027 VARIDIV(I2,2,UINT,1,I4,2);
9028 VARIDIV(I4,2,NULL,0,NULL,0);
9029 VARIDIV(I4,2,I2,1,I4,2);
9030 VARIDIV(I4,2,I4,1,I4,2);
9031 VARIDIV(I4,2,R4,1,I4,2);
9032 VARIDIV(I4,2,R8,1,I4,2);
9033 VARIDIV(I4,2,DATE,1,I4,2);
9034 VARIDIV(I4,2,BSTR,num1_str,I4,2);
9035 VARIDIV(I4,2,BOOL,VARIANT_TRUE,I4,-2);
9036 VARIDIV(I4,2,I1,1,I4,2);
9037 VARIDIV(I4,2,UI1,1,I4,2);
9038 VARIDIV(I4,2,UI2,1,I4,2);
9039 VARIDIV(I4,2,UI4,1,I4,2);
9040 if (has_i8)
9042 VARIDIV(I4,2,I8,1,I8,2);
9043 VARIDIV(I4,2,UI8,1,I4,2);
9045 VARIDIV(I4,2,INT,1,I4,2);
9046 VARIDIV(I4,2,UINT,1,I4,2);
9047 VARIDIV(R4,2.0f,NULL,0,NULL,0);
9048 VARIDIV(R4,2.0f,I2,1,I4,2);
9049 VARIDIV(R4,2.0f,I4,1,I4,2);
9050 VARIDIV(R4,2.0f,R4,1.0f,I4,2);
9051 VARIDIV(R4,2.0f,R8,1.0,I4,2);
9052 VARIDIV(R4,2.0f,DATE,1,I4,2);
9053 VARIDIV(R4,2.0f,BSTR,num1_str,I4,2);
9054 VARIDIV(R4,2.0f,BOOL,VARIANT_TRUE,I4,-2);
9055 VARIDIV(R4,2.0f,I1,1,I4,2);
9056 VARIDIV(R4,2.0f,UI1,1,I4,2);
9057 VARIDIV(R4,2.0f,UI2,1,I4,2);
9058 VARIDIV(R4,2.0f,UI4,1,I4,2);
9059 if (has_i8)
9061 VARIDIV(R4,2.0f,I8,1,I8,2);
9062 VARIDIV(R4,2.0f,UI8,1,I4,2);
9064 VARIDIV(R4,2.0f,INT,1,I4,2);
9065 VARIDIV(R4,2.0f,UINT,1,I4,2);
9066 VARIDIV(R8,2.0,NULL,0,NULL,0);
9067 VARIDIV(R8,2.0,I2,1,I4,2);
9068 VARIDIV(R8,2.0,I4,1,I4,2);
9069 VARIDIV(R8,2.0,R4,1,I4,2);
9070 VARIDIV(R8,2.0,R8,1,I4,2);
9071 VARIDIV(R8,2.0,DATE,1,I4,2);
9072 VARIDIV(R8,2.0,BSTR,num1_str,I4,2);
9073 VARIDIV(R8,2.0,BOOL,VARIANT_TRUE,I4,-2);
9074 VARIDIV(R8,2.0,I1,1,I4,2);
9075 VARIDIV(R8,2.0,UI1,1,I4,2);
9076 VARIDIV(R8,2.0,UI2,1,I4,2);
9077 VARIDIV(R8,2.0,UI4,1,I4,2);
9078 if (has_i8)
9080 VARIDIV(R8,2.0,I8,1,I8,2);
9081 VARIDIV(R8,2.0,UI8,1,I4,2);
9083 VARIDIV(R8,2.0,INT,1,I4,2);
9084 VARIDIV(R8,2.0,UINT,1,I4,2);
9085 VARIDIV(DATE,2,NULL,0,NULL,0);
9086 VARIDIV(DATE,2,I2,1,I4,2);
9087 VARIDIV(DATE,2,I4,1,I4,2);
9088 VARIDIV(DATE,2,R4,1,I4,2);
9089 VARIDIV(DATE,2,R8,1,I4,2);
9090 VARIDIV(DATE,2,DATE,1,I4,2);
9091 VARIDIV(DATE,2,BSTR,num1_str,I4,2);
9092 VARIDIV(DATE,2,BOOL,VARIANT_TRUE,I4,-2);
9093 VARIDIV(DATE,2,I1,1,I4,2);
9094 VARIDIV(DATE,2,UI1,1,I4,2);
9095 VARIDIV(DATE,2,UI2,1,I4,2);
9096 VARIDIV(DATE,2,UI4,1,I4,2);
9097 if (has_i8)
9099 VARIDIV(DATE,2,I8,1,I8,2);
9100 VARIDIV(DATE,2,UI8,1,I4,2);
9102 VARIDIV(DATE,2,INT,1,I4,2);
9103 VARIDIV(DATE,2,UINT,1,I4,2);
9104 VARIDIV(BSTR,num2_str,NULL,0,NULL,0);
9105 VARIDIV(BSTR,num2_str,I2,1,I4,2);
9106 VARIDIV(BSTR,num2_str,I4,1,I4,2);
9107 VARIDIV(BSTR,num2_str,R4,1.0f,I4,2);
9108 VARIDIV(BSTR,num2_str,R8,1.0,I4,2);
9109 VARIDIV(BSTR,num2_str,DATE,1,I4,2);
9110 VARIDIV(BSTR,num2_str,BSTR,num1_str,I4,2);
9111 VARIDIV(BSTR,num2_str,BOOL,VARIANT_TRUE,I4,-2);
9112 VARIDIV(BSTR,num2_str,I1,1,I4,2);
9113 VARIDIV(BSTR,num2_str,UI1,1,I4,2);
9114 VARIDIV(BSTR,num2_str,UI2,1,I4,2);
9115 VARIDIV(BSTR,num2_str,UI4,1,I4,2);
9116 if (has_i8)
9118 VARIDIV(BSTR,num2_str,I8,1,I8,2);
9119 VARIDIV(BSTR,num2_str,UI8,1,I4,2);
9121 VARIDIV(BSTR,num2_str,INT,1,I4,2);
9122 VARIDIV(BSTR,num2_str,UINT,1,I4,2);
9123 VARIDIV(BOOL,VARIANT_TRUE,NULL,0,NULL,0);
9124 VARIDIV(BOOL,VARIANT_TRUE,I2,1,I2,-1);
9125 VARIDIV(BOOL,VARIANT_TRUE,I4,1,I4,-1);
9126 VARIDIV(BOOL,VARIANT_TRUE,R4,1.0f,I4,-1);
9127 VARIDIV(BOOL,VARIANT_TRUE,R8,1.0,I4,-1);
9128 VARIDIV(BOOL,VARIANT_TRUE,DATE,1,I4,-1);
9129 VARIDIV(BOOL,VARIANT_TRUE,BSTR,num1_str,I4,-1);
9130 VARIDIV(BOOL,VARIANT_TRUE,BOOL,VARIANT_TRUE,I2,1);
9131 VARIDIV(BOOL,VARIANT_TRUE,I1,1,I4,-1);
9132 VARIDIV(BOOL,VARIANT_TRUE,UI1,1,I2,-1);
9133 VARIDIV(BOOL,VARIANT_TRUE,UI2,1,I4,-1);
9134 VARIDIV(BOOL,VARIANT_TRUE,UI4,1,I4,-1);
9135 if (has_i8)
9137 VARIDIV(BOOL,VARIANT_TRUE,I8,1,I8,-1);
9138 VARIDIV(BOOL,VARIANT_TRUE,UI8,1,I4,-1);
9140 VARIDIV(BOOL,VARIANT_TRUE,INT,1,I4,-1);
9141 VARIDIV(BOOL,VARIANT_TRUE,UINT,1,I4,-1);
9142 VARIDIV(I1,2,NULL,0,NULL,0);
9143 VARIDIV(I1,2,I2,1,I4,2);
9144 VARIDIV(I1,2,I4,1,I4,2);
9145 VARIDIV(I1,2,R4,1.0f,I4,2);
9146 VARIDIV(I1,2,R8,1.0,I4,2);
9147 VARIDIV(I1,2,DATE,1,I4,2);
9148 VARIDIV(I1,2,BSTR,num1_str,I4,2);
9149 VARIDIV(I1,2,BOOL,VARIANT_TRUE,I4,-2);
9150 VARIDIV(I1,2,I1,1,I4,2);
9151 VARIDIV(I1,2,UI1,1,I4,2);
9152 VARIDIV(I1,2,UI2,1,I4,2);
9153 VARIDIV(I1,2,UI4,1,I4,2);
9154 if (has_i8)
9156 VARIDIV(I1,2,I8,1,I8,2);
9157 VARIDIV(I1,2,UI8,1,I4,2);
9159 VARIDIV(I1,2,INT,1,I4,2);
9160 VARIDIV(I1,2,UINT,1,I4,2);
9161 VARIDIV(UI1,2,NULL,0,NULL,0);
9162 VARIDIV(UI1,2,I2,1,I2,2);
9163 VARIDIV(UI1,2,I4,1,I4,2);
9164 VARIDIV(UI1,2,R4,1.0f,I4,2);
9165 VARIDIV(UI1,2,R8,1.0,I4,2);
9166 VARIDIV(UI1,2,DATE,1,I4,2);
9167 VARIDIV(UI1,2,BSTR,num1_str,I4,2);
9168 VARIDIV(UI1,2,BOOL,VARIANT_TRUE,I2,-2);
9169 VARIDIV(UI1,2,I1,1,I4,2);
9170 VARIDIV(UI1,2,UI1,1,UI1,2);
9171 VARIDIV(UI1,2,UI2,1,I4,2);
9172 VARIDIV(UI1,2,UI4,1,I4,2);
9173 if (has_i8)
9175 VARIDIV(UI1,2,I8,1,I8,2);
9176 VARIDIV(UI1,2,UI8,1,I4,2);
9178 VARIDIV(UI1,2,INT,1,I4,2);
9179 VARIDIV(UI1,2,UINT,1,I4,2);
9180 VARIDIV(UI2,2,NULL,0,NULL,0);
9181 VARIDIV(UI2,2,I2,1,I4,2);
9182 VARIDIV(UI2,2,I4,1,I4,2);
9183 VARIDIV(UI2,2,R4,1.0f,I4,2);
9184 VARIDIV(UI2,2,R8,1.0,I4,2);
9185 VARIDIV(UI2,2,DATE,1,I4,2);
9186 VARIDIV(UI2,2,BSTR,num1_str,I4,2);
9187 VARIDIV(UI2,2,BOOL,VARIANT_TRUE,I4,-2);
9188 VARIDIV(UI2,2,I1,1,I4,2);
9189 VARIDIV(UI2,2,UI1,1,I4,2);
9190 VARIDIV(UI2,2,UI2,1,I4,2);
9191 VARIDIV(UI2,2,UI4,1,I4,2);
9192 if (has_i8)
9194 VARIDIV(UI2,2,I8,1,I8,2);
9195 VARIDIV(UI2,2,UI8,1,I4,2);
9197 VARIDIV(UI2,2,INT,1,I4,2);
9198 VARIDIV(UI2,2,UINT,1,I4,2);
9199 VARIDIV(UI4,2,NULL,0,NULL,0);
9200 VARIDIV(UI4,2,I2,1,I4,2);
9201 VARIDIV(UI4,2,I4,1,I4,2);
9202 VARIDIV(UI4,2,R4,1.0f,I4,2);
9203 VARIDIV(UI4,2,R8,1.0,I4,2);
9204 VARIDIV(UI4,2,DATE,1,I4,2);
9205 VARIDIV(UI4,2,BSTR,num1_str,I4,2);
9206 VARIDIV(UI4,2,BOOL,VARIANT_TRUE,I4,-2);
9207 VARIDIV(UI4,2,I1,1,I4,2);
9208 VARIDIV(UI4,2,UI1,1,I4,2);
9209 VARIDIV(UI4,2,UI2,1,I4,2);
9210 VARIDIV(UI4,2,UI4,1,I4,2);
9211 if (has_i8)
9213 VARIDIV(UI4,2,I8,1,I8,2);
9214 VARIDIV(UI4,2,UI8,1,I4,2);
9216 VARIDIV(UI4,2,INT,1,I4,2);
9217 VARIDIV(UI4,2,UINT,1,I4,2);
9218 if (has_i8)
9220 VARIDIV(I8,2,NULL,0,NULL,0);
9221 VARIDIV(I8,2,I2,1,I8,2);
9222 VARIDIV(I8,2,I4,1,I8,2);
9223 VARIDIV(I8,2,R4,1.0f,I8,2);
9224 VARIDIV(I8,2,R8,1.0,I8,2);
9225 VARIDIV(I8,2,DATE,1,I8,2);
9226 VARIDIV(I8,2,BSTR,num1_str,I8,2);
9227 VARIDIV(I8,2,BOOL,1,I8,2);
9228 VARIDIV(I8,2,I1,1,I8,2);
9229 VARIDIV(I8,2,UI1,1,I8,2);
9230 VARIDIV(I8,2,UI2,1,I8,2);
9231 VARIDIV(I8,2,UI4,1,I8,2);
9232 VARIDIV(I8,2,I8,1,I8,2);
9233 VARIDIV(I8,2,UI8,1,I8,2);
9234 VARIDIV(I8,2,UINT,1,I8,2);
9235 VARIDIV(UI8,2,NULL,0,NULL,0);
9236 VARIDIV(UI8,2,I2,1,I4,2);
9237 VARIDIV(UI8,2,I4,1,I4,2);
9238 VARIDIV(UI8,2,R4,1.0f,I4,2);
9239 VARIDIV(UI8,2,R8,1.0,I4,2);
9240 VARIDIV(UI8,2,DATE,1,I4,2);
9241 VARIDIV(UI8,2,BSTR,num1_str,I4,2);
9242 VARIDIV(UI8,2,BOOL,VARIANT_TRUE,I4,-2);
9243 VARIDIV(UI8,2,I1,1,I4,2);
9244 VARIDIV(UI8,2,UI1,1,I4,2);
9245 VARIDIV(UI8,2,UI2,1,I4,2);
9246 VARIDIV(UI8,2,UI4,1,I4,2);
9247 VARIDIV(UI8,2,I8,1,I8,2);
9248 VARIDIV(UI8,2,UI8,1,I4,2);
9249 VARIDIV(UI8,2,INT,1,I4,2);
9250 VARIDIV(UI8,2,UINT,1,I4,2);
9252 VARIDIV(INT,2,NULL,0,NULL,0);
9253 VARIDIV(INT,2,I2,1,I4,2);
9254 VARIDIV(INT,2,I4,1,I4,2);
9255 VARIDIV(INT,2,R4,1.0f,I4,2);
9256 VARIDIV(INT,2,R8,1.0,I4,2);
9257 VARIDIV(INT,2,DATE,1,I4,2);
9258 VARIDIV(INT,2,BSTR,num1_str,I4,2);
9259 VARIDIV(INT,2,BOOL,VARIANT_TRUE,I4,-2);
9260 VARIDIV(INT,2,I1,1,I4,2);
9261 VARIDIV(INT,2,UI1,1,I4,2);
9262 VARIDIV(INT,2,UI2,1,I4,2);
9263 VARIDIV(INT,2,UI4,1,I4,2);
9264 if (has_i8)
9266 VARIDIV(INT,2,UI8,1,I4,2);
9268 VARIDIV(INT,2,INT,1,I4,2);
9269 VARIDIV(INT,2,UINT,1,I4,2);
9270 VARIDIV(UINT,2,NULL,0,NULL,0);
9271 VARIDIV(UINT,2,I2,1,I4,2);
9272 VARIDIV(UINT,2,I4,1,I4,2);
9273 VARIDIV(UINT,2,R4,1.0f,I4,2);
9274 VARIDIV(UINT,2,R8,1.0,I4,2);
9275 VARIDIV(UINT,2,DATE,1,I4,2);
9276 VARIDIV(UINT,2,BSTR,num1_str,I4,2);
9277 VARIDIV(UINT,2,BOOL,VARIANT_TRUE,I4,-2);
9278 VARIDIV(UINT,2,I1,1,I4,2);
9279 VARIDIV(UINT,2,UI1,1,I4,2);
9280 VARIDIV(UINT,2,UI2,1,I4,2);
9281 VARIDIV(UINT,2,UI4,1,I4,2);
9282 if (has_i8)
9284 VARIDIV(UINT,2,I8,1,I8,2);
9285 VARIDIV(UINT,2,UI8,1,I4,2);
9287 VARIDIV(UINT,2,INT,1,I4,2);
9288 VARIDIV(UINT,2,UINT,1,I4,2);
9290 /* Manually test some VT_CY, VT_DECIMAL variants */
9291 V_VT(&cy) = VT_CY;
9292 hres = VarCyFromI4(10000, &V_CY(&cy));
9293 ok(hres == S_OK, "VarCyFromI4 failed!\n");
9294 V_VT(&dec) = VT_DECIMAL;
9295 hres = VarDecFromR8(2.0, &V_DECIMAL(&dec));
9296 ok(hres == S_OK, "VarDecFromR4 failed!\n");
9297 memset(&left, 0, sizeof(left));
9298 memset(&right, 0, sizeof(right));
9299 V_VT(&left) = VT_I4;
9300 V_I4(&left) = 100;
9301 V_VT(&right) = VT_I8;
9302 V_UI1(&right) = 2;
9304 hres = pVarIdiv(&cy, &cy, &result);
9305 ok(hres == S_OK && V_VT(&result) == VT_I4,
9306 "VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9307 S_OK, hres, vtstr(V_VT(&result)));
9308 ok(hres == S_OK && V_I4(&result) == 1,
9309 "VARIDIV: CY value %d, expected %d\n", V_I4(&result), 1);
9311 if (has_i8)
9313 hres = pVarIdiv(&cy, &right, &result);
9314 ok(hres == S_OK && V_VT(&result) == VT_I8,
9315 "VARIDIV: expected coerced hres 0x%X type VT_I8, got hres 0x%X type %s!\n",
9316 S_OK, hres, vtstr(V_VT(&result)));
9317 ok(hres == S_OK && V_I8(&result) == 5000,
9318 "VARIDIV: CY value 0x%x%08x, expected 0x%x\n",
9319 (DWORD)(V_I8(&result) >>32), (DWORD)V_I8(&result), 5000);
9322 hres = pVarIdiv(&left, &cy, &result);
9323 ok(hres == S_OK && V_VT(&result) == VT_I4,
9324 "VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9325 S_OK, hres, vtstr(V_VT(&result)));
9326 ok(hres == S_OK && V_I4(&result) == 0,
9327 "VARIDIV: CY value %d, expected %d\n", V_I4(&result), 0);
9329 hres = pVarIdiv(&left, &dec, &result);
9330 ok(hres == S_OK && V_VT(&result) == VT_I4,
9331 "VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9332 S_OK, hres, vtstr(V_VT(&result)));
9333 ok(hres == S_OK && V_I4(&result) == 50,
9334 "VARIDIV: DECIMAL value %d, expected %d\n", V_I4(&result), 50);
9336 hres = pVarIdiv(&dec, &dec, &result);
9337 ok(hres == S_OK && V_VT(&result) == VT_I4,
9338 "VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9339 S_OK, hres, vtstr(V_VT(&result)));
9340 ok(hres == S_OK && V_I4(&result) == 1,
9341 "VARIDIV: DECIMAL value %d, expected %d\n", V_I4(&result), 1);
9343 if (has_i8)
9345 hres = pVarIdiv(&dec, &right, &result);
9346 ok(hres == S_OK && V_VT(&result) == VT_I8,
9347 "VARIDIV: expected coerced hres 0x%X type VT_I8, got hres 0x%X type %s!\n",
9348 S_OK, hres, vtstr(V_VT(&result)));
9349 ok(hres == S_OK && V_I8(&result) == 1,
9350 "VARIDIV: DECIMAL value 0x%x%08x, expected %d\n",
9351 (DWORD)(V_I8(&result) >> 32), (DWORD)V_I8(&result), 1);
9354 /* Check for division by zero */
9355 V_VT(&left) = VT_INT;
9356 V_I4(&left) = 1;
9357 V_VT(&right) = VT_INT;
9358 V_I4(&right) = 0;
9359 hres = pVarIdiv(&left, &right, &result);
9360 ok(hres == DISP_E_DIVBYZERO && V_VT(&result) == VT_EMPTY,
9361 "VARIDIV: Division by 0 should result in DISP_E_DIVBYZERO but got 0x%X\n", hres);
9363 V_VT(&left) = VT_INT;
9364 V_I4(&left) = 0;
9365 V_VT(&right) = VT_INT;
9366 V_I4(&right) = 0;
9367 hres = pVarIdiv(&left, &right, &result);
9368 ok(hres == DISP_E_DIVBYZERO && V_VT(&result) == VT_EMPTY,
9369 "VARIDIV: Division by 0 should result in DISP_E_DIVBYZERO but got 0x%X\n", hres);
9371 SysFreeString(num1_str);
9372 SysFreeString(num2_str);
9376 static HRESULT (WINAPI *pVarImp)(LPVARIANT,LPVARIANT,LPVARIANT);
9378 #define VARIMP(vt1,val1,vt2,val2,rvt,rval) \
9379 V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
9380 V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
9381 V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
9382 test_var_call2( __LINE__, pVarImp, &left, &right, &exp )
9384 /* Skip any type that is not defined or produces an error for every case */
9385 #define SKIPTESTIMP(a) \
9386 if (a == VT_ERROR || a == VT_VARIANT || \
9387 a == VT_DISPATCH || a == VT_UNKNOWN || \
9388 a == VT_RECORD || a > VT_UINT || \
9389 a == 15 /*not defined*/) \
9390 continue
9392 static void test_VarImp(void)
9394 static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
9395 static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
9396 VARIANT left, right, exp, result, cy, dec;
9397 BSTR true_str, false_str;
9398 VARTYPE i;
9399 HRESULT hres;
9401 CHECKPTR(VarImp);
9403 true_str = SysAllocString(szTrue);
9404 false_str = SysAllocString(szFalse);
9406 /* Test all possible flag/vt combinations & the resulting vt type */
9407 for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
9409 VARTYPE leftvt, rightvt, resvt;
9411 for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
9413 SKIPTESTIMP(leftvt);
9415 /* Check if we need/have support for I8 and/or UI8 */
9416 if ((leftvt == VT_I8 || leftvt == VT_UI8) && !has_i8)
9417 continue;
9419 for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
9421 BOOL bFail = FALSE;
9422 SKIPTESTIMP(rightvt);
9424 /* Native crashes when using the extra flag VT_BYREF
9425 * or with the following VT combinations
9427 if ((leftvt == VT_UI4 && rightvt == VT_BSTR) ||
9428 (leftvt == VT_UI8 && rightvt == VT_BSTR) ||
9429 ExtraFlags[i] == VT_BYREF)
9430 continue;
9432 /* Check if we need/have support for I8 and/or UI8 */
9433 if ((rightvt == VT_I8 || rightvt == VT_UI8) && !has_i8)
9434 continue;
9436 memset(&left, 0, sizeof(left));
9437 memset(&right, 0, sizeof(right));
9438 V_VT(&left) = leftvt | ExtraFlags[i];
9439 V_VT(&right) = rightvt | ExtraFlags[i];
9440 V_VT(&result) = VT_EMPTY;
9441 resvt = VT_EMPTY;
9443 if (leftvt == VT_BSTR)
9444 V_BSTR(&left) = true_str;
9446 /* This allows us to test return types that are not NULL
9447 * (NULL Imp value = n, NULL Imp 0 = NULL)
9449 switch(rightvt)
9451 case VT_BSTR:
9452 V_BSTR(&right) = true_str;
9453 break;
9454 case VT_DECIMAL:
9455 VarDecFromR8(2.0, &V_DECIMAL(&right));
9456 V_VT(&right) = rightvt | ExtraFlags[i];
9457 break;
9458 case VT_BOOL:
9459 V_BOOL(&right) = VARIANT_TRUE;
9460 break;
9461 case VT_I1: V_I1(&right) = 2; break;
9462 case VT_I2: V_I2(&right) = 2; break;
9463 case VT_I4: V_I4(&right) = 2; break;
9464 case VT_R4: V_R4(&right) = 2.0f; break;
9465 case VT_R8: V_R8(&right) = 2.0; break;
9466 case VT_CY: V_CY(&right).int64 = 10000; break;
9467 case VT_DATE: V_DATE(&right) = 2; break;
9468 case VT_I8: V_I8(&right) = 2; break;
9469 case VT_INT: V_INT(&right) = 2; break;
9470 case VT_UINT: V_UINT(&right) = 2; break;
9471 case VT_UI1: V_UI1(&right) = 2; break;
9472 case VT_UI2: V_UI2(&right) = 2; break;
9473 case VT_UI4: V_UI4(&right) = 2; break;
9474 case VT_UI8: V_UI8(&right) = 2; break;
9475 default: break;
9478 /* Native VarImp always returns an error when using extra
9479 * flags or if the variants are I8 and INT.
9481 if ((leftvt == VT_I8 && rightvt == VT_INT) ||
9482 ExtraFlags[i] != 0)
9483 bFail = TRUE;
9485 /* Determine result type */
9486 else if ((leftvt == VT_BSTR && rightvt == VT_NULL) ||
9487 (leftvt == VT_NULL && rightvt == VT_NULL) ||
9488 (leftvt == VT_NULL && rightvt == VT_EMPTY))
9489 resvt = VT_NULL;
9490 else if (leftvt == VT_I8 || rightvt == VT_I8)
9491 resvt = VT_I8;
9492 else if (leftvt == VT_I4 || rightvt == VT_I4 ||
9493 leftvt == VT_INT || rightvt == VT_INT ||
9494 leftvt == VT_UINT || rightvt == VT_UINT ||
9495 leftvt == VT_UI4 || rightvt == VT_UI4 ||
9496 leftvt == VT_UI8 || rightvt == VT_UI8 ||
9497 leftvt == VT_UI2 || rightvt == VT_UI2 ||
9498 leftvt == VT_DECIMAL || rightvt == VT_DECIMAL ||
9499 leftvt == VT_DATE || rightvt == VT_DATE ||
9500 leftvt == VT_CY || rightvt == VT_CY ||
9501 leftvt == VT_R8 || rightvt == VT_R8 ||
9502 leftvt == VT_R4 || rightvt == VT_R4 ||
9503 leftvt == VT_I1 || rightvt == VT_I1)
9504 resvt = VT_I4;
9505 else if ((leftvt == VT_UI1 && rightvt == VT_UI1) ||
9506 (leftvt == VT_UI1 && rightvt == VT_NULL) ||
9507 (leftvt == VT_NULL && rightvt == VT_UI1))
9508 resvt = VT_UI1;
9509 else if (leftvt == VT_EMPTY || rightvt == VT_EMPTY ||
9510 leftvt == VT_I2 || rightvt == VT_I2 ||
9511 leftvt == VT_UI1 || rightvt == VT_UI1)
9512 resvt = VT_I2;
9513 else if (leftvt == VT_BOOL || rightvt == VT_BOOL ||
9514 leftvt == VT_BSTR || rightvt == VT_BSTR)
9515 resvt = VT_BOOL;
9517 hres = pVarImp(&left, &right, &result);
9519 /* Check expected HRESULT and if result variant type is correct */
9520 if (bFail)
9521 ok (hres == DISP_E_BADVARTYPE || hres == DISP_E_TYPEMISMATCH,
9522 "VarImp: %s|0x%X, %s|0x%X: got vt %s hr 0x%X\n",
9523 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i],
9524 vtstr(V_VT(&result)), hres);
9525 else
9526 ok (hres == S_OK && resvt == V_VT(&result),
9527 "VarImp: %s|0x%X, %s|0x%X: expected vt %s hr 0x%X, got vt %s hr 0x%X\n",
9528 vtstr(leftvt), ExtraFlags[i], vtstr(rightvt), ExtraFlags[i], vtstr(resvt),
9529 S_OK, vtstr(V_VT(&result)), hres);
9534 VARIMP(EMPTY,0,EMPTY,0,I2,-1);
9535 VARIMP(EMPTY,0,NULL,0,I2,-1);
9536 VARIMP(EMPTY,0,I2,-1,I2,-1);
9537 VARIMP(EMPTY,0,I4,-1,I4,-1);
9538 VARIMP(EMPTY,0,R4,0.0f,I4,-1);
9539 VARIMP(EMPTY,0,R8,-1.0,I4,-1);
9540 VARIMP(EMPTY,0,DATE,0,I4,-1);
9541 VARIMP(EMPTY,0,BSTR,true_str,I2,-1);
9542 VARIMP(EMPTY,0,BOOL,VARIANT_FALSE,I2,-1);
9543 VARIMP(EMPTY,0,I1,0,I4,-1);
9544 VARIMP(EMPTY,0,UI1,1,I2,-1);
9545 VARIMP(EMPTY,0,UI2,1,I4,-1);
9546 VARIMP(EMPTY,0,UI4,1,I4,-1);
9547 if (has_i8)
9549 VARIMP(EMPTY,0,I8,1,I8,-1);
9550 VARIMP(EMPTY,0,UI8,1,I4,-1);
9552 VARIMP(EMPTY,0,INT,-1,I4,-1);
9553 VARIMP(EMPTY,0,UINT,1,I4,-1);
9554 VARIMP(NULL,0,EMPTY,0,NULL,0);
9555 VARIMP(NULL,0,NULL,0,NULL,0);
9556 VARIMP(NULL,0,I2,-1,I2,-1);
9557 VARIMP(NULL,0,I4,-1,I4,-1);
9558 VARIMP(NULL,0,R4,0.0f,NULL,0);
9559 VARIMP(NULL,0,R8,-1.0,I4,-1);
9560 VARIMP(NULL,0,DATE,0,NULL,0);
9561 VARIMP(NULL,0,BSTR,true_str,BOOL,-1);
9562 VARIMP(NULL,0,BOOL,VARIANT_FALSE,NULL,0);
9563 VARIMP(NULL,0,I1,0,NULL,0);
9564 VARIMP(NULL,0,UI1,1,UI1,1);
9565 VARIMP(NULL,0,UI2,1,I4,1);
9566 VARIMP(NULL,0,UI4,1,I4,1);
9567 if (has_i8)
9569 VARIMP(NULL,0,I8,1,I8,1);
9570 VARIMP(NULL,0,UI8,1,I4,1);
9572 VARIMP(NULL,0,INT,-1,I4,-1);
9573 VARIMP(NULL,0,UINT,1,I4,1);
9574 VARIMP(I2,-1,EMPTY,0,I2,0);
9575 VARIMP(I2,-1,I2,-1,I2,-1);
9576 VARIMP(I2,-1,I4,-1,I4,-1);
9577 VARIMP(I2,-1,R4,0.0f,I4,0);
9578 VARIMP(I2,-1,R8,-1.0,I4,-1);
9579 VARIMP(I2,-1,DATE,0,I4,0);
9580 VARIMP(I2,-1,BSTR,true_str,I2,-1);
9581 VARIMP(I2,-1,BOOL,VARIANT_FALSE,I2,0);
9582 VARIMP(I2,-1,I1,0,I4,0);
9583 VARIMP(I2,-1,UI1,1,I2,1);
9584 VARIMP(I2,-1,UI2,1,I4,1);
9585 VARIMP(I2,-1,UI4,1,I4,1);
9586 if (has_i8)
9588 VARIMP(I2,-1,I8,1,I8,1);
9589 VARIMP(I2,-1,UI8,1,I4,1);
9591 VARIMP(I2,-1,INT,-1,I4,-1);
9592 VARIMP(I2,-1,UINT,1,I4,1);
9593 VARIMP(I4,2,EMPTY,0,I4,-3);
9594 VARIMP(I4,2,NULL,0,I4,-3);
9595 VARIMP(I4,2,I2,-1,I4,-1);
9596 VARIMP(I4,2,I4,-1,I4,-1);
9597 VARIMP(I4,2,R4,0.0f,I4,-3);
9598 VARIMP(I4,2,R8,-1.0,I4,-1);
9599 VARIMP(I4,2,DATE,0,I4,-3);
9600 VARIMP(I4,2,BSTR,true_str,I4,-1);
9601 VARIMP(I4,2,BOOL,VARIANT_FALSE,I4,-3);
9602 VARIMP(I4,2,I1,0,I4,-3);
9603 VARIMP(I4,2,UI1,1,I4,-3);
9604 VARIMP(I4,2,UI2,1,I4,-3);
9605 VARIMP(I4,2,UI4,1,I4,-3);
9606 if (has_i8)
9608 VARIMP(I4,2,I8,1,I8,-3);
9609 VARIMP(I4,2,UI8,1,I4,-3);
9611 VARIMP(I4,2,INT,-1,I4,-1);
9612 VARIMP(I4,2,UINT,1,I4,-3);
9613 VARIMP(R4,-1.0f,EMPTY,0,I4,0);
9614 VARIMP(R4,-1.0f,NULL,0,NULL,0);
9615 VARIMP(R4,-1.0f,I2,-1,I4,-1);
9616 VARIMP(R4,-1.0f,I4,-1,I4,-1);
9617 VARIMP(R4,-1.0f,R4,0.0f,I4,0);
9618 VARIMP(R4,-1.0f,R8,-1.0,I4,-1);
9619 VARIMP(R4,-1.0f,DATE,1,I4,1);
9620 VARIMP(R4,-1.0f,BSTR,true_str,I4,-1);
9621 VARIMP(R4,-1.0f,BOOL,VARIANT_FALSE,I4,0);
9622 VARIMP(R4,-1.0f,I1,0,I4,0);
9623 VARIMP(R4,-1.0f,UI1,1,I4,1);
9624 VARIMP(R4,-1.0f,UI2,1,I4,1);
9625 VARIMP(R4,-1.0f,UI4,1,I4,1);
9626 if (has_i8)
9628 VARIMP(R4,-1.0f,I8,1,I8,1);
9629 VARIMP(R4,-1.0f,UI8,1,I4,1);
9631 VARIMP(R4,-1.0f,INT,-1,I4,-1);
9632 VARIMP(R4,-1.0f,UINT,1,I4,1);
9633 VARIMP(R8,1.0,EMPTY,0,I4,-2);
9634 VARIMP(R8,1.0,NULL,0,I4,-2);
9635 VARIMP(R8,1.0,I2,-1,I4,-1);
9636 VARIMP(R8,1.0,I4,-1,I4,-1);
9637 VARIMP(R8,1.0,R4,0.0f,I4,-2);
9638 VARIMP(R8,1.0,R8,-1.0,I4,-1);
9639 VARIMP(R8,1.0,DATE,0,I4,-2);
9640 VARIMP(R8,1.0,BSTR,true_str,I4,-1);
9641 VARIMP(R8,1.0,BOOL,VARIANT_FALSE,I4,-2);
9642 VARIMP(R8,1.0,I1,0,I4,-2);
9643 VARIMP(R8,1.0,UI1,1,I4,-1);
9644 VARIMP(R8,1.0,UI2,1,I4,-1);
9645 VARIMP(R8,1.0,UI4,1,I4,-1);
9646 if (has_i8)
9648 VARIMP(R8,1.0,I8,1,I8,-1);
9649 VARIMP(R8,1.0,UI8,1,I4,-1);
9651 VARIMP(R8,1.0,INT,-1,I4,-1);
9652 VARIMP(R8,1.0,UINT,1,I4,-1);
9653 VARIMP(DATE,0,EMPTY,0,I4,-1);
9654 VARIMP(DATE,0,NULL,0,I4,-1);
9655 VARIMP(DATE,0,I2,-1,I4,-1);
9656 VARIMP(DATE,0,I4,-1,I4,-1);
9657 VARIMP(DATE,0,R4,0.0f,I4,-1);
9658 VARIMP(DATE,0,R8,-1.0,I4,-1);
9659 VARIMP(DATE,0,DATE,0,I4,-1);
9660 VARIMP(DATE,0,BSTR,true_str,I4,-1);
9661 VARIMP(DATE,0,BOOL,VARIANT_FALSE,I4,-1);
9662 VARIMP(DATE,0,I1,0,I4,-1);
9663 VARIMP(DATE,0,UI1,1,I4,-1);
9664 VARIMP(DATE,0,UI2,1,I4,-1);
9665 VARIMP(DATE,0,UI4,1,I4,-1);
9666 if (has_i8)
9668 VARIMP(DATE,0,I8,1,I8,-1);
9669 VARIMP(DATE,0,UI8,1,I4,-1);
9671 VARIMP(DATE,0,INT,-1,I4,-1);
9672 VARIMP(DATE,0,UINT,1,I4,-1);
9673 VARIMP(BSTR,false_str,EMPTY,0,I2,-1);
9674 VARIMP(BSTR,false_str,NULL,0,BOOL,-1);
9675 VARIMP(BSTR,false_str,I2,-1,I2,-1);
9676 VARIMP(BSTR,false_str,I4,-1,I4,-1);
9677 VARIMP(BSTR,false_str,R4,0.0f,I4,-1);
9678 VARIMP(BSTR,false_str,R8,-1.0,I4,-1);
9679 VARIMP(BSTR,false_str,DATE,0,I4,-1);
9680 VARIMP(BSTR,false_str,BSTR,true_str,BOOL,-1);
9681 VARIMP(BSTR,false_str,BOOL,VARIANT_FALSE,BOOL,-1);
9682 VARIMP(BSTR,false_str,I1,0,I4,-1);
9683 VARIMP(BSTR,false_str,UI1,1,I2,-1);
9684 VARIMP(BSTR,false_str,UI2,1,I4,-1);
9685 VARIMP(BSTR,false_str,UI4,1,I4,-1);
9686 if (has_i8)
9688 VARIMP(BSTR,false_str,I8,1,I8,-1);
9689 VARIMP(BSTR,false_str,UI8,1,I4,-1);
9691 VARIMP(BSTR,false_str,INT,-1,I4,-1);
9692 VARIMP(BSTR,false_str,UINT,1,I4,-1);
9693 VARIMP(BOOL,VARIANT_TRUE,EMPTY,0,I2,0);
9694 VARIMP(BOOL,VARIANT_TRUE,NULL,0,NULL,0);
9695 VARIMP(BOOL,VARIANT_TRUE,I2,-1,I2,-1);
9696 VARIMP(BOOL,VARIANT_TRUE,I4,-1,I4,-1);
9697 VARIMP(BOOL,VARIANT_TRUE,R4,0.0f,I4,0);
9698 VARIMP(BOOL,VARIANT_TRUE,R8,-1.0,I4,-1);
9699 VARIMP(BOOL,VARIANT_TRUE,DATE,0,I4,0);
9700 VARIMP(BOOL,VARIANT_TRUE,BSTR,true_str,BOOL,-1);
9701 VARIMP(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE,BOOL,0);
9702 VARIMP(BOOL,VARIANT_TRUE,I1,0,I4,0);
9703 VARIMP(BOOL,VARIANT_TRUE,UI1,1,I2,1);
9704 VARIMP(BOOL,VARIANT_TRUE,UI2,1,I4,1);
9705 VARIMP(BOOL,VARIANT_TRUE,UI4,1,I4,1);
9706 if (has_i8)
9708 VARIMP(BOOL,VARIANT_TRUE,I8,1,I8,1);
9709 VARIMP(BOOL,VARIANT_TRUE,UI8,1,I4,1);
9711 VARIMP(BOOL,VARIANT_TRUE,INT,-1,I4,-1);
9712 VARIMP(BOOL,VARIANT_TRUE,UINT,1,I4,1);
9713 VARIMP(I1,-1,EMPTY,0,I4,0);
9714 VARIMP(I1,-1,NULL,0,NULL,0);
9715 VARIMP(I1,-1,I2,-1,I4,-1);
9716 VARIMP(I1,-1,I4,-1,I4,-1);
9717 VARIMP(I1,-1,R4,0.0f,I4,0);
9718 VARIMP(I1,-1,R8,-1.0,I4,-1);
9719 VARIMP(I1,-1,DATE,0,I4,0);
9720 VARIMP(I1,-1,BSTR,true_str,I4,-1);
9721 VARIMP(I1,-1,BOOL,VARIANT_FALSE,I4,0);
9722 VARIMP(I1,-1,I1,0,I4,0);
9723 VARIMP(I1,-1,UI1,1,I4,1);
9724 VARIMP(I1,-1,UI2,1,I4,1);
9725 VARIMP(I1,-1,UI4,1,I4,1);
9726 if (has_i8)
9728 VARIMP(I1,-1,I8,1,I8,1);
9729 VARIMP(I1,-1,UI8,1,I4,1);
9731 VARIMP(I1,-1,INT,-1,I4,-1);
9732 VARIMP(I1,-1,UINT,1,I4,1);
9733 VARIMP(UI1,0,EMPTY,0,I2,-1);
9734 VARIMP(UI1,0,NULL,0,UI1,255);
9735 VARIMP(UI1,0,I2,-1,I2,-1);
9736 VARIMP(UI1,0,I4,-1,I4,-1);
9737 VARIMP(UI1,0,R4,0.0f,I4,-1);
9738 VARIMP(UI1,0,R8,-1.0,I4,-1);
9739 VARIMP(UI1,0,DATE,0,I4,-1);
9740 VARIMP(UI1,0,BSTR,true_str,I2,-1);
9741 VARIMP(UI1,0,BOOL,VARIANT_FALSE,I2,-1);
9742 VARIMP(UI1,0,I1,0,I4,-1);
9743 VARIMP(UI1,0,UI1,1,UI1,255);
9744 VARIMP(UI1,0,UI2,1,I4,-1);
9745 VARIMP(UI1,0,UI4,1,I4,-1);
9746 if (has_i8)
9748 VARIMP(UI1,0,I8,1,I8,-1);
9749 VARIMP(UI1,0,UI8,1,I4,-1);
9751 VARIMP(UI1,0,INT,-1,I4,-1);
9752 VARIMP(UI1,0,UINT,1,I4,-1);
9753 VARIMP(UI2,0,EMPTY,0,I4,-1);
9754 VARIMP(UI2,0,NULL,0,I4,-1);
9755 VARIMP(UI2,0,I2,-1,I4,-1);
9756 VARIMP(UI2,0,I4,-1,I4,-1);
9757 VARIMP(UI2,0,R4,0.0f,I4,-1);
9758 VARIMP(UI2,0,R8,-1.0,I4,-1);
9759 VARIMP(UI2,0,DATE,0,I4,-1);
9760 VARIMP(UI2,0,BSTR,true_str,I4,-1);
9761 VARIMP(UI2,0,BOOL,VARIANT_FALSE,I4,-1);
9762 VARIMP(UI2,0,I1,0,I4,-1);
9763 VARIMP(UI2,0,UI1,1,I4,-1);
9764 VARIMP(UI2,0,UI2,1,I4,-1);
9765 VARIMP(UI2,0,UI4,1,I4,-1);
9766 if (has_i8)
9768 VARIMP(UI2,0,I8,1,I8,-1);
9769 VARIMP(UI2,0,UI8,1,I4,-1);
9771 VARIMP(UI2,0,INT,-1,I4,-1);
9772 VARIMP(UI2,0,UINT,1,I4,-1);
9773 VARIMP(UI4,0,EMPTY,0,I4,-1);
9774 VARIMP(UI4,0,NULL,0,I4,-1);
9775 VARIMP(UI4,0,I2,-1,I4,-1);
9776 VARIMP(UI4,0,I4,-1,I4,-1);
9777 VARIMP(UI4,0,R4,0.0f,I4,-1);
9778 VARIMP(UI4,0,R8,-1.0,I4,-1);
9779 VARIMP(UI4,0,DATE,0,I4,-1);
9780 VARIMP(UI4,0,BSTR,true_str,I4,-1);
9781 VARIMP(UI4,0,BOOL,VARIANT_FALSE,I4,-1);
9782 VARIMP(UI4,0,I1,0,I4,-1);
9783 VARIMP(UI4,0,UI1,1,I4,-1);
9784 VARIMP(UI4,0,UI2,1,I4,-1);
9785 VARIMP(UI4,0,UI4,1,I4,-1);
9786 if (has_i8)
9788 VARIMP(UI4,0,I8,1,I8,-1);
9789 VARIMP(UI4,0,UI8,1,I4,-1);
9791 VARIMP(UI4,0,INT,-1,I4,-1);
9792 VARIMP(UI4,0,UINT,1,I4,-1);
9793 if (has_i8)
9795 VARIMP(I8,-1,EMPTY,0,I8,0);
9796 VARIMP(I8,-1,NULL,0,NULL,0);
9797 VARIMP(I8,-1,I2,-1,I8,-1);
9798 VARIMP(I8,-1,I4,-1,I8,-1);
9799 VARIMP(I8,-1,R4,0.0f,I8,0);
9800 VARIMP(I8,-1,R8,-1.0,I8,-1);
9801 VARIMP(I8,-1,DATE,0,I8,0);
9802 VARIMP(I8,-1,BSTR,true_str,I8,-1);
9803 VARIMP(I8,-1,BOOL,VARIANT_FALSE,I8,0);
9804 VARIMP(I8,-1,I1,0,I8,0);
9805 VARIMP(I8,-1,UI1,1,I8,1);
9806 VARIMP(I8,-1,UI2,1,I8,1);
9807 VARIMP(I8,-1,UI4,1,I8,1);
9808 VARIMP(I8,-1,I8,1,I8,1);
9809 VARIMP(I8,-1,UI8,1,I8,1);
9810 VARIMP(I8,-1,UINT,1,I8,1);
9811 VARIMP(UI8,0,EMPTY,0,I4,-1);
9812 VARIMP(UI8,0,NULL,0,I4,-1);
9813 VARIMP(UI8,0,I2,-1,I4,-1);
9814 VARIMP(UI8,0,I4,-1,I4,-1);
9815 VARIMP(UI8,0,R4,0.0f,I4,-1);
9816 VARIMP(UI8,0,R8,-1.0,I4,-1);
9817 VARIMP(UI8,0,DATE,0,I4,-1);
9818 VARIMP(UI8,0,BSTR,true_str,I4,-1);
9819 VARIMP(UI8,0,BOOL,VARIANT_FALSE,I4,-1);
9820 VARIMP(UI8,0,I1,0,I4,-1);
9821 VARIMP(UI8,0,UI1,1,I4,-1);
9822 VARIMP(UI8,0,UI2,1,I4,-1);
9823 VARIMP(UI8,0,UI4,1,I4,-1);
9824 VARIMP(UI8,0,I8,1,I8,-1);
9825 VARIMP(UI8,0,UI8,1,I4,-1);
9826 VARIMP(UI8,0,INT,-1,I4,-1);
9827 VARIMP(UI8,0,UINT,1,I4,-1);
9829 VARIMP(INT,-1,EMPTY,0,I4,0);
9830 VARIMP(INT,-1,NULL,0,NULL,0);
9831 VARIMP(INT,-1,I2,-1,I4,-1);
9832 VARIMP(INT,-1,I4,-1,I4,-1);
9833 VARIMP(INT,-1,R4,0.0f,I4,0);
9834 VARIMP(INT,-1,R8,-1.0,I4,-1);
9835 VARIMP(INT,-1,DATE,0,I4,0);
9836 VARIMP(INT,-1,BSTR,true_str,I4,-1);
9837 VARIMP(INT,-1,BOOL,VARIANT_FALSE,I4,0);
9838 VARIMP(INT,-1,I1,0,I4,0);
9839 VARIMP(INT,-1,UI1,1,I4,1);
9840 VARIMP(INT,-1,UI2,1,I4,1);
9841 VARIMP(INT,-1,UI4,1,I4,1);
9842 if (has_i8)
9844 VARIMP(INT,-1,I8,1,I8,1);
9845 VARIMP(INT,-1,UI8,1,I4,1);
9847 VARIMP(INT,-1,INT,-1,I4,-1);
9848 VARIMP(INT,-1,UINT,1,I4,1);
9849 VARIMP(UINT,1,EMPTY,0,I4,-2);
9850 VARIMP(UINT,1,NULL,0,I4,-2);
9851 VARIMP(UINT,1,I2,-1,I4,-1);
9852 VARIMP(UINT,1,I4,-1,I4,-1);
9853 VARIMP(UINT,1,R4,0.0f,I4,-2);
9854 VARIMP(UINT,1,R8,-1.0,I4,-1);
9855 VARIMP(UINT,1,DATE,0,I4,-2);
9856 VARIMP(UINT,1,BSTR,true_str,I4,-1);
9857 VARIMP(UINT,1,BOOL,VARIANT_FALSE,I4,-2);
9858 VARIMP(UINT,1,I1,0,I4,-2);
9859 VARIMP(UINT,1,UI1,1,I4,-1);
9860 VARIMP(UINT,1,UI2,1,I4,-1);
9861 VARIMP(UINT,1,UI4,1,I4,-1);
9862 if (has_i8)
9864 VARIMP(UINT,1,I8,1,I8,-1);
9865 VARIMP(UINT,1,UI8,1,I4,-1);
9867 VARIMP(UINT,1,INT,-1,I4,-1);
9868 VARIMP(UINT,1,UINT,1,I4,-1);
9870 /* Manually test some VT_CY, VT_DECIMAL variants */
9871 V_VT(&cy) = VT_CY;
9872 hres = VarCyFromI4(1, &V_CY(&cy));
9873 ok(hres == S_OK, "VarCyFromI4 failed!\n");
9874 V_VT(&dec) = VT_DECIMAL;
9875 hres = VarDecFromR8(2.0, &V_DECIMAL(&dec));
9876 ok(hres == S_OK, "VarDecFromR4 failed!\n");
9877 memset(&left, 0, sizeof(left));
9878 memset(&right, 0, sizeof(right));
9879 V_VT(&left) = VT_I4;
9880 V_I4(&left) = 0;
9881 V_VT(&right) = VT_I8;
9882 V_UI1(&right) = 0;
9884 hres = pVarImp(&cy, &cy, &result);
9885 ok(hres == S_OK && V_VT(&result) == VT_I4,
9886 "VARIMP: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9887 S_OK, hres, vtstr(V_VT(&result)));
9888 ok(hres == S_OK && V_I4(&result) == -1,
9889 "VARIMP: CY value %d, expected %d\n", V_I4(&result), -1);
9891 if (has_i8)
9893 hres = pVarImp(&cy, &right, &result);
9894 ok(hres == S_OK && V_VT(&result) == VT_I8,
9895 "VARIMP: expected coerced hres 0x%X type VT_I8, got hres 0x%X type %s!\n",
9896 S_OK, hres, vtstr(V_VT(&result)));
9897 ok(hres == S_OK && V_I8(&result) == -2,
9898 "VARIMP: CY value %x%08x, expected %d\n",
9899 (DWORD)((V_I8(&result)) >> 32), (DWORD)(V_I8(&result)), -2);
9902 hres = pVarImp(&left, &cy, &result);
9903 ok(hres == S_OK && V_VT(&result) == VT_I4,
9904 "VARIMP: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9905 S_OK, hres, vtstr(V_VT(&result)));
9906 ok(hres == S_OK && V_I4(&result) == -1,
9907 "VARIMP: CY value %d, expected %d\n", V_I4(&result), -1);
9909 hres = pVarImp(&left, &dec, &result);
9910 ok(hres == S_OK && V_VT(&result) == VT_I4,
9911 "VARIMP: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9912 S_OK, hres, vtstr(V_VT(&result)));
9913 ok(hres == S_OK && V_I4(&result) == -1,
9914 "VARIMP: DECIMAL value %d, expected %d\n", V_I4(&result), -1);
9916 hres = pVarImp(&dec, &dec, &result);
9917 ok(hres == S_OK && V_VT(&result) == VT_I4,
9918 "VARIMP: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
9919 S_OK, hres, vtstr(V_VT(&result)));
9920 ok(hres == S_OK && V_I4(&result) == -1,
9921 "VARIMP: DECIMAL value %d, expected %d\n", V_I4(&result), -1);
9923 if (has_i8)
9925 hres = pVarImp(&dec, &right, &result);
9926 ok(hres == S_OK && V_VT(&result) == VT_I8,
9927 "VARIMP: expected coerced hres 0x%X type VT_I8, got hres 0x%X type %s!\n",
9928 S_OK, hres, vtstr(V_VT(&result)));
9929 ok(hres == S_OK && V_I8(&result) == -3,
9930 "VARIMP: DECIMAL value 0x%x%08x, expected %d\n",
9931 (DWORD)(V_I8(&result) >>32), (DWORD)V_I8(&result), -3);
9934 SysFreeString(false_str);
9935 SysFreeString(true_str);
9938 START_TEST(vartest)
9940 init();
9942 test_VariantInit();
9943 test_VariantClear();
9944 test_VariantCopy();
9945 test_VariantCopyInd();
9946 test_VarParseNumFromStrEn();
9947 test_VarParseNumFromStrFr();
9948 test_VarParseNumFromStrMisc();
9949 test_VarNumFromParseNum();
9950 test_VarUdateFromDate();
9951 test_VarDateFromUdate();
9952 test_SystemTimeToVariantTime();
9953 test_VariantTimeToSystemTime();
9954 test_DosDateTimeToVariantTime();
9955 test_VariantTimeToDosDateTime();
9956 test_VarAbs();
9957 test_VarNot();
9958 test_VarSub();
9959 test_VarMod();
9960 test_VarFix();
9961 test_VarInt();
9962 test_VarNeg();
9963 test_VarRound();
9964 test_VarXor();
9965 test_VarOr();
9966 test_VarPow();
9967 test_VarEqv();
9968 test_VarMul();
9969 test_VarAdd();
9970 test_VarCmp(); /* Before test_VarCat() which needs VarCmp() */
9971 test_VarCat();
9972 test_VarAnd();
9973 test_VarDiv();
9974 test_VarIdiv();
9975 test_VarImp();