4 * Copyright 1998 Jean-Claude Cote
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * - Does not test IDispatch, IUnknown, IRecordInfo, DECIMAL, CY, I8/UI8
22 * - VarDateFromStr is not implemented yet.
23 * - The date and floating point format may not be the exact same
24 * format has the one inwindows depending on what the Internatinal
25 * setting are in windows.
38 #include "wine/test.h"
48 static HMODULE hOleaut32
;
50 static HRESULT (WINAPI
*pVarBstrFromI1
)(CHAR
,LCID
,ULONG
,BSTR
*)=NULL
;
52 static HRESULT (WINAPI
*pVarI1FromBool
)(VARIANT_BOOL
,CHAR
*)=NULL
;
53 static HRESULT (WINAPI
*pVarI1FromDate
)(DATE
,CHAR
*)=NULL
;
54 static HRESULT (WINAPI
*pVarI1FromI4
)(LONG
,CHAR
*)=NULL
;
55 static HRESULT (WINAPI
*pVarI1FromR8
)(double,CHAR
*)=NULL
;
56 static HRESULT (WINAPI
*pVarI1FromStr
)(OLECHAR
*,LCID
,ULONG
,CHAR
*);
57 static HRESULT (WINAPI
*pVarI1FromUI1
)(BYTE
,CHAR
*)=NULL
;
59 static HRESULT (WINAPI
*pVarI2FromUI2
)(USHORT
,short*)=NULL
;
61 static HRESULT (WINAPI
*pVarUI2FromBool
)(VARIANT_BOOL
,USHORT
*)=NULL
;
62 static HRESULT (WINAPI
*pVarUI2FromDate
)(DATE
,USHORT
*)=NULL
;
63 static HRESULT (WINAPI
*pVarUI2FromI2
)(short,USHORT
*)=NULL
;
64 static HRESULT (WINAPI
*pVarUI2FromI4
)(LONG
,USHORT
*);
65 static HRESULT (WINAPI
*pVarUI2FromR8
)(double,USHORT
*)=NULL
;
66 static HRESULT (WINAPI
*pVarUI2FromStr
)(OLECHAR
*,LCID
,ULONG
,USHORT
*)=NULL
;
68 static HRESULT (WINAPI
*pVarUI4FromBool
)(VARIANT_BOOL
,ULONG
*)=NULL
;
69 static HRESULT (WINAPI
*pVarUI4FromDate
)(DATE
,ULONG
*)=NULL
;
70 static HRESULT (WINAPI
*pVarUI4FromI2
)(short,ULONG
*)=NULL
;
71 static HRESULT (WINAPI
*pVarUI4FromR8
)(double,ULONG
*)=NULL
;
72 static HRESULT (WINAPI
*pVarUI4FromStr
)(OLECHAR
*,LCID
,ULONG
,ULONG
*)=NULL
;
74 static HRESULT (WINAPI
*pVarUdateFromDate
)(DATE
,ULONG
,UDATE
*);
75 static HRESULT (WINAPI
*pVarDateFromUdate
)(UDATE
*,ULONG
,DATE
*);
76 static INT (WINAPI
*pSystemTimeToVariantTime
)(LPSYSTEMTIME
,double*);
77 static INT (WINAPI
*pVariantTimeToSystemTime
)(double,LPSYSTEMTIME
);
78 static INT (WINAPI
*pDosDateTimeToVariantTime
)(USHORT
,USHORT
,double*);
79 static INT (WINAPI
*pVariantTimeToDosDateTime
)(double,USHORT
*,USHORT
*);
81 /* Get a conversion function ptr, return if function not available */
82 #define CHECKPTR(func) p##func = (void*)GetProcAddress(hOleaut32, #func); \
83 if (!p##func) { trace("function " # func " not available, not testing it\n"); return; }
85 /* When comparing floating point values we cannot expect an exact match
86 * because the rounding errors depend on the exact algorithm.
88 #define EQ_DOUBLE(a,b) (fabs((a)-(b))<1e-14)
90 #define MAX_BUFFER 1024
92 static char* WtoA( OLECHAR
* p
)
94 static char buffer
[MAX_BUFFER
];
95 DWORD len
= WideCharToMultiByte( CP_ACP
, 0, p
, -1, buffer
+1, sizeof(buffer
)-3, NULL
, NULL
);
102 static OLECHAR
* AtoW( const char* p
)
105 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, p
, -1, NULL
, 0 );
106 buffer
= malloc( len
* sizeof(OLECHAR
) );
107 MultiByteToWideChar( CP_ACP
, 0, p
, -1, buffer
, len
);
111 static const struct _vartypes
{
113 HRESULT vcind1
,vcind2
,vcex1
,vcex2
;
114 int todoind1
,todoind2
,todowcex1
,todowcex2
;
116 {0, 0, 0x80070057, 0, 0x80020008,0,1 },
117 {1, 0, 0x80070057, 0, 0x80020008,0,1 },
118 {2, 0, 0, 0, 0x80020005 },
119 {3, 0, 0, 0, 0x80020005 },
120 {4, 0, 0, 0, 0x80020005 },
121 {5, 0, 0, 0, 0x80020005 },
122 {6, 0, 0, 0, 0x80020005 },
123 {7, 0, 0, 0, 0x80020005 },
124 {77,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
125 {78,0x80020008, 0x80070057, 0x80020005, 0x80020005,0,1 },
126 {79,0x80020008, 0x80070057, 0x80020005, 0x80020005,0,1 },
127 {80,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
128 {81,0x80020008, 0x80070057, 0x80020005, 0x80020005,0,1 },
129 {82,0x80020008, 0x80070057, 0x80020005, 0x80020005,0,1 },
130 {83,0x80020008, 0x80070057, 0, 0x80020005,0,1,1 },
131 {84,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
132 {85,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
133 {86,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
134 {87,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
135 {88,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
136 {89,0x80020008, 0x80070057, 0, 0x80020005,0,1,1 },
137 {90,0x80020008, 0x80070057, 0, 0x80020005,0,1,1 },
138 {91,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
139 {92,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
140 {93,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
141 {94,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
142 {95,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
143 {96,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
144 {97,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
145 {98,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
146 {99,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
149 static const char *strfromr8
[] = {
180 "7.65432198765432E+15",
181 "-7.65432198765432E+15",
182 "8.76543219876543E+16",
183 "-8.76543219876543E+16",
184 "9.87654321987654E+17",
185 "-9.87654321987654E+17",
186 "1.98765432198765E+18",
187 "-1.98765432198765E+18",
188 "2.19876543219877E+19",
189 "-2.19876543219877E+19",
280 "7.65432198765432E+15",
281 "-7.65432198765432E+15",
282 "8.76543219876543E+16",
283 "-8.76543219876543E+16",
284 "9.87654321987654E+17",
285 "-9.87654321987654E+17",
286 "1.98765432198765E+18",
287 "-1.98765432198765E+18",
288 "2.19876543219877E+19",
289 "-2.19876543219877E+19",
363 /* These are the strings we use for the XxxFromStr tests.
364 * The arrays that follow define the expected results for each type.
366 static const char* _pTestStrA
[] = {
419 "1000000000000000000000000000000000000000000000000000000000000000",
420 "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
421 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
422 "100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
423 "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
437 "11/11/1999:11:11:1134",
438 "11/11/1999 11:11:11:1",
439 "\t1999/\t11/21 11 :11:11am",
441 "11/11/1999 11:11:11Am",
442 "11/11/1999 11:11:11PM",
443 "11/11/199911:11:11PM",
444 "11/11/1999 0:0:11am",
445 "11/11/1999 11,11:11am",
446 "11/11/1999 11:11:11am",
447 "11/11/1999 11/11:11am",
448 "11/11/1999 11:11AM",
452 "11/11/1999 11:11:11",
460 "1999 January 3 9AM",
461 "1 January 1999 11AM",
464 "4:22 11/11/1999 AM",
466 "11-11/1999 11:11:11.12AM",
467 "1999 January 3, 9AM",
468 "December, 31, 2078",
469 "December, 31, 2078,",
489 #define NB_OLE_STRINGS (sizeof(_pTestStrA)/sizeof(*_pTestStrA))
491 static const struct _strret_date
{
496 } strrets_DATE
[NB_OLE_STRINGS
] = {
504 { 0, 0.03402777777777, 1 },
505 { 0, 0.00347222222222, 1 },
506 { 0, 0.03541666666666, 1 },
518 { 0x80020005, 0.0, 1 },
519 { 0x80020005, 0.0, 1 },
521 { 0x80020005, 0.0, 1 },
535 { 0x80020005, 0.0, 1 },
536 { 0, 0.04309027777777, 0, 1 },
539 { 0x80020005, 0.0, 1 },
540 { 0x80020005, 0.0, 1 },
542 { 0x80020005, 0.0, 1 },
561 { 0x80020005, 0.0, 1 },
566 { 0, 36485.466099537036, 1 },
567 { 0, 36475.466099537036 },
568 { 0, 36475.966099537036 },
569 { 0x80020005, 0.0, 1 },
570 { 0, 36475.000127314815 },
572 { 0, 36475.466099537036 },
574 { 0, 36475.465972222222 },
575 { 0, 36475.041666666664, 1 },
577 { 0, 36475.466099537036 },
582 { 0x80020005, 0.0, 1 },
585 { 0, 36163.375000000000, 1 },
586 { 0, 36161.458333333336, 1 },
587 { 0, 36475.166666666664, 1 },
588 { 0x80020005, 0.0, 1 },
590 { 0x80020005, 0.0, 1 },
593 { 0x80020005, 0.0, 1 },
606 { 0, 0.045138888888889, 1 },
607 { 0, 0.086805555555556, 1 },
608 { 0, 0.128472222222222, 1 },
609 { 0, 0.170138888888889, 1 },
611 static const struct _strret_b
{
614 } strrets_B
[NB_OLE_STRINGS
] = {
620 { 0, VARIANT_FALSE
},
621 { 0, VARIANT_FALSE
},
655 { 0, VARIANT_FALSE
},
656 { 0, VARIANT_FALSE
},
721 { 0, VARIANT_FALSE
},
729 static const struct _strret_r8
{
732 } strrets_R8
[NB_OLE_STRINGS
] = {
752 { 0, -32768.000000 },
753 { 0, -32769.000000 },
754 { 0, 16777216.000000 },
755 { 0, 16777217.000000 },
756 { 0, -16777216.000000 },
757 { 0, 16777217.000000 },
758 { 0, 2147483647.000000 },
759 { 0, 2147483648.000000 },
760 { 0, -2147483647.000000 },
761 { 0, -2147483648.000000 },
775 { 0, 100000000000.000000 },
786 { 0, 99999999999999997e183
},
791 { 0, 4294967295.000000 },
792 { 0, 4294967296.000000 },
847 static const struct _strret_r4
{
850 } strrets_R4
[NB_OLE_STRINGS
] = {
868 { 0, 32767.000000F
},
869 { 0, 32768.000000F
},
870 { 0, -32768.000000F
},
871 { 0, -32769.000000F
},
872 { 0, 16777216.000000F
},
873 { 0, 16777216.000000F
},
874 { 0, -16777216.000000F
},
875 { 0, 16777216.000000F
},
876 { 0, 2147483648.000000F
},
877 { 0, 2147483648.000000F
},
878 { 0, -2147483648.000000F
},
879 { 0, -2147483648.000000F
},
893 { 0, 99999997952.000000F
},
906 { 0, 65535.000000F
},
907 { 0, 65535.500000F
},
908 { 0, 65536.000000F
},
909 { 0, 4294967296.000000F
},
910 { 0, 4294967296.000000F
},
965 static const struct _strret_i4
{
968 } strrets_I4
[NB_OLE_STRINGS
] = {
1083 static const struct _strret_i2
{
1086 } strrets_I2
[NB_OLE_STRINGS
] = {
1201 static const struct _strret_i1
{
1204 } strrets_I1
[NB_OLE_STRINGS
] = {
1319 static const struct _strret_u1
{
1322 } strrets_U1
[NB_OLE_STRINGS
] = {
1438 static const struct _strret_U2
{
1441 } strrets_U2
[NB_OLE_STRINGS
] = {
1557 static const struct _strret_U4
{
1560 } strrets_U4
[NB_OLE_STRINGS
] = {
1676 static void test_variant(void)
1688 int* pInt
= &theInt
;
1690 VARIANT_BOOL
* pBool
= &b
;
1691 unsigned short uShort
= 0;
1692 unsigned short* pUShort
= &uShort
;
1693 unsigned long uLong
= 0;
1694 unsigned long* pULong
= &uLong
;
1696 CHAR
* pChar
= &theChar
;
1698 BYTE
* pByte
= &byte
;
1702 long* pLong
= &Long
;
1706 double* pDouble
= &d
;
1710 OLECHAR
* pOleChar
[NB_OLE_STRINGS
];
1712 for (i
=0; i
<NB_OLE_STRINGS
;i
++) {
1713 pOleChar
[i
]=AtoW(_pTestStrA
[i
]);
1715 lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
1717 /* Start testing the Low-Level API ( the coercions )
1719 hdll
=LoadLibraryA("netapi32.dll");
1720 pVarI1FromBool
=(void*)GetProcAddress(hdll
,"VarI1FromBool");
1721 pVarI1FromDate
=(void*)GetProcAddress(hdll
,"VarI1FromDate");
1722 pVarI1FromI4
=(void*)GetProcAddress(hdll
,"VarI1FromI4");
1723 pVarI1FromR8
=(void*)GetProcAddress(hdll
,"VarI1FromR8");
1724 pVarI1FromStr
=(void*)GetProcAddress(hdll
,"VarI1FromStr");
1725 pVarI1FromUI1
=(void*)GetProcAddress(hdll
,"VarI1FromUI1");
1727 pVarI2FromUI2
=(void*)GetProcAddress(hdll
,"VarI2FromUI2");
1729 pVarUI2FromBool
=(void*)GetProcAddress(hdll
,"VarUI2FromBool");
1730 pVarUI2FromDate
=(void*)GetProcAddress(hdll
,"VarUI2FromDate");
1731 pVarUI2FromI2
=(void*)GetProcAddress(hdll
,"VarUI2FromI2");
1732 pVarUI2FromI4
=(void*)GetProcAddress(hdll
,"VarUI2FromI4");
1733 pVarUI2FromR8
=(void*)GetProcAddress(hdll
,"VarUI2FromR8");
1734 pVarUI2FromStr
=(void*)GetProcAddress(hdll
,"VarUI2FromStr");
1736 pVarUI4FromBool
=(void*)GetProcAddress(hdll
,"VarUI4FromBool");
1737 pVarUI4FromDate
=(void*)GetProcAddress(hdll
,"VarUI4FromDate");
1738 pVarUI4FromI2
=(void*)GetProcAddress(hdll
,"VarUI4FromI2");
1739 pVarUI4FromR8
=(void*)GetProcAddress(hdll
,"VarUI4FromR8");
1740 pVarUI4FromStr
=(void*)GetProcAddress(hdll
,"VarUI4FromStr");
1742 /* unsigned char from...
1744 trace( "======== Testing VarUI1FromXXX ========\n");
1746 #define XOK "should return S_OK\n"
1747 #define XOV "should return DISP_E_OVERFLOW\n"
1748 /* Crashes on Win95: VarUI1FromI2( 0, NULL ) */
1750 ok(VarUI1FromStr(NULL
, lcid
, 0, pByte
) == DISP_E_TYPEMISMATCH
,"should return DISP_E_TYPEMISMATCH");
1751 ok(S_OK
== VarUI1FromI2( 0, pByte
), XOK
);
1752 ok(*pByte
== 0,"should give 0 byte value");
1754 ok(S_OK
== VarUI1FromI2( 69, pByte
), XOK
);
1755 ok(*pByte
== 69,"should give 69 byte value");
1757 ok(S_OK
== VarUI1FromI2( 70, pByte
), XOK
);
1758 ok(*pByte
== 70,"should give 70 byte value");
1760 ok(S_OK
== VarUI1FromI2( 128, pByte
), XOK
);
1761 ok(*pByte
== 128,"should give 128 byte value");
1763 ok(S_OK
== VarUI1FromI2( 255, pByte
), XOK
);
1764 ok(*pByte
== 255,"should give 255 byte value");
1766 ok(DISP_E_OVERFLOW
== VarUI1FromI2( 256, pByte
), XOV
);
1767 ok(DISP_E_OVERFLOW
== VarUI1FromI2( 257, pByte
), XOV
);
1769 ok(S_OK
== VarUI1FromR8( 0.0, pByte
), XOK
);
1770 ok(*pByte
== 0,"0.0 float should be converted to 0");
1772 ok(S_OK
== VarUI1FromR8( 69.33, pByte
), XOK
);
1773 ok(*pByte
== 0x45, "expected 69 (hex 0x45) as byte value");
1775 ok(S_OK
== VarUI1FromR8( 69.66, pByte
), XOK
);
1776 ok(*pByte
== 0x46, "expected 70 (hex 0x46) as byte value");
1778 ok(DISP_E_OVERFLOW
== VarUI1FromR8( -69.33, pByte
), XOV
);
1779 ok(DISP_E_OVERFLOW
== VarUI1FromR8( -69.66, pByte
), XOV
);
1781 ok(S_OK
== VarUI1FromR8( -0.5, pByte
), XOK
);
1782 ok(*pByte
== 0,"-0.5 should give return 0");
1784 ok(DISP_E_OVERFLOW
== VarUI1FromR8( -0.51, pByte
), XOV
);
1786 ok(S_OK
== VarUI1FromR8( -0.49, pByte
), XOK
);
1787 ok(*pByte
== 0,"-0.49 should give return 0");
1789 ok(S_OK
== VarUI1FromR8( 0.5, pByte
), XOK
);
1790 ok(*pByte
== 0,"0.5 should give return 0");
1792 ok(S_OK
== VarUI1FromR8( 0.51, pByte
), XOK
);
1793 ok(*pByte
== 1,"0.51 should give return 1");
1795 ok(S_OK
== VarUI1FromR8( 0.49, pByte
), XOK
);
1796 ok(*pByte
== 0,"0.49 should give return 0");
1798 ok(S_OK
== VarUI1FromDate( 0.0, pByte
), XOK
);
1799 ok(*pByte
== 0,"0.0 date should give return 0");
1801 ok(S_OK
== VarUI1FromDate( 69.33, pByte
), XOK
);
1802 ok(*pByte
== 0x45,"69.33 date should give return 0x45");
1804 ok(S_OK
== VarUI1FromDate( 69.66, pByte
), XOK
);
1805 ok(*pByte
== 0x46,"69.66 date should give return 0x46");
1807 ok(DISP_E_OVERFLOW
== VarUI1FromDate( -69.33, pByte
), XOV
);
1809 ok(DISP_E_OVERFLOW
== VarUI1FromDate( -69.66, pByte
), XOV
);
1811 ok(S_OK
== VarUI1FromBool( VARIANT_TRUE
, pByte
), XOK
);
1812 ok(*pByte
== 0xff, "true should be converted to 0xff");
1814 ok(S_OK
== VarUI1FromBool( VARIANT_FALSE
, pByte
), XOK
);
1815 ok(*pByte
== 0, "false should be converted to 0");
1817 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
1820 rc
=VarUI1FromStr( pOleChar
[i
], lcid
, 0, pByte
);
1821 ok(rc
== strrets_U1
[i
].error
,
1822 "VarUI1FromStr([%d]=\"%s\") rc=%lx instead of %lx",
1823 i
,_pTestStrA
[i
],rc
,strrets_U1
[i
].error
);
1824 if (rc
== 0 && strrets_U1
[i
].error
== 0) {
1825 ok(*pByte
== strrets_U1
[i
].retval
,
1826 "VarUI1FromStr([%d]=\"%s\") got %02x instead of %02x",
1827 i
,_pTestStrA
[i
],*pByte
,strrets_U1
[i
].retval
);
1831 /* unsigned short from ... */
1832 trace( "======== Testing VarUI2FromXXX ========\n");
1834 if (pVarUI2FromI2
) {
1835 ok(DISP_E_OVERFLOW
== pVarUI2FromI2( -1, pUShort
), XOV
);
1836 ok(S_OK
== pVarUI2FromI2( 0, NULL
), XOK
);
1838 ok(S_OK
== pVarUI2FromI2( 0, pUShort
), XOK
);
1839 ok(*pUShort
== 0,"0 should be 0");
1840 ok(S_OK
== pVarUI2FromI2( 69, pUShort
), XOK
);
1841 ok(*pUShort
== 69,"69 should be 69");
1842 ok(S_OK
== pVarUI2FromI2( 70, pUShort
), XOK
);
1843 ok(*pUShort
== 70,"70 should be 70");
1845 ok(S_OK
== pVarUI2FromI2( 128, pUShort
), XOK
);
1846 ok(*pUShort
== 128,"128 should be 128");
1849 if (pVarUI2FromI4
) {
1850 ok(S_OK
== pVarUI2FromI4( 65535, pUShort
), XOK
);
1851 ok(*pUShort
== 65535,"65535 should be 65535");
1852 ok(DISP_E_OVERFLOW
== pVarUI2FromI4( 65536, pUShort
), XOV
);
1853 ok(DISP_E_OVERFLOW
== pVarUI2FromI4( 65537, pUShort
), XOV
);
1856 if (pVarUI2FromR8
) {
1857 ok(S_OK
== pVarUI2FromR8( 0.0, pUShort
), XOK
);
1858 ok(*pUShort
== 0,"0.0 should be 0");
1859 ok(S_OK
== pVarUI2FromR8( 69.33, pUShort
), XOK
);
1860 ok(*pUShort
== 69,"69.33 should be 69");
1861 ok(S_OK
== pVarUI2FromR8( 69.66, pUShort
), XOK
);
1862 ok(*pUShort
== 70,"69.66 should be 70");
1864 ok(DISP_E_OVERFLOW
== pVarUI2FromR8( -69.33, pUShort
), XOV
);
1865 ok(DISP_E_OVERFLOW
== pVarUI2FromR8( -69.66, pUShort
), XOV
);
1867 ok(S_OK
== pVarUI2FromR8( -0.5, pUShort
), XOK
);
1868 ok(*pUShort
== 0, "-0.5 -> 0");
1869 ok(DISP_E_OVERFLOW
== pVarUI2FromR8( -0.51, pUShort
), XOV
);
1870 ok(S_OK
== pVarUI2FromR8( -0.49, pUShort
), XOK
);
1871 ok(*pUShort
== 0, "-0.49 -> 0");
1873 ok(S_OK
== pVarUI2FromR8( 0.5, pUShort
), XOK
);
1874 ok(*pUShort
== 0,"0.5 should be 0");
1875 ok(S_OK
== pVarUI2FromR8( 0.51, pUShort
), XOK
);
1876 ok(*pUShort
== 1,"0.51 should be 1");
1877 ok(S_OK
== pVarUI2FromR8( 0.49, pUShort
), XOK
);
1878 ok(*pUShort
== 0,"0.49 should be 0");
1881 if (pVarUI2FromDate
) {
1882 ok(S_OK
== pVarUI2FromDate( 0.0, pUShort
), XOK
);
1883 ok(*pUShort
== 0,"0.0 should be 0");
1884 ok(S_OK
== pVarUI2FromDate( 69.33, pUShort
), XOK
);
1885 ok(*pUShort
== 69,"69.33 should be 69");
1886 ok(S_OK
== pVarUI2FromDate( 69.66, pUShort
), XOK
);
1887 ok(*pUShort
== 70,"69.66 should be 70");
1888 ok(DISP_E_OVERFLOW
== pVarUI2FromDate( -69.33, pUShort
), XOV
);
1889 ok(DISP_E_OVERFLOW
== pVarUI2FromDate( -69.66, pUShort
), XOV
);
1892 if (pVarUI2FromBool
) {
1893 ok(S_OK
== pVarUI2FromBool( VARIANT_TRUE
, pUShort
), XOK
);
1894 ok(*pUShort
== 65535,"TRUE should be 65535");
1895 ok(S_OK
== pVarUI2FromBool( VARIANT_FALSE
, pUShort
), XOK
);
1896 ok(*pUShort
== 0,"FALSE should be 0");
1899 if (pVarUI2FromStr
) {
1900 ok(DISP_E_TYPEMISMATCH
== pVarUI2FromStr( NULL
, lcid
, 0, pUShort
), "should return DISP_E_TYPEMISMATCH");
1902 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
1905 rc
=pVarUI2FromStr( pOleChar
[i
], lcid
, 0, pUShort
);
1906 ok(rc
== strrets_U2
[i
].error
,
1907 "VarUI2FromStr([%d]=\"%s\") rc=%lx instead of %lx",
1908 i
,_pTestStrA
[i
],rc
,strrets_U2
[i
].error
);
1909 if (rc
== 0 && strrets_U2
[i
].error
== 0) {
1910 ok(*pUShort
== strrets_U2
[i
].retval
,
1911 "VarUI2FromStr([%d]=\"%s\") got %u instead of %u",
1912 i
,_pTestStrA
[i
],*pUShort
,strrets_U2
[i
].retval
);
1917 /* unsigned long from ...
1919 trace( "======== Testing VarUI4FromXXX ========\n");
1921 if (pVarUI4FromI2
) {
1922 ok(S_OK
== pVarUI4FromI2( 0, NULL
), XOK
);
1924 ok(S_OK
== pVarUI4FromI2( 0, pULong
), XOK
);
1925 ok(*pULong
== 0,"0 should be 0");
1926 ok(S_OK
== pVarUI4FromI2( 69, pULong
), XOK
);
1927 ok(*pULong
== 69,"69 should be 69");
1929 ok(S_OK
== pVarUI4FromI2( 70, pULong
), XOK
);
1930 ok(*pULong
== 70,"70 should be 70");
1932 ok(S_OK
== pVarUI4FromI2( 128, pULong
), XOK
);
1933 ok(*pULong
== 128,"128 should be 128");
1934 ok(S_OK
== pVarUI4FromI2( 255, pULong
), XOK
);
1935 ok(*pULong
== 255,"255 should be 255");
1938 if (pVarUI4FromR8
) {
1939 ok(S_OK
== pVarUI4FromR8( 4294967295.0, pULong
), XOK
);
1940 ok(*pULong
== 4294967295U,"4294967295.0 should be 4294967295");
1941 ok(DISP_E_OVERFLOW
== pVarUI4FromR8( 4294967296.0, pULong
), XOV
);
1943 ok(S_OK
== pVarUI4FromR8( 0.0, pULong
), XOK
);
1944 ok(*pULong
== 0,"0 should be 0");
1945 ok(S_OK
== pVarUI4FromR8( 69.33, pULong
), XOK
);
1946 ok(*pULong
== 69,"69.33 should be 69");
1947 ok(S_OK
== pVarUI4FromR8( 69.66, pULong
), XOK
);
1948 ok(*pULong
== 70,"69.66 should be 70");
1949 ok(DISP_E_OVERFLOW
== pVarUI4FromR8( -69.33, pULong
), XOV
);
1950 ok(DISP_E_OVERFLOW
== pVarUI4FromR8( -69.66, pULong
), XOV
);
1952 ok(S_OK
== pVarUI4FromR8( -0.5, pULong
), XOK
);
1953 ok(*pULong
== 0,"-0.5 should be 0");
1955 ok(DISP_E_OVERFLOW
== pVarUI4FromR8( -0.51, pULong
), XOV
);
1957 ok(S_OK
== pVarUI4FromR8( -0.49, pULong
), XOK
);
1958 ok(*pULong
== 0,"-0.49 should be 0");
1960 ok(S_OK
== pVarUI4FromR8( 0.5, pULong
), XOK
);
1961 ok(*pULong
== 0,"0.5 should be 0");
1962 ok(S_OK
== pVarUI4FromR8( 0.51, pULong
), XOK
);
1963 ok(*pULong
== 1,"0.51 should be 1");
1964 ok(S_OK
== pVarUI4FromR8( 0.49, pULong
), XOK
);
1965 ok(*pULong
== 0,"0.49 should be 0");
1968 if (pVarUI4FromDate
) {
1969 ok(S_OK
== pVarUI4FromDate( 0.0, pULong
), XOK
);
1970 ok(*pULong
== 0,"0.0 should be 0");
1971 ok(S_OK
== pVarUI4FromDate( 69.33, pULong
), XOK
);
1972 ok(*pULong
== 69,"69.33 should be 69");
1973 ok(S_OK
== pVarUI4FromDate( 69.66, pULong
), XOK
);
1974 ok(*pULong
== 70,"69.66 should be 70");
1975 ok(DISP_E_OVERFLOW
== pVarUI4FromDate( -69.33, pULong
), XOV
);
1976 ok(DISP_E_OVERFLOW
== pVarUI4FromDate( -69.66, pULong
), XOV
);
1979 if (pVarUI4FromBool
) {
1980 ok(S_OK
== pVarUI4FromBool( VARIANT_TRUE
, pULong
), XOK
);
1981 ok(*pULong
== 4294967295U, "TRUE should be 4294967295");
1982 ok(S_OK
== pVarUI4FromBool( VARIANT_FALSE
, pULong
), XOK
);
1983 ok(*pULong
== 0, "FALSE should be 0");
1986 if (pVarUI4FromStr
) {
1987 ok(DISP_E_TYPEMISMATCH
== pVarUI4FromStr( NULL
, lcid
, 0, pULong
), "should erturn DISP_E_TYPEMISMATCH");
1988 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
1991 rc
=pVarUI4FromStr( pOleChar
[i
], lcid
, 0, pULong
);
1992 ok(rc
== strrets_U4
[i
].error
,
1993 "VarUI4FromStr([%d]=\"%s\") rc=%lx instead of %lx",
1994 i
,_pTestStrA
[i
],rc
,strrets_U4
[i
].error
);
1995 if (rc
== 0 && strrets_U4
[i
].error
== 0) {
1996 ok(*pULong
== strrets_U4
[i
].retval
,
1997 "VarUI4FromStr([%d]=\"%s\") got %lu instead of %lu",
1998 i
,_pTestStrA
[i
],*pULong
,strrets_U4
[i
].retval
);
2005 trace( "======== Testing VarI1FromXXX ========\n");
2007 if (pVarI1FromBool
) {
2008 ok(S_OK
== pVarI1FromBool( VARIANT_TRUE
, pByte
), XOK
);
2009 ok(*pByte
== 0xff,"true should be 0xff");
2011 ok(S_OK
== pVarI1FromBool( VARIANT_TRUE
, pChar
), XOK
);
2012 ok(*pChar
== -1, "TRUE should be -1");
2014 ok(S_OK
== pVarI1FromBool( VARIANT_FALSE
, pChar
), XOK
);
2015 ok(*pChar
== 0, "FALSE should be 0");
2018 if (pVarI1FromUI1
) {
2019 ok(DISP_E_OVERFLOW
== pVarI1FromUI1( (unsigned char)32767, pChar
), XOV
);
2020 ok(*pChar
== 0, "should still be 0");
2021 ok(DISP_E_OVERFLOW
== pVarI1FromUI1( (unsigned char)65535, pChar
), XOV
);
2022 ok(*pChar
== 0, "should still be 0");
2026 ok(DISP_E_OVERFLOW
== pVarI1FromI4( 32767, pChar
), XOV
);
2027 ok(*pChar
== 0, "should still be 0");
2028 ok(DISP_E_OVERFLOW
== pVarI1FromI4( 32768, pChar
), XOV
);
2029 ok(*pChar
== 0, "should still be 0");
2030 ok(DISP_E_OVERFLOW
== pVarI1FromI4( -32768, pChar
), XOV
);
2031 ok(*pChar
== 0, "should still be 0");
2032 ok(DISP_E_OVERFLOW
== pVarI1FromI4( -32769, pChar
), XOV
);
2033 ok(*pChar
== 0, "should still be 0");
2037 ok(S_OK
== pVarI1FromR8( 69.33, pChar
), XOK
);
2038 ok(*pChar
== 69, "69.33 should be 69");
2039 ok(S_OK
== pVarI1FromR8( 69.66, pChar
), XOK
);
2040 ok(*pChar
== 70, "69.66 should be 70");
2042 ok(S_OK
== pVarI1FromR8( -69.33, pChar
), XOK
);
2043 ok(*pChar
== -69, "-69.33 should be -69");
2044 ok(S_OK
== pVarI1FromR8( -69.66, pChar
), XOK
);
2045 ok(*pChar
== -70, "-69.66 should be -70");
2048 if (pVarI1FromDate
) {
2049 ok(S_OK
== pVarI1FromDate( -69.66, pChar
), XOK
);
2050 ok(*pChar
== -70, "-69.66 should be -70");
2053 if (pVarI1FromStr
) {
2054 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2057 rc
=pVarI1FromStr( pOleChar
[i
], lcid
, 0, pChar
);
2058 ok(rc
== strrets_I1
[i
].error
,
2059 "VarI1FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2060 i
,_pTestStrA
[i
],rc
,strrets_I1
[i
].error
);
2061 if (rc
== 0 && strrets_I1
[i
].error
== 0) {
2062 ok(*pChar
== strrets_I1
[i
].retval
,
2063 "VarI1FromStr([%d]=\"%s\") got %d instead of %d",
2064 i
,_pTestStrA
[i
],*pChar
,strrets_I1
[i
].retval
);
2071 trace( "======== Testing VarI2FromXXX ========\n");
2073 if (pVarI2FromUI2
) {
2074 ok(S_OK
== pVarI2FromUI2( 32767, pShort
), XOK
);
2075 ok(*pShort
== 32767, "should be 32767");
2076 ok(DISP_E_OVERFLOW
== pVarI2FromUI2( 65535, pShort
), XOV
);
2077 ok(*pShort
== 32767, "pShort should be unchanged");
2080 ok(S_OK
== VarI2FromI4( 32767, pShort
), XOK
);
2081 ok(*pShort
== 32767, "should be 32767");
2082 ok(DISP_E_OVERFLOW
== VarI2FromI4( 32768, pShort
), XOV
);
2083 ok(*pShort
== 32767, "should still be 32767");
2084 ok(S_OK
== VarI2FromI4( -32768, pShort
), XOK
);
2085 ok(*pShort
== -32768, "should be -32768");
2086 ok(DISP_E_OVERFLOW
== VarI2FromI4( -32769, pShort
), XOV
);
2087 ok(*pShort
== -32768, "should still be -32768");
2089 ok(S_OK
== VarI2FromR8( 69.33, pShort
), XOK
);
2090 ok(*pShort
== 69, "should be 69");
2091 ok(S_OK
== VarI2FromR8( 69.66, pShort
), XOK
);
2092 ok(*pShort
== 70, "should be 70");
2093 ok(S_OK
== VarI2FromR8( -69.33, pShort
), XOK
);
2094 ok(*pShort
== -69, "should be -69");
2095 ok(S_OK
== VarI2FromR8( -69.66, pShort
), XOK
);
2096 ok(*pShort
== -70, "should be -70");
2097 ok(S_OK
== VarI2FromDate( -69.66, pShort
), XOK
);
2098 ok(*pShort
== -70, "should be -70");
2100 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2103 rc
=VarI2FromStr( pOleChar
[i
], lcid
, 0, pShort
);
2104 ok(rc
== strrets_I2
[i
].error
,
2105 "VarI2FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2106 i
,_pTestStrA
[i
],rc
,strrets_I2
[i
].error
);
2107 if (rc
== 0 && strrets_I2
[i
].error
== 0) {
2108 ok(*pShort
== strrets_I2
[i
].retval
,
2109 "VarI2FromStr([%d]=\"%s\") got %d instead of %d",
2110 i
,_pTestStrA
[i
],*pShort
,strrets_I2
[i
].retval
);
2116 trace( "======== Testing VarI4FromXXX ========\n");
2118 ok(S_OK
== VarI4FromI2( 3, (long*)pInt
), XOK
);
2119 ok(*pInt
== 3,"should be 3");
2121 ok(S_OK
== VarI4FromR8( 69.33, pLong
), XOK
);
2122 ok(*pLong
== 69,"should be 69");
2123 ok(S_OK
== VarI4FromR8( 69.66, pLong
), XOK
);
2124 ok(*pLong
== 70,"should be 70");
2125 ok(S_OK
== VarI4FromR8( -69.33, pLong
), XOK
);
2126 ok(*pLong
== -69,"should be -69");
2127 ok(S_OK
== VarI4FromR8( -69.66, pLong
), XOK
);
2128 ok(*pLong
== -70,"should be -70");
2130 ok(S_OK
== VarI4FromR8( 2147483647.0, pLong
), XOK
);
2131 ok(*pLong
== 2147483647,"should be 2147483647");
2132 ok(DISP_E_OVERFLOW
== VarI4FromR8( 2147483648.0, pLong
), XOV
);
2133 ok(*pLong
== 2147483647,"should still be 2147483647");
2135 ok(S_OK
== VarI4FromR8( -2147483647.0, pLong
), XOK
);
2136 ok(*pLong
== -2147483647,"should be -2147483647");
2137 ok(S_OK
== VarI4FromR8( -2147483648.0, pLong
), XOK
);
2138 ok(*pLong
== 0x80000000L
,"should be -2147483648");
2139 ok(DISP_E_OVERFLOW
== VarI4FromR8( -2147483649.0, pLong
), XOV
);
2140 ok(*pLong
== 0x80000000L
,"should still be -2147483648");
2141 ok(DISP_E_OVERFLOW
== VarI4FromDate( -2147483649.0, pLong
), XOV
);
2142 ok(*pLong
== 0x80000000L
,"should still be -2147483648");
2144 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2147 rc
=VarI4FromStr( pOleChar
[i
], lcid
, 0, pLong
);
2148 ok(rc
== strrets_I4
[i
].error
,
2149 "VarI4FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2150 i
,_pTestStrA
[i
],rc
,strrets_I4
[i
].error
);
2151 if (rc
== 0 && strrets_I4
[i
].error
== 0) {
2152 ok(*pLong
== strrets_I4
[i
].retval
,
2153 "VarI4FromStr([%d]=\"%s\") got %ld instead of %ld",
2154 i
,_pTestStrA
[i
],*pLong
,strrets_I4
[i
].retval
);
2160 trace( "======== Testing VarR4FromXXX ========\n");
2162 ok(S_OK
== VarR4FromI4( 16777216, pFloat
), XOK
);
2163 ok(16777216.0 == *pFloat
,"should be 16777216.0");
2165 ok(S_OK
== VarR4FromI4( 16777217, pFloat
), XOK
);
2166 ok(16777216.0 == *pFloat
,"should be 16777216.0");
2167 ok(S_OK
== VarR4FromI4( -16777216, pFloat
), XOK
);
2168 ok(-16777216.0 == *pFloat
,"should be -16777216.0");
2169 ok(S_OK
== VarR4FromI4( -16777217, pFloat
), XOK
);
2170 ok(-16777216.0 == *pFloat
,"should be -16777216.0");
2172 ok(S_OK
== VarR4FromR8( 16777216.0, pFloat
), XOK
);
2173 ok(16777216.0 == *pFloat
,"should be 16777216.0");
2174 ok(S_OK
== VarR4FromR8( 16777217.0, pFloat
), XOK
);
2175 ok(16777216.0 == *pFloat
,"should be 16777216.0");
2176 ok(S_OK
== VarR4FromR8( -16777216.0, pFloat
), XOK
);
2177 ok(-16777216.0 == *pFloat
,"should be -16777216.0");
2178 ok(S_OK
== VarR4FromR8( -16777217.0, pFloat
), XOK
);
2179 ok(-16777216.0 == *pFloat
,"should be -16777216.0");
2181 ok(S_OK
== VarR4FromR8( 16777218e31
, pFloat
), XOK
);
2182 ok(*pFloat
== 167772177736353110000000000000000000000.000000,
2183 "should be 167772177736353110000000000000000000000.000000");
2184 ok(DISP_E_OVERFLOW
== VarR4FromR8( 16777218e32
, pFloat
), XOV
);
2185 ok(*pFloat
== 167772177736353110000000000000000000000.000000,
2186 "should still be 167772177736353110000000000000000000000.000000");
2187 ok(S_OK
== VarR4FromDate( 16777218e31
, pFloat
), XOK
);
2188 ok(*pFloat
== 167772177736353110000000000000000000000.000000,
2189 "should be 167772177736353110000000000000000000000.000000");
2191 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2194 rc
=VarR4FromStr( pOleChar
[i
], lcid
, 0, pFloat
);
2195 ok(rc
== strrets_R4
[i
].error
,
2196 "VarR4FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2197 i
,_pTestStrA
[i
],rc
,strrets_R4
[i
].error
);
2198 if (rc
== 0 && strrets_R4
[i
].error
== 0) {
2199 ok(*pFloat
== strrets_R4
[i
].retval
,
2200 "VarR4FromStr([%d]=\"%s\") got %f instead of %f",
2201 i
,_pTestStrA
[i
],*pFloat
,strrets_R4
[i
].retval
);
2207 trace( "======== Testing VarR8FromXXX ========\n");
2209 ok(S_OK
== VarR8FromDate( 900719925474099.0, pDouble
), XOK
);
2210 ok(*pDouble
== 900719925474099.000000,"should be 900719925474099.000000\n");
2211 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2214 rc
=VarR8FromStr( pOleChar
[i
], lcid
, 0, pDouble
);
2215 ok(rc
== strrets_R8
[i
].error
,
2216 "VarR8FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2217 i
,_pTestStrA
[i
],rc
,strrets_R8
[i
].error
);
2218 if (rc
== 0 && strrets_R8
[i
].error
== 0) {
2219 ok(*pDouble
== strrets_R8
[i
].retval
,
2220 "VarR8FromStr([%d]=\"%s\") got %.15f instead of %.15f",
2221 i
,_pTestStrA
[i
],*pDouble
,strrets_R8
[i
].retval
);
2227 trace( "======== Testing VarDateFromXXX ========\n");
2229 ok(S_OK
== VarDateFromI4( 2958465, pDouble
), XOK
);
2230 ok(*pDouble
== 2958465.000000,"should be 2958465.000000");
2231 rc
=VarDateFromI4( 2958466, pDouble
);
2232 ok(rc
==DISP_E_OVERFLOW
|| rc
==DISP_E_TYPEMISMATCH
/* Win95 */,
2234 ok(*pDouble
== 2958465.000000,"should still be 2958465.000000");
2235 ok(S_OK
== VarDateFromI4( -657434, pDouble
), XOK
);
2236 ok(*pDouble
== -657434.000000,"should be -657434.000000");
2237 rc
=VarDateFromI4( -657435, pDouble
);
2238 ok(rc
==DISP_E_OVERFLOW
|| rc
==DISP_E_TYPEMISMATCH
/* Win95 */,
2240 ok(*pDouble
== -657434.000000,"should still be -657434.000000");
2242 ok(S_OK
== VarDateFromR8( 2958465.9999, pDouble
), XOK
);
2243 ok(*pDouble
== 2958465.999900, "should be 2958465.999900");
2244 rc
=VarDateFromR8( 2958466, pDouble
);
2245 ok(rc
==DISP_E_OVERFLOW
|| rc
==DISP_E_TYPEMISMATCH
/* Win95 */,
2247 ok(*pDouble
== 2958465.999900, "should still be 2958465.999900");
2248 ok(S_OK
== VarDateFromR8( -657434.9999, pDouble
), XOK
);
2249 ok(*pDouble
== -657434.999900,"should be -657434.999900");
2250 rc
=VarDateFromR8( -657435, pDouble
);
2251 ok(rc
==DISP_E_OVERFLOW
|| rc
==DISP_E_TYPEMISMATCH
/* Win95 */,
2253 ok(*pDouble
== -657434.999900,"should still be -657434.999900");
2255 ok(S_OK
== VarDateFromR8( 0.0, pDouble
), XOK
);
2256 ok(*pDouble
== 0.0,"0.0 should be 0.0");
2257 ok(S_OK
== VarDateFromR8( 1.0, pDouble
), XOK
);
2258 ok(*pDouble
== 1.0,"1.0 should be 1.0");
2259 ok(S_OK
== VarDateFromR8( 2.25, pDouble
), XOK
);
2260 ok(*pDouble
== 2.25,"2.25 should be 2.25");
2261 ok(S_OK
== VarDateFromR8( -2.0, pDouble
), XOK
);
2262 ok(*pDouble
== -2.0,"-2.0 should be -2.0");
2264 /* Need some parsing function in Linux to emulate this...
2267 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2270 rc
=VarDateFromStr( pOleChar
[i
], lcid
, 0, pDouble
);
2271 if (strrets_DATE
[i
].todo_rc
) {
2273 ok(rc
== strrets_DATE
[i
].error
,
2274 "VarDateFromStr([%d]=\"%s\") rc= %lx instead of %lx",
2275 i
,_pTestStrA
[i
],rc
,strrets_DATE
[i
].error
);
2278 ok(rc
== strrets_DATE
[i
].error
,
2279 "VarDateFromStr([%d]=\"%s\") rc= %lx instead of %lx",
2280 i
,_pTestStrA
[i
],rc
,strrets_DATE
[i
].error
);
2282 if (rc
== 0 && strrets_DATE
[i
].error
== 0) {
2283 if (strrets_DATE
[i
].todo_rc
|| strrets_DATE
[i
].todo_val
) {
2285 ok(EQ_DOUBLE(*pDouble
,strrets_DATE
[i
].retval
),
2286 "VarDateFromStr([%d]=\"%s\") got %.15f instead of %.15f",
2287 i
,_pTestStrA
[i
],*pDouble
,strrets_DATE
[i
].retval
);
2290 ok(EQ_DOUBLE(*pDouble
,strrets_DATE
[i
].retval
),
2291 "VarDateFromStr([%d]=\"%s\") got %.15f instead of %.15f",
2292 i
,_pTestStrA
[i
],*pDouble
,strrets_DATE
[i
].retval
);
2298 trace( "======== Testing VarBoolFromXXX ========\n");
2300 ok(S_OK
== VarBoolFromI4( 0, pBool
), XOK
);
2301 ok(VARIANT_FALSE
== *pBool
, "expected FALSE");
2302 ok(S_OK
== VarBoolFromI4( 1, pBool
), XOK
);
2303 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2304 ok(S_OK
== VarBoolFromI4( -1, pBool
), XOK
);
2305 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2306 ok(S_OK
== VarBoolFromI4( 2, pBool
), XOK
);
2307 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2309 ok(S_OK
== VarBoolFromUI1( ' ', pBool
), XOK
);
2310 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2311 ok(S_OK
== VarBoolFromUI1( '\0', pBool
), XOK
);
2312 ok(VARIANT_FALSE
== *pBool
, "expected FALSE");
2313 ok(S_OK
== VarBoolFromUI1( 0x0000, pBool
), XOK
);
2314 ok(VARIANT_FALSE
== *pBool
, "expected FALSE");
2315 ok(S_OK
== VarBoolFromUI1( (unsigned char)0xFFF, pBool
), XOK
);
2316 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2317 ok(S_OK
== VarBoolFromUI1( (unsigned char)0xFFFF, pBool
), XOK
);
2318 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2320 ok(S_OK
== VarBoolFromR8( 0.0, pBool
), XOK
);
2321 ok(VARIANT_FALSE
== *pBool
, "expected FALSE");
2322 ok(S_OK
== VarBoolFromR8( 1.1, pBool
), XOK
);
2323 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2324 ok(S_OK
== VarBoolFromR8( 0.5, pBool
), XOK
);
2325 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2326 ok(S_OK
== VarBoolFromR8( 0.49, pBool
), XOK
);
2327 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2328 ok(S_OK
== VarBoolFromR8( 0.51, pBool
), XOK
);
2329 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2330 ok(S_OK
== VarBoolFromR8( -0.5, pBool
), XOK
);
2331 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2332 ok(S_OK
== VarBoolFromR8( -0.49, pBool
), XOK
);
2333 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2334 ok(S_OK
== VarBoolFromR8( -0.51, pBool
), XOK
);
2335 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2338 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2341 rc
=VarBoolFromStr( pOleChar
[i
], lcid
, 0, pBool
);
2342 ok(rc
== strrets_B
[i
].error
,
2343 "VarBoolFromStr([%d]=\"%s\") rc=%lx instead of %lx",
2344 i
,_pTestStrA
[i
],rc
,strrets_B
[i
].error
);
2345 if (rc
== 0 && strrets_B
[i
].error
== 0) {
2346 ok(*pBool
== strrets_B
[i
].retval
,
2347 "VarBoolFromStr([%d]=\"%s\") got %x instead of %x",
2348 i
,_pTestStrA
[i
],*pBool
,strrets_B
[i
].retval
);
2354 trace( "======== Testing VarBSTRFromXXX ========\n");
2358 if (pVarBstrFromI1
) {
2359 ok(S_OK
== pVarBstrFromI1( -100, 0, 0, &bstr
), XOK
);
2360 ok(!strcmp(WtoA(bstr
),"\"-100\""),"should be string -100");
2363 ok(S_OK
== VarBstrFromUI1( 0x5A, 0, 0, &bstr
), XOK
);
2364 ok(!strcmp(WtoA(bstr
),"\"90\""),"should be string 90");
2365 ok(S_OK
== VarBstrFromI4( 2958465, 0, 0, &bstr
), XOK
);
2366 ok(!strcmp(WtoA(bstr
),"\"2958465\""),"should be string 2958465");
2372 for( i
=0; i
<20; i
++ )
2375 /* add an integer to the real number
2377 d
+= ((i
%9)+1) * pow( 10, i
);
2379 ok(S_OK
== VarBstrFromR8( d
, lcid
, 0, &bstr
), XOK
);
2380 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2381 ok(!strcmp(xval
,WtoA(bstr
)),
2382 "d is %.15f, should be cvt. to %s, but return val is %s",
2383 d
,strfromr8
[off
],WtoA(bstr
));
2386 ok(S_OK
== VarBstrFromR8( -d
, lcid
, 0, &bstr
), XOK
);
2387 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2388 ok(!strcmp(xval
,WtoA(bstr
)),
2389 "d is %.15f, should be cvt. to %s, but return val is %s",
2390 -d
,strfromr8
[off
],WtoA(bstr
));
2394 for( i
=0; i
<20; i
++ )
2397 /* add a decimal to the real number
2399 d
+= ((i
%9)+1) * pow( 10, (i
*-1) );
2400 ok(S_OK
== VarBstrFromR8( d
, lcid
, 0, &bstr
), XOK
);
2401 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2402 ok(!strcmp(xval
,WtoA(bstr
)),
2403 "d is %.15f, should be cvt. to %s, but return val is %s",
2404 d
,strfromr8
[off
],WtoA(bstr
));
2406 ok(S_OK
== VarBstrFromR8( d
-1, lcid
, 0, &bstr
), XOK
);
2407 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2408 ok(!strcmp(xval
,WtoA(bstr
)),
2409 "d is %.15f, should be cvt. to %s, but return val is %s",
2410 d
-1,strfromr8
[off
],WtoA(bstr
));
2412 ok(S_OK
== VarBstrFromR8( -d
, lcid
, 0, &bstr
), XOK
);
2413 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2414 ok(!strcmp(xval
,WtoA(bstr
)),
2415 "d is %.15f, should be cvt. to %s, but return val is %s",
2416 -d
,strfromr8
[off
],WtoA(bstr
));
2421 for( i
=0; i
<20; i
++ )
2424 /* add an integer to the real number
2426 d
+= ((i
%9)+1) * pow( 10, i
);
2427 /* add a decimal to the real number
2429 d
+= ((i
%9)+1) * pow( 10, (i
*-1) );
2430 ok(S_OK
== VarBstrFromR8( d
, lcid
, 0, &bstr
), XOK
);
2431 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2432 ok(!strcmp(xval
,WtoA(bstr
)),
2433 "d is %.15f, should be cvt. to %s, but return val is %s",
2434 d
,strfromr8
[off
],WtoA(bstr
));
2436 ok(S_OK
== VarBstrFromR8( -d
, lcid
, 0, &bstr
), XOK
);
2437 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2438 ok(!strcmp(xval
,WtoA(bstr
)),
2439 "d is %.15f, should be cvt. to %s, but return val is %s",
2440 -d
,strfromr8
[off
],WtoA(bstr
));
2445 for( i
=0; i
<10; i
++ )
2448 /* add an integer to the real number
2450 d
+= ((i
%9)+1) * pow( 10, i
);
2451 ok(S_OK
== VarBstrFromR4( (float)d
, lcid
, 0, &bstr
), XOK
);
2452 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2453 ok(!strcmp(xval
,WtoA(bstr
)),
2454 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2455 i
,d
,strfromr8
[off
],WtoA(bstr
));
2457 ok(S_OK
== VarBstrFromR4( (float)-d
, lcid
, 0, &bstr
), XOK
);
2458 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2459 ok(!strcmp(xval
,WtoA(bstr
)),
2460 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2461 i
,-d
,strfromr8
[off
],WtoA(bstr
));
2465 for( i
=0; i
<10; i
++ )
2468 /* add a decimal to the real number
2470 d
+= ((i
%9)+1) * pow( 10, (i
*-1) );
2471 ok(S_OK
== VarBstrFromR4( (float)d
, lcid
, 0, &bstr
), XOK
);
2472 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2473 ok(!strcmp(xval
,WtoA(bstr
)),
2474 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2475 i
,d
,strfromr8
[off
],WtoA(bstr
));
2477 ok(S_OK
== VarBstrFromR4( (float)(d
-1), lcid
, 0, &bstr
), XOK
);
2478 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2479 ok(!strcmp(xval
,WtoA(bstr
)),
2480 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2481 i
,d
-1,strfromr8
[off
],WtoA(bstr
));
2483 ok(S_OK
== VarBstrFromR4( (float)-d
, lcid
, 0, &bstr
), XOK
);
2484 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2485 ok(!strcmp(xval
,WtoA(bstr
)),
2486 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2487 i
,-d
,strfromr8
[off
],WtoA(bstr
));
2492 for( i
=0; i
<10; i
++ )
2494 static int istodo
[10]={0,0,0,0,0,1,0,0,0,0};
2496 /* add an integer to the real number
2498 d
+= ((i
%9)+1) * pow( 10, i
);
2499 /* add a decimal to the real number
2501 d
+= ((i
%9)+1) * pow( 10, (i
*-1) );
2502 ok(S_OK
== VarBstrFromR4( (float)d
, lcid
, 0, &bstr
), XOK
);
2503 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2506 ok(!strcmp(xval
,WtoA(bstr
)),
2507 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2508 i
,d
,strfromr8
[off
],WtoA(bstr
));
2511 ok(!strcmp(xval
,WtoA(bstr
)),
2512 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2513 i
,d
,strfromr8
[off
],WtoA(bstr
));
2516 ok(S_OK
== VarBstrFromR4( (float)-d
, lcid
, 0, &bstr
), XOK
);
2517 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2520 ok(!strcmp(xval
,WtoA(bstr
)),
2521 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2522 i
,-d
,strfromr8
[off
],WtoA(bstr
));
2525 ok(!strcmp(xval
,WtoA(bstr
)),
2526 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2527 i
,-d
,strfromr8
[off
],WtoA(bstr
));
2532 ok(S_OK
== VarBstrFromBool( 0x00, lcid
, 0, &bstr
), XOK
);
2533 ok(!strcmp(WtoA(bstr
),"\"False\""),"should be 'False'");
2534 ok(S_OK
== VarBstrFromBool( 0xFF, lcid
, 0, &bstr
), XOK
);
2535 ok(!strcmp(WtoA(bstr
),"\"True\""),"should be 'True'");
2537 ok(S_OK
== VarBstrFromDate( 0.0, lcid
, 0, &bstr
), XOK
);
2539 ok(!strcmp(WtoA(bstr
),"\"12:00:00 AM\""),
2540 "should be '12:00:00 AM', but is %s\n",WtoA(bstr
));
2543 ok(S_OK
== VarBstrFromDate( 3.34, lcid
, 0, &bstr
), XOK
);
2545 ok(strcmp(WtoA(bstr
),"\"1/2/1900 8:09:36 AM\"")==0 ||
2546 strcmp(WtoA(bstr
),"\"1/2/00 8:09:36 AM\"")==0 /* Win95 */,
2547 "should be '1/2/1900 8:09:36 AM', but is %s\n",WtoA(bstr
));
2550 ok(S_OK
== VarBstrFromDate( 3339.34, lcid
, 0, &bstr
), XOK
);
2552 ok(strcmp(WtoA(bstr
),"\"2/20/1909 8:09:36 AM\"")==0 ||
2553 strcmp(WtoA(bstr
),"\"2/20/09 8:09:36 AM\"")==0 /* Win95 */,
2554 "should be '2/20/1909 8:09:36 AM', but is %s\n",WtoA(bstr
));
2557 ok(S_OK
== VarBstrFromDate( 365.00, lcid
, 0, &bstr
), XOK
);
2559 ok(strcmp(WtoA(bstr
),"\"12/30/1900\"")==0 ||
2560 strcmp(WtoA(bstr
),"\"12/30/00\"")==0 /* Win95 */,
2561 "should be '12/30/1900', but is %s\n",WtoA(bstr
));
2564 ok(S_OK
== VarBstrFromDate( 365.25, lcid
, 0, &bstr
), XOK
);
2566 ok(strcmp(WtoA(bstr
),"\"12/30/1900 6:00:00 AM\"")==0 ||
2567 strcmp(WtoA(bstr
),"\"12/30/00 6:00:00 AM\"")==0 /* Win95 */,
2568 "should be '12/30/1900 6:00:00 AM', but is %s\n",WtoA(bstr
));
2571 ok(S_OK
== VarBstrFromDate( 1461.0, lcid
, 0, &bstr
), XOK
);
2573 ok(strcmp(WtoA(bstr
),"\"12/31/1903\"")==0 ||
2574 strcmp(WtoA(bstr
),"\"12/31/03\"")==0 /* Win95 */,
2575 "should be '12/31/1903', but is %s\n",WtoA(bstr
));
2578 ok(S_OK
== VarBstrFromDate( 1461.5, lcid
, 0, &bstr
), XOK
);
2580 ok(strcmp(WtoA(bstr
),"\"12/31/1903 12:00:00 PM\"")==0 ||
2581 strcmp(WtoA(bstr
),"\"12/31/03 12:00:00 PM\"")==0 /* Win95 */,
2582 "should be '12/31/1903 12:00:00 PM', but is %s\n",WtoA(bstr
));
2585 /* Test variant API...
2587 trace( "======== Testing Hi-Level Variant API ========\n");
2589 bstr
= SysAllocString( pOleChar
[4] );
2591 VariantClear( &va
);
2599 V_VT(&va
) = VT_BSTR
;
2600 V_UNION(&va
,bstrVal
) = bstr
;
2601 ok(S_OK
== VariantClear( &va
), XOK
);
2602 SysFreeString( bstr
);
2603 SysFreeString( bstr
);
2605 ok(S_OK
== VariantCopy( &vb
, &va
), XOK
);
2606 ok(S_OK
== VariantClear( &vb
), XOK
);
2607 ok(S_OK
== VariantClear( &va
), XOK
);
2611 V_UNION(&va
,dblVal
) = d
;
2612 ok(S_OK
== VariantCopy( &va
, &va
), XOK
);
2613 ok(V_R8(&va
) == 4.123,"should be 4.123");
2615 V_VT(&va
) = VT_R8
| VT_BYREF
;
2617 V_UNION(&va
,pdblVal
) = &d
;
2618 ok(S_OK
== VariantCopyInd( &va
, &va
), XOK
);
2619 ok(V_R8(&va
) == 31.123,"should be 31.123");
2623 V_UNION(&va
,dblVal
) = d
;
2624 ok(S_OK
== VariantCopy( &vb
, &va
), XOK
);
2625 ok(V_R8(&vb
) == 1.123,"should be 1.123");
2627 V_VT(&va
) = VT_R8
| VT_BYREF
;
2629 V_UNION(&va
,pdblVal
) = &d
;
2630 ok(S_OK
== VariantCopy( &vb
, &va
), XOK
);
2631 ok(*(V_R8REF(&vb
)) == 123.123,"should be 123.123");
2633 V_VT(&va
) = VT_R8
| VT_BYREF
;
2635 V_UNION(&va
,pdblVal
) = &d
;
2636 ok(S_OK
== VariantCopyInd( &vb
, &va
), XOK
);
2637 ok(V_R8(&vb
) == 111.2,"should be 111.2");
2639 V_VT(&va
) = VT_R8
| VT_BYREF
;
2641 V_UNION(&va
,pdblVal
) = &d
;
2642 ok(S_OK
== VariantChangeTypeEx( &va
, &va
, lcid
, 0, VT_I2
), XOK
);
2643 ok(V_VT(&va
) == VT_I2
,"should be type VT_I2");
2646 V_UNION(&va
,intVal
) = 4;
2647 ok(S_OK
== VariantChangeTypeEx(&vb
, &va
, lcid
, 0, VT_BSTR
), XOK
);
2648 ok(!strcmp(WtoA(V_BSTR(&vb
)),"\"4\""),"should be 4");
2650 V_VT(&va
) = VT_DATE
;
2651 V_UNION(&va
,date
) = 34465.332431;
2652 ok(S_OK
== VariantChangeTypeEx(&vb
, &va
, lcid
, 0, VT_BSTR
), XOK
);
2654 ok(strcmp(WtoA(V_BSTR(&vb
)),"\"5/11/1994 7:58:42 AM\"")==0 ||
2655 strcmp(WtoA(V_BSTR(&vb
)),"\"5/11/94 7:58:42 AM\"")==0 /* Win95 */,
2656 "should be 5/11/94 7:58:42 AM got %s",WtoA(V_BSTR(&vb
)));
2660 V_VT(&va
) = VT_BSTR
;
2661 V_UNION(&va
,bstrVal
) = bstr
;
2662 ok(S_OK
== VariantChangeTypeEx(&vb
, &va
, lcid
, 0, VT_R8
), XOK
);
2663 ok(V_R8(&vb
) == -0.490000,"should be -0.49");
2665 V_VT(&vc
) = VT_BSTR
| VT_BYREF
;
2666 V_UNION(&vc
,pbstrVal
) = &bstr
;
2667 V_VT(&vb
) = VT_VARIANT
| VT_BYREF
;
2668 V_UNION(&vb
,pvarVal
) = &vc
;
2669 V_VT(&va
) = VT_VARIANT
| VT_BYREF
;
2670 V_UNION(&va
,pvarVal
) = &vb
;
2671 ok(E_INVALIDARG
== VariantCopyInd( &vd
, &va
), "expect E_INVALIDARG");
2673 /* test what happens when bad vartypes are passed in */
2674 trace( "======== Testing different VARTYPES ========\n" );
2676 for( i
=0; i
<sizeof(vartypes
)/sizeof(vartypes
[0]); i
++ )
2678 /* Trying to use variants that are set to be BSTR but
2679 * do not contain a valid pointer makes the program crash
2680 * in Windows so we will skip those. We do not need them
2681 * anyway to illustrate the behavior.
2683 V_VT(&va
) = vartypes
[i
].ind
;
2685 V_UNION(&va
,dblVal
) = d
;
2686 rc
= VariantCopyInd( &vb
, &va
);
2687 if (vartypes
[i
].todoind1
) {
2689 ok(vartypes
[i
].vcind1
== rc
,
2690 "%d: vt %d, return value %lx, expected was %lx",
2691 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcind1
);
2694 ok(vartypes
[i
].vcind1
== rc
,
2695 "%d: vt %d, return value %lx, expected was %lx",
2696 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcind1
);
2698 V_VT(&va
) = vartypes
[i
].ind
| VT_BYREF
;
2700 V_UNION(&va
,pdblVal
) = &d
;
2701 rc
= VariantCopyInd( &vb
, &va
);
2702 if (vartypes
[i
].todoind2
) {
2704 ok(vartypes
[i
].vcind2
== rc
,
2705 "%d: vt %d, return value %lx, expected was %lx",
2706 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcind2
);
2709 ok(vartypes
[i
].vcind2
== rc
,
2710 "%d: vt %d, return value %lx, expected was %lx",
2711 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcind2
);
2715 V_UNION(&va
,dblVal
) = d
;
2716 rc
= VariantChangeTypeEx( &vb
, &va
, lcid
, 0, (VARTYPE
)i
);
2717 if (vartypes
[i
].todowcex1
) {
2719 ok(vartypes
[i
].vcex1
== rc
|| rc
== DISP_E_BADVARTYPE
,
2720 "%d: vt %d, return value %lx, expected was %lx",
2721 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcex1
);
2724 ok(vartypes
[i
].vcex1
== rc
|| rc
== DISP_E_BADVARTYPE
,
2725 "%d: vt %d, return value %lx, expected was %lx",
2726 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcex1
);
2730 V_UNION(&va
,dblVal
) = d
;
2731 rc
= VariantChangeTypeEx( &vb
, &va
, lcid
, 0, (VARTYPE
)(i
| VT_BYREF
) );
2732 if (vartypes
[i
].todowcex2
) {
2734 ok(vartypes
[i
].vcex2
== rc
|| rc
== DISP_E_BADVARTYPE
,
2735 "%d: vt %d, return value %lx, expected was %lx",
2736 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcex2
);
2739 ok(vartypes
[i
].vcex2
== rc
|| rc
== DISP_E_BADVARTYPE
,
2740 "%d: vt %d, return value %lx, expected was %lx",
2741 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcex2
);
2746 V_UNION(&va
,dblVal
) = d
;
2747 ok(DISP_E_BADVARTYPE
== VariantClear( &va
), "should give DISP_E_BADVARTYPE");
2749 VariantClear( &va
);
2750 VariantClear( &vb
);
2751 VariantClear( &vc
);
2752 VariantClear( &vd
);
2753 VariantClear( &ve
);
2754 /* There is alot of memory leaks but this is simply a test program.
2758 static void test_VariantInit(void)
2762 /* Test that VariantInit() only sets the type */
2763 memset(&v1
, -1, sizeof(v1
));
2765 V_VT(&v2
) = VT_EMPTY
;
2767 ok(!memcmp(&v1
, &v2
, sizeof(v1
)), "VariantInit() set extra fields\n");
2770 /* All possible combinations of extra V_VT() flags */
2771 static const VARTYPE ExtraFlags
[16] =
2780 VT_VECTOR
|VT_RESERVED
,
2781 VT_VECTOR
|VT_ARRAY
|VT_BYREF
,
2782 VT_VECTOR
|VT_ARRAY
|VT_RESERVED
,
2783 VT_VECTOR
|VT_BYREF
|VT_RESERVED
,
2784 VT_VECTOR
|VT_ARRAY
|VT_BYREF
|VT_RESERVED
,
2786 VT_ARRAY
|VT_RESERVED
,
2787 VT_ARRAY
|VT_BYREF
|VT_RESERVED
,
2788 VT_BYREF
|VT_RESERVED
,
2791 static void test_VariantClear(void)
2798 /* Crashes: Native does not test input for NULL, so neither does Wine */
2799 hres
= VariantClear(NULL
);
2802 /* Only the type field is set, to VT_EMPTY */
2805 hres
= VariantClear(&v
);
2806 ok(hres
== S_OK
&& V_VT(&v
) == VT_EMPTY
, "VariantClear: Type set to %d\n", V_VT(&v
));
2807 ok(V_UI4(&v
) == ~0u, "VariantClear: Overwrote value\n");
2809 /* Test all possible V_VT values.
2810 * Also demonstrates that null pointers in 'v' are not dereferenced.
2811 * Individual variant tests should test VariantClear() with non-NULL values.
2813 for (i
= 0; i
< sizeof(ExtraFlags
)/sizeof(ExtraFlags
[0]); i
++)
2817 for (vt
= 0; vt
<= VT_BSTR_BLOB
; vt
++)
2819 HRESULT hExpected
= DISP_E_BADVARTYPE
;
2821 memset(&v
, 0, sizeof(v
));
2822 V_VT(&v
) = vt
| ExtraFlags
[i
];
2824 hres
= VariantClear(&v
);
2826 /* Only the following flags/types are valid */
2827 if ((vt
<= VT_LPWSTR
|| vt
== VT_RECORD
|| vt
== VT_CLSID
) &&
2828 vt
!= (VARTYPE
)15 &&
2829 (vt
< (VARTYPE
)24 || vt
> (VARTYPE
)31) &&
2830 (!(ExtraFlags
[i
] & (VT_BYREF
|VT_ARRAY
)) || vt
> VT_NULL
) &&
2831 (ExtraFlags
[i
] == 0 || ExtraFlags
[i
] == VT_BYREF
|| ExtraFlags
[i
] == VT_ARRAY
||
2832 ExtraFlags
[i
] == (VT_ARRAY
|VT_BYREF
)))
2835 ok(hres
== hExpected
, "VariantClear: expected 0x%lX, got 0x%lX for vt %d | 0x%X\n",
2836 hExpected
, hres
, vt
, ExtraFlags
[i
]);
2841 /* Macros for converting and testing the result of VarParseNumFromStr */
2843 #define CONVERTN(str,dig,flags) MultiByteToWideChar(CP_ACP,0,str,-1,buff,sizeof(buff)); \
2844 memset(rgb, FAILDIG, sizeof(rgb)); memset(&np,-1,sizeof(np)); np.cDig = dig; np.dwInFlags = flags; \
2845 hres = VarParseNumFromStr(buff,lcid,0,&np,rgb)
2846 #define CONVERT(str,flags) CONVERTN(str,sizeof(rgb),flags)
2847 #define EXPECT(a,b,c,d,e,f) ok(hres == (HRESULT)S_OK, "Call failed, hres = %08lx\n", hres); \
2848 if (hres == (HRESULT)S_OK) { \
2849 ok(np.cDig == (a), "Expected cDig = %d, got %d\n", (a), np.cDig); \
2850 ok(np.dwInFlags == (b), "Expected dwInFlags = 0x%lx, got 0x%lx\n", (ULONG)(b), np.dwInFlags); \
2851 ok(np.dwOutFlags == (c), "Expected dwOutFlags = 0x%lx, got 0x%lx\n", (ULONG)(c), np.dwOutFlags); \
2852 ok(np.cchUsed == (d), "Expected cchUsed = %d, got %d\n", (d), np.cchUsed); \
2853 ok(np.nBaseShift == (e), "Expected nBaseShift = %d, got %d\n", (e), np.nBaseShift); \
2854 ok(np.nPwr10 == (f), "Expected nPwr10 = %d, got %d\n", (f), np.nPwr10); \
2856 #define EXPECTRGB(a,b) ok(rgb[a] == b, "Digit[%d], expected %d, got %d\n", a, b, rgb[a])
2857 #define EXPECTFAIL ok(hres == (HRESULT)DISP_E_TYPEMISMATCH, "Call succeeded, hres = %08lx\n", hres)
2858 #define EXPECT2(a,b) EXPECTRGB(0,a); EXPECTRGB(1,b)
2860 static void test_VarParseNumFromStr(void)
2864 /* Ensure all tests are using the same locale characters for '$', ',' etc */
2865 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
,SUBLANG_ENGLISH_US
),SORT_DEFAULT
);
2871 /* Consume a single digit */
2873 EXPECT(1,0,0,1,0,0);
2876 /* cDig is not literal digits - zeros are suppressed and nPwr10 is increased */
2878 EXPECT(1,0,0,2,0,1);
2879 /* Note: Win32 writes the trailing zeros if they are within cDig's limits,
2880 * but then excludes them from the returned cDig count.
2881 * In our implementation we don't bother writing them at all.
2885 /* if cDig is too small and numbers follow, sets INEXACT */
2886 CONVERTN("11",1, 0);
2887 EXPECT(1,0,NUMPRS_INEXACT
,2,0,1);
2890 /* Strips leading zeros */
2892 EXPECT(1,0,0,2,0,0);
2895 /* Strips leading zeros */
2896 CONVERTN("01",1, 0);
2897 EXPECT(1,0,0,2,0,0);
2901 /* Fails on non digits */
2904 EXPECTRGB(0,FAILDIG
);
2906 /** NUMPRS_LEADING_WHITE/NUMPRS_TRAILING_WHITE **/
2908 /* Without flag, fails on whitespace */
2911 EXPECTRGB(0,FAILDIG
);
2914 /* With flag, consumes whitespace */
2915 CONVERT(" 0", NUMPRS_LEADING_WHITE
);
2916 EXPECT(1,NUMPRS_LEADING_WHITE
,NUMPRS_LEADING_WHITE
,2,0,0);
2919 /* Test TAB once, then assume it acts as space for all cases */
2920 CONVERT("\t0", NUMPRS_LEADING_WHITE
);
2921 EXPECT(1,NUMPRS_LEADING_WHITE
,NUMPRS_LEADING_WHITE
,2,0,0);
2925 /* Doesn't pick up trailing whitespace without flag */
2927 EXPECT(1,0,0,1,0,0);
2930 /* With flag, consumes trailing whitespace */
2931 CONVERT("0 ", NUMPRS_TRAILING_WHITE
);
2932 EXPECT(1,NUMPRS_TRAILING_WHITE
,NUMPRS_TRAILING_WHITE
,2,0,0);
2935 /* Leading flag only consumes leading */
2936 CONVERT(" 0 ", NUMPRS_LEADING_WHITE
);
2937 EXPECT(1,NUMPRS_LEADING_WHITE
,NUMPRS_LEADING_WHITE
,2,0,0);
2940 /* Both flags consumes both */
2941 CONVERT(" 0 ", NUMPRS_LEADING_WHITE
|NUMPRS_TRAILING_WHITE
);
2942 EXPECT(1,NUMPRS_LEADING_WHITE
|NUMPRS_TRAILING_WHITE
,NUMPRS_LEADING_WHITE
|NUMPRS_TRAILING_WHITE
,3,0,0);
2945 /** NUMPRS_LEADING_PLUS/NUMPRS_TRAILING_PLUS **/
2947 /* Without flag, fails on + */
2950 EXPECTRGB(0,FAILDIG
);
2952 /* With flag, consumes + */
2953 CONVERT("+0", NUMPRS_LEADING_PLUS
);
2954 EXPECT(1,NUMPRS_LEADING_PLUS
,NUMPRS_LEADING_PLUS
,2,0,0);
2957 /* Without flag, doesn't consume trailing + */
2959 EXPECT(1,0,0,1,0,0);
2962 /* With flag, consumes trailing + */
2963 CONVERT("0+", NUMPRS_TRAILING_PLUS
);
2964 EXPECT(1,NUMPRS_TRAILING_PLUS
,NUMPRS_TRAILING_PLUS
,2,0,0);
2967 /* With leading flag, doesn't consume trailing + */
2968 CONVERT("+0+", NUMPRS_LEADING_PLUS
);
2969 EXPECT(1,NUMPRS_LEADING_PLUS
,NUMPRS_LEADING_PLUS
,2,0,0);
2972 /* Trailing + doesn't get consumed if we specify both (unlike whitespace) */
2973 CONVERT("+0+", NUMPRS_LEADING_PLUS
|NUMPRS_TRAILING_PLUS
);
2974 EXPECT(1,NUMPRS_LEADING_PLUS
|NUMPRS_TRAILING_PLUS
,NUMPRS_LEADING_PLUS
,2,0,0);
2977 /** NUMPRS_LEADING_MINUS/NUMPRS_TRAILING_MINUS **/
2979 /* Without flag, fails on - */
2982 EXPECTRGB(0,FAILDIG
);
2984 /* With flag, consumes - */
2985 CONVERT("-0", NUMPRS_LEADING_MINUS
);
2986 EXPECT(1,NUMPRS_LEADING_MINUS
,NUMPRS_NEG
|NUMPRS_LEADING_MINUS
,2,0,0);
2989 /* Without flag, doesn't consume trailing - */
2991 EXPECT(1,0,0,1,0,0);
2994 /* With flag, consumes trailing - */
2995 CONVERT("0-", NUMPRS_TRAILING_MINUS
);
2996 EXPECT(1,NUMPRS_TRAILING_MINUS
,NUMPRS_NEG
|NUMPRS_TRAILING_MINUS
,2,0,0);
2999 /* With leading flag, doesn't consume trailing - */
3000 CONVERT("-0-", NUMPRS_LEADING_MINUS
);
3001 EXPECT(1,NUMPRS_LEADING_MINUS
,NUMPRS_NEG
|NUMPRS_LEADING_MINUS
,2,0,0);
3004 /* Trailing - doesn't get consumed if we specify both (unlike whitespace) */
3005 CONVERT("-0-", NUMPRS_LEADING_MINUS
|NUMPRS_TRAILING_MINUS
);
3006 EXPECT(1,NUMPRS_LEADING_MINUS
|NUMPRS_TRAILING_MINUS
,NUMPRS_NEG
|NUMPRS_LEADING_MINUS
,2,0,0);
3009 /** NUMPRS_HEX_OCT **/
3011 /* Could be hex, octal or decimal - With flag reads as decimal */
3012 CONVERT("0", NUMPRS_HEX_OCT
);
3013 EXPECT(1,NUMPRS_HEX_OCT
,0,1,0,0);
3016 /* Doesn't recognise hex in .asm sytax */
3017 CONVERT("0h", NUMPRS_HEX_OCT
);
3018 EXPECT(1,NUMPRS_HEX_OCT
,0,1,0,0);
3021 /* Doesn't fail with valid leading string but no digits */
3022 CONVERT("0x", NUMPRS_HEX_OCT
);
3023 EXPECT(1,NUMPRS_HEX_OCT
,0,1,0,0);
3026 /* Doesn't recognise hex format humbers at all! */
3027 CONVERT("0x0", NUMPRS_HEX_OCT
);
3028 EXPECT(1,NUMPRS_HEX_OCT
,0,1,0,0);
3031 /* Doesn't recognise plain hex digits either */
3032 CONVERT("FE", NUMPRS_HEX_OCT
);
3034 EXPECTRGB(0,FAILDIG
);
3037 CONVERT("0100", NUMPRS_HEX_OCT
);
3038 EXPECT(1,NUMPRS_HEX_OCT
,0,4,0,2);
3045 EXPECTRGB(3,FAILDIG
);
3047 /** NUMPRS_PARENS **/
3049 /* Empty parens = error */
3050 CONVERT("()", NUMPRS_PARENS
);
3052 EXPECTRGB(0,FAILDIG
);
3054 /* With flag, trailing parens not consumed */
3055 CONVERT("0()", NUMPRS_PARENS
);
3056 EXPECT(1,NUMPRS_PARENS
,0,1,0,0);
3059 /* With flag, Number in parens made negative and parens consumed */
3060 CONVERT("(0)", NUMPRS_PARENS
);
3061 EXPECT(1,NUMPRS_PARENS
,NUMPRS_NEG
|NUMPRS_PARENS
,3,0,0);
3064 /** NUMPRS_THOUSANDS **/
3066 /* With flag, thousands sep. not needed */
3067 CONVERT("0", NUMPRS_THOUSANDS
);
3068 EXPECT(1,NUMPRS_THOUSANDS
,0,1,0,0);
3071 /* With flag, thousands sep. and following digits consumed */
3072 CONVERT("1,000", NUMPRS_THOUSANDS
);
3073 EXPECT(1,NUMPRS_THOUSANDS
,NUMPRS_THOUSANDS
,5,0,3);
3076 /* With flag and decimal point, thousands sep. but not decimals consumed */
3077 CONVERT("1,000.0", NUMPRS_THOUSANDS
);
3078 EXPECT(1,NUMPRS_THOUSANDS
,NUMPRS_THOUSANDS
,5,0,3);
3081 /** NUMPRS_CURRENCY **/
3083 /* Without flag, chokes on currency sign */
3086 EXPECTRGB(0,FAILDIG
);
3088 /* With flag, consumes currency sign */
3089 CONVERT("$11", NUMPRS_CURRENCY
);
3090 EXPECT(2,NUMPRS_CURRENCY
,NUMPRS_CURRENCY
,3,0,0);
3092 EXPECTRGB(2,FAILDIG
);
3094 /* With flag only, doesn't consume decimal point */
3095 CONVERT("$11.1", NUMPRS_CURRENCY
);
3096 EXPECT(2,NUMPRS_CURRENCY
,NUMPRS_CURRENCY
,3,0,0);
3098 EXPECTRGB(2,FAILDIG
);
3100 /* With flag and decimal flag, consumes decimal point and following digits */
3101 CONVERT("$11.1", NUMPRS_CURRENCY
|NUMPRS_DECIMAL
);
3102 EXPECT(3,NUMPRS_CURRENCY
|NUMPRS_DECIMAL
,NUMPRS_CURRENCY
|NUMPRS_DECIMAL
,5,0,-1);
3105 EXPECTRGB(3,FAILDIG
);
3107 /* Thousands flag can only be used with currency */
3108 CONVERT("$1,234", NUMPRS_CURRENCY
|NUMPRS_THOUSANDS
);
3109 EXPECT(4,NUMPRS_CURRENCY
|NUMPRS_THOUSANDS
,NUMPRS_CURRENCY
|NUMPRS_THOUSANDS
,6,0,0);
3113 EXPECTRGB(4,FAILDIG
);
3115 /** NUMPRS_DECIMAL **/
3117 /* With flag, consumes decimal point */
3118 CONVERT("1.1", NUMPRS_DECIMAL
);
3119 EXPECT(2,NUMPRS_DECIMAL
,NUMPRS_DECIMAL
,3,0,-1);
3121 EXPECTRGB(2,FAILDIG
);
3123 /* With flag, consumes decimal point. Skipping the decimal part is not an error */
3124 CONVERT("1.", NUMPRS_DECIMAL
);
3125 EXPECT(1,NUMPRS_DECIMAL
,NUMPRS_DECIMAL
,2,0,0);
3128 /* Consumes only one decimal point */
3129 CONVERT("1.1.", NUMPRS_DECIMAL
);
3130 EXPECT(2,NUMPRS_DECIMAL
,NUMPRS_DECIMAL
,3,0,-1);
3132 EXPECTRGB(2,FAILDIG
);
3134 /** NUMPRS_EXPONENT **/
3136 /* Without flag, doesn't consume exponent */
3138 EXPECT(1,0,0,1,0,0);
3141 /* With flag, consumes exponent */
3142 CONVERT("1e1", NUMPRS_EXPONENT
);
3143 EXPECT(1,NUMPRS_EXPONENT
,NUMPRS_EXPONENT
,3,0,1);
3146 /* Negative exponents are accepted without flags */
3147 CONVERT("1e-1", NUMPRS_EXPONENT
);
3148 EXPECT(1,NUMPRS_EXPONENT
,NUMPRS_EXPONENT
,4,0,-1);
3151 /* As are positive exponents and leading exponent 0's */
3152 CONVERT("1e+01", NUMPRS_EXPONENT
);
3153 EXPECT(1,NUMPRS_EXPONENT
,NUMPRS_EXPONENT
,5,0,1);
3156 /* Doesn't consume a real number exponent */
3157 CONVERT("1e1.", NUMPRS_EXPONENT
);
3158 EXPECT(1,NUMPRS_EXPONENT
,NUMPRS_EXPONENT
,3,0,1);
3161 /* Powers of 10 are calculated from the position of any decimal point */
3162 CONVERT("1.5e20", NUMPRS_EXPONENT
|NUMPRS_DECIMAL
);
3163 EXPECT(2,NUMPRS_EXPONENT
|NUMPRS_DECIMAL
,NUMPRS_EXPONENT
|NUMPRS_DECIMAL
,6,0,19);
3166 CONVERT("1.5e-20", NUMPRS_EXPONENT
|NUMPRS_DECIMAL
);
3167 EXPECT(2,NUMPRS_EXPONENT
|NUMPRS_DECIMAL
,NUMPRS_EXPONENT
|NUMPRS_DECIMAL
,7,0,-21);
3170 /** NUMPRS_USE_ALL **/
3172 /* Flag expects all digits */
3173 CONVERT("0", NUMPRS_USE_ALL
);
3174 EXPECT(1,NUMPRS_USE_ALL
,0,1,0,0);
3177 /* Rejects anything trailing */
3178 CONVERT("0 ", NUMPRS_USE_ALL
);
3182 /* Unless consumed by trailing flag */
3183 CONVERT("0 ", NUMPRS_USE_ALL
|NUMPRS_TRAILING_WHITE
);
3184 EXPECT(1,NUMPRS_USE_ALL
|NUMPRS_TRAILING_WHITE
,NUMPRS_TRAILING_WHITE
,2,0,0);
3187 /** Combinations **/
3189 /* Leading whitepace and plus, doesn't consume trailing whitespace */
3190 CONVERT("+ 0 ", NUMPRS_LEADING_PLUS
|NUMPRS_LEADING_WHITE
);
3191 EXPECT(1,NUMPRS_LEADING_PLUS
|NUMPRS_LEADING_WHITE
,NUMPRS_LEADING_PLUS
|NUMPRS_LEADING_WHITE
,3,0,0);
3194 /* Order of whitepace and plus is unimportant */
3195 CONVERT(" +0", NUMPRS_LEADING_PLUS
|NUMPRS_LEADING_WHITE
);
3196 EXPECT(1,NUMPRS_LEADING_PLUS
|NUMPRS_LEADING_WHITE
,NUMPRS_LEADING_PLUS
|NUMPRS_LEADING_WHITE
,3,0,0);
3199 /* Leading whitespace can be repeated */
3200 CONVERT(" + 0", NUMPRS_LEADING_PLUS
|NUMPRS_LEADING_WHITE
);
3201 EXPECT(1,NUMPRS_LEADING_PLUS
|NUMPRS_LEADING_WHITE
,NUMPRS_LEADING_PLUS
|NUMPRS_LEADING_WHITE
,4,0,0);
3204 /* But plus/minus etc. cannot */
3205 CONVERT("+ +0", NUMPRS_LEADING_PLUS
|NUMPRS_LEADING_WHITE
);
3207 EXPECTRGB(0,FAILDIG
);
3209 /* Inexact is not set if trailing zeros are removed */
3210 CONVERTN("10", 1, 0);
3211 EXPECT(1,0,0,2,0,1);
3214 /* Make sure a leading 0 is stripped but decimals after it get read */
3215 CONVERT("-0.51", NUMPRS_STD
);
3216 EXPECT(2,NUMPRS_STD
,NUMPRS_NEG
|NUMPRS_DECIMAL
|NUMPRS_LEADING_MINUS
,5,0,-2);
3220 /* Macros for converting and testing the result of VarNumFromParseNum */
3221 #define SETRGB(indx,val) if (!indx) memset(rgb, FAILDIG, sizeof(rgb)); rgb[indx] = val
3223 #define CONVERT(a,b,c,d,e,f,bits) \
3224 np.cDig = (a); np.dwInFlags = (b); np.dwOutFlags = (c); np.cchUsed = (d); \
3225 np.nBaseShift = (e); np.nPwr10 = (f); hres = VarNumFromParseNum(&np, rgb, bits, &vOut)
3226 #define EXPECT_OVERFLOW ok(hres == (HRESULT)DISP_E_OVERFLOW, "Expected overflow, hres = %08lx\n", hres)
3227 #define EXPECT_OK ok(hres == (HRESULT)S_OK, "Call failed, hres = %08lx\n", hres); \
3228 if (hres == (HRESULT)S_OK)
3229 #define EXPECT_TYPE(typ) ok(V_VT(&vOut) == typ,"Expected Type = " #typ ", got %d\n", V_VT(&vOut))
3230 #define EXPECT_I1(val) EXPECT_OK { EXPECT_TYPE(VT_I1); \
3231 ok(V_I1(&vOut) == val, "Expected i1 = %d, got %d\n", (signed char)val, V_I1(&vOut)); }
3232 #define EXPECT_UI1(val) EXPECT_OK { EXPECT_TYPE(VT_UI1); \
3233 ok(V_UI1(&vOut) == val, "Expected ui1 = %d, got %d\n", (BYTE)val, V_UI1(&vOut)); }
3234 #define EXPECT_I2(val) EXPECT_OK { EXPECT_TYPE(VT_I2); \
3235 ok(V_I2(&vOut) == val, "Expected i2 = %d, got %d\n", (SHORT)val, V_I2(&vOut)); }
3236 #define EXPECT_UI2(val) EXPECT_OK { EXPECT_TYPE(VT_UI2); \
3237 ok(V_UI2(&vOut) == val, "Expected ui2 = %d, got %d\n", (USHORT)val, V_UI2(&vOut)); }
3238 #define EXPECT_I4(val) EXPECT_OK { EXPECT_TYPE(VT_I4); \
3239 ok(V_I4(&vOut) == val, "Expected i4 = %ld, got %ld\n", (LONG)val, V_I4(&vOut)); }
3240 #define EXPECT_UI4(val) EXPECT_OK { EXPECT_TYPE(VT_UI4); \
3241 ok(V_UI4(&vOut) == val, "Expected ui4 = %ld, got %ld\n", (ULONG)val, V_UI4(&vOut)); }
3242 #define EXPECT_I8(val) EXPECT_OK { EXPECT_TYPE(VT_I8); \
3243 ok(V_I8(&vOut) == val, "Expected i8 = %lld, got %lld\n", (LONG64)val, V_I8(&vOut)); }
3244 #define EXPECT_UI8(val) EXPECT_OK { EXPECT_TYPE(VT_UI8); \
3245 ok(V_UI8(&vOut) == val, "Expected ui8 = %lld, got %lld\n", (ULONG64)val, V_UI8(&vOut)); }
3246 #define EXPECT_R4(val) EXPECT_OK { EXPECT_TYPE(VT_R4); \
3247 ok(V_R4(&vOut) == val, "Expected r4 = %f, got %f\n", val, V_R4(&vOut)); }
3248 #define EXPECT_R8(val) EXPECT_OK { EXPECT_TYPE(VT_R8); \
3249 ok(V_R8(&vOut) == val, "Expected r8 = %g, got %g\n", val, V_R8(&vOut)); }
3250 #define CY_MULTIPLIER 10000
3251 #define EXPECT_CY(val) EXPECT_OK { EXPECT_TYPE(VT_CY); \
3252 ok(V_CY(&vOut).int64 == (LONG64)(val * CY_MULTIPLIER), "Expected r8 = %lld, got %lld\n", (LONG64)val, V_CY(&vOut).int64); }
3254 static void test_VarNumFromParseNum(void)
3261 /* Convert the number 1 to different types */
3262 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I1
); EXPECT_I1(1);
3263 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_UI1
); EXPECT_UI1(1);
3264 /* Prefers a signed type to unsigned of the same size */
3265 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I1
|VTBIT_UI1
); EXPECT_I1(1);
3266 /* But takes the smaller size if possible */
3267 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I2
|VTBIT_UI1
); EXPECT_UI1(1);
3269 /* Try different integer sizes */
3270 #define INTEGER_VTBITS (VTBIT_I1|VTBIT_UI1|VTBIT_I2|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|VTBIT_I8|VTBIT_UI8)
3272 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, INTEGER_VTBITS
); EXPECT_I1(1);
3274 SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 7);
3275 CONVERT(3,0,0,3,0,0, INTEGER_VTBITS
); EXPECT_I1(127);
3277 SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 8);
3278 CONVERT(3,0,0,3,0,0, INTEGER_VTBITS
); EXPECT_UI1(128);
3280 SETRGB(0, 2); SETRGB(1, 5); SETRGB(2, 5);
3281 CONVERT(3,0,0,3,0,0, INTEGER_VTBITS
); EXPECT_UI1(255);
3283 SETRGB(0, 2); SETRGB(1, 5); SETRGB(2, 6);
3284 CONVERT(3,0,0,3,0,0, INTEGER_VTBITS
); EXPECT_I2(256);
3286 SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 7);
3287 CONVERT(5,0,0,5,0,0, INTEGER_VTBITS
); EXPECT_I2(32767);
3289 SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 8);
3290 CONVERT(5,0,0,5,0,0, INTEGER_VTBITS
); EXPECT_UI2(32768);
3292 /* Assume the above pattern holds for remaining positive integers; test negative */
3295 SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 8);
3296 CONVERT(3,0,NUMPRS_NEG
,3,0,0, INTEGER_VTBITS
); EXPECT_I1(-128);
3298 SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 9);
3299 CONVERT(3,0,NUMPRS_NEG
,3,0,0, INTEGER_VTBITS
); EXPECT_I2(-129);
3301 SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 8);
3302 CONVERT(5,0,NUMPRS_NEG
,5,0,0, INTEGER_VTBITS
); EXPECT_I2(-32768);
3304 SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 9);
3305 CONVERT(5,0,NUMPRS_NEG
,5,0,0, INTEGER_VTBITS
); EXPECT_I4(-32769);
3307 /* Assume the above pattern holds for remaining negative integers */
3309 /* Negative numbers overflow if we have only unsigned outputs */
3311 SETRGB(0, 1); CONVERT(1,0,NUMPRS_NEG
,1,0,0, VTBIT_UI1
); EXPECT_OVERFLOW
;
3313 SETRGB(0, 6); CONVERT(1,0,NUMPRS_NEG
,1,0,~0u, VTBIT_UI1
); EXPECT_OVERFLOW
;
3315 /* Except that rounding is done first, so -0.5 to 0 are accepted as 0 */
3317 SETRGB(0, 5); CONVERT(1,0,NUMPRS_NEG
,1,0,~0u, VTBIT_UI1
); EXPECT_UI1(0);
3319 /* Float is acceptable for an integer input value */
3320 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R4
); EXPECT_R4(1.0f
);
3322 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R8
); EXPECT_R8(1.0);
3323 /* As is currency */
3324 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_CY
); EXPECT_CY(1);
3326 /* Float is preferred over double */
3327 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R4
|VTBIT_R8
); EXPECT_R4(1.0f
);
3329 /* Double is preferred over currency */
3330 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R8
|VTBIT_CY
); EXPECT_R8(1.0);
3332 /* Currency is preferred over decimal */
3333 SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_CY
|VTBIT_DECIMAL
); EXPECT_CY(1);
3336 #define DT2UD(dt,flags,r,d,m,y,h,mn,s,ms,dw,dy) \
3337 memset(&ud, 0, sizeof(ud)); \
3338 res = pVarUdateFromDate(dt, flags, &ud); \
3339 ok(r == res && (FAILED(r) || (ud.st.wYear == y && ud.st.wMonth == m && ud.st.wDay == d && \
3340 ud.st.wHour == h && ud.st.wMinute == mn && ud.st.wSecond == s && \
3341 ud.st.wMilliseconds == ms && ud.st.wDayOfWeek == dw && ud.wDayOfYear == dy)), \
3342 "%.16g expected %lx, %d,%d,%d,%d,%d,%d,%d %d %d, got %lx, %d,%d,%d,%d,%d,%d,%d %d %d\n", \
3343 dt, r, d, m, y, h, mn, s, ms, dw, dy, res, ud.st.wDay, ud.st.wMonth, \
3344 ud.st.wYear, ud.st.wHour, ud.st.wMinute, ud.st.wSecond, \
3345 ud.st.wMilliseconds, ud.st.wDayOfWeek, ud.wDayOfYear)
3347 static void test_VarUdateFromDate(void)
3352 CHECKPTR(VarUdateFromDate
);
3353 DT2UD(29221.0,0,S_OK
,1,1,1980,0,0,0,0,2,1); /* 1 Jan 1980 */
3354 DT2UD(29222.0,0,S_OK
,2,1,1980,0,0,0,0,3,2); /* 2 Jan 1980 */
3355 DT2UD(33238.0,0,S_OK
,31,12,1990,0,0,0,0,1,365); /* 31 Dec 1990 */
3356 DT2UD(0.0,0,S_OK
,30,12,1899,0,0,0,0,6,364); /* 30 Dec 1899 - VT_DATE 0.0 */
3357 DT2UD(-657434.0,0,S_OK
,1,1,100,0,0,0,0,5,1); /* 1 Jan 100 - Min */
3358 DT2UD(-657435.0,0,E_INVALIDARG
,0,0,0,0,0,0,0,0,0); /* < 1 Jan 100 => err */
3359 DT2UD(2958465.0,0,S_OK
,31,12,9999,0,0,0,0,5,365); /* 31 Dec 9999 - Max */
3360 DT2UD(2958466.0,0,E_INVALIDARG
,0,0,0,0,0,0,0,0,0); /* > 31 Dec 9999 => err */
3362 /* VAR_VALIDDATE doesn't prevent upper and lower bounds being checked */
3363 DT2UD(-657435.0,VAR_VALIDDATE
,E_INVALIDARG
,0,0,0,0,0,0,0,0,0);
3364 DT2UD(2958466.0,VAR_VALIDDATE
,E_INVALIDARG
,0,0,0,0,0,0,0,0,0);
3367 DT2UD(29221.25,0,S_OK
,1,1,1980,6,0,0,0,2,1); /* 6 AM */
3368 DT2UD(29221.33333333,0,S_OK
,1,1,1980,8,0,0,0,2,1); /* 8 AM */
3369 DT2UD(29221.5,0,S_OK
,1,1,1980,12,0,0,0,2,1); /* 12 AM */
3370 DT2UD(29221.9888884444,0,S_OK
,1,1,1980,23,44,0,0,2,1); /* 11:44 PM */
3371 DT2UD(29221.7508765432,0,S_OK
,1,1,1980,18,1,16,0,2,1); /* 6:18:02 PM */
3375 #define UD2T(d,m,y,h,mn,s,ms,dw,dy,flags,r,dt) \
3376 ud.st.wYear = (y); ud.st.wMonth = (m); ud.st.wDay = (d); ud.st.wHour = (h); \
3377 ud.st.wMinute = (mn); ud.st.wSecond = (s); ud.st.wMilliseconds = (ms); \
3378 ud.st.wDayOfWeek = (dw); ud.wDayOfYear = (dy); \
3379 res = pVarDateFromUdate(&ud, (flags), &out); \
3380 ok((r) == res && (FAILED(r) || fabs(out-(dt)) < 1.0e-11), \
3381 "expected %lx, %.16g, got %lx, %.16g\n", r, dt, res, out)
3383 static void test_VarDateFromUdate(void)
3389 CHECKPTR(VarDateFromUdate
);
3390 UD2T(1,1,1980,0,0,0,0,2,1,0,S_OK
,29221.0); /* 1 Jan 1980 */
3391 UD2T(2,1,1980,0,0,0,0,3,2,0,S_OK
,29222.0); /* 2 Jan 1980 */
3392 UD2T(31,12,1990,0,0,0,0,0,0,0,S_OK
,33238.0); /* 31 Dec 1990 */
3393 UD2T(31,12,90,0,0,0,0,0,0,0,S_OK
,33238.0); /* year < 100 is 1900+year! */
3394 UD2T(30,12,1899,0,0,0,0,6,364,0,S_OK
,0.0); /* 30 Dec 1899 - VT_DATE 0.0 */
3395 UD2T(1,1,100,0,0,0,0,0,0,0,S_OK
,-657434.0); /* 1 Jan 100 - Min */
3396 UD2T(31,12,9999,0,0,0,0,0,0,0,S_OK
,2958465.0); /* 31 Dec 9999 - Max */
3397 UD2T(1,1,10000,0,0,0,0,0,0,0,E_INVALIDARG
,0.0); /* > 31 Dec 9999 => err */
3399 UD2T(1,1,1980,18,1,16,0,2,1,0,S_OK
,29221.75087962963); /* 6:18:02 PM */
3401 UD2T(0,1,1980,0,0,0,0,2,1,0,S_OK
,29220.0); /* Rolls back to 31 Dec 1899 */
3402 UD2T(1,13,1980,0,0,0,0,2,1,0,S_OK
,29587.0); /* Rolls fwd to 1/1/1981 */
3405 #define ST2DT(d,m,y,h,mn,s,ms,r,dt) \
3406 st.wYear = y; st.wMonth = m; st.wDay = d; st.wHour = h; st.wMinute = mn; \
3407 st.wSecond = s; st.wMilliseconds = ms; st.wDayOfWeek = 0; \
3408 res = pSystemTimeToVariantTime(&st, &out); \
3409 ok(r == res && (!r || fabs(out-dt) < 1.0e-11), \
3410 "expected %d, %.16g, got %d, %.16g\n", r, dt, res, out)
3412 static void test_SystemTimeToVariantTime(void)
3418 CHECKPTR(SystemTimeToVariantTime
);
3419 ST2DT(1,1,1980,0,0,0,0,TRUE
,29221.0);
3420 ST2DT(2,1,1980,0,0,0,0,TRUE
,29222.0);
3421 ST2DT(0,1,1980,0,0,0,0,TRUE
,29220.0); /* Rolls back to 31 Dec 1899 */
3422 ST2DT(1,13,1980,0,0,0,0,FALSE
,29587.0); /* Fails on invalid month */
3423 ST2DT(31,12,90,0,0,0,0,TRUE
,33238.0); /* year < 100 is 1900+year! */
3426 #define DT2ST(dt,r,d,m,y,h,mn,s,ms) \
3427 memset(&st, 0, sizeof(st)); \
3428 res = pVariantTimeToSystemTime(dt, &st); \
3429 ok(r == res && (!r || (st.wYear == y && st.wMonth == m && st.wDay == d && \
3430 st.wHour == h && st.wMinute == mn && st.wSecond == s && \
3431 st.wMilliseconds == ms)), \
3432 "%.16g expected %d, %d,%d,%d,%d,%d,%d,%d, got %d, %d,%d,%d,%d,%d,%d,%d\n", \
3433 dt, r, d, m, y, h, mn, s, ms, res, st.wDay, st.wMonth, st.wYear, \
3434 st.wHour, st.wMinute, st.wSecond, st.wMilliseconds)
3436 static void test_VariantTimeToSystemTime(void)
3441 CHECKPTR(VariantTimeToSystemTime
);
3442 DT2ST(29221.0,1,1,1,1980,0,0,0,0);
3443 DT2ST(29222.0,1,2,1,1980,0,0,0,0);
3446 #define MKDOSDATE(d,m,y) ((d & 0x1f) | ((m & 0xf) << 5) | (((y-1980) & 0x7f) << 9))
3447 #define MKDOSTIME(h,m,s) (((s>>1) & 0x1f) | ((m & 0x3f) << 5) | ((h & 0x1f) << 11))
3449 #define DOS2DT(d,m,y,h,mn,s,r,dt) out = 0.0; \
3450 dosDate = MKDOSDATE(d,m,y); \
3451 dosTime = MKDOSTIME(h,mn,s); \
3452 res = pDosDateTimeToVariantTime(dosDate, dosTime, &out); \
3453 ok(r == res && (!r || fabs(out-dt) < 1.0e-11), \
3454 "expected %d, %.16g, got %d, %.16g\n", r, dt, res, out)
3456 static void test_DosDateTimeToVariantTime(void)
3458 USHORT dosDate
, dosTime
;
3462 CHECKPTR(DosDateTimeToVariantTime
);
3465 DOS2DT(1,1,1980,0,0,0,1,29221.0); /* 1/1/1980 */
3466 DOS2DT(31,12,2099,0,0,0,1,73050.0); /* 31/12/2099 */
3467 /* Dates are limited to the dos date max of 31/12/2099 */
3468 DOS2DT(31,12,2100,0,0,0,0,0.0); /* 31/12/2100 */
3469 /* Days and months of 0 cause date to roll back 1 day or month */
3470 DOS2DT(0,1,1980,0,0,0,1,29220.0); /* 0 Day => 31/12/1979 */
3471 DOS2DT(1,0,1980,0,0,0,1,29190.0); /* 0 Mth => 1/12/1979 */
3472 DOS2DT(0,0,1980,0,0,0,1,29189.0); /* 0 D/M => 30/11/1979 */
3473 /* Days > days in the month cause date to roll forward 1 month */
3474 DOS2DT(29,2,1981,0,0,0,1,29646.0); /* 29/2/1981 -> 3/1/1980 */
3475 DOS2DT(30,2,1981,0,0,0,1,29647.0); /* 30/2/1981 -> 4/1/1980 */
3476 /* Takes leap years into account when rolling forward */
3477 DOS2DT(29,2,1980,0,0,0,1,29280.0); /* 2/29/1980 */
3478 /* Months > 12 cause an error */
3479 DOS2DT(2,13,1980,0,0,0,0,0.0);
3482 DOS2DT(1,1,1980,0,0,29,1,29221.00032407407); /* 1/1/1980 12:00:28 AM */
3483 DOS2DT(1,1,1980,0,0,31,1,29221.00034722222); /* 1/1/1980 12:00:30 AM */
3484 DOS2DT(1,1,1980,0,59,0,1,29221.04097222222); /* 1/1/1980 12:59:00 AM */
3485 DOS2DT(1,1,1980,0,60,0,0,0.0); /* Invalid seconds */
3486 DOS2DT(1,1,1980,23,0,0,1,29221.95833333333); /* 1/1/1980 11:00:00 PM */
3487 DOS2DT(1,1,1980,24,0,0,0,0.0); /* Invalid hours */
3490 #define DT2DOS(dt,r,d,m,y,h,mn,s) dosTime = dosDate = 0; \
3491 expDosDate = MKDOSDATE(d,m,y); \
3492 expDosTime = MKDOSTIME(h,mn,s); \
3493 res = pVariantTimeToDosDateTime(dt, &dosDate, &dosTime); \
3494 ok(r == res && (!r || (dosTime == expDosTime && dosDate == expDosDate)), \
3495 "%g: expected %d,%d(%d/%d/%d),%d(%d:%d:%d) got %d,%d(%d/%d/%d),%d(%d:%d:%d)\n", \
3496 dt, r, expDosDate, expDosDate & 0x1f, (expDosDate >> 5) & 0xf, 1980 + (expDosDate >> 9), \
3497 expDosTime, expDosTime >> 11, (expDosTime >> 5) & 0x3f, (expDosTime & 0x1f), \
3498 res, dosDate, dosDate & 0x1f, (dosDate >> 5) & 0xf, 1980 + (dosDate >> 9), \
3499 dosTime, dosTime >> 11, (dosTime >> 5) & 0x3f, (dosTime & 0x1f))
3501 static void test_VariantTimeToDosDateTime(void)
3503 USHORT dosDate
, dosTime
, expDosDate
, expDosTime
;
3506 CHECKPTR(VariantTimeToDosDateTime
);
3509 DT2DOS(29221.0,1,1,1,1980,0,0,0); /* 1/1/1980 */
3510 DT2DOS(73050.0,1,31,12,2099,0,0,0); /* 31/12/2099 */
3511 DT2DOS(29220.0,0,0,0,0,0,0,0); /* 31/12/1979 - out of range */
3512 DT2DOS(73415.0,0,0,0,0,0,0,0); /* 31/12/2100 - out of range */
3515 DT2DOS(29221.00032407407,1,1,1,1980,0,0,29); /* 1/1/1980 12:00:28 AM */
3516 DT2DOS(29221.00034722222,1,1,1,1980,0,0,31); /* 1/1/1980 12:00:30 AM */
3517 DT2DOS(29221.04097222222,1,1,1,1980,0,59,0); /* 1/1/1980 12:59:00 AM */
3518 DT2DOS(29221.95833333333,1,1,1,1980,23,0,0); /* 1/1/1980 11:00:00 PM */
3523 hOleaut32
= LoadLibraryA("oleaut32.dll");
3527 test_VariantClear();
3528 test_VarParseNumFromStr();
3529 test_VarNumFromParseNum();
3530 test_VarUdateFromDate();
3531 test_VarDateFromUdate();
3532 test_SystemTimeToVariantTime();
3533 test_VariantTimeToSystemTime();
3534 test_DosDateTimeToVariantTime();
3535 test_VariantTimeToDosDateTime();