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
30 #include "wine/test.h"
40 static HMODULE hOleaut32
;
42 static HRESULT (WINAPI
*pVarBstrCmp
)(BSTR
,BSTR
,LCID
,ULONG
);
43 static HRESULT (WINAPI
*pVarFormatNumber
)(LPVARIANT
,int,int,int,int,ULONG
,BSTR
*);
44 static HRESULT (WINAPI
*pVarFormat
)(LPVARIANT
,LPOLESTR
,int,int,ULONG
,BSTR
*);
45 static HRESULT (WINAPI
*pVarWeekdayName
)(int,int,int,ULONG
,BSTR
*);
47 /* Has I8/UI8 data type? */
50 /* Get a conversion function ptr, return if function not available */
51 #define CHECKPTR(func) p##func = (void*)GetProcAddress(hOleaut32, #func); \
52 if (!p##func) { win_skip("function " # func " not available, not testing it\n"); return; }
54 static inline int strcmpW( const WCHAR
*str1
, const WCHAR
*str2
)
56 while (*str1
&& (*str1
== *str2
)) { str1
++; str2
++; }
60 #define FMT_NUMBER(vt,val) \
61 VariantInit(&v); V_VT(&v) = vt; val(&v) = 1; \
62 hres = pVarFormatNumber(&v,2,0,0,0,0,&str); \
63 ok(hres == S_OK, "VarFormatNumber (vt %d): returned %8x\n", vt, hres); \
65 ok(str && strcmpW(str,szResult1) == 0, \
66 "VarFormatNumber (vt %d): string different\n", vt); \
70 static void test_VarFormatNumber(void)
72 static const WCHAR szSrc1
[] = { '1','\0' };
73 static const WCHAR szResult1
[] = { '1','.','0','0','\0' };
74 static const WCHAR szSrc2
[] = { '-','1','\0' };
75 static const WCHAR szResult2
[] = { '(','1','.','0','0',')','\0' };
81 CHECKPTR(VarFormatNumber
);
83 GetLocaleInfoA(LOCALE_USER_DEFAULT
, LOCALE_SDECIMAL
, buff
, sizeof(buff
)/sizeof(char));
84 if (buff
[0] != '.' || buff
[1])
86 skip("Skipping VarFormatNumber tests as decimal separator is '%s'\n", buff
);
90 FMT_NUMBER(VT_I1
, V_I1
);
91 FMT_NUMBER(VT_UI1
, V_UI1
);
92 FMT_NUMBER(VT_I2
, V_I2
);
93 FMT_NUMBER(VT_UI2
, V_UI2
);
94 FMT_NUMBER(VT_I4
, V_I4
);
95 FMT_NUMBER(VT_UI4
, V_UI4
);
98 FMT_NUMBER(VT_I8
, V_I8
);
99 FMT_NUMBER(VT_UI8
, V_UI8
);
101 FMT_NUMBER(VT_R4
, V_R4
);
102 FMT_NUMBER(VT_R8
, V_R8
);
103 FMT_NUMBER(VT_BOOL
, V_BOOL
);
106 V_BSTR(&v
) = SysAllocString(szSrc1
);
108 hres
= pVarFormatNumber(&v
,2,0,0,0,0,&str
);
109 ok(hres
== S_OK
, "VarFormatNumber (bstr): returned %8x\n", hres
);
111 ok(str
&& strcmpW(str
, szResult1
) == 0, "VarFormatNumber (bstr): string different\n");
112 SysFreeString(V_BSTR(&v
));
115 V_BSTR(&v
) = SysAllocString(szSrc2
);
116 hres
= pVarFormatNumber(&v
,2,0,-1,0,0,&str
);
117 ok(hres
== S_OK
, "VarFormatNumber (bstr): returned %8x\n", hres
);
119 ok(str
&& strcmpW(str
, szResult2
) == 0, "VarFormatNumber (-bstr): string different\n");
120 SysFreeString(V_BSTR(&v
));
124 #define SIGNED_VTBITS (VTBIT_I1|VTBIT_I2|VTBIT_I4|VTBIT_I8|VTBIT_R4|VTBIT_R8)
126 static const char *szVarFmtFail
= "VT %d|0x%04x Format %s: expected 0x%08x, '%s', got 0x%08x, '%s'\n";
127 #define VARFMT(vt,v,val,fmt,ret,str) do { \
129 V_VT(&in) = (vt); v(&in) = val; \
130 if (fmt) MultiByteToWideChar(CP_ACP, 0, fmt, -1, buffW, sizeof(buffW)/sizeof(WCHAR)); \
131 hres = pVarFormat(&in,fmt ? buffW : NULL,fd,fw,flags,&out); \
132 if (SUCCEEDED(hres)) WideCharToMultiByte(CP_ACP, 0, out, -1, buff, sizeof(buff),0,0); \
133 else buff[0] = '\0'; \
134 ok(hres == ret && (FAILED(ret) || !strcmp(buff, str)), \
136 (vt)&VT_TYPEMASK,(vt)&~VT_TYPEMASK,fmt?fmt:"<null>",ret,str,hres,buff); \
137 SysFreeString(out); \
140 typedef struct tagFMTRES
147 static const FMTRES VarFormat_results
[] =
151 { "General Number", "1", "0" },
152 { "Percent", "100.00%", "0.00%" },
153 { "Standard", "1.00", "0.00" },
154 { "Scientific","1.00E+00", "0.00E+00" },
155 { "True/False", "True", "False" },
156 { "On/Off", "On", "Off" },
157 { "Yes/No", "Yes", "No" },
160 { "#.#", "1.", "." },
162 { "00", "01", "00" },
163 { "0.0", "1.0", "0.0" },
164 { "00\\c\\o\\p\\y", "01copy","00copy" },
165 { "\"pos\";\"neg\"", "pos", "pos" },
166 { "\"pos\";\"neg\";\"zero\"","pos", "zero" }
169 typedef struct tagFMTDATERES
176 static const FMTDATERES VarFormat_date_results
[] =
184 { 0.0, "w", "1" }, /* First 7 entries must remain in this order! */
185 { 2.525, "am/pm", "pm" },
186 { 2.525, "AM/PM", "PM" },
187 { 2.525, "A/P", "P" },
188 { 2.525, "a/p", "p" },
191 { 2.525, "dd", "01" },
192 { 2.525, "ddd", "Mon" },
193 { 2.525, "dddd", "Monday" },
194 { 2.525, "mmm", "Jan" },
195 { 2.525, "mmmm", "January" },
197 { 2.525, "yy", "00" },
198 { 2.525, "yyy", "001" },
199 { 2.525, "yyyy", "1900" },
200 { 2.525, "dd mm yyyy hh:mm:ss", "01 01 1900 12:36:00" },
201 { 2.525, "dd mm yyyy mm", "01 01 1900 01" },
202 { 2.525, "dd mm yyyy :mm", "01 01 1900 :01" },
203 { 2.525, "dd mm yyyy hh:mm", "01 01 1900 12:36" },
204 { 2.525, "mm mm", "01 01" },
205 { 2.525, "mm :mm:ss", "01 :01:00" },
206 { 2.525, "mm :ss:mm", "01 :00:01" },
207 { 2.525, "hh:mm :ss:mm", "12:36 :00:01" },
208 { 2.525, "hh:dd :mm:mm", "12:01 :01:01" },
209 { 2.525, "dd:hh :mm:mm", "01:12 :36:01" },
210 { 2.525, "hh :mm:mm", "12 :36:01" },
211 { 2.525, "dd :mm:mm", "01 :01:01" },
212 { 2.525, "dd :mm:nn", "01 :01:36" },
213 { 2.725, "hh:nn:ss A/P", "05:24:00 P" },
214 { 40531.0, "dddd", "Sunday" },
215 { 40531.0, "ddd", "Sun" }
218 /* The following tests require that the time separator is a colon (:) */
219 static const FMTDATERES VarFormat_namedtime_results
[] =
221 { 2.525, "short time", "12:36" },
222 { 2.525, "medium time", "12:36 PM" },
223 { 2.525, "long time", "12:36:00 PM" }
226 #define VNUMFMT(vt,v) \
227 for (i = 0; i < sizeof(VarFormat_results)/sizeof(FMTRES); i++) \
229 VARFMT(vt,v,1,VarFormat_results[i].fmt,S_OK,VarFormat_results[i].one_res); \
230 VARFMT(vt,v,0,VarFormat_results[i].fmt,S_OK,VarFormat_results[i].zero_res); \
232 if ((1 << vt) & SIGNED_VTBITS) \
234 VARFMT(vt,v,-1,"\"pos\";\"neg\"",S_OK,"neg"); \
235 VARFMT(vt,v,-1,"\"pos\";\"neg\";\"zero\"",S_OK,"neg"); \
238 static void test_VarFormat(void)
240 static const WCHAR szTesting
[] = { 't','e','s','t','i','n','g','\0' };
241 static const WCHAR szNum
[] = { '3','9','6','9','7','.','1','1','\0' };
246 VARIANT_BOOL bTrue
= VARIANT_TRUE
, bFalse
= VARIANT_FALSE
;
249 BSTR bstrin
, out
= NULL
;
254 if (PRIMARYLANGID(LANGIDFROMLCID(GetUserDefaultLCID())) != LANG_ENGLISH
)
256 skip("Skipping VarFormat tests for non English language\n");
259 GetLocaleInfoA(LOCALE_USER_DEFAULT
, LOCALE_SDECIMAL
, buff
, sizeof(buff
)/sizeof(char));
260 if (buff
[0] != '.' || buff
[1])
262 skip("Skipping VarFormat tests as decimal separator is '%s'\n", buff
);
265 GetLocaleInfoA(LOCALE_USER_DEFAULT
, LOCALE_IDIGITS
, buff
, sizeof(buff
)/sizeof(char));
266 if (buff
[0] != '2' || buff
[1])
268 skip("Skipping VarFormat tests as decimal places is '%s'\n", buff
);
272 VARFMT(VT_BOOL
,V_BOOL
,VARIANT_TRUE
,"True/False",S_OK
,"True");
273 VARFMT(VT_BOOL
,V_BOOL
,VARIANT_FALSE
,"True/False",S_OK
,"False");
282 VNUMFMT(VT_INT
,V_INT
);
283 VNUMFMT(VT_UI1
,V_UI1
);
284 VNUMFMT(VT_UI2
,V_UI2
);
285 VNUMFMT(VT_UI4
,V_UI4
);
288 VNUMFMT(VT_UI8
,V_UI8
);
290 VNUMFMT(VT_UINT
,V_UINT
);
294 /* Reference types are dereferenced */
295 VARFMT(VT_BOOL
|VT_BYREF
,V_BOOLREF
,&bTrue
,"True/False",S_OK
,"True");
296 VARFMT(VT_BOOL
|VT_BYREF
,V_BOOLREF
,&bFalse
,"True/False",S_OK
,"False");
299 for (i
= 0; i
< sizeof(VarFormat_date_results
)/sizeof(FMTDATERES
); i
++)
302 fd
= i
+ 1; /* Test first day */
305 VARFMT(VT_DATE
,V_DATE
,VarFormat_date_results
[i
].val
,
306 VarFormat_date_results
[i
].fmt
,S_OK
,
307 VarFormat_date_results
[i
].res
);
310 /* Named time formats */
311 GetLocaleInfoA(LOCALE_USER_DEFAULT
, LOCALE_STIMEFORMAT
, buff
, sizeof(buff
)/sizeof(char));
312 if (strcmp(buff
, "h:mm:ss tt"))
314 skip("Skipping named time tests as time format is '%s'\n", buff
);
318 for (i
= 0; i
< sizeof(VarFormat_namedtime_results
)/sizeof(FMTDATERES
); i
++)
321 VARFMT(VT_DATE
,V_DATE
,VarFormat_namedtime_results
[i
].val
,
322 VarFormat_namedtime_results
[i
].fmt
,S_OK
,
323 VarFormat_namedtime_results
[i
].res
);
328 bstrin
= SysAllocString(szTesting
);
329 VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"",S_OK
,"testing");
330 VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"@",S_OK
,"testing");
331 VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"&",S_OK
,"testing");
332 VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"\\x@\\x@",S_OK
,"xtxesting");
333 VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"\\x&\\x&",S_OK
,"xtxesting");
334 VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"@\\x",S_OK
,"txesting");
335 VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"@@@@@@@@",S_OK
," testing");
336 VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"@\\x@@@@@@@",S_OK
," xtesting");
337 VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"&&&&&&&&",S_OK
,"testing");
338 VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"!&&&&&&&",S_OK
,"testing");
339 VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"&&&&&&&!",S_OK
,"testing");
340 VARFMT(VT_BSTR
,V_BSTR
,bstrin
,">&&",S_OK
,"TESTING");
341 VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"<&&",S_OK
,"testing");
342 VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"<&>&",S_OK
,"testing");
343 SysFreeString(bstrin
);
344 bstrin
= SysAllocString(szNum
);
345 todo_wine
VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"hh:mm",S_OK
,"02:38");
346 todo_wine
VARFMT(VT_BSTR
,V_BSTR
,bstrin
,"mm-dd-yy",S_OK
,"09-06-08");
347 SysFreeString(bstrin
);
348 /* Numeric values are converted to strings then output */
349 VARFMT(VT_I1
,V_I1
,1,"<&>&",S_OK
,"1");
352 VARFMT(VT_I4
,V_I4
,1,"#00000000",S_OK
,"00000001");
353 VARFMT(VT_I4
,V_I4
,1,"000###",S_OK
,"000001");
354 VARFMT(VT_I4
,V_I4
,1,"#00##00#0",S_OK
,"00000001");
355 VARFMT(VT_I4
,V_I4
,1,"1#####0000",S_OK
,"10001");
356 VARFMT(VT_I4
,V_I4
,1,"##abcdefghijklmnopqrstuvwxyz",S_OK
,"1abcdefghijklmnopqrstuvwxyz");
357 VARFMT(VT_I4
,V_I4
,100000,"#,###,###,###",S_OK
,"100,000");
358 VARFMT(VT_I4
,V_I4
,1,"0,000,000,000",S_OK
,"0,000,000,001");
359 VARFMT(VT_I4
,V_I4
,123456789,"#,#.#",S_OK
,"123,456,789.");
360 VARFMT(VT_I4
,V_I4
,123456789,"###, ###, ###",S_OK
,"123, 456, 789");
361 VARFMT(VT_I4
,V_I4
,1,"#;-#",S_OK
,"1");
362 VARFMT(VT_I4
,V_I4
,-1,"#;-#",S_OK
,"-1");
363 VARFMT(VT_R8
,V_R8
,1.23456789,"0#.0#0#0#0#0",S_OK
,"01.234567890");
364 VARFMT(VT_R8
,V_R8
,1.2,"0#.0#0#0#0#0",S_OK
,"01.200000000");
365 VARFMT(VT_R8
,V_R8
,9.87654321,"#0.#0#0#0#0#",S_OK
,"9.87654321");
366 VARFMT(VT_R8
,V_R8
,9.8,"#0.#0#0#0#0#",S_OK
,"9.80000000");
367 VARFMT(VT_R8
,V_R8
,0.00000008,"#0.#0#0#0#0#0",S_OK
,"0.0000000800");
368 VARFMT(VT_R8
,V_R8
,0.00010705,"#0.##########",S_OK
,"0.00010705");
369 VARFMT(VT_I4
,V_I4
,17,"#0",S_OK
,"17");
370 VARFMT(VT_I4
,V_I4
,4711,"#0",S_OK
,"4711");
371 VARFMT(VT_I4
,V_I4
,17,"#00",S_OK
,"17");
372 VARFMT(VT_I4
,V_I4
,100,"0##",S_OK
,"100");
373 VARFMT(VT_I4
,V_I4
,17,"#000",S_OK
,"017");
374 VARFMT(VT_I4
,V_I4
,17,"#0.00",S_OK
,"17.00");
375 VARFMT(VT_I4
,V_I4
,17,"#0000.00",S_OK
,"0017.00");
376 VARFMT(VT_I4
,V_I4
,17,"#.00",S_OK
,"17.00");
377 VARFMT(VT_R8
,V_R8
,1.7,"#.00",S_OK
,"1.70");
378 VARFMT(VT_R8
,V_R8
,.17,"#.00",S_OK
,".17");
379 VARFMT(VT_I4
,V_I4
,17,"#3",S_OK
,"173");
380 VARFMT(VT_I4
,V_I4
,17,"#33",S_OK
,"1733");
381 VARFMT(VT_I4
,V_I4
,17,"#3.33",S_OK
,"173.33");
382 VARFMT(VT_I4
,V_I4
,17,"#3333.33",S_OK
,"173333.33");
383 VARFMT(VT_I4
,V_I4
,17,"#.33",S_OK
,"17.33");
384 VARFMT(VT_R8
,V_R8
,.17,"#.33",S_OK
,".33");
385 VARFMT(VT_R8
,V_R8
,1.7,"0.0000E-000",S_OK
,"1.7000E000");
386 VARFMT(VT_R8
,V_R8
,1.7,"0.0000e-1",S_OK
,"1.7000e01");
387 VARFMT(VT_R8
,V_R8
,86.936849,"#0.000000000000e-000",S_OK
,"86.936849000000e000");
388 VARFMT(VT_R8
,V_R8
,1.7,"#0",S_OK
,"2");
389 VARFMT(VT_R8
,V_R8
,1.7,"#.33",S_OK
,"2.33");
390 VARFMT(VT_R8
,V_R8
,1.7,"#3",S_OK
,"23");
391 VARFMT(VT_R8
,V_R8
,1.73245,"0.0000E+000",S_OK
,"1.7325E+000");
392 VARFMT(VT_R8
,V_R8
,9.9999999,"#0.000000",S_OK
,"10.000000");
393 VARFMT(VT_R8
,V_R8
,1.7,"0.0000e+0#",S_OK
,"1.7000e+0");
394 VARFMT(VT_R8
,V_R8
,100.0001e+0,"0.0000E+0",S_OK
,"1.0000E+2");
395 VARFMT(VT_R8
,V_R8
,1000001,"0.0000e+1",S_OK
,"1.0000e+61");
396 VARFMT(VT_R8
,V_R8
,100.0001e+25,"0.0000e+0",S_OK
,"1.0000e+27");
397 VARFMT(VT_R8
,V_R8
,450.0001e+43,"#000.0000e+0",S_OK
,"4500.0010e+42");
398 VARFMT(VT_R8
,V_R8
,0.0001e-11,"##00.0000e-0",S_OK
,"1000.0000e-18");
399 VARFMT(VT_R8
,V_R8
,0.0317e-11,"0000.0000e-0",S_OK
,"3170.0000e-16");
400 VARFMT(VT_R8
,V_R8
,0.0021e-11,"00##.0000e-0",S_OK
,"2100.0000e-17");
401 VARFMT(VT_R8
,V_R8
,1.0001e-27,"##00.0000e-0",S_OK
,"1000.1000e-30");
402 VARFMT(VT_R8
,V_R8
,47.11,".0000E+0",S_OK
,".4711E+2");
403 VARFMT(VT_R8
,V_R8
,3.0401e-13,"#####.####e-0%",S_OK
,"30401.e-15%");
404 VARFMT(VT_R8
,V_R8
,1.57,"0.00",S_OK
,"1.57");
405 VARFMT(VT_R8
,V_R8
,-1.57,"0.00",S_OK
,"-1.57");
406 VARFMT(VT_R8
,V_R8
,-1.57,"#.##",S_OK
,"-1.57");
407 VARFMT(VT_R8
,V_R8
,-0.1,".#",S_OK
,"-.1");
408 VARFMT(VT_R8
,V_R8
,0.099,"#.#",S_OK
,".1");
409 VARFMT(VT_R8
,V_R8
,0.0999,"#.##",S_OK
,".1");
410 VARFMT(VT_R8
,V_R8
,0.099,"#.##",S_OK
,".1");
411 VARFMT(VT_R8
,V_R8
,0.0099,"#.##",S_OK
,".01");
412 VARFMT(VT_R8
,V_R8
,0.0049,"#.##",S_OK
,".");
413 VARFMT(VT_R8
,V_R8
,0.0094,"#.##",S_OK
,".01");
414 VARFMT(VT_R8
,V_R8
,0.00099,"#.##",S_OK
,".");
415 VARFMT(VT_R8
,V_R8
,0.0995,"#.##",S_OK
,".1");
416 VARFMT(VT_R8
,V_R8
,8.0995,"#.##",S_OK
,"8.1");
417 VARFMT(VT_R8
,V_R8
,0.0994,"#.##",S_OK
,".1");
418 VARFMT(VT_R8
,V_R8
,1.00,"#,##0.00",S_OK
,"1.00");
419 VARFMT(VT_R8
,V_R8
,0.0995,"#.###",S_OK
,".1");
422 /* 'out' is not cleared */
424 hres
= pVarFormat(&in
,NULL
,fd
,fw
,flags
,&out
); /* Would crash if out is cleared */
425 ok(hres
== S_OK
, "got %08x\n", hres
);
431 hres
= pVarFormat(&in
,NULL
,fd
,fw
,0,&out
);
432 ok(hres
== S_OK
, "VarFormat failed with 0x%08x\n", hres
);
433 ok(out
== NULL
, "expected NULL formatted string\n");
436 hres
= pVarFormat(&in
,NULL
,fd
,fw
,flags
,NULL
);
437 ok(hres
== E_INVALIDARG
, "Null out: expected E_INVALIDARG, got 0x%08x\n", hres
);
438 hres
= pVarFormat(NULL
,NULL
,fd
,fw
,flags
,&out
);
439 ok(hres
== E_INVALIDARG
, "Null in: expected E_INVALIDARG, got 0x%08x\n", hres
);
441 VARFMT(VT_BOOL
,V_BOOL
,VARIANT_TRUE
,"",E_INVALIDARG
,"");
443 VARFMT(VT_BOOL
,V_BOOL
,VARIANT_TRUE
,"",E_INVALIDARG
,"");
445 VARFMT(VT_BOOL
,V_BOOL
,VARIANT_TRUE
,"",E_INVALIDARG
,"");
447 VARFMT(VT_BOOL
,V_BOOL
,VARIANT_TRUE
,"",E_INVALIDARG
,"");
450 static const char *szVarWdnFail
=
451 "VarWeekdayName (%d, %d, %d, %d, %x): returned %8x, expected %8x\n";
452 #define VARWDN(iWeekday, fAbbrev, iFirstDay, dwFlags, ret, buff, out, freeOut) \
454 hres = pVarWeekdayName(iWeekday, fAbbrev, iFirstDay, dwFlags, &out); \
455 if (SUCCEEDED(hres)) { \
456 WideCharToMultiByte(CP_ACP, 0, out, -1, buff, sizeof(buff), 0, 0); \
457 if (freeOut) SysFreeString(out); \
463 iWeekday, fAbbrev, iFirstDay, dwFlags, &out, hres, ret \
467 #define VARWDN_F(iWeekday, fAbbrev, iFirstDay, dwFlags, ret) \
468 VARWDN(iWeekday, fAbbrev, iFirstDay, dwFlags, ret, buff, out, 1)
470 #define VARWDN_O(iWeekday, fAbbrev, iFirstDay, dwFlags) \
471 VARWDN(iWeekday, fAbbrev, iFirstDay, dwFlags, S_OK, buff, out, 0)
473 static void test_VarWeekdayName(void)
478 int iWeekday
, fAbbrev
, iFirstDay
;
479 BSTR dayNames
[7][2]; /* Monday-Sunday, full/abbr */
480 DWORD defaultFirstDay
;
486 CHECKPTR(VarWeekdayName
);
488 SetLastError(0xdeadbeef);
489 GetLocaleInfoW(LOCALE_USER_DEFAULT
, 0, NULL
, 0);
490 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
492 win_skip("GetLocaleInfoW is not implemented\n");
496 /* Initialize days' names */
497 for (day
= 0; day
<= 6; ++day
)
499 for (fAbbrev
= 0; fAbbrev
<= 1; ++fAbbrev
)
501 localeValue
= fAbbrev
? LOCALE_SABBREVDAYNAME1
: LOCALE_SDAYNAME1
;
503 size
= GetLocaleInfoW(LOCALE_USER_DEFAULT
, localeValue
, NULL
, 0);
504 dayNames
[day
][fAbbrev
] = SysAllocStringLen(NULL
, size
- 1);
505 GetLocaleInfoW(LOCALE_USER_DEFAULT
, localeValue
,
506 dayNames
[day
][fAbbrev
], size
);
510 /* Get the user's first day of week. 0=Monday, .. */
512 LOCALE_USER_DEFAULT
, LOCALE_IFIRSTDAYOFWEEK
| LOCALE_RETURN_NUMBER
,
513 (LPWSTR
)&defaultFirstDay
, sizeof(defaultFirstDay
) / sizeof(WCHAR
));
515 /* Check invalid arguments */
516 VARWDN_F(0, 0, 4, 0, E_INVALIDARG
);
517 VARWDN_F(8, 0, 4, 0, E_INVALIDARG
);
518 VARWDN_F(4, 0, -1, 0, E_INVALIDARG
);
519 VARWDN_F(4, 0, 8, 0, E_INVALIDARG
);
521 hres
= pVarWeekdayName(1, 0, 0, 0, NULL
);
522 ok(E_INVALIDARG
== hres
,
523 "Null pointer: expected E_INVALIDARG, got 0x%08x\n", hres
);
525 /* Check all combinations */
526 pVarBstrCmp
= (void*)GetProcAddress(hOleaut32
, "VarBstrCmp");
528 for (iWeekday
= 1; iWeekday
<= 7; ++iWeekday
)
530 for (fAbbrev
= 0; fAbbrev
<= 1; ++fAbbrev
)
532 /* 0 = Default, 1 = Sunday, 2 = Monday, .. */
533 for (iFirstDay
= 0; iFirstDay
<= 7; ++iFirstDay
)
535 VARWDN_O(iWeekday
, fAbbrev
, iFirstDay
, 0);
537 firstDay
= defaultFirstDay
;
539 /* Translate from 0=Sunday to 0=Monday in the modulo 7 space */
540 firstDay
= iFirstDay
- 2;
541 day
= (7 + iWeekday
- 1 + firstDay
) % 7;
542 ok(VARCMP_EQ
== pVarBstrCmp(out
, dayNames
[day
][fAbbrev
],
543 LOCALE_USER_DEFAULT
, 0),
544 "VarWeekdayName(%d,%d,%d): got wrong dayname: '%s'\n",
545 iWeekday
, fAbbrev
, iFirstDay
, buff
);
552 for (day
= 0; day
<= 6; ++day
)
554 for (fAbbrev
= 0; fAbbrev
<= 1; ++fAbbrev
)
556 SysFreeString(dayNames
[day
][fAbbrev
]);
561 static void test_VarFormatFromTokens(void)
563 static WCHAR number_fmt
[] = {'#','#','#',',','#','#','0','.','0','0',0};
564 static const WCHAR number
[] = {'6',',','9','0',0};
565 static const WCHAR number_us
[] = {'6','9','0','.','0','0',0};
567 static WCHAR date_fmt
[] = {'d','d','-','m','m',0};
568 static const WCHAR date
[] = {'1','2','-','1','1',0};
569 static const WCHAR date_us
[] = {'1','1','-','1','2',0};
571 static WCHAR string_fmt
[] = {'@',0};
572 static const WCHAR string_de
[] = {'1',',','5',0};
573 static const WCHAR string_us
[] = {'1','.','5',0};
581 V_VT(&var
) = VT_BSTR
;
582 V_BSTR(&var
) = SysAllocString(number
);
584 lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
585 hres
= VarTokenizeFormatString(number_fmt
, buff
, sizeof(buff
), 1, 1, lcid
, NULL
);
586 ok(hres
== S_OK
, "VarTokenizeFormatString failed: %x\n", hres
);
587 hres
= VarFormatFromTokens(&var
, number_fmt
, buff
, 0, &bstr
, lcid
);
588 ok(hres
== S_OK
, "VarFormatFromTokens failed: %x\n", hres
);
589 ok(!strcmpW(bstr
, number_us
), "incorrectly formatted number: %s\n", wine_dbgstr_w(bstr
));
592 lcid
= MAKELCID(MAKELANGID(LANG_GERMAN
, SUBLANG_GERMAN
), SORT_DEFAULT
);
593 hres
= VarTokenizeFormatString(number_fmt
, buff
, sizeof(buff
), 1, 1, lcid
, NULL
);
594 ok(hres
== S_OK
, "VarTokenizeFormatString failed: %x\n", hres
);
595 hres
= VarFormatFromTokens(&var
, number_fmt
, buff
, 0, &bstr
, lcid
);
596 ok(hres
== S_OK
, "VarFormatFromTokens failed: %x\n", hres
);
597 ok(!strcmpW(bstr
, number
), "incorrectly formatted number: %s\n", wine_dbgstr_w(bstr
));
602 V_VT(&var
) = VT_BSTR
;
603 V_BSTR(&var
) = SysAllocString(date
);
605 lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
606 hres
= VarTokenizeFormatString(date_fmt
, buff
, sizeof(buff
), 1, 1, lcid
, NULL
);
607 ok(hres
== S_OK
, "VarTokenizeFormatString failed: %x\n", hres
);
608 hres
= VarFormatFromTokens(&var
, date_fmt
, buff
, 0, &bstr
, lcid
);
609 ok(hres
== S_OK
, "VarFormatFromTokens failed: %x\n", hres
);
610 ok(!strcmpW(bstr
, date_us
), "incorrectly formatted date: %s\n", wine_dbgstr_w(bstr
));
613 lcid
= MAKELCID(MAKELANGID(LANG_GERMAN
, SUBLANG_GERMAN
), SORT_DEFAULT
);
614 hres
= VarTokenizeFormatString(date_fmt
, buff
, sizeof(buff
), 1, 1, lcid
, NULL
);
615 ok(hres
== S_OK
, "VarTokenizeFormatString failed: %x\n", hres
);
616 hres
= VarFormatFromTokens(&var
, date_fmt
, buff
, 0, &bstr
, lcid
);
617 ok(hres
== S_OK
, "VarFormatFromTokens failed: %x\n", hres
);
618 ok(!strcmpW(bstr
, date
), "incorrectly formatted date: %s\n", wine_dbgstr_w(bstr
));
626 lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
627 hres
= VarTokenizeFormatString(string_fmt
, buff
, sizeof(buff
), 1, 1, lcid
, NULL
);
628 ok(hres
== S_OK
, "VarTokenizeFormatString failed: %x\n", hres
);
629 hres
= VarFormatFromTokens(&var
, string_fmt
, buff
, 0, &bstr
, lcid
);
630 ok(hres
== S_OK
, "VarFormatFromTokens failed: %x\n", hres
);
631 ok(!strcmpW(bstr
, string_us
), "incorrectly formatted string: %s\n", wine_dbgstr_w(bstr
));
634 lcid
= MAKELCID(MAKELANGID(LANG_GERMAN
, SUBLANG_GERMAN
), SORT_DEFAULT
);
635 hres
= VarTokenizeFormatString(string_fmt
, buff
, sizeof(buff
), 1, 1, lcid
, NULL
);
636 ok(hres
== S_OK
, "VarTokenizeFormatString failed: %x\n", hres
);
637 hres
= VarFormatFromTokens(&var
, string_fmt
, buff
, 0, &bstr
, lcid
);
638 ok(hres
== S_OK
, "VarFormatFromTokens failed: %x\n", hres
);
639 ok(!strcmpW(bstr
, string_de
), "incorrectly formatted string: %s\n", wine_dbgstr_w(bstr
));
643 static void test_GetAltMonthNames(void)
645 LPOLESTR
*str
, *str2
;
648 str
= (void *)0xdeadbeef;
649 hr
= GetAltMonthNames(0, &str
);
650 ok(hr
== S_OK
, "Unexpected return value %08x\n", hr
);
651 ok(str
== NULL
, "Got %p\n", str
);
653 str
= (void *)0xdeadbeef;
654 hr
= GetAltMonthNames(MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
), &str
);
655 ok(hr
== S_OK
, "Unexpected return value %08x\n", hr
);
656 ok(str
== NULL
, "Got %p\n", str
);
659 hr
= GetAltMonthNames(MAKELCID(MAKELANGID(LANG_ARABIC
, SUBLANG_ARABIC_EGYPT
), SORT_DEFAULT
), &str
);
660 ok(hr
== S_OK
, "Unexpected return value %08x\n", hr
);
661 ok(str
!= NULL
, "Got %p\n", str
);
664 hr
= GetAltMonthNames(MAKELCID(MAKELANGID(LANG_ARABIC
, SUBLANG_ARABIC_EGYPT
), SORT_DEFAULT
), &str2
);
665 ok(hr
== S_OK
, "Unexpected return value %08x\n", hr
);
666 ok(str2
== str
, "Got %p\n", str2
);
669 hr
= GetAltMonthNames(MAKELCID(MAKELANGID(LANG_RUSSIAN
, SUBLANG_DEFAULT
), SORT_DEFAULT
), &str
);
670 ok(hr
== S_OK
, "Unexpected return value %08x\n", hr
);
671 ok(str
!= NULL
, "Got %p\n", str
);
674 hr
= GetAltMonthNames(MAKELCID(MAKELANGID(LANG_POLISH
, SUBLANG_DEFAULT
), SORT_DEFAULT
), &str
);
675 ok(hr
== S_OK
, "Unexpected return value %08x\n", hr
);
676 ok(str
!= NULL
, "Got %p\n", str
);
679 START_TEST(varformat
)
681 hOleaut32
= GetModuleHandleA("oleaut32.dll");
683 has_i8
= GetProcAddress(hOleaut32
, "VarI8FromI1") != NULL
;
685 test_VarFormatNumber();
687 test_VarWeekdayName();
688 test_VarFormatFromTokens();
689 test_GetAltMonthNames();