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