2 * Unit tests for locale functions
4 * Copyright 2002 YASAR Mehmet
5 * Copyright 2003 Dmitry Timoshkov
6 * Copyright 2003 Jon Griffiths
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * We must pass LOCALE_NOUSEROVERRIDE (NUO) to formatting functions so that
24 * even when the user has overridden their default i8n settings (e.g. in
25 * the control panel i8n page), we will still get the expected results.
32 #include "wine/test.h"
38 static inline unsigned int strlenW( const WCHAR
*str
)
45 static inline int strncmpW( const WCHAR
*str1
, const WCHAR
*str2
, int n
)
48 while ((--n
> 0) && *str1
&& (*str1
== *str2
)) { str1
++; str2
++; }
52 static inline WCHAR
*strchrW( const WCHAR
*str
, WCHAR ch
)
54 do { if (*str
== ch
) return (WCHAR
*)str
; } while (*str
++);
58 static inline int isdigitW( WCHAR wc
)
61 GetStringTypeW( CT_CTYPE1
, &wc
, 1, &type
);
62 return type
& C1_DIGIT
;
65 /* Some functions are only in later versions of kernel32.dll */
66 static HMODULE hKernel32
;
67 static WORD enumCount
;
69 typedef BOOL (WINAPI
*EnumSystemLanguageGroupsAFn
)(LANGUAGEGROUP_ENUMPROC
,
71 static EnumSystemLanguageGroupsAFn pEnumSystemLanguageGroupsA
;
72 typedef BOOL (WINAPI
*EnumLanguageGroupLocalesAFn
)(LANGGROUPLOCALE_ENUMPROC
,
73 LGRPID
, DWORD
, LONG_PTR
);
74 static EnumLanguageGroupLocalesAFn pEnumLanguageGroupLocalesA
;
75 typedef BOOL (WINAPI
*EnumUILanguagesAFn
)(UILANGUAGE_ENUMPROC
,
77 static EnumUILanguagesAFn pEnumUILanguagesA
;
79 typedef INT (WINAPI
*FoldStringAFn
)(DWORD
, LPCSTR
, INT
, LPSTR
, INT
);
80 static FoldStringAFn pFoldStringA
;
81 typedef INT (WINAPI
*FoldStringWFn
)(DWORD
, LPCWSTR
, INT
, LPWSTR
, INT
);
82 static FoldStringWFn pFoldStringW
;
84 typedef BOOL (WINAPI
*IsValidLanguageGroupFn
)(LGRPID
, DWORD
);
85 static IsValidLanguageGroupFn pIsValidLanguageGroup
;
87 static void InitFunctionPointers(void)
89 hKernel32
= GetModuleHandleA("kernel32");
90 pEnumSystemLanguageGroupsA
= (void*)GetProcAddress(hKernel32
, "EnumSystemLanguageGroupsA");
91 pEnumLanguageGroupLocalesA
= (void*)GetProcAddress(hKernel32
, "EnumLanguageGroupLocalesA");
92 pFoldStringA
= (void*)GetProcAddress(hKernel32
, "FoldStringA");
93 pFoldStringW
= (void*)GetProcAddress(hKernel32
, "FoldStringW");
94 pIsValidLanguageGroup
= (void*)GetProcAddress(hKernel32
, "IsValidLanguageGroup");
95 pEnumUILanguagesA
= (void*)GetProcAddress(hKernel32
, "EnumUILanguagesA");
98 #define eq(received, expected, label, type) \
99 ok((received) == (expected), "%s: got " type " instead of " type "\n", \
100 (label), (received), (expected))
102 #define BUFFER_SIZE 128
103 #define COUNTOF(x) (sizeof(x)/sizeof(x)[0])
105 #define STRINGSA(x,y) strcpy(input, x); strcpy(Expected, y); SetLastError(0xdeadbeef); buffer[0] = '\0'
106 #define EXPECT_LENA ok(ret == lstrlen(Expected)+1, "Expected Len %d, got %d\n", lstrlen(Expected)+1, ret)
107 #define EXPECT_EQA ok(strncmp(buffer, Expected, strlen(Expected)) == 0, \
108 "Expected '%s', got '%s'\n", Expected, buffer)
110 #define STRINGSW(x,y) MultiByteToWideChar(CP_ACP,0,x,-1,input,COUNTOF(input)); \
111 MultiByteToWideChar(CP_ACP,0,y,-1,Expected,COUNTOF(Expected)); \
112 SetLastError(0xdeadbeef); buffer[0] = '\0'
113 #define EXPECT_LENW ok(ret == lstrlenW(Expected)+1, "Expected Len %d, got %d\n", lstrlenW(Expected)+1, ret)
114 #define EXPECT_EQW ok(strncmpW(buffer, Expected, strlenW(Expected)) == 0, "Bad conversion\n")
116 #define NUO LOCALE_NOUSEROVERRIDE
118 static void test_GetLocaleInfoA(void)
122 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
123 char buffer
[BUFFER_SIZE
];
124 char expected
[BUFFER_SIZE
];
126 ok(lcid
== 0x409, "wrong LCID calculated - %d\n", lcid
);
128 /* en and ar use SUBLANG_NEUTRAL, but GetLocaleInfo assume SUBLANG_DEFAULT
129 Same is true for zh on pre-Vista, but on Vista and higher GetLocaleInfo
130 assumes SUBLANG_NEUTRAL for zh */
131 memset(expected
, 0, COUNTOF(expected
));
132 len
= GetLocaleInfoA(MAKELANGID(LANG_ENGLISH
, SUBLANG_DEFAULT
), LOCALE_SLANGUAGE
, expected
, COUNTOF(expected
));
133 SetLastError(0xdeadbeef);
134 memset(buffer
, 0, COUNTOF(buffer
));
135 ret
= GetLocaleInfoA(LANG_ENGLISH
, LOCALE_SLANGUAGE
, buffer
, COUNTOF(buffer
));
136 ok((ret
== len
) && !lstrcmpA(buffer
, expected
),
137 "got %d with '%s' (expected %d with '%s')\n",
138 ret
, buffer
, len
, expected
);
140 memset(expected
, 0, COUNTOF(expected
));
141 len
= GetLocaleInfoA(MAKELANGID(LANG_ARABIC
, SUBLANG_DEFAULT
), LOCALE_SLANGUAGE
, expected
, COUNTOF(expected
));
143 SetLastError(0xdeadbeef);
144 memset(buffer
, 0, COUNTOF(buffer
));
145 ret
= GetLocaleInfoA(LANG_ARABIC
, LOCALE_SLANGUAGE
, buffer
, COUNTOF(buffer
));
146 ok((ret
== len
) && !lstrcmpA(buffer
, expected
),
147 "got %d with '%s' (expected %d with '%s')\n",
148 ret
, buffer
, len
, expected
);
151 win_skip("LANG_ARABIC not installed\n");
153 /* SUBLANG_DEFAULT is required for mlang.dll, but optional for GetLocaleInfo */
154 memset(expected
, 0, COUNTOF(expected
));
155 len
= GetLocaleInfoA(MAKELANGID(LANG_GERMAN
, SUBLANG_DEFAULT
), LOCALE_SLANGUAGE
, expected
, COUNTOF(expected
));
156 SetLastError(0xdeadbeef);
157 memset(buffer
, 0, COUNTOF(buffer
));
158 ret
= GetLocaleInfoA(LANG_GERMAN
, LOCALE_SLANGUAGE
, buffer
, COUNTOF(buffer
));
159 ok((ret
== len
) && !lstrcmpA(buffer
, expected
),
160 "got %d with '%s' (expected %d with '%s')\n",
161 ret
, buffer
, len
, expected
);
164 /* HTMLKit and "Font xplorer lite" expect GetLocaleInfoA to
165 * partially fill the buffer even if it is too short. See bug 637.
167 SetLastError(0xdeadbeef);
168 memset(buffer
, 0, COUNTOF(buffer
));
169 ret
= GetLocaleInfoA(lcid
, NUO
|LOCALE_SDAYNAME1
, buffer
, 0);
170 ok(ret
== 7 && !buffer
[0], "Expected len=7, got %d\n", ret
);
172 SetLastError(0xdeadbeef);
173 memset(buffer
, 0, COUNTOF(buffer
));
174 ret
= GetLocaleInfoA(lcid
, NUO
|LOCALE_SDAYNAME1
, buffer
, 3);
175 ok( !ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
176 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
177 ok(!strcmp(buffer
, "Mon"), "Expected 'Mon', got '%s'\n", buffer
);
179 SetLastError(0xdeadbeef);
180 memset(buffer
, 0, COUNTOF(buffer
));
181 ret
= GetLocaleInfoA(lcid
, NUO
|LOCALE_SDAYNAME1
, buffer
, 10);
182 ok(ret
== 7, "Expected ret == 7, got %d, error %d\n", ret
, GetLastError());
183 ok(!strcmp(buffer
, "Monday"), "Expected 'Monday', got '%s'\n", buffer
);
186 static void test_GetLocaleInfoW(void)
188 LCID lcid_en
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
189 LCID lcid_ru
= MAKELCID(MAKELANGID(LANG_RUSSIAN
, SUBLANG_NEUTRAL
), SORT_DEFAULT
);
190 WCHAR bufferW
[80], buffer2W
[80];
195 ret
= GetLocaleInfoW(lcid_en
, LOCALE_SMONTHNAME1
, bufferW
, COUNTOF(bufferW
));
197 win_skip("GetLocaleInfoW() isn't implemented\n");
200 ret
= GetLocaleInfoW(lcid_ru
, LOCALE_SMONTHNAME1
, bufferW
, COUNTOF(bufferW
));
202 win_skip("LANG_RUSSIAN locale data unavailable\n");
205 ret
= GetLocaleInfoW(lcid_ru
, LOCALE_SMONTHNAME1
|LOCALE_RETURN_GENITIVE_NAMES
,
206 bufferW
, COUNTOF(bufferW
));
208 win_skip("LOCALE_RETURN_GENITIVE_NAMES isn't supported\n");
212 /* LOCALE_RETURN_GENITIVE_NAMES isn't supported for GetLocaleInfoA */
214 SetLastError(0xdeadbeef);
215 ret
= GetLocaleInfoA(lcid_ru
, LOCALE_SMONTHNAME1
|LOCALE_RETURN_GENITIVE_NAMES
,
216 bufferA
, COUNTOF(bufferA
));
217 ok(ret
== 0, "LOCALE_RETURN_GENITIVE_NAMES should fail with GetLocaleInfoA\n");
218 ok(bufferA
[0] == 'a', "Expected buffer to be untouched\n");
219 ok(GetLastError() == ERROR_INVALID_FLAGS
,
220 "Expected ERROR_INVALID_FLAGS, got %x\n", GetLastError());
223 SetLastError(0xdeadbeef);
224 ret
= GetLocaleInfoW(lcid_ru
, LOCALE_RETURN_GENITIVE_NAMES
,
225 bufferW
, COUNTOF(bufferW
));
227 "LOCALE_RETURN_GENITIVE_NAMES itself doesn't return anything, got %d\n", ret
);
228 ok(bufferW
[0] == 'a', "Expected buffer to be untouched\n");
229 ok(GetLastError() == ERROR_INVALID_FLAGS
,
230 "Expected ERROR_INVALID_FLAGS, got %x\n", GetLastError());
232 /* yes, test empty 13 month entry too */
233 for (i
= 0; i
< 12; i
++) {
235 ret
= GetLocaleInfoW(lcid_ru
, (LOCALE_SMONTHNAME1
+i
)|LOCALE_RETURN_GENITIVE_NAMES
,
236 bufferW
, COUNTOF(bufferW
));
237 ok(ret
, "Expected non zero result\n");
238 ok(ret
== lstrlenW(bufferW
)+1, "Expected actual length, got %d, length %d\n",
239 ret
, lstrlenW(bufferW
));
241 ret
= GetLocaleInfoW(lcid_ru
, LOCALE_SMONTHNAME1
+i
,
242 buffer2W
, COUNTOF(buffer2W
));
243 ok(ret
, "Expected non zero result\n");
244 ok(ret
== lstrlenW(buffer2W
)+1, "Expected actual length, got %d, length %d\n",
245 ret
, lstrlenW(buffer2W
));
247 ok(lstrcmpW(bufferW
, buffer2W
) != 0,
248 "Expected genitive name to differ, got the same for month %d\n", i
+1);
250 /* for locale without genitive names nominative returned in both cases */
252 ret
= GetLocaleInfoW(lcid_en
, (LOCALE_SMONTHNAME1
+i
)|LOCALE_RETURN_GENITIVE_NAMES
,
253 bufferW
, COUNTOF(bufferW
));
254 ok(ret
, "Expected non zero result\n");
255 ok(ret
== lstrlenW(bufferW
)+1, "Expected actual length, got %d, length %d\n",
256 ret
, lstrlenW(bufferW
));
258 ret
= GetLocaleInfoW(lcid_en
, LOCALE_SMONTHNAME1
+i
,
259 buffer2W
, COUNTOF(buffer2W
));
260 ok(ret
, "Expected non zero result\n");
261 ok(ret
== lstrlenW(buffer2W
)+1, "Expected actual length, got %d, length %d\n",
262 ret
, lstrlenW(buffer2W
));
264 ok(lstrcmpW(bufferW
, buffer2W
) == 0,
265 "Expected same names, got different for month %d\n", i
+1);
269 static void test_GetTimeFormatA(void)
273 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
274 char buffer
[BUFFER_SIZE
], input
[BUFFER_SIZE
], Expected
[BUFFER_SIZE
];
276 memset(&curtime
, 2, sizeof(SYSTEMTIME
));
277 STRINGSA("tt HH':'mm'@'ss", ""); /* Invalid time */
278 SetLastError(0xdeadbeef);
279 ret
= GetTimeFormatA(lcid
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
280 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
281 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
284 curtime
.wMinute
= 56;
285 curtime
.wSecond
= 13;
286 curtime
.wMilliseconds
= 22;
287 STRINGSA("tt HH':'mm'@'ss", "AM 08:56@13"); /* Valid time */
288 SetLastError(0xdeadbeef);
289 ret
= GetTimeFormatA(lcid
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
290 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
291 EXPECT_LENA
; EXPECT_EQA
;
293 /* MSDN: LOCALE_NOUSEROVERRIDE can't be specified with a format string */
294 SetLastError(0xdeadbeef);
295 ret
= GetTimeFormatA(lcid
, NUO
|TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
296 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
297 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
299 STRINGSA("tt HH':'mm'@'ss", "A"); /* Insufficient buffer */
300 SetLastError(0xdeadbeef);
301 ret
= GetTimeFormatA(lcid
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, 2);
302 ok( !ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
303 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
305 STRINGSA("tt HH':'mm'@'ss", "AM 08:56@13"); /* Calculate length only */
306 ret
= GetTimeFormatA(lcid
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, NULL
, 0);
307 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
310 STRINGSA("", "8 AM"); /* TIME_NOMINUTESORSECONDS, default format */
311 ret
= GetTimeFormatA(lcid
, NUO
|TIME_NOMINUTESORSECONDS
, &curtime
, NULL
, buffer
, COUNTOF(buffer
));
312 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
313 EXPECT_LENA
; EXPECT_EQA
;
315 STRINGSA("m1s2m3s4", ""); /* TIME_NOMINUTESORSECONDS/complex format */
316 ret
= GetTimeFormatA(lcid
, TIME_NOMINUTESORSECONDS
, &curtime
, input
, buffer
, COUNTOF(buffer
));
317 ok(ret
== strlen(buffer
)+1, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
318 ok( !strcmp( buffer
, "" ) || broken( !strcmp( buffer
, "4" )), /* win9x */
319 "Expected '', got '%s'\n", buffer
);
321 STRINGSA("", "8:56 AM"); /* TIME_NOSECONDS/Default format */
322 ret
= GetTimeFormatA(lcid
, NUO
|TIME_NOSECONDS
, &curtime
, NULL
, buffer
, COUNTOF(buffer
));
323 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
324 EXPECT_LENA
; EXPECT_EQA
;
326 STRINGSA("h:m:s tt", "8:56 AM"); /* TIME_NOSECONDS */
327 strcpy(Expected
, "8:56 AM");
328 ret
= GetTimeFormatA(lcid
, TIME_NOSECONDS
, &curtime
, input
, buffer
, COUNTOF(buffer
));
329 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
330 EXPECT_LENA
; EXPECT_EQA
;
332 STRINGSA("h.@:m.@:s.@:tt", "8.@:56AM"); /* Multiple delimiters */
333 ret
= GetTimeFormatA(lcid
, TIME_NOSECONDS
, &curtime
, input
, buffer
, COUNTOF(buffer
));
334 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
335 ok( !strcmp( buffer
, "8.@:56AM" ) || broken( !strcmp( buffer
, "8.@:56.@:AM" )) /* win9x */,
336 "Expected '8.@:56AM', got '%s'\n", buffer
);
338 STRINGSA("s1s2s3", ""); /* Duplicate tokens */
339 ret
= GetTimeFormatA(lcid
, TIME_NOSECONDS
, &curtime
, input
, buffer
, COUNTOF(buffer
));
340 ok(ret
== strlen(buffer
)+1, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
341 ok( !strcmp( buffer
, "" ) || broken( !strcmp( buffer
, "3" )), /* win9x */
342 "Expected '', got '%s'\n", buffer
);
344 STRINGSA("t/tt", "A/AM"); /* AM time marker */
345 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
346 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
347 EXPECT_LENA
; EXPECT_EQA
;
350 STRINGSA("t/tt", "P/PM"); /* PM time marker */
351 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
352 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
353 EXPECT_LENA
; EXPECT_EQA
;
355 STRINGSA("h1t2tt3m", "156"); /* TIME_NOTIMEMARKER: removes text around time marker token */
356 ret
= GetTimeFormatA(lcid
, TIME_NOTIMEMARKER
, &curtime
, input
, buffer
, COUNTOF(buffer
));
357 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
358 EXPECT_LENA
; EXPECT_EQA
;
360 STRINGSA("h:m:s tt", "13:56:13 PM"); /* TIME_FORCE24HOURFORMAT */
361 ret
= GetTimeFormatA(lcid
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
362 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
363 EXPECT_LENA
; EXPECT_EQA
;
365 STRINGSA("h:m:s", "13:56:13"); /* TIME_FORCE24HOURFORMAT doesn't add time marker */
366 ret
= GetTimeFormatA(lcid
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
367 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
368 EXPECT_LENA
; EXPECT_EQA
;
370 curtime
.wHour
= 14; /* change this to 14 or 2pm */
373 STRINGSA("h hh H HH m mm s ss t tt", "2 02 14 14 5 05 3 03 P PM"); /* 24 hrs, leading 0 */
374 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
375 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
376 EXPECT_LENA
; EXPECT_EQA
;
379 STRINGSA("h/H/hh/HH", "12/0/12/00"); /* "hh" and "HH" */
380 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
381 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
382 EXPECT_LENA
; EXPECT_EQA
;
384 STRINGSA("h:m:s tt", "12:5:3 AM"); /* non-zero flags should fail with format, doesn't */
385 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
386 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
387 EXPECT_LENA
; EXPECT_EQA
;
389 /* try to convert formatting strings with more than two letters
390 * "h:hh:hhh:H:HH:HHH:m:mm:mmm:M:MM:MMM:s:ss:sss:S:SS:SSS"
391 * NOTE: We expect any letter for which there is an upper case value
392 * we should see a replacement. For letters that DO NOT have
393 * upper case values we should see NO REPLACEMENT.
396 curtime
.wMinute
= 56;
397 curtime
.wSecond
= 13;
398 curtime
.wMilliseconds
= 22;
399 STRINGSA("h:hh:hhh H:HH:HHH m:mm:mmm M:MM:MMM s:ss:sss S:SS:SSS",
400 "8:08:08 8:08:08 56:56:56 M:MM:MMM 13:13:13 S:SS:SSS");
401 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
402 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
403 EXPECT_LENA
; EXPECT_EQA
;
405 STRINGSA("h", "text"); /* Don't write to buffer if len is 0 */
406 strcpy(buffer
, "text");
407 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, 0);
408 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
411 STRINGSA("h 'h' H 'H' HH 'HH' m 'm' s 's' t 't' tt 'tt'",
412 "8 h 8 H 08 HH 56 m 13 s A t AM tt"); /* "'" preserves tokens */
413 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
414 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
415 EXPECT_LENA
; EXPECT_EQA
;
417 STRINGSA("'''", "'"); /* invalid quoted string */
418 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
419 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
420 EXPECT_LENA
; EXPECT_EQA
;
422 /* test that msdn suggested single quotation usage works as expected */
423 STRINGSA("''''", "'"); /* single quote mark */
424 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
425 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
426 EXPECT_LENA
; EXPECT_EQA
;
428 STRINGSA("''HHHHHH", "08"); /* Normal use */
429 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
430 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
431 EXPECT_LENA
; EXPECT_EQA
;
433 /* and test for normal use of the single quotation mark */
434 STRINGSA("'''HHHHHH'", "'HHHHHH"); /* Normal use */
435 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
436 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
437 EXPECT_LENA
; EXPECT_EQA
;
439 STRINGSA("'''HHHHHH", "'HHHHHH"); /* Odd use */
440 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
441 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
442 EXPECT_LENA
; EXPECT_EQA
;
444 STRINGSA("'123'tt", ""); /* TIME_NOTIMEMARKER drops literals too */
445 ret
= GetTimeFormatA(lcid
, TIME_NOTIMEMARKER
, &curtime
, input
, buffer
, COUNTOF(buffer
));
446 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
447 EXPECT_LENA
; EXPECT_EQA
;
450 STRINGSA("'123'tt", ""); /* Invalid time */
451 SetLastError(0xdeadbeef);
452 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
453 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
454 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
457 curtime
.wMonth
= 60; /* Invalid */
458 STRINGSA("h:m:s", "12:56:13"); /* Invalid date */
459 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
460 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
461 EXPECT_LENA
; EXPECT_EQA
;
464 static void test_GetDateFormatA(void)
468 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
469 char buffer
[BUFFER_SIZE
], input
[BUFFER_SIZE
], Expected
[BUFFER_SIZE
];
471 memset(&curtime
, 2, sizeof(SYSTEMTIME
)); /* Invalid time */
472 STRINGSA("ddd',' MMM dd yy","");
473 SetLastError(0xdeadbeef);
474 ret
= GetDateFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
475 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
476 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
478 curtime
.wYear
= 2002;
481 curtime
.wDayOfWeek
= 3;
482 STRINGSA("ddd',' MMM dd yy","Sat, May 04 02"); /* Simple case */
483 ret
= GetDateFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
484 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
485 EXPECT_LENA
; EXPECT_EQA
;
487 /* Same as above but with LOCALE_NOUSEROVERRIDE */
488 STRINGSA("ddd',' MMM dd yy",""); /* Simple case */
489 SetLastError(0xdeadbeef);
490 ret
= GetDateFormatA(lcid
, NUO
, &curtime
, input
, buffer
, COUNTOF(buffer
));
491 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
492 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
495 STRINGSA("ddd',' MMM dd yy","Sat, May 04 02"); /* Format containing "'" */
496 ret
= GetDateFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
497 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
498 EXPECT_LENA
; EXPECT_EQA
;
500 curtime
.wHour
= 36; /* Invalid */
501 STRINGSA("ddd',' MMM dd ''''yy","Sat, May 04 '02"); /* Invalid time */
502 ret
= GetDateFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
503 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
504 EXPECT_LENA
; EXPECT_EQA
;
506 STRINGSA("ddd',' MMM dd ''''yy",""); /* Get size only */
507 ret
= GetDateFormatA(lcid
, 0, &curtime
, input
, NULL
, 0);
508 ok(ret
== 16, "Expected ret == 16, got %d, error %d\n", ret
, GetLastError());
511 STRINGSA("ddd',' MMM dd ''''yy",""); /* Buffer too small */
512 SetLastError(0xdeadbeef);
513 ret
= GetDateFormatA(lcid
, 0, &curtime
, input
, buffer
, 2);
514 ok( !ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
515 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
517 STRINGSA("ddd',' MMM dd ''''yy","5/4/2002"); /* Default to DATE_SHORTDATE */
518 ret
= GetDateFormat(lcid
, NUO
, &curtime
, NULL
, buffer
, COUNTOF(buffer
));
519 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
520 if (strncmp(buffer
, Expected
, strlen(Expected
)) && strncmp(buffer
, "5/4/02", strlen(Expected
)) != 0)
521 ok (0, "Expected '%s' or '5/4/02', got '%s'\n", Expected
, buffer
);
523 STRINGSA("ddd',' MMM dd ''''yy", "Saturday, May 04, 2002"); /* DATE_LONGDATE */
524 ret
= GetDateFormat(lcid
, NUO
|DATE_LONGDATE
, &curtime
, NULL
, buffer
, COUNTOF(buffer
));
525 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
526 EXPECT_LENA
; EXPECT_EQA
;
528 /* test for expected DATE_YEARMONTH behavior with null format */
529 /* NT4 returns ERROR_INVALID_FLAGS for DATE_YEARMONTH */
530 STRINGSA("ddd',' MMM dd ''''yy", ""); /* DATE_YEARMONTH */
531 SetLastError(0xdeadbeef);
532 ret
= GetDateFormat(lcid
, NUO
|DATE_YEARMONTH
, &curtime
, input
, buffer
, COUNTOF(buffer
));
533 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
534 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
537 /* Test that using invalid DATE_* flags results in the correct error */
538 /* and return values */
539 STRINGSA("m/d/y", ""); /* Invalid flags */
540 SetLastError(0xdeadbeef);
541 ret
= GetDateFormat(lcid
, DATE_YEARMONTH
|DATE_SHORTDATE
|DATE_LONGDATE
,
542 &curtime
, input
, buffer
, COUNTOF(buffer
));
543 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
544 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
548 static void test_GetDateFormatW(void)
552 WCHAR buffer
[BUFFER_SIZE
], input
[BUFFER_SIZE
], Expected
[BUFFER_SIZE
];
553 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
555 STRINGSW("",""); /* If flags is not zero then format must be NULL */
556 ret
= GetDateFormatW(LOCALE_SYSTEM_DEFAULT
, DATE_LONGDATE
, NULL
,
557 input
, buffer
, COUNTOF(buffer
));
558 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
560 win_skip("GetDateFormatW is not implemented\n");
563 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
564 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
567 STRINGSW("",""); /* NULL buffer, len > 0 */
568 SetLastError(0xdeadbeef);
569 ret
= GetDateFormatW (lcid
, 0, NULL
, input
, NULL
, COUNTOF(buffer
));
570 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
571 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
573 STRINGSW("",""); /* NULL buffer, len == 0 */
574 ret
= GetDateFormatW (lcid
, 0, NULL
, input
, NULL
, 0);
575 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
576 EXPECT_LENW
; EXPECT_EQW
;
578 curtime
.wYear
= 2002;
581 curtime
.wDayOfWeek
= 45612; /* Should be 3 - Wednesday */
582 curtime
.wHour
= 65432; /* Invalid */
583 curtime
.wMinute
= 34512; /* Invalid */
584 curtime
.wSecond
= 65535; /* Invalid */
585 curtime
.wMilliseconds
= 12345;
586 STRINGSW("dddd d MMMM yyyy","Wednesday 23 October 2002"); /* Incorrect DOW and time */
587 ret
= GetDateFormatW (lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
588 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
589 EXPECT_LENW
; EXPECT_EQW
;
593 curtime
.wYear
= 1601;
596 curtime
.wDayOfWeek
= 0; /* Irrelevant */
600 curtime
.wMilliseconds
= 0;
601 STRINGSW("dddd d MMMM yyyy","Monday 1 January 1601");
602 SetLastError(0xdeadbeef);
603 ret
= GetDateFormatW (lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
604 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
605 EXPECT_LENW
; EXPECT_EQW
;
607 curtime
.wYear
= 1600;
610 curtime
.wDayOfWeek
= 0; /* Irrelevant */
612 curtime
.wMinute
= 59;
613 curtime
.wSecond
= 59;
614 curtime
.wMilliseconds
= 999;
615 STRINGSW("dddd d MMMM yyyy","Friday 31 December 1600");
616 SetLastError(0xdeadbeef);
617 ret
= GetDateFormatW (lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
618 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
619 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
623 #define CY_POS_LEFT 0
624 #define CY_POS_RIGHT 1
625 #define CY_POS_LEFT_SPACE 2
626 #define CY_POS_RIGHT_SPACE 3
628 static void test_GetCurrencyFormatA(void)
630 static char szDot
[] = { '.', '\0' };
631 static char szComma
[] = { ',', '\0' };
632 static char szDollar
[] = { '$', '\0' };
634 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
635 char buffer
[BUFFER_SIZE
], Expected
[BUFFER_SIZE
], input
[BUFFER_SIZE
];
638 memset(&format
, 0, sizeof(format
));
640 STRINGSA("23",""); /* NULL output, length > 0 --> Error */
641 SetLastError(0xdeadbeef);
642 ret
= GetCurrencyFormatA(lcid
, 0, input
, NULL
, NULL
, COUNTOF(buffer
));
643 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
644 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
646 STRINGSA("23,53",""); /* Invalid character --> Error */
647 SetLastError(0xdeadbeef);
648 ret
= GetCurrencyFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
649 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
650 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
652 STRINGSA("--",""); /* Double '-' --> Error */
653 SetLastError(0xdeadbeef);
654 ret
= GetCurrencyFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
655 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
656 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
658 STRINGSA("0-",""); /* Trailing '-' --> Error */
659 SetLastError(0xdeadbeef);
660 ret
= GetCurrencyFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
661 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
662 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
664 STRINGSA("0..",""); /* Double '.' --> Error */
665 SetLastError(0xdeadbeef);
666 ret
= GetCurrencyFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
667 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
668 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
670 STRINGSA(" 0.1",""); /* Leading space --> Error */
671 SetLastError(0xdeadbeef);
672 ret
= GetCurrencyFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
673 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
674 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
676 STRINGSA("1234","$"); /* Length too small --> Write up to length chars */
677 SetLastError(0xdeadbeef);
678 ret
= GetCurrencyFormatA(lcid
, NUO
, input
, NULL
, buffer
, 2);
679 ok( !ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
680 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
682 STRINGSA("2353",""); /* Format and flags given --> Error */
683 SetLastError(0xdeadbeef);
684 ret
= GetCurrencyFormatA(lcid
, NUO
, input
, &format
, buffer
, COUNTOF(buffer
));
685 ok( !ret
, "Expected ret == 0, got %d\n", ret
);
686 ok( GetLastError() == ERROR_INVALID_FLAGS
|| GetLastError() == ERROR_INVALID_PARAMETER
,
687 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
689 STRINGSA("2353",""); /* Invalid format --> Error */
690 SetLastError(0xdeadbeef);
691 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
692 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
693 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
695 STRINGSA("2353","$2,353.00"); /* Valid number */
696 ret
= GetCurrencyFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
697 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
698 EXPECT_LENA
; EXPECT_EQA
;
700 STRINGSA("-2353","($2,353.00)"); /* Valid negative number */
701 ret
= GetCurrencyFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
702 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
703 EXPECT_LENA
; EXPECT_EQA
;
705 STRINGSA("2353.1","$2,353.10"); /* Valid real number */
706 ret
= GetCurrencyFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
707 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
708 EXPECT_LENA
; EXPECT_EQA
;
710 STRINGSA("2353.111","$2,353.11"); /* Too many DP --> Truncated */
711 ret
= GetCurrencyFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
712 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
713 EXPECT_LENA
; EXPECT_EQA
;
715 STRINGSA("2353.119","$2,353.12"); /* Too many DP --> Rounded */
716 ret
= GetCurrencyFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
717 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
718 EXPECT_LENA
; EXPECT_EQA
;
720 format
.NumDigits
= 0; /* No decimal separator */
721 format
.LeadingZero
= 0;
722 format
.Grouping
= 0; /* No grouping char */
723 format
.NegativeOrder
= 0;
724 format
.PositiveOrder
= CY_POS_LEFT
;
725 format
.lpDecimalSep
= szDot
;
726 format
.lpThousandSep
= szComma
;
727 format
.lpCurrencySymbol
= szDollar
;
729 STRINGSA("2353","$2353"); /* No decimal or grouping chars expected */
730 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
731 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
732 EXPECT_LENA
; EXPECT_EQA
;
734 format
.NumDigits
= 1; /* 1 DP --> Expect decimal separator */
735 STRINGSA("2353","$2353.0");
736 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
737 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
738 EXPECT_LENA
; EXPECT_EQA
;
740 format
.Grouping
= 2; /* Group by 100's */
741 STRINGSA("2353","$23,53.0");
742 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
743 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
744 EXPECT_LENA
; EXPECT_EQA
;
746 format
.LeadingZero
= 1; /* Always provide leading zero */
747 STRINGSA(".5","$0.5");
748 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
749 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
750 EXPECT_LENA
; EXPECT_EQA
;
752 format
.PositiveOrder
= CY_POS_RIGHT
;
753 STRINGSA("1","1.0$");
754 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
755 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
756 EXPECT_LENA
; EXPECT_EQA
;
758 format
.PositiveOrder
= CY_POS_LEFT_SPACE
;
759 STRINGSA("1","$ 1.0");
760 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
761 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
762 EXPECT_LENA
; EXPECT_EQA
;
764 format
.PositiveOrder
= CY_POS_RIGHT_SPACE
;
765 STRINGSA("1","1.0 $");
766 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
767 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
768 EXPECT_LENA
; EXPECT_EQA
;
770 format
.NegativeOrder
= 0;
771 STRINGSA("-1","($1.0)");
772 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
773 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
774 EXPECT_LENA
; EXPECT_EQA
;
776 format
.NegativeOrder
= 1;
777 STRINGSA("-1","-$1.0");
778 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
779 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
780 EXPECT_LENA
; EXPECT_EQA
;
782 format
.NegativeOrder
= 2;
783 STRINGSA("-1","$-1.0");
784 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
785 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
786 EXPECT_LENA
; EXPECT_EQA
;
788 format
.NegativeOrder
= 3;
789 STRINGSA("-1","$1.0-");
790 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
791 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
792 EXPECT_LENA
; EXPECT_EQA
;
794 format
.NegativeOrder
= 4;
795 STRINGSA("-1","(1.0$)");
796 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
797 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
798 EXPECT_LENA
; EXPECT_EQA
;
800 format
.NegativeOrder
= 5;
801 STRINGSA("-1","-1.0$");
802 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
803 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
804 EXPECT_LENA
; EXPECT_EQA
;
806 format
.NegativeOrder
= 6;
807 STRINGSA("-1","1.0-$");
808 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
809 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
810 EXPECT_LENA
; EXPECT_EQA
;
812 format
.NegativeOrder
= 7;
813 STRINGSA("-1","1.0$-");
814 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
815 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
816 EXPECT_LENA
; EXPECT_EQA
;
818 format
.NegativeOrder
= 8;
819 STRINGSA("-1","-1.0 $");
820 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
821 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
822 EXPECT_LENA
; EXPECT_EQA
;
824 format
.NegativeOrder
= 9;
825 STRINGSA("-1","-$ 1.0");
826 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
827 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
828 EXPECT_LENA
; EXPECT_EQA
;
830 format
.NegativeOrder
= 10;
831 STRINGSA("-1","1.0 $-");
832 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
833 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
834 EXPECT_LENA
; EXPECT_EQA
;
836 format
.NegativeOrder
= 11;
837 STRINGSA("-1","$ 1.0-");
838 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
839 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
840 EXPECT_LENA
; EXPECT_EQA
;
842 format
.NegativeOrder
= 12;
843 STRINGSA("-1","$ -1.0");
844 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
845 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
846 EXPECT_LENA
; EXPECT_EQA
;
848 format
.NegativeOrder
= 13;
849 STRINGSA("-1","1.0- $");
850 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
851 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
852 EXPECT_LENA
; EXPECT_EQA
;
854 format
.NegativeOrder
= 14;
855 STRINGSA("-1","($ 1.0)");
856 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
857 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
858 EXPECT_LENA
; EXPECT_EQA
;
860 format
.NegativeOrder
= 15;
861 STRINGSA("-1","(1.0 $)");
862 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
863 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
864 EXPECT_LENA
; EXPECT_EQA
;
867 #define NEG_PARENS 0 /* "(1.1)" */
868 #define NEG_LEFT 1 /* "-1.1" */
869 #define NEG_LEFT_SPACE 2 /* "- 1.1" */
870 #define NEG_RIGHT 3 /* "1.1-" */
871 #define NEG_RIGHT_SPACE 4 /* "1.1 -" */
873 static void test_GetNumberFormatA(void)
875 static char szDot
[] = { '.', '\0' };
876 static char szComma
[] = { ',', '\0' };
878 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
879 char buffer
[BUFFER_SIZE
], Expected
[BUFFER_SIZE
], input
[BUFFER_SIZE
];
882 memset(&format
, 0, sizeof(format
));
884 STRINGSA("23",""); /* NULL output, length > 0 --> Error */
885 SetLastError(0xdeadbeef);
886 ret
= GetNumberFormatA(lcid
, 0, input
, NULL
, NULL
, COUNTOF(buffer
));
887 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
888 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
890 STRINGSA("23,53",""); /* Invalid character --> Error */
891 SetLastError(0xdeadbeef);
892 ret
= GetNumberFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
893 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
894 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
896 STRINGSA("--",""); /* Double '-' --> Error */
897 SetLastError(0xdeadbeef);
898 ret
= GetNumberFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
899 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
900 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
902 STRINGSA("0-",""); /* Trailing '-' --> Error */
903 SetLastError(0xdeadbeef);
904 ret
= GetNumberFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
905 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
906 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
908 STRINGSA("0..",""); /* Double '.' --> Error */
909 SetLastError(0xdeadbeef);
910 ret
= GetNumberFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
911 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
912 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
914 STRINGSA(" 0.1",""); /* Leading space --> Error */
915 SetLastError(0xdeadbeef);
916 ret
= GetNumberFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
917 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
918 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
920 STRINGSA("1234","1"); /* Length too small --> Write up to length chars */
921 SetLastError(0xdeadbeef);
922 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, 2);
923 ok( !ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
924 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
926 STRINGSA("2353",""); /* Format and flags given --> Error */
927 SetLastError(0xdeadbeef);
928 ret
= GetNumberFormatA(lcid
, NUO
, input
, &format
, buffer
, COUNTOF(buffer
));
929 ok( !ret
, "Expected ret == 0, got %d\n", ret
);
930 ok( GetLastError() == ERROR_INVALID_FLAGS
|| GetLastError() == ERROR_INVALID_PARAMETER
,
931 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
933 STRINGSA("2353",""); /* Invalid format --> Error */
934 SetLastError(0xdeadbeef);
935 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
936 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
937 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
939 STRINGSA("2353","2,353.00"); /* Valid number */
940 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
941 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
942 EXPECT_LENA
; EXPECT_EQA
;
944 STRINGSA("-2353","-2,353.00"); /* Valid negative number */
945 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
946 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
947 EXPECT_LENA
; EXPECT_EQA
;
949 STRINGSA("-353","-353.00"); /* test for off by one error in grouping */
950 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
951 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
952 EXPECT_LENA
; EXPECT_EQA
;
954 STRINGSA("2353.1","2,353.10"); /* Valid real number */
955 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
956 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
957 EXPECT_LENA
; EXPECT_EQA
;
959 STRINGSA("2353.111","2,353.11"); /* Too many DP --> Truncated */
960 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
961 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
962 EXPECT_LENA
; EXPECT_EQA
;
964 STRINGSA("2353.119","2,353.12"); /* Too many DP --> Rounded */
965 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
966 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
967 EXPECT_LENA
; EXPECT_EQA
;
969 format
.NumDigits
= 0; /* No decimal separator */
970 format
.LeadingZero
= 0;
971 format
.Grouping
= 0; /* No grouping char */
972 format
.NegativeOrder
= 0;
973 format
.lpDecimalSep
= szDot
;
974 format
.lpThousandSep
= szComma
;
976 STRINGSA("2353","2353"); /* No decimal or grouping chars expected */
977 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
978 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
979 EXPECT_LENA
; EXPECT_EQA
;
981 format
.NumDigits
= 1; /* 1 DP --> Expect decimal separator */
982 STRINGSA("2353","2353.0");
983 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
984 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
985 EXPECT_LENA
; EXPECT_EQA
;
987 format
.Grouping
= 2; /* Group by 100's */
988 STRINGSA("2353","23,53.0");
989 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
990 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
991 EXPECT_LENA
; EXPECT_EQA
;
993 format
.LeadingZero
= 1; /* Always provide leading zero */
994 STRINGSA(".5","0.5");
995 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
996 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
997 EXPECT_LENA
; EXPECT_EQA
;
999 format
.NegativeOrder
= NEG_PARENS
;
1000 STRINGSA("-1","(1.0)");
1001 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1002 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1003 EXPECT_LENA
; EXPECT_EQA
;
1005 format
.NegativeOrder
= NEG_LEFT
;
1006 STRINGSA("-1","-1.0");
1007 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1008 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1009 EXPECT_LENA
; EXPECT_EQA
;
1011 format
.NegativeOrder
= NEG_LEFT_SPACE
;
1012 STRINGSA("-1","- 1.0");
1013 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1014 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1015 EXPECT_LENA
; EXPECT_EQA
;
1017 format
.NegativeOrder
= NEG_RIGHT
;
1018 STRINGSA("-1","1.0-");
1019 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1020 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1021 EXPECT_LENA
; EXPECT_EQA
;
1023 format
.NegativeOrder
= NEG_RIGHT_SPACE
;
1024 STRINGSA("-1","1.0 -");
1025 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1026 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1027 EXPECT_LENA
; EXPECT_EQA
;
1029 lcid
= MAKELCID(MAKELANGID(LANG_FRENCH
, SUBLANG_DEFAULT
), SORT_DEFAULT
);
1031 if (IsValidLocale(lcid
, 0))
1033 STRINGSA("-12345","-12 345,00"); /* Try French formatting */
1034 Expected
[3] = 160; /* Non breaking space */
1035 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
1036 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1037 EXPECT_LENA
; EXPECT_EQA
;
1042 static void test_CompareStringA(void)
1045 LCID lcid
= MAKELCID(MAKELANGID(LANG_FRENCH
, SUBLANG_DEFAULT
), SORT_DEFAULT
);
1047 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "Salut", -1, "Salute", -1);
1048 ok (ret
== 1, "(Salut/Salute) Expected 1, got %d\n", ret
);
1050 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "Salut", -1, "SaLuT", -1);
1051 ok (ret
== 2, "(Salut/SaLuT) Expected 2, got %d\n", ret
);
1053 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "Salut", -1, "hola", -1);
1054 ok (ret
== 3, "(Salut/hola) Expected 3, got %d\n", ret
);
1056 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "haha", -1, "hoho", -1);
1057 ok (ret
== 1, "(haha/hoho) Expected 1, got %d\n", ret
);
1059 lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
1061 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "haha", -1, "hoho", -1);
1062 ok (ret
== 1, "(haha/hoho) Expected 1, got %d\n", ret
);
1064 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "haha", -1, "hoho", 0);
1065 ok (ret
== 3, "(haha/hoho) Expected 3, got %d\n", ret
);
1067 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "Salut", 5, "saLuT", -1);
1068 ok (ret
== 2, "(Salut/saLuT) Expected 2, got %d\n", ret
);
1070 /* test for CompareStringA flags */
1071 SetLastError(0xdeadbeef);
1072 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0x8, "NULL", -1, "NULL", -1);
1073 ok(GetLastError() == ERROR_INVALID_FLAGS
,
1074 "unexpected error code %d\n", GetLastError());
1075 ok(!ret
, "CompareStringA must fail with invalid flag\n");
1077 SetLastError(0xdeadbeef);
1078 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, LOCALE_USE_CP_ACP
, "NULL", -1, "NULL", -1);
1079 ok(GetLastError() == 0xdeadbeef, "unexpected error code %d\n", GetLastError());
1080 ok(ret
== CSTR_EQUAL
, "CompareStringA error: %d != CSTR_EQUAL\n", ret
);
1081 /* end of test for CompareStringA flags */
1083 ret
= lstrcmpA("", "");
1084 ok (ret
== 0, "lstrcmpA(\"\", \"\") should return 0, got %d\n", ret
);
1086 ret
= lstrcmpA(NULL
, NULL
);
1087 ok (ret
== 0 || broken(ret
== -2) /* win9x */, "lstrcmpA(NULL, NULL) should return 0, got %d\n", ret
);
1089 ret
= lstrcmpA("", NULL
);
1090 ok (ret
== 1 || broken(ret
== -2) /* win9x */, "lstrcmpA(\"\", NULL) should return 1, got %d\n", ret
);
1092 ret
= lstrcmpA(NULL
, "");
1093 ok (ret
== -1 || broken(ret
== -2) /* win9x */, "lstrcmpA(NULL, \"\") should return -1, got %d\n", ret
);
1095 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
,0,"EndDialog",-1,"_Property",-1);
1096 ok( ret
== 3, "EndDialog vs _Property ... expected 3, got %d\n", ret
);
1098 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
,0,"osp_vba.sreg0070",-1,"_IEWWBrowserComp",-1);
1099 ok( ret
== 3, "osp_vba.sreg0070 vs _IEWWBrowserComp ... expected 3, got %d\n", ret
);
1101 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
,0,"r",-1,"\\",-1);
1102 ok( ret
== 3, "r vs \\ ... expected 3, got %d\n", ret
);
1104 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
,0,"osp_vba.sreg0031", -1, "OriginalDatabase", -1 );
1105 ok( ret
== 3, "osp_vba.sreg0031 vs OriginalDatabase ... expected 3, got %d\n", ret
);
1107 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "AAA", -1, "aaa", -1 );
1108 ok( ret
== 3, "AAA vs aaa expected 3, got %d\n", ret
);
1110 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "AAA", -1, "aab", -1 );
1111 ok( ret
== 1, "AAA vs aab expected 1, got %d\n", ret
);
1113 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "AAA", -1, "Aab", -1 );
1114 ok( ret
== 1, "AAA vs Aab expected 1, got %d\n", ret
);
1116 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, ".AAA", -1, "Aab", -1 );
1117 ok( ret
== 1, ".AAA vs Aab expected 1, got %d\n", ret
);
1119 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, ".AAA", -1, "A.ab", -1 );
1120 ok( ret
== 1, ".AAA vs A.ab expected 1, got %d\n", ret
);
1122 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "aa", -1, "AB", -1 );
1123 ok( ret
== 1, "aa vs AB expected 1, got %d\n", ret
);
1125 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "aa", -1, "Aab", -1 );
1126 ok( ret
== 1, "aa vs Aab expected 1, got %d\n", ret
);
1128 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "aB", -1, "Aab", -1 );
1129 ok( ret
== 3, "aB vs Aab expected 3, got %d\n", ret
);
1131 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "Ba", -1, "bab", -1 );
1132 ok( ret
== 1, "Ba vs bab expected 1, got %d\n", ret
);
1134 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "{100}{83}{71}{71}{71}", -1, "Global_DataAccess_JRO", -1 );
1135 ok( ret
== 1, "{100}{83}{71}{71}{71} vs Global_DataAccess_JRO expected 1, got %d\n", ret
);
1137 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "a", -1, "{", -1 );
1138 ok( ret
== 3, "a vs { expected 3, got %d\n", ret
);
1140 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "A", -1, "{", -1 );
1141 ok( ret
== 3, "A vs { expected 3, got %d\n", ret
);
1143 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "3.5", 0, "4.0", -1 );
1144 ok(ret
== 1, "3.5/0 vs 4.0/-1 expected 1, got %d\n", ret
);
1146 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "3.5", -1, "4.0", -1 );
1147 ok(ret
== 1, "3.5 vs 4.0 expected 1, got %d\n", ret
);
1149 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "3.520.4403.2", -1, "4.0.2927.10", -1 );
1150 ok(ret
== 1, "3.520.4403.2 vs 4.0.2927.10 expected 1, got %d\n", ret
);
1152 /* hyphen and apostrophe are treated differently depending on
1153 * whether SORT_STRINGSORT specified or not
1155 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "-o", -1, "/m", -1 );
1156 ok(ret
== 3, "-o vs /m expected 3, got %d\n", ret
);
1158 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "/m", -1, "-o", -1 );
1159 ok(ret
== 1, "/m vs -o expected 1, got %d\n", ret
);
1161 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "-o", -1, "/m", -1 );
1162 ok(ret
== 1, "-o vs /m expected 1, got %d\n", ret
);
1164 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "/m", -1, "-o", -1 );
1165 ok(ret
== 3, "/m vs -o expected 3, got %d\n", ret
);
1167 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "'o", -1, "/m", -1 );
1168 ok(ret
== 3, "'o vs /m expected 3, got %d\n", ret
);
1170 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "/m", -1, "'o", -1 );
1171 ok(ret
== 1, "/m vs 'o expected 1, got %d\n", ret
);
1173 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "'o", -1, "/m", -1 );
1174 ok(ret
== 1, "'o vs /m expected 1, got %d\n", ret
);
1176 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "/m", -1, "'o", -1 );
1177 ok(ret
== 3, "/m vs 'o expected 3, got %d\n", ret
);
1179 if (0) { /* this requires collation table patch to make it MS compatible */
1180 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "'o", -1, "-o", -1 );
1181 ok(ret
== 1, "'o vs -o expected 1, got %d\n", ret
);
1183 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "'o", -1, "-o", -1 );
1184 ok(ret
== 1, "'o vs -o expected 1, got %d\n", ret
);
1186 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "'", -1, "-", -1 );
1187 ok(ret
== 1, "' vs - expected 1, got %d\n", ret
);
1189 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "'", -1, "-", -1 );
1190 ok(ret
== 1, "' vs - expected 1, got %d\n", ret
);
1192 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "`o", -1, "/m", -1 );
1193 ok(ret
== 3, "`o vs /m expected 3, got %d\n", ret
);
1195 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "/m", -1, "`o", -1 );
1196 ok(ret
== 1, "/m vs `o expected 1, got %d\n", ret
);
1198 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "`o", -1, "/m", -1 );
1199 ok(ret
== 3, "`o vs /m expected 3, got %d\n", ret
);
1201 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "/m", -1, "`o", -1 );
1202 ok(ret
== 1, "/m vs `o expected 1, got %d\n", ret
);
1204 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "`o", -1, "-m", -1 );
1205 ok(ret
== 1, "`o vs -m expected 1, got %d\n", ret
);
1207 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "-m", -1, "`o", -1 );
1208 ok(ret
== 3, "-m vs `o expected 3, got %d\n", ret
);
1210 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "`o", -1, "-m", -1 );
1211 ok(ret
== 3, "`o vs -m expected 3, got %d\n", ret
);
1213 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "-m", -1, "`o", -1 );
1214 ok(ret
== 1, "-m vs `o expected 1, got %d\n", ret
);
1217 ret
= CompareStringA(LOCALE_USER_DEFAULT
, 0, "aLuZkUtZ", 8, "aLuZkUtZ", 9);
1218 ok(ret
== 2, "aLuZkUtZ vs aLuZkUtZ\\0 expected 2, got %d\n", ret
);
1220 ret
= CompareStringA(LOCALE_USER_DEFAULT
, 0, "aLuZkUtZ", 7, "aLuZkUtZ\0A", 10);
1221 ok(ret
== 1, "aLuZkUtZ vs aLuZkUtZ\\0A expected 1, got %d\n", ret
);
1223 /* WinXP handles embedded NULLs differently than earlier versions */
1224 ret
= CompareStringA(LOCALE_USER_DEFAULT
, 0, "aLuZkUtZ", 8, "aLuZkUtZ\0A", 10);
1225 ok(ret
== 1 || ret
== 2, "aLuZkUtZ vs aLuZkUtZ\\0A expected 1 or 2, got %d\n", ret
);
1227 ret
= CompareStringA(LOCALE_USER_DEFAULT
, 0, "aLu\0ZkUtZ", 8, "aLu\0ZkUtZ\0A", 10);
1228 ok(ret
== 1 || ret
== 2, "aLu\\0ZkUtZ vs aLu\\0ZkUtZ\\0A expected 1 or 2, got %d\n", ret
);
1230 ret
= CompareStringA(lcid
, 0, "a\0b", -1, "a", -1);
1231 ok(ret
== 2, "a vs a expected 2, got %d\n", ret
);
1233 ret
= CompareStringA(lcid
, 0, "a\0b", 4, "a", 2);
1234 ok(ret
== CSTR_EQUAL
|| /* win2k */
1235 ret
== CSTR_GREATER_THAN
,
1236 "a\\0b vs a expected CSTR_EQUAL or CSTR_GREATER_THAN, got %d\n", ret
);
1238 ret
= CompareStringA(lcid
, 0, "\2", 2, "\1", 2);
1239 todo_wine
ok(ret
!= 2, "\\2 vs \\1 expected unequal\n");
1241 ret
= CompareStringA(lcid
, NORM_IGNORECASE
| LOCALE_USE_CP_ACP
, "#", -1, ".", -1);
1242 todo_wine
ok(ret
== CSTR_LESS_THAN
, "\"#\" vs \".\" expected CSTR_LESS_THAN, got %d\n", ret
);
1244 ret
= lstrcmpi("#", ".");
1245 todo_wine
ok(ret
== -1, "\"#\" vs \".\" expected -1, got %d\n", ret
);
1248 static void test_LCMapStringA(void)
1251 char buf
[256], buf2
[256];
1252 static const char upper_case
[] = "\tJUST! A, TEST; STRING 1/*+-.\r\n";
1253 static const char lower_case
[] = "\tjust! a, test; string 1/*+-.\r\n";
1254 static const char symbols_stripped
[] = "justateststring1";
1256 SetLastError(0xdeadbeef);
1257 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LOCALE_USE_CP_ACP
| LCMAP_LOWERCASE
,
1258 lower_case
, -1, buf
, sizeof(buf
));
1259 ok(ret
== lstrlenA(lower_case
) + 1,
1260 "ret %d, error %d, expected value %d\n",
1261 ret
, GetLastError(), lstrlenA(lower_case
) + 1);
1262 ok(!memcmp(buf
, lower_case
, ret
), "LCMapStringA should return %s, but not %s\n", lower_case
, buf
);
1264 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
| LCMAP_UPPERCASE
,
1265 upper_case
, -1, buf
, sizeof(buf
));
1266 ok(!ret
, "LCMAP_LOWERCASE and LCMAP_UPPERCASE are mutually exclusive\n");
1267 ok(GetLastError() == ERROR_INVALID_FLAGS
,
1268 "unexpected error code %d\n", GetLastError());
1270 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_HIRAGANA
| LCMAP_KATAKANA
,
1271 upper_case
, -1, buf
, sizeof(buf
));
1272 ok(!ret
, "LCMAP_HIRAGANA and LCMAP_KATAKANA are mutually exclusive\n");
1273 ok(GetLastError() == ERROR_INVALID_FLAGS
,
1274 "unexpected error code %d\n", GetLastError());
1276 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_HALFWIDTH
| LCMAP_FULLWIDTH
,
1277 upper_case
, -1, buf
, sizeof(buf
));
1278 ok(!ret
, "LCMAP_HALFWIDTH | LCMAP_FULLWIDTH are mutually exclusive\n");
1279 ok(GetLastError() == ERROR_INVALID_FLAGS
,
1280 "unexpected error code %d\n", GetLastError());
1282 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_TRADITIONAL_CHINESE
| LCMAP_SIMPLIFIED_CHINESE
,
1283 upper_case
, -1, buf
, sizeof(buf
));
1284 ok(!ret
, "LCMAP_TRADITIONAL_CHINESE and LCMAP_SIMPLIFIED_CHINESE are mutually exclusive\n");
1285 ok(GetLastError() == ERROR_INVALID_FLAGS
,
1286 "unexpected error code %d\n", GetLastError());
1288 /* SORT_STRINGSORT must be used exclusively with LCMAP_SORTKEY */
1289 SetLastError(0xdeadbeef);
1290 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
| SORT_STRINGSORT
,
1291 upper_case
, -1, buf
, sizeof(buf
));
1292 ok(GetLastError() == ERROR_INVALID_FLAGS
, "expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
1293 ok(!ret
, "SORT_STRINGSORT without LCMAP_SORTKEY must fail\n");
1295 /* test LCMAP_LOWERCASE */
1296 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
,
1297 upper_case
, -1, buf
, sizeof(buf
));
1298 ok(ret
== lstrlenA(upper_case
) + 1,
1299 "ret %d, error %d, expected value %d\n",
1300 ret
, GetLastError(), lstrlenA(upper_case
) + 1);
1301 ok(!lstrcmpA(buf
, lower_case
), "LCMapStringA should return %s, but not %s\n", lower_case
, buf
);
1303 /* test LCMAP_UPPERCASE */
1304 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_UPPERCASE
,
1305 lower_case
, -1, buf
, sizeof(buf
));
1306 ok(ret
== lstrlenA(lower_case
) + 1,
1307 "ret %d, error %d, expected value %d\n",
1308 ret
, GetLastError(), lstrlenA(lower_case
) + 1);
1309 ok(!lstrcmpA(buf
, upper_case
), "LCMapStringA should return %s, but not %s\n", upper_case
, buf
);
1311 /* test buffer overflow */
1312 SetLastError(0xdeadbeef);
1313 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_UPPERCASE
,
1314 lower_case
, -1, buf
, 4);
1315 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1316 "should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d\n", ret
);
1318 /* LCMAP_UPPERCASE or LCMAP_LOWERCASE should accept src == dst */
1319 lstrcpyA(buf
, lower_case
);
1320 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_UPPERCASE
,
1321 buf
, -1, buf
, sizeof(buf
));
1322 if (!ret
) /* Win9x */
1323 trace("Ignoring LCMapStringA(LCMAP_UPPERCASE, buf, buf) error on Win9x\n");
1326 ok(ret
== lstrlenA(lower_case
) + 1,
1327 "ret %d, error %d, expected value %d\n",
1328 ret
, GetLastError(), lstrlenA(lower_case
) + 1);
1329 ok(!lstrcmpA(buf
, upper_case
), "LCMapStringA should return %s, but not %s\n", upper_case
, buf
);
1331 lstrcpyA(buf
, upper_case
);
1332 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
,
1333 buf
, -1, buf
, sizeof(buf
));
1334 if (!ret
) /* Win9x */
1335 trace("Ignoring LCMapStringA(LCMAP_LOWERCASE, buf, buf) error on Win9x\n");
1338 ok(ret
== lstrlenA(upper_case
) + 1,
1339 "ret %d, error %d, expected value %d\n",
1340 ret
, GetLastError(), lstrlenA(lower_case
) + 1);
1341 ok(!lstrcmpA(buf
, lower_case
), "LCMapStringA should return %s, but not %s\n", lower_case
, buf
);
1344 /* otherwise src == dst should fail */
1345 SetLastError(0xdeadbeef);
1346 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
| LCMAP_UPPERCASE
,
1347 buf
, 10, buf
, sizeof(buf
));
1348 ok(GetLastError() == ERROR_INVALID_FLAGS
/* NT */ ||
1349 GetLastError() == ERROR_INVALID_PARAMETER
/* Win9x */,
1350 "unexpected error code %d\n", GetLastError());
1351 ok(!ret
, "src == dst without LCMAP_UPPERCASE or LCMAP_LOWERCASE must fail\n");
1353 /* test whether '\0' is always appended */
1354 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
,
1355 upper_case
, -1, buf
, sizeof(buf
));
1356 ok(ret
, "LCMapStringA must succeed\n");
1357 ok(buf
[ret
-1] == 0, "LCMapStringA not null-terminated\n");
1358 ret2
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
,
1359 upper_case
, lstrlenA(upper_case
), buf2
, sizeof(buf2
));
1360 ok(ret2
, "LCMapStringA must succeed\n");
1361 ok(buf2
[ret2
-1] == 0, "LCMapStringA not null-terminated\n" );
1362 ok(ret
== ret2
, "lengths of sort keys must be equal\n");
1363 ok(!lstrcmpA(buf
, buf2
), "sort keys must be equal\n");
1365 /* test LCMAP_SORTKEY | NORM_IGNORECASE */
1366 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
| NORM_IGNORECASE
,
1367 upper_case
, -1, buf
, sizeof(buf
));
1368 ok(ret
, "LCMapStringA must succeed\n");
1369 ret2
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
,
1370 lower_case
, -1, buf2
, sizeof(buf2
));
1371 ok(ret2
, "LCMapStringA must succeed\n");
1372 ok(ret
== ret2
, "lengths of sort keys must be equal\n");
1373 ok(!lstrcmpA(buf
, buf2
), "sort keys must be equal\n");
1375 /* Don't test LCMAP_SORTKEY | NORM_IGNORENONSPACE, produces different
1376 results from plain LCMAP_SORTKEY on Vista */
1378 /* test LCMAP_SORTKEY | NORM_IGNORESYMBOLS */
1379 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
| NORM_IGNORESYMBOLS
,
1380 lower_case
, -1, buf
, sizeof(buf
));
1381 ok(ret
, "LCMapStringA must succeed\n");
1382 ret2
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
,
1383 symbols_stripped
, -1, buf2
, sizeof(buf2
));
1384 ok(ret2
, "LCMapStringA must succeed\n");
1385 ok(ret
== ret2
, "lengths of sort keys must be equal\n");
1386 ok(!lstrcmpA(buf
, buf2
), "sort keys must be equal\n");
1388 /* test NORM_IGNORENONSPACE */
1389 lstrcpyA(buf
, "foo");
1390 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, NORM_IGNORENONSPACE
,
1391 lower_case
, -1, buf
, sizeof(buf
));
1392 ok(ret
== lstrlenA(lower_case
) + 1, "LCMapStringA should return %d, ret = %d\n",
1393 lstrlenA(lower_case
) + 1, ret
);
1394 ok(!lstrcmpA(buf
, lower_case
), "LCMapStringA should return %s, but not %s\n", lower_case
, buf
);
1396 /* test NORM_IGNORESYMBOLS */
1397 lstrcpyA(buf
, "foo");
1398 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, NORM_IGNORESYMBOLS
,
1399 lower_case
, -1, buf
, sizeof(buf
));
1400 ok(ret
== lstrlenA(symbols_stripped
) + 1, "LCMapStringA should return %d, ret = %d\n",
1401 lstrlenA(symbols_stripped
) + 1, ret
);
1402 ok(!lstrcmpA(buf
, symbols_stripped
), "LCMapStringA should return %s, but not %s\n", lower_case
, buf
);
1404 /* test srclen = 0 */
1405 SetLastError(0xdeadbeef);
1406 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, 0, upper_case
, 0, buf
, sizeof(buf
));
1407 ok(!ret
, "LCMapStringA should fail with srclen = 0\n");
1408 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1409 "unexpected error code %d\n", GetLastError());
1412 static void test_LCMapStringW(void)
1415 WCHAR buf
[256], buf2
[256];
1416 char *p_buf
= (char *)buf
, *p_buf2
= (char *)buf2
;
1417 static const WCHAR upper_case
[] = {'\t','J','U','S','T','!',' ','A',',',' ','T','E','S','T',';',' ','S','T','R','I','N','G',' ','1','/','*','+','-','.','\r','\n',0};
1418 static const WCHAR lower_case
[] = {'\t','j','u','s','t','!',' ','a',',',' ','t','e','s','t',';',' ','s','t','r','i','n','g',' ','1','/','*','+','-','.','\r','\n',0};
1419 static const WCHAR symbols_stripped
[] = {'j','u','s','t','a','t','e','s','t','s','t','r','i','n','g','1',0};
1420 static const WCHAR fooW
[] = {'f','o','o',0};
1422 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
| LCMAP_UPPERCASE
,
1423 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
1424 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
1426 win_skip("LCMapStringW is not implemented\n");
1430 ok(lstrcmpW(buf
, upper_case
) == 0, "Expected upper case string\n");
1433 ok(!ret
, "LCMAP_LOWERCASE and LCMAP_UPPERCASE are mutually exclusive\n");
1434 ok(GetLastError() == ERROR_INVALID_FLAGS
,
1435 "unexpected error code %d\n", GetLastError());
1438 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_HIRAGANA
| LCMAP_KATAKANA
,
1439 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
1440 ok(!ret
, "LCMAP_HIRAGANA and LCMAP_KATAKANA are mutually exclusive\n");
1441 ok(GetLastError() == ERROR_INVALID_FLAGS
,
1442 "unexpected error code %d\n", GetLastError());
1444 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_HALFWIDTH
| LCMAP_FULLWIDTH
,
1445 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
1446 ok(!ret
, "LCMAP_HALFWIDTH | LCMAP_FULLWIDTH are mutually exclusive\n");
1447 ok(GetLastError() == ERROR_INVALID_FLAGS
,
1448 "unexpected error code %d\n", GetLastError());
1450 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_TRADITIONAL_CHINESE
| LCMAP_SIMPLIFIED_CHINESE
,
1451 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
1452 ok(!ret
, "LCMAP_TRADITIONAL_CHINESE and LCMAP_SIMPLIFIED_CHINESE are mutually exclusive\n");
1453 ok(GetLastError() == ERROR_INVALID_FLAGS
,
1454 "unexpected error code %d\n", GetLastError());
1456 /* SORT_STRINGSORT must be used exclusively with LCMAP_SORTKEY */
1457 SetLastError(0xdeadbeef);
1458 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
| SORT_STRINGSORT
,
1459 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
1460 ok(GetLastError() == ERROR_INVALID_FLAGS
, "expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
1461 ok(!ret
, "SORT_STRINGSORT without LCMAP_SORTKEY must fail\n");
1463 /* test LCMAP_LOWERCASE */
1464 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
,
1465 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
1466 ok(ret
== lstrlenW(upper_case
) + 1,
1467 "ret %d, error %d, expected value %d\n",
1468 ret
, GetLastError(), lstrlenW(upper_case
) + 1);
1469 ok(!lstrcmpW(buf
, lower_case
), "string compare mismatch\n");
1471 /* test LCMAP_UPPERCASE */
1472 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_UPPERCASE
,
1473 lower_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
1474 ok(ret
== lstrlenW(lower_case
) + 1,
1475 "ret %d, error %d, expected value %d\n",
1476 ret
, GetLastError(), lstrlenW(lower_case
) + 1);
1477 ok(!lstrcmpW(buf
, upper_case
), "string compare mismatch\n");
1479 /* test buffer overflow */
1480 SetLastError(0xdeadbeef);
1481 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_UPPERCASE
,
1482 lower_case
, -1, buf
, 4);
1483 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1484 "should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d\n", ret
);
1486 /* LCMAP_UPPERCASE or LCMAP_LOWERCASE should accept src == dst */
1487 lstrcpyW(buf
, lower_case
);
1488 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_UPPERCASE
,
1489 buf
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
1490 ok(ret
== lstrlenW(lower_case
) + 1,
1491 "ret %d, error %d, expected value %d\n",
1492 ret
, GetLastError(), lstrlenW(lower_case
) + 1);
1493 ok(!lstrcmpW(buf
, upper_case
), "string compare mismatch\n");
1495 lstrcpyW(buf
, upper_case
);
1496 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
,
1497 buf
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
1498 ok(ret
== lstrlenW(upper_case
) + 1,
1499 "ret %d, error %d, expected value %d\n",
1500 ret
, GetLastError(), lstrlenW(lower_case
) + 1);
1501 ok(!lstrcmpW(buf
, lower_case
), "string compare mismatch\n");
1503 /* otherwise src == dst should fail */
1504 SetLastError(0xdeadbeef);
1505 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
| LCMAP_UPPERCASE
,
1506 buf
, 10, buf
, sizeof(buf
));
1507 ok(GetLastError() == ERROR_INVALID_FLAGS
/* NT */ ||
1508 GetLastError() == ERROR_INVALID_PARAMETER
/* Win9x */,
1509 "unexpected error code %d\n", GetLastError());
1510 ok(!ret
, "src == dst without LCMAP_UPPERCASE or LCMAP_LOWERCASE must fail\n");
1512 /* test whether '\0' is always appended */
1513 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
,
1514 upper_case
, -1, buf
, sizeof(buf
));
1515 ok(ret
, "LCMapStringW must succeed\n");
1516 ret2
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
,
1517 upper_case
, lstrlenW(upper_case
), buf2
, sizeof(buf2
));
1518 ok(ret
, "LCMapStringW must succeed\n");
1519 ok(ret
== ret2
, "lengths of sort keys must be equal\n");
1520 ok(!lstrcmpA(p_buf
, p_buf2
), "sort keys must be equal\n");
1522 /* test LCMAP_SORTKEY | NORM_IGNORECASE */
1523 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
| NORM_IGNORECASE
,
1524 upper_case
, -1, buf
, sizeof(buf
));
1525 ok(ret
, "LCMapStringW must succeed\n");
1526 ret2
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
,
1527 lower_case
, -1, buf2
, sizeof(buf2
));
1528 ok(ret2
, "LCMapStringW must succeed\n");
1529 ok(ret
== ret2
, "lengths of sort keys must be equal\n");
1530 ok(!lstrcmpA(p_buf
, p_buf2
), "sort keys must be equal\n");
1532 /* Don't test LCMAP_SORTKEY | NORM_IGNORENONSPACE, produces different
1533 results from plain LCMAP_SORTKEY on Vista */
1535 /* test LCMAP_SORTKEY | NORM_IGNORESYMBOLS */
1536 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
| NORM_IGNORESYMBOLS
,
1537 lower_case
, -1, buf
, sizeof(buf
));
1538 ok(ret
, "LCMapStringW must succeed\n");
1539 ret2
= LCMapStringW(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
,
1540 symbols_stripped
, -1, buf2
, sizeof(buf2
));
1541 ok(ret2
, "LCMapStringW must succeed\n");
1542 ok(ret
== ret2
, "lengths of sort keys must be equal\n");
1543 ok(!lstrcmpA(p_buf
, p_buf2
), "sort keys must be equal\n");
1545 /* test NORM_IGNORENONSPACE */
1546 lstrcpyW(buf
, fooW
);
1547 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, NORM_IGNORENONSPACE
,
1548 lower_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
1549 ok(ret
== lstrlenW(lower_case
) + 1, "LCMapStringW should return %d, ret = %d\n",
1550 lstrlenW(lower_case
) + 1, ret
);
1551 ok(!lstrcmpW(buf
, lower_case
), "string comparison mismatch\n");
1553 /* test NORM_IGNORESYMBOLS */
1554 lstrcpyW(buf
, fooW
);
1555 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, NORM_IGNORESYMBOLS
,
1556 lower_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
1557 ok(ret
== lstrlenW(symbols_stripped
) + 1, "LCMapStringW should return %d, ret = %d\n",
1558 lstrlenW(symbols_stripped
) + 1, ret
);
1559 ok(!lstrcmpW(buf
, symbols_stripped
), "string comparison mismatch\n");
1561 /* test srclen = 0 */
1562 SetLastError(0xdeadbeef);
1563 ret
= LCMapStringW(LOCALE_USER_DEFAULT
, 0, upper_case
, 0, buf
, sizeof(buf
)/sizeof(WCHAR
));
1564 ok(!ret
, "LCMapStringW should fail with srclen = 0\n");
1565 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1566 "unexpected error code %d\n", GetLastError());
1569 /* this requires collation table patch to make it MS compatible */
1570 static const char * const strings_sorted
[] =
1602 static const char * const strings
[] =
1634 static int compare_string1(const void *e1
, const void *e2
)
1636 const char *s1
= *(const char *const *)e1
;
1637 const char *s2
= *(const char *const *)e2
;
1639 return lstrcmpA(s1
, s2
);
1642 static int compare_string2(const void *e1
, const void *e2
)
1644 const char *s1
= *(const char *const *)e1
;
1645 const char *s2
= *(const char *const *)e2
;
1647 return CompareStringA(0, 0, s1
, -1, s2
, -1) - 2;
1650 static int compare_string3(const void *e1
, const void *e2
)
1652 const char *s1
= *(const char *const *)e1
;
1653 const char *s2
= *(const char *const *)e2
;
1654 char key1
[256], key2
[256];
1656 LCMapStringA(0, LCMAP_SORTKEY
, s1
, -1, key1
, sizeof(key1
));
1657 LCMapStringA(0, LCMAP_SORTKEY
, s2
, -1, key2
, sizeof(key2
));
1658 return strcmp(key1
, key2
);
1661 static void test_sorting(void)
1664 char **str_buf
= (char **)buf
;
1667 assert(sizeof(buf
) >= sizeof(strings
));
1669 /* 1. sort using lstrcmpA */
1670 memcpy(buf
, strings
, sizeof(strings
));
1671 qsort(buf
, sizeof(strings
)/sizeof(strings
[0]), sizeof(strings
[0]), compare_string1
);
1672 for (i
= 0; i
< sizeof(strings
)/sizeof(strings
[0]); i
++)
1674 ok(!strcmp(strings_sorted
[i
], str_buf
[i
]),
1675 "qsort using lstrcmpA failed for element %d\n", i
);
1677 /* 2. sort using CompareStringA */
1678 memcpy(buf
, strings
, sizeof(strings
));
1679 qsort(buf
, sizeof(strings
)/sizeof(strings
[0]), sizeof(strings
[0]), compare_string2
);
1680 for (i
= 0; i
< sizeof(strings
)/sizeof(strings
[0]); i
++)
1682 ok(!strcmp(strings_sorted
[i
], str_buf
[i
]),
1683 "qsort using CompareStringA failed for element %d\n", i
);
1685 /* 3. sort using sort keys */
1686 memcpy(buf
, strings
, sizeof(strings
));
1687 qsort(buf
, sizeof(strings
)/sizeof(strings
[0]), sizeof(strings
[0]), compare_string3
);
1688 for (i
= 0; i
< sizeof(strings
)/sizeof(strings
[0]); i
++)
1690 ok(!strcmp(strings_sorted
[i
], str_buf
[i
]),
1691 "qsort using sort keys failed for element %d\n", i
);
1695 static void test_FoldStringA(void)
1699 char src
[256], dst
[256];
1700 static const char digits_src
[] = { 0xB9,0xB2,0xB3,'\0' };
1701 static const char digits_dst
[] = { '1','2','3','\0' };
1702 static const char composite_src
[] =
1704 0x8a,0x8e,0x9a,0x9e,0x9f,0xc0,0xc1,0xc2,
1705 0xc3,0xc4,0xc5,0xc7,0xc8,0xc9,0xca,0xcb,
1706 0xcc,0xcd,0xce,0xcf,0xd1,0xd2,0xd3,0xd4,
1707 0xd5,0xd6,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,
1708 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe7,0xe8,
1709 0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf1,
1710 0xf2,0xf3,0xf4,0xf5,0xf6,0xf8,0xf9,0xfa,
1711 0xfb,0xfc,0xfd,0xff,'\0'
1713 static const char composite_dst
[] =
1715 0x53,0x3f,0x5a,0x3f,0x73,0x3f,0x7a,0x3f,
1716 0x59,0xa8,0x41,0x60,0x41,0xb4,0x41,0x5e,
1717 0x41,0x7e,0x41,0xa8,0x41,0xb0,0x43,0xb8,
1718 0x45,0x60,0x45,0xb4,0x45,0x5e,0x45,0xa8,
1719 0x49,0x60,0x49,0xb4,0x49,0x5e,0x49,0xa8,
1720 0x4e,0x7e,0x4f,0x60,0x4f,0xb4,0x4f,0x5e,
1721 0x4f,0x7e,0x4f,0xa8,0x4f,0x3f,0x55,0x60,
1722 0x55,0xb4,0x55,0x5e,0x55,0xa8,0x59,0xb4,
1723 0x61,0x60,0x61,0xb4,0x61,0x5e,0x61,0x7e,
1724 0x61,0xa8,0x61,0xb0,0x63,0xb8,0x65,0x60,
1725 0x65,0xb4,0x65,0x5e,0x65,0xa8,0x69,0x60,
1726 0x69,0xb4,0x69,0x5e,0x69,0xa8,0x6e,0x7e,
1727 0x6f,0x60,0x6f,0xb4,0x6f,0x5e,0x6f,0x7e,
1728 0x6f,0xa8,0x6f,0x3f,0x75,0x60,0x75,0xb4,
1729 0x75,0x5e,0x75,0xa8,0x79,0xb4,0x79,0xa8,'\0'
1731 static const char composite_dst_alt
[] =
1733 0x53,0x3f,0x5a,0x3f,0x73,0x3f,0x7a,0x3f,
1734 0x59,0xa8,0x41,0x60,0x41,0xb4,0x41,0x5e,
1735 0x41,0x7e,0x41,0xa8,0x41,0xb0,0x43,0xb8,
1736 0x45,0x60,0x45,0xb4,0x45,0x5e,0x45,0xa8,
1737 0x49,0x60,0x49,0xb4,0x49,0x5e,0x49,0xa8,
1738 0x4e,0x7e,0x4f,0x60,0x4f,0xb4,0x4f,0x5e,
1739 0x4f,0x7e,0x4f,0xa8,0xd8,0x55,0x60,0x55,
1740 0xb4,0x55,0x5e,0x55,0xa8,0x59,0xb4,0x61,
1741 0x60,0x61,0xb4,0x61,0x5e,0x61,0x7e,0x61,
1742 0xa8,0x61,0xb0,0x63,0xb8,0x65,0x60,0x65,
1743 0xb4,0x65,0x5e,0x65,0xa8,0x69,0x60,0x69,
1744 0xb4,0x69,0x5e,0x69,0xa8,0x6e,0x7e,0x6f,
1745 0x60,0x6f,0xb4,0x6f,0x5e,0x6f,0x7e,0x6f,
1746 0xa8,0xf8,0x75,0x60,0x75,0xb4,0x75,0x5e,
1747 0x75,0xa8,0x79,0xb4,0x79,0xa8,'\0'
1749 static const char ligatures_src
[] =
1751 0x8C,0x9C,0xC6,0xDE,0xDF,0xE6,0xFE,'\0'
1753 static const char ligatures_dst
[] =
1755 'O','E','o','e','A','E','T','H','s','s','a','e','t','h','\0'
1757 static const struct special
1761 } foldczone_special
[] =
1764 { 0x85, { 0x2e, 0x2e, 0x2e, 0x00 } },
1765 { 0x98, { 0x20, 0x7e, 0x00 } },
1766 { 0x99, { 0x54, 0x4d, 0x00 } },
1767 { 0xa0, { 0x20, 0x00 } },
1768 { 0xa8, { 0x20, 0xa8, 0x00 } },
1769 { 0xaa, { 0x61, 0x00 } },
1770 { 0xaf, { 0x20, 0xaf, 0x00 } },
1771 { 0xb2, { 0x32, 0x00 } },
1772 { 0xb3, { 0x33, 0x00 } },
1773 { 0xb4, { 0x20, 0xb4, 0x00 } },
1774 { 0xb8, { 0x20, 0xb8, 0x00 } },
1775 { 0xb9, { 0x31, 0x00 } },
1776 { 0xba, { 0x6f, 0x00 } },
1777 { 0xbc, { 0x31, 0x2f, 0x34, 0x00 } },
1778 { 0xbd, { 0x31, 0x2f, 0x32, 0x00 } },
1779 { 0xbe, { 0x33, 0x2f, 0x34, 0x00 } },
1784 return; /* FoldString is present in NT v3.1+, but not 95/98/Me */
1786 /* these tests are locale specific */
1787 if (GetACP() != 1252)
1789 trace("Skipping FoldStringA tests for a not Latin 1 locale\n");
1793 /* MAP_FOLDDIGITS */
1795 ret
= pFoldStringA(MAP_FOLDDIGITS
, digits_src
, -1, dst
, 256);
1796 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
1798 win_skip("FoldStringA is not implemented\n");
1801 ok(ret
== 4, "Expected ret == 4, got %d, error %d\n", ret
, GetLastError());
1802 ok(strcmp(dst
, digits_dst
) == 0,
1803 "MAP_FOLDDIGITS: Expected '%s', got '%s'\n", digits_dst
, dst
);
1804 for (i
= 1; i
< 256; i
++)
1806 if (!strchr(digits_src
, i
))
1811 ret
= pFoldStringA(MAP_FOLDDIGITS
, src
, -1, dst
, 256);
1812 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
1813 ok(dst
[0] == src
[0],
1814 "MAP_FOLDDIGITS: Expected '%s', got '%s'\n", src
, dst
);
1818 /* MAP_EXPAND_LIGATURES */
1820 ret
= pFoldStringA(MAP_EXPAND_LIGATURES
, ligatures_src
, -1, dst
, 256);
1821 /* NT 4.0 doesn't support MAP_EXPAND_LIGATURES */
1822 if (!(ret
== 0 && GetLastError() == ERROR_INVALID_FLAGS
)) {
1823 ok(ret
== sizeof(ligatures_dst
), "Got %d, error %d\n", ret
, GetLastError());
1824 ok(strcmp(dst
, ligatures_dst
) == 0,
1825 "MAP_EXPAND_LIGATURES: Expected '%s', got '%s'\n", ligatures_dst
, dst
);
1826 for (i
= 1; i
< 256; i
++)
1828 if (!strchr(ligatures_src
, i
))
1833 ret
= pFoldStringA(MAP_EXPAND_LIGATURES
, src
, -1, dst
, 256);
1837 ok((i
== 0xDC && lstrcmpA(dst
, "UE") == 0) ||
1838 (i
== 0xFC && lstrcmpA(dst
, "ue") == 0),
1839 "Got %s for %d\n", dst
, i
);
1843 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
1844 ok(dst
[0] == src
[0],
1845 "MAP_EXPAND_LIGATURES: Expected '%s', got '%s'\n", src
, dst
);
1853 ret
= pFoldStringA(MAP_COMPOSITE
, composite_src
, -1, dst
, 256);
1854 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1855 ok(ret
== 121 || ret
== 119, "Expected 121 or 119, got %d\n", ret
);
1856 ok(strcmp(dst
, composite_dst
) == 0 || strcmp(dst
, composite_dst_alt
) == 0,
1857 "MAP_COMPOSITE: Mismatch, got '%s'\n", dst
);
1859 for (i
= 1; i
< 256; i
++)
1861 if (!strchr(composite_src
, i
))
1866 ret
= pFoldStringA(MAP_COMPOSITE
, src
, -1, dst
, 256);
1867 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
1868 ok(dst
[0] == src
[0],
1869 "0x%02x, 0x%02x,0x%02x,0x%02x,\n", (unsigned char)src
[0],
1870 (unsigned char)dst
[0],(unsigned char)dst
[1],(unsigned char)dst
[2]);
1875 for (i
= 1; i
< 256; i
++)
1880 ret
= pFoldStringA(MAP_FOLDCZONE
, src
, -1, dst
, 256);
1882 for (j
= 0; foldczone_special
[j
].src
!= 0 && ! is_special
; j
++)
1884 if (foldczone_special
[j
].src
== src
[0])
1886 ok(ret
== 2 || ret
== lstrlenA(foldczone_special
[j
].dst
) + 1,
1887 "Expected ret == 2 or %d, got %d, error %d\n",
1888 lstrlenA(foldczone_special
[j
].dst
) + 1, ret
, GetLastError());
1889 ok(src
[0] == dst
[0] || lstrcmpA(foldczone_special
[j
].dst
, dst
) == 0,
1890 "MAP_FOLDCZONE: string mismatch for 0x%02x\n",
1891 (unsigned char)src
[0]);
1897 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
1898 ok(src
[0] == dst
[0],
1899 "MAP_FOLDCZONE: Expected 0x%02x, got 0x%02x\n",
1900 (unsigned char)src
[0], (unsigned char)dst
[0]);
1904 /* MAP_PRECOMPOSED */
1905 for (i
= 1; i
< 256; i
++)
1910 ret
= pFoldStringA(MAP_PRECOMPOSED
, src
, -1, dst
, 256);
1911 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
1912 ok(src
[0] == dst
[0],
1913 "MAP_PRECOMPOSED: Expected 0x%02x, got 0x%02x\n",
1914 (unsigned char)src
[0], (unsigned char)dst
[0]);
1918 static void test_FoldStringW(void)
1922 WCHAR src
[256], dst
[256], ch
, prev_ch
= 1;
1923 static const DWORD badFlags
[] =
1926 MAP_PRECOMPOSED
|MAP_COMPOSITE
,
1927 MAP_PRECOMPOSED
|MAP_EXPAND_LIGATURES
,
1928 MAP_COMPOSITE
|MAP_EXPAND_LIGATURES
1930 /* Ranges of digits 0-9 : Must be sorted! */
1931 static const WCHAR digitRanges
[] =
1933 0x0030, /* '0'-'9' */
1934 0x0660, /* Eastern Arabic */
1935 0x06F0, /* Arabic - Hindu */
1936 0x0966, /* Devengari */
1937 0x09E6, /* Bengalii */
1938 0x0A66, /* Gurmukhi */
1939 0x0AE6, /* Gujarati */
1941 0x0BE6, /* Tamil - No 0 */
1942 0x0C66, /* Telugu */
1943 0x0CE6, /* Kannada */
1944 0x0D66, /* Maylayalam */
1947 0x0F29, /* Tibet - 0 is out of sequence */
1948 0x2070, /* Superscript - 1, 2, 3 are out of sequence */
1949 0x2080, /* Subscript */
1950 0x245F, /* Circled - 0 is out of sequence */
1951 0x2473, /* Bracketed */
1952 0x2487, /* Full stop */
1953 0x2775, /* Inverted circled - No 0 */
1954 0x277F, /* Patterned circled - No 0 */
1955 0x2789, /* Inverted Patterned circled - No 0 */
1956 0x3020, /* Hangzhou */
1957 0xff10, /* Pliene chasse (?) */
1958 0xffff /* Terminator */
1960 /* Digits which are represented, but out of sequence */
1961 static const WCHAR outOfSequenceDigits
[] =
1963 0xB9, /* Superscript 1 */
1964 0xB2, /* Superscript 2 */
1965 0xB3, /* Superscript 3 */
1966 0x0F33, /* Tibetan half zero */
1967 0x24EA, /* Circled 0 */
1968 0x3007, /* Ideographic number zero */
1969 '\0' /* Terminator */
1971 /* Digits in digitRanges for which no representation is available */
1972 static const WCHAR noDigitAvailable
[] =
1974 0x0BE6, /* No Tamil 0 */
1975 0x0F29, /* No Tibetan half zero (out of sequence) */
1976 0x2473, /* No Bracketed 0 */
1977 0x2487, /* No 0 Full stop */
1978 0x2775, /* No inverted circled 0 */
1979 0x277F, /* No patterned circled */
1980 0x2789, /* No inverted Patterned circled */
1981 0x3020, /* No Hangzhou 0 */
1982 '\0' /* Terminator */
1984 static const WCHAR foldczone_src
[] =
1986 'W', 'i', 'n', 'e', 0x0348, 0x0551, 0x1323, 0x280d,
1987 0xff37, 0xff49, 0xff4e, 0xff45, '\0'
1989 static const WCHAR foldczone_dst
[] =
1991 'W','i','n','e',0x0348,0x0551,0x1323,0x280d,'W','i','n','e','\0'
1993 static const WCHAR ligatures_src
[] =
1995 'W', 'i', 'n', 'e', 0x03a6, 0x03b9, 0x03bd, 0x03b5,
1996 0x00c6, 0x00de, 0x00df, 0x00e6, 0x00fe, 0x0132, 0x0133, 0x0152,
1997 0x0153, 0x01c4, 0x01c5, 0x01c6, 0x01c7, 0x01c8, 0x01c9, 0x01ca,
1998 0x01cb, 0x01cc, 0x01e2, 0x01e3, 0x01f1, 0x01f2, 0x01f3, 0x01fc,
1999 0x01fd, 0x05f0, 0x05f1, 0x05f2, 0xfb00, 0xfb01, 0xfb02, 0xfb03,
2000 0xfb04, 0xfb05, 0xfb06, '\0'
2002 static const WCHAR ligatures_dst
[] =
2004 'W','i','n','e',0x03a6,0x03b9,0x03bd,0x03b5,
2005 'A','E','T','H','s','s','a','e','t','h','I','J','i','j','O','E','o','e',
2006 'D',0x017d,'D',0x017e,'d',0x017e,'L','J','L','j','l','j','N','J','N','j',
2007 'n','j',0x0100,0x0112,0x0101,0x0113,'D','Z','D','z','d','z',0x00c1,0x00c9,
2008 0x00e1,0x00e9,0x05d5,0x05d5,0x05d5,0x05d9,0x05d9,0x05d9,'f','f','f','i',
2009 'f','l','f','f','i','f','f','l',0x017f,'t','s','t','\0'
2014 win_skip("FoldStringW is not available\n");
2015 return; /* FoldString is present in NT v3.1+, but not 95/98/Me */
2018 /* Invalid flag combinations */
2019 for (i
= 0; i
< sizeof(badFlags
)/sizeof(badFlags
[0]); i
++)
2021 src
[0] = dst
[0] = '\0';
2023 ret
= pFoldStringW(badFlags
[i
], src
, 256, dst
, 256);
2024 if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED
)
2026 win_skip("FoldStringW is not implemented\n");
2029 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
2030 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
2033 /* src & dst cannot be the same */
2035 ret
= pFoldStringW(MAP_FOLDCZONE
, src
, -1, src
, 256);
2036 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2037 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2039 /* src can't be NULL */
2041 ret
= pFoldStringW(MAP_FOLDCZONE
, NULL
, -1, dst
, 256);
2042 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2043 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2045 /* srclen can't be 0 */
2047 ret
= pFoldStringW(MAP_FOLDCZONE
, src
, 0, dst
, 256);
2048 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2049 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2051 /* dstlen can't be < 0 */
2053 ret
= pFoldStringW(MAP_FOLDCZONE
, src
, -1, dst
, -1);
2054 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2055 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2057 /* Ret includes terminating NUL which is appended if srclen = -1 */
2062 ret
= pFoldStringW(MAP_FOLDCZONE
, src
, -1, dst
, 256);
2063 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
2064 ok(dst
[0] == 'A' && dst
[1] == '\0',
2065 "srclen=-1: Expected ret=2 [%d,%d], got ret=%d [%d,%d], err=%d\n",
2066 'A', '\0', ret
, dst
[0], dst
[1], GetLastError());
2068 /* If size is given, result is not NUL terminated */
2074 ret
= pFoldStringW(MAP_FOLDCZONE
, src
, 1, dst
, 256);
2075 ok(ret
== 1, "Expected ret == 1, got %d, error %d\n", ret
, GetLastError());
2076 ok(dst
[0] == 'A' && dst
[1] == 'X',
2077 "srclen=1: Expected ret=1, [%d,%d], got ret=%d,[%d,%d], err=%d\n",
2078 'A','X', ret
, dst
[0], dst
[1], GetLastError());
2080 /* MAP_FOLDDIGITS */
2081 for (j
= 0; j
< sizeof(digitRanges
)/sizeof(digitRanges
[0]); j
++)
2083 /* Check everything before this range */
2084 for (ch
= prev_ch
; ch
< digitRanges
[j
]; ch
++)
2088 src
[1] = dst
[0] = '\0';
2089 ret
= pFoldStringW(MAP_FOLDDIGITS
, src
, -1, dst
, 256);
2090 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
2092 ok(dst
[0] == ch
|| strchrW(outOfSequenceDigits
, ch
) ||
2093 /* Wine (correctly) maps all Unicode 4.0+ digits */
2094 isdigitW(ch
) || (ch
>= 0x24F5 && ch
<= 0x24FD) || ch
== 0x24FF ||
2095 (ch
>= 0x1369 && ch
<= 0x1371),
2096 "MAP_FOLDDIGITS: ch %d 0x%04x Expected unchanged got %d\n", ch
, ch
, dst
[0]);
2099 if (digitRanges
[j
] == 0xffff)
2100 break; /* Finished the whole code point space */
2102 for (ch
= digitRanges
[j
]; ch
< digitRanges
[j
] + 10; ch
++)
2106 /* Map out of sequence characters */
2107 if (ch
== 0x2071) c
= 0x00B9; /* Superscript 1 */
2108 else if (ch
== 0x2072) c
= 0x00B2; /* Superscript 2 */
2109 else if (ch
== 0x2073) c
= 0x00B3; /* Superscript 3 */
2110 else if (ch
== 0x245F) c
= 0x24EA; /* Circled 0 */
2114 src
[1] = dst
[0] = '\0';
2115 ret
= pFoldStringW(MAP_FOLDDIGITS
, src
, -1, dst
, 256);
2116 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
2118 ok((dst
[0] == '0' + ch
- digitRanges
[j
] && dst
[1] == '\0') ||
2119 broken( dst
[0] == ch
) || /* old Windows versions don't have all mappings */
2120 (digitRanges
[j
] == 0x3020 && dst
[0] == ch
) || /* Hangzhou not present in all Windows versions */
2121 (digitRanges
[j
] == 0x0F29 && dst
[0] == ch
) || /* Tibetan not present in all Windows versions */
2122 strchrW(noDigitAvailable
, c
),
2123 "MAP_FOLDDIGITS: ch %d Expected %d got %d\n",
2124 ch
, '0' + digitRanges
[j
] - ch
, dst
[0]);
2131 ret
= pFoldStringW(MAP_FOLDCZONE
, foldczone_src
, -1, dst
, 256);
2132 ok(ret
== sizeof(foldczone_dst
)/sizeof(foldczone_dst
[0]),
2133 "Got %d, error %d\n", ret
, GetLastError());
2134 ok(!memcmp(dst
, foldczone_dst
, sizeof(foldczone_dst
)),
2135 "MAP_FOLDCZONE: Expanded incorrectly\n");
2137 /* MAP_EXPAND_LIGATURES */
2139 ret
= pFoldStringW(MAP_EXPAND_LIGATURES
, ligatures_src
, -1, dst
, 256);
2140 /* NT 4.0 doesn't support MAP_EXPAND_LIGATURES */
2141 if (!(ret
== 0 && GetLastError() == ERROR_INVALID_FLAGS
)) {
2142 ok(ret
== sizeof(ligatures_dst
)/sizeof(ligatures_dst
[0]),
2143 "Got %d, error %d\n", ret
, GetLastError());
2144 ok(!memcmp(dst
, ligatures_dst
, sizeof(ligatures_dst
)),
2145 "MAP_EXPAND_LIGATURES: Expanded incorrectly\n");
2148 /* FIXME: MAP_PRECOMPOSED : MAP_COMPOSITE */
2153 #define LCID_OK(l) \
2154 ok(lcid == l, "Expected lcid = %08x, got %08x\n", l, lcid)
2155 #define MKLCID(x,y,z) MAKELCID(MAKELANGID(x, y), z)
2156 #define LCID_RES(src, res) lcid = ConvertDefaultLocale(src); LCID_OK(res)
2157 #define TEST_LCIDLANG(a,b) LCID_RES(MAKELCID(a,b), MAKELCID(a,b))
2158 #define TEST_LCID(a,b,c) LCID_RES(MKLCID(a,b,c), MKLCID(a,b,c))
2160 static void test_ConvertDefaultLocale(void)
2164 /* Doesn't change lcid, even if non default sublang/sort used */
2165 TEST_LCID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
, SORT_DEFAULT
);
2166 TEST_LCID(LANG_ENGLISH
, SUBLANG_ENGLISH_UK
, SORT_DEFAULT
);
2167 TEST_LCID(LANG_JAPANESE
, SUBLANG_DEFAULT
, SORT_DEFAULT
);
2168 TEST_LCID(LANG_JAPANESE
, SUBLANG_DEFAULT
, SORT_JAPANESE_UNICODE
);
2170 /* SUBLANG_NEUTRAL -> SUBLANG_DEFAULT */
2171 LCID_RES(MKLCID(LANG_ENGLISH
, SUBLANG_NEUTRAL
, SORT_DEFAULT
),
2172 MKLCID(LANG_ENGLISH
, SUBLANG_DEFAULT
, SORT_DEFAULT
));
2173 LCID_RES(MKLCID(LANG_JAPANESE
, SUBLANG_NEUTRAL
, SORT_DEFAULT
),
2174 MKLCID(LANG_JAPANESE
, SUBLANG_DEFAULT
, SORT_DEFAULT
));
2176 /* Invariant language is not treated specially */
2177 TEST_LCID(LANG_INVARIANT
, SUBLANG_DEFAULT
, SORT_DEFAULT
);
2179 /* User/system default languages alone are not mapped */
2180 TEST_LCIDLANG(LANG_SYSTEM_DEFAULT
, SORT_JAPANESE_UNICODE
);
2181 TEST_LCIDLANG(LANG_USER_DEFAULT
, SORT_JAPANESE_UNICODE
);
2184 LCID_RES(LOCALE_SYSTEM_DEFAULT
, GetSystemDefaultLCID());
2185 LCID_RES(LOCALE_USER_DEFAULT
, GetUserDefaultLCID());
2186 LCID_RES(LOCALE_NEUTRAL
, GetUserDefaultLCID());
2189 static BOOL CALLBACK
langgrp_procA(LGRPID lgrpid
, LPSTR lpszNum
, LPSTR lpszName
,
2190 DWORD dwFlags
, LONG_PTR lParam
)
2192 trace("%08x, %s, %s, %08x, %08lx\n",
2193 lgrpid
, lpszNum
, lpszName
, dwFlags
, lParam
);
2195 ok(pIsValidLanguageGroup(lgrpid
, dwFlags
) == TRUE
,
2196 "Enumerated grp %d not valid (flags %d)\n", lgrpid
, dwFlags
);
2198 /* If lParam is one, we are calling with flags defaulted from 0 */
2199 ok(!lParam
|| (dwFlags
== LGRPID_INSTALLED
|| dwFlags
== LGRPID_SUPPORTED
),
2200 "Expected dwFlags == LGRPID_INSTALLED || dwFlags == LGRPID_SUPPORTED, got %d\n", dwFlags
);
2205 static void test_EnumSystemLanguageGroupsA(void)
2209 if (!pEnumSystemLanguageGroupsA
|| !pIsValidLanguageGroup
)
2211 win_skip("EnumSystemLanguageGroupsA and/or IsValidLanguageGroup are not available\n");
2215 /* No enumeration proc */
2217 ret
= pEnumSystemLanguageGroupsA(0, LGRPID_INSTALLED
, 0);
2218 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
2220 win_skip("EnumSystemLanguageGroupsA is not implemented\n");
2223 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2224 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2228 pEnumSystemLanguageGroupsA(langgrp_procA
, LGRPID_INSTALLED
|LGRPID_SUPPORTED
, 0);
2229 ok(GetLastError() == ERROR_INVALID_FLAGS
, "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
2231 /* No flags - defaults to LGRPID_INSTALLED */
2232 SetLastError(0xdeadbeef);
2233 pEnumSystemLanguageGroupsA(langgrp_procA
, 0, 1);
2234 ok(GetLastError() == 0xdeadbeef, "got error %d\n", GetLastError());
2236 pEnumSystemLanguageGroupsA(langgrp_procA
, LGRPID_INSTALLED
, 0);
2237 pEnumSystemLanguageGroupsA(langgrp_procA
, LGRPID_SUPPORTED
, 0);
2241 static BOOL CALLBACK
lgrplocale_procA(LGRPID lgrpid
, LCID lcid
, LPSTR lpszNum
,
2244 trace("%08x, %08x, %s, %08lx\n", lgrpid
, lcid
, lpszNum
, lParam
);
2246 /* invalid locale enumerated on some platforms */
2250 ok(pIsValidLanguageGroup(lgrpid
, LGRPID_SUPPORTED
) == TRUE
,
2251 "Enumerated grp %d not valid\n", lgrpid
);
2252 ok(IsValidLocale(lcid
, LCID_SUPPORTED
) == TRUE
,
2253 "Enumerated grp locale %d not valid\n", lcid
);
2257 static void test_EnumLanguageGroupLocalesA(void)
2261 if (!pEnumLanguageGroupLocalesA
|| !pIsValidLanguageGroup
)
2263 win_skip("EnumLanguageGroupLocalesA and/or IsValidLanguageGroup are not available\n");
2267 /* No enumeration proc */
2269 ret
= pEnumLanguageGroupLocalesA(0, LGRPID_WESTERN_EUROPE
, 0, 0);
2270 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
2272 win_skip("EnumLanguageGroupLocalesA is not implemented\n");
2275 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2276 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2278 /* lgrpid too small */
2280 ret
= pEnumLanguageGroupLocalesA(lgrplocale_procA
, 0, 0, 0);
2281 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2282 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2284 /* lgrpid too big */
2286 ret
= pEnumLanguageGroupLocalesA(lgrplocale_procA
, LGRPID_ARMENIAN
+ 1, 0, 0);
2287 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2288 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2290 /* dwFlags is reserved */
2292 ret
= pEnumLanguageGroupLocalesA(0, LGRPID_WESTERN_EUROPE
, 0x1, 0);
2293 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2294 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2296 pEnumLanguageGroupLocalesA(lgrplocale_procA
, LGRPID_WESTERN_EUROPE
, 0, 0);
2299 static void test_SetLocaleInfoA(void)
2302 LCID lcid
= GetUserDefaultLCID();
2306 bRet
= SetLocaleInfoA(lcid
, LOCALE_SDATE
, 0);
2307 ok( !bRet
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2308 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2312 bRet
= SetLocaleInfoA(lcid
, LOCALE_IDATE
, (LPSTR
)test_SetLocaleInfoA
);
2313 ok(!bRet
&& GetLastError() == ERROR_INVALID_FLAGS
,
2314 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
2318 bRet
= SetLocaleInfoA(lcid
, LOCALE_ILDATE
, (LPSTR
)test_SetLocaleInfoA
);
2319 ok(!bRet
&& GetLastError() == ERROR_INVALID_FLAGS
,
2320 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
2323 static BOOL CALLBACK
luilocale_proc1A(LPSTR value
, LONG_PTR lParam
)
2325 trace("%s %08lx\n", value
, lParam
);
2329 static BOOL CALLBACK
luilocale_proc2A(LPSTR value
, LONG_PTR lParam
)
2331 ok(!enumCount
, "callback called again unexpected\n");
2336 static BOOL CALLBACK
luilocale_proc3A(LPSTR value
, LONG_PTR lParam
)
2338 ok(0,"callback called unexpected\n");
2342 static void test_EnumUILanguageA(void)
2345 if (!pEnumUILanguagesA
) {
2346 win_skip("EnumUILanguagesA is not available on Win9x or NT4\n");
2350 SetLastError(ERROR_SUCCESS
);
2351 ret
= pEnumUILanguagesA(luilocale_proc1A
, 0, 0);
2352 if (ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
2354 win_skip("EnumUILanguagesA is not implemented\n");
2357 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
2360 SetLastError(ERROR_SUCCESS
);
2361 ret
= pEnumUILanguagesA(luilocale_proc2A
, 0, 0);
2362 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
2364 SetLastError(ERROR_SUCCESS
);
2365 ret
= pEnumUILanguagesA(NULL
, 0, 0);
2366 ok(!ret
, "Expected return value FALSE, got %u\n", ret
);
2367 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
2368 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2370 SetLastError(ERROR_SUCCESS
);
2371 ret
= pEnumUILanguagesA(luilocale_proc3A
, 0x5a5a5a5a, 0);
2372 ok(!ret
, "Expected return value FALSE, got %u\n", ret
);
2373 ok(GetLastError() == ERROR_INVALID_FLAGS
, "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
2375 SetLastError(ERROR_SUCCESS
);
2376 ret
= pEnumUILanguagesA(NULL
, 0x5a5a5a5a, 0);
2377 ok(!ret
, "Expected return value FALSE, got %u\n", ret
);
2378 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
2379 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2382 static char date_fmt_buf
[1024];
2384 static BOOL CALLBACK
enum_datetime_procA(LPSTR fmt
)
2386 lstrcatA(date_fmt_buf
, fmt
);
2387 lstrcatA(date_fmt_buf
, "\n");
2391 static void test_EnumDateFormatsA(void)
2395 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
2397 trace("EnumDateFormatsA 0\n");
2398 date_fmt_buf
[0] = 0;
2399 SetLastError(0xdeadbeef);
2400 ret
= EnumDateFormatsA(enum_datetime_procA
, lcid
, 0);
2401 if (!ret
&& (GetLastError() == ERROR_INVALID_FLAGS
))
2403 win_skip("0 for dwFlags is not supported\n");
2407 ok(ret
, "EnumDateFormatsA(0) error %d\n", GetLastError());
2408 trace("%s\n", date_fmt_buf
);
2409 /* test the 1st enumerated format */
2410 if ((p
= strchr(date_fmt_buf
, '\n'))) *p
= 0;
2411 ret
= GetLocaleInfoA(lcid
, LOCALE_SSHORTDATE
, buf
, sizeof(buf
));
2412 ok(ret
, "GetLocaleInfoA(LOCALE_SSHORTDATE) error %d\n", GetLastError());
2413 ok(!lstrcmpA(date_fmt_buf
, buf
), "expected \"%s\" got \"%s\"\n", date_fmt_buf
, buf
);
2416 trace("EnumDateFormatsA LOCALE_USE_CP_ACP\n");
2417 date_fmt_buf
[0] = 0;
2418 SetLastError(0xdeadbeef);
2419 ret
= EnumDateFormatsA(enum_datetime_procA
, lcid
, LOCALE_USE_CP_ACP
);
2420 if (!ret
&& (GetLastError() == ERROR_INVALID_FLAGS
))
2422 win_skip("LOCALE_USE_CP_ACP is not supported\n");
2426 ok(ret
, "EnumDateFormatsA(LOCALE_USE_CP_ACP) error %d\n", GetLastError());
2427 trace("%s\n", date_fmt_buf
);
2428 /* test the 1st enumerated format */
2429 if ((p
= strchr(date_fmt_buf
, '\n'))) *p
= 0;
2430 ret
= GetLocaleInfoA(lcid
, LOCALE_SSHORTDATE
, buf
, sizeof(buf
));
2431 ok(ret
, "GetLocaleInfoA(LOCALE_SSHORTDATE) error %d\n", GetLastError());
2432 ok(!lstrcmpA(date_fmt_buf
, buf
), "expected \"%s\" got \"%s\"\n", date_fmt_buf
, buf
);
2435 trace("EnumDateFormatsA DATE_SHORTDATE\n");
2436 date_fmt_buf
[0] = 0;
2437 ret
= EnumDateFormatsA(enum_datetime_procA
, lcid
, DATE_SHORTDATE
);
2438 ok(ret
, "EnumDateFormatsA(DATE_SHORTDATE) error %d\n", GetLastError());
2439 trace("%s\n", date_fmt_buf
);
2440 /* test the 1st enumerated format */
2441 if ((p
= strchr(date_fmt_buf
, '\n'))) *p
= 0;
2442 ret
= GetLocaleInfoA(lcid
, LOCALE_SSHORTDATE
, buf
, sizeof(buf
));
2443 ok(ret
, "GetLocaleInfoA(LOCALE_SSHORTDATE) error %d\n", GetLastError());
2444 ok(!lstrcmpA(date_fmt_buf
, buf
), "expected \"%s\" got \"%s\"\n", date_fmt_buf
, buf
);
2446 trace("EnumDateFormatsA DATE_LONGDATE\n");
2447 date_fmt_buf
[0] = 0;
2448 ret
= EnumDateFormatsA(enum_datetime_procA
, lcid
, DATE_LONGDATE
);
2449 ok(ret
, "EnumDateFormatsA(DATE_LONGDATE) error %d\n", GetLastError());
2450 trace("%s\n", date_fmt_buf
);
2451 /* test the 1st enumerated format */
2452 if ((p
= strchr(date_fmt_buf
, '\n'))) *p
= 0;
2453 ret
= GetLocaleInfoA(lcid
, LOCALE_SLONGDATE
, buf
, sizeof(buf
));
2454 ok(ret
, "GetLocaleInfoA(LOCALE_SLONGDATE) error %d\n", GetLastError());
2455 ok(!lstrcmpA(date_fmt_buf
, buf
), "expected \"%s\" got \"%s\"\n", date_fmt_buf
, buf
);
2457 trace("EnumDateFormatsA DATE_YEARMONTH\n");
2458 date_fmt_buf
[0] = 0;
2459 SetLastError(0xdeadbeef);
2460 ret
= EnumDateFormatsA(enum_datetime_procA
, lcid
, DATE_YEARMONTH
);
2461 if (!ret
&& (GetLastError() == ERROR_INVALID_FLAGS
))
2463 skip("DATE_YEARMONTH is only present on W2K and later\n");
2466 ok(ret
, "EnumDateFormatsA(DATE_YEARMONTH) error %d\n", GetLastError());
2467 trace("%s\n", date_fmt_buf
);
2468 /* test the 1st enumerated format */
2469 if ((p
= strchr(date_fmt_buf
, '\n'))) *p
= 0;
2470 ret
= GetLocaleInfoA(lcid
, LOCALE_SYEARMONTH
, buf
, sizeof(buf
));
2471 ok(ret
, "GetLocaleInfoA(LOCALE_SYEARMONTH) error %d\n", GetLastError());
2472 ok(!lstrcmpA(date_fmt_buf
, buf
) || broken(!buf
[0]) /* win9x */,
2473 "expected \"%s\" got \"%s\"\n", date_fmt_buf
, buf
);
2476 static void test_EnumTimeFormatsA(void)
2480 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
2482 trace("EnumTimeFormatsA 0\n");
2483 date_fmt_buf
[0] = 0;
2484 ret
= EnumTimeFormatsA(enum_datetime_procA
, lcid
, 0);
2485 ok(ret
, "EnumTimeFormatsA(0) error %d\n", GetLastError());
2486 trace("%s\n", date_fmt_buf
);
2487 /* test the 1st enumerated format */
2488 if ((p
= strchr(date_fmt_buf
, '\n'))) *p
= 0;
2489 ret
= GetLocaleInfoA(lcid
, LOCALE_STIMEFORMAT
, buf
, sizeof(buf
));
2490 ok(ret
, "GetLocaleInfoA(LOCALE_STIMEFORMAT) error %d\n", GetLastError());
2491 ok(!lstrcmpA(date_fmt_buf
, buf
), "expected \"%s\" got \"%s\"\n", date_fmt_buf
, buf
);
2493 trace("EnumTimeFormatsA LOCALE_USE_CP_ACP\n");
2494 date_fmt_buf
[0] = 0;
2495 ret
= EnumTimeFormatsA(enum_datetime_procA
, lcid
, LOCALE_USE_CP_ACP
);
2496 ok(ret
, "EnumTimeFormatsA(LOCALE_USE_CP_ACP) error %d\n", GetLastError());
2497 trace("%s\n", date_fmt_buf
);
2498 /* test the 1st enumerated format */
2499 if ((p
= strchr(date_fmt_buf
, '\n'))) *p
= 0;
2500 ret
= GetLocaleInfoA(lcid
, LOCALE_STIMEFORMAT
, buf
, sizeof(buf
));
2501 ok(ret
, "GetLocaleInfoA(LOCALE_STIMEFORMAT) error %d\n", GetLastError());
2502 ok(!lstrcmpA(date_fmt_buf
, buf
), "expected \"%s\" got \"%s\"\n", date_fmt_buf
, buf
);
2505 static void test_GetCPInfo(void)
2510 SetLastError(0xdeadbeef);
2511 ret
= GetCPInfo(CP_SYMBOL
, &cpinfo
);
2512 ok(!ret
, "GetCPInfo(CP_SYMBOL) should fail\n");
2513 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
2514 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
2516 SetLastError(0xdeadbeef);
2517 ret
= GetCPInfo(CP_UTF7
, &cpinfo
);
2518 if (!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
)
2520 skip("Codepage CP_UTF7 is not installed/available\n");
2524 ok(ret
, "GetCPInfo(CP_UTF7) error %u\n", GetLastError());
2525 ok(cpinfo
.DefaultChar
[0] == 0x3f, "expected 0x3f, got 0x%x\n", cpinfo
.DefaultChar
[0]);
2526 ok(cpinfo
.DefaultChar
[1] == 0, "expected 0, got 0x%x\n", cpinfo
.DefaultChar
[1]);
2527 ok(cpinfo
.LeadByte
[0] == 0, "expected 0, got 0x%x\n", cpinfo
.LeadByte
[0]);
2528 ok(cpinfo
.LeadByte
[1] == 0, "expected 0, got 0x%x\n", cpinfo
.LeadByte
[1]);
2529 ok(cpinfo
.MaxCharSize
== 5, "expected 5, got 0x%x\n", cpinfo
.MaxCharSize
);
2532 SetLastError(0xdeadbeef);
2533 ret
= GetCPInfo(CP_UTF8
, &cpinfo
);
2534 if (!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
)
2536 skip("Codepage CP_UTF8 is not installed/available\n");
2540 ok(ret
, "GetCPInfo(CP_UTF8) error %u\n", GetLastError());
2541 ok(cpinfo
.DefaultChar
[0] == 0x3f, "expected 0x3f, got 0x%x\n", cpinfo
.DefaultChar
[0]);
2542 ok(cpinfo
.DefaultChar
[1] == 0, "expected 0, got 0x%x\n", cpinfo
.DefaultChar
[1]);
2543 ok(cpinfo
.LeadByte
[0] == 0, "expected 0, got 0x%x\n", cpinfo
.LeadByte
[0]);
2544 ok(cpinfo
.LeadByte
[1] == 0, "expected 0, got 0x%x\n", cpinfo
.LeadByte
[1]);
2545 ok(cpinfo
.MaxCharSize
== 4 || broken(cpinfo
.MaxCharSize
== 3) /* win9x */,
2546 "expected 4, got %u\n", cpinfo
.MaxCharSize
);
2552 InitFunctionPointers();
2554 test_EnumTimeFormatsA();
2555 test_EnumDateFormatsA();
2556 test_GetLocaleInfoA();
2557 test_GetLocaleInfoW();
2558 test_GetTimeFormatA();
2559 test_GetDateFormatA();
2560 test_GetDateFormatW();
2561 test_GetCurrencyFormatA(); /* Also tests the W version */
2562 test_GetNumberFormatA(); /* Also tests the W version */
2563 test_CompareStringA();
2564 test_LCMapStringA();
2565 test_LCMapStringW();
2568 test_ConvertDefaultLocale();
2569 test_EnumSystemLanguageGroupsA();
2570 test_EnumLanguageGroupLocalesA();
2571 test_SetLocaleInfoA();
2572 test_EnumUILanguageA();
2574 /* this requires collation table patch to make it MS compatible */
2575 if (0) test_sorting();