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.
33 #include "wine/test.h"
39 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};
40 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};
41 static const WCHAR symbols_stripped
[] = {'j','u','s','t','a','t','e','s','t','s','t','r','i','n','g','1',0};
42 static const WCHAR localeW
[] = {'e','n','-','U','S',0};
43 static const WCHAR fooW
[] = {'f','o','o',0};
44 static const WCHAR emptyW
[] = {0};
46 static inline unsigned int strlenW( const WCHAR
*str
)
53 static inline int strncmpW( const WCHAR
*str1
, const WCHAR
*str2
, int n
)
56 while ((--n
> 0) && *str1
&& (*str1
== *str2
)) { str1
++; str2
++; }
60 static inline WCHAR
*strchrW( const WCHAR
*str
, WCHAR ch
)
62 do { if (*str
== ch
) return (WCHAR
*)str
; } while (*str
++);
66 static inline BOOL
isdigitW( WCHAR wc
)
69 GetStringTypeW( CT_CTYPE1
, &wc
, 1, &type
);
70 return type
& C1_DIGIT
;
73 /* Some functions are only in later versions of kernel32.dll */
74 static HMODULE hKernel32
;
75 static WORD enumCount
;
77 static INT (WINAPI
*pGetTimeFormatEx
)(LPCWSTR
, DWORD
, const SYSTEMTIME
*, LPCWSTR
, LPWSTR
, INT
);
78 static INT (WINAPI
*pGetDateFormatEx
)(LPCWSTR
, DWORD
, const SYSTEMTIME
*, LPCWSTR
, LPWSTR
, INT
, LPCWSTR
);
79 static BOOL (WINAPI
*pEnumSystemLanguageGroupsA
)(LANGUAGEGROUP_ENUMPROCA
, DWORD
, LONG_PTR
);
80 static BOOL (WINAPI
*pEnumLanguageGroupLocalesA
)(LANGGROUPLOCALE_ENUMPROCA
, LGRPID
, DWORD
, LONG_PTR
);
81 static BOOL (WINAPI
*pEnumUILanguagesA
)(UILANGUAGE_ENUMPROCA
, DWORD
, LONG_PTR
);
82 static BOOL (WINAPI
*pEnumSystemLocalesEx
)(LOCALE_ENUMPROCEX
, DWORD
, LPARAM
, LPVOID
);
83 static INT (WINAPI
*pLCMapStringEx
)(LPCWSTR
, DWORD
, LPCWSTR
, INT
, LPWSTR
, INT
, LPNLSVERSIONINFO
, LPVOID
, LPARAM
);
84 static LCID (WINAPI
*pLocaleNameToLCID
)(LPCWSTR
, DWORD
);
85 static INT (WINAPI
*pLCIDToLocaleName
)(LCID
, LPWSTR
, INT
, DWORD
);
86 static INT (WINAPI
*pFoldStringA
)(DWORD
, LPCSTR
, INT
, LPSTR
, INT
);
87 static INT (WINAPI
*pFoldStringW
)(DWORD
, LPCWSTR
, INT
, LPWSTR
, INT
);
88 static BOOL (WINAPI
*pIsValidLanguageGroup
)(LGRPID
, DWORD
);
89 static INT (WINAPI
*pIdnToNameprepUnicode
)(DWORD
, LPCWSTR
, INT
, LPWSTR
, INT
);
90 static INT (WINAPI
*pIdnToAscii
)(DWORD
, LPCWSTR
, INT
, LPWSTR
, INT
);
91 static INT (WINAPI
*pIdnToUnicode
)(DWORD
, LPCWSTR
, INT
, LPWSTR
, INT
);
92 static INT (WINAPI
*pGetLocaleInfoEx
)(LPCWSTR
, LCTYPE
, LPWSTR
, INT
);
93 static BOOL (WINAPI
*pIsValidLocaleName
)(LPCWSTR
);
94 static INT (WINAPI
*pCompareStringOrdinal
)(const WCHAR
*, INT
, const WCHAR
*, INT
, BOOL
);
95 static INT (WINAPI
*pCompareStringEx
)(LPCWSTR
, DWORD
, LPCWSTR
, INT
, LPCWSTR
, INT
,
96 LPNLSVERSIONINFO
, LPVOID
, LPARAM
);
97 static INT (WINAPI
*pGetGeoInfoA
)(GEOID
, GEOTYPE
, LPSTR
, INT
, LANGID
);
98 static INT (WINAPI
*pGetGeoInfoW
)(GEOID
, GEOTYPE
, LPWSTR
, INT
, LANGID
);
99 static BOOL (WINAPI
*pEnumSystemGeoID
)(GEOCLASS
, GEOID
, GEO_ENUMPROC
);
100 static BOOL (WINAPI
*pGetSystemPreferredUILanguages
)(DWORD
, ULONG
*, WCHAR
*, ULONG
*);
102 static void InitFunctionPointers(void)
104 hKernel32
= GetModuleHandleA("kernel32");
106 #define X(f) p##f = (void*)GetProcAddress(hKernel32, #f)
109 X(EnumSystemLanguageGroupsA
);
110 X(EnumLanguageGroupLocalesA
);
116 X(IsValidLanguageGroup
);
118 X(EnumSystemLocalesEx
);
119 X(IdnToNameprepUnicode
);
123 X(IsValidLocaleName
);
124 X(CompareStringOrdinal
);
129 X(GetSystemPreferredUILanguages
);
133 #define eq(received, expected, label, type) \
134 ok((received) == (expected), "%s: got " type " instead of " type "\n", \
135 (label), (received), (expected))
137 #define BUFFER_SIZE 128
138 #define COUNTOF(x) (sizeof(x)/sizeof(x)[0])
140 #define STRINGSA(x,y) strcpy(input, x); strcpy(Expected, y); SetLastError(0xdeadbeef); buffer[0] = '\0'
141 #define EXPECT_LENA ok(ret == lstrlenA(Expected)+1, "Expected len %d, got %d\n", lstrlenA(Expected)+1, ret)
142 #define EXPECT_EQA ok(strncmp(buffer, Expected, strlen(Expected)) == 0, \
143 "Expected '%s', got '%s'\n", Expected, buffer)
145 #define STRINGSW(x,y) MultiByteToWideChar(CP_ACP,0,x,-1,input,COUNTOF(input)); \
146 MultiByteToWideChar(CP_ACP,0,y,-1,Expected,COUNTOF(Expected)); \
147 SetLastError(0xdeadbeef); buffer[0] = '\0'
148 #define EXPECT_LENW ok(ret == lstrlenW(Expected)+1, "Expected Len %d, got %d\n", lstrlenW(Expected)+1, ret)
149 #define EXPECT_EQW ok(strncmpW(buffer, Expected, strlenW(Expected)) == 0, "Bad conversion\n")
151 #define NUO LOCALE_NOUSEROVERRIDE
153 static void test_GetLocaleInfoA(void)
157 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
158 char buffer
[BUFFER_SIZE
];
159 char expected
[BUFFER_SIZE
];
162 ok(lcid
== 0x409, "wrong LCID calculated - %d\n", lcid
);
164 ret
= GetLocaleInfoA(lcid
, LOCALE_ILANGUAGE
|LOCALE_RETURN_NUMBER
, (char*)&val
, sizeof(val
));
165 ok(ret
, "got %d\n", ret
);
166 ok(val
== lcid
, "got 0x%08x\n", val
);
168 /* en and ar use SUBLANG_NEUTRAL, but GetLocaleInfo assume SUBLANG_DEFAULT
169 Same is true for zh on pre-Vista, but on Vista and higher GetLocaleInfo
170 assumes SUBLANG_NEUTRAL for zh */
171 memset(expected
, 0, COUNTOF(expected
));
172 len
= GetLocaleInfoA(MAKELANGID(LANG_ENGLISH
, SUBLANG_DEFAULT
), LOCALE_SLANGUAGE
, expected
, COUNTOF(expected
));
173 SetLastError(0xdeadbeef);
174 memset(buffer
, 0, COUNTOF(buffer
));
175 ret
= GetLocaleInfoA(LANG_ENGLISH
, LOCALE_SLANGUAGE
, buffer
, COUNTOF(buffer
));
176 ok((ret
== len
) && !lstrcmpA(buffer
, expected
),
177 "got %d with '%s' (expected %d with '%s')\n",
178 ret
, buffer
, len
, expected
);
180 memset(expected
, 0, COUNTOF(expected
));
181 len
= GetLocaleInfoA(MAKELANGID(LANG_ARABIC
, SUBLANG_DEFAULT
), LOCALE_SLANGUAGE
, expected
, COUNTOF(expected
));
183 SetLastError(0xdeadbeef);
184 memset(buffer
, 0, COUNTOF(buffer
));
185 ret
= GetLocaleInfoA(LANG_ARABIC
, LOCALE_SLANGUAGE
, buffer
, COUNTOF(buffer
));
186 ok((ret
== len
) && !lstrcmpA(buffer
, expected
),
187 "got %d with '%s' (expected %d with '%s')\n",
188 ret
, buffer
, len
, expected
);
191 win_skip("LANG_ARABIC not installed\n");
193 /* SUBLANG_DEFAULT is required for mlang.dll, but optional for GetLocaleInfo */
194 memset(expected
, 0, COUNTOF(expected
));
195 len
= GetLocaleInfoA(MAKELANGID(LANG_GERMAN
, SUBLANG_DEFAULT
), LOCALE_SLANGUAGE
, expected
, COUNTOF(expected
));
196 SetLastError(0xdeadbeef);
197 memset(buffer
, 0, COUNTOF(buffer
));
198 ret
= GetLocaleInfoA(LANG_GERMAN
, LOCALE_SLANGUAGE
, buffer
, COUNTOF(buffer
));
199 ok((ret
== len
) && !lstrcmpA(buffer
, expected
),
200 "got %d with '%s' (expected %d with '%s')\n",
201 ret
, buffer
, len
, expected
);
204 /* HTMLKit and "Font xplorer lite" expect GetLocaleInfoA to
205 * partially fill the buffer even if it is too short. See bug 637.
207 SetLastError(0xdeadbeef);
208 memset(buffer
, 0, COUNTOF(buffer
));
209 ret
= GetLocaleInfoA(lcid
, NUO
|LOCALE_SDAYNAME1
, buffer
, 0);
210 ok(ret
== 7 && !buffer
[0], "Expected len=7, got %d\n", ret
);
212 SetLastError(0xdeadbeef);
213 memset(buffer
, 0, COUNTOF(buffer
));
214 ret
= GetLocaleInfoA(lcid
, NUO
|LOCALE_SDAYNAME1
, buffer
, 3);
215 ok( !ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
216 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
217 ok(!strcmp(buffer
, "Mon"), "Expected 'Mon', got '%s'\n", buffer
);
219 SetLastError(0xdeadbeef);
220 memset(buffer
, 0, COUNTOF(buffer
));
221 ret
= GetLocaleInfoA(lcid
, NUO
|LOCALE_SDAYNAME1
, buffer
, 10);
222 ok(ret
== 7, "Expected ret == 7, got %d, error %d\n", ret
, GetLastError());
223 ok(!strcmp(buffer
, "Monday"), "Expected 'Monday', got '%s'\n", buffer
);
226 struct neutralsublang_name2_t
{
231 WCHAR sname_broken
[15];
235 static const struct neutralsublang_name2_t neutralsublang_names2
[] = {
236 { {'a','r',0}, {'a','r','-','S','A',0},
237 MAKELCID(MAKELANGID(LANG_ARABIC
, SUBLANG_ARABIC_SAUDI_ARABIA
), SORT_DEFAULT
) },
238 { {'a','z',0}, {'a','z','-','L','a','t','n','-','A','Z',0},
239 MAKELCID(MAKELANGID(LANG_AZERI
, SUBLANG_AZERI_LATIN
), SORT_DEFAULT
) },
240 { {'d','e',0}, {'d','e','-','D','E',0},
241 MAKELCID(MAKELANGID(LANG_GERMAN
, SUBLANG_GERMAN
), SORT_DEFAULT
) },
242 { {'e','n',0}, {'e','n','-','U','S',0},
243 MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
) },
244 { {'e','s',0}, {'e','s','-','E','S',0},
245 MAKELCID(MAKELANGID(LANG_SPANISH
, SUBLANG_SPANISH_MODERN
), SORT_DEFAULT
),
246 MAKELCID(MAKELANGID(LANG_SPANISH
, SUBLANG_SPANISH
), SORT_DEFAULT
) /* vista */,
247 {'e','s','-','E','S','_','t','r','a','d','n','l',0}, 0x1 },
248 { {'g','a',0}, {'g','a','-','I','E',0},
249 MAKELCID(MAKELANGID(LANG_IRISH
, SUBLANG_IRISH_IRELAND
), SORT_DEFAULT
), 0, {0}, 0x3 },
250 { {'i','t',0}, {'i','t','-','I','T',0},
251 MAKELCID(MAKELANGID(LANG_ITALIAN
, SUBLANG_ITALIAN
), SORT_DEFAULT
) },
252 { {'m','s',0}, {'m','s','-','M','Y',0},
253 MAKELCID(MAKELANGID(LANG_MALAY
, SUBLANG_MALAY_MALAYSIA
), SORT_DEFAULT
) },
254 { {'n','l',0}, {'n','l','-','N','L',0},
255 MAKELCID(MAKELANGID(LANG_DUTCH
, SUBLANG_DUTCH
), SORT_DEFAULT
) },
256 { {'p','t',0}, {'p','t','-','B','R',0},
257 MAKELCID(MAKELANGID(LANG_PORTUGUESE
, SUBLANG_PORTUGUESE_BRAZILIAN
), SORT_DEFAULT
) },
258 { {'s','r',0}, {'h','r','-','H','R',0},
259 MAKELCID(MAKELANGID(LANG_SERBIAN
, SUBLANG_SERBIAN_CROATIA
), SORT_DEFAULT
) },
260 { {'s','v',0}, {'s','v','-','S','E',0},
261 MAKELCID(MAKELANGID(LANG_SWEDISH
, SUBLANG_SWEDISH
), SORT_DEFAULT
) },
262 { {'u','z',0}, {'u','z','-','L','a','t','n','-','U','Z',0},
263 MAKELCID(MAKELANGID(LANG_UZBEK
, SUBLANG_UZBEK_LATIN
), SORT_DEFAULT
) },
264 { {'z','h',0}, {'z','h','-','C','N',0},
265 MAKELCID(MAKELANGID(LANG_CHINESE
, SUBLANG_CHINESE_SIMPLIFIED
), SORT_DEFAULT
), 0, {0}, 0x3 },
269 static void test_GetLocaleInfoW(void)
271 LCID lcid_en
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
272 LCID lcid_ru
= MAKELCID(MAKELANGID(LANG_RUSSIAN
, SUBLANG_NEUTRAL
), SORT_DEFAULT
);
273 LCID lcid_en_neut
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_NEUTRAL
), SORT_DEFAULT
);
274 WCHAR bufferW
[80], buffer2W
[80];
280 ret
= GetLocaleInfoW(lcid_en
, LOCALE_SMONTHNAME1
, bufferW
, COUNTOF(bufferW
));
282 win_skip("GetLocaleInfoW() isn't implemented\n");
286 ret
= GetLocaleInfoW(lcid_en
, LOCALE_ILANGUAGE
|LOCALE_RETURN_NUMBER
, (WCHAR
*)&val
, sizeof(val
)/sizeof(WCHAR
));
287 ok(ret
, "got %d\n", ret
);
288 ok(val
== lcid_en
, "got 0x%08x\n", val
);
290 ret
= GetLocaleInfoW(lcid_en_neut
, LOCALE_SNAME
, bufferW
, COUNTOF(bufferW
));
293 static const WCHAR slangW
[] = {'E','n','g','l','i','s','h',' ','(','U','n','i','t','e','d',' ',
294 'S','t','a','t','e','s',')',0};
295 static const WCHAR statesW
[] = {'U','n','i','t','e','d',' ','S','t','a','t','e','s',0};
296 static const WCHAR enW
[] = {'e','n','-','U','S',0};
297 const struct neutralsublang_name2_t
*ptr
= neutralsublang_names2
;
299 ok(!lstrcmpW(bufferW
, enW
), "got wrong name %s\n", wine_dbgstr_w(bufferW
));
301 ret
= GetLocaleInfoW(lcid_en_neut
, LOCALE_SCOUNTRY
, bufferW
, COUNTOF(bufferW
));
302 ok(ret
, "got %d\n", ret
);
303 if ((PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) != LANG_ENGLISH
) ||
304 (PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH
))
306 skip("Non-English locale\n");
309 ok(!lstrcmpW(statesW
, bufferW
), "got wrong name %s\n", wine_dbgstr_w(bufferW
));
311 ret
= GetLocaleInfoW(lcid_en_neut
, LOCALE_SLANGUAGE
, bufferW
, COUNTOF(bufferW
));
312 ok(ret
, "got %d\n", ret
);
313 if ((PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) != LANG_ENGLISH
) ||
314 (PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH
))
316 skip("Non-English locale\n");
319 ok(!lstrcmpW(slangW
, bufferW
), "got wrong name %s\n", wine_dbgstr_w(bufferW
));
326 /* make neutral lcid */
327 langid
= MAKELANGID(PRIMARYLANGID(LANGIDFROMLCID(ptr
->lcid
)), SUBLANG_NEUTRAL
);
328 lcid
= MAKELCID(langid
, SORT_DEFAULT
);
331 GetLocaleInfoW(lcid
, LOCALE_ILANGUAGE
|LOCALE_RETURN_NUMBER
, (WCHAR
*)&val
, sizeof(val
)/sizeof(WCHAR
));
335 ok(val
== ptr
->lcid
|| (val
&& broken(val
== ptr
->lcid_broken
)), "%s: got wrong lcid 0x%04x, expected 0x%04x\n",
336 wine_dbgstr_w(ptr
->name
), val
, ptr
->lcid
);
339 ok(val
== ptr
->lcid
|| (val
&& broken(val
== ptr
->lcid_broken
)), "%s: got wrong lcid 0x%04x, expected 0x%04x\n",
340 wine_dbgstr_w(ptr
->name
), val
, ptr
->lcid
);
342 /* now check LOCALE_SNAME */
343 GetLocaleInfoW(lcid
, LOCALE_SNAME
, bufferW
, COUNTOF(bufferW
));
346 ok(!lstrcmpW(bufferW
, ptr
->sname
) ||
347 (*ptr
->sname_broken
&& broken(!lstrcmpW(bufferW
, ptr
->sname_broken
))),
348 "%s: got %s\n", wine_dbgstr_w(ptr
->name
), wine_dbgstr_w(bufferW
));
350 ok(!lstrcmpW(bufferW
, ptr
->sname
) ||
351 (*ptr
->sname_broken
&& broken(!lstrcmpW(bufferW
, ptr
->sname_broken
))),
352 "%s: got %s\n", wine_dbgstr_w(ptr
->name
), wine_dbgstr_w(bufferW
));
357 win_skip("English neutral locale not supported\n");
359 ret
= GetLocaleInfoW(lcid_ru
, LOCALE_SMONTHNAME1
, bufferW
, COUNTOF(bufferW
));
361 win_skip("LANG_RUSSIAN locale data unavailable\n");
364 ret
= GetLocaleInfoW(lcid_ru
, LOCALE_SMONTHNAME1
|LOCALE_RETURN_GENITIVE_NAMES
,
365 bufferW
, COUNTOF(bufferW
));
367 win_skip("LOCALE_RETURN_GENITIVE_NAMES isn't supported\n");
371 /* LOCALE_RETURN_GENITIVE_NAMES isn't supported for GetLocaleInfoA */
373 SetLastError(0xdeadbeef);
374 ret
= GetLocaleInfoA(lcid_ru
, LOCALE_SMONTHNAME1
|LOCALE_RETURN_GENITIVE_NAMES
,
375 bufferA
, COUNTOF(bufferA
));
376 ok(ret
== 0, "LOCALE_RETURN_GENITIVE_NAMES should fail with GetLocaleInfoA\n");
377 ok(bufferA
[0] == 'a', "Expected buffer to be untouched\n");
378 ok(GetLastError() == ERROR_INVALID_FLAGS
,
379 "Expected ERROR_INVALID_FLAGS, got %x\n", GetLastError());
382 SetLastError(0xdeadbeef);
383 ret
= GetLocaleInfoW(lcid_ru
, LOCALE_RETURN_GENITIVE_NAMES
,
384 bufferW
, COUNTOF(bufferW
));
386 "LOCALE_RETURN_GENITIVE_NAMES itself doesn't return anything, got %d\n", ret
);
387 ok(bufferW
[0] == 'a', "Expected buffer to be untouched\n");
388 ok(GetLastError() == ERROR_INVALID_FLAGS
,
389 "Expected ERROR_INVALID_FLAGS, got %x\n", GetLastError());
391 /* yes, test empty 13 month entry too */
392 for (i
= 0; i
< 12; i
++) {
394 ret
= GetLocaleInfoW(lcid_ru
, (LOCALE_SMONTHNAME1
+i
)|LOCALE_RETURN_GENITIVE_NAMES
,
395 bufferW
, COUNTOF(bufferW
));
396 ok(ret
, "Expected non zero result\n");
397 ok(ret
== lstrlenW(bufferW
)+1, "Expected actual length, got %d, length %d\n",
398 ret
, lstrlenW(bufferW
));
400 ret
= GetLocaleInfoW(lcid_ru
, LOCALE_SMONTHNAME1
+i
,
401 buffer2W
, COUNTOF(buffer2W
));
402 ok(ret
, "Expected non zero result\n");
403 ok(ret
== lstrlenW(buffer2W
)+1, "Expected actual length, got %d, length %d\n",
404 ret
, lstrlenW(buffer2W
));
406 ok(lstrcmpW(bufferW
, buffer2W
) != 0,
407 "Expected genitive name to differ, got the same for month %d\n", i
+1);
409 /* for locale without genitive names nominative returned in both cases */
411 ret
= GetLocaleInfoW(lcid_en
, (LOCALE_SMONTHNAME1
+i
)|LOCALE_RETURN_GENITIVE_NAMES
,
412 bufferW
, COUNTOF(bufferW
));
413 ok(ret
, "Expected non zero result\n");
414 ok(ret
== lstrlenW(bufferW
)+1, "Expected actual length, got %d, length %d\n",
415 ret
, lstrlenW(bufferW
));
417 ret
= GetLocaleInfoW(lcid_en
, LOCALE_SMONTHNAME1
+i
,
418 buffer2W
, COUNTOF(buffer2W
));
419 ok(ret
, "Expected non zero result\n");
420 ok(ret
== lstrlenW(buffer2W
)+1, "Expected actual length, got %d, length %d\n",
421 ret
, lstrlenW(buffer2W
));
423 ok(lstrcmpW(bufferW
, buffer2W
) == 0,
424 "Expected same names, got different for month %d\n", i
+1);
428 static void test_GetTimeFormatA(void)
432 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
433 char buffer
[BUFFER_SIZE
], input
[BUFFER_SIZE
], Expected
[BUFFER_SIZE
];
435 memset(&curtime
, 2, sizeof(SYSTEMTIME
));
436 STRINGSA("tt HH':'mm'@'ss", ""); /* Invalid time */
437 SetLastError(0xdeadbeef);
438 ret
= GetTimeFormatA(lcid
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
439 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
440 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
443 curtime
.wMinute
= 56;
444 curtime
.wSecond
= 13;
445 curtime
.wMilliseconds
= 22;
446 STRINGSA("tt HH':'mm'@'ss", "AM 08:56@13"); /* Valid time */
447 SetLastError(0xdeadbeef);
448 ret
= GetTimeFormatA(lcid
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
449 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
450 EXPECT_LENA
; EXPECT_EQA
;
452 /* MSDN: LOCALE_NOUSEROVERRIDE can't be specified with a format string */
453 SetLastError(0xdeadbeef);
454 ret
= GetTimeFormatA(lcid
, NUO
|TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
455 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
456 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
458 STRINGSA("tt HH':'mm'@'ss", "A"); /* Insufficient buffer */
459 SetLastError(0xdeadbeef);
460 ret
= GetTimeFormatA(lcid
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, 2);
461 ok( !ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
462 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
464 STRINGSA("tt HH':'mm'@'ss", "AM 08:56@13"); /* Calculate length only */
465 ret
= GetTimeFormatA(lcid
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, NULL
, 0);
466 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
469 STRINGSA("", "8 AM"); /* TIME_NOMINUTESORSECONDS, default format */
470 ret
= GetTimeFormatA(lcid
, NUO
|TIME_NOMINUTESORSECONDS
, &curtime
, NULL
, buffer
, COUNTOF(buffer
));
471 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
472 EXPECT_LENA
; EXPECT_EQA
;
474 STRINGSA("m1s2m3s4", ""); /* TIME_NOMINUTESORSECONDS/complex format */
475 ret
= GetTimeFormatA(lcid
, TIME_NOMINUTESORSECONDS
, &curtime
, input
, buffer
, COUNTOF(buffer
));
476 ok(ret
== strlen(buffer
)+1, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
477 ok( !strcmp( buffer
, "" ) || broken( !strcmp( buffer
, "4" )), /* win9x */
478 "Expected '', got '%s'\n", buffer
);
480 STRINGSA("", "8:56 AM"); /* TIME_NOSECONDS/Default format */
481 ret
= GetTimeFormatA(lcid
, NUO
|TIME_NOSECONDS
, &curtime
, NULL
, buffer
, COUNTOF(buffer
));
482 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
483 EXPECT_LENA
; EXPECT_EQA
;
485 STRINGSA("h:m:s tt", "8:56 AM"); /* TIME_NOSECONDS */
486 strcpy(Expected
, "8:56 AM");
487 ret
= GetTimeFormatA(lcid
, TIME_NOSECONDS
, &curtime
, input
, buffer
, COUNTOF(buffer
));
488 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
489 EXPECT_LENA
; EXPECT_EQA
;
491 STRINGSA("h.@:m.@:s.@:tt", "8.@:56AM"); /* Multiple delimiters */
492 ret
= GetTimeFormatA(lcid
, TIME_NOSECONDS
, &curtime
, input
, buffer
, COUNTOF(buffer
));
493 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
494 ok( !strcmp( buffer
, "8.@:56AM" ) || broken( !strcmp( buffer
, "8.@:56.@:AM" )) /* win9x */,
495 "Expected '8.@:56AM', got '%s'\n", buffer
);
497 STRINGSA("s1s2s3", ""); /* Duplicate tokens */
498 ret
= GetTimeFormatA(lcid
, TIME_NOSECONDS
, &curtime
, input
, buffer
, COUNTOF(buffer
));
499 ok(ret
== strlen(buffer
)+1, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
500 ok( !strcmp( buffer
, "" ) || broken( !strcmp( buffer
, "3" )), /* win9x */
501 "Expected '', got '%s'\n", buffer
);
503 STRINGSA("t/tt", "A/AM"); /* AM time marker */
504 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
505 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
506 EXPECT_LENA
; EXPECT_EQA
;
509 STRINGSA("t/tt", "P/PM"); /* PM time marker */
510 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
511 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
512 EXPECT_LENA
; EXPECT_EQA
;
514 STRINGSA("h1t2tt3m", "156"); /* TIME_NOTIMEMARKER: removes text around time marker token */
515 ret
= GetTimeFormatA(lcid
, TIME_NOTIMEMARKER
, &curtime
, input
, buffer
, COUNTOF(buffer
));
516 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
517 EXPECT_LENA
; EXPECT_EQA
;
519 STRINGSA("h:m:s tt", "13:56:13 PM"); /* TIME_FORCE24HOURFORMAT */
520 ret
= GetTimeFormatA(lcid
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
521 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
522 EXPECT_LENA
; EXPECT_EQA
;
524 STRINGSA("h:m:s", "13:56:13"); /* TIME_FORCE24HOURFORMAT doesn't add time marker */
525 ret
= GetTimeFormatA(lcid
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
526 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
527 EXPECT_LENA
; EXPECT_EQA
;
529 curtime
.wHour
= 14; /* change this to 14 or 2pm */
532 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 */
533 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
534 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
535 EXPECT_LENA
; EXPECT_EQA
;
538 STRINGSA("h/H/hh/HH", "12/0/12/00"); /* "hh" and "HH" */
539 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
540 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
541 EXPECT_LENA
; EXPECT_EQA
;
543 STRINGSA("h:m:s tt", "12:5:3 AM"); /* non-zero flags should fail with format, doesn't */
544 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
545 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
546 EXPECT_LENA
; EXPECT_EQA
;
548 /* try to convert formatting strings with more than two letters
549 * "h:hh:hhh:H:HH:HHH:m:mm:mmm:M:MM:MMM:s:ss:sss:S:SS:SSS"
550 * NOTE: We expect any letter for which there is an upper case value
551 * we should see a replacement. For letters that DO NOT have
552 * upper case values we should see NO REPLACEMENT.
555 curtime
.wMinute
= 56;
556 curtime
.wSecond
= 13;
557 curtime
.wMilliseconds
= 22;
558 STRINGSA("h:hh:hhh H:HH:HHH m:mm:mmm M:MM:MMM s:ss:sss S:SS:SSS",
559 "8:08:08 8:08:08 56:56:56 M:MM:MMM 13:13:13 S:SS:SSS");
560 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
561 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
562 EXPECT_LENA
; EXPECT_EQA
;
564 STRINGSA("h", "text"); /* Don't write to buffer if len is 0 */
565 strcpy(buffer
, "text");
566 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, 0);
567 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
570 STRINGSA("h 'h' H 'H' HH 'HH' m 'm' s 's' t 't' tt 'tt'",
571 "8 h 8 H 08 HH 56 m 13 s A t AM tt"); /* "'" preserves tokens */
572 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
573 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
574 EXPECT_LENA
; EXPECT_EQA
;
576 STRINGSA("'''", "'"); /* invalid quoted string */
577 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
578 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
579 EXPECT_LENA
; EXPECT_EQA
;
581 /* test that msdn suggested single quotation usage works as expected */
582 STRINGSA("''''", "'"); /* single quote mark */
583 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
584 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
585 EXPECT_LENA
; EXPECT_EQA
;
587 STRINGSA("''HHHHHH", "08"); /* Normal use */
588 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
589 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
590 EXPECT_LENA
; EXPECT_EQA
;
592 /* and test for normal use of the single quotation mark */
593 STRINGSA("'''HHHHHH'", "'HHHHHH"); /* Normal use */
594 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
595 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
596 EXPECT_LENA
; EXPECT_EQA
;
598 STRINGSA("'''HHHHHH", "'HHHHHH"); /* Odd use */
599 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
600 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
601 EXPECT_LENA
; EXPECT_EQA
;
603 STRINGSA("'123'tt", ""); /* TIME_NOTIMEMARKER drops literals too */
604 ret
= GetTimeFormatA(lcid
, TIME_NOTIMEMARKER
, &curtime
, input
, buffer
, COUNTOF(buffer
));
605 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
606 EXPECT_LENA
; EXPECT_EQA
;
609 STRINGSA("'123'tt", ""); /* Invalid time */
610 SetLastError(0xdeadbeef);
611 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
612 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
613 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
616 curtime
.wMonth
= 60; /* Invalid */
617 STRINGSA("h:m:s", "12:56:13"); /* Invalid date */
618 ret
= GetTimeFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
619 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
620 EXPECT_LENA
; EXPECT_EQA
;
623 static void test_GetTimeFormatEx(void)
627 WCHAR buffer
[BUFFER_SIZE
], input
[BUFFER_SIZE
], Expected
[BUFFER_SIZE
];
629 if (!pGetTimeFormatEx
)
631 win_skip("GetTimeFormatEx not supported\n");
635 memset(&curtime
, 2, sizeof(SYSTEMTIME
));
636 STRINGSW("tt HH':'mm'@'ss", ""); /* Invalid time */
637 SetLastError(0xdeadbeef);
638 ret
= pGetTimeFormatEx(localeW
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
639 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
640 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
643 curtime
.wMinute
= 56;
644 curtime
.wSecond
= 13;
645 curtime
.wMilliseconds
= 22;
646 STRINGSW("tt HH':'mm'@'ss", "AM 08:56@13"); /* Valid time */
647 SetLastError(0xdeadbeef);
648 ret
= pGetTimeFormatEx(localeW
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
649 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
650 EXPECT_LENW
; EXPECT_EQW
;
652 /* MSDN: LOCALE_NOUSEROVERRIDE can't be specified with a format string */
653 SetLastError(0xdeadbeef);
654 ret
= pGetTimeFormatEx(localeW
, NUO
|TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
655 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
656 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
658 STRINGSW("tt HH':'mm'@'ss", "A"); /* Insufficient buffer */
659 SetLastError(0xdeadbeef);
660 ret
= pGetTimeFormatEx(localeW
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, 2);
661 ok( !ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
662 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
664 STRINGSW("tt HH':'mm'@'ss", "AM 08:56@13"); /* Calculate length only */
665 ret
= pGetTimeFormatEx(localeW
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, NULL
, 0);
666 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
669 STRINGSW("", "8 AM"); /* TIME_NOMINUTESORSECONDS, default format */
670 ret
= pGetTimeFormatEx(localeW
, NUO
|TIME_NOMINUTESORSECONDS
, &curtime
, NULL
, buffer
, COUNTOF(buffer
));
671 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
672 EXPECT_LENW
; EXPECT_EQW
;
674 STRINGSW("m1s2m3s4", ""); /* TIME_NOMINUTESORSECONDS/complex format */
675 ret
= pGetTimeFormatEx(localeW
, TIME_NOMINUTESORSECONDS
, &curtime
, input
, buffer
, COUNTOF(buffer
));
676 ok(ret
== strlenW(buffer
)+1, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
677 EXPECT_LENW
; EXPECT_EQW
;
679 STRINGSW("", "8:56 AM"); /* TIME_NOSECONDS/Default format */
680 ret
= pGetTimeFormatEx(localeW
, NUO
|TIME_NOSECONDS
, &curtime
, NULL
, buffer
, COUNTOF(buffer
));
681 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
682 EXPECT_LENW
; EXPECT_EQW
;
684 STRINGSW("h:m:s tt", "8:56 AM"); /* TIME_NOSECONDS */
685 ret
= pGetTimeFormatEx(localeW
, TIME_NOSECONDS
, &curtime
, input
, buffer
, COUNTOF(buffer
));
686 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
687 EXPECT_LENW
; EXPECT_EQW
;
689 STRINGSW("h.@:m.@:s.@:tt", "8.@:56AM"); /* Multiple delimiters */
690 ret
= pGetTimeFormatEx(localeW
, TIME_NOSECONDS
, &curtime
, input
, buffer
, COUNTOF(buffer
));
691 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
692 EXPECT_LENW
; EXPECT_EQW
;
694 STRINGSW("s1s2s3", ""); /* Duplicate tokens */
695 ret
= pGetTimeFormatEx(localeW
, TIME_NOSECONDS
, &curtime
, input
, buffer
, COUNTOF(buffer
));
696 ok(ret
== strlenW(buffer
)+1, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
697 EXPECT_LENW
; EXPECT_EQW
;
699 STRINGSW("t/tt", "A/AM"); /* AM time marker */
700 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
701 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
702 EXPECT_LENW
; EXPECT_EQW
;
705 STRINGSW("t/tt", "P/PM"); /* PM time marker */
706 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
707 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
708 EXPECT_LENW
; EXPECT_EQW
;
710 STRINGSW("h1t2tt3m", "156"); /* TIME_NOTIMEMARKER: removes text around time marker token */
711 ret
= pGetTimeFormatEx(localeW
, TIME_NOTIMEMARKER
, &curtime
, input
, buffer
, COUNTOF(buffer
));
712 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
713 EXPECT_LENW
; EXPECT_EQW
;
715 STRINGSW("h:m:s tt", "13:56:13 PM"); /* TIME_FORCE24HOURFORMAT */
716 ret
= pGetTimeFormatEx(localeW
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
717 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
718 EXPECT_LENW
; EXPECT_EQW
;
720 STRINGSW("h:m:s", "13:56:13"); /* TIME_FORCE24HOURFORMAT doesn't add time marker */
721 ret
= pGetTimeFormatEx(localeW
, TIME_FORCE24HOURFORMAT
, &curtime
, input
, buffer
, COUNTOF(buffer
));
722 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
723 EXPECT_LENW
; EXPECT_EQW
;
725 curtime
.wHour
= 14; /* change this to 14 or 2pm */
728 STRINGSW("h hh H HH m mm s ss t tt", "2 02 14 14 5 05 3 03 P PM"); /* 24 hrs, leading 0 */
729 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
730 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
731 EXPECT_LENW
; EXPECT_EQW
;
734 STRINGSW("h/H/hh/HH", "12/0/12/00"); /* "hh" and "HH" */
735 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
736 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
737 EXPECT_LENW
; EXPECT_EQW
;
739 STRINGSW("h:m:s tt", "12:5:3 AM"); /* non-zero flags should fail with format, doesn't */
740 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
741 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
742 EXPECT_LENW
; EXPECT_EQW
;
744 /* try to convert formatting strings with more than two letters
745 * "h:hh:hhh:H:HH:HHH:m:mm:mmm:M:MM:MMM:s:ss:sss:S:SS:SSS"
746 * NOTE: We expect any letter for which there is an upper case value
747 * we should see a replacement. For letters that DO NOT have
748 * upper case values we should see NO REPLACEMENT.
751 curtime
.wMinute
= 56;
752 curtime
.wSecond
= 13;
753 curtime
.wMilliseconds
= 22;
754 STRINGSW("h:hh:hhh H:HH:HHH m:mm:mmm M:MM:MMM s:ss:sss S:SS:SSS",
755 "8:08:08 8:08:08 56:56:56 M:MM:MMM 13:13:13 S:SS:SSS");
756 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
757 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
758 EXPECT_LENW
; EXPECT_EQW
;
760 STRINGSW("h", "text"); /* Don't write to buffer if len is 0 */
761 lstrcpyW(buffer
, Expected
);
762 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, 0);
763 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
766 STRINGSW("h 'h' H 'H' HH 'HH' m 'm' s 's' t 't' tt 'tt'",
767 "8 h 8 H 08 HH 56 m 13 s A t AM tt"); /* "'" preserves tokens */
768 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
769 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
770 EXPECT_LENW
; EXPECT_EQW
;
772 STRINGSW("'''", "'"); /* invalid quoted string */
773 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
774 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
775 EXPECT_LENW
; EXPECT_EQW
;
777 /* test that msdn suggested single quotation usage works as expected */
778 STRINGSW("''''", "'"); /* single quote mark */
779 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
780 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
781 EXPECT_LENW
; EXPECT_EQW
;
783 STRINGSW("''HHHHHH", "08"); /* Normal use */
784 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
785 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
786 EXPECT_LENW
; EXPECT_EQW
;
788 /* and test for normal use of the single quotation mark */
789 STRINGSW("'''HHHHHH'", "'HHHHHH"); /* Normal use */
790 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
791 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
792 EXPECT_LENW
; EXPECT_EQW
;
794 STRINGSW("'''HHHHHH", "'HHHHHH"); /* Odd use */
795 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
796 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
797 EXPECT_LENW
; EXPECT_EQW
;
799 STRINGSW("'123'tt", ""); /* TIME_NOTIMEMARKER drops literals too */
800 ret
= pGetTimeFormatEx(localeW
, TIME_NOTIMEMARKER
, &curtime
, input
, buffer
, COUNTOF(buffer
));
801 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
802 EXPECT_LENW
; EXPECT_EQW
;
805 STRINGSW("'123'tt", ""); /* Invalid time */
806 SetLastError(0xdeadbeef);
807 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
808 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
809 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
812 curtime
.wMonth
= 60; /* Invalid */
813 STRINGSW("h:m:s", "12:56:13"); /* Invalid date */
814 ret
= pGetTimeFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
815 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
816 EXPECT_LENW
; EXPECT_EQW
;
819 static void test_GetDateFormatA(void)
823 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
824 LCID lcid_ru
= MAKELCID(MAKELANGID(LANG_RUSSIAN
, SUBLANG_NEUTRAL
), SORT_DEFAULT
);
825 char buffer
[BUFFER_SIZE
], input
[BUFFER_SIZE
], Expected
[BUFFER_SIZE
];
826 char Broken
[BUFFER_SIZE
];
827 char short_day
[10], month
[10], genitive_month
[10];
829 memset(&curtime
, 2, sizeof(SYSTEMTIME
)); /* Invalid time */
830 STRINGSA("ddd',' MMM dd yy","");
831 SetLastError(0xdeadbeef);
832 ret
= GetDateFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
833 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
834 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
836 curtime
.wYear
= 2002;
839 curtime
.wDayOfWeek
= 3;
840 STRINGSA("ddd',' MMM dd yy","Sat, May 04 02"); /* Simple case */
841 ret
= GetDateFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
842 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
843 EXPECT_LENA
; EXPECT_EQA
;
845 /* Same as above but with LOCALE_NOUSEROVERRIDE */
846 STRINGSA("ddd',' MMM dd yy",""); /* Simple case */
847 SetLastError(0xdeadbeef);
848 ret
= GetDateFormatA(lcid
, NUO
, &curtime
, input
, buffer
, COUNTOF(buffer
));
849 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
850 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
853 STRINGSA("ddd',' MMM dd yy","Sat, May 04 02"); /* Format containing "'" */
854 ret
= GetDateFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
855 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
856 EXPECT_LENA
; EXPECT_EQA
;
858 curtime
.wHour
= 36; /* Invalid */
859 STRINGSA("ddd',' MMM dd ''''yy","Sat, May 04 '02"); /* Invalid time */
860 ret
= GetDateFormatA(lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
861 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
862 EXPECT_LENA
; EXPECT_EQA
;
864 STRINGSA("ddd',' MMM dd ''''yy",""); /* Get size only */
865 ret
= GetDateFormatA(lcid
, 0, &curtime
, input
, NULL
, 0);
866 ok(ret
== 16, "Expected ret == 16, got %d, error %d\n", ret
, GetLastError());
869 STRINGSA("ddd',' MMM dd ''''yy",""); /* Buffer too small */
870 SetLastError(0xdeadbeef);
871 ret
= GetDateFormatA(lcid
, 0, &curtime
, input
, buffer
, 2);
872 ok( !ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
873 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
875 STRINGSA("ddd',' MMM dd ''''yy","5/4/2002"); /* Default to DATE_SHORTDATE */
876 ret
= GetDateFormatA(lcid
, NUO
, &curtime
, NULL
, buffer
, COUNTOF(buffer
));
877 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
878 if (strncmp(buffer
, Expected
, strlen(Expected
)) && strncmp(buffer
, "5/4/02", strlen(Expected
)) != 0)
879 ok (0, "Expected '%s' or '5/4/02', got '%s'\n", Expected
, buffer
);
881 SetLastError(0xdeadbeef); buffer
[0] = '\0'; /* DATE_LONGDATE */
882 ret
= GetDateFormatA(lcid
, NUO
|DATE_LONGDATE
, &curtime
, NULL
, buffer
, COUNTOF(buffer
));
883 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
884 ok(strcmp(buffer
, "Saturday, May 04, 2002") == 0 ||
885 strcmp(buffer
, "Saturday, May 4, 2002") == 0 /* Win 8 */,
886 "got an unexpected date string '%s'\n", buffer
);
888 /* test for expected DATE_YEARMONTH behavior with null format */
889 /* NT4 returns ERROR_INVALID_FLAGS for DATE_YEARMONTH */
890 STRINGSA("ddd',' MMM dd ''''yy", ""); /* DATE_YEARMONTH */
891 SetLastError(0xdeadbeef);
892 ret
= GetDateFormatA(lcid
, NUO
|DATE_YEARMONTH
, &curtime
, input
, buffer
, COUNTOF(buffer
));
893 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
894 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
897 /* Test that using invalid DATE_* flags results in the correct error */
898 /* and return values */
899 STRINGSA("m/d/y", ""); /* Invalid flags */
900 SetLastError(0xdeadbeef);
901 ret
= GetDateFormatA(lcid
, DATE_YEARMONTH
|DATE_SHORTDATE
|DATE_LONGDATE
,
902 &curtime
, input
, buffer
, COUNTOF(buffer
));
903 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
904 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
906 ret
= GetDateFormatA(lcid_ru
, 0, &curtime
, "ddMMMM", buffer
, COUNTOF(buffer
));
909 win_skip("LANG_RUSSIAN locale data unavailable\n");
913 /* month part should be in genitive form */
914 strcpy(genitive_month
, buffer
+ 2);
915 ret
= GetDateFormatA(lcid_ru
, 0, &curtime
, "MMMM", buffer
, COUNTOF(buffer
));
916 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
917 strcpy(month
, buffer
);
918 ok(strcmp(genitive_month
, month
) != 0, "Expected different month forms\n");
920 ret
= GetDateFormatA(lcid_ru
, 0, &curtime
, "ddd", buffer
, COUNTOF(buffer
));
921 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
922 strcpy(short_day
, buffer
);
924 STRINGSA("dd MMMMddd dd", "");
925 sprintf(Expected
, "04 %s%s 04", genitive_month
, short_day
);
926 ret
= GetDateFormatA(lcid_ru
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
927 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
930 STRINGSA("MMMMddd dd", "");
931 sprintf(Expected
, "%s%s 04", month
, short_day
);
932 ret
= GetDateFormatA(lcid_ru
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
933 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
936 STRINGSA("MMMMddd", "");
937 sprintf(Expected
, "%s%s", month
, short_day
);
938 ret
= GetDateFormatA(lcid_ru
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
939 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
942 STRINGSA("MMMMdd", "");
943 sprintf(Expected
, "%s04", genitive_month
);
944 sprintf(Broken
, "%s04", month
);
945 ret
= GetDateFormatA(lcid_ru
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
946 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
947 ok(strncmp(buffer
, Expected
, strlen(Expected
)) == 0 ||
948 broken(strncmp(buffer
, Broken
, strlen(Broken
)) == 0) /* nt4 */,
949 "Expected '%s', got '%s'\n", Expected
, buffer
);
951 STRINGSA("MMMMdd ddd", "");
952 sprintf(Expected
, "%s04 %s", genitive_month
, short_day
);
953 sprintf(Broken
, "%s04 %s", month
, short_day
);
954 ret
= GetDateFormatA(lcid_ru
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
955 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
956 ok(strncmp(buffer
, Expected
, strlen(Expected
)) == 0 ||
957 broken(strncmp(buffer
, Broken
, strlen(Broken
)) == 0) /* nt4 */,
958 "Expected '%s', got '%s'\n", Expected
, buffer
);
960 STRINGSA("dd dddMMMM", "");
961 sprintf(Expected
, "04 %s%s", short_day
, month
);
962 ret
= GetDateFormatA(lcid_ru
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
963 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
966 STRINGSA("dd dddMMMM ddd MMMMdd", "");
967 sprintf(Expected
, "04 %s%s %s %s04", short_day
, month
, short_day
, genitive_month
);
968 sprintf(Broken
, "04 %s%s %s %s04", short_day
, month
, short_day
, month
);
969 ret
= GetDateFormatA(lcid_ru
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
970 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
971 ok(strncmp(buffer
, Expected
, strlen(Expected
)) == 0 ||
972 broken(strncmp(buffer
, Broken
, strlen(Broken
)) == 0) /* nt4 */,
973 "Expected '%s', got '%s'\n", Expected
, buffer
);
975 /* with literal part */
976 STRINGSA("ddd',' MMMM dd", "");
977 sprintf(Expected
, "%s, %s 04", short_day
, genitive_month
);
978 sprintf(Broken
, "%s, %s 04", short_day
, month
);
979 ret
= GetDateFormatA(lcid_ru
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
980 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
981 ok(strncmp(buffer
, Expected
, strlen(Expected
)) == 0 ||
982 broken(strncmp(buffer
, Broken
, strlen(Broken
)) == 0) /* nt4 */,
983 "Expected '%s', got '%s'\n", Expected
, buffer
);
986 static void test_GetDateFormatEx(void)
990 WCHAR buffer
[BUFFER_SIZE
], input
[BUFFER_SIZE
], Expected
[BUFFER_SIZE
];
992 if (!pGetDateFormatEx
)
994 win_skip("GetDateFormatEx not supported\n");
998 STRINGSW("",""); /* If flags are set, then format must be NULL */
999 SetLastError(0xdeadbeef);
1000 ret
= pGetDateFormatEx(localeW
, DATE_LONGDATE
, NULL
,
1001 input
, buffer
, COUNTOF(buffer
), NULL
);
1002 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
1003 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
1006 STRINGSW("",""); /* NULL buffer, len > 0 */
1007 SetLastError(0xdeadbeef);
1008 ret
= pGetDateFormatEx(localeW
, 0, NULL
, input
, NULL
, COUNTOF(buffer
), NULL
);
1009 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1010 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1012 STRINGSW("",""); /* NULL buffer, len == 0 */
1013 ret
= pGetDateFormatEx(localeW
, 0, NULL
, input
, NULL
, 0, NULL
);
1014 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1015 EXPECT_LENW
; EXPECT_EQW
;
1017 STRINGSW("",""); /* Invalid flag combination */
1018 SetLastError(0xdeadbeef);
1019 ret
= pGetDateFormatEx(localeW
, DATE_LONGDATE
|DATE_SHORTDATE
, NULL
,
1020 input
, NULL
, 0, NULL
);
1021 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
1022 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
1025 curtime
.wYear
= 2002;
1026 curtime
.wMonth
= 10;
1028 curtime
.wDayOfWeek
= 45612; /* Should be 3 - Wednesday */
1029 curtime
.wHour
= 65432; /* Invalid */
1030 curtime
.wMinute
= 34512; /* Invalid */
1031 curtime
.wSecond
= 65535; /* Invalid */
1032 curtime
.wMilliseconds
= 12345;
1033 STRINGSW("dddd d MMMM yyyy","Wednesday 23 October 2002"); /* Incorrect DOW and time */
1034 ret
= pGetDateFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
), NULL
);
1035 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1036 EXPECT_LENW
; EXPECT_EQW
;
1038 curtime
.wYear
= 2002;
1039 curtime
.wMonth
= 10;
1041 curtime
.wDayOfWeek
= 45612; /* Should be 3 - Wednesday */
1042 curtime
.wHour
= 65432; /* Invalid */
1043 curtime
.wMinute
= 34512; /* Invalid */
1044 curtime
.wSecond
= 65535; /* Invalid */
1045 curtime
.wMilliseconds
= 12345;
1046 STRINGSW("dddd d MMMM yyyy","Wednesday 23 October 2002");
1047 ret
= pGetDateFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
), emptyW
); /* Use reserved arg */
1048 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1049 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1053 curtime
.wYear
= 1601;
1056 curtime
.wDayOfWeek
= 0; /* Irrelevant */
1058 curtime
.wMinute
= 0;
1059 curtime
.wSecond
= 0;
1060 curtime
.wMilliseconds
= 0;
1061 STRINGSW("dddd d MMMM yyyy","Monday 1 January 1601");
1062 SetLastError(0xdeadbeef);
1063 ret
= pGetDateFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
), NULL
);
1064 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1065 EXPECT_LENW
; EXPECT_EQW
;
1067 curtime
.wYear
= 1600;
1068 curtime
.wMonth
= 12;
1070 curtime
.wDayOfWeek
= 0; /* Irrelevant */
1072 curtime
.wMinute
= 59;
1073 curtime
.wSecond
= 59;
1074 curtime
.wMilliseconds
= 999;
1075 STRINGSW("dddd d MMMM yyyy","Friday 31 December 1600");
1076 SetLastError(0xdeadbeef);
1077 ret
= pGetDateFormatEx(localeW
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
), NULL
);
1078 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1079 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1082 static void test_GetDateFormatW(void)
1086 WCHAR buffer
[BUFFER_SIZE
], input
[BUFFER_SIZE
], Expected
[BUFFER_SIZE
];
1087 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
1089 STRINGSW("",""); /* If flags is not zero then format must be NULL */
1090 ret
= GetDateFormatW(LOCALE_SYSTEM_DEFAULT
, DATE_LONGDATE
, NULL
,
1091 input
, buffer
, COUNTOF(buffer
));
1092 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
1094 win_skip("GetDateFormatW is not implemented\n");
1097 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
1098 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
1101 STRINGSW("",""); /* NULL buffer, len > 0 */
1102 SetLastError(0xdeadbeef);
1103 ret
= GetDateFormatW (lcid
, 0, NULL
, input
, NULL
, COUNTOF(buffer
));
1104 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1105 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1107 STRINGSW("",""); /* NULL buffer, len == 0 */
1108 ret
= GetDateFormatW (lcid
, 0, NULL
, input
, NULL
, 0);
1109 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1110 EXPECT_LENW
; EXPECT_EQW
;
1112 curtime
.wYear
= 2002;
1113 curtime
.wMonth
= 10;
1115 curtime
.wDayOfWeek
= 45612; /* Should be 3 - Wednesday */
1116 curtime
.wHour
= 65432; /* Invalid */
1117 curtime
.wMinute
= 34512; /* Invalid */
1118 curtime
.wSecond
= 65535; /* Invalid */
1119 curtime
.wMilliseconds
= 12345;
1120 STRINGSW("dddd d MMMM yyyy","Wednesday 23 October 2002"); /* Incorrect DOW and time */
1121 ret
= GetDateFormatW (lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
1122 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1123 EXPECT_LENW
; EXPECT_EQW
;
1127 curtime
.wYear
= 1601;
1130 curtime
.wDayOfWeek
= 0; /* Irrelevant */
1132 curtime
.wMinute
= 0;
1133 curtime
.wSecond
= 0;
1134 curtime
.wMilliseconds
= 0;
1135 STRINGSW("dddd d MMMM yyyy","Monday 1 January 1601");
1136 SetLastError(0xdeadbeef);
1137 ret
= GetDateFormatW (lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
1138 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1139 EXPECT_LENW
; EXPECT_EQW
;
1141 curtime
.wYear
= 1600;
1142 curtime
.wMonth
= 12;
1144 curtime
.wDayOfWeek
= 0; /* Irrelevant */
1146 curtime
.wMinute
= 59;
1147 curtime
.wSecond
= 59;
1148 curtime
.wMilliseconds
= 999;
1149 STRINGSW("dddd d MMMM yyyy","Friday 31 December 1600");
1150 SetLastError(0xdeadbeef);
1151 ret
= GetDateFormatW (lcid
, 0, &curtime
, input
, buffer
, COUNTOF(buffer
));
1152 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1153 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1157 #define CY_POS_LEFT 0
1158 #define CY_POS_RIGHT 1
1159 #define CY_POS_LEFT_SPACE 2
1160 #define CY_POS_RIGHT_SPACE 3
1162 static void test_GetCurrencyFormatA(void)
1164 static char szDot
[] = { '.', '\0' };
1165 static char szComma
[] = { ',', '\0' };
1166 static char szDollar
[] = { '$', '\0' };
1168 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
1169 char buffer
[BUFFER_SIZE
], Expected
[BUFFER_SIZE
], input
[BUFFER_SIZE
];
1170 CURRENCYFMTA format
;
1172 memset(&format
, 0, sizeof(format
));
1174 STRINGSA("23",""); /* NULL output, length > 0 --> Error */
1175 SetLastError(0xdeadbeef);
1176 ret
= GetCurrencyFormatA(lcid
, 0, input
, NULL
, NULL
, COUNTOF(buffer
));
1177 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1178 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1180 STRINGSA("23,53",""); /* Invalid character --> Error */
1181 SetLastError(0xdeadbeef);
1182 ret
= GetCurrencyFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
1183 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1184 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1186 STRINGSA("--",""); /* Double '-' --> Error */
1187 SetLastError(0xdeadbeef);
1188 ret
= GetCurrencyFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
1189 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1190 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1192 STRINGSA("0-",""); /* Trailing '-' --> Error */
1193 SetLastError(0xdeadbeef);
1194 ret
= GetCurrencyFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
1195 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1196 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1198 STRINGSA("0..",""); /* Double '.' --> Error */
1199 SetLastError(0xdeadbeef);
1200 ret
= GetCurrencyFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
1201 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1202 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1204 STRINGSA(" 0.1",""); /* Leading space --> Error */
1205 SetLastError(0xdeadbeef);
1206 ret
= GetCurrencyFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
1207 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1208 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1210 STRINGSA("1234","$"); /* Length too small --> Write up to length chars */
1211 SetLastError(0xdeadbeef);
1212 ret
= GetCurrencyFormatA(lcid
, NUO
, input
, NULL
, buffer
, 2);
1213 ok( !ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1214 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1216 STRINGSA("2353",""); /* Format and flags given --> Error */
1217 SetLastError(0xdeadbeef);
1218 ret
= GetCurrencyFormatA(lcid
, NUO
, input
, &format
, buffer
, COUNTOF(buffer
));
1219 ok( !ret
, "Expected ret == 0, got %d\n", ret
);
1220 ok( GetLastError() == ERROR_INVALID_FLAGS
|| GetLastError() == ERROR_INVALID_PARAMETER
,
1221 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
1223 STRINGSA("2353",""); /* Invalid format --> Error */
1224 SetLastError(0xdeadbeef);
1225 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1226 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1227 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1229 STRINGSA("2353","$2,353.00"); /* Valid number */
1230 ret
= GetCurrencyFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
1231 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1232 EXPECT_LENA
; EXPECT_EQA
;
1234 STRINGSA("-2353","($2,353.00)"); /* Valid negative number */
1235 ret
= GetCurrencyFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
1236 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1237 EXPECT_LENA
; EXPECT_EQA
;
1239 STRINGSA("2353.1","$2,353.10"); /* Valid real number */
1240 ret
= GetCurrencyFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
1241 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1242 EXPECT_LENA
; EXPECT_EQA
;
1244 STRINGSA("2353.111","$2,353.11"); /* Too many DP --> Truncated */
1245 ret
= GetCurrencyFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
1246 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1247 EXPECT_LENA
; EXPECT_EQA
;
1249 STRINGSA("2353.119","$2,353.12"); /* Too many DP --> Rounded */
1250 ret
= GetCurrencyFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
1251 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1252 EXPECT_LENA
; EXPECT_EQA
;
1254 format
.NumDigits
= 0; /* No decimal separator */
1255 format
.LeadingZero
= 0;
1256 format
.Grouping
= 0; /* No grouping char */
1257 format
.NegativeOrder
= 0;
1258 format
.PositiveOrder
= CY_POS_LEFT
;
1259 format
.lpDecimalSep
= szDot
;
1260 format
.lpThousandSep
= szComma
;
1261 format
.lpCurrencySymbol
= szDollar
;
1263 STRINGSA("2353","$2353"); /* No decimal or grouping chars expected */
1264 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1265 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1266 EXPECT_LENA
; EXPECT_EQA
;
1268 format
.NumDigits
= 1; /* 1 DP --> Expect decimal separator */
1269 STRINGSA("2353","$2353.0");
1270 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1271 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1272 EXPECT_LENA
; EXPECT_EQA
;
1274 format
.Grouping
= 2; /* Group by 100's */
1275 STRINGSA("2353","$23,53.0");
1276 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1277 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1278 EXPECT_LENA
; EXPECT_EQA
;
1280 STRINGSA("235","$235.0"); /* Grouping of a positive number */
1281 format
.Grouping
= 3;
1282 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1283 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1284 EXPECT_LENA
; EXPECT_EQA
;
1286 STRINGSA("-235","$-235.0"); /* Grouping of a negative number */
1287 format
.NegativeOrder
= 2;
1288 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1289 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1290 EXPECT_LENA
; EXPECT_EQA
;
1292 format
.LeadingZero
= 1; /* Always provide leading zero */
1293 STRINGSA(".5","$0.5");
1294 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1295 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1296 EXPECT_LENA
; EXPECT_EQA
;
1298 format
.PositiveOrder
= CY_POS_RIGHT
;
1299 STRINGSA("1","1.0$");
1300 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1301 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1302 EXPECT_LENA
; EXPECT_EQA
;
1304 format
.PositiveOrder
= CY_POS_LEFT_SPACE
;
1305 STRINGSA("1","$ 1.0");
1306 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1307 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1308 EXPECT_LENA
; EXPECT_EQA
;
1310 format
.PositiveOrder
= CY_POS_RIGHT_SPACE
;
1311 STRINGSA("1","1.0 $");
1312 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1313 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1314 EXPECT_LENA
; EXPECT_EQA
;
1316 format
.NegativeOrder
= 0;
1317 STRINGSA("-1","($1.0)");
1318 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1319 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1320 EXPECT_LENA
; EXPECT_EQA
;
1322 format
.NegativeOrder
= 1;
1323 STRINGSA("-1","-$1.0");
1324 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1325 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1326 EXPECT_LENA
; EXPECT_EQA
;
1328 format
.NegativeOrder
= 2;
1329 STRINGSA("-1","$-1.0");
1330 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1331 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1332 EXPECT_LENA
; EXPECT_EQA
;
1334 format
.NegativeOrder
= 3;
1335 STRINGSA("-1","$1.0-");
1336 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1337 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1338 EXPECT_LENA
; EXPECT_EQA
;
1340 format
.NegativeOrder
= 4;
1341 STRINGSA("-1","(1.0$)");
1342 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1343 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1344 EXPECT_LENA
; EXPECT_EQA
;
1346 format
.NegativeOrder
= 5;
1347 STRINGSA("-1","-1.0$");
1348 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1349 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1350 EXPECT_LENA
; EXPECT_EQA
;
1352 format
.NegativeOrder
= 6;
1353 STRINGSA("-1","1.0-$");
1354 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1355 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1356 EXPECT_LENA
; EXPECT_EQA
;
1358 format
.NegativeOrder
= 7;
1359 STRINGSA("-1","1.0$-");
1360 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1361 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1362 EXPECT_LENA
; EXPECT_EQA
;
1364 format
.NegativeOrder
= 8;
1365 STRINGSA("-1","-1.0 $");
1366 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1367 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1368 EXPECT_LENA
; EXPECT_EQA
;
1370 format
.NegativeOrder
= 9;
1371 STRINGSA("-1","-$ 1.0");
1372 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1373 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1374 EXPECT_LENA
; EXPECT_EQA
;
1376 format
.NegativeOrder
= 10;
1377 STRINGSA("-1","1.0 $-");
1378 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1379 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1380 EXPECT_LENA
; EXPECT_EQA
;
1382 format
.NegativeOrder
= 11;
1383 STRINGSA("-1","$ 1.0-");
1384 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1385 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1386 EXPECT_LENA
; EXPECT_EQA
;
1388 format
.NegativeOrder
= 12;
1389 STRINGSA("-1","$ -1.0");
1390 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1391 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1392 EXPECT_LENA
; EXPECT_EQA
;
1394 format
.NegativeOrder
= 13;
1395 STRINGSA("-1","1.0- $");
1396 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1397 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1398 EXPECT_LENA
; EXPECT_EQA
;
1400 format
.NegativeOrder
= 14;
1401 STRINGSA("-1","($ 1.0)");
1402 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1403 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1404 EXPECT_LENA
; EXPECT_EQA
;
1406 format
.NegativeOrder
= 15;
1407 STRINGSA("-1","(1.0 $)");
1408 ret
= GetCurrencyFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1409 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1410 EXPECT_LENA
; EXPECT_EQA
;
1413 #define NEG_PARENS 0 /* "(1.1)" */
1414 #define NEG_LEFT 1 /* "-1.1" */
1415 #define NEG_LEFT_SPACE 2 /* "- 1.1" */
1416 #define NEG_RIGHT 3 /* "1.1-" */
1417 #define NEG_RIGHT_SPACE 4 /* "1.1 -" */
1419 static void test_GetNumberFormatA(void)
1421 static char szDot
[] = { '.', '\0' };
1422 static char szComma
[] = { ',', '\0' };
1424 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
1425 char buffer
[BUFFER_SIZE
], Expected
[BUFFER_SIZE
], input
[BUFFER_SIZE
];
1428 memset(&format
, 0, sizeof(format
));
1430 STRINGSA("23",""); /* NULL output, length > 0 --> Error */
1431 SetLastError(0xdeadbeef);
1432 ret
= GetNumberFormatA(lcid
, 0, input
, NULL
, NULL
, COUNTOF(buffer
));
1433 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1434 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1436 STRINGSA("23,53",""); /* Invalid character --> Error */
1437 SetLastError(0xdeadbeef);
1438 ret
= GetNumberFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
1439 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1440 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1442 STRINGSA("--",""); /* Double '-' --> Error */
1443 SetLastError(0xdeadbeef);
1444 ret
= GetNumberFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
1445 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1446 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1448 STRINGSA("0-",""); /* Trailing '-' --> Error */
1449 SetLastError(0xdeadbeef);
1450 ret
= GetNumberFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
1451 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1452 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1454 STRINGSA("0..",""); /* Double '.' --> Error */
1455 SetLastError(0xdeadbeef);
1456 ret
= GetNumberFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
1457 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1458 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1460 STRINGSA(" 0.1",""); /* Leading space --> Error */
1461 SetLastError(0xdeadbeef);
1462 ret
= GetNumberFormatA(lcid
, 0, input
, NULL
, buffer
, COUNTOF(buffer
));
1463 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1464 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1466 STRINGSA("1234","1"); /* Length too small --> Write up to length chars */
1467 SetLastError(0xdeadbeef);
1468 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, 2);
1469 ok( !ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1470 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1472 STRINGSA("2353",""); /* Format and flags given --> Error */
1473 SetLastError(0xdeadbeef);
1474 ret
= GetNumberFormatA(lcid
, NUO
, input
, &format
, buffer
, COUNTOF(buffer
));
1475 ok( !ret
, "Expected ret == 0, got %d\n", ret
);
1476 ok( GetLastError() == ERROR_INVALID_FLAGS
|| GetLastError() == ERROR_INVALID_PARAMETER
,
1477 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
1479 STRINGSA("2353",""); /* Invalid format --> Error */
1480 SetLastError(0xdeadbeef);
1481 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1482 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1483 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1485 STRINGSA("2353","2,353.00"); /* Valid number */
1486 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
1487 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1488 EXPECT_LENA
; EXPECT_EQA
;
1490 STRINGSA("-2353","-2,353.00"); /* Valid negative number */
1491 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
1492 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1493 EXPECT_LENA
; EXPECT_EQA
;
1495 STRINGSA("-353","-353.00"); /* test for off by one error in grouping */
1496 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
1497 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1498 EXPECT_LENA
; EXPECT_EQA
;
1500 STRINGSA("2353.1","2,353.10"); /* Valid real number */
1501 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
1502 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1503 EXPECT_LENA
; EXPECT_EQA
;
1505 STRINGSA("2353.111","2,353.11"); /* Too many DP --> Truncated */
1506 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
1507 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1508 EXPECT_LENA
; EXPECT_EQA
;
1510 STRINGSA("2353.119","2,353.12"); /* Too many DP --> Rounded */
1511 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
1512 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1513 EXPECT_LENA
; EXPECT_EQA
;
1515 format
.NumDigits
= 0; /* No decimal separator */
1516 format
.LeadingZero
= 0;
1517 format
.Grouping
= 0; /* No grouping char */
1518 format
.NegativeOrder
= 0;
1519 format
.lpDecimalSep
= szDot
;
1520 format
.lpThousandSep
= szComma
;
1522 STRINGSA("2353","2353"); /* No decimal or grouping chars expected */
1523 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1524 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1525 EXPECT_LENA
; EXPECT_EQA
;
1527 format
.NumDigits
= 1; /* 1 DP --> Expect decimal separator */
1528 STRINGSA("2353","2353.0");
1529 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1530 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1531 EXPECT_LENA
; EXPECT_EQA
;
1533 format
.Grouping
= 2; /* Group by 100's */
1534 STRINGSA("2353","23,53.0");
1535 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1536 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1537 EXPECT_LENA
; EXPECT_EQA
;
1539 STRINGSA("235","235.0"); /* Grouping of a positive number */
1540 format
.Grouping
= 3;
1541 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1542 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1543 EXPECT_LENA
; EXPECT_EQA
;
1545 STRINGSA("-235","-235.0"); /* Grouping of a negative number */
1546 format
.NegativeOrder
= NEG_LEFT
;
1547 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1548 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1549 EXPECT_LENA
; EXPECT_EQA
;
1551 format
.LeadingZero
= 1; /* Always provide leading zero */
1552 STRINGSA(".5","0.5");
1553 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1554 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1555 EXPECT_LENA
; EXPECT_EQA
;
1557 format
.NegativeOrder
= NEG_PARENS
;
1558 STRINGSA("-1","(1.0)");
1559 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1560 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1561 EXPECT_LENA
; EXPECT_EQA
;
1563 format
.NegativeOrder
= NEG_LEFT
;
1564 STRINGSA("-1","-1.0");
1565 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1566 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1567 EXPECT_LENA
; EXPECT_EQA
;
1569 format
.NegativeOrder
= NEG_LEFT_SPACE
;
1570 STRINGSA("-1","- 1.0");
1571 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1572 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1573 EXPECT_LENA
; EXPECT_EQA
;
1575 format
.NegativeOrder
= NEG_RIGHT
;
1576 STRINGSA("-1","1.0-");
1577 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1578 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1579 EXPECT_LENA
; EXPECT_EQA
;
1581 format
.NegativeOrder
= NEG_RIGHT_SPACE
;
1582 STRINGSA("-1","1.0 -");
1583 ret
= GetNumberFormatA(lcid
, 0, input
, &format
, buffer
, COUNTOF(buffer
));
1584 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1585 EXPECT_LENA
; EXPECT_EQA
;
1587 lcid
= MAKELCID(MAKELANGID(LANG_FRENCH
, SUBLANG_DEFAULT
), SORT_DEFAULT
);
1589 if (IsValidLocale(lcid
, 0))
1591 STRINGSA("-12345","-12 345,00"); /* Try French formatting */
1592 Expected
[3] = 160; /* Non breaking space */
1593 ret
= GetNumberFormatA(lcid
, NUO
, input
, NULL
, buffer
, COUNTOF(buffer
));
1594 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
1595 EXPECT_LENA
; EXPECT_EQA
;
1599 struct comparestringa_entry
{
1609 static const struct comparestringa_entry comparestringa_data
[] = {
1610 { LOCALE_SYSTEM_DEFAULT
, 0, "EndDialog", -1, "_Property", -1, CSTR_GREATER_THAN
},
1611 { LOCALE_SYSTEM_DEFAULT
, 0, "osp_vba.sreg0070", -1, "_IEWWBrowserComp", -1, CSTR_GREATER_THAN
},
1612 { LOCALE_SYSTEM_DEFAULT
, 0, "r", -1, "\\", -1, CSTR_GREATER_THAN
},
1613 { LOCALE_SYSTEM_DEFAULT
, 0, "osp_vba.sreg0031", -1, "OriginalDatabase", -1, CSTR_GREATER_THAN
},
1614 { LOCALE_SYSTEM_DEFAULT
, 0, "AAA", -1, "aaa", -1, CSTR_GREATER_THAN
},
1615 { LOCALE_SYSTEM_DEFAULT
, 0, "AAA", -1, "aab", -1, CSTR_LESS_THAN
},
1616 { LOCALE_SYSTEM_DEFAULT
, 0, "AAA", -1, "Aab", -1, CSTR_LESS_THAN
},
1617 { LOCALE_SYSTEM_DEFAULT
, 0, ".AAA", -1, "Aab", -1, CSTR_LESS_THAN
},
1618 { LOCALE_SYSTEM_DEFAULT
, 0, ".AAA", -1, "A.ab", -1, CSTR_LESS_THAN
},
1619 { LOCALE_SYSTEM_DEFAULT
, 0, "aa", -1, "AB", -1, CSTR_LESS_THAN
},
1620 { LOCALE_SYSTEM_DEFAULT
, 0, "aa", -1, "Aab", -1, CSTR_LESS_THAN
},
1621 { LOCALE_SYSTEM_DEFAULT
, 0, "aB", -1, "Aab", -1, CSTR_GREATER_THAN
},
1622 { LOCALE_SYSTEM_DEFAULT
, 0, "Ba", -1, "bab", -1, CSTR_LESS_THAN
},
1623 { LOCALE_SYSTEM_DEFAULT
, 0, "{100}{83}{71}{71}{71}", -1, "Global_DataAccess_JRO", -1, CSTR_LESS_THAN
},
1624 { LOCALE_SYSTEM_DEFAULT
, 0, "a", -1, "{", -1, CSTR_GREATER_THAN
},
1625 { LOCALE_SYSTEM_DEFAULT
, 0, "A", -1, "{", -1, CSTR_GREATER_THAN
},
1626 { LOCALE_SYSTEM_DEFAULT
, 0, "3.5", 0, "4.0", -1, CSTR_LESS_THAN
},
1627 { LOCALE_SYSTEM_DEFAULT
, 0, "3.5", -1, "4.0", -1, CSTR_LESS_THAN
},
1628 { LOCALE_SYSTEM_DEFAULT
, 0, "3.520.4403.2", -1, "4.0.2927.10", -1, CSTR_LESS_THAN
},
1629 /* hyphen and apostrophe are treated differently depending on whether SORT_STRINGSORT specified or not */
1630 { LOCALE_SYSTEM_DEFAULT
, 0, "-o", -1, "/m", -1, CSTR_GREATER_THAN
},
1631 { LOCALE_SYSTEM_DEFAULT
, 0, "/m", -1, "-o", -1, CSTR_LESS_THAN
},
1632 { LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "-o", -1, "/m", -1, CSTR_LESS_THAN
},
1633 { LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "/m", -1, "-o", -1, CSTR_GREATER_THAN
},
1634 { LOCALE_SYSTEM_DEFAULT
, 0, "'o", -1, "/m", -1, CSTR_GREATER_THAN
},
1635 { LOCALE_SYSTEM_DEFAULT
, 0, "/m", -1, "'o", -1, CSTR_LESS_THAN
},
1636 { LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "'o", -1, "/m", -1, CSTR_LESS_THAN
},
1637 { LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "/m", -1, "'o", -1, CSTR_GREATER_THAN
},
1638 { LOCALE_SYSTEM_DEFAULT
, 0, "aLuZkUtZ", 8, "aLuZkUtZ", 9, CSTR_EQUAL
},
1639 { LOCALE_SYSTEM_DEFAULT
, 0, "aLuZkUtZ", 7, "aLuZkUtZ\0A", 10, CSTR_LESS_THAN
}
1642 static void test_CompareStringA(void)
1646 LCID lcid
= MAKELCID(MAKELANGID(LANG_FRENCH
, SUBLANG_DEFAULT
), SORT_DEFAULT
);
1648 for (i
= 0; i
< sizeof(comparestringa_data
)/sizeof(struct comparestringa_entry
); i
++)
1650 const struct comparestringa_entry
*entry
= &comparestringa_data
[i
];
1652 ret
= CompareStringA(entry
->lcid
, entry
->flags
, entry
->first
, entry
->first_len
,
1653 entry
->second
, entry
->second_len
);
1654 ok(ret
== entry
->ret
, "%d: got %d, expected %d\n", i
, ret
, entry
->ret
);
1657 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "Salut", -1, "Salute", -1);
1658 ok (ret
== CSTR_LESS_THAN
, "(Salut/Salute) Expected CSTR_LESS_THAN, got %d\n", ret
);
1660 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "Salut", -1, "SaLuT", -1);
1661 ok (ret
== CSTR_EQUAL
, "(Salut/SaLuT) Expected CSTR_EQUAL, got %d\n", ret
);
1663 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "Salut", -1, "hola", -1);
1664 ok (ret
== CSTR_GREATER_THAN
, "(Salut/hola) Expected CSTR_GREATER_THAN, got %d\n", ret
);
1666 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "haha", -1, "hoho", -1);
1667 ok (ret
== CSTR_LESS_THAN
, "(haha/hoho) Expected CSTR_LESS_THAN, got %d\n", ret
);
1669 lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
1671 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "haha", -1, "hoho", -1);
1672 ok (ret
== CSTR_LESS_THAN
, "(haha/hoho) Expected CSTR_LESS_THAN, got %d\n", ret
);
1674 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "haha", -1, "hoho", 0);
1675 ok (ret
== CSTR_GREATER_THAN
, "(haha/hoho) Expected CSTR_GREATER_THAN, got %d\n", ret
);
1677 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "Salut", 5, "saLuT", -1);
1678 ok (ret
== CSTR_EQUAL
, "(Salut/saLuT) Expected CSTR_EQUAL, got %d\n", ret
);
1680 /* test for CompareStringA flags */
1681 SetLastError(0xdeadbeef);
1682 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0x8, "NULL", -1, "NULL", -1);
1683 ok(GetLastError() == ERROR_INVALID_FLAGS
,
1684 "unexpected error code %d\n", GetLastError());
1685 ok(!ret
, "CompareStringA must fail with invalid flag\n");
1687 SetLastError(0xdeadbeef);
1688 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, LOCALE_USE_CP_ACP
, "NULL", -1, "NULL", -1);
1689 ok(GetLastError() == 0xdeadbeef, "unexpected error code %d\n", GetLastError());
1690 ok(ret
== CSTR_EQUAL
, "CompareStringA error: %d != CSTR_EQUAL\n", ret
);
1691 /* end of test for CompareStringA flags */
1693 ret
= lstrcmpA("", "");
1694 ok (ret
== 0, "lstrcmpA(\"\", \"\") should return 0, got %d\n", ret
);
1696 ret
= lstrcmpA(NULL
, NULL
);
1697 ok (ret
== 0 || broken(ret
== -2) /* win9x */, "lstrcmpA(NULL, NULL) should return 0, got %d\n", ret
);
1699 ret
= lstrcmpA("", NULL
);
1700 ok (ret
== 1 || broken(ret
== -2) /* win9x */, "lstrcmpA(\"\", NULL) should return 1, got %d\n", ret
);
1702 ret
= lstrcmpA(NULL
, "");
1703 ok (ret
== -1 || broken(ret
== -2) /* win9x */, "lstrcmpA(NULL, \"\") should return -1, got %d\n", ret
);
1706 if (0) { /* this requires collation table patch to make it MS compatible */
1707 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "'o", -1, "-o", -1 );
1708 ok(ret
== CSTR_LESS_THAN
, "'o vs -o expected CSTR_LESS_THAN, got %d\n", ret
);
1710 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "'o", -1, "-o", -1 );
1711 ok(ret
== CSTR_LESS_THAN
, "'o vs -o expected CSTR_LESS_THAN, got %d\n", ret
);
1713 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "'", -1, "-", -1 );
1714 ok(ret
== CSTR_LESS_THAN
, "' vs - expected CSTR_LESS_THAN, got %d\n", ret
);
1716 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "'", -1, "-", -1 );
1717 ok(ret
== CSTR_LESS_THAN
, "' vs - expected CSTR_LESS_THAN, got %d\n", ret
);
1719 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "`o", -1, "/m", -1 );
1720 ok(ret
== CSTR_GREATER_THAN
, "`o vs /m CSTR_GREATER_THAN got %d\n", ret
);
1722 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "/m", -1, "`o", -1 );
1723 ok(ret
== CSTR_LESS_THAN
, "/m vs `o expected CSTR_LESS_THAN, got %d\n", ret
);
1725 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "`o", -1, "/m", -1 );
1726 ok(ret
== CSTR_GREATER_THAN
, "`o vs /m CSTR_GREATER_THAN got %d\n", ret
);
1728 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "/m", -1, "`o", -1 );
1729 ok(ret
== CSTR_LESS_THAN
, "/m vs `o expected CSTR_LESS_THAN, got %d\n", ret
);
1731 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "`o", -1, "-m", -1 );
1732 ok(ret
== CSTR_LESS_THAN
, "`o vs -m expected CSTR_LESS_THAN, got %d\n", ret
);
1734 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0, "-m", -1, "`o", -1 );
1735 ok(ret
== CSTR_GREATER_THAN
, "-m vs `o CSTR_GREATER_THAN got %d\n", ret
);
1737 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "`o", -1, "-m", -1 );
1738 ok(ret
== CSTR_GREATER_THAN
, "`o vs -m CSTR_GREATER_THAN got %d\n", ret
);
1740 ret
= CompareStringA(LOCALE_SYSTEM_DEFAULT
, SORT_STRINGSORT
, "-m", -1, "`o", -1 );
1741 ok(ret
== CSTR_LESS_THAN
, "-m vs `o expected CSTR_LESS_THAN, got %d\n", ret
);
1745 /* WinXP handles embedded NULLs differently than earlier versions */
1746 ret
= CompareStringA(LOCALE_USER_DEFAULT
, 0, "aLuZkUtZ", 8, "aLuZkUtZ\0A", 10);
1747 ok(ret
== CSTR_LESS_THAN
|| ret
== CSTR_EQUAL
, "aLuZkUtZ vs aLuZkUtZ\\0A expected CSTR_LESS_THAN or CSTR_EQUAL, got %d\n", ret
);
1749 ret
= CompareStringA(LOCALE_USER_DEFAULT
, 0, "aLu\0ZkUtZ", 8, "aLu\0ZkUtZ\0A", 10);
1750 ok(ret
== CSTR_LESS_THAN
|| ret
== CSTR_EQUAL
, "aLu\\0ZkUtZ vs aLu\\0ZkUtZ\\0A expected CSTR_LESS_THAN or CSTR_EQUAL, got %d\n", ret
);
1752 ret
= CompareStringA(lcid
, 0, "a\0b", -1, "a", -1);
1753 ok(ret
== CSTR_EQUAL
, "a vs a expected CSTR_EQUAL, got %d\n", ret
);
1755 ret
= CompareStringA(lcid
, 0, "a\0b", 4, "a", 2);
1756 ok(ret
== CSTR_EQUAL
|| /* win2k */
1757 ret
== CSTR_GREATER_THAN
,
1758 "a\\0b vs a expected CSTR_EQUAL or CSTR_GREATER_THAN, got %d\n", ret
);
1760 ret
= CompareStringA(lcid
, 0, "\2", 2, "\1", 2);
1761 todo_wine
ok(ret
!= CSTR_EQUAL
, "\\2 vs \\1 expected unequal\n");
1763 ret
= CompareStringA(lcid
, NORM_IGNORECASE
| LOCALE_USE_CP_ACP
, "#", -1, ".", -1);
1764 todo_wine
ok(ret
== CSTR_LESS_THAN
, "\"#\" vs \".\" expected CSTR_LESS_THAN, got %d\n", ret
);
1766 ret
= CompareStringA(lcid
, NORM_IGNORECASE
, "_", -1, ".", -1);
1767 todo_wine
ok(ret
== CSTR_GREATER_THAN
, "\"_\" vs \".\" expected CSTR_GREATER_THAN, got %d\n", ret
);
1769 ret
= lstrcmpiA("#", ".");
1770 todo_wine
ok(ret
== -1, "\"#\" vs \".\" expected -1, got %d\n", ret
);
1772 lcid
= MAKELCID(MAKELANGID(LANG_POLISH
, SUBLANG_DEFAULT
), SORT_DEFAULT
);
1774 /* \xB9 character lies between a and b */
1775 ret
= CompareStringA(lcid
, 0, "a", 1, "\xB9", 1);
1776 todo_wine
ok(ret
== CSTR_LESS_THAN
, "\'\\xB9\' character should be greater than \'a\'\n");
1777 ret
= CompareStringA(lcid
, 0, "\xB9", 1, "b", 1);
1778 ok(ret
== CSTR_LESS_THAN
, "\'\\xB9\' character should be smaller than \'b\'\n");
1780 memset(a
, 'a', sizeof(a
));
1781 SetLastError(0xdeadbeef);
1782 ret
= CompareStringA(lcid
, 0, a
, sizeof(a
), a
, sizeof(a
));
1783 ok (GetLastError() == 0xdeadbeef && ret
== CSTR_EQUAL
,
1784 "ret %d, error %d, expected value %d\n", ret
, GetLastError(), CSTR_EQUAL
);
1787 struct comparestringex_test
{
1790 const WCHAR first
[2];
1791 const WCHAR second
[2];
1797 static const struct comparestringex_test comparestringex_tests
[] = {
1798 /* default behavior */
1801 {'i',0}, {'I',0}, CSTR_LESS_THAN
, -1, FALSE
1805 {'i',0}, {0x130,0}, CSTR_LESS_THAN
, -1, FALSE
1809 {'i',0}, {0x131,0}, CSTR_LESS_THAN
, -1, FALSE
1813 {'I',0}, {0x130,0}, CSTR_LESS_THAN
, -1, TRUE
1817 {'I',0}, {0x131,0}, CSTR_LESS_THAN
, -1, FALSE
1821 {0x130,0}, {0x131,0}, CSTR_GREATER_THAN
, -1, TRUE
1823 /* with NORM_IGNORECASE */
1825 "tr-TR", NORM_IGNORECASE
,
1826 {'i',0}, {'I',0}, CSTR_EQUAL
, -1, FALSE
1829 "tr-TR", NORM_IGNORECASE
,
1830 {'i',0}, {0x130,0}, CSTR_LESS_THAN
, -1, TRUE
1833 "tr-TR", NORM_IGNORECASE
,
1834 {'i',0}, {0x131,0}, CSTR_LESS_THAN
, -1, FALSE
1837 "tr-TR", NORM_IGNORECASE
,
1838 {'I',0}, {0x130,0}, CSTR_LESS_THAN
, -1, TRUE
1841 "tr-TR", NORM_IGNORECASE
,
1842 {'I',0}, {0x131,0}, CSTR_LESS_THAN
, -1, FALSE
1845 "tr-TR", NORM_IGNORECASE
,
1846 {0x130,0}, {0x131,0}, CSTR_GREATER_THAN
, -1, TRUE
1848 /* with NORM_LINGUISTIC_CASING */
1850 "tr-TR", NORM_LINGUISTIC_CASING
,
1851 {'i',0}, {'I',0}, CSTR_GREATER_THAN
, CSTR_LESS_THAN
, TRUE
1854 "tr-TR", NORM_LINGUISTIC_CASING
,
1855 {'i',0}, {0x130,0}, CSTR_LESS_THAN
, -1, FALSE
1858 "tr-TR", NORM_LINGUISTIC_CASING
,
1859 {'i',0}, {0x131,0}, CSTR_GREATER_THAN
, CSTR_LESS_THAN
, TRUE
1862 "tr-TR", NORM_LINGUISTIC_CASING
,
1863 {'I',0}, {0x130,0}, CSTR_LESS_THAN
, -1, TRUE
1866 "tr-TR", NORM_LINGUISTIC_CASING
,
1867 {'I',0}, {0x131,0}, CSTR_GREATER_THAN
, CSTR_LESS_THAN
, TRUE
1870 "tr-TR", NORM_LINGUISTIC_CASING
,
1871 {0x130,0}, {0x131,0}, CSTR_GREATER_THAN
, -1, TRUE
1873 /* with LINGUISTIC_IGNORECASE */
1875 "tr-TR", LINGUISTIC_IGNORECASE
,
1876 {'i',0}, {'I',0}, CSTR_EQUAL
, -1, TRUE
1879 "tr-TR", LINGUISTIC_IGNORECASE
,
1880 {'i',0}, {0x130,0}, CSTR_LESS_THAN
, -1, FALSE
1883 "tr-TR", LINGUISTIC_IGNORECASE
,
1884 {'i',0}, {0x131,0}, CSTR_LESS_THAN
, -1, FALSE
1887 "tr-TR", LINGUISTIC_IGNORECASE
,
1888 {'I',0}, {0x130,0}, CSTR_LESS_THAN
, -1, TRUE
1891 "tr-TR", LINGUISTIC_IGNORECASE
,
1892 {'I',0}, {0x131,0}, CSTR_LESS_THAN
, -1, FALSE
1895 "tr-TR", LINGUISTIC_IGNORECASE
,
1896 {0x130,0}, {0x131,0}, CSTR_GREATER_THAN
, -1, TRUE
1898 /* with NORM_LINGUISTIC_CASING | NORM_IGNORECASE */
1900 "tr-TR", NORM_LINGUISTIC_CASING
| NORM_IGNORECASE
,
1901 {'i',0}, {'I',0}, CSTR_GREATER_THAN
, CSTR_EQUAL
, TRUE
1904 "tr-TR", NORM_LINGUISTIC_CASING
| NORM_IGNORECASE
,
1905 {'i',0}, {0x130,0}, CSTR_EQUAL
, CSTR_LESS_THAN
, FALSE
1908 "tr-TR", NORM_LINGUISTIC_CASING
| NORM_IGNORECASE
,
1909 {'i',0}, {0x131,0}, CSTR_GREATER_THAN
, CSTR_LESS_THAN
, TRUE
1912 "tr-TR", NORM_LINGUISTIC_CASING
| NORM_IGNORECASE
,
1913 {'I',0}, {0x130,0}, CSTR_LESS_THAN
, -1, TRUE
1916 "tr-TR", NORM_LINGUISTIC_CASING
| NORM_IGNORECASE
,
1917 {'I',0}, {0x131,0}, CSTR_EQUAL
, CSTR_LESS_THAN
, TRUE
1920 "tr-TR", NORM_LINGUISTIC_CASING
| NORM_IGNORECASE
,
1921 {0x130,0}, {0x131,0}, CSTR_GREATER_THAN
, -1, TRUE
1923 /* with NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE */
1925 "tr-TR", NORM_LINGUISTIC_CASING
| LINGUISTIC_IGNORECASE
,
1926 {'i',0}, {'I',0}, CSTR_GREATER_THAN
, CSTR_EQUAL
, TRUE
1929 "tr-TR", NORM_LINGUISTIC_CASING
| LINGUISTIC_IGNORECASE
,
1930 {'i',0}, {0x130,0}, CSTR_EQUAL
, CSTR_LESS_THAN
, TRUE
1933 "tr-TR", NORM_LINGUISTIC_CASING
| LINGUISTIC_IGNORECASE
,
1934 {'i',0}, {0x131,0}, CSTR_GREATER_THAN
, CSTR_LESS_THAN
, TRUE
1937 "tr-TR", NORM_LINGUISTIC_CASING
| LINGUISTIC_IGNORECASE
,
1938 {'I',0}, {0x130,0}, CSTR_LESS_THAN
, -1, TRUE
1941 "tr-TR", NORM_LINGUISTIC_CASING
| LINGUISTIC_IGNORECASE
,
1942 {'I',0}, {0x131,0}, CSTR_EQUAL
, CSTR_LESS_THAN
, TRUE
1945 "tr-TR", NORM_LINGUISTIC_CASING
| LINGUISTIC_IGNORECASE
,
1946 {0x130,0}, {0x131,0}, CSTR_GREATER_THAN
, CSTR_LESS_THAN
, TRUE
1950 static void test_CompareStringEx(void)
1952 const char *op
[] = {"ERROR", "CSTR_LESS_THAN", "CSTR_EQUAL", "CSTR_GREATER_THAN"};
1956 /* CompareStringEx is only available on Vista+ */
1957 if (!pCompareStringEx
)
1959 win_skip("CompareStringEx not supported\n");
1963 for (i
= 0; i
< sizeof(comparestringex_tests
)/sizeof(comparestringex_tests
[0]); i
++)
1965 const struct comparestringex_test
*e
= &comparestringex_tests
[i
];
1967 MultiByteToWideChar(CP_ACP
, 0, e
->locale
, -1, locale
, sizeof(locale
)/sizeof(WCHAR
));
1968 ret
= pCompareStringEx(locale
, e
->flags
, e
->first
, -1, e
->second
, -1, NULL
, NULL
, 0);
1971 todo_wine
ok(ret
== e
->ret
|| broken(ret
== e
->broken
),
1972 "%d: got %s, expected %s\n", i
, op
[ret
], op
[e
->ret
]);
1976 ok(ret
== e
->ret
|| broken(ret
== e
->broken
),
1977 "%d: got %s, expected %s\n", i
, op
[ret
], op
[e
->ret
]);
1983 static void test_LCMapStringA(void)
1986 char buf
[256], buf2
[256];
1987 static const char upper_case
[] = "\tJUST! A, TEST; STRING 1/*+-.\r\n";
1988 static const char lower_case
[] = "\tjust! a, test; string 1/*+-.\r\n";
1989 static const char symbols_stripped
[] = "justateststring1";
1991 SetLastError(0xdeadbeef);
1992 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LOCALE_USE_CP_ACP
| LCMAP_LOWERCASE
,
1993 lower_case
, -1, buf
, sizeof(buf
));
1994 ok(ret
== lstrlenA(lower_case
) + 1,
1995 "ret %d, error %d, expected value %d\n",
1996 ret
, GetLastError(), lstrlenA(lower_case
) + 1);
1997 ok(!memcmp(buf
, lower_case
, ret
), "LCMapStringA should return %s, but not %s\n", lower_case
, buf
);
1999 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
| LCMAP_UPPERCASE
,
2000 upper_case
, -1, buf
, sizeof(buf
));
2001 ok(!ret
, "LCMAP_LOWERCASE and LCMAP_UPPERCASE are mutually exclusive\n");
2002 ok(GetLastError() == ERROR_INVALID_FLAGS
,
2003 "unexpected error code %d\n", GetLastError());
2005 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_HIRAGANA
| LCMAP_KATAKANA
,
2006 upper_case
, -1, buf
, sizeof(buf
));
2007 ok(!ret
, "LCMAP_HIRAGANA and LCMAP_KATAKANA are mutually exclusive\n");
2008 ok(GetLastError() == ERROR_INVALID_FLAGS
,
2009 "unexpected error code %d\n", GetLastError());
2011 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_HALFWIDTH
| LCMAP_FULLWIDTH
,
2012 upper_case
, -1, buf
, sizeof(buf
));
2013 ok(!ret
, "LCMAP_HALFWIDTH | LCMAP_FULLWIDTH are mutually exclusive\n");
2014 ok(GetLastError() == ERROR_INVALID_FLAGS
,
2015 "unexpected error code %d\n", GetLastError());
2017 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_TRADITIONAL_CHINESE
| LCMAP_SIMPLIFIED_CHINESE
,
2018 upper_case
, -1, buf
, sizeof(buf
));
2019 ok(!ret
, "LCMAP_TRADITIONAL_CHINESE and LCMAP_SIMPLIFIED_CHINESE are mutually exclusive\n");
2020 ok(GetLastError() == ERROR_INVALID_FLAGS
,
2021 "unexpected error code %d\n", GetLastError());
2023 /* SORT_STRINGSORT must be used exclusively with LCMAP_SORTKEY */
2024 SetLastError(0xdeadbeef);
2025 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
| SORT_STRINGSORT
,
2026 upper_case
, -1, buf
, sizeof(buf
));
2027 ok(GetLastError() == ERROR_INVALID_FLAGS
, "expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
2028 ok(!ret
, "SORT_STRINGSORT without LCMAP_SORTKEY must fail\n");
2030 /* test LCMAP_LOWERCASE */
2031 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
,
2032 upper_case
, -1, buf
, sizeof(buf
));
2033 ok(ret
== lstrlenA(upper_case
) + 1,
2034 "ret %d, error %d, expected value %d\n",
2035 ret
, GetLastError(), lstrlenA(upper_case
) + 1);
2036 ok(!lstrcmpA(buf
, lower_case
), "LCMapStringA should return %s, but not %s\n", lower_case
, buf
);
2038 /* test LCMAP_UPPERCASE */
2039 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_UPPERCASE
,
2040 lower_case
, -1, buf
, sizeof(buf
));
2041 ok(ret
== lstrlenA(lower_case
) + 1,
2042 "ret %d, error %d, expected value %d\n",
2043 ret
, GetLastError(), lstrlenA(lower_case
) + 1);
2044 ok(!lstrcmpA(buf
, upper_case
), "LCMapStringA should return %s, but not %s\n", upper_case
, buf
);
2046 /* test buffer overflow */
2047 SetLastError(0xdeadbeef);
2048 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_UPPERCASE
,
2049 lower_case
, -1, buf
, 4);
2050 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
2051 "should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d\n", ret
);
2053 /* LCMAP_UPPERCASE or LCMAP_LOWERCASE should accept src == dst */
2054 lstrcpyA(buf
, lower_case
);
2055 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_UPPERCASE
,
2056 buf
, -1, buf
, sizeof(buf
));
2057 if (!ret
) /* Win9x */
2058 trace("Ignoring LCMapStringA(LCMAP_UPPERCASE, buf, buf) error on Win9x\n");
2061 ok(ret
== lstrlenA(lower_case
) + 1,
2062 "ret %d, error %d, expected value %d\n",
2063 ret
, GetLastError(), lstrlenA(lower_case
) + 1);
2064 ok(!lstrcmpA(buf
, upper_case
), "LCMapStringA should return %s, but not %s\n", upper_case
, buf
);
2066 lstrcpyA(buf
, upper_case
);
2067 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_LOWERCASE
,
2068 buf
, -1, buf
, sizeof(buf
));
2069 if (!ret
) /* Win9x */
2070 trace("Ignoring LCMapStringA(LCMAP_LOWERCASE, buf, buf) error on Win9x\n");
2073 ok(ret
== lstrlenA(upper_case
) + 1,
2074 "ret %d, error %d, expected value %d\n",
2075 ret
, GetLastError(), lstrlenA(lower_case
) + 1);
2076 ok(!lstrcmpA(buf
, lower_case
), "LCMapStringA should return %s, but not %s\n", lower_case
, buf
);
2079 /* otherwise src == dst should fail */
2080 SetLastError(0xdeadbeef);
2081 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
| LCMAP_UPPERCASE
,
2082 buf
, 10, buf
, sizeof(buf
));
2083 ok(GetLastError() == ERROR_INVALID_FLAGS
/* NT */ ||
2084 GetLastError() == ERROR_INVALID_PARAMETER
/* Win9x */,
2085 "unexpected error code %d\n", GetLastError());
2086 ok(!ret
, "src == dst without LCMAP_UPPERCASE or LCMAP_LOWERCASE must fail\n");
2088 /* test whether '\0' is always appended */
2089 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
,
2090 upper_case
, -1, buf
, sizeof(buf
));
2091 ok(ret
, "LCMapStringA must succeed\n");
2092 ok(buf
[ret
-1] == 0, "LCMapStringA not null-terminated\n");
2093 ret2
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
,
2094 upper_case
, lstrlenA(upper_case
), buf2
, sizeof(buf2
));
2095 ok(ret2
, "LCMapStringA must succeed\n");
2096 ok(buf2
[ret2
-1] == 0, "LCMapStringA not null-terminated\n" );
2097 ok(ret
== ret2
, "lengths of sort keys must be equal\n");
2098 ok(!lstrcmpA(buf
, buf2
), "sort keys must be equal\n");
2100 /* test LCMAP_SORTKEY | NORM_IGNORECASE */
2101 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
| NORM_IGNORECASE
,
2102 upper_case
, -1, buf
, sizeof(buf
));
2103 ok(ret
, "LCMapStringA must succeed\n");
2104 ret2
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
,
2105 lower_case
, -1, buf2
, sizeof(buf2
));
2106 ok(ret2
, "LCMapStringA must succeed\n");
2107 ok(ret
== ret2
, "lengths of sort keys must be equal\n");
2108 ok(!lstrcmpA(buf
, buf2
), "sort keys must be equal\n");
2110 /* Don't test LCMAP_SORTKEY | NORM_IGNORENONSPACE, produces different
2111 results from plain LCMAP_SORTKEY on Vista */
2113 /* test LCMAP_SORTKEY | NORM_IGNORESYMBOLS */
2114 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
| NORM_IGNORESYMBOLS
,
2115 lower_case
, -1, buf
, sizeof(buf
));
2116 ok(ret
, "LCMapStringA must succeed\n");
2117 ret2
= LCMapStringA(LOCALE_USER_DEFAULT
, LCMAP_SORTKEY
,
2118 symbols_stripped
, -1, buf2
, sizeof(buf2
));
2119 ok(ret2
, "LCMapStringA must succeed\n");
2120 ok(ret
== ret2
, "lengths of sort keys must be equal\n");
2121 ok(!lstrcmpA(buf
, buf2
), "sort keys must be equal\n");
2123 /* test NORM_IGNORENONSPACE */
2124 lstrcpyA(buf
, "foo");
2125 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, NORM_IGNORENONSPACE
,
2126 lower_case
, -1, buf
, sizeof(buf
));
2127 ok(ret
== lstrlenA(lower_case
) + 1, "LCMapStringA should return %d, ret = %d\n",
2128 lstrlenA(lower_case
) + 1, ret
);
2129 ok(!lstrcmpA(buf
, lower_case
), "LCMapStringA should return %s, but not %s\n", lower_case
, buf
);
2131 /* test NORM_IGNORESYMBOLS */
2132 lstrcpyA(buf
, "foo");
2133 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, NORM_IGNORESYMBOLS
,
2134 lower_case
, -1, buf
, sizeof(buf
));
2135 ok(ret
== lstrlenA(symbols_stripped
) + 1, "LCMapStringA should return %d, ret = %d\n",
2136 lstrlenA(symbols_stripped
) + 1, ret
);
2137 ok(!lstrcmpA(buf
, symbols_stripped
), "LCMapStringA should return %s, but not %s\n", lower_case
, buf
);
2139 /* test srclen = 0 */
2140 SetLastError(0xdeadbeef);
2141 ret
= LCMapStringA(LOCALE_USER_DEFAULT
, 0, upper_case
, 0, buf
, sizeof(buf
));
2142 ok(!ret
, "LCMapStringA should fail with srclen = 0\n");
2143 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
2144 "unexpected error code %d\n", GetLastError());
2147 typedef INT (*lcmapstring_wrapper
)(DWORD
, LPCWSTR
, INT
, LPWSTR
, INT
);
2149 static void test_lcmapstring_unicode(lcmapstring_wrapper func_ptr
, const char *func_name
)
2152 WCHAR buf
[256], buf2
[256];
2153 char *p_buf
= (char *)buf
, *p_buf2
= (char *)buf2
;
2155 ret
= func_ptr(LCMAP_LOWERCASE
| LCMAP_UPPERCASE
,
2156 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
2158 ok(lstrcmpW(buf
, upper_case
) == 0, "Expected upper case string\n");
2161 ok(!ret
, "%s LCMAP_LOWERCASE and LCMAP_UPPERCASE are mutually exclusive\n", func_name
);
2162 ok(GetLastError() == ERROR_INVALID_FLAGS
, "%s unexpected error code %d\n",
2163 func_name
, GetLastError());
2166 ret
= func_ptr(LCMAP_HIRAGANA
| LCMAP_KATAKANA
,
2167 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
2168 ok(!ret
, "%s LCMAP_HIRAGANA and LCMAP_KATAKANA are mutually exclusive\n", func_name
);
2169 ok(GetLastError() == ERROR_INVALID_FLAGS
, "%s unexpected error code %d\n",
2170 func_name
, GetLastError());
2172 ret
= func_ptr(LCMAP_HALFWIDTH
| LCMAP_FULLWIDTH
,
2173 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
2174 ok(!ret
, "%s LCMAP_HALFWIDTH | LCMAP_FULLWIDTH are mutually exclusive\n", func_name
);
2175 ok(GetLastError() == ERROR_INVALID_FLAGS
, "%s unexpected error code %d\n",
2176 func_name
, GetLastError());
2178 ret
= func_ptr(LCMAP_TRADITIONAL_CHINESE
| LCMAP_SIMPLIFIED_CHINESE
,
2179 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
2180 ok(!ret
, "%s LCMAP_TRADITIONAL_CHINESE and LCMAP_SIMPLIFIED_CHINESE are mutually exclusive\n",
2182 ok(GetLastError() == ERROR_INVALID_FLAGS
, "%s unexpected error code %d\n",
2183 func_name
, GetLastError());
2185 /* SORT_STRINGSORT must be used exclusively with LCMAP_SORTKEY */
2186 SetLastError(0xdeadbeef);
2187 ret
= func_ptr(LCMAP_LOWERCASE
| SORT_STRINGSORT
,
2188 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
2189 ok(GetLastError() == ERROR_INVALID_FLAGS
, "%s expected ERROR_INVALID_FLAGS, got %d\n",
2190 func_name
, GetLastError());
2191 ok(!ret
, "%s SORT_STRINGSORT without LCMAP_SORTKEY must fail\n", func_name
);
2193 /* test LCMAP_LOWERCASE */
2194 ret
= func_ptr(LCMAP_LOWERCASE
,
2195 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
2196 ok(ret
== lstrlenW(upper_case
) + 1, "%s ret %d, error %d, expected value %d\n", func_name
,
2197 ret
, GetLastError(), lstrlenW(upper_case
) + 1);
2198 ok(!lstrcmpW(buf
, lower_case
), "%s string compare mismatch\n", func_name
);
2200 /* test LCMAP_UPPERCASE */
2201 ret
= func_ptr(LCMAP_UPPERCASE
,
2202 lower_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
2203 ok(ret
== lstrlenW(lower_case
) + 1, "%s ret %d, error %d, expected value %d\n", func_name
,
2204 ret
, GetLastError(), lstrlenW(lower_case
) + 1);
2205 ok(!lstrcmpW(buf
, upper_case
), "%s string compare mismatch\n", func_name
);
2207 /* test buffer overflow */
2208 SetLastError(0xdeadbeef);
2209 ret
= func_ptr(LCMAP_UPPERCASE
,
2210 lower_case
, -1, buf
, 4);
2211 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
2212 "%s should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d\n", func_name
, ret
);
2214 /* LCMAP_UPPERCASE or LCMAP_LOWERCASE should accept src == dst */
2215 lstrcpyW(buf
, lower_case
);
2216 ret
= func_ptr(LCMAP_UPPERCASE
,
2217 buf
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
2218 ok(ret
== lstrlenW(lower_case
) + 1, "%s ret %d, error %d, expected value %d\n", func_name
,
2219 ret
, GetLastError(), lstrlenW(lower_case
) + 1);
2220 ok(!lstrcmpW(buf
, upper_case
), "%s string compare mismatch\n", func_name
);
2222 lstrcpyW(buf
, upper_case
);
2223 ret
= func_ptr(LCMAP_LOWERCASE
,
2224 buf
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
2225 ok(ret
== lstrlenW(upper_case
) + 1, "%s ret %d, error %d, expected value %d\n", func_name
,
2226 ret
, GetLastError(), lstrlenW(lower_case
) + 1);
2227 ok(!lstrcmpW(buf
, lower_case
), "%s string compare mismatch\n", func_name
);
2229 /* otherwise src == dst should fail */
2230 SetLastError(0xdeadbeef);
2231 ret
= func_ptr(LCMAP_SORTKEY
| LCMAP_UPPERCASE
,
2232 buf
, 10, buf
, sizeof(buf
));
2233 ok(GetLastError() == ERROR_INVALID_FLAGS
/* NT */ ||
2234 GetLastError() == ERROR_INVALID_PARAMETER
/* Win7+ */,
2235 "%s unexpected error code %d\n", func_name
, GetLastError());
2236 ok(!ret
, "%s src == dst without LCMAP_UPPERCASE or LCMAP_LOWERCASE must fail\n", func_name
);
2238 /* test whether '\0' is always appended */
2239 ret
= func_ptr(LCMAP_SORTKEY
,
2240 upper_case
, -1, buf
, sizeof(buf
));
2241 ok(ret
, "%s func_ptr must succeed\n", func_name
);
2242 ret2
= func_ptr(LCMAP_SORTKEY
,
2243 upper_case
, lstrlenW(upper_case
), buf2
, sizeof(buf2
));
2244 ok(ret
, "%s func_ptr must succeed\n", func_name
);
2245 ok(ret
== ret2
, "%s lengths of sort keys must be equal\n", func_name
);
2246 ok(!lstrcmpA(p_buf
, p_buf2
), "%s sort keys must be equal\n", func_name
);
2248 /* test LCMAP_SORTKEY | NORM_IGNORECASE */
2249 ret
= func_ptr(LCMAP_SORTKEY
| NORM_IGNORECASE
,
2250 upper_case
, -1, buf
, sizeof(buf
));
2251 ok(ret
, "%s func_ptr must succeed\n", func_name
);
2252 ret2
= func_ptr(LCMAP_SORTKEY
,
2253 lower_case
, -1, buf2
, sizeof(buf2
));
2254 ok(ret2
, "%s func_ptr must succeed\n", func_name
);
2255 ok(ret
== ret2
, "%s lengths of sort keys must be equal\n", func_name
);
2256 ok(!lstrcmpA(p_buf
, p_buf2
), "%s sort keys must be equal\n", func_name
);
2258 /* Don't test LCMAP_SORTKEY | NORM_IGNORENONSPACE, produces different
2259 results from plain LCMAP_SORTKEY on Vista */
2261 /* test LCMAP_SORTKEY | NORM_IGNORESYMBOLS */
2262 ret
= func_ptr(LCMAP_SORTKEY
| NORM_IGNORESYMBOLS
,
2263 lower_case
, -1, buf
, sizeof(buf
));
2264 ok(ret
, "%s func_ptr must succeed\n", func_name
);
2265 ret2
= func_ptr(LCMAP_SORTKEY
,
2266 symbols_stripped
, -1, buf2
, sizeof(buf2
));
2267 ok(ret2
, "%s func_ptr must succeed\n", func_name
);
2268 ok(ret
== ret2
, "%s lengths of sort keys must be equal\n", func_name
);
2269 ok(!lstrcmpA(p_buf
, p_buf2
), "%s sort keys must be equal\n", func_name
);
2271 /* test NORM_IGNORENONSPACE */
2272 lstrcpyW(buf
, fooW
);
2273 ret
= func_ptr(NORM_IGNORENONSPACE
,
2274 lower_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
2275 ok(ret
== lstrlenW(lower_case
) + 1, "%s func_ptr should return %d, ret = %d\n", func_name
,
2276 lstrlenW(lower_case
) + 1, ret
);
2277 ok(!lstrcmpW(buf
, lower_case
), "%s string comparison mismatch\n", func_name
);
2279 /* test NORM_IGNORESYMBOLS */
2280 lstrcpyW(buf
, fooW
);
2281 ret
= func_ptr(NORM_IGNORESYMBOLS
,
2282 lower_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
2283 ok(ret
== lstrlenW(symbols_stripped
) + 1, "%s func_ptr should return %d, ret = %d\n", func_name
,
2284 lstrlenW(symbols_stripped
) + 1, ret
);
2285 ok(!lstrcmpW(buf
, symbols_stripped
), "%s string comparison mismatch\n", func_name
);
2287 /* test srclen = 0 */
2288 SetLastError(0xdeadbeef);
2289 ret
= func_ptr(0, upper_case
, 0, buf
, sizeof(buf
)/sizeof(WCHAR
));
2290 ok(!ret
, "%s func_ptr should fail with srclen = 0\n", func_name
);
2291 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
2292 "%s unexpected error code %d\n", func_name
, GetLastError());
2295 static INT
LCMapStringW_wrapper(DWORD flags
, LPCWSTR src
, INT srclen
, LPWSTR dst
, INT dstlen
)
2297 return LCMapStringW(LOCALE_USER_DEFAULT
, flags
, src
, srclen
, dst
, dstlen
);
2300 static void test_LCMapStringW(void)
2305 trace("testing LCMapStringW\n");
2307 SetLastError(0xdeadbeef);
2308 ret
= LCMapStringW((LCID
)-1, LCMAP_LOWERCASE
, upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
2310 ok(!ret
, "LCMapStringW should fail with bad lcid\n");
2311 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "unexpected error code %d\n", GetLastError());
2314 test_lcmapstring_unicode(LCMapStringW_wrapper
, "LCMapStringW:");
2317 static INT
LCMapStringEx_wrapper(DWORD flags
, LPCWSTR src
, INT srclen
, LPWSTR dst
, INT dstlen
)
2319 return pLCMapStringEx(LOCALE_NAME_USER_DEFAULT
, flags
, src
, srclen
, dst
, dstlen
, NULL
, NULL
, 0);
2322 static void test_LCMapStringEx(void)
2327 if (!pLCMapStringEx
)
2329 win_skip( "LCMapStringEx not available\n" );
2333 trace("testing LCMapStringEx\n");
2335 SetLastError(0xdeadbeef);
2336 ret
= pLCMapStringEx(fooW
, LCMAP_LOWERCASE
,
2337 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
), NULL
, NULL
, 0);
2339 ok(!ret
, "LCMapStringEx should fail with bad locale name\n");
2340 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "unexpected error code %d\n", GetLastError());
2343 /* test reserved parameters */
2344 ret
= pLCMapStringEx(LOCALE_NAME_USER_DEFAULT
, LCMAP_LOWERCASE
,
2345 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
), NULL
, NULL
, 1);
2346 ok(ret
== lstrlenW(upper_case
) + 1, "ret %d, error %d, expected value %d\n",
2347 ret
, GetLastError(), lstrlenW(upper_case
) + 1);
2348 ok(!lstrcmpW(buf
, lower_case
), "string compare mismatch\n");
2350 ret
= pLCMapStringEx(LOCALE_NAME_USER_DEFAULT
, LCMAP_LOWERCASE
,
2351 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
), NULL
, (void*)1, 0);
2352 ok(ret
== lstrlenW(upper_case
) + 1, "ret %d, error %d, expected value %d\n",
2353 ret
, GetLastError(), lstrlenW(upper_case
) + 1);
2354 ok(!lstrcmpW(buf
, lower_case
), "string compare mismatch\n");
2356 /* crashes on native */
2358 ret
= pLCMapStringEx(LOCALE_NAME_USER_DEFAULT
, LCMAP_LOWERCASE
,
2359 upper_case
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
), (void*)1, NULL
, 0);
2361 test_lcmapstring_unicode(LCMapStringEx_wrapper
, "LCMapStringEx:");
2364 struct neutralsublang_name_t
{
2370 static const struct neutralsublang_name_t neutralsublang_names
[] = {
2371 { {'a','r',0}, MAKELCID(MAKELANGID(LANG_ARABIC
, SUBLANG_ARABIC_SAUDI_ARABIA
), SORT_DEFAULT
) },
2372 { {'a','z',0}, MAKELCID(MAKELANGID(LANG_AZERI
, SUBLANG_AZERI_LATIN
), SORT_DEFAULT
) },
2373 { {'d','e',0}, MAKELCID(MAKELANGID(LANG_GERMAN
, SUBLANG_GERMAN
), SORT_DEFAULT
) },
2374 { {'e','n',0}, MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
) },
2375 { {'e','s',0}, MAKELCID(MAKELANGID(LANG_SPANISH
, SUBLANG_SPANISH_MODERN
), SORT_DEFAULT
), 1 },
2376 { {'g','a',0}, MAKELCID(MAKELANGID(LANG_IRISH
, SUBLANG_IRISH_IRELAND
), SORT_DEFAULT
) },
2377 { {'i','t',0}, MAKELCID(MAKELANGID(LANG_ITALIAN
, SUBLANG_ITALIAN
), SORT_DEFAULT
) },
2378 { {'m','s',0}, MAKELCID(MAKELANGID(LANG_MALAY
, SUBLANG_MALAY_MALAYSIA
), SORT_DEFAULT
) },
2379 { {'n','l',0}, MAKELCID(MAKELANGID(LANG_DUTCH
, SUBLANG_DUTCH
), SORT_DEFAULT
) },
2380 { {'p','t',0}, MAKELCID(MAKELANGID(LANG_PORTUGUESE
, SUBLANG_PORTUGUESE_BRAZILIAN
), SORT_DEFAULT
) },
2381 { {'s','r',0}, MAKELCID(MAKELANGID(LANG_SERBIAN
, SUBLANG_SERBIAN_SERBIA_LATIN
), SORT_DEFAULT
), 1 },
2382 { {'s','v',0}, MAKELCID(MAKELANGID(LANG_SWEDISH
, SUBLANG_SWEDISH
), SORT_DEFAULT
) },
2383 { {'u','z',0}, MAKELCID(MAKELANGID(LANG_UZBEK
, SUBLANG_UZBEK_LATIN
), SORT_DEFAULT
) },
2384 { {'z','h',0}, MAKELCID(MAKELANGID(LANG_CHINESE
, SUBLANG_CHINESE_SIMPLIFIED
), SORT_DEFAULT
), 1 },
2388 static void test_LocaleNameToLCID(void)
2392 WCHAR buffer
[LOCALE_NAME_MAX_LENGTH
];
2393 static const WCHAR enW
[] = {'e','n',0};
2395 if (!pLocaleNameToLCID
)
2397 win_skip( "LocaleNameToLCID not available\n" );
2403 SetLastError(0xdeadbeef);
2404 lcid
= pLocaleNameToLCID(LOCALE_NAME_USER_DEFAULT
, 0);
2405 ok(lcid
== GetUserDefaultLCID() || broken(GetLastError() == ERROR_INVALID_PARAMETER
/* Vista */),
2406 "Expected lcid == %08x, got %08x, error %d\n", GetUserDefaultLCID(), lcid
, GetLastError());
2407 ret
= pLCIDToLocaleName(lcid
, buffer
, LOCALE_NAME_MAX_LENGTH
, 0);
2408 ok(ret
> 0, "Expected ret > 0, got %d, error %d\n", ret
, GetLastError());
2409 trace("%08x, %s\n", lcid
, wine_dbgstr_w(buffer
));
2412 SetLastError(0xdeadbeef);
2413 lcid
= pLocaleNameToLCID(LOCALE_NAME_SYSTEM_DEFAULT
, 0);
2414 ok(!lcid
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2415 "Expected lcid == 0, got %08x, error %d\n", lcid
, GetLastError());
2416 ret
= pLCIDToLocaleName(lcid
, buffer
, LOCALE_NAME_MAX_LENGTH
, 0);
2417 ok(ret
> 0, "Expected ret > 0, got %d, error %d\n", ret
, GetLastError());
2418 trace("%08x, %s\n", lcid
, wine_dbgstr_w(buffer
));
2421 SetLastError(0xdeadbeef);
2422 lcid
= pLocaleNameToLCID(LOCALE_NAME_INVARIANT
, 0);
2423 ok(lcid
== 0x7F, "Expected lcid = 0x7F, got %08x, error %d\n", lcid
, GetLastError());
2424 ret
= pLCIDToLocaleName(lcid
, buffer
, LOCALE_NAME_MAX_LENGTH
, 0);
2425 ok(ret
> 0, "Expected ret > 0, got %d, error %d\n", ret
, GetLastError());
2426 trace("%08x, %s\n", lcid
, wine_dbgstr_w(buffer
));
2429 SetLastError(0xdeadbeef);
2430 lcid
= pLocaleNameToLCID(fooW
, 0);
2431 ok(!lcid
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2432 "Expected lcid == 0, got got %08x, error %d\n", lcid
, GetLastError());
2434 /* english neutral name */
2435 lcid
= pLocaleNameToLCID(enW
, 0);
2436 ok(lcid
== MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
) ||
2437 broken(lcid
== 0) /* Vista */, "got 0x%04x\n", lcid
);
2440 const struct neutralsublang_name_t
*ptr
= neutralsublang_names
;
2444 lcid
= pLocaleNameToLCID(ptr
->name
, 0);
2447 ok(lcid
== ptr
->lcid
, "%s: got wrong lcid 0x%04x, expected 0x%04x\n",
2448 wine_dbgstr_w(ptr
->name
), lcid
, ptr
->lcid
);
2450 ok(lcid
== ptr
->lcid
, "%s: got wrong lcid 0x%04x, expected 0x%04x\n",
2451 wine_dbgstr_w(ptr
->name
), lcid
, ptr
->lcid
);
2454 ret
= pLCIDToLocaleName(lcid
, buffer
, sizeof(buffer
)/sizeof(WCHAR
), 0);
2455 ok(ret
> 0, "%s: got %d\n", wine_dbgstr_w(ptr
->name
), ret
);
2456 ok(lstrcmpW(ptr
->name
, buffer
), "%s: got wrong locale name %s\n",
2457 wine_dbgstr_w(ptr
->name
), wine_dbgstr_w(buffer
));
2464 /* this requires collation table patch to make it MS compatible */
2465 static const char * const strings_sorted
[] =
2497 static const char * const strings
[] =
2529 static int compare_string1(const void *e1
, const void *e2
)
2531 const char *s1
= *(const char *const *)e1
;
2532 const char *s2
= *(const char *const *)e2
;
2534 return lstrcmpA(s1
, s2
);
2537 static int compare_string2(const void *e1
, const void *e2
)
2539 const char *s1
= *(const char *const *)e1
;
2540 const char *s2
= *(const char *const *)e2
;
2542 return CompareStringA(0, 0, s1
, -1, s2
, -1) - 2;
2545 static int compare_string3(const void *e1
, const void *e2
)
2547 const char *s1
= *(const char *const *)e1
;
2548 const char *s2
= *(const char *const *)e2
;
2549 char key1
[256], key2
[256];
2551 LCMapStringA(0, LCMAP_SORTKEY
, s1
, -1, key1
, sizeof(key1
));
2552 LCMapStringA(0, LCMAP_SORTKEY
, s2
, -1, key2
, sizeof(key2
));
2553 return strcmp(key1
, key2
);
2556 static void test_sorting(void)
2559 char **str_buf
= (char **)buf
;
2562 assert(sizeof(buf
) >= sizeof(strings
));
2564 /* 1. sort using lstrcmpA */
2565 memcpy(buf
, strings
, sizeof(strings
));
2566 qsort(buf
, sizeof(strings
)/sizeof(strings
[0]), sizeof(strings
[0]), compare_string1
);
2567 for (i
= 0; i
< sizeof(strings
)/sizeof(strings
[0]); i
++)
2569 ok(!strcmp(strings_sorted
[i
], str_buf
[i
]),
2570 "qsort using lstrcmpA failed for element %d\n", i
);
2572 /* 2. sort using CompareStringA */
2573 memcpy(buf
, strings
, sizeof(strings
));
2574 qsort(buf
, sizeof(strings
)/sizeof(strings
[0]), sizeof(strings
[0]), compare_string2
);
2575 for (i
= 0; i
< sizeof(strings
)/sizeof(strings
[0]); i
++)
2577 ok(!strcmp(strings_sorted
[i
], str_buf
[i
]),
2578 "qsort using CompareStringA failed for element %d\n", i
);
2580 /* 3. sort using sort keys */
2581 memcpy(buf
, strings
, sizeof(strings
));
2582 qsort(buf
, sizeof(strings
)/sizeof(strings
[0]), sizeof(strings
[0]), compare_string3
);
2583 for (i
= 0; i
< sizeof(strings
)/sizeof(strings
[0]); i
++)
2585 ok(!strcmp(strings_sorted
[i
], str_buf
[i
]),
2586 "qsort using sort keys failed for element %d\n", i
);
2590 static void test_FoldStringA(void)
2594 char src
[256], dst
[256];
2595 static const char digits_src
[] = { 0xB9,0xB2,0xB3,'\0' };
2596 static const char digits_dst
[] = { '1','2','3','\0' };
2597 static const char composite_src
[] =
2599 0x8a,0x8e,0x9a,0x9e,0x9f,0xc0,0xc1,0xc2,
2600 0xc3,0xc4,0xc5,0xc7,0xc8,0xc9,0xca,0xcb,
2601 0xcc,0xcd,0xce,0xcf,0xd1,0xd2,0xd3,0xd4,
2602 0xd5,0xd6,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,
2603 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe7,0xe8,
2604 0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf1,
2605 0xf2,0xf3,0xf4,0xf5,0xf6,0xf8,0xf9,0xfa,
2606 0xfb,0xfc,0xfd,0xff,'\0'
2608 static const char composite_dst
[] =
2610 0x53,0x3f,0x5a,0x3f,0x73,0x3f,0x7a,0x3f,
2611 0x59,0xa8,0x41,0x60,0x41,0xb4,0x41,0x5e,
2612 0x41,0x7e,0x41,0xa8,0x41,0xb0,0x43,0xb8,
2613 0x45,0x60,0x45,0xb4,0x45,0x5e,0x45,0xa8,
2614 0x49,0x60,0x49,0xb4,0x49,0x5e,0x49,0xa8,
2615 0x4e,0x7e,0x4f,0x60,0x4f,0xb4,0x4f,0x5e,
2616 0x4f,0x7e,0x4f,0xa8,0x4f,0x3f,0x55,0x60,
2617 0x55,0xb4,0x55,0x5e,0x55,0xa8,0x59,0xb4,
2618 0x61,0x60,0x61,0xb4,0x61,0x5e,0x61,0x7e,
2619 0x61,0xa8,0x61,0xb0,0x63,0xb8,0x65,0x60,
2620 0x65,0xb4,0x65,0x5e,0x65,0xa8,0x69,0x60,
2621 0x69,0xb4,0x69,0x5e,0x69,0xa8,0x6e,0x7e,
2622 0x6f,0x60,0x6f,0xb4,0x6f,0x5e,0x6f,0x7e,
2623 0x6f,0xa8,0x6f,0x3f,0x75,0x60,0x75,0xb4,
2624 0x75,0x5e,0x75,0xa8,0x79,0xb4,0x79,0xa8,'\0'
2626 static const char composite_dst_alt
[] =
2628 0x53,0x3f,0x5a,0x3f,0x73,0x3f,0x7a,0x3f,
2629 0x59,0xa8,0x41,0x60,0x41,0xb4,0x41,0x5e,
2630 0x41,0x7e,0x41,0xa8,0x41,0xb0,0x43,0xb8,
2631 0x45,0x60,0x45,0xb4,0x45,0x5e,0x45,0xa8,
2632 0x49,0x60,0x49,0xb4,0x49,0x5e,0x49,0xa8,
2633 0x4e,0x7e,0x4f,0x60,0x4f,0xb4,0x4f,0x5e,
2634 0x4f,0x7e,0x4f,0xa8,0xd8,0x55,0x60,0x55,
2635 0xb4,0x55,0x5e,0x55,0xa8,0x59,0xb4,0x61,
2636 0x60,0x61,0xb4,0x61,0x5e,0x61,0x7e,0x61,
2637 0xa8,0x61,0xb0,0x63,0xb8,0x65,0x60,0x65,
2638 0xb4,0x65,0x5e,0x65,0xa8,0x69,0x60,0x69,
2639 0xb4,0x69,0x5e,0x69,0xa8,0x6e,0x7e,0x6f,
2640 0x60,0x6f,0xb4,0x6f,0x5e,0x6f,0x7e,0x6f,
2641 0xa8,0xf8,0x75,0x60,0x75,0xb4,0x75,0x5e,
2642 0x75,0xa8,0x79,0xb4,0x79,0xa8,'\0'
2644 static const char ligatures_src
[] =
2646 0x8C,0x9C,0xC6,0xDE,0xDF,0xE6,0xFE,'\0'
2648 static const char ligatures_dst
[] =
2650 'O','E','o','e','A','E','T','H','s','s','a','e','t','h','\0'
2652 static const struct special
2656 } foldczone_special
[] =
2659 { 0x85, { 0x2e, 0x2e, 0x2e, 0x00 } },
2660 { 0x98, { 0x20, 0x7e, 0x00 } },
2661 { 0x99, { 0x54, 0x4d, 0x00 } },
2662 { 0xa0, { 0x20, 0x00 } },
2663 { 0xa8, { 0x20, 0xa8, 0x00 } },
2664 { 0xaa, { 0x61, 0x00 } },
2665 { 0xaf, { 0x20, 0xaf, 0x00 } },
2666 { 0xb2, { 0x32, 0x00 } },
2667 { 0xb3, { 0x33, 0x00 } },
2668 { 0xb4, { 0x20, 0xb4, 0x00 } },
2669 { 0xb8, { 0x20, 0xb8, 0x00 } },
2670 { 0xb9, { 0x31, 0x00 } },
2671 { 0xba, { 0x6f, 0x00 } },
2672 { 0xbc, { 0x31, 0x2f, 0x34, 0x00 } },
2673 { 0xbd, { 0x31, 0x2f, 0x32, 0x00 } },
2674 { 0xbe, { 0x33, 0x2f, 0x34, 0x00 } },
2679 return; /* FoldString is present in NT v3.1+, but not 95/98/Me */
2681 /* these tests are locale specific */
2682 if (GetACP() != 1252)
2684 trace("Skipping FoldStringA tests for a not Latin 1 locale\n");
2688 /* MAP_FOLDDIGITS */
2690 ret
= pFoldStringA(MAP_FOLDDIGITS
, digits_src
, -1, dst
, 256);
2691 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
2693 win_skip("FoldStringA is not implemented\n");
2696 ok(ret
== 4, "Expected ret == 4, got %d, error %d\n", ret
, GetLastError());
2697 ok(strcmp(dst
, digits_dst
) == 0,
2698 "MAP_FOLDDIGITS: Expected '%s', got '%s'\n", digits_dst
, dst
);
2699 for (i
= 1; i
< 256; i
++)
2701 if (!strchr(digits_src
, i
))
2706 ret
= pFoldStringA(MAP_FOLDDIGITS
, src
, -1, dst
, 256);
2707 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
2708 ok(dst
[0] == src
[0],
2709 "MAP_FOLDDIGITS: Expected '%s', got '%s'\n", src
, dst
);
2713 /* MAP_EXPAND_LIGATURES */
2715 ret
= pFoldStringA(MAP_EXPAND_LIGATURES
, ligatures_src
, -1, dst
, 256);
2716 /* NT 4.0 doesn't support MAP_EXPAND_LIGATURES */
2717 if (!(ret
== 0 && GetLastError() == ERROR_INVALID_FLAGS
)) {
2718 ok(ret
== sizeof(ligatures_dst
), "Got %d, error %d\n", ret
, GetLastError());
2719 ok(strcmp(dst
, ligatures_dst
) == 0,
2720 "MAP_EXPAND_LIGATURES: Expected '%s', got '%s'\n", ligatures_dst
, dst
);
2721 for (i
= 1; i
< 256; i
++)
2723 if (!strchr(ligatures_src
, i
))
2728 ret
= pFoldStringA(MAP_EXPAND_LIGATURES
, src
, -1, dst
, 256);
2732 ok((i
== 0xDC && lstrcmpA(dst
, "UE") == 0) ||
2733 (i
== 0xFC && lstrcmpA(dst
, "ue") == 0),
2734 "Got %s for %d\n", dst
, i
);
2738 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
2739 ok(dst
[0] == src
[0],
2740 "MAP_EXPAND_LIGATURES: Expected '%s', got '%s'\n", src
, dst
);
2748 ret
= pFoldStringA(MAP_COMPOSITE
, composite_src
, -1, dst
, 256);
2749 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
2750 ok(ret
== 121 || ret
== 119, "Expected 121 or 119, got %d\n", ret
);
2751 ok(strcmp(dst
, composite_dst
) == 0 || strcmp(dst
, composite_dst_alt
) == 0,
2752 "MAP_COMPOSITE: Mismatch, got '%s'\n", dst
);
2754 for (i
= 1; i
< 256; i
++)
2756 if (!strchr(composite_src
, i
))
2761 ret
= pFoldStringA(MAP_COMPOSITE
, src
, -1, dst
, 256);
2762 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
2763 ok(dst
[0] == src
[0],
2764 "0x%02x, 0x%02x,0x%02x,0x%02x,\n", (unsigned char)src
[0],
2765 (unsigned char)dst
[0],(unsigned char)dst
[1],(unsigned char)dst
[2]);
2770 for (i
= 1; i
< 256; i
++)
2775 ret
= pFoldStringA(MAP_FOLDCZONE
, src
, -1, dst
, 256);
2777 for (j
= 0; foldczone_special
[j
].src
!= 0 && ! is_special
; j
++)
2779 if (foldczone_special
[j
].src
== src
[0])
2781 ok(ret
== 2 || ret
== lstrlenA(foldczone_special
[j
].dst
) + 1,
2782 "Expected ret == 2 or %d, got %d, error %d\n",
2783 lstrlenA(foldczone_special
[j
].dst
) + 1, ret
, GetLastError());
2784 ok(src
[0] == dst
[0] || lstrcmpA(foldczone_special
[j
].dst
, dst
) == 0,
2785 "MAP_FOLDCZONE: string mismatch for 0x%02x\n",
2786 (unsigned char)src
[0]);
2792 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
2793 ok(src
[0] == dst
[0],
2794 "MAP_FOLDCZONE: Expected 0x%02x, got 0x%02x\n",
2795 (unsigned char)src
[0], (unsigned char)dst
[0]);
2799 /* MAP_PRECOMPOSED */
2800 for (i
= 1; i
< 256; i
++)
2805 ret
= pFoldStringA(MAP_PRECOMPOSED
, src
, -1, dst
, 256);
2806 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
2807 ok(src
[0] == dst
[0],
2808 "MAP_PRECOMPOSED: Expected 0x%02x, got 0x%02x\n",
2809 (unsigned char)src
[0], (unsigned char)dst
[0]);
2813 static void test_FoldStringW(void)
2817 WCHAR src
[256], dst
[256], ch
, prev_ch
= 1;
2818 static const DWORD badFlags
[] =
2821 MAP_PRECOMPOSED
|MAP_COMPOSITE
,
2822 MAP_PRECOMPOSED
|MAP_EXPAND_LIGATURES
,
2823 MAP_COMPOSITE
|MAP_EXPAND_LIGATURES
2825 /* Ranges of digits 0-9 : Must be sorted! */
2826 static const WCHAR digitRanges
[] =
2828 0x0030, /* '0'-'9' */
2829 0x0660, /* Eastern Arabic */
2830 0x06F0, /* Arabic - Hindu */
2832 0x0966, /* Devengari */
2833 0x09E6, /* Bengalii */
2834 0x0A66, /* Gurmukhi */
2835 0x0AE6, /* Gujarati */
2837 0x0BE6, /* Tamil - No 0 */
2838 0x0C66, /* Telugu */
2839 0x0CE6, /* Kannada */
2840 0x0D66, /* Maylayalam */
2841 0x0DE6, /* Sinhala Lith */
2845 0x0F29, /* Tibet half - 0 is out of sequence */
2846 0x1040, /* Myanmar */
2847 0x1090, /* Myanmar Shan */
2848 0x1368, /* Ethiopic - no 0 */
2850 0x1810, /* Mongolian */
2852 0x19D0, /* New Tai Lue */
2853 0x1A80, /* Tai Tham Hora */
2854 0x1A90, /* Tai Tham Tham */
2855 0x1B50, /* Balinese */
2856 0x1BB0, /* Sundanese */
2857 0x1C40, /* Lepcha */
2858 0x1C50, /* Ol Chiki */
2859 0x2070, /* Superscript - 1, 2, 3 are out of sequence */
2860 0x2080, /* Subscript */
2861 0x245F, /* Circled - 0 is out of sequence */
2862 0x2473, /* Bracketed */
2863 0x2487, /* Full stop */
2864 0x24F4, /* Double Circled */
2865 0x2775, /* Inverted circled - No 0 */
2866 0x277F, /* Patterned circled - No 0 */
2867 0x2789, /* Inverted Patterned circled - No 0 */
2868 0x3020, /* Hangzhou */
2870 0xA8D0, /* Saurashtra */
2871 0xA900, /* Kayah Li */
2872 0xA9D0, /* Javanese */
2873 0xA9F0, /* Myanmar Tai Laing */
2875 0xABF0, /* Meetei Mayek */
2876 0xff10, /* Pliene chasse (?) */
2877 0xffff /* Terminator */
2879 /* Digits which are represented, but out of sequence */
2880 static const WCHAR outOfSequenceDigits
[] =
2882 0xB9, /* Superscript 1 */
2883 0xB2, /* Superscript 2 */
2884 0xB3, /* Superscript 3 */
2885 0x0C78, /* Telugu Fraction 0 */
2886 0x0C79, /* Telugu Fraction 1 */
2887 0x0C7A, /* Telugu Fraction 2 */
2888 0x0C7B, /* Telugu Fraction 3 */
2889 0x0C7C, /* Telugu Fraction 1 */
2890 0x0C7D, /* Telugu Fraction 2 */
2891 0x0C7E, /* Telugu Fraction 3 */
2892 0x0F33, /* Tibetan half zero */
2893 0x19DA, /* New Tai Lue Tham 1 */
2894 0x24EA, /* Circled 0 */
2895 0x24FF, /* Negative Circled 0 */
2896 0x3007, /* Ideographic number zero */
2897 '\0' /* Terminator */
2899 /* Digits in digitRanges for which no representation is available */
2900 static const WCHAR noDigitAvailable
[] =
2902 0x0BE6, /* No Tamil 0 */
2903 0x0F29, /* No Tibetan half zero (out of sequence) */
2904 0x1368, /* No Ethiopic 0 */
2905 0x2473, /* No Bracketed 0 */
2906 0x2487, /* No 0 Full stop */
2907 0x24F4, /* No double circled 0 */
2908 0x2775, /* No inverted circled 0 */
2909 0x277F, /* No patterned circled */
2910 0x2789, /* No inverted Patterned circled */
2911 0x3020, /* No Hangzhou 0 */
2912 '\0' /* Terminator */
2914 static const WCHAR foldczone_src
[] =
2916 'W', 'i', 'n', 'e', 0x0348, 0x0551, 0x1323, 0x280d,
2917 0xff37, 0xff49, 0xff4e, 0xff45, '\0'
2919 static const WCHAR foldczone_dst
[] =
2921 'W','i','n','e',0x0348,0x0551,0x1323,0x280d,'W','i','n','e','\0'
2923 static const WCHAR foldczone_todo_src
[] =
2925 0x3c5,0x308,0x6a,0x30c,0xa0,0xaa,0
2927 static const WCHAR foldczone_todo_dst
[] =
2929 0x3cb,0x1f0,' ','a',0
2931 static const WCHAR foldczone_todo_broken_dst
[] =
2933 0x3cb,0x1f0,0xa0,0xaa,0
2935 static const WCHAR ligatures_src
[] =
2937 'W', 'i', 'n', 'e', 0x03a6, 0x03b9, 0x03bd, 0x03b5,
2938 0x00c6, 0x00de, 0x00df, 0x00e6, 0x00fe, 0x0132, 0x0133, 0x0152,
2939 0x0153, 0x01c4, 0x01c5, 0x01c6, 0x01c7, 0x01c8, 0x01c9, 0x01ca,
2940 0x01cb, 0x01cc, 0x01e2, 0x01e3, 0x01f1, 0x01f2, 0x01f3, 0x01fc,
2941 0x01fd, 0x05f0, 0x05f1, 0x05f2, 0xfb00, 0xfb01, 0xfb02, 0xfb03,
2942 0xfb04, 0xfb05, 0xfb06, '\0'
2944 static const WCHAR ligatures_dst
[] =
2946 'W','i','n','e',0x03a6,0x03b9,0x03bd,0x03b5,
2947 'A','E','T','H','s','s','a','e','t','h','I','J','i','j','O','E','o','e',
2948 'D',0x017d,'D',0x017e,'d',0x017e,'L','J','L','j','l','j','N','J','N','j',
2949 'n','j',0x0100,0x0112,0x0101,0x0113,'D','Z','D','z','d','z',0x00c1,0x00c9,
2950 0x00e1,0x00e9,0x05d5,0x05d5,0x05d5,0x05d9,0x05d9,0x05d9,'f','f','f','i',
2951 'f','l','f','f','i','f','f','l',0x017f,'t','s','t','\0'
2956 win_skip("FoldStringW is not available\n");
2957 return; /* FoldString is present in NT v3.1+, but not 95/98/Me */
2960 /* Invalid flag combinations */
2961 for (i
= 0; i
< sizeof(badFlags
)/sizeof(badFlags
[0]); i
++)
2963 src
[0] = dst
[0] = '\0';
2965 ret
= pFoldStringW(badFlags
[i
], src
, 256, dst
, 256);
2966 if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED
)
2968 win_skip("FoldStringW is not implemented\n");
2971 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
,
2972 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
2975 /* src & dst cannot be the same */
2977 ret
= pFoldStringW(MAP_FOLDCZONE
, src
, -1, src
, 256);
2978 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2979 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2981 /* src can't be NULL */
2983 ret
= pFoldStringW(MAP_FOLDCZONE
, NULL
, -1, dst
, 256);
2984 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2985 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2987 /* srclen can't be 0 */
2989 ret
= pFoldStringW(MAP_FOLDCZONE
, src
, 0, dst
, 256);
2990 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2991 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2993 /* dstlen can't be < 0 */
2995 ret
= pFoldStringW(MAP_FOLDCZONE
, src
, -1, dst
, -1);
2996 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2997 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2999 /* Ret includes terminating NUL which is appended if srclen = -1 */
3004 ret
= pFoldStringW(MAP_FOLDCZONE
, src
, -1, dst
, 256);
3005 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
3006 ok(dst
[0] == 'A' && dst
[1] == '\0',
3007 "srclen=-1: Expected ret=2 [%d,%d], got ret=%d [%d,%d], err=%d\n",
3008 'A', '\0', ret
, dst
[0], dst
[1], GetLastError());
3010 /* If size is given, result is not NUL terminated */
3016 ret
= pFoldStringW(MAP_FOLDCZONE
, src
, 1, dst
, 256);
3017 ok(ret
== 1, "Expected ret == 1, got %d, error %d\n", ret
, GetLastError());
3018 ok(dst
[0] == 'A' && dst
[1] == 'X',
3019 "srclen=1: Expected ret=1, [%d,%d], got ret=%d,[%d,%d], err=%d\n",
3020 'A','X', ret
, dst
[0], dst
[1], GetLastError());
3022 /* MAP_FOLDDIGITS */
3023 for (j
= 0; j
< sizeof(digitRanges
)/sizeof(digitRanges
[0]); j
++)
3025 /* Check everything before this range */
3026 for (ch
= prev_ch
; ch
< digitRanges
[j
]; ch
++)
3030 src
[1] = dst
[0] = '\0';
3031 ret
= pFoldStringW(MAP_FOLDDIGITS
, src
, -1, dst
, 256);
3032 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
3034 ok(dst
[0] == ch
|| strchrW(outOfSequenceDigits
, ch
) ||
3035 (ch
>= 0xa8e0 && ch
<= 0xa8e9), /* combining Devanagari on Win8 */
3036 "MAP_FOLDDIGITS: ch 0x%04x Expected unchanged got %04x\n", ch
, dst
[0]);
3037 ok(!isdigitW(ch
) || strchrW(outOfSequenceDigits
, ch
) ||
3038 broken( ch
>= 0xbf0 && ch
<= 0xbf2 ), /* win2k */
3039 "char %04x should not be a digit\n", ch
);
3042 if (digitRanges
[j
] == 0xffff)
3043 break; /* Finished the whole code point space */
3045 for (ch
= digitRanges
[j
]; ch
< digitRanges
[j
] + 10; ch
++)
3049 /* Map out of sequence characters */
3050 if (ch
== 0x2071) c
= 0x00B9; /* Superscript 1 */
3051 else if (ch
== 0x2072) c
= 0x00B2; /* Superscript 2 */
3052 else if (ch
== 0x2073) c
= 0x00B3; /* Superscript 3 */
3053 else if (ch
== 0x245F) c
= 0x24EA; /* Circled 0 */
3057 src
[1] = dst
[0] = '\0';
3058 ret
= pFoldStringW(MAP_FOLDDIGITS
, src
, -1, dst
, 256);
3059 ok(ret
== 2, "Expected ret == 2, got %d, error %d\n", ret
, GetLastError());
3061 ok((dst
[0] == '0' + ch
- digitRanges
[j
] && dst
[1] == '\0') ||
3062 broken( dst
[0] == ch
) || /* old Windows versions don't have all mappings */
3063 (digitRanges
[j
] == 0x3020 && dst
[0] == ch
) || /* Hangzhou not present in all Windows versions */
3064 (digitRanges
[j
] == 0x0F29 && dst
[0] == ch
) || /* Tibetan not present in all Windows versions */
3065 strchrW(noDigitAvailable
, c
),
3066 "MAP_FOLDDIGITS: ch %04x Expected %04x got %04x\n",
3067 ch
, '0' + digitRanges
[j
] - ch
, dst
[0]);
3074 ret
= pFoldStringW(MAP_FOLDCZONE
, foldczone_src
, -1, dst
, 256);
3075 ok(ret
== sizeof(foldczone_dst
)/sizeof(foldczone_dst
[0]),
3076 "Got %d, error %d\n", ret
, GetLastError());
3077 ok(!memcmp(dst
, foldczone_dst
, sizeof(foldczone_dst
)),
3078 "MAP_FOLDCZONE: Expanded incorrectly\n");
3080 ret
= pFoldStringW(MAP_FOLDCZONE
|MAP_PRECOMPOSED
, foldczone_todo_src
, -1, dst
, 256);
3081 todo_wine
ok(ret
== sizeof(foldczone_todo_dst
)/sizeof(foldczone_todo_dst
[0]),
3082 "Got %d, error %d\n", ret
, GetLastError());
3083 todo_wine
ok(!memcmp(dst
, foldczone_todo_dst
, sizeof(foldczone_todo_dst
))
3084 || broken(!memcmp(dst
, foldczone_todo_broken_dst
, sizeof(foldczone_todo_broken_dst
))),
3085 "MAP_FOLDCZONE: Expanded incorrectly (%s)\n", wine_dbgstr_w(dst
));
3087 /* MAP_EXPAND_LIGATURES */
3089 ret
= pFoldStringW(MAP_EXPAND_LIGATURES
, ligatures_src
, -1, dst
, 256);
3090 /* NT 4.0 doesn't support MAP_EXPAND_LIGATURES */
3091 if (!(ret
== 0 && GetLastError() == ERROR_INVALID_FLAGS
)) {
3092 ok(ret
== sizeof(ligatures_dst
)/sizeof(ligatures_dst
[0]),
3093 "Got %d, error %d\n", ret
, GetLastError());
3094 ok(!memcmp(dst
, ligatures_dst
, sizeof(ligatures_dst
)),
3095 "MAP_EXPAND_LIGATURES: Expanded incorrectly\n");
3098 /* FIXME: MAP_PRECOMPOSED : MAP_COMPOSITE */
3103 #define LCID_OK(l) \
3104 ok(lcid == l, "Expected lcid = %08x, got %08x\n", l, lcid)
3105 #define MKLCID(x,y,z) MAKELCID(MAKELANGID(x, y), z)
3106 #define LCID_RES(src, res) lcid = ConvertDefaultLocale(src); LCID_OK(res)
3107 #define TEST_LCIDLANG(a,b) LCID_RES(MAKELCID(a,b), MAKELCID(a,b))
3108 #define TEST_LCID(a,b,c) LCID_RES(MKLCID(a,b,c), MKLCID(a,b,c))
3110 static void test_ConvertDefaultLocale(void)
3114 /* Doesn't change lcid, even if non default sublang/sort used */
3115 TEST_LCID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
, SORT_DEFAULT
);
3116 TEST_LCID(LANG_ENGLISH
, SUBLANG_ENGLISH_UK
, SORT_DEFAULT
);
3117 TEST_LCID(LANG_JAPANESE
, SUBLANG_DEFAULT
, SORT_DEFAULT
);
3118 TEST_LCID(LANG_JAPANESE
, SUBLANG_DEFAULT
, SORT_JAPANESE_UNICODE
);
3120 /* SUBLANG_NEUTRAL -> SUBLANG_DEFAULT */
3121 LCID_RES(MKLCID(LANG_ENGLISH
, SUBLANG_NEUTRAL
, SORT_DEFAULT
),
3122 MKLCID(LANG_ENGLISH
, SUBLANG_DEFAULT
, SORT_DEFAULT
));
3123 LCID_RES(MKLCID(LANG_JAPANESE
, SUBLANG_NEUTRAL
, SORT_DEFAULT
),
3124 MKLCID(LANG_JAPANESE
, SUBLANG_DEFAULT
, SORT_DEFAULT
));
3126 /* Invariant language is not treated specially */
3127 TEST_LCID(LANG_INVARIANT
, SUBLANG_DEFAULT
, SORT_DEFAULT
);
3129 /* User/system default languages alone are not mapped */
3130 TEST_LCIDLANG(LANG_SYSTEM_DEFAULT
, SORT_JAPANESE_UNICODE
);
3131 TEST_LCIDLANG(LANG_USER_DEFAULT
, SORT_JAPANESE_UNICODE
);
3134 LCID_RES(LOCALE_SYSTEM_DEFAULT
, GetSystemDefaultLCID());
3135 LCID_RES(LOCALE_USER_DEFAULT
, GetUserDefaultLCID());
3136 LCID_RES(LOCALE_NEUTRAL
, GetUserDefaultLCID());
3137 lcid
= ConvertDefaultLocale(LOCALE_INVARIANT
);
3138 ok(lcid
== LOCALE_INVARIANT
|| broken(lcid
== 0x47f) /* win2k[3]/winxp */,
3139 "Expected lcid = %08x, got %08x\n", LOCALE_INVARIANT
, lcid
);
3142 static BOOL CALLBACK
langgrp_procA(LGRPID lgrpid
, LPSTR lpszNum
, LPSTR lpszName
,
3143 DWORD dwFlags
, LONG_PTR lParam
)
3145 if (winetest_debug
> 1)
3146 trace("%08x, %s, %s, %08x, %08lx\n",
3147 lgrpid
, lpszNum
, lpszName
, dwFlags
, lParam
);
3149 ok(pIsValidLanguageGroup(lgrpid
, dwFlags
) == TRUE
,
3150 "Enumerated grp %d not valid (flags %d)\n", lgrpid
, dwFlags
);
3152 /* If lParam is one, we are calling with flags defaulted from 0 */
3153 ok(!lParam
|| (dwFlags
== LGRPID_INSTALLED
|| dwFlags
== LGRPID_SUPPORTED
),
3154 "Expected dwFlags == LGRPID_INSTALLED || dwFlags == LGRPID_SUPPORTED, got %d\n", dwFlags
);
3159 static void test_EnumSystemLanguageGroupsA(void)
3163 if (!pEnumSystemLanguageGroupsA
|| !pIsValidLanguageGroup
)
3165 win_skip("EnumSystemLanguageGroupsA and/or IsValidLanguageGroup are not available\n");
3169 /* No enumeration proc */
3171 ret
= pEnumSystemLanguageGroupsA(0, LGRPID_INSTALLED
, 0);
3172 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
3174 win_skip("EnumSystemLanguageGroupsA is not implemented\n");
3177 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
3178 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3182 pEnumSystemLanguageGroupsA(langgrp_procA
, LGRPID_INSTALLED
|LGRPID_SUPPORTED
, 0);
3183 ok(GetLastError() == ERROR_INVALID_FLAGS
, "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
3185 /* No flags - defaults to LGRPID_INSTALLED */
3186 SetLastError(0xdeadbeef);
3187 pEnumSystemLanguageGroupsA(langgrp_procA
, 0, 1);
3188 ok(GetLastError() == 0xdeadbeef, "got error %d\n", GetLastError());
3190 pEnumSystemLanguageGroupsA(langgrp_procA
, LGRPID_INSTALLED
, 0);
3191 pEnumSystemLanguageGroupsA(langgrp_procA
, LGRPID_SUPPORTED
, 0);
3194 static BOOL CALLBACK
enum_func( LPWSTR name
, DWORD flags
, LPARAM lparam
)
3196 if (winetest_debug
> 1)
3197 trace( "%s %x\n", wine_dbgstr_w(name
), flags
);
3201 static void test_EnumSystemLocalesEx(void)
3205 if (!pEnumSystemLocalesEx
)
3207 win_skip( "EnumSystemLocalesEx not available\n" );
3210 SetLastError( 0xdeadbeef );
3211 ret
= pEnumSystemLocalesEx( enum_func
, LOCALE_ALL
, 0, (void *)1 );
3212 ok( !ret
, "should have failed\n" );
3213 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
3214 SetLastError( 0xdeadbeef );
3215 ret
= pEnumSystemLocalesEx( enum_func
, 0, 0, NULL
);
3216 ok( ret
, "failed err %u\n", GetLastError() );
3219 static BOOL CALLBACK
lgrplocale_procA(LGRPID lgrpid
, LCID lcid
, LPSTR lpszNum
,
3222 if (winetest_debug
> 1)
3223 trace("%08x, %08x, %s, %08lx\n", lgrpid
, lcid
, lpszNum
, lParam
);
3225 /* invalid locale enumerated on some platforms */
3229 ok(pIsValidLanguageGroup(lgrpid
, LGRPID_SUPPORTED
) == TRUE
,
3230 "Enumerated grp %d not valid\n", lgrpid
);
3231 ok(IsValidLocale(lcid
, LCID_SUPPORTED
) == TRUE
,
3232 "Enumerated grp locale %04x not valid\n", lcid
);
3236 static void test_EnumLanguageGroupLocalesA(void)
3240 if (!pEnumLanguageGroupLocalesA
|| !pIsValidLanguageGroup
)
3242 win_skip("EnumLanguageGroupLocalesA and/or IsValidLanguageGroup are not available\n");
3246 /* No enumeration proc */
3248 ret
= pEnumLanguageGroupLocalesA(0, LGRPID_WESTERN_EUROPE
, 0, 0);
3249 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
3251 win_skip("EnumLanguageGroupLocalesA is not implemented\n");
3254 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
3255 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3257 /* lgrpid too small */
3259 ret
= pEnumLanguageGroupLocalesA(lgrplocale_procA
, 0, 0, 0);
3260 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
3261 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3263 /* lgrpid too big */
3265 ret
= pEnumLanguageGroupLocalesA(lgrplocale_procA
, LGRPID_ARMENIAN
+ 1, 0, 0);
3266 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
3267 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3269 /* dwFlags is reserved */
3271 ret
= pEnumLanguageGroupLocalesA(0, LGRPID_WESTERN_EUROPE
, 0x1, 0);
3272 ok( !ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
3273 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3275 pEnumLanguageGroupLocalesA(lgrplocale_procA
, LGRPID_WESTERN_EUROPE
, 0, 0);
3278 static void test_SetLocaleInfoA(void)
3281 LCID lcid
= GetUserDefaultLCID();
3285 bRet
= SetLocaleInfoA(lcid
, LOCALE_SDATE
, 0);
3286 ok( !bRet
&& GetLastError() == ERROR_INVALID_PARAMETER
,
3287 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3291 bRet
= SetLocaleInfoA(lcid
, LOCALE_IDATE
, "test_SetLocaleInfoA");
3292 ok(!bRet
&& GetLastError() == ERROR_INVALID_FLAGS
,
3293 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
3297 bRet
= SetLocaleInfoA(lcid
, LOCALE_ILDATE
, "test_SetLocaleInfoA");
3298 ok(!bRet
&& GetLastError() == ERROR_INVALID_FLAGS
,
3299 "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
3302 static BOOL CALLBACK
luilocale_proc1A(LPSTR value
, LONG_PTR lParam
)
3304 if (winetest_debug
> 1)
3305 trace("%s %08lx\n", value
, lParam
);
3309 static BOOL CALLBACK
luilocale_proc2A(LPSTR value
, LONG_PTR lParam
)
3311 ok(!enumCount
, "callback called again unexpected\n");
3316 static BOOL CALLBACK
luilocale_proc3A(LPSTR value
, LONG_PTR lParam
)
3318 ok(0,"callback called unexpected\n");
3322 static void test_EnumUILanguageA(void)
3325 if (!pEnumUILanguagesA
) {
3326 win_skip("EnumUILanguagesA is not available on Win9x or NT4\n");
3330 SetLastError(ERROR_SUCCESS
);
3331 ret
= pEnumUILanguagesA(luilocale_proc1A
, 0, 0);
3332 if (ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
3334 win_skip("EnumUILanguagesA is not implemented\n");
3337 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
3340 SetLastError(ERROR_SUCCESS
);
3341 ret
= pEnumUILanguagesA(luilocale_proc2A
, 0, 0);
3342 ok(ret
, "Expected ret != 0, got %d, error %d\n", ret
, GetLastError());
3344 SetLastError(ERROR_SUCCESS
);
3345 ret
= pEnumUILanguagesA(NULL
, 0, 0);
3346 ok(!ret
, "Expected return value FALSE, got %u\n", ret
);
3347 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
3348 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3350 SetLastError(ERROR_SUCCESS
);
3351 ret
= pEnumUILanguagesA(luilocale_proc3A
, 0x5a5a5a5a, 0);
3352 ok(!ret
, "Expected return value FALSE, got %u\n", ret
);
3353 ok(GetLastError() == ERROR_INVALID_FLAGS
, "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
3355 SetLastError(ERROR_SUCCESS
);
3356 ret
= pEnumUILanguagesA(NULL
, 0x5a5a5a5a, 0);
3357 ok(!ret
, "Expected return value FALSE, got %u\n", ret
);
3358 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
3359 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3362 static char date_fmt_buf
[1024];
3363 static WCHAR date_fmt_bufW
[1024];
3365 static BOOL CALLBACK
enum_datetime_procA(LPSTR fmt
)
3367 lstrcatA(date_fmt_buf
, fmt
);
3368 lstrcatA(date_fmt_buf
, "\n");
3372 static BOOL CALLBACK
enum_datetime_procW(WCHAR
*fmt
)
3374 lstrcatW(date_fmt_bufW
, fmt
);
3378 static void test_EnumDateFormatsA(void)
3382 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
3384 date_fmt_buf
[0] = 0;
3385 SetLastError(0xdeadbeef);
3386 ret
= EnumDateFormatsA(enum_datetime_procA
, lcid
, 0);
3387 if (!ret
&& (GetLastError() == ERROR_INVALID_FLAGS
))
3389 win_skip("0 for dwFlags is not supported\n");
3393 ok(ret
, "EnumDateFormatsA(0) error %d\n", GetLastError());
3394 trace("EnumDateFormatsA(0): %s\n", date_fmt_buf
);
3395 /* test the 1st enumerated format */
3396 if ((p
= strchr(date_fmt_buf
, '\n'))) *p
= 0;
3397 ret
= GetLocaleInfoA(lcid
, LOCALE_SSHORTDATE
, buf
, sizeof(buf
));
3398 ok(ret
, "GetLocaleInfoA(LOCALE_SSHORTDATE) error %d\n", GetLastError());
3399 ok(!lstrcmpA(date_fmt_buf
, buf
), "expected \"%s\" got \"%s\"\n", date_fmt_buf
, buf
);
3402 date_fmt_buf
[0] = 0;
3403 SetLastError(0xdeadbeef);
3404 ret
= EnumDateFormatsA(enum_datetime_procA
, lcid
, LOCALE_USE_CP_ACP
);
3405 if (!ret
&& (GetLastError() == ERROR_INVALID_FLAGS
))
3407 win_skip("LOCALE_USE_CP_ACP is not supported\n");
3411 ok(ret
, "EnumDateFormatsA(LOCALE_USE_CP_ACP) error %d\n", GetLastError());
3412 trace("EnumDateFormatsA(LOCALE_USE_CP_ACP): %s\n", date_fmt_buf
);
3413 /* test the 1st enumerated format */
3414 if ((p
= strchr(date_fmt_buf
, '\n'))) *p
= 0;
3415 ret
= GetLocaleInfoA(lcid
, LOCALE_SSHORTDATE
, buf
, sizeof(buf
));
3416 ok(ret
, "GetLocaleInfoA(LOCALE_SSHORTDATE) error %d\n", GetLastError());
3417 ok(!lstrcmpA(date_fmt_buf
, buf
), "expected \"%s\" got \"%s\"\n", date_fmt_buf
, buf
);
3420 date_fmt_buf
[0] = 0;
3421 ret
= EnumDateFormatsA(enum_datetime_procA
, lcid
, DATE_SHORTDATE
);
3422 ok(ret
, "EnumDateFormatsA(DATE_SHORTDATE) error %d\n", GetLastError());
3423 trace("EnumDateFormatsA(DATE_SHORTDATE): %s\n", date_fmt_buf
);
3424 /* test the 1st enumerated format */
3425 if ((p
= strchr(date_fmt_buf
, '\n'))) *p
= 0;
3426 ret
= GetLocaleInfoA(lcid
, LOCALE_SSHORTDATE
, buf
, sizeof(buf
));
3427 ok(ret
, "GetLocaleInfoA(LOCALE_SSHORTDATE) error %d\n", GetLastError());
3428 ok(!lstrcmpA(date_fmt_buf
, buf
), "expected \"%s\" got \"%s\"\n", date_fmt_buf
, buf
);
3430 date_fmt_buf
[0] = 0;
3431 ret
= EnumDateFormatsA(enum_datetime_procA
, lcid
, DATE_LONGDATE
);
3432 ok(ret
, "EnumDateFormatsA(DATE_LONGDATE) error %d\n", GetLastError());
3433 trace("EnumDateFormatsA(DATE_LONGDATE): %s\n", date_fmt_buf
);
3434 /* test the 1st enumerated format */
3435 if ((p
= strchr(date_fmt_buf
, '\n'))) *p
= 0;
3436 ret
= GetLocaleInfoA(lcid
, LOCALE_SLONGDATE
, buf
, sizeof(buf
));
3437 ok(ret
, "GetLocaleInfoA(LOCALE_SLONGDATE) error %d\n", GetLastError());
3438 ok(!lstrcmpA(date_fmt_buf
, buf
), "expected \"%s\" got \"%s\"\n", date_fmt_buf
, buf
);
3440 date_fmt_buf
[0] = 0;
3441 SetLastError(0xdeadbeef);
3442 ret
= EnumDateFormatsA(enum_datetime_procA
, lcid
, DATE_YEARMONTH
);
3443 if (!ret
&& (GetLastError() == ERROR_INVALID_FLAGS
))
3445 win_skip("DATE_YEARMONTH is only present on W2K and later\n");
3448 ok(ret
, "EnumDateFormatsA(DATE_YEARMONTH) error %d\n", GetLastError());
3449 trace("EnumDateFormatsA(DATE_YEARMONTH): %s\n", date_fmt_buf
);
3450 /* test the 1st enumerated format */
3451 if ((p
= strchr(date_fmt_buf
, '\n'))) *p
= 0;
3452 ret
= GetLocaleInfoA(lcid
, LOCALE_SYEARMONTH
, buf
, sizeof(buf
));
3453 ok(ret
, "GetLocaleInfoA(LOCALE_SYEARMONTH) error %d\n", GetLastError());
3454 ok(!lstrcmpA(date_fmt_buf
, buf
) || broken(!buf
[0]) /* win9x */,
3455 "expected \"%s\" got \"%s\"\n", date_fmt_buf
, buf
);
3458 static void test_EnumTimeFormatsA(void)
3462 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
3464 date_fmt_buf
[0] = 0;
3465 ret
= EnumTimeFormatsA(enum_datetime_procA
, lcid
, 0);
3466 ok(ret
, "EnumTimeFormatsA(0) error %d\n", GetLastError());
3467 trace("EnumTimeFormatsA(0): %s\n", date_fmt_buf
);
3468 /* test the 1st enumerated format */
3469 if ((p
= strchr(date_fmt_buf
, '\n'))) *p
= 0;
3470 ret
= GetLocaleInfoA(lcid
, LOCALE_STIMEFORMAT
, buf
, sizeof(buf
));
3471 ok(ret
, "GetLocaleInfoA(LOCALE_STIMEFORMAT) error %d\n", GetLastError());
3472 ok(!lstrcmpA(date_fmt_buf
, buf
), "expected \"%s\" got \"%s\"\n", date_fmt_buf
, buf
);
3474 date_fmt_buf
[0] = 0;
3475 ret
= EnumTimeFormatsA(enum_datetime_procA
, lcid
, LOCALE_USE_CP_ACP
);
3476 ok(ret
, "EnumTimeFormatsA(LOCALE_USE_CP_ACP) error %d\n", GetLastError());
3477 trace("EnumTimeFormatsA(LOCALE_USE_CP_ACP): %s\n", date_fmt_buf
);
3478 /* test the 1st enumerated format */
3479 if ((p
= strchr(date_fmt_buf
, '\n'))) *p
= 0;
3480 ret
= GetLocaleInfoA(lcid
, LOCALE_STIMEFORMAT
, buf
, sizeof(buf
));
3481 ok(ret
, "GetLocaleInfoA(LOCALE_STIMEFORMAT) error %d\n", GetLastError());
3482 ok(!lstrcmpA(date_fmt_buf
, buf
), "expected \"%s\" got \"%s\"\n", date_fmt_buf
, buf
);
3485 static void test_EnumTimeFormatsW(void)
3487 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
3491 date_fmt_bufW
[0] = 0;
3492 ret
= EnumTimeFormatsW(enum_datetime_procW
, lcid
, 0);
3493 ok(ret
, "EnumTimeFormatsW(0) error %d\n", GetLastError());
3494 ret
= GetLocaleInfoW(lcid
, LOCALE_STIMEFORMAT
, bufW
, sizeof(bufW
)/sizeof(bufW
[0]));
3495 ok(ret
, "GetLocaleInfoW(LOCALE_STIMEFORMAT) error %d\n", GetLastError());
3496 ok(!lstrcmpW(date_fmt_bufW
, bufW
), "expected \"%s\" got \"%s\"\n", wine_dbgstr_w(date_fmt_bufW
),
3497 wine_dbgstr_w(bufW
));
3499 date_fmt_bufW
[0] = 0;
3500 ret
= EnumTimeFormatsW(enum_datetime_procW
, lcid
, LOCALE_USE_CP_ACP
);
3501 ok(ret
, "EnumTimeFormatsW(LOCALE_USE_CP_ACP) error %d\n", GetLastError());
3502 ret
= GetLocaleInfoW(lcid
, LOCALE_STIMEFORMAT
, bufW
, sizeof(bufW
)/sizeof(bufW
[0]));
3503 ok(ret
, "GetLocaleInfoW(LOCALE_STIMEFORMAT) error %d\n", GetLastError());
3504 ok(!lstrcmpW(date_fmt_bufW
, bufW
), "expected \"%s\" got \"%s\"\n", wine_dbgstr_w(date_fmt_bufW
),
3505 wine_dbgstr_w(bufW
));
3507 /* TIME_NOSECONDS is Win7+ feature */
3508 date_fmt_bufW
[0] = 0;
3509 ret
= EnumTimeFormatsW(enum_datetime_procW
, lcid
, TIME_NOSECONDS
);
3510 if (!ret
&& GetLastError() == ERROR_INVALID_FLAGS
)
3511 win_skip("EnumTimeFormatsW doesn't support TIME_NOSECONDS\n");
3515 ok(ret
, "EnumTimeFormatsW(TIME_NOSECONDS) error %d\n", GetLastError());
3516 ret
= GetLocaleInfoW(lcid
, LOCALE_SSHORTTIME
, bufW
, sizeof(bufW
)/sizeof(bufW
[0]));
3517 ok(ret
, "GetLocaleInfoW(LOCALE_SSHORTTIME) error %d\n", GetLastError());
3518 ok(!lstrcmpW(date_fmt_bufW
, bufW
), "expected \"%s\" got \"%s\"\n", wine_dbgstr_w(date_fmt_bufW
),
3519 wine_dbgstr_w(bufW
));
3521 /* EnumTimeFormatsA doesn't support this flag */
3522 ret
= EnumTimeFormatsA(enum_datetime_procA
, lcid
, TIME_NOSECONDS
);
3523 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
, "EnumTimeFormatsA(TIME_NOSECONDS) ret %d, error %d\n", ret
,
3526 ret
= EnumTimeFormatsA(NULL
, lcid
, TIME_NOSECONDS
);
3527 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
, "EnumTimeFormatsA(TIME_NOSECONDS) ret %d, error %d\n", ret
,
3530 /* And it's not supported by GetLocaleInfoA either */
3531 ret
= GetLocaleInfoA(lcid
, LOCALE_SSHORTTIME
, buf
, sizeof(buf
)/sizeof(buf
[0]));
3532 ok(!ret
&& GetLastError() == ERROR_INVALID_FLAGS
, "GetLocaleInfoA(LOCALE_SSHORTTIME) ret %d, error %d\n", ret
,
3536 static void test_GetCPInfo(void)
3541 SetLastError(0xdeadbeef);
3542 ret
= GetCPInfo(CP_SYMBOL
, &cpinfo
);
3543 ok(!ret
, "GetCPInfo(CP_SYMBOL) should fail\n");
3544 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
3545 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
3547 SetLastError(0xdeadbeef);
3548 ret
= GetCPInfo(CP_UTF7
, &cpinfo
);
3549 if (!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
)
3551 win_skip("Codepage CP_UTF7 is not installed/available\n");
3555 ok(ret
, "GetCPInfo(CP_UTF7) error %u\n", GetLastError());
3556 ok(cpinfo
.DefaultChar
[0] == 0x3f, "expected 0x3f, got 0x%x\n", cpinfo
.DefaultChar
[0]);
3557 ok(cpinfo
.DefaultChar
[1] == 0, "expected 0, got 0x%x\n", cpinfo
.DefaultChar
[1]);
3558 ok(cpinfo
.LeadByte
[0] == 0, "expected 0, got 0x%x\n", cpinfo
.LeadByte
[0]);
3559 ok(cpinfo
.LeadByte
[1] == 0, "expected 0, got 0x%x\n", cpinfo
.LeadByte
[1]);
3560 ok(cpinfo
.MaxCharSize
== 5, "expected 5, got 0x%x\n", cpinfo
.MaxCharSize
);
3563 SetLastError(0xdeadbeef);
3564 ret
= GetCPInfo(CP_UTF8
, &cpinfo
);
3565 if (!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
)
3567 win_skip("Codepage CP_UTF8 is not installed/available\n");
3571 ok(ret
, "GetCPInfo(CP_UTF8) error %u\n", GetLastError());
3572 ok(cpinfo
.DefaultChar
[0] == 0x3f, "expected 0x3f, got 0x%x\n", cpinfo
.DefaultChar
[0]);
3573 ok(cpinfo
.DefaultChar
[1] == 0, "expected 0, got 0x%x\n", cpinfo
.DefaultChar
[1]);
3574 ok(cpinfo
.LeadByte
[0] == 0, "expected 0, got 0x%x\n", cpinfo
.LeadByte
[0]);
3575 ok(cpinfo
.LeadByte
[1] == 0, "expected 0, got 0x%x\n", cpinfo
.LeadByte
[1]);
3576 ok(cpinfo
.MaxCharSize
== 4 || broken(cpinfo
.MaxCharSize
== 3) /* win9x */,
3577 "expected 4, got %u\n", cpinfo
.MaxCharSize
);
3582 * The CT_TYPE1 has varied over windows version.
3583 * The current target for correct behavior is windows 7.
3584 * There was a big shift between windows 2000 (first introduced) and windows Xp
3585 * Most of the old values below are from windows 2000.
3586 * A smaller subset of changes happened between windows Xp and Window vista/7
3588 static void test_GetStringTypeW(void)
3590 static const WCHAR blanks
[] = {0x9, 0x20, 0xa0, 0x3000, 0xfeff};
3591 static const WORD blanks_new
[] = {C1_SPACE
| C1_CNTRL
| C1_BLANK
| C1_DEFINED
,
3592 C1_SPACE
| C1_BLANK
| C1_DEFINED
,
3593 C1_SPACE
| C1_BLANK
| C1_DEFINED
,
3594 C1_SPACE
| C1_BLANK
| C1_DEFINED
,
3595 C1_CNTRL
| C1_BLANK
| C1_DEFINED
};
3596 static const WORD blanks_old
[] ={C1_SPACE
| C1_CNTRL
| C1_BLANK
,
3597 C1_SPACE
| C1_BLANK
,
3598 C1_SPACE
| C1_BLANK
,
3599 C1_SPACE
| C1_BLANK
,
3600 C1_SPACE
| C1_BLANK
};
3602 static const WCHAR undefined
[] = {0x378, 0x379, 0x5ff, 0xfff8, 0xfffe};
3605 static const WCHAR alpha
[] = {0x47, 0x67, 0x1c5};
3606 static const WORD alpha_old
[] = {C1_UPPER
| C1_ALPHA
,
3607 C1_LOWER
| C1_ALPHA
,
3608 C1_UPPER
| C1_LOWER
| C1_ALPHA
,
3611 /* Sk, Sk, Mn, So, Me */
3612 static const WCHAR oldpunc
[] = { 0x2c2, 0x2e5, 0x322, 0x482, 0x6de,
3614 0xffe0, 0xffe9, 0x2153};
3616 /* Lm, Nl, Cf, 0xad(Cf), 0x1f88 (Lt), Lo, Mc */
3617 static const WCHAR changed
[] = {0x2b0, 0x2160, 0x600, 0xad, 0x1f88, 0x294, 0x903};
3618 static const WORD changed_old
[] = { C1_PUNCT
, C1_PUNCT
, 0, C1_PUNCT
, C1_UPPER
| C1_ALPHA
, C1_ALPHA
, C1_PUNCT
};
3619 static const WORD changed_xp
[] = {C1_ALPHA
| C1_DEFINED
,
3620 C1_ALPHA
| C1_DEFINED
,
3621 C1_CNTRL
| C1_DEFINED
,
3622 C1_PUNCT
| C1_DEFINED
,
3623 C1_UPPER
| C1_LOWER
| C1_ALPHA
| C1_DEFINED
,
3624 C1_ALPHA
| C1_LOWER
| C1_DEFINED
,
3625 C1_ALPHA
| C1_DEFINED
};
3626 static const WORD changed_new
[] = { C1_ALPHA
| C1_DEFINED
,
3627 C1_ALPHA
| C1_DEFINED
,
3628 C1_CNTRL
| C1_DEFINED
,
3629 C1_PUNCT
| C1_CNTRL
| C1_DEFINED
,
3630 C1_UPPER
| C1_LOWER
| C1_ALPHA
| C1_DEFINED
,
3631 C1_ALPHA
| C1_DEFINED
,
3634 /* Pc, Pd, Ps, Pe, Pi, Pf, Po*/
3635 static const WCHAR punct
[] = { 0x5f, 0x2d, 0x28, 0x29, 0xab, 0xbb, 0x21 };
3637 static const WCHAR punct_special
[] = {0x24, 0x2b, 0x3c, 0x3e, 0x5e, 0x60,
3638 0x7c, 0x7e, 0xa2, 0xbe, 0xd7, 0xf7};
3639 static const WCHAR digit_special
[] = {0xb2, 0xb3, 0xb9};
3640 static const WCHAR lower_special
[] = {0x2071, 0x207f};
3641 static const WCHAR cntrl_special
[] = {0x070f, 0x200c, 0x200d,
3642 0x200e, 0x200f, 0x202a, 0x202b, 0x202c, 0x202d, 0x202e,
3643 0x206a, 0x206b, 0x206c, 0x206d, 0x206e, 0x206f, 0xfeff,
3644 0xfff9, 0xfffa, 0xfffb};
3645 static const WCHAR space_special
[] = {0x09, 0x0d, 0x85};
3653 SetLastError(0xdeadbeef);
3654 ret
= GetStringTypeW(CT_CTYPE1
, NULL
, 0, NULL
);
3655 ok(!ret
, "got %d\n", ret
);
3656 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got error %d\n", GetLastError());
3658 SetLastError(0xdeadbeef);
3659 ret
= GetStringTypeW(CT_CTYPE1
, NULL
, 0, types
);
3660 ok(!ret
, "got %d\n", ret
);
3661 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got error %d\n", GetLastError());
3663 SetLastError(0xdeadbeef);
3664 ret
= GetStringTypeW(CT_CTYPE1
, NULL
, 5, types
);
3665 ok(!ret
, "got %d\n", ret
);
3666 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got error %d\n", GetLastError());
3668 memset(types
,0,sizeof(types
));
3669 GetStringTypeW(CT_CTYPE1
, blanks
, 5, types
);
3670 for (i
= 0; i
< 5; i
++)
3671 ok(types
[i
] == blanks_new
[i
] || broken(types
[i
] == blanks_old
[i
] || broken(types
[i
] == 0)), "incorrect type1 returned for %x -> (%x != %x)\n",blanks
[i
],types
[i
],blanks_new
[i
]);
3673 memset(types
,0,sizeof(types
));
3674 GetStringTypeW(CT_CTYPE1
, alpha
, 3, types
);
3675 for (i
= 0; i
< 3; i
++)
3676 ok(types
[i
] == (C1_DEFINED
| alpha_old
[i
]) || broken(types
[i
] == alpha_old
[i
]) || broken(types
[i
] == 0), "incorrect types returned for %x -> (%x != %x)\n",alpha
[i
], types
[i
],(C1_DEFINED
| alpha_old
[i
]));
3677 memset(types
,0,sizeof(types
));
3678 GetStringTypeW(CT_CTYPE1
, undefined
, 5, types
);
3679 for (i
= 0; i
< 5; i
++)
3680 ok(types
[i
] == 0, "incorrect types returned for %x -> (%x != 0)\n",undefined
[i
], types
[i
]);
3682 memset(types
,0,sizeof(types
));
3683 GetStringTypeW(CT_CTYPE1
, oldpunc
, 8, types
);
3684 for (i
= 0; i
< 8; i
++)
3685 ok(types
[i
] == C1_DEFINED
|| broken(types
[i
] == C1_PUNCT
) || broken(types
[i
] == 0), "incorrect types returned for %x -> (%x != %x)\n",oldpunc
[i
], types
[i
], C1_DEFINED
);
3687 memset(types
,0,sizeof(types
));
3688 GetStringTypeW(CT_CTYPE1
, changed
, 7, types
);
3689 for (i
= 0; i
< 7; i
++)
3690 ok(types
[i
] == changed_new
[i
] || broken(types
[i
] == changed_old
[i
]) || broken(types
[i
] == changed_xp
[i
]) || broken(types
[i
] == 0), "incorrect types returned for %x -> (%x != %x)\n",changed
[i
], types
[i
], changed_new
[i
]);
3692 memset(types
,0,sizeof(types
));
3693 GetStringTypeW(CT_CTYPE1
, punct
, 7, types
);
3694 for (i
= 0; i
< 7; i
++)
3695 ok(types
[i
] == (C1_PUNCT
| C1_DEFINED
) || broken(types
[i
] == C1_PUNCT
) || broken(types
[i
] == 0), "incorrect types returned for %x -> (%x != %x)\n",punct
[i
], types
[i
], (C1_PUNCT
| C1_DEFINED
));
3698 memset(types
,0,sizeof(types
));
3699 GetStringTypeW(CT_CTYPE1
, punct_special
, 12, types
);
3700 for (i
= 0; i
< 12; i
++)
3701 ok(types
[i
] & C1_PUNCT
|| broken(types
[i
] == 0), "incorrect types returned for %x -> (%x doest not have %x)\n",punct_special
[i
], types
[i
], C1_PUNCT
);
3703 memset(types
,0,sizeof(types
));
3704 GetStringTypeW(CT_CTYPE1
, digit_special
, 3, types
);
3705 for (i
= 0; i
< 3; i
++)
3706 ok(types
[i
] & C1_DIGIT
|| broken(types
[i
] == 0), "incorrect types returned for %x -> (%x doest not have = %x)\n",digit_special
[i
], types
[i
], C1_DIGIT
);
3708 memset(types
,0,sizeof(types
));
3709 GetStringTypeW(CT_CTYPE1
, lower_special
, 2, types
);
3710 for (i
= 0; i
< 2; i
++)
3711 ok(types
[i
] & C1_LOWER
|| broken(types
[i
] == C1_PUNCT
) || broken(types
[i
] == 0), "incorrect types returned for %x -> (%x does not have %x)\n",lower_special
[i
], types
[i
], C1_LOWER
);
3713 memset(types
,0,sizeof(types
));
3714 GetStringTypeW(CT_CTYPE1
, cntrl_special
, 20, types
);
3715 for (i
= 0; i
< 20; i
++)
3716 ok(types
[i
] & C1_CNTRL
|| broken(types
[i
] == (C1_BLANK
|C1_SPACE
)) || broken(types
[i
] == C1_PUNCT
) || broken(types
[i
] == 0), "incorrect types returned for %x -> (%x does not have %x)\n",cntrl_special
[i
], types
[i
], C1_CNTRL
);
3718 memset(types
,0,sizeof(types
));
3719 GetStringTypeW(CT_CTYPE1
, space_special
, 3, types
);
3720 for (i
= 0; i
< 3; i
++)
3721 ok(types
[i
] & C1_SPACE
|| broken(types
[i
] == C1_CNTRL
) || broken(types
[i
] == 0), "incorrect types returned for %x -> (%x does not have %x)\n",space_special
[i
], types
[i
], C1_SPACE
);
3723 /* surrogate pairs */
3725 memset(types
, 0, sizeof(types
));
3726 GetStringTypeW(CT_CTYPE3
, &ch
, 1, types
);
3727 if (types
[0] == C3_NOTAPPLICABLE
)
3728 win_skip("C3_HIGHSURROGATE/C3_LOWSURROGATE are not supported.\n");
3730 ok(types
[0] == C3_HIGHSURROGATE
, "got %x\n", types
[0]);
3733 memset(types
, 0, sizeof(types
));
3734 GetStringTypeW(CT_CTYPE3
, &ch
, 1, types
);
3735 ok(types
[0] == C3_LOWSURROGATE
, "got %x\n", types
[0]);
3739 static void test_IdnToNameprepUnicode(void)
3746 const WCHAR out
[64];
3752 5, {'t','e','s','t',0},
3753 5, 5, {'t','e','s','t',0},
3757 3, {'a',0xe111,'b'},
3759 0, ERROR_INVALID_NAME
3764 0, ERROR_INVALID_NAME
3774 0, ERROR_INVALID_NAME
3777 6, {' ','-','/','[',']',0},
3778 6, 6, {' ','-','/','[',']',0},
3783 3, 3, {'a','-','a'},
3784 IDN_USE_STD3_ASCII_RULES
, 0xdeadbeef
3789 IDN_USE_STD3_ASCII_RULES
, ERROR_INVALID_NAME
3791 { /* FoldString is not working as expected when MAP_FOLDCZONE is specified (composition+compatibility) */
3792 10, {'T',0xdf,0x130,0x143,0x37a,0x6a,0x30c,' ',0xaa,0},
3793 12, 12, {'t','s','s','i',0x307,0x144,' ',0x3b9,0x1f0,' ','a',0},
3797 11, {'t',0xad,0x34f,0x1806,0x180b,0x180c,0x180d,0x200b,0x200c,0x200d,0},
3801 { /* Another example of incorrectly working FoldString (composition) */
3809 0, ERROR_NO_UNICODE_TRANSLATION
3814 IDN_ALLOW_UNASSIGNED
, 0xdeadbeef
3817 5, {'a','.','.','a',0},
3819 0, ERROR_INVALID_NAME
3831 if (!pIdnToNameprepUnicode
)
3833 win_skip("IdnToNameprepUnicode is not available\n");
3837 ret
= pIdnToNameprepUnicode(0, test_data
[0].in
,
3838 test_data
[0].in_len
, NULL
, 0);
3839 ok(ret
== test_data
[0].ret
, "ret = %d\n", ret
);
3841 SetLastError(0xdeadbeef);
3842 ret
= pIdnToNameprepUnicode(0, test_data
[1].in
,
3843 test_data
[1].in_len
, NULL
, 0);
3844 err
= GetLastError();
3845 ok(ret
== test_data
[1].ret
, "ret = %d\n", ret
);
3846 ok(err
== test_data
[1].err
, "err = %d\n", err
);
3848 SetLastError(0xdeadbeef);
3849 ret
= pIdnToNameprepUnicode(0, test_data
[0].in
, -1,
3850 buf
, sizeof(buf
)/sizeof(WCHAR
));
3851 err
= GetLastError();
3852 ok(ret
== test_data
[0].ret
, "ret = %d\n", ret
);
3853 ok(err
== 0xdeadbeef, "err = %d\n", err
);
3855 SetLastError(0xdeadbeef);
3856 ret
= pIdnToNameprepUnicode(0, test_data
[0].in
, -2,
3857 buf
, sizeof(buf
)/sizeof(WCHAR
));
3858 err
= GetLastError();
3859 ok(ret
== 0, "ret = %d\n", ret
);
3860 ok(err
== ERROR_INVALID_PARAMETER
, "err = %d\n", err
);
3862 SetLastError(0xdeadbeef);
3863 ret
= pIdnToNameprepUnicode(0, test_data
[0].in
, 0,
3864 buf
, sizeof(buf
)/sizeof(WCHAR
));
3865 err
= GetLastError();
3866 ok(ret
== 0, "ret = %d\n", ret
);
3867 ok(err
== ERROR_INVALID_NAME
, "err = %d\n", err
);
3869 ret
= pIdnToNameprepUnicode(IDN_ALLOW_UNASSIGNED
|IDN_USE_STD3_ASCII_RULES
,
3870 test_data
[0].in
, -1, buf
, sizeof(buf
)/sizeof(WCHAR
));
3871 ok(ret
== test_data
[0].ret
, "ret = %d\n", ret
);
3873 SetLastError(0xdeadbeef);
3874 ret
= pIdnToNameprepUnicode(0, NULL
, 0, NULL
, 0);
3875 err
= GetLastError();
3876 ok(ret
== 0, "ret = %d\n", ret
);
3877 ok(err
== ERROR_INVALID_PARAMETER
, "err = %d\n", err
);
3879 SetLastError(0xdeadbeef);
3880 ret
= pIdnToNameprepUnicode(4, NULL
, 0, NULL
, 0);
3881 err
= GetLastError();
3882 ok(ret
== 0, "ret = %d\n", ret
);
3883 ok(err
== ERROR_INVALID_FLAGS
|| err
== ERROR_INVALID_PARAMETER
/* Win8 */,
3886 for (i
=0; i
<sizeof(test_data
)/sizeof(*test_data
); i
++)
3888 SetLastError(0xdeadbeef);
3889 ret
= pIdnToNameprepUnicode(test_data
[i
].flags
, test_data
[i
].in
,
3890 test_data
[i
].in_len
, buf
, sizeof(buf
)/sizeof(WCHAR
));
3891 err
= GetLastError();
3893 if (!test_data
[i
].todo
)
3895 ok(ret
== test_data
[i
].ret
||
3896 broken(ret
== test_data
[i
].broken_ret
), "%d) ret = %d\n", i
, ret
);
3900 todo_wine
ok(ret
== test_data
[i
].ret
||
3901 broken(ret
== test_data
[i
].broken_ret
), "%d) ret = %d\n", i
, ret
);
3903 if(ret
!= test_data
[i
].ret
)
3906 ok(err
== test_data
[i
].err
, "%d) err = %d\n", i
, err
);
3907 ok(!memcmp(test_data
[i
].out
, buf
, ret
*sizeof(WCHAR
)),
3908 "%d) buf = %s\n", i
, wine_dbgstr_wn(buf
, ret
));
3912 static void test_IdnToAscii(void)
3918 const WCHAR out
[64];
3923 5, {'T','e','s','t',0},
3924 5, {'T','e','s','t',0},
3928 5, {'T','e',0x017c,'s','t',0},
3929 12, {'x','n','-','-','t','e','s','t','-','c','b','b',0},
3933 12, {'t','e',0x0105,'s','t','.','t','e',0x017c,'s','t',0},
3934 26, {'x','n','-','-','t','e','s','t','-','c','t','a','.','x','n','-','-','t','e','s','t','-','c','b','b',0},
3939 9, {'x','n','-','-','2','d','a','.',0},
3943 10, {'h','t','t','p',':','/','/','t',0x0106,0},
3944 17, {'x','n','-','-','h','t','t','p',':','/','/','t','-','7','8','a',0},
3948 10, {0x4e3a,0x8bf4,0x4e0d,0x4ed6,0x5011,0x10d,0x11b,0x305c,0x306a,0},
3949 35, {'x','n','-','-','b','e','a','2','a','1','6','3','1','a','v','b','a',
3950 'v','4','4','t','y','h','a','3','2','b','9','1','e','g','s','2','t',0},
3955 8, {'x','n','-','-','6','l','a',0},
3956 IDN_ALLOW_UNASSIGNED
, 0xdeadbeef
3965 win_skip("IdnToAscii is not available\n");
3969 for (i
=0; i
<sizeof(test_data
)/sizeof(*test_data
); i
++)
3971 SetLastError(0xdeadbeef);
3972 ret
= pIdnToAscii(test_data
[i
].flags
, test_data
[i
].in
,
3973 test_data
[i
].in_len
, buf
, sizeof(buf
));
3974 err
= GetLastError();
3975 ok(ret
== test_data
[i
].ret
, "%d) ret = %d\n", i
, ret
);
3976 ok(err
== test_data
[i
].err
, "%d) err = %d\n", i
, err
);
3977 ok(!memcmp(test_data
[i
].out
, buf
, ret
*sizeof(WCHAR
)),
3978 "%d) buf = %s\n", i
, wine_dbgstr_wn(buf
, ret
));
3982 static void test_IdnToUnicode(void)
3988 const WCHAR out
[64];
3993 5, {'T','e','s','.',0},
3994 5, {'T','e','s','.',0},
4000 0, ERROR_INVALID_NAME
4003 33, {'x','n','-','-','4','d','b','c','a','g','d','a','h','y','m','b',
4004 'x','e','k','h','e','h','6','e','0','a','7','f','e','i','0','b',0},
4005 23, {0x05dc,0x05de,0x05d4,0x05d4,0x05dd,0x05e4,0x05e9,0x05d5,0x05d8,
4006 0x05dc,0x05d0,0x05de,0x05d3,0x05d1,0x05e8,0x05d9,0x05dd,0x05e2,
4007 0x05d1,0x05e8,0x05d9,0x05ea,0},
4011 34, {'t','e','s','t','.','x','n','-','-','k','d','a','9','a','g','5','e',
4012 '9','j','n','f','s','j','.','x','n','-','-','p','d','-','f','n','a'},
4013 16, {'t','e','s','t','.',0x0105,0x0119,0x015b,0x0107,
4014 0x0142,0x00f3,0x017c,'.','p',0x0119,'d'},
4018 64, {'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4019 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4020 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
4021 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a'},
4023 0, ERROR_INVALID_NAME
4026 8, {'x','n','-','-','6','l','a',0},
4028 IDN_ALLOW_UNASSIGNED
, 0xdeadbeef
4037 win_skip("IdnToUnicode is not available\n");
4041 for (i
=0; i
<sizeof(test_data
)/sizeof(*test_data
); i
++)
4043 ret
= pIdnToUnicode(test_data
[i
].flags
, test_data
[i
].in
,
4044 test_data
[i
].in_len
, NULL
, 0);
4045 ok(ret
== test_data
[i
].ret
, "%d) ret = %d\n", i
, ret
);
4047 SetLastError(0xdeadbeef);
4048 ret
= pIdnToUnicode(test_data
[i
].flags
, test_data
[i
].in
,
4049 test_data
[i
].in_len
, buf
, sizeof(buf
));
4050 err
= GetLastError();
4051 ok(ret
== test_data
[i
].ret
, "%d) ret = %d\n", i
, ret
);
4052 ok(err
== test_data
[i
].err
, "%d) err = %d\n", i
, err
);
4053 ok(!memcmp(test_data
[i
].out
, buf
, ret
*sizeof(WCHAR
)),
4054 "%d) buf = %s\n", i
, wine_dbgstr_wn(buf
, ret
));
4058 static void test_GetLocaleInfoEx(void)
4060 static const WCHAR enW
[] = {'e','n',0};
4064 if (!pGetLocaleInfoEx
)
4066 win_skip("GetLocaleInfoEx not supported\n");
4070 ret
= pGetLocaleInfoEx(enW
, LOCALE_SNAME
, bufferW
, sizeof(bufferW
)/sizeof(WCHAR
));
4071 ok(ret
|| broken(ret
== 0) /* Vista */, "got %d\n", ret
);
4074 static const WCHAR statesW
[] = {'U','n','i','t','e','d',' ','S','t','a','t','e','s',0};
4075 static const WCHAR dummyW
[] = {'d','u','m','m','y',0};
4076 static const WCHAR enusW
[] = {'e','n','-','U','S',0};
4077 static const WCHAR usaW
[] = {'U','S','A',0};
4078 static const WCHAR enuW
[] = {'E','N','U',0};
4079 const struct neutralsublang_name_t
*ptr
= neutralsublang_names
;
4082 ok(ret
== lstrlenW(bufferW
)+1, "got %d\n", ret
);
4083 ok(!lstrcmpW(bufferW
, enW
), "got %s\n", wine_dbgstr_w(bufferW
));
4085 SetLastError(0xdeadbeef);
4086 ret
= pGetLocaleInfoEx(enW
, LOCALE_SNAME
, bufferW
, 2);
4087 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "got %d, %d\n", ret
, GetLastError());
4089 SetLastError(0xdeadbeef);
4090 ret
= pGetLocaleInfoEx(enW
, LOCALE_SNAME
, NULL
, 0);
4091 ok(ret
== 3 && GetLastError() == 0xdeadbeef, "got %d, %d\n", ret
, GetLastError());
4093 ret
= pGetLocaleInfoEx(enusW
, LOCALE_SNAME
, bufferW
, sizeof(bufferW
)/sizeof(WCHAR
));
4094 ok(ret
== lstrlenW(bufferW
)+1, "got %d\n", ret
);
4095 ok(!lstrcmpW(bufferW
, enusW
), "got %s\n", wine_dbgstr_w(bufferW
));
4097 ret
= pGetLocaleInfoEx(enW
, LOCALE_SABBREVCTRYNAME
, bufferW
, sizeof(bufferW
)/sizeof(WCHAR
));
4098 ok(ret
== lstrlenW(bufferW
)+1, "got %d\n", ret
);
4099 ok(!lstrcmpW(bufferW
, usaW
), "got %s\n", wine_dbgstr_w(bufferW
));
4101 ret
= pGetLocaleInfoEx(enW
, LOCALE_SABBREVLANGNAME
, bufferW
, sizeof(bufferW
)/sizeof(WCHAR
));
4102 ok(ret
== lstrlenW(bufferW
)+1, "got %d\n", ret
);
4103 ok(!lstrcmpW(bufferW
, enuW
), "got %s\n", wine_dbgstr_w(bufferW
));
4105 ret
= pGetLocaleInfoEx(enW
, LOCALE_SCOUNTRY
, bufferW
, sizeof(bufferW
)/sizeof(WCHAR
));
4106 ok(ret
== lstrlenW(bufferW
)+1, "got %d\n", ret
);
4107 if ((PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) != LANG_ENGLISH
) ||
4108 (PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH
))
4110 skip("Non-English locale\n");
4113 ok(!lstrcmpW(bufferW
, statesW
), "got %s\n", wine_dbgstr_w(bufferW
));
4116 SetLastError(0xdeadbeef);
4117 ret
= pGetLocaleInfoEx(dummyW
, LOCALE_SNAME
, bufferW
, sizeof(bufferW
)/sizeof(WCHAR
));
4118 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
, "got %d, error %d\n", ret
, GetLastError());
4123 pGetLocaleInfoEx(ptr
->name
, LOCALE_ILANGUAGE
|LOCALE_RETURN_NUMBER
, (WCHAR
*)&val
, sizeof(val
)/sizeof(WCHAR
));
4126 ok(val
== ptr
->lcid
, "%s: got wrong lcid 0x%04x, expected 0x%04x\n", wine_dbgstr_w(ptr
->name
), val
, ptr
->lcid
);
4128 ok(val
== ptr
->lcid
, "%s: got wrong lcid 0x%04x, expected 0x%04x\n", wine_dbgstr_w(ptr
->name
), val
, ptr
->lcid
);
4130 ret
= pGetLocaleInfoEx(ptr
->name
, LOCALE_SNAME
, bufferW
, sizeof(bufferW
)/sizeof(WCHAR
));
4131 ok(ret
== lstrlenW(bufferW
)+1, "%s: got ret value %d\n", wine_dbgstr_w(ptr
->name
), ret
);
4132 ok(!lstrcmpW(bufferW
, ptr
->name
), "%s: got wrong LOCALE_SNAME %s\n", wine_dbgstr_w(ptr
->name
), wine_dbgstr_w(bufferW
));
4138 static void test_IsValidLocaleName(void)
4140 static const WCHAR enusW
[] = {'e','n','-','U','S',0};
4141 static const WCHAR zzW
[] = {'z','z',0};
4142 static const WCHAR zzzzW
[] = {'z','z','-','Z','Z',0};
4145 if (!pIsValidLocaleName
)
4147 win_skip("IsValidLocaleName not supported\n");
4151 ret
= pIsValidLocaleName(enusW
);
4152 ok(ret
, "IsValidLocaleName failed\n");
4153 ret
= pIsValidLocaleName(zzW
);
4154 ok(!ret
, "IsValidLocaleName should have failed\n");
4155 ret
= pIsValidLocaleName(zzzzW
);
4156 ok(!ret
, "IsValidLocaleName should have failed\n");
4157 ret
= pIsValidLocaleName(LOCALE_NAME_INVARIANT
);
4158 ok(ret
, "IsValidLocaleName failed\n");
4161 static void test_CompareStringOrdinal(void)
4164 WCHAR test1
[] = { 't','e','s','t',0 };
4165 WCHAR test2
[] = { 'T','e','S','t',0 };
4166 WCHAR test3
[] = { 't','e','s','t','3',0 };
4167 WCHAR null1
[] = { 'a',0,'a',0 };
4168 WCHAR null2
[] = { 'a',0,'b',0 };
4169 WCHAR bills1
[] = { 'b','i','l','l','\'','s',0 };
4170 WCHAR bills2
[] = { 'b','i','l','l','s',0 };
4171 WCHAR coop1
[] = { 'c','o','-','o','p',0 };
4172 WCHAR coop2
[] = { 'c','o','o','p',0 };
4173 WCHAR nonascii1
[] = { 0x0102,0 };
4174 WCHAR nonascii2
[] = { 0x0201,0 };
4176 if (!pCompareStringOrdinal
)
4178 win_skip("CompareStringOrdinal not supported\n");
4183 SetLastError(0xdeadbeef);
4184 ret
= pCompareStringOrdinal(NULL
, 0, NULL
, 0, FALSE
);
4185 ok(!ret
, "Got %u, expected 0\n", ret
);
4186 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Got %x, expected %x\n", GetLastError(), ERROR_INVALID_PARAMETER
);
4187 SetLastError(0xdeadbeef);
4188 ret
= pCompareStringOrdinal(test1
, -1, NULL
, 0, FALSE
);
4189 ok(!ret
, "Got %u, expected 0\n", ret
);
4190 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Got %x, expected %x\n", GetLastError(), ERROR_INVALID_PARAMETER
);
4191 SetLastError(0xdeadbeef);
4192 ret
= pCompareStringOrdinal(NULL
, 0, test1
, -1, FALSE
);
4193 ok(!ret
, "Got %u, expected 0\n", ret
);
4194 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Got %x, expected %x\n", GetLastError(), ERROR_INVALID_PARAMETER
);
4197 ret
= pCompareStringOrdinal(test1
, -1, test1
, -1, FALSE
);
4198 ok(ret
== CSTR_EQUAL
, "Got %u, expected %u\n", ret
, CSTR_EQUAL
);
4199 ret
= pCompareStringOrdinal(test1
, -1, test2
, -1, FALSE
);
4200 ok(ret
== CSTR_GREATER_THAN
, "Got %u, expected %u\n", ret
, CSTR_GREATER_THAN
);
4201 ret
= pCompareStringOrdinal(test2
, -1, test1
, -1, FALSE
);
4202 ok(ret
== CSTR_LESS_THAN
, "Got %u, expected %u\n", ret
, CSTR_LESS_THAN
);
4203 ret
= pCompareStringOrdinal(test1
, -1, test2
, -1, TRUE
);
4204 ok(ret
== CSTR_EQUAL
, "Got %u, expected %u\n", ret
, CSTR_EQUAL
);
4206 /* Check different sizes */
4207 ret
= pCompareStringOrdinal(test1
, 3, test2
, -1, TRUE
);
4208 ok(ret
== CSTR_LESS_THAN
, "Got %u, expected %u\n", ret
, CSTR_LESS_THAN
);
4209 ret
= pCompareStringOrdinal(test1
, -1, test2
, 3, TRUE
);
4210 ok(ret
== CSTR_GREATER_THAN
, "Got %u, expected %u\n", ret
, CSTR_GREATER_THAN
);
4212 /* Check null character */
4213 ret
= pCompareStringOrdinal(null1
, 3, null2
, 3, FALSE
);
4214 ok(ret
== CSTR_LESS_THAN
, "Got %u, expected %u\n", ret
, CSTR_LESS_THAN
);
4215 ret
= pCompareStringOrdinal(null1
, 3, null2
, 3, TRUE
);
4216 ok(ret
== CSTR_LESS_THAN
, "Got %u, expected %u\n", ret
, CSTR_LESS_THAN
);
4217 ret
= pCompareStringOrdinal(test1
, 5, test3
, 5, FALSE
);
4218 ok(ret
== CSTR_LESS_THAN
, "Got %u, expected %u\n", ret
, CSTR_LESS_THAN
);
4219 ret
= pCompareStringOrdinal(test1
, 4, test1
, 5, FALSE
);
4220 ok(ret
== CSTR_LESS_THAN
, "Got %u, expected %u\n", ret
, CSTR_LESS_THAN
);
4222 /* Check ordinal behaviour */
4223 ret
= pCompareStringOrdinal(bills1
, -1, bills2
, -1, FALSE
);
4224 ok(ret
== CSTR_LESS_THAN
, "Got %u, expected %u\n", ret
, CSTR_LESS_THAN
);
4225 ret
= pCompareStringOrdinal(coop2
, -1, coop1
, -1, FALSE
);
4226 ok(ret
== CSTR_GREATER_THAN
, "Got %u, expected %u\n", ret
, CSTR_GREATER_THAN
);
4227 ret
= pCompareStringOrdinal(nonascii1
, -1, nonascii2
, -1, FALSE
);
4228 ok(ret
== CSTR_LESS_THAN
, "Got %u, expected %u\n", ret
, CSTR_LESS_THAN
);
4229 ret
= pCompareStringOrdinal(nonascii1
, -1, nonascii2
, -1, TRUE
);
4230 ok(ret
== CSTR_LESS_THAN
, "Got %u, expected %u\n", ret
, CSTR_LESS_THAN
);
4233 static void test_GetGeoInfo(void)
4240 win_skip("GetGeoInfo is not available.\n");
4245 SetLastError(0xdeadbeef);
4246 ret
= pGetGeoInfoA(344, GEO_ISO2
, NULL
, 0, 0);
4247 ok(ret
== 0, "got %d\n", ret
);
4248 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %d\n", GetLastError());
4250 ret
= pGetGeoInfoA(203, GEO_ISO2
, NULL
, 0, 0);
4251 ok(ret
== 3, "got %d\n", ret
);
4253 ret
= pGetGeoInfoA(203, GEO_ISO3
, NULL
, 0, 0);
4254 ok(ret
== 4, "got %d\n", ret
);
4256 ret
= pGetGeoInfoA(203, GEO_ISO2
, buffA
, 3, 0);
4257 ok(ret
== 3, "got %d\n", ret
);
4258 ok(!strcmp(buffA
, "RU"), "got %s\n", buffA
);
4260 /* buffer pointer not NULL, length is 0 - return required length */
4262 SetLastError(0xdeadbeef);
4263 ret
= pGetGeoInfoA(203, GEO_ISO2
, buffA
, 0, 0);
4264 ok(ret
== 3, "got %d\n", ret
);
4265 ok(buffA
[0] == 'a', "got %c\n", buffA
[0]);
4267 ret
= pGetGeoInfoA(203, GEO_ISO3
, buffA
, 4, 0);
4268 ok(ret
== 4, "got %d\n", ret
);
4269 ok(!strcmp(buffA
, "RUS"), "got %s\n", buffA
);
4271 /* shorter buffer */
4272 SetLastError(0xdeadbeef);
4273 buffA
[1] = buffA
[2] = 0;
4274 ret
= pGetGeoInfoA(203, GEO_ISO2
, buffA
, 2, 0);
4275 ok(ret
== 0, "got %d\n", ret
);
4276 ok(!strcmp(buffA
, "RU"), "got %s\n", buffA
);
4277 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "got %d\n", GetLastError());
4279 /* GEO_NATION returns GEOID in a string form */
4281 ret
= pGetGeoInfoA(203, GEO_NATION
, buffA
, 20, 0);
4282 ok(ret
== 4, "got %d\n", ret
);
4283 ok(!strcmp(buffA
, "203"), "got %s\n", buffA
);
4287 ret
= pGetGeoInfoA(203, GEO_PARENT
, buffA
, 20, 0);
4289 win_skip("GEO_PARENT not supported.\n");
4292 ok(ret
== 6, "got %d\n", ret
);
4293 ok(!strcmp(buffA
, "47609"), "got %s\n", buffA
);
4297 ret
= pGetGeoInfoA(203, GEO_ISO_UN_NUMBER
, buffA
, 20, 0);
4299 win_skip("GEO_ISO_UN_NUMBER not supported.\n");
4302 ok(ret
== 4, "got %d\n", ret
);
4303 ok(!strcmp(buffA
, "643"), "got %s\n", buffA
);
4306 /* try invalid type value */
4307 SetLastError(0xdeadbeef);
4308 ret
= pGetGeoInfoA(203, GEO_CURRENCYSYMBOL
+ 1, NULL
, 0, 0);
4309 ok(ret
== 0, "got %d\n", ret
);
4310 ok(GetLastError() == ERROR_INVALID_FLAGS
, "got %d\n", GetLastError());
4313 static int geoidenum_count
;
4314 static BOOL CALLBACK
test_geoid_enumproc(GEOID geoid
)
4316 INT ret
= pGetGeoInfoA(geoid
, GEO_ISO2
, NULL
, 0, 0);
4317 ok(ret
== 3, "got %d for %d\n", ret
, geoid
);
4318 /* valid geoid starts at 2 */
4319 ok(geoid
>= 2, "got geoid %d\n", geoid
);
4321 return geoidenum_count
++ < 5;
4324 static BOOL CALLBACK
test_geoid_enumproc2(GEOID geoid
)
4330 static void test_EnumSystemGeoID(void)
4334 if (!pEnumSystemGeoID
)
4336 win_skip("EnumSystemGeoID is not available.\n");
4340 SetLastError(0xdeadbeef);
4341 ret
= pEnumSystemGeoID(GEOCLASS_NATION
, 0, NULL
);
4342 ok(!ret
, "got %d\n", ret
);
4343 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %d\n", GetLastError());
4345 SetLastError(0xdeadbeef);
4346 ret
= pEnumSystemGeoID(GEOCLASS_NATION
+1, 0, test_geoid_enumproc
);
4347 ok(!ret
, "got %d\n", ret
);
4348 ok(GetLastError() == ERROR_INVALID_FLAGS
, "got %d\n", GetLastError());
4350 SetLastError(0xdeadbeef);
4351 ret
= pEnumSystemGeoID(GEOCLASS_NATION
+1, 0, NULL
);
4352 ok(!ret
, "got %d\n", ret
);
4353 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %d\n", GetLastError());
4355 ret
= pEnumSystemGeoID(GEOCLASS_NATION
, 0, test_geoid_enumproc
);
4356 ok(ret
, "got %d\n", ret
);
4358 /* only the first level is enumerated, not the whole hierarchy */
4359 geoidenum_count
= 0;
4360 ret
= pEnumSystemGeoID(GEOCLASS_NATION
, 39070, test_geoid_enumproc2
);
4362 win_skip("Parent GEOID is not supported in EnumSystemGeoID.\n");
4364 ok(ret
&& geoidenum_count
> 0, "got %d, count %d\n", ret
, geoidenum_count
);
4366 geoidenum_count
= 0;
4367 ret
= pEnumSystemGeoID(GEOCLASS_REGION
, 39070, test_geoid_enumproc2
);
4369 win_skip("GEOCLASS_REGION is not supported in EnumSystemGeoID.\n");
4372 ok(ret
&& geoidenum_count
> 0, "got %d, count %d\n", ret
, geoidenum_count
);
4374 geoidenum_count
= 0;
4375 ret
= pEnumSystemGeoID(GEOCLASS_REGION
, 0, test_geoid_enumproc2
);
4376 ok(ret
&& geoidenum_count
> 0, "got %d, count %d\n", ret
, geoidenum_count
);
4380 struct invariant_entry
{
4387 static const struct invariant_entry invariant_list
[] = {
4388 { X(LOCALE_ILANGUAGE
), "007f" },
4389 { X(LOCALE_SENGLANGUAGE
), "Invariant Language" },
4390 { X(LOCALE_SABBREVLANGNAME
), "IVL" },
4391 { X(LOCALE_SNATIVELANGNAME
), "Invariant Language" },
4392 { X(LOCALE_ICOUNTRY
), "1" },
4393 { X(LOCALE_SENGCOUNTRY
), "Invariant Country" },
4394 { X(LOCALE_SABBREVCTRYNAME
), "IVC" },
4395 { X(LOCALE_SNATIVECTRYNAME
), "Invariant Country" },
4396 { X(LOCALE_IDEFAULTLANGUAGE
), "0409" },
4397 { X(LOCALE_IDEFAULTCOUNTRY
), "1" },
4398 { X(LOCALE_IDEFAULTCODEPAGE
), "437" },
4399 { X(LOCALE_IDEFAULTANSICODEPAGE
), "1252" },
4400 { X(LOCALE_IDEFAULTMACCODEPAGE
), "10000" },
4401 { X(LOCALE_SLIST
), "," },
4402 { X(LOCALE_IMEASURE
), "0" },
4403 { X(LOCALE_SDECIMAL
), "." },
4404 { X(LOCALE_STHOUSAND
), "," },
4405 { X(LOCALE_SGROUPING
), "3;0" },
4406 { X(LOCALE_IDIGITS
), "2" },
4407 { X(LOCALE_ILZERO
), "1" },
4408 { X(LOCALE_INEGNUMBER
), "1" },
4409 { X(LOCALE_SNATIVEDIGITS
), "0123456789" },
4410 { X(LOCALE_SCURRENCY
), "\x00a4" },
4411 { X(LOCALE_SINTLSYMBOL
), "XDR" },
4412 { X(LOCALE_SMONDECIMALSEP
), "." },
4413 { X(LOCALE_SMONTHOUSANDSEP
), "," },
4414 { X(LOCALE_SMONGROUPING
), "3;0" },
4415 { X(LOCALE_ICURRDIGITS
), "2" },
4416 { X(LOCALE_IINTLCURRDIGITS
), "2" },
4417 { X(LOCALE_ICURRENCY
), "0" },
4418 { X(LOCALE_INEGCURR
), "0" },
4419 { X(LOCALE_SDATE
), "/" },
4420 { X(LOCALE_STIME
), ":" },
4421 { X(LOCALE_SSHORTDATE
), "MM/dd/yyyy" },
4422 { X(LOCALE_SLONGDATE
), "dddd, dd MMMM yyyy" },
4423 { X(LOCALE_STIMEFORMAT
), "HH:mm:ss" },
4424 { X(LOCALE_IDATE
), "0" },
4425 { X(LOCALE_ILDATE
), "1" },
4426 { X(LOCALE_ITIME
), "1" },
4427 { X(LOCALE_ITIMEMARKPOSN
), "0" },
4428 { X(LOCALE_ICENTURY
), "1" },
4429 { X(LOCALE_ITLZERO
), "1" },
4430 { X(LOCALE_IDAYLZERO
), "1" },
4431 { X(LOCALE_IMONLZERO
), "1" },
4432 { X(LOCALE_S1159
), "AM" },
4433 { X(LOCALE_S2359
), "PM" },
4434 { X(LOCALE_ICALENDARTYPE
), "1" },
4435 { X(LOCALE_IOPTIONALCALENDAR
), "0" },
4436 { X(LOCALE_IFIRSTDAYOFWEEK
), "6" },
4437 { X(LOCALE_IFIRSTWEEKOFYEAR
), "0" },
4438 { X(LOCALE_SDAYNAME1
), "Monday" },
4439 { X(LOCALE_SDAYNAME2
), "Tuesday" },
4440 { X(LOCALE_SDAYNAME3
), "Wednesday" },
4441 { X(LOCALE_SDAYNAME4
), "Thursday" },
4442 { X(LOCALE_SDAYNAME5
), "Friday" },
4443 { X(LOCALE_SDAYNAME6
), "Saturday" },
4444 { X(LOCALE_SDAYNAME7
), "Sunday" },
4445 { X(LOCALE_SABBREVDAYNAME1
), "Mon" },
4446 { X(LOCALE_SABBREVDAYNAME2
), "Tue" },
4447 { X(LOCALE_SABBREVDAYNAME3
), "Wed" },
4448 { X(LOCALE_SABBREVDAYNAME4
), "Thu" },
4449 { X(LOCALE_SABBREVDAYNAME5
), "Fri" },
4450 { X(LOCALE_SABBREVDAYNAME6
), "Sat" },
4451 { X(LOCALE_SABBREVDAYNAME7
), "Sun" },
4452 { X(LOCALE_SMONTHNAME1
), "January" },
4453 { X(LOCALE_SMONTHNAME2
), "February" },
4454 { X(LOCALE_SMONTHNAME3
), "March" },
4455 { X(LOCALE_SMONTHNAME4
), "April" },
4456 { X(LOCALE_SMONTHNAME5
), "May" },
4457 { X(LOCALE_SMONTHNAME6
), "June" },
4458 { X(LOCALE_SMONTHNAME7
), "July" },
4459 { X(LOCALE_SMONTHNAME8
), "August" },
4460 { X(LOCALE_SMONTHNAME9
), "September" },
4461 { X(LOCALE_SMONTHNAME10
), "October" },
4462 { X(LOCALE_SMONTHNAME11
), "November" },
4463 { X(LOCALE_SMONTHNAME12
), "December" },
4464 { X(LOCALE_SMONTHNAME13
), "" },
4465 { X(LOCALE_SABBREVMONTHNAME1
), "Jan" },
4466 { X(LOCALE_SABBREVMONTHNAME2
), "Feb" },
4467 { X(LOCALE_SABBREVMONTHNAME3
), "Mar" },
4468 { X(LOCALE_SABBREVMONTHNAME4
), "Apr" },
4469 { X(LOCALE_SABBREVMONTHNAME5
), "May" },
4470 { X(LOCALE_SABBREVMONTHNAME6
), "Jun" },
4471 { X(LOCALE_SABBREVMONTHNAME7
), "Jul" },
4472 { X(LOCALE_SABBREVMONTHNAME8
), "Aug" },
4473 { X(LOCALE_SABBREVMONTHNAME9
), "Sep" },
4474 { X(LOCALE_SABBREVMONTHNAME10
), "Oct" },
4475 { X(LOCALE_SABBREVMONTHNAME11
), "Nov" },
4476 { X(LOCALE_SABBREVMONTHNAME12
), "Dec" },
4477 { X(LOCALE_SABBREVMONTHNAME13
), "" },
4478 { X(LOCALE_SPOSITIVESIGN
), "+" },
4479 { X(LOCALE_SNEGATIVESIGN
), "-" },
4480 { X(LOCALE_IPOSSIGNPOSN
), "3" },
4481 { X(LOCALE_INEGSIGNPOSN
), "0" },
4482 { X(LOCALE_IPOSSYMPRECEDES
), "1" },
4483 { X(LOCALE_IPOSSEPBYSPACE
), "0" },
4484 { X(LOCALE_INEGSYMPRECEDES
), "1" },
4485 { X(LOCALE_INEGSEPBYSPACE
), "0" },
4486 { X(LOCALE_SISO639LANGNAME
), "iv" },
4487 { X(LOCALE_SISO3166CTRYNAME
), "IV" },
4488 { X(LOCALE_IDEFAULTEBCDICCODEPAGE
), "037" },
4489 { X(LOCALE_IPAPERSIZE
), "9" },
4490 { X(LOCALE_SENGCURRNAME
), "International Monetary Fund" },
4491 { X(LOCALE_SNATIVECURRNAME
), "International Monetary Fund" },
4492 { X(LOCALE_SYEARMONTH
), "yyyy MMMM" },
4493 { X(LOCALE_IDIGITSUBSTITUTION
), "1" },
4494 { X(LOCALE_SNAME
), "" },
4495 { X(LOCALE_SSCRIPTS
), "Latn;" },
4500 static void test_invariant(void)
4504 char buffer
[BUFFER_SIZE
];
4505 const struct invariant_entry
*ptr
= invariant_list
;
4507 if (!GetLocaleInfoA(LOCALE_INVARIANT
, NUO
|LOCALE_SLANGUAGE
, buffer
, sizeof(buffer
)))
4509 win_skip("GetLocaleInfoA(LOCALE_INVARIANT) not supported\n"); /* win2k */
4515 ret
= GetLocaleInfoA(LOCALE_INVARIANT
, NUO
|ptr
->id
, buffer
, sizeof(buffer
));
4516 if (!ret
&& (ptr
->id
== LOCALE_SNAME
|| ptr
->id
== LOCALE_SSCRIPTS
))
4517 win_skip("not supported\n"); /* winxp/win2k3 */
4520 len
= strlen(ptr
->expect
)+1; /* include \0 */
4521 ok(ret
== len
, "For id %d, expected ret == %d, got %d, error %d\n",
4522 ptr
->id
, len
, ret
, GetLastError());
4523 ok(!strcmp(buffer
, ptr
->expect
), "For id %d, Expected %s, got '%s'\n",
4524 ptr
->id
, ptr
->expect
, buffer
);
4530 if ((PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) != LANG_ENGLISH
) ||
4531 (PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH
))
4533 skip("Non-English locale\n");
4537 /* some locales translate these */
4538 static const char lang
[] = "Invariant Language (Invariant Country)";
4539 static const char cntry
[] = "Invariant Country";
4540 static const char sortm
[] = "Math Alphanumerics";
4541 static const char sortd
[] = "Default"; /* win2k3 */
4543 ret
= GetLocaleInfoA(LOCALE_INVARIANT
, NUO
|LOCALE_SLANGUAGE
, buffer
, sizeof(buffer
));
4544 len
= lstrlenA(lang
) + 1;
4545 ok(ret
== len
, "Expected ret == %d, got %d, error %d\n", len
, ret
, GetLastError());
4546 ok(!strcmp(buffer
, lang
), "Expected %s, got '%s'\n", lang
, buffer
);
4548 ret
= GetLocaleInfoA(LOCALE_INVARIANT
, NUO
|LOCALE_SCOUNTRY
, buffer
, sizeof(buffer
));
4549 len
= lstrlenA(cntry
) + 1;
4550 ok(ret
== len
, "Expected ret == %d, got %d, error %d\n", len
, ret
, GetLastError());
4551 ok(!strcmp(buffer
, cntry
), "Expected %s, got '%s'\n", cntry
, buffer
);
4553 ret
= GetLocaleInfoA(LOCALE_INVARIANT
, NUO
|LOCALE_SSORTNAME
, buffer
, sizeof(buffer
));
4554 if (ret
== lstrlenA(sortm
)+1)
4555 ok(!strcmp(buffer
, sortm
), "Expected %s, got '%s'\n", sortm
, buffer
);
4556 else if (ret
== lstrlenA(sortd
)+1) /* win2k3 */
4557 ok(!strcmp(buffer
, sortd
), "Expected %s, got '%s'\n", sortd
, buffer
);
4559 ok(0, "Expected ret == %d or %d, got %d, error %d\n",
4560 lstrlenA(sortm
)+1, lstrlenA(sortd
)+1, ret
, GetLastError());
4564 static void test_GetSystemPreferredUILanguages(void)
4567 ULONG count
, size
, size_id
, size_name
, size_buffer
;
4571 if (!pGetSystemPreferredUILanguages
)
4573 win_skip("GetSystemPreferredUILanguages is not available.\n");
4577 /* (in)valid first parameter */
4580 SetLastError(0xdeadbeef);
4581 ret
= pGetSystemPreferredUILanguages(0, &count
, NULL
, &size
);
4583 ok(ret
, "Expected GetSystemPreferredUILanguages to succeed\n");
4584 ok(count
, "Expected count > 0\n");
4586 ok(size
% 6 == 1, "Expected size (%d) %% 6 == 1\n", size
);
4590 SetLastError(0xdeadbeef);
4591 ret
= pGetSystemPreferredUILanguages(MUI_FULL_LANGUAGE
, &count
, NULL
, &size
);
4592 ok(!ret
, "Expected GetSystemPreferredUILanguages to fail\n");
4593 ok(ERROR_INVALID_PARAMETER
== GetLastError(),
4594 "Expected error ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
4598 SetLastError(0xdeadbeef);
4599 ret
= pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID
| MUI_FULL_LANGUAGE
, &count
, NULL
, &size
);
4600 ok(!ret
, "Expected GetSystemPreferredUILanguages to fail\n");
4601 ok(ERROR_INVALID_PARAMETER
== GetLastError(),
4602 "Expected error ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
4606 SetLastError(0xdeadbeef);
4607 ret
= pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID
| MUI_LANGUAGE_NAME
, &count
, NULL
, &size
);
4608 ok(!ret
, "Expected GetSystemPreferredUILanguages to fail\n");
4609 ok(ERROR_INVALID_PARAMETER
== GetLastError(),
4610 "Expected error ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
4614 SetLastError(0xdeadbeef);
4615 ret
= pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID
| MUI_MACHINE_LANGUAGE_SETTINGS
, &count
, NULL
, &size
);
4617 ok(ret
, "Expected GetSystemPreferredUILanguages to succeed\n");
4618 ok(count
, "Expected count > 0\n");
4620 ok(size
% 5 == 1, "Expected size (%d) %% 5 == 1\n", size
);
4624 SetLastError(0xdeadbeef);
4625 ret
= pGetSystemPreferredUILanguages(MUI_LANGUAGE_NAME
| MUI_MACHINE_LANGUAGE_SETTINGS
, &count
, NULL
, &size
);
4627 ok(ret
, "Expected GetSystemPreferredUILanguages to succeed\n");
4628 ok(count
, "Expected count > 0\n");
4630 ok(size
% 6 == 1, "Expected size (%d) %% 6 == 1\n", size
);
4633 * ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID, NULL, NULL, &size);
4634 * -> unhandled exception c0000005
4637 /* invalid third parameter */
4640 SetLastError(0xdeadbeef);
4641 ret
= pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID
, &count
, NULL
, &size
);
4642 ok(!ret
, "Expected GetSystemPreferredUILanguages to fail\n");
4643 ok(ERROR_INVALID_PARAMETER
== GetLastError(),
4644 "Expected error ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
4647 * ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID, &count, NULL, NULL);
4648 * -> unhandled exception c0000005
4653 SetLastError(0xdeadbeef);
4654 ret
= pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID
, &count
, NULL
, &size_id
);
4656 ok(ret
, "Expected GetSystemPreferredUILanguages to succeed\n");
4657 ok(count
, "Expected count > 0\n");
4659 ok(size_id
% 5 == 1, "Expected size (%d) %% 5 == 1\n", size_id
);
4663 SetLastError(0xdeadbeef);
4664 ret
= pGetSystemPreferredUILanguages(MUI_LANGUAGE_NAME
, &count
, NULL
, &size_name
);
4666 ok(ret
, "Expected GetSystemPreferredUILanguages to succeed\n");
4667 ok(count
, "Expected count > 0\n");
4669 ok(size_name
% 6 == 1, "Expected size (%d) %% 6 == 1\n", size_name
);
4671 size_buffer
= max(size_id
, size_name
);
4674 skip("No vaild buffer size\n");
4678 buffer
= HeapAlloc(GetProcessHeap(), 0, size_buffer
* sizeof(WCHAR
));
4681 skip("Failed to allocate memory with size %d\n", size_buffer
* sizeof(WCHAR
));
4687 memset(buffer
, 0x5a, size_buffer
* sizeof(WCHAR
));
4688 SetLastError(0xdeadbeef);
4689 ret
= pGetSystemPreferredUILanguages(0, &count
, buffer
, &size
);
4690 ok(ret
, "Expected GetSystemPreferredUILanguages to succeed\n");
4691 ok(count
, "Expected count > 0\n");
4692 ok(size
% 6 == 1, "Expected size (%d) %% 6 == 1\n", size
);
4693 if (ret
&& size
% 6 == 1)
4694 ok(!buffer
[size
-2] && !buffer
[size
-1],
4695 "Expected last two WCHARs being empty, got 0x%x 0x%x\n",
4696 buffer
[size
-2], buffer
[size
-1]);
4700 memset(buffer
, 0x5a, size_buffer
* sizeof(WCHAR
));
4701 SetLastError(0xdeadbeef);
4702 ret
= pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID
, &count
, buffer
, &size
);
4703 ok(ret
, "Expected GetSystemPreferredUILanguages to succeed\n");
4704 ok(count
, "Expected count > 0\n");
4705 ok(size
% 5 == 1, "Expected size (%d) %% 5 == 1\n", size
);
4706 if (ret
&& size
% 5 == 1)
4707 ok(!buffer
[size
-2] && !buffer
[size
-1],
4708 "Expected last two WCHARs being empty, got 0x%x 0x%x\n",
4709 buffer
[size
-2], buffer
[size
-1]);
4713 SetLastError(0xdeadbeef);
4714 ret
= pGetSystemPreferredUILanguages(MUI_LANGUAGE_NAME
, &count
, buffer
, &size
);
4715 ok(ret
, "Expected GetSystemPreferredUILanguages to succeed\n");
4716 ok(count
, "Expected count > 0\n");
4717 ok(size
% 6 == 1, "Expected size (%d) %% 6 == 1\n", size
);
4718 if (ret
&& size
% 5 == 1)
4719 ok(!buffer
[size
-2] && !buffer
[size
-1],
4720 "Expected last two WCHARs being empty, got 0x%x 0x%x\n",
4721 buffer
[size
-2], buffer
[size
-1]);
4725 SetLastError(0xdeadbeef);
4726 ret
= pGetSystemPreferredUILanguages(MUI_MACHINE_LANGUAGE_SETTINGS
, &count
, NULL
, &size
);
4727 ok(ret
, "Expected GetSystemPreferredUILanguages to succeed\n");
4728 ok(count
, "Expected count > 0\n");
4729 ok(size
% 6 == 1, "Expected size (%d) %% 6 == 1\n", size
);
4730 if (ret
&& size
% 6 == 1)
4731 ok(!buffer
[size
-2] && !buffer
[size
-1],
4732 "Expected last two WCHARs being empty, got 0x%x 0x%x\n",
4733 buffer
[size
-2], buffer
[size
-1]);
4737 SetLastError(0xdeadbeef);
4738 ret
= pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID
, &count
, buffer
, &size
);
4739 ok(!ret
, "Expected GetSystemPreferredUILanguages to fail\n");
4740 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
4741 "Expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
4745 memset(buffer
, 0x5a, size_buffer
* sizeof(WCHAR
));
4746 SetLastError(0xdeadbeef);
4747 ret
= pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID
, &count
, buffer
, &size
);
4748 ok(!ret
, "Expected GetSystemPreferredUILanguages to fail\n");
4749 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
4750 "Expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
4754 memset(buffer
, 0x5a, size_buffer
* sizeof(WCHAR
));
4755 SetLastError(0xdeadbeef);
4756 ret
= pGetSystemPreferredUILanguages(0, &count
, buffer
, &size
);
4757 ok(!ret
, "Expected GetSystemPreferredUILanguages to fail\n");
4758 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(),
4759 "Expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
4764 InitFunctionPointers();
4766 test_EnumTimeFormatsA();
4767 test_EnumTimeFormatsW();
4768 test_EnumDateFormatsA();
4769 test_GetLocaleInfoA();
4770 test_GetLocaleInfoW();
4771 test_GetLocaleInfoEx();
4772 test_GetTimeFormatA();
4773 test_GetTimeFormatEx();
4774 test_GetDateFormatA();
4775 test_GetDateFormatEx();
4776 test_GetDateFormatW();
4777 test_GetCurrencyFormatA(); /* Also tests the W version */
4778 test_GetNumberFormatA(); /* Also tests the W version */
4779 test_CompareStringA();
4780 test_CompareStringEx();
4781 test_LCMapStringA();
4782 test_LCMapStringW();
4783 test_LCMapStringEx();
4784 test_LocaleNameToLCID();
4787 test_ConvertDefaultLocale();
4788 test_EnumSystemLanguageGroupsA();
4789 test_EnumSystemLocalesEx();
4790 test_EnumLanguageGroupLocalesA();
4791 test_SetLocaleInfoA();
4792 test_EnumUILanguageA();
4794 test_GetStringTypeW();
4795 test_IdnToNameprepUnicode();
4797 test_IdnToUnicode();
4798 test_IsValidLocaleName();
4799 test_CompareStringOrdinal();
4801 test_EnumSystemGeoID();
4803 test_GetSystemPreferredUILanguages();
4804 /* this requires collation table patch to make it MS compatible */
4805 if (0) test_sorting();