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