wined3d: Pass a wined3d_device_context to wined3d_cs_emit_blt_sub_resource().
[wine/zf.git] / dlls / oleaut32 / tests / varformat.c
blobd1951b85a61a0083bcc929d67bdd346a6bb79817
1 /*
2 * VARFORMAT test program
4 * Copyright 1998 Jean-Claude Cote
5 * Copyright 2006 Google (Benjamin Arai)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <math.h>
25 #include <float.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winsock2.h"
30 #include "wine/test.h"
31 #include "winuser.h"
32 #include "wingdi.h"
33 #include "winnls.h"
34 #include "winerror.h"
35 #include "winnt.h"
37 #include "wtypes.h"
38 #include "oleauto.h"
40 #define FMT_NUMBER(vt,val) \
41 VariantInit(&v); V_VT(&v) = vt; val(&v) = 1; \
42 hres = VarFormatNumber(&v,2,0,0,0,0,&str); \
43 ok(hres == S_OK, "VarFormatNumber (vt %d): returned %8x\n", vt, hres); \
44 if (hres == S_OK) { \
45 ok(str && wcscmp(str,szResult1) == 0, \
46 "VarFormatNumber (vt %d): string different\n", vt); \
47 SysFreeString(str); \
50 static void test_VarFormatNumber(void)
52 static const WCHAR szResult1[] = L"1.00";
53 char buff[8];
54 HRESULT hres;
55 VARIANT v;
56 BSTR str = NULL;
58 GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, ARRAY_SIZE(buff));
59 if (buff[0] != '.' || buff[1])
61 skip("Skipping VarFormatNumber tests as decimal separator is '%s'\n", buff);
62 return;
65 FMT_NUMBER(VT_I1, V_I1);
66 FMT_NUMBER(VT_UI1, V_UI1);
67 FMT_NUMBER(VT_I2, V_I2);
68 FMT_NUMBER(VT_UI2, V_UI2);
69 FMT_NUMBER(VT_I4, V_I4);
70 FMT_NUMBER(VT_UI4, V_UI4);
71 FMT_NUMBER(VT_I8, V_I8);
72 FMT_NUMBER(VT_UI8, V_UI8);
73 FMT_NUMBER(VT_R4, V_R4);
74 FMT_NUMBER(VT_R8, V_R8);
75 FMT_NUMBER(VT_BOOL, V_BOOL);
77 V_VT(&v) = VT_BSTR;
78 V_BSTR(&v) = SysAllocString(L"1");
80 hres = VarFormatNumber(&v,2,0,0,0,0,&str);
81 ok(hres == S_OK, "VarFormatNumber (bstr): returned %8x\n", hres);
82 if (hres == S_OK)
83 ok(str && wcscmp(str, szResult1) == 0, "VarFormatNumber (bstr): string different\n");
84 SysFreeString(V_BSTR(&v));
85 SysFreeString(str);
87 V_BSTR(&v) = SysAllocString(L"-1");
88 hres = VarFormatNumber(&v,2,0,-1,0,0,&str);
89 ok(hres == S_OK, "VarFormatNumber (bstr): returned %8x\n", hres);
90 if (hres == S_OK)
91 ok(str && wcscmp(str, L"(1.00)") == 0, "VarFormatNumber (-bstr): string different\n");
92 SysFreeString(V_BSTR(&v));
93 SysFreeString(str);
96 #define SIGNED_VTBITS (VTBIT_I1|VTBIT_I2|VTBIT_I4|VTBIT_I8|VTBIT_R4|VTBIT_R8)
98 static const char *szVarFmtFail = "VT %d|0x%04x Format %s: expected 0x%08x, '%s', got 0x%08x, '%s'\n";
99 #define VARFMT(vt,v,val,fmt,ret,str) do { \
100 out = NULL; \
101 V_VT(&in) = (vt); v(&in) = val; \
102 if (fmt) MultiByteToWideChar(CP_ACP, 0, fmt, -1, buffW, ARRAY_SIZE(buffW)); \
103 hres = VarFormat(&in,fmt ? buffW : NULL,fd,fw,flags,&out); \
104 if (SUCCEEDED(hres)) WideCharToMultiByte(CP_ACP, 0, out, -1, buff, sizeof(buff),0,0); \
105 else buff[0] = '\0'; \
106 ok(hres == ret && (FAILED(ret) || !strcmp(buff, str)), \
107 szVarFmtFail, \
108 (vt)&VT_TYPEMASK,(vt)&~VT_TYPEMASK,fmt?fmt:"<null>",ret,str,hres,buff); \
109 SysFreeString(out); \
110 } while(0)
112 typedef struct tagFMTRES
114 LPCSTR fmt;
115 LPCSTR one_res;
116 LPCSTR zero_res;
117 } FMTRES;
119 static const FMTRES VarFormat_results[] =
121 { NULL, "1", "0" },
122 { "", "1", "0" },
123 { "General Number", "1", "0" },
124 { "Percent", "100.00%", "0.00%" },
125 { "Standard", "1.00", "0.00" },
126 { "Scientific","1.00E+00", "0.00E+00" },
127 { "True/False", "True", "False" },
128 { "On/Off", "On", "Off" },
129 { "Yes/No", "Yes", "No" },
130 { "#", "1", "" },
131 { "##", "1", "" },
132 { "#.#", "1.", "." },
133 { "0", "1", "0" },
134 { "00", "01", "00" },
135 { "0.0", "1.0", "0.0" },
136 { "00\\c\\o\\p\\y", "01copy","00copy" },
137 { "\"pos\";\"neg\"", "pos", "pos" },
138 { "\"pos\";\"neg\";\"zero\"","pos", "zero" }
141 typedef struct tagFMTDATERES
143 DATE val;
144 LPCSTR fmt;
145 LPCSTR res;
146 } FMTDATERES;
148 static const FMTDATERES VarFormat_date_results[] =
150 { 0.0, "w", "7" },
151 { 0.0, "w", "6" },
152 { 0.0, "w", "5" },
153 { 0.0, "w", "4" },
154 { 0.0, "w", "3" },
155 { 0.0, "w", "2" },
156 { 0.0, "w", "1" }, /* First 7 entries must remain in this order! */
157 { 2.525, "am/pm", "pm" },
158 { 2.525, "AM/PM", "PM" },
159 { 2.525, "A/P", "P" },
160 { 2.525, "a/p", "p" },
161 { 2.525, "q", "1" },
162 { 2.525, "d", "1" },
163 { 2.525, "dd", "01" },
164 { 2.525, "ddd", "Mon" },
165 { 2.525, "dddd", "Monday" },
166 { 2.525, "mmm", "Jan" },
167 { 2.525, "mmmm", "January" },
168 { 2.525, "y", "1" },
169 { 2.525, "yy", "00" },
170 { 2.525, "yyy", "001" },
171 { 2.525, "yyyy", "1900" },
172 { 2.525, "dd mm yyyy hh:mm:ss", "01 01 1900 12:36:00" },
173 { 2.525, "dd mm yyyy mm", "01 01 1900 01" },
174 { 2.525, "dd mm yyyy :mm", "01 01 1900 :01" },
175 { 2.525, "dd mm yyyy hh:mm", "01 01 1900 12:36" },
176 { 2.525, "mm mm", "01 01" },
177 { 2.525, "mm :mm:ss", "01 :01:00" },
178 { 2.525, "mm :ss:mm", "01 :00:01" },
179 { 2.525, "hh:mm :ss:mm", "12:36 :00:01" },
180 { 2.525, "hh:dd :mm:mm", "12:01 :01:01" },
181 { 2.525, "dd:hh :mm:mm", "01:12 :36:01" },
182 { 2.525, "hh :mm:mm", "12 :36:01" },
183 { 2.525, "dd :mm:mm", "01 :01:01" },
184 { 2.525, "dd :mm:nn", "01 :01:36" },
185 { 2.725, "hh:nn:ss A/P", "05:24:00 P" },
186 { 40531.0, "dddd", "Sunday" },
187 { 40531.0, "ddd", "Sun" }
190 /* The following tests require that the time separator is a colon (:) */
191 static const FMTDATERES VarFormat_namedtime_results[] =
193 { 2.525, "short time", "12:36" },
194 { 2.525, "medium time", "12:36 PM" },
195 { 2.525, "long time", "12:36:00 PM" }
198 #define VNUMFMT(vt,v) \
199 for (i = 0; i < ARRAY_SIZE(VarFormat_results); i++) \
201 VARFMT(vt,v,1,VarFormat_results[i].fmt,S_OK,VarFormat_results[i].one_res); \
202 VARFMT(vt,v,0,VarFormat_results[i].fmt,S_OK,VarFormat_results[i].zero_res); \
204 if ((1 << vt) & SIGNED_VTBITS) \
206 VARFMT(vt,v,-1,"\"pos\";\"neg\"",S_OK,"neg"); \
207 VARFMT(vt,v,-1,"\"pos\";\"neg\";\"zero\"",S_OK,"neg"); \
210 static void test_VarFormat(void)
212 size_t i;
213 WCHAR buffW[256];
214 char buff[256];
215 VARIANT in;
216 VARIANT_BOOL bTrue = VARIANT_TRUE, bFalse = VARIANT_FALSE;
217 int fd = 0, fw = 0;
218 ULONG flags = 0;
219 BSTR bstrin, out = NULL;
220 HRESULT hres;
222 if (PRIMARYLANGID(LANGIDFROMLCID(GetUserDefaultLCID())) != LANG_ENGLISH)
224 skip("Skipping VarFormat tests for non English language\n");
225 return;
227 GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, ARRAY_SIZE(buff));
228 if (buff[0] != '.' || buff[1])
230 skip("Skipping VarFormat tests as decimal separator is '%s'\n", buff);
231 return;
233 GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDIGITS, buff, ARRAY_SIZE(buff));
234 if (buff[0] != '2' || buff[1])
236 skip("Skipping VarFormat tests as decimal places is '%s'\n", buff);
237 return;
240 VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"True/False",S_OK,"True");
241 VARFMT(VT_BOOL,V_BOOL,VARIANT_FALSE,"True/False",S_OK,"False");
243 VNUMFMT(VT_I1,V_I1);
244 VNUMFMT(VT_I2,V_I2);
245 VNUMFMT(VT_I4,V_I4);
246 VNUMFMT(VT_I8,V_I8);
247 VNUMFMT(VT_INT,V_INT);
248 VNUMFMT(VT_UI1,V_UI1);
249 VNUMFMT(VT_UI2,V_UI2);
250 VNUMFMT(VT_UI4,V_UI4);
251 VNUMFMT(VT_UI8,V_UI8);
252 VNUMFMT(VT_UINT,V_UINT);
253 VNUMFMT(VT_R4,V_R4);
254 VNUMFMT(VT_R8,V_R8);
256 /* Reference types are dereferenced */
257 VARFMT(VT_BOOL|VT_BYREF,V_BOOLREF,&bTrue,"True/False",S_OK,"True");
258 VARFMT(VT_BOOL|VT_BYREF,V_BOOLREF,&bFalse,"True/False",S_OK,"False");
260 /* Dates */
261 for (i = 0; i < ARRAY_SIZE(VarFormat_date_results); i++)
263 if (i < 7)
264 fd = i + 1; /* Test first day */
265 else
266 fd = 0;
267 VARFMT(VT_DATE,V_DATE,VarFormat_date_results[i].val,
268 VarFormat_date_results[i].fmt,S_OK,
269 VarFormat_date_results[i].res);
272 /* Named time formats */
273 GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, buff, ARRAY_SIZE(buff));
274 if (strcmp(buff, "h:mm:ss tt"))
276 skip("Skipping named time tests as time format is '%s'\n", buff);
278 else
280 for (i = 0; i < ARRAY_SIZE(VarFormat_namedtime_results); i++)
282 fd = 0;
283 VARFMT(VT_DATE,V_DATE,VarFormat_namedtime_results[i].val,
284 VarFormat_namedtime_results[i].fmt,S_OK,
285 VarFormat_namedtime_results[i].res);
289 /* Strings */
290 bstrin = SysAllocString(L"testing");
291 VARFMT(VT_BSTR,V_BSTR,bstrin,"",S_OK,"testing");
292 VARFMT(VT_BSTR,V_BSTR,bstrin,"@",S_OK,"testing");
293 VARFMT(VT_BSTR,V_BSTR,bstrin,"&",S_OK,"testing");
294 VARFMT(VT_BSTR,V_BSTR,bstrin,"\\x@\\x@",S_OK,"xtxesting");
295 VARFMT(VT_BSTR,V_BSTR,bstrin,"\\x&\\x&",S_OK,"xtxesting");
296 VARFMT(VT_BSTR,V_BSTR,bstrin,"@\\x",S_OK,"txesting");
297 VARFMT(VT_BSTR,V_BSTR,bstrin,"@@@@@@@@",S_OK," testing");
298 VARFMT(VT_BSTR,V_BSTR,bstrin,"@\\x@@@@@@@",S_OK," xtesting");
299 VARFMT(VT_BSTR,V_BSTR,bstrin,"&&&&&&&&",S_OK,"testing");
300 VARFMT(VT_BSTR,V_BSTR,bstrin,"!&&&&&&&",S_OK,"testing");
301 VARFMT(VT_BSTR,V_BSTR,bstrin,"&&&&&&&!",S_OK,"testing");
302 VARFMT(VT_BSTR,V_BSTR,bstrin,">&&",S_OK,"TESTING");
303 VARFMT(VT_BSTR,V_BSTR,bstrin,"<&&",S_OK,"testing");
304 VARFMT(VT_BSTR,V_BSTR,bstrin,"<&>&",S_OK,"testing");
305 SysFreeString(bstrin);
306 bstrin = SysAllocString(L"39697.11");
307 todo_wine VARFMT(VT_BSTR,V_BSTR,bstrin,"hh:mm",S_OK,"02:38");
308 todo_wine VARFMT(VT_BSTR,V_BSTR,bstrin,"mm-dd-yy",S_OK,"09-06-08");
309 SysFreeString(bstrin);
310 /* Numeric values are converted to strings then output */
311 VARFMT(VT_I1,V_I1,1,"<&>&",S_OK,"1");
313 /* Number formats */
314 VARFMT(VT_I4,V_I4,1,"#00000000",S_OK,"00000001");
315 VARFMT(VT_I4,V_I4,1,"000###",S_OK,"000001");
316 VARFMT(VT_I4,V_I4,1,"#00##00#0",S_OK,"00000001");
317 VARFMT(VT_I4,V_I4,1,"1#####0000",S_OK,"10001");
318 VARFMT(VT_I4,V_I4,1,"##abcdefghijklmnopqrstuvwxyz",S_OK,"1abcdefghijklmnopqrstuvwxyz");
319 VARFMT(VT_I4,V_I4,100000,"#,###,###,###",S_OK,"100,000");
320 VARFMT(VT_I4,V_I4,1,"0,000,000,000",S_OK,"0,000,000,001");
321 VARFMT(VT_I4,V_I4,123456789,"#,#.#",S_OK,"123,456,789.");
322 VARFMT(VT_I4,V_I4,123456789,"###, ###, ###",S_OK,"123, 456, 789");
323 VARFMT(VT_I4,V_I4,1,"#;-#",S_OK,"1");
324 VARFMT(VT_I4,V_I4,-1,"#;-#",S_OK,"-1");
325 VARFMT(VT_R8,V_R8,1.23456789,"0#.0#0#0#0#0",S_OK,"01.234567890");
326 VARFMT(VT_R8,V_R8,1.2,"0#.0#0#0#0#0",S_OK,"01.200000000");
327 VARFMT(VT_R8,V_R8,9.87654321,"#0.#0#0#0#0#",S_OK,"9.87654321");
328 VARFMT(VT_R8,V_R8,9.8,"#0.#0#0#0#0#",S_OK,"9.80000000");
329 VARFMT(VT_R8,V_R8,0.00000008,"#0.#0#0#0#0#0",S_OK,"0.0000000800");
330 VARFMT(VT_R8,V_R8,0.00010705,"#0.##########",S_OK,"0.00010705");
331 VARFMT(VT_I4,V_I4,17,"#0",S_OK,"17");
332 VARFMT(VT_I4,V_I4,4711,"#0",S_OK,"4711");
333 VARFMT(VT_I4,V_I4,17,"#00",S_OK,"17");
334 VARFMT(VT_I4,V_I4,100,"0##",S_OK,"100");
335 VARFMT(VT_I4,V_I4,17,"#000",S_OK,"017");
336 VARFMT(VT_I4,V_I4,17,"#0.00",S_OK,"17.00");
337 VARFMT(VT_I4,V_I4,17,"#0000.00",S_OK,"0017.00");
338 VARFMT(VT_I4,V_I4,17,"#.00",S_OK,"17.00");
339 VARFMT(VT_R8,V_R8,1.7,"#.00",S_OK,"1.70");
340 VARFMT(VT_R8,V_R8,.17,"#.00",S_OK,".17");
341 VARFMT(VT_I4,V_I4,17,"#3",S_OK,"173");
342 VARFMT(VT_I4,V_I4,17,"#33",S_OK,"1733");
343 VARFMT(VT_I4,V_I4,17,"#3.33",S_OK,"173.33");
344 VARFMT(VT_I4,V_I4,17,"#3333.33",S_OK,"173333.33");
345 VARFMT(VT_I4,V_I4,17,"#.33",S_OK,"17.33");
346 VARFMT(VT_R8,V_R8,.17,"#.33",S_OK,".33");
347 VARFMT(VT_R8,V_R8,1.7,"0.0000E-000",S_OK,"1.7000E000");
348 VARFMT(VT_R8,V_R8,1.7,"0.0000e-1",S_OK,"1.7000e01");
349 VARFMT(VT_R8,V_R8,86.936849,"#0.000000000000e-000",S_OK,"86.936849000000e000");
350 VARFMT(VT_R8,V_R8,1.7,"#0",S_OK,"2");
351 VARFMT(VT_R8,V_R8,1.7,"#.33",S_OK,"2.33");
352 VARFMT(VT_R8,V_R8,1.7,"#3",S_OK,"23");
353 VARFMT(VT_R8,V_R8,1.73245,"0.0000E+000",S_OK,"1.7325E+000");
354 VARFMT(VT_R8,V_R8,9.9999999,"#0.000000",S_OK,"10.000000");
355 VARFMT(VT_R8,V_R8,1.7,"0.0000e+0#",S_OK,"1.7000e+0");
356 VARFMT(VT_R8,V_R8,100.0001e+0,"0.0000E+0",S_OK,"1.0000E+2");
357 VARFMT(VT_R8,V_R8,1000001,"0.0000e+1",S_OK,"1.0000e+61");
358 VARFMT(VT_R8,V_R8,100.0001e+25,"0.0000e+0",S_OK,"1.0000e+27");
359 VARFMT(VT_R8,V_R8,450.0001e+43,"#000.0000e+0",S_OK,"4500.0010e+42");
360 VARFMT(VT_R8,V_R8,0.0001e-11,"##00.0000e-0",S_OK,"1000.0000e-18");
361 VARFMT(VT_R8,V_R8,0.0317e-11,"0000.0000e-0",S_OK,"3170.0000e-16");
362 VARFMT(VT_R8,V_R8,0.0021e-11,"00##.0000e-0",S_OK,"2100.0000e-17");
363 VARFMT(VT_R8,V_R8,1.0001e-27,"##00.0000e-0",S_OK,"1000.1000e-30");
364 VARFMT(VT_R8,V_R8,47.11,".0000E+0",S_OK,".4711E+2");
365 VARFMT(VT_R8,V_R8,3.0401e-13,"#####.####e-0%",S_OK,"30401.e-15%");
366 VARFMT(VT_R8,V_R8,1.57,"0.00",S_OK,"1.57");
367 VARFMT(VT_R8,V_R8,-1.57,"0.00",S_OK,"-1.57");
368 VARFMT(VT_R8,V_R8,-1.57,"#.##",S_OK,"-1.57");
369 VARFMT(VT_R8,V_R8,-0.1,".#",S_OK,"-.1");
370 VARFMT(VT_R8,V_R8,0.099,"#.#",S_OK,".1");
371 VARFMT(VT_R8,V_R8,0.0999,"#.##",S_OK,".1");
372 VARFMT(VT_R8,V_R8,0.099,"#.##",S_OK,".1");
373 VARFMT(VT_R8,V_R8,0.0099,"#.##",S_OK,".01");
374 VARFMT(VT_R8,V_R8,0.0049,"#.##",S_OK,".");
375 VARFMT(VT_R8,V_R8,0.0094,"#.##",S_OK,".01");
376 VARFMT(VT_R8,V_R8,0.00099,"#.##",S_OK,".");
377 VARFMT(VT_R8,V_R8,0.0995,"#.##",S_OK,".1");
378 VARFMT(VT_R8,V_R8,8.0995,"#.##",S_OK,"8.1");
379 VARFMT(VT_R8,V_R8,0.0994,"#.##",S_OK,".1");
380 VARFMT(VT_R8,V_R8,1.00,"#,##0.00",S_OK,"1.00");
381 VARFMT(VT_R8,V_R8,0.0995,"#.###",S_OK,".1");
384 /* 'out' is not cleared */
385 out = (BSTR)0x1;
386 hres = VarFormat(&in,NULL,fd,fw,flags,&out); /* Would crash if out is cleared */
387 ok(hres == S_OK, "got %08x\n", hres);
388 SysFreeString(out);
389 out = NULL;
391 /* VT_NULL */
392 V_VT(&in) = VT_NULL;
393 hres = VarFormat(&in,NULL,fd,fw,0,&out);
394 ok(hres == S_OK, "VarFormat failed with 0x%08x\n", hres);
395 ok(out == NULL, "expected NULL formatted string\n");
397 /* Invalid args */
398 hres = VarFormat(&in,NULL,fd,fw,flags,NULL);
399 ok(hres == E_INVALIDARG, "Null out: expected E_INVALIDARG, got 0x%08x\n", hres);
400 hres = VarFormat(NULL,NULL,fd,fw,flags,&out);
401 ok(hres == E_INVALIDARG, "Null in: expected E_INVALIDARG, got 0x%08x\n", hres);
402 fd = -1;
403 VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,"");
404 fd = 8;
405 VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,"");
406 fd = 0; fw = -1;
407 VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,"");
408 fw = 4;
409 VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,"");
412 static const char *szVarWdnFail =
413 "VarWeekdayName (%d, %d, %d, %d, %x): returned %8x, expected %8x\n";
414 #define VARWDN(iWeekday, fAbbrev, iFirstDay, dwFlags, ret, buff, out, freeOut) \
415 do { \
416 hres = VarWeekdayName(iWeekday, fAbbrev, iFirstDay, dwFlags, &out); \
417 if (SUCCEEDED(hres)) { \
418 WideCharToMultiByte(CP_ACP, 0, out, -1, buff, sizeof(buff), 0, 0); \
419 if (freeOut) SysFreeString(out); \
420 } else { \
421 buff[0] = '\0'; \
423 ok(hres == ret, \
424 szVarWdnFail, \
425 iWeekday, fAbbrev, iFirstDay, dwFlags, &out, hres, ret \
426 ); \
427 } while(0)
429 #define VARWDN_F(iWeekday, fAbbrev, iFirstDay, dwFlags, ret) \
430 VARWDN(iWeekday, fAbbrev, iFirstDay, dwFlags, ret, buff, out, 1)
432 #define VARWDN_O(iWeekday, fAbbrev, iFirstDay, dwFlags) \
433 VARWDN(iWeekday, fAbbrev, iFirstDay, dwFlags, S_OK, buff, out, 0)
435 static void test_VarWeekdayName(void)
437 char buff[256];
438 BSTR out = NULL;
439 HRESULT hres;
440 int iWeekday, fAbbrev, iFirstDay;
441 BSTR dayNames[7][2]; /* Monday-Sunday, full/abbr */
442 DWORD defaultFirstDay;
443 int firstDay;
444 int day;
445 int size;
446 DWORD localeValue;
448 SetLastError(0xdeadbeef);
449 GetLocaleInfoW(LOCALE_USER_DEFAULT, 0, NULL, 0);
450 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
452 win_skip("GetLocaleInfoW is not implemented\n");
453 return;
456 /* Initialize days' names */
457 for (day = 0; day <= 6; ++day)
459 for (fAbbrev = 0; fAbbrev <= 1; ++fAbbrev)
461 localeValue = fAbbrev ? LOCALE_SABBREVDAYNAME1 : LOCALE_SDAYNAME1;
462 localeValue += day;
463 size = GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue, NULL, 0);
464 dayNames[day][fAbbrev] = SysAllocStringLen(NULL, size - 1);
465 GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue,
466 dayNames[day][fAbbrev], size);
470 /* Get the user's first day of week. 0=Monday, .. */
471 GetLocaleInfoW(
472 LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK | LOCALE_RETURN_NUMBER,
473 (LPWSTR)&defaultFirstDay, sizeof(defaultFirstDay) / sizeof(WCHAR));
475 /* Check invalid arguments */
476 VARWDN_F(0, 0, 4, 0, E_INVALIDARG);
477 VARWDN_F(8, 0, 4, 0, E_INVALIDARG);
478 VARWDN_F(4, 0, -1, 0, E_INVALIDARG);
479 VARWDN_F(4, 0, 8, 0, E_INVALIDARG);
481 hres = VarWeekdayName(1, 0, 0, 0, NULL);
482 ok(E_INVALIDARG == hres,
483 "Null pointer: expected E_INVALIDARG, got 0x%08x\n", hres);
485 /* Check all combinations */
486 for (iWeekday = 1; iWeekday <= 7; ++iWeekday)
488 for (fAbbrev = 0; fAbbrev <= 1; ++fAbbrev)
490 /* 0 = Default, 1 = Sunday, 2 = Monday, .. */
491 for (iFirstDay = 0; iFirstDay <= 7; ++iFirstDay)
493 VARWDN_O(iWeekday, fAbbrev, iFirstDay, 0);
494 if (iFirstDay == 0)
495 firstDay = defaultFirstDay;
496 else
497 /* Translate from 0=Sunday to 0=Monday in the modulo 7 space */
498 firstDay = iFirstDay - 2;
499 day = (7 + iWeekday - 1 + firstDay) % 7;
500 ok(VARCMP_EQ == VarBstrCmp(out, dayNames[day][fAbbrev], LOCALE_USER_DEFAULT, 0),
501 "VarWeekdayName(%d,%d,%d): got wrong dayname: '%s'\n",
502 iWeekday, fAbbrev, iFirstDay, buff);
503 SysFreeString(out);
508 /* Cleanup */
509 for (day = 0; day <= 6; ++day)
511 for (fAbbrev = 0; fAbbrev <= 1; ++fAbbrev)
513 SysFreeString(dayNames[day][fAbbrev]);
518 static void test_VarFormatFromTokens(void)
520 static WCHAR number_fmt[] = L"###,##0.00";
521 static WCHAR date_fmt[] = L"dd-mm";
522 static WCHAR string_fmt[] = L"@";
524 BYTE buff[256];
525 LCID lcid;
526 VARIANT var;
527 BSTR bstr;
528 HRESULT hres;
530 V_VT(&var) = VT_BSTR;
531 V_BSTR(&var) = SysAllocString(L"6,90");
533 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
534 hres = VarTokenizeFormatString(number_fmt, buff, sizeof(buff), 1, 1, lcid, NULL);
535 ok(hres == S_OK, "VarTokenizeFormatString failed: %x\n", hres);
536 hres = VarFormatFromTokens(&var, number_fmt, buff, 0, &bstr, lcid);
537 ok(hres == S_OK, "VarFormatFromTokens failed: %x\n", hres);
538 ok(!wcscmp(bstr, L"690.00"), "incorrectly formatted number: %s\n", wine_dbgstr_w(bstr));
539 SysFreeString(bstr);
541 lcid = MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), SORT_DEFAULT);
542 hres = VarTokenizeFormatString(number_fmt, buff, sizeof(buff), 1, 1, lcid, NULL);
543 ok(hres == S_OK, "VarTokenizeFormatString failed: %x\n", hres);
544 hres = VarFormatFromTokens(&var, number_fmt, buff, 0, &bstr, lcid);
545 ok(hres == S_OK, "VarFormatFromTokens failed: %x\n", hres);
546 ok(!wcscmp(bstr, L"6,90"), "incorrectly formatted number: %s\n", wine_dbgstr_w(bstr));
547 SysFreeString(bstr);
549 VariantClear(&var);
551 V_VT(&var) = VT_BSTR;
552 V_BSTR(&var) = SysAllocString(L"12-11");
554 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
555 hres = VarTokenizeFormatString(date_fmt, buff, sizeof(buff), 1, 1, lcid, NULL);
556 ok(hres == S_OK, "VarTokenizeFormatString failed: %x\n", hres);
557 hres = VarFormatFromTokens(&var, date_fmt, buff, 0, &bstr, lcid);
558 ok(hres == S_OK, "VarFormatFromTokens failed: %x\n", hres);
559 ok(!wcscmp(bstr, L"11-12"), "incorrectly formatted date: %s\n", wine_dbgstr_w(bstr));
560 SysFreeString(bstr);
562 lcid = MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), SORT_DEFAULT);
563 hres = VarTokenizeFormatString(date_fmt, buff, sizeof(buff), 1, 1, lcid, NULL);
564 ok(hres == S_OK, "VarTokenizeFormatString failed: %x\n", hres);
565 hres = VarFormatFromTokens(&var, date_fmt, buff, 0, &bstr, lcid);
566 ok(hres == S_OK, "VarFormatFromTokens failed: %x\n", hres);
567 ok(!wcscmp(bstr, L"12-11"), "incorrectly formatted date: %s\n", wine_dbgstr_w(bstr));
568 SysFreeString(bstr);
570 VariantClear(&var);
572 V_VT(&var) = VT_R4;
573 V_R4(&var) = 1.5;
575 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
576 hres = VarTokenizeFormatString(string_fmt, buff, sizeof(buff), 1, 1, lcid, NULL);
577 ok(hres == S_OK, "VarTokenizeFormatString failed: %x\n", hres);
578 hres = VarFormatFromTokens(&var, string_fmt, buff, 0, &bstr, lcid);
579 ok(hres == S_OK, "VarFormatFromTokens failed: %x\n", hres);
580 ok(!wcscmp(bstr, L"1.5"), "incorrectly formatted string: %s\n", wine_dbgstr_w(bstr));
581 SysFreeString(bstr);
583 lcid = MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), SORT_DEFAULT);
584 hres = VarTokenizeFormatString(string_fmt, buff, sizeof(buff), 1, 1, lcid, NULL);
585 ok(hres == S_OK, "VarTokenizeFormatString failed: %x\n", hres);
586 hres = VarFormatFromTokens(&var, string_fmt, buff, 0, &bstr, lcid);
587 ok(hres == S_OK, "VarFormatFromTokens failed: %x\n", hres);
588 ok(!wcscmp(bstr, L"1,5"), "incorrectly formatted string: %s\n", wine_dbgstr_w(bstr));
589 SysFreeString(bstr);
592 static void test_GetAltMonthNames(void)
594 LPOLESTR *str, *str2;
595 HRESULT hr;
597 str = (void *)0xdeadbeef;
598 hr = GetAltMonthNames(0, &str);
599 ok(hr == S_OK, "Unexpected return value %08x\n", hr);
600 ok(str == NULL, "Got %p\n", str);
602 str = (void *)0xdeadbeef;
603 hr = GetAltMonthNames(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), &str);
604 ok(hr == S_OK, "Unexpected return value %08x\n", hr);
605 ok(str == NULL, "Got %p\n", str);
607 str = NULL;
608 hr = GetAltMonthNames(MAKELCID(MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_EGYPT), SORT_DEFAULT), &str);
609 ok(hr == S_OK, "Unexpected return value %08x\n", hr);
610 ok(str != NULL, "Got %p\n", str);
612 str2 = NULL;
613 hr = GetAltMonthNames(MAKELCID(MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_EGYPT), SORT_DEFAULT), &str2);
614 ok(hr == S_OK, "Unexpected return value %08x\n", hr);
615 ok(str2 == str, "Got %p\n", str2);
617 str = NULL;
618 hr = GetAltMonthNames(MAKELCID(MAKELANGID(LANG_RUSSIAN, SUBLANG_DEFAULT), SORT_DEFAULT), &str);
619 ok(hr == S_OK, "Unexpected return value %08x\n", hr);
620 ok(str != NULL, "Got %p\n", str);
622 str = NULL;
623 hr = GetAltMonthNames(MAKELCID(MAKELANGID(LANG_POLISH, SUBLANG_DEFAULT), SORT_DEFAULT), &str);
624 ok(hr == S_OK, "Unexpected return value %08x\n", hr);
625 ok(str != NULL, "Got %p\n", str);
628 static void test_VarFormatCurrency(void)
630 HRESULT hr;
631 VARIANT in;
632 BSTR str, str2;
634 V_CY(&in).int64 = 0;
635 V_VT(&in) = VT_CY;
636 hr = VarFormatCurrency(&in, 3, -2, -2, -2, 0, &str);
637 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
639 V_VT(&in) = VT_BSTR;
640 V_BSTR(&in) = str;
641 hr = VarFormatCurrency(&in, 1, -2, -2, -2, 0, &str2);
642 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
643 ok(lstrcmpW(str, str2), "Expected different string.\n");
644 SysFreeString(str2);
646 V_VT(&in) = VT_BSTR | VT_BYREF;
647 V_BSTRREF(&in) = &str;
648 hr = VarFormatCurrency(&in, 1, -2, -2, -2, 0, &str2);
649 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
650 ok(lstrcmpW(str, str2), "Expected different string.\n");
652 SysFreeString(str);
653 SysFreeString(str2);
655 V_VT(&in) = VT_BSTR;
656 V_BSTR(&in) = SysAllocString(L"test");
657 hr = VarFormatCurrency(&in, 1, -2, -2, -2, 0, &str2);
658 ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr);
659 VariantClear(&in);
662 START_TEST(varformat)
664 test_VarFormatNumber();
665 test_VarFormat();
666 test_VarWeekdayName();
667 test_VarFormatFromTokens();
668 test_GetAltMonthNames();
669 test_VarFormatCurrency();