Added YUV routines needed for v4l driver, and in the future possibly
[wine/gsoc-2012-control.git] / dlls / kernel / tests / locale.c
blob87e18491dd336b173b64cb1547376a3f8ba9dab7
1 /*
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * NOTES
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.
28 #include <assert.h>
29 #include <stdlib.h>
30 #include <stdarg.h>
32 #include "wine/test.h"
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winerror.h"
36 #include "winnls.h"
38 static inline unsigned int strlenW( const WCHAR *str )
40 const WCHAR *s = str;
41 while (*s) s++;
42 return s - str;
45 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
47 if (n <= 0) return 0;
48 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
49 return *str1 - *str2;
52 static inline WCHAR *strchrW( const WCHAR *str, WCHAR ch )
54 for ( ; *str; str++) if (*str == ch) return (WCHAR *)str;
55 return NULL;
58 inline static int isdigitW( WCHAR wc )
60 WORD type;
61 GetStringTypeW( CT_CTYPE1, &wc, 1, &type );
62 return type & C1_DIGIT;
65 /* Some functions are only in later versions of kernel32.dll */
66 static HMODULE hKernel32;
67 static WORD enumCount;
69 typedef BOOL (WINAPI *EnumSystemLanguageGroupsAFn)(LANGUAGEGROUP_ENUMPROC,
70 DWORD, LONG_PTR);
71 static EnumSystemLanguageGroupsAFn pEnumSystemLanguageGroupsA;
72 typedef BOOL (WINAPI *EnumLanguageGroupLocalesAFn)(LANGGROUPLOCALE_ENUMPROC,
73 LGRPID, DWORD, LONG_PTR);
74 static EnumLanguageGroupLocalesAFn pEnumLanguageGroupLocalesA;
75 typedef BOOL (WINAPI *EnumUILanguagesAFn)(UILANGUAGE_ENUMPROC,
76 DWORD, LONG_PTR);
77 static EnumUILanguagesAFn pEnumUILanguagesA;
79 typedef INT (WINAPI *FoldStringAFn)(DWORD, LPCSTR, INT, LPSTR, INT);
80 static FoldStringAFn pFoldStringA;
81 typedef INT (WINAPI *FoldStringWFn)(DWORD, LPCWSTR, INT, LPWSTR, INT);
82 static FoldStringWFn pFoldStringW;
84 typedef BOOL (WINAPI *IsValidLanguageGroupFn)(LGRPID, DWORD);
85 static IsValidLanguageGroupFn pIsValidLanguageGroup;
87 static void InitFunctionPointers(void)
89 hKernel32 = GetModuleHandleA("kernel32");
91 if (hKernel32)
93 pEnumSystemLanguageGroupsA = (void*)GetProcAddress(hKernel32, "EnumSystemLanguageGroupsA");
94 pEnumLanguageGroupLocalesA = (void*)GetProcAddress(hKernel32, "EnumLanguageGroupLocalesA");
95 pFoldStringA = (void*)GetProcAddress(hKernel32, "FoldStringA");
96 pFoldStringW = (void*)GetProcAddress(hKernel32, "FoldStringW");
97 pIsValidLanguageGroup = (void*)GetProcAddress(hKernel32, "IsValidLanguageGroup");
98 pEnumUILanguagesA = (void*)GetProcAddress(hKernel32, "EnumUILanguagesA");
102 #define eq(received, expected, label, type) \
103 ok((received) == (expected), "%s: got " type " instead of " type "\n", \
104 (label), (received), (expected))
106 #define BUFFER_SIZE 128
107 char GlobalBuffer[BUFFER_SIZE]; /* Buffer used by callback function */
108 #define COUNTOF(x) (sizeof(x)/sizeof(x)[0])
110 #define EXPECT_LEN(len) ok(ret == (len), "Expected Len %d, got %d\n", (len), ret)
111 #define EXPECT_INVALID ok(GetLastError() == ERROR_INVALID_PARAMETER, \
112 "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError())
113 #define EXPECT_BUFFER ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, \
114 "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError())
115 #define EXPECT_FLAGS ok(GetLastError() == ERROR_INVALID_FLAGS, \
116 "Expected ERROR_INVALID_FLAGS, got %ld\n", GetLastError())
117 #define EXPECT_INVALIDFLAGS ok(GetLastError() == ERROR_INVALID_FLAGS || \
118 GetLastError() == ERROR_INVALID_PARAMETER, \
119 "Expected ERROR_INVALID_FLAGS, got %ld\n", GetLastError())
120 #define EXPECT_VALID ok(GetLastError() == 0, \
121 "Expected GetLastError() == 0, got %ld\n", GetLastError())
123 #define STRINGSA(x,y) strcpy(input, x); strcpy(Expected, y); SetLastError(0); buffer[0] = '\0'
124 #define EXPECT_LENA EXPECT_LEN((int)strlen(Expected)+1)
125 #define EXPECT_EQA ok(strncmp(buffer, Expected, strlen(Expected)) == 0, \
126 "Expected '%s', got '%s'\n", Expected, buffer)
128 #define STRINGSW(x,y) MultiByteToWideChar(CP_ACP,0,x,-1,input,COUNTOF(input)); \
129 MultiByteToWideChar(CP_ACP,0,y,-1,Expected,COUNTOF(Expected)); \
130 SetLastError(0); buffer[0] = '\0'
131 #define EXPECT_LENW EXPECT_LEN((int)strlenW(Expected)+1)
132 #define EXPECT_EQW ok(strncmpW(buffer, Expected, strlenW(Expected)) == 0, "Bad conversion\n")
133 #define EXPECT_FALSE ok(FALSE == ret, "Expected return value FALSE, got TRUE\n")
134 #define EXPECT_TRUE ok(FALSE != ret, "Expected return value TRUE, got FALSE\n")
136 #define NUO LOCALE_NOUSEROVERRIDE
138 static void test_GetLocaleInfoA()
140 int ret;
141 LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
142 char buffer[BUFFER_SIZE];
144 ok(lcid == 0x409, "wrong LCID calculated - %ld\n", lcid);
146 /* HTMLKit and "Font xplorer lite" expect GetLocaleInfoA to
147 * partially fill the buffer even if it is too short. See bug 637.
149 SetLastError(0); memset(buffer, 0, COUNTOF(buffer));
150 ret = GetLocaleInfoA(lcid, NUO|LOCALE_SDAYNAME1, buffer, 0);
151 ok(ret == 7 && !buffer[0], "Expected len=7, got %d\n", ret);
153 SetLastError(0); memset(buffer, 0, COUNTOF(buffer));
154 ret = GetLocaleInfoA(lcid, NUO|LOCALE_SDAYNAME1, buffer, 3);
155 EXPECT_BUFFER; EXPECT_LEN(0);
156 ok(!strcmp(buffer, "Mon"), "Expected 'Mon', got '%s'\n", buffer);
158 SetLastError(0); memset(buffer, 0, COUNTOF(buffer));
159 ret = GetLocaleInfoA(lcid, NUO|LOCALE_SDAYNAME1, buffer, 10);
160 EXPECT_VALID; EXPECT_LEN(7);
161 ok(!strcmp(buffer, "Monday"), "Expected 'Monday', got '%s'\n", buffer);
164 static void test_GetTimeFormatA()
166 int ret;
167 SYSTEMTIME curtime;
168 LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
169 char buffer[BUFFER_SIZE], input[BUFFER_SIZE], Expected[BUFFER_SIZE];
171 memset(&curtime, 2, sizeof(SYSTEMTIME));
172 STRINGSA("tt HH':'mm'@'ss", ""); /* Invalid time */
173 ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
174 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
176 curtime.wHour = 8;
177 curtime.wMinute = 56;
178 curtime.wSecond = 13;
179 curtime.wMilliseconds = 22;
180 STRINGSA("tt HH':'mm'@'ss", "AM 08:56@13"); /* Valid time */
181 ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
182 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
184 STRINGSA("tt HH':'mm'@'ss", "A"); /* Insufficent buffer */
185 ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, 2);
186 EXPECT_BUFFER; EXPECT_LEN(0); EXPECT_EQA;
188 STRINGSA("tt HH':'mm'@'ss", "AM 08:56@13"); /* Calculate length only */
189 ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, NULL, 0);
190 EXPECT_VALID; EXPECT_LENA;
192 STRINGSA("", "8 AM"); /* TIME_NOMINUTESORSECONDS, default format */
193 ret = GetTimeFormatA(lcid, NUO|TIME_NOMINUTESORSECONDS, &curtime, NULL, buffer, COUNTOF(buffer));
194 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
196 STRINGSA("m1s2m3s4", ""); /* TIME_NOMINUTESORSECONDS/complex format */
197 ret = GetTimeFormatA(lcid, TIME_NOMINUTESORSECONDS, &curtime, input, buffer, COUNTOF(buffer));
198 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
200 STRINGSA("", "8:56 AM"); /* TIME_NOSECONDS/Default format */
201 ret = GetTimeFormatA(lcid, NUO|TIME_NOSECONDS, &curtime, NULL, buffer, COUNTOF(buffer));
202 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
204 STRINGSA("h:m:s tt", "8:56 AM"); /* TIME_NOSECONDS */
205 strcpy(Expected, "8:56 AM");
206 ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
207 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
209 STRINGSA("h.@:m.@:s.@:tt", "8.@:56AM"); /* Multiple delimiters */
210 ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
211 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
213 STRINGSA("s1s2s3", ""); /* Duplicate tokens */
214 ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
215 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
217 STRINGSA("t/tt", "A/AM"); /* AM time marker */
218 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
219 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
221 curtime.wHour = 13;
222 STRINGSA("t/tt", "P/PM"); /* PM time marker */
223 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
224 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
226 STRINGSA("h1t2tt3m", "156"); /* TIME_NOTIMEMARKER: removes text around time marker token */
227 ret = GetTimeFormatA(lcid, TIME_NOTIMEMARKER, &curtime, input, buffer, COUNTOF(buffer));
228 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
230 STRINGSA("h:m:s tt", "13:56:13 PM"); /* TIME_FORCE24HOURFORMAT */
231 ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
232 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
234 STRINGSA("h:m:s", "13:56:13"); /* TIME_FORCE24HOURFORMAT doesn't add time marker */
235 ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
236 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
238 curtime.wHour = 14; /* change this to 14 or 2pm */
239 curtime.wMinute = 5;
240 curtime.wSecond = 3;
241 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 */
242 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
243 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
245 curtime.wHour = 0;
246 STRINGSA("h/H/hh/HH", "12/0/12/00"); /* "hh" and "HH" */
247 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
248 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
250 STRINGSA("h:m:s tt", "12:5:3 AM"); /* non-zero flags should fail with format, doesn't */
251 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
252 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
254 /* try to convert formatting strings with more than two letters
255 * "h:hh:hhh:H:HH:HHH:m:mm:mmm:M:MM:MMM:s:ss:sss:S:SS:SSS"
256 * NOTE: We expect any letter for which there is an upper case value
257 * we should see a replacement. For letters that DO NOT have
258 * upper case values we should see NO REPLACEMENT.
260 curtime.wHour = 8;
261 curtime.wMinute = 56;
262 curtime.wSecond = 13;
263 curtime.wMilliseconds = 22;
264 STRINGSA("h:hh:hhh H:HH:HHH m:mm:mmm M:MM:MMM s:ss:sss S:SS:SSS",
265 "8:08:08 8:08:08 56:56:56 M:MM:MMM 13:13:13 S:SS:SSS");
266 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
267 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
269 STRINGSA("h", "text"); /* Don't write to buffer if len is 0 */
270 strcpy(buffer, "text");
271 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, 0);
272 EXPECT_VALID; EXPECT_LEN(2); EXPECT_EQA;
274 STRINGSA("h 'h' H 'H' HH 'HH' m 'm' s 's' t 't' tt 'tt'",
275 "8 h 8 H 08 HH 56 m 13 s A t AM tt"); /* "'" preserves tokens */
276 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
277 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
279 STRINGSA("'''", "'"); /* invalid quoted string */
280 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
281 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
283 /* test that msdn suggested single quotation usage works as expected */
284 STRINGSA("''''", "'"); /* single quote mark */
285 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
286 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
288 STRINGSA("''HHHHHH", "08"); /* Normal use */
289 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
290 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
292 /* and test for normal use of the single quotation mark */
293 STRINGSA("'''HHHHHH'", "'HHHHHH"); /* Normal use */
294 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
295 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
297 STRINGSA("'''HHHHHH", "'HHHHHH"); /* Odd use */
298 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
299 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
301 STRINGSA("'123'tt", ""); /* TIME_NOTIMEMARKER drops literals too */
302 ret = GetTimeFormatA(lcid, TIME_NOTIMEMARKER, &curtime, input, buffer, COUNTOF(buffer));
303 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
305 curtime.wHour = 25;
306 STRINGSA("'123'tt", ""); /* Invalid time */
307 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
308 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
310 curtime.wHour = 12;
311 curtime.wMonth = 60; /* Invalid */
312 STRINGSA("h:m:s", "12:56:13"); /* Invalid date */
313 ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
314 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
317 static void test_GetDateFormatA()
319 int ret;
320 SYSTEMTIME curtime;
321 LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
322 char buffer[BUFFER_SIZE], input[BUFFER_SIZE], Expected[BUFFER_SIZE];
324 memset(&curtime, 2, sizeof(SYSTEMTIME)); /* Invalid time */
325 STRINGSA("ddd',' MMM dd yy","");
326 ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
327 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
329 curtime.wYear = 2002;
330 curtime.wMonth = 5;
331 curtime.wDay = 4;
332 curtime.wDayOfWeek = 3;
333 STRINGSA("ddd',' MMM dd yy","Sat, May 04 02"); /* Simple case */
334 ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
335 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
337 STRINGSA("ddd',' MMM dd yy","Sat, May 04 02"); /* Format containing "'" */
338 ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
339 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
341 curtime.wHour = 36; /* Invalid */
342 STRINGSA("ddd',' MMM dd ''''yy","Sat, May 04 '02"); /* Invalid time */
343 ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
344 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
346 STRINGSA("ddd',' MMM dd ''''yy",""); /* Get size only */
347 ret = GetDateFormatA(lcid, 0, &curtime, input, NULL, 0);
348 EXPECT_VALID; EXPECT_LEN(16); EXPECT_EQA;
350 STRINGSA("ddd',' MMM dd ''''yy",""); /* Buffer too small */
351 ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, 2);
352 EXPECT_BUFFER; EXPECT_LEN(0); EXPECT_EQA;
354 STRINGSA("ddd',' MMM dd ''''yy","5/4/2002"); /* Default to DATE_SHORTDATE */
355 ret = GetDateFormat(lcid, NUO, &curtime, NULL, buffer, COUNTOF(buffer));
356 EXPECT_VALID; EXPECT_LENA;
357 if (strncmp(buffer, Expected, strlen(Expected)) && strncmp(buffer, "5/4/02", strlen(Expected)) != 0)
358 ok (0, "Expected '%s' or '5/4/02', got '%s'\n", Expected, buffer);
360 STRINGSA("ddd',' MMM dd ''''yy", "Saturday, May 04, 2002"); /* DATE_LONGDATE */
361 ret = GetDateFormat(lcid, NUO|DATE_LONGDATE, &curtime, NULL, buffer, COUNTOF(buffer));
362 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
364 /* test for expected DATE_YEARMONTH behavior with null format */
365 /* NT4 returns ERROR_INVALID_FLAGS for DATE_YEARMONTH */
366 STRINGSA("ddd',' MMM dd ''''yy", ""); /* DATE_YEARMONTH */
367 ret = GetDateFormat(lcid, NUO|DATE_YEARMONTH, &curtime, input, buffer, COUNTOF(buffer));
368 EXPECT_FLAGS; EXPECT_LEN(0); EXPECT_EQA;
370 /* Test that using invalid DATE_* flags results in the correct error */
371 /* and return values */
372 STRINGSA("m/d/y", ""); /* Invalid flags */
373 ret = GetDateFormat(lcid, DATE_YEARMONTH|DATE_SHORTDATE|DATE_LONGDATE,
374 &curtime, input, buffer, COUNTOF(buffer));
375 EXPECT_FLAGS; EXPECT_LEN(0); EXPECT_EQA;
378 static void test_GetDateFormatW()
380 int ret;
381 SYSTEMTIME curtime;
382 WCHAR buffer[BUFFER_SIZE], input[BUFFER_SIZE], Expected[BUFFER_SIZE];
383 LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
385 STRINGSW("",""); /* If flags is not zero then format must be NULL */
386 ret = GetDateFormatW(LOCALE_SYSTEM_DEFAULT, DATE_LONGDATE, NULL,
387 input, buffer, COUNTOF(buffer));
388 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
389 return;
390 EXPECT_FLAGS; EXPECT_LEN(0); EXPECT_EQW;
392 STRINGSW("",""); /* NULL buffer, len > 0 */
393 ret = GetDateFormatW (lcid, 0, NULL, input, NULL, COUNTOF(buffer));
394 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQW;
396 STRINGSW("",""); /* NULL buffer, len == 0 */
397 ret = GetDateFormatW (lcid, 0, NULL, input, NULL, 0);
398 EXPECT_VALID; EXPECT_LENW; EXPECT_EQW;
400 curtime.wYear = 2002;
401 curtime.wMonth = 10;
402 curtime.wDay = 23;
403 curtime.wDayOfWeek = 45612; /* Should be 3 - Wednesday */
404 curtime.wHour = 65432; /* Invalid */
405 curtime.wMinute = 34512; /* Invalid */
406 curtime.wSecond = 65535; /* Invalid */
407 curtime.wMilliseconds = 12345;
408 STRINGSW("dddd d MMMM yyyy","Wednesday 23 October 2002"); /* Incorrect DOW and time */
409 ret = GetDateFormatW (lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
410 EXPECT_VALID; EXPECT_LENW; EXPECT_EQW;
414 #define CY_POS_LEFT 0
415 #define CY_POS_RIGHT 1
416 #define CY_POS_LEFT_SPACE 2
417 #define CY_POS_RIGHT_SPACE 3
419 static void test_GetCurrencyFormatA()
421 static char szDot[] = { '.', '\0' };
422 static char szComma[] = { ',', '\0' };
423 static char szDollar[] = { '$', '\0' };
424 int ret;
425 LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
426 char buffer[BUFFER_SIZE], Expected[BUFFER_SIZE], input[BUFFER_SIZE];
427 CURRENCYFMTA format;
429 memset(&format, 0, sizeof(format));
431 STRINGSA("23",""); /* NULL output, length > 0 --> Error */
432 ret = GetCurrencyFormatA(lcid, 0, input, NULL, NULL, COUNTOF(buffer));
433 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
435 STRINGSA("23,53",""); /* Invalid character --> Error */
436 ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
437 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
439 STRINGSA("--",""); /* Double '-' --> Error */
440 ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
441 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
443 STRINGSA("0-",""); /* Trailing '-' --> Error */
444 ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
445 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
447 STRINGSA("0..",""); /* Double '.' --> Error */
448 ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
449 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
451 STRINGSA(" 0.1",""); /* Leading space --> Error */
452 ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
453 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
455 STRINGSA("1234","$"); /* Length too small --> Write up to length chars */
456 ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, 2);
457 EXPECT_BUFFER; EXPECT_LEN(0); EXPECT_EQA;
459 STRINGSA("2353",""); /* Format and flags given --> Error */
460 ret = GetCurrencyFormatA(lcid, NUO, input, &format, buffer, COUNTOF(buffer));
461 EXPECT_INVALIDFLAGS; EXPECT_LEN(0); EXPECT_EQA;
463 STRINGSA("2353",""); /* Invalid format --> Error */
464 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
465 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
467 STRINGSA("2353","$2,353.00"); /* Valid number */
468 ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
469 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
471 STRINGSA("-2353","($2,353.00)"); /* Valid negative number */
472 ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
473 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
475 STRINGSA("2353.1","$2,353.10"); /* Valid real number */
476 ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
477 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
479 STRINGSA("2353.111","$2,353.11"); /* Too many DP --> Truncated */
480 ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
481 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
483 STRINGSA("2353.119","$2,353.12"); /* Too many DP --> Rounded */
484 ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
485 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
487 format.NumDigits = 0; /* No decimal separator */
488 format.LeadingZero = 0;
489 format.Grouping = 0; /* No grouping char */
490 format.NegativeOrder = 0;
491 format.PositiveOrder = CY_POS_LEFT;
492 format.lpDecimalSep = szDot;
493 format.lpThousandSep = szComma;
494 format.lpCurrencySymbol = szDollar;
496 STRINGSA("2353","$2353"); /* No decimal or grouping chars expected */
497 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
498 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
500 format.NumDigits = 1; /* 1 DP --> Expect decimal separator */
501 STRINGSA("2353","$2353.0");
502 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
503 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
505 format.Grouping = 2; /* Group by 100's */
506 STRINGSA("2353","$23,53.0");
507 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
508 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
510 format.LeadingZero = 1; /* Always provide leading zero */
511 STRINGSA(".5","$0.5");
512 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
513 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
515 format.PositiveOrder = CY_POS_RIGHT;
516 STRINGSA("1","1.0$");
517 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
518 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
520 format.PositiveOrder = CY_POS_LEFT_SPACE;
521 STRINGSA("1","$ 1.0");
522 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
523 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
525 format.PositiveOrder = CY_POS_RIGHT_SPACE;
526 STRINGSA("1","1.0 $");
527 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
528 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
530 format.NegativeOrder = 0;
531 STRINGSA("-1","($1.0)");
532 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
533 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
535 format.NegativeOrder = 1;
536 STRINGSA("-1","-$1.0");
537 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
538 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
540 format.NegativeOrder = 2;
541 STRINGSA("-1","$-1.0");
542 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
543 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
545 format.NegativeOrder = 3;
546 STRINGSA("-1","$1.0-");
547 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
548 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
550 format.NegativeOrder = 4;
551 STRINGSA("-1","(1.0$)");
552 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
553 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
555 format.NegativeOrder = 5;
556 STRINGSA("-1","-1.0$");
557 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
558 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
560 format.NegativeOrder = 6;
561 STRINGSA("-1","1.0-$");
562 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
563 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
565 format.NegativeOrder = 7;
566 STRINGSA("-1","1.0$-");
567 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
568 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
570 format.NegativeOrder = 8;
571 STRINGSA("-1","-1.0 $");
572 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
573 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
575 format.NegativeOrder = 9;
576 STRINGSA("-1","-$ 1.0");
577 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
578 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
580 format.NegativeOrder = 10;
581 STRINGSA("-1","1.0 $-");
582 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
583 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
585 format.NegativeOrder = 11;
586 STRINGSA("-1","$ 1.0-");
587 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
588 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
590 format.NegativeOrder = 12;
591 STRINGSA("-1","$ -1.0");
592 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
593 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
595 format.NegativeOrder = 13;
596 STRINGSA("-1","1.0- $");
597 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
598 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
600 format.NegativeOrder = 14;
601 STRINGSA("-1","($ 1.0)");
602 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
603 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
605 format.NegativeOrder = 15;
606 STRINGSA("-1","(1.0 $)");
607 ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
608 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
611 #define NEG_PARENS 0 /* "(1.1)" */
612 #define NEG_LEFT 1 /* "-1.1" */
613 #define NEG_LEFT_SPACE 2 /* "- 1.1" */
614 #define NEG_RIGHT 3 /* "1.1-" */
615 #define NEG_RIGHT_SPACE 4 /* "1.1 -" */
617 static void test_GetNumberFormatA()
619 static char szDot[] = { '.', '\0' };
620 static char szComma[] = { ',', '\0' };
621 int ret;
622 LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
623 char buffer[BUFFER_SIZE], Expected[BUFFER_SIZE], input[BUFFER_SIZE];
624 NUMBERFMTA format;
626 memset(&format, 0, sizeof(format));
628 STRINGSA("23",""); /* NULL output, length > 0 --> Error */
629 ret = GetNumberFormatA(lcid, 0, input, NULL, NULL, COUNTOF(buffer));
630 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
632 STRINGSA("23,53",""); /* Invalid character --> Error */
633 ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
634 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
636 STRINGSA("--",""); /* Double '-' --> Error */
637 ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
638 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
640 STRINGSA("0-",""); /* Trailing '-' --> Error */
641 ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
642 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
644 STRINGSA("0..",""); /* Double '.' --> Error */
645 ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
646 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
648 STRINGSA(" 0.1",""); /* Leading space --> Error */
649 ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
650 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
652 STRINGSA("1234","1"); /* Length too small --> Write up to length chars */
653 ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, 2);
654 EXPECT_BUFFER; EXPECT_LEN(0); EXPECT_EQA;
656 STRINGSA("2353",""); /* Format and flags given --> Error */
657 ret = GetNumberFormatA(lcid, NUO, input, &format, buffer, COUNTOF(buffer));
658 EXPECT_INVALIDFLAGS; EXPECT_LEN(0); EXPECT_EQA;
660 STRINGSA("2353",""); /* Invalid format --> Error */
661 ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
662 EXPECT_INVALID; EXPECT_LEN(0); EXPECT_EQA;
664 STRINGSA("2353","2,353.00"); /* Valid number */
665 ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
666 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
668 STRINGSA("-2353","-2,353.00"); /* Valid negative number */
669 ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
670 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
672 STRINGSA("-353","-353.00"); /* test for off by one error in grouping */
673 ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
674 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
676 STRINGSA("2353.1","2,353.10"); /* Valid real number */
677 ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
678 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
680 STRINGSA("2353.111","2,353.11"); /* Too many DP --> Truncated */
681 ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
682 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
684 STRINGSA("2353.119","2,353.12"); /* Too many DP --> Rounded */
685 ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
686 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
688 format.NumDigits = 0; /* No decimal separator */
689 format.LeadingZero = 0;
690 format.Grouping = 0; /* No grouping char */
691 format.NegativeOrder = 0;
692 format.lpDecimalSep = szDot;
693 format.lpThousandSep = szComma;
695 STRINGSA("2353","2353"); /* No decimal or grouping chars expected */
696 ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
697 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
699 format.NumDigits = 1; /* 1 DP --> Expect decimal separator */
700 STRINGSA("2353","2353.0");
701 ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
702 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
704 format.Grouping = 2; /* Group by 100's */
705 STRINGSA("2353","23,53.0");
706 ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
707 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
709 format.LeadingZero = 1; /* Always provide leading zero */
710 STRINGSA(".5","0.5");
711 ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
712 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
714 format.NegativeOrder = NEG_PARENS;
715 STRINGSA("-1","(1.0)");
716 ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
717 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
719 format.NegativeOrder = NEG_LEFT;
720 STRINGSA("-1","-1.0");
721 ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
722 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
724 format.NegativeOrder = NEG_LEFT_SPACE;
725 STRINGSA("-1","- 1.0");
726 ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
727 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
729 format.NegativeOrder = NEG_RIGHT;
730 STRINGSA("-1","1.0-");
731 ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
732 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
734 format.NegativeOrder = NEG_RIGHT_SPACE;
735 STRINGSA("-1","1.0 -");
736 ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
737 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
739 lcid = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT);
741 if (IsValidLocale(lcid, 0))
743 STRINGSA("-12345","-12 345,00"); /* Try French formatting */
744 Expected[3] = 160; /* Non breaking space */
745 ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
746 EXPECT_VALID; EXPECT_LENA; EXPECT_EQA;
751 /* Callback function used by TestEnumTimeFormats */
752 static BOOL CALLBACK EnumTimeFormatsProc(char * lpTimeFormatString)
754 trace("%s\n", lpTimeFormatString);
755 strcpy(GlobalBuffer, lpTimeFormatString);
756 #if 0
757 return TRUE;
758 #endif
759 return FALSE;
762 void test_EnumTimeFormats()
764 int ret;
765 LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
767 GlobalBuffer[0] = '\0';
768 ret = EnumTimeFormatsA(EnumTimeFormatsProc, lcid, 0);
769 ok (ret == 1 && !strcmp(GlobalBuffer,"h:mm:ss tt"), "Expected %d '%s'\n", ret, GlobalBuffer);
772 static void test_CompareStringA()
774 int ret;
775 LCID lcid = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT);
777 ret = CompareStringA(lcid, NORM_IGNORECASE, "Salut", -1, "Salute", -1);
778 ok (ret== 1, "(Salut/Salute) Expected 1, got %d\n", ret);
780 ret = CompareStringA(lcid, NORM_IGNORECASE, "Salut", -1, "SaLuT", -1);
781 ok (ret== 2, "(Salut/SaLuT) Expected 2, got %d\n", ret);
783 ret = CompareStringA(lcid, NORM_IGNORECASE, "Salut", -1, "hola", -1);
784 ok (ret== 3, "(Salut/hola) Expected 3, got %d\n", ret);
786 ret = CompareStringA(lcid, NORM_IGNORECASE, "haha", -1, "hoho", -1);
787 ok (ret== 1, "(haha/hoho) Expected 1, got %d\n", ret);
789 lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
791 ret = CompareStringA(lcid, NORM_IGNORECASE, "haha", -1, "hoho", -1);
792 ok (ret== 1, "(haha/hoho) Expected 1, got %d\n", ret);
794 ret = CompareStringA(lcid, NORM_IGNORECASE, "haha", -1, "hoho", 0);
795 ok (ret== 3, "(haha/hoho) Expected 3, got %d\n", ret);
797 ret = CompareStringA(lcid, NORM_IGNORECASE, "Salut", 5, "saLuT", -1);
798 ok (ret == 2, "(Salut/saLuT) Expected 2, got %d\n", ret);
800 /* test for CompareStringA flags */
801 SetLastError(0xdeadbeef);
802 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0x10, "NULL", -1, "NULL", -1);
803 ok(GetLastError() == ERROR_INVALID_FLAGS,
804 "unexpected error code %ld\n", GetLastError());
805 ok(!ret, "CompareStringA must fail with invalid flag\n");
807 SetLastError(0xdeadbeef);
808 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, LOCALE_USE_CP_ACP, "NULL", -1, "NULL", -1);
809 ok(GetLastError() == 0xdeadbeef, "unexpected error code %ld\n", GetLastError());
810 ok(ret == CSTR_EQUAL, "CompareStringA error: %d != CSTR_EQUAL\n", ret);
811 /* end of test for CompareStringA flags */
813 ret = lstrcmpA("", "");
814 ok (ret == 0, "lstrcmpA(\"\", \"\") should return 0, got %d\n", ret);
816 ret = lstrcmpA(NULL, NULL);
817 ok (ret == 0, "lstrcmpA(NULL, NULL) should return 0, got %d\n", ret);
819 ret = lstrcmpA("", NULL);
820 ok (ret == 1, "lstrcmpA(\"\", NULL) should return 1, got %d\n", ret);
822 ret = lstrcmpA(NULL, "");
823 ok (ret == -1, "lstrcmpA(NULL, \"\") should return -1, got %d\n", ret);
825 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT,0,"EndDialog",-1,"_Property",-1);
826 ok( ret == 3, "EndDialog vs _Property ... expected 3, got %d\n", ret);
828 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT,0,"osp_vba.sreg0070",-1,"_IEWWBrowserComp",-1);
829 ok( ret == 3, "osp_vba.sreg0070 vs _IEWWBrowserComp ... expected 3, got %d\n", ret);
831 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT,0,"r",-1,"\\",-1);
832 ok( ret == 3, "r vs \\ ... expected 3, got %d\n", ret);
834 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT,0,"osp_vba.sreg0031", -1, "OriginalDatabase", -1 );
835 ok( ret == 3, "osp_vba.sreg0031 vs OriginalDatabase ... expected 3, got %d\n", ret);
837 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "AAA", -1, "aaa", -1 );
838 ok( ret == 3, "AAA vs aaa expected 3, got %d\n", ret);
840 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "AAA", -1, "aab", -1 );
841 ok( ret == 1, "AAA vs aab expected 1, got %d\n", ret);
843 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "AAA", -1, "Aab", -1 );
844 ok( ret == 1, "AAA vs Aab expected 1, got %d\n", ret);
846 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, ".AAA", -1, "Aab", -1 );
847 ok( ret == 1, ".AAA vs Aab expected 1, got %d\n", ret);
849 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, ".AAA", -1, "A.ab", -1 );
850 ok( ret == 1, ".AAA vs A.ab expected 1, got %d\n", ret);
852 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "aa", -1, "AB", -1 );
853 ok( ret == 1, "aa vs AB expected 1, got %d\n", ret);
855 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "aa", -1, "Aab", -1 );
856 ok( ret == 1, "aa vs Aab expected 1, got %d\n", ret);
858 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "aB", -1, "Aab", -1 );
859 ok( ret == 3, "aB vs Aab expected 3, got %d\n", ret);
861 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "Ba", -1, "bab", -1 );
862 ok( ret == 1, "Ba vs bab expected 1, got %d\n", ret);
864 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "{100}{83}{71}{71}{71}", -1, "Global_DataAccess_JRO", -1 );
865 ok( ret == 1, "{100}{83}{71}{71}{71} vs Global_DataAccess_JRO expected 1, got %d\n", ret);
867 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "a", -1, "{", -1 );
868 ok( ret == 3, "a vs { expected 3, got %d\n", ret);
870 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "A", -1, "{", -1 );
871 ok( ret == 3, "A vs { expected 3, got %d\n", ret);
873 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "3.5", 0, "4.0", -1 );
874 ok(ret == 1, "3.5/0 vs 4.0/-1 expected 1, got %d\n", ret);
876 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "3.5", -1, "4.0", -1 );
877 ok(ret == 1, "3.5 vs 4.0 expected 1, got %d\n", ret);
879 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "3.520.4403.2", -1, "4.0.2927.10", -1 );
880 ok(ret == 1, "3.520.4403.2 vs 4.0.2927.10 expected 1, got %d\n", ret);
882 /* hyphen and apostrophe are treated differently depending on
883 * whether SORT_STRINGSORT specified or not
885 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "-o", -1, "/m", -1 );
886 ok(ret == 3, "-o vs /m expected 3, got %d\n", ret);
888 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "/m", -1, "-o", -1 );
889 ok(ret == 1, "/m vs -o expected 1, got %d\n", ret);
891 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "-o", -1, "/m", -1 );
892 ok(ret == 1, "-o vs /m expected 1, got %d\n", ret);
894 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "/m", -1, "-o", -1 );
895 ok(ret == 3, "/m vs -o expected 3, got %d\n", ret);
897 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "'o", -1, "/m", -1 );
898 ok(ret == 3, "'o vs /m expected 3, got %d\n", ret);
900 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "/m", -1, "'o", -1 );
901 ok(ret == 1, "/m vs 'o expected 1, got %d\n", ret);
903 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "'o", -1, "/m", -1 );
904 ok(ret == 1, "'o vs /m expected 1, got %d\n", ret);
906 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "/m", -1, "'o", -1 );
907 ok(ret == 3, "/m vs 'o expected 3, got %d\n", ret);
909 #if 0 /* this requires collation table patch to make it MS compatible */
910 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "'o", -1, "-o", -1 );
911 ok(ret == 1, "'o vs -o expected 1, got %d\n", ret);
913 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "'o", -1, "-o", -1 );
914 ok(ret == 1, "'o vs -o expected 1, got %d\n", ret);
916 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "'", -1, "-", -1 );
917 ok(ret == 1, "' vs - expected 1, got %d\n", ret);
919 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "'", -1, "-", -1 );
920 ok(ret == 1, "' vs - expected 1, got %d\n", ret);
922 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "`o", -1, "/m", -1 );
923 ok(ret == 3, "`o vs /m expected 3, got %d\n", ret);
925 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "/m", -1, "`o", -1 );
926 ok(ret == 1, "/m vs `o expected 1, got %d\n", ret);
928 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "`o", -1, "/m", -1 );
929 ok(ret == 3, "`o vs /m expected 3, got %d\n", ret);
931 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "/m", -1, "`o", -1 );
932 ok(ret == 1, "/m vs `o expected 1, got %d\n", ret);
934 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "`o", -1, "-m", -1 );
935 ok(ret == 1, "`o vs -m expected 1, got %d\n", ret);
937 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "-m", -1, "`o", -1 );
938 ok(ret == 3, "-m vs `o expected 3, got %d\n", ret);
940 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "`o", -1, "-m", -1 );
941 ok(ret == 3, "`o vs -m expected 3, got %d\n", ret);
943 ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "-m", -1, "`o", -1 );
944 ok(ret == 1, "-m vs `o expected 1, got %d\n", ret);
945 #endif
947 ret = CompareStringA(LOCALE_USER_DEFAULT, 0, "aLuZkUtZ", 8, "aLuZkUtZ", 9);
948 ok(ret == 2, "aLuZkUtZ vs aLuZkUtZ\\0 expected 2, got %d\n", ret);
950 ret = CompareStringA(LOCALE_USER_DEFAULT, 0, "aLuZkUtZ", 7, "aLuZkUtZ\0A", 10);
951 ok(ret == 1, "aLuZkUtZ vs aLuZkUtZ\\0A expected 1, got %d\n", ret);
953 ret = CompareStringA(LOCALE_USER_DEFAULT, 0, "aLuZkUtZ", 8, "aLuZkUtZ\0A", 10);
954 ok(ret == 2, "aLuZkUtZ vs aLuZkUtZ\\0A expected 2, got %d\n", ret);
956 ret = CompareStringA(LOCALE_USER_DEFAULT, 0, "aLu\0ZkUtZ", 8, "aLu\0ZkUtZ\0A", 10);
957 ok(ret == 2, "aLu\\0ZkUtZ vs aLu\\0ZkUtZ\\0A expected 2, got %d\n", ret);
960 void test_LCMapStringA(void)
962 int ret, ret2;
963 char buf[256], buf2[256];
964 static const char upper_case[] = "\tJUST! A, TEST; STRING 1/*+-.\r\n";
965 static const char lower_case[] = "\tjust! a, test; string 1/*+-.\r\n";
966 static const char symbols_stripped[] = "justateststring1";
968 SetLastError(0xdeadbeef);
969 ret = LCMapStringA(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP | LCMAP_LOWERCASE,
970 lower_case, -1, buf, sizeof(buf));
971 ok(ret == lstrlenA(lower_case) + 1,
972 "ret %d, error %ld, expected value %d\n",
973 ret, GetLastError(), lstrlenA(lower_case) + 1);
974 ok(!memcmp(buf, lower_case, ret), "LCMapStringA should return %s, but not %s\n", lower_case, buf);
976 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE | LCMAP_UPPERCASE,
977 upper_case, -1, buf, sizeof(buf));
978 ok(!ret, "LCMAP_LOWERCASE and LCMAP_UPPERCASE are mutually exclusive\n");
979 ok(GetLastError() == ERROR_INVALID_FLAGS,
980 "unexpected error code %ld\n", GetLastError());
982 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_HIRAGANA | LCMAP_KATAKANA,
983 upper_case, -1, buf, sizeof(buf));
984 ok(!ret, "LCMAP_HIRAGANA and LCMAP_KATAKANA are mutually exclusive\n");
985 ok(GetLastError() == ERROR_INVALID_FLAGS,
986 "unexpected error code %ld\n", GetLastError());
988 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_HALFWIDTH | LCMAP_FULLWIDTH,
989 upper_case, -1, buf, sizeof(buf));
990 ok(!ret, "LCMAP_HALFWIDTH | LCMAP_FULLWIDTH are mutually exclusive\n");
991 ok(GetLastError() == ERROR_INVALID_FLAGS,
992 "unexpected error code %ld\n", GetLastError());
994 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_TRADITIONAL_CHINESE | LCMAP_SIMPLIFIED_CHINESE,
995 upper_case, -1, buf, sizeof(buf));
996 ok(!ret, "LCMAP_TRADITIONAL_CHINESE and LCMAP_SIMPLIFIED_CHINESE are mutually exclusive\n");
997 ok(GetLastError() == ERROR_INVALID_FLAGS,
998 "unexpected error code %ld\n", GetLastError());
1000 /* SORT_STRINGSORT must be used exclusively with LCMAP_SORTKEY */
1001 SetLastError(0xdeadbeef);
1002 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE | SORT_STRINGSORT,
1003 upper_case, -1, buf, sizeof(buf));
1004 ok(GetLastError() == ERROR_INVALID_FLAGS, "expected ERROR_INVALID_FLAGS, got %ld\n", GetLastError());
1005 ok(!ret, "SORT_STRINGSORT without LCMAP_SORTKEY must fail\n");
1007 /* test LCMAP_LOWERCASE */
1008 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE,
1009 upper_case, -1, buf, sizeof(buf));
1010 ok(ret == lstrlenA(upper_case) + 1,
1011 "ret %d, error %ld, expected value %d\n",
1012 ret, GetLastError(), lstrlenA(upper_case) + 1);
1013 ok(!lstrcmpA(buf, lower_case), "LCMapStringA should return %s, but not %s\n", lower_case, buf);
1015 /* test LCMAP_UPPERCASE */
1016 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE,
1017 lower_case, -1, buf, sizeof(buf));
1018 ok(ret == lstrlenA(lower_case) + 1,
1019 "ret %d, error %ld, expected value %d\n",
1020 ret, GetLastError(), lstrlenA(lower_case) + 1);
1021 ok(!lstrcmpA(buf, upper_case), "LCMapStringA should return %s, but not %s\n", upper_case, buf);
1023 /* test buffer overflow */
1024 SetLastError(0xdeadbeef);
1025 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE,
1026 lower_case, -1, buf, 4);
1027 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1028 "should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d\n", ret);
1030 /* LCMAP_UPPERCASE or LCMAP_LOWERCASE should accept src == dst */
1031 lstrcpyA(buf, lower_case);
1032 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE,
1033 buf, -1, buf, sizeof(buf));
1034 if (!ret) /* Win9x */
1035 trace("Ignoring LCMapStringA(LCMAP_UPPERCASE, buf, buf) error on Win9x\n");
1036 else
1038 ok(ret == lstrlenA(lower_case) + 1,
1039 "ret %d, error %ld, expected value %d\n",
1040 ret, GetLastError(), lstrlenA(lower_case) + 1);
1041 ok(!lstrcmpA(buf, upper_case), "LCMapStringA should return %s, but not %s\n", upper_case, buf);
1043 lstrcpyA(buf, upper_case);
1044 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE,
1045 buf, -1, buf, sizeof(buf));
1046 if (!ret) /* Win9x */
1047 trace("Ignoring LCMapStringA(LCMAP_LOWERCASE, buf, buf) error on Win9x\n");
1048 else
1050 ok(ret == lstrlenA(upper_case) + 1,
1051 "ret %d, error %ld, expected value %d\n",
1052 ret, GetLastError(), lstrlenA(lower_case) + 1);
1053 ok(!lstrcmpA(buf, lower_case), "LCMapStringA should return %s, but not %s\n", lower_case, buf);
1056 /* otherwise src == dst should fail */
1057 SetLastError(0xdeadbeef);
1058 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | LCMAP_UPPERCASE,
1059 buf, 10, buf, sizeof(buf));
1060 ok(GetLastError() == ERROR_INVALID_FLAGS /* NT */ ||
1061 GetLastError() == ERROR_INVALID_PARAMETER /* Win9x */,
1062 "unexpected error code %ld\n", GetLastError());
1063 ok(!ret, "src == dst without LCMAP_UPPERCASE or LCMAP_LOWERCASE must fail\n");
1065 /* test whether '\0' is always appended */
1066 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1067 upper_case, -1, buf, sizeof(buf));
1068 ok(ret, "LCMapStringA must succeed\n");
1069 ret2 = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1070 upper_case, lstrlenA(upper_case), buf2, sizeof(buf2));
1071 ok(ret, "LCMapStringA must succeed\n");
1072 ok(ret == ret2, "lengths of sort keys must be equal\n");
1073 ok(!lstrcmpA(buf, buf2), "sort keys must be equal\n");
1075 /* test LCMAP_SORTKEY | NORM_IGNORECASE */
1076 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | NORM_IGNORECASE,
1077 upper_case, -1, buf, sizeof(buf));
1078 ok(ret, "LCMapStringA must succeed\n");
1079 ret2 = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1080 lower_case, -1, buf2, sizeof(buf2));
1081 ok(ret2, "LCMapStringA must succeed\n");
1082 ok(ret == ret2, "lengths of sort keys must be equal\n");
1083 ok(!lstrcmpA(buf, buf2), "sort keys must be equal\n");
1085 /* test LCMAP_SORTKEY | NORM_IGNORENONSPACE */
1086 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | NORM_IGNORENONSPACE,
1087 lower_case, -1, buf, sizeof(buf));
1088 ok(ret, "LCMapStringA must succeed\n");
1089 ret2 = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1090 lower_case, -1, buf2, sizeof(buf2));
1091 ok(ret2, "LCMapStringA must succeed\n");
1092 ok(ret == ret2, "lengths of sort keys must be equal\n");
1093 ok(!lstrcmpA(buf, buf2), "sort keys must be equal\n");
1095 /* test LCMAP_SORTKEY | NORM_IGNORESYMBOLS */
1096 ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | NORM_IGNORESYMBOLS,
1097 lower_case, -1, buf, sizeof(buf));
1098 ok(ret, "LCMapStringA must succeed\n");
1099 ret2 = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1100 symbols_stripped, -1, buf2, sizeof(buf2));
1101 ok(ret2, "LCMapStringA must succeed\n");
1102 ok(ret == ret2, "lengths of sort keys must be equal\n");
1103 ok(!lstrcmpA(buf, buf2), "sort keys must be equal\n");
1105 /* test NORM_IGNORENONSPACE */
1106 lstrcpyA(buf, "foo");
1107 ret = LCMapStringA(LOCALE_USER_DEFAULT, NORM_IGNORENONSPACE,
1108 lower_case, -1, buf, sizeof(buf));
1109 ok(ret == lstrlenA(lower_case) + 1, "LCMapStringA should return %d, ret = %d\n",
1110 lstrlenA(lower_case) + 1, ret);
1111 ok(!lstrcmpA(buf, lower_case), "LCMapStringA should return %s, but not %s\n", lower_case, buf);
1113 /* test NORM_IGNORESYMBOLS */
1114 lstrcpyA(buf, "foo");
1115 ret = LCMapStringA(LOCALE_USER_DEFAULT, NORM_IGNORESYMBOLS,
1116 lower_case, -1, buf, sizeof(buf));
1117 ok(ret == lstrlenA(symbols_stripped) + 1, "LCMapStringA should return %d, ret = %d\n",
1118 lstrlenA(symbols_stripped) + 1, ret);
1119 ok(!lstrcmpA(buf, symbols_stripped), "LCMapStringA should return %s, but not %s\n", lower_case, buf);
1121 /* test srclen = 0 */
1122 SetLastError(0xdeadbeef);
1123 ret = LCMapStringA(LOCALE_USER_DEFAULT, 0, upper_case, 0, buf, sizeof(buf));
1124 ok(!ret, "LCMapStringA should fail with srclen = 0\n");
1125 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1126 "unexpected error code %ld\n", GetLastError());
1129 void test_LCMapStringW(void)
1131 int ret, ret2;
1132 WCHAR buf[256], buf2[256];
1133 char *p_buf = (char *)buf, *p_buf2 = (char *)buf2;
1134 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};
1135 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};
1136 static const WCHAR symbols_stripped[] = {'j','u','s','t','a','t','e','s','t','s','t','r','i','n','g','1',0};
1137 static const WCHAR fooW[] = {'f','o','o',0};
1139 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE | LCMAP_UPPERCASE,
1140 upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1141 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1143 trace("Skipping LCMapStringW tests on Win9x\n");
1144 return;
1146 ok(!ret, "LCMAP_LOWERCASE and LCMAP_UPPERCASE are mutually exclusive\n");
1147 ok(GetLastError() == ERROR_INVALID_FLAGS,
1148 "unexpected error code %ld\n", GetLastError());
1150 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_HIRAGANA | LCMAP_KATAKANA,
1151 upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1152 ok(!ret, "LCMAP_HIRAGANA and LCMAP_KATAKANA are mutually exclusive\n");
1153 ok(GetLastError() == ERROR_INVALID_FLAGS,
1154 "unexpected error code %ld\n", GetLastError());
1156 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_HALFWIDTH | LCMAP_FULLWIDTH,
1157 upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1158 ok(!ret, "LCMAP_HALFWIDTH | LCMAP_FULLWIDTH are mutually exclusive\n");
1159 ok(GetLastError() == ERROR_INVALID_FLAGS,
1160 "unexpected error code %ld\n", GetLastError());
1162 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_TRADITIONAL_CHINESE | LCMAP_SIMPLIFIED_CHINESE,
1163 upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1164 ok(!ret, "LCMAP_TRADITIONAL_CHINESE and LCMAP_SIMPLIFIED_CHINESE are mutually exclusive\n");
1165 ok(GetLastError() == ERROR_INVALID_FLAGS,
1166 "unexpected error code %ld\n", GetLastError());
1168 /* SORT_STRINGSORT must be used exclusively with LCMAP_SORTKEY */
1169 SetLastError(0xdeadbeef);
1170 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE | SORT_STRINGSORT,
1171 upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1172 ok(GetLastError() == ERROR_INVALID_FLAGS, "expected ERROR_INVALID_FLAGS, got %ld\n", GetLastError());
1173 ok(!ret, "SORT_STRINGSORT without LCMAP_SORTKEY must fail\n");
1175 /* test LCMAP_LOWERCASE */
1176 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE,
1177 upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1178 ok(ret == lstrlenW(upper_case) + 1,
1179 "ret %d, error %ld, expected value %d\n",
1180 ret, GetLastError(), lstrlenW(upper_case) + 1);
1181 ok(!lstrcmpW(buf, lower_case), "string compare mismatch\n");
1183 /* test LCMAP_UPPERCASE */
1184 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE,
1185 lower_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1186 ok(ret == lstrlenW(lower_case) + 1,
1187 "ret %d, error %ld, expected value %d\n",
1188 ret, GetLastError(), lstrlenW(lower_case) + 1);
1189 ok(!lstrcmpW(buf, upper_case), "string compare mismatch\n");
1191 /* test buffer overflow */
1192 SetLastError(0xdeadbeef);
1193 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE,
1194 lower_case, -1, buf, 4);
1195 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1196 "should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d\n", ret);
1198 /* LCMAP_UPPERCASE or LCMAP_LOWERCASE should accept src == dst */
1199 lstrcpyW(buf, lower_case);
1200 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE,
1201 buf, -1, buf, sizeof(buf)/sizeof(WCHAR));
1202 ok(ret == lstrlenW(lower_case) + 1,
1203 "ret %d, error %ld, expected value %d\n",
1204 ret, GetLastError(), lstrlenW(lower_case) + 1);
1205 ok(!lstrcmpW(buf, upper_case), "string compare mismatch\n");
1207 lstrcpyW(buf, upper_case);
1208 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE,
1209 buf, -1, buf, sizeof(buf)/sizeof(WCHAR));
1210 ok(ret == lstrlenW(upper_case) + 1,
1211 "ret %d, error %ld, expected value %d\n",
1212 ret, GetLastError(), lstrlenW(lower_case) + 1);
1213 ok(!lstrcmpW(buf, lower_case), "string compare mismatch\n");
1215 /* otherwise src == dst should fail */
1216 SetLastError(0xdeadbeef);
1217 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | LCMAP_UPPERCASE,
1218 buf, 10, buf, sizeof(buf));
1219 ok(GetLastError() == ERROR_INVALID_FLAGS /* NT */ ||
1220 GetLastError() == ERROR_INVALID_PARAMETER /* Win9x */,
1221 "unexpected error code %ld\n", GetLastError());
1222 ok(!ret, "src == dst without LCMAP_UPPERCASE or LCMAP_LOWERCASE must fail\n");
1224 /* test whether '\0' is always appended */
1225 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1226 upper_case, -1, buf, sizeof(buf));
1227 ok(ret, "LCMapStringW must succeed\n");
1228 ret2 = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1229 upper_case, lstrlenW(upper_case), buf2, sizeof(buf2));
1230 ok(ret, "LCMapStringW must succeed\n");
1231 ok(ret == ret2, "lengths of sort keys must be equal\n");
1232 ok(!lstrcmpA(p_buf, p_buf2), "sort keys must be equal\n");
1234 /* test LCMAP_SORTKEY | NORM_IGNORECASE */
1235 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | NORM_IGNORECASE,
1236 upper_case, -1, buf, sizeof(buf));
1237 ok(ret, "LCMapStringW must succeed\n");
1238 ret2 = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1239 lower_case, -1, buf2, sizeof(buf2));
1240 ok(ret2, "LCMapStringW must succeed\n");
1241 ok(ret == ret2, "lengths of sort keys must be equal\n");
1242 ok(!lstrcmpA(p_buf, p_buf2), "sort keys must be equal\n");
1244 /* test LCMAP_SORTKEY | NORM_IGNORENONSPACE */
1245 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | NORM_IGNORENONSPACE,
1246 lower_case, -1, buf, sizeof(buf));
1247 ok(ret, "LCMapStringW must succeed\n");
1248 ret2 = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1249 lower_case, -1, buf2, sizeof(buf2));
1250 ok(ret2, "LCMapStringW must succeed\n");
1251 ok(ret == ret2, "lengths of sort keys must be equal\n");
1252 ok(!lstrcmpA(p_buf, p_buf2), "sort keys must be equal\n");
1254 /* test LCMAP_SORTKEY | NORM_IGNORESYMBOLS */
1255 ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | NORM_IGNORESYMBOLS,
1256 lower_case, -1, buf, sizeof(buf));
1257 ok(ret, "LCMapStringW must succeed\n");
1258 ret2 = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1259 symbols_stripped, -1, buf2, sizeof(buf2));
1260 ok(ret2, "LCMapStringW must succeed\n");
1261 ok(ret == ret2, "lengths of sort keys must be equal\n");
1262 ok(!lstrcmpA(p_buf, p_buf2), "sort keys must be equal\n");
1264 /* test NORM_IGNORENONSPACE */
1265 lstrcpyW(buf, fooW);
1266 ret = LCMapStringW(LOCALE_USER_DEFAULT, NORM_IGNORENONSPACE,
1267 lower_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1268 ok(ret == lstrlenW(lower_case) + 1, "LCMapStringW should return %d, ret = %d\n",
1269 lstrlenW(lower_case) + 1, ret);
1270 ok(!lstrcmpW(buf, lower_case), "string comparison mismatch\n");
1272 /* test NORM_IGNORESYMBOLS */
1273 lstrcpyW(buf, fooW);
1274 ret = LCMapStringW(LOCALE_USER_DEFAULT, NORM_IGNORESYMBOLS,
1275 lower_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1276 ok(ret == lstrlenW(symbols_stripped) + 1, "LCMapStringW should return %d, ret = %d\n",
1277 lstrlenW(symbols_stripped) + 1, ret);
1278 ok(!lstrcmpW(buf, symbols_stripped), "string comparison mismatch\n");
1280 /* test srclen = 0 */
1281 SetLastError(0xdeadbeef);
1282 ret = LCMapStringW(LOCALE_USER_DEFAULT, 0, upper_case, 0, buf, sizeof(buf));
1283 ok(!ret, "LCMapStringW should fail with srclen = 0\n");
1284 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1285 "unexpected error code %ld\n", GetLastError());
1288 #if 0 /* this requires collation table patch to make it MS compatible */
1289 const char *strings_sorted[] =
1291 "'",
1292 "-",
1293 "!",
1294 "\"",
1295 ".",
1296 ":",
1297 "\\",
1298 "_",
1299 "`",
1300 "{",
1301 "}",
1302 "+",
1303 "0",
1304 "1",
1305 "2",
1306 "3",
1307 "4",
1308 "5",
1309 "6",
1310 "7",
1311 "8",
1312 "9",
1313 "a",
1314 "A",
1315 "b",
1316 "B",
1317 "c",
1321 const char *strings[] =
1323 "C",
1324 "\"",
1325 "9",
1326 "'",
1327 "}",
1328 "-",
1329 "7",
1330 "+",
1331 "`",
1332 "1",
1333 "a",
1334 "5",
1335 "\\",
1336 "8",
1337 "B",
1338 "3",
1339 "_",
1340 "6",
1341 "{",
1342 "2",
1343 "c",
1344 "4",
1345 "!",
1346 "0",
1347 "A",
1348 ":",
1349 "b",
1353 static int compare_string1(const void *e1, const void *e2)
1355 const char *s1 = *(const char **)e1;
1356 const char *s2 = *(const char **)e2;
1358 return lstrcmpA(s1, s2);
1361 static int compare_string2(const void *e1, const void *e2)
1363 const char *s1 = *(const char **)e1;
1364 const char *s2 = *(const char **)e2;
1366 return CompareStringA(0, 0, s1, -1, s2, -1) - 2;
1369 static int compare_string3(const void *e1, const void *e2)
1371 const char *s1 = *(const char **)e1;
1372 const char *s2 = *(const char **)e2;
1373 char key1[256], key2[256];
1375 LCMapStringA(0, LCMAP_SORTKEY, s1, -1, key1, sizeof(key1));
1376 LCMapStringA(0, LCMAP_SORTKEY, s2, -1, key2, sizeof(key2));
1377 return strcmp(key1, key2);
1380 static void test_sorting(void)
1382 char buf[256];
1383 char **str_buf = (char **)buf;
1384 int i;
1386 assert(sizeof(buf) >= sizeof(strings));
1388 /* 1. sort using lstrcmpA */
1389 memcpy(buf, strings, sizeof(strings));
1390 qsort(buf, sizeof(strings)/sizeof(strings[0]), sizeof(strings[0]), compare_string1);
1391 for (i = 0; i < sizeof(strings)/sizeof(strings[0]); i++)
1393 ok(!strcmp(strings_sorted[i], str_buf[i]),
1394 "qsort using lstrcmpA failed for element %d\n", i);
1396 /* 2. sort using CompareStringA */
1397 memcpy(buf, strings, sizeof(strings));
1398 qsort(buf, sizeof(strings)/sizeof(strings[0]), sizeof(strings[0]), compare_string2);
1399 for (i = 0; i < sizeof(strings)/sizeof(strings[0]); i++)
1401 ok(!strcmp(strings_sorted[i], str_buf[i]),
1402 "qsort using CompareStringA failed for element %d\n", i);
1404 /* 3. sort using sort keys */
1405 memcpy(buf, strings, sizeof(strings));
1406 qsort(buf, sizeof(strings)/sizeof(strings[0]), sizeof(strings[0]), compare_string3);
1407 for (i = 0; i < sizeof(strings)/sizeof(strings[0]); i++)
1409 ok(!strcmp(strings_sorted[i], str_buf[i]),
1410 "qsort using sort keys failed for element %d\n", i);
1413 #endif
1415 static void test_FoldStringA(void)
1417 int ret, i;
1418 char src[256], dst[256];
1419 static const char digits_src[] = { 0xB9,0xB2,0xB3,'\0' };
1420 static const char digits_dst[] = { '1','2','3','\0' };
1421 static const char composite_src[] =
1423 0x8a,0x8e,0x9a,0x9e,0x9f,0xc0,0xc1,0xc2,
1424 0xc3,0xc4,0xc5,0xc7,0xc8,0xc9,0xca,0xcb,
1425 0xcc,0xcd,0xce,0xcf,0xd1,0xd2,0xd3,0xd4,
1426 0xd5,0xd6,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,
1427 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe7,0xe8,
1428 0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf1,
1429 0xf2,0xf3,0xf4,0xf5,0xf6,0xf8,0xf9,0xfa,
1430 0xfb,0xfc,0xfd,0xff,'\0'
1432 static const char composite_dst[] =
1434 0x53,0x3f,0x5a,0x3f,0x73,0x3f,0x7a,0x3f,
1435 0x59,0xa8,0x41,0x60,0x41,0xb4,0x41,0x5e,
1436 0x41,0x7e,0x41,0xa8,0x41,0xb0,0x43,0xb8,
1437 0x45,0x60,0x45,0xb4,0x45,0x5e,0x45,0xa8,
1438 0x49,0x60,0x49,0xb4,0x49,0x5e,0x49,0xa8,
1439 0x4e,0x7e,0x4f,0x60,0x4f,0xb4,0x4f,0x5e,
1440 0x4f,0x7e,0x4f,0xa8,0x4f,0x3f,0x55,0x60,
1441 0x55,0xb4,0x55,0x5e,0x55,0xa8,0x59,0xb4,
1442 0x61,0x60,0x61,0xb4,0x61,0x5e,0x61,0x7e,
1443 0x61,0xa8,0x61,0xb0,0x63,0xb8,0x65,0x60,
1444 0x65,0xb4,0x65,0x5e,0x65,0xa8,0x69,0x60,
1445 0x69,0xb4,0x69,0x5e,0x69,0xa8,0x6e,0x7e,
1446 0x6f,0x60,0x6f,0xb4,0x6f,0x5e,0x6f,0x7e,
1447 0x6f,0xa8,0x6f,0x3f,0x75,0x60,0x75,0xb4,
1448 0x75,0x5e,0x75,0xa8,0x79,0xb4,0x79,0xa8,'\0'
1450 static const char ligatures_src[] =
1452 0x8C,0x9C,0xC6,0xDE,0xDF,0xE6,0xFE,'\0'
1454 static const char ligatures_dst[] =
1456 'O','E','o','e','A','E','T','H','s','s','a','e','t','h','\0'
1459 if (!pFoldStringA)
1460 return; /* FoldString is present in NT v3.1+, but not 95/98/Me */
1462 /* these tests are locale specific */
1463 if (GetACP() != 1252)
1465 trace("Skipping FoldStringA tests for a not Latin 1 locale\n");
1466 return;
1469 /* MAP_FOLDDIGITS */
1470 SetLastError(0);
1471 ret = pFoldStringA(MAP_FOLDDIGITS, digits_src, -1, dst, 256);
1472 if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
1473 return;
1474 EXPECT_LEN(4); EXPECT_VALID;
1475 ok(strcmp(dst, digits_dst) == 0,
1476 "MAP_FOLDDIGITS: Expected '%s', got '%s'\n", digits_dst, dst);
1477 for (i = 1; i < 256; i++)
1479 if (!strchr(digits_src, i))
1481 src[0] = i;
1482 src[1] = '\0';
1483 SetLastError(0);
1484 ret = pFoldStringA(MAP_FOLDDIGITS, src, -1, dst, 256);
1485 EXPECT_LEN(2); EXPECT_VALID;
1486 ok(dst[0] == src[0],
1487 "MAP_FOLDDIGITS: Expected '%s', got '%s'\n", src, dst);
1491 /* MAP_EXPAND_LIGATURES */
1492 SetLastError(0);
1493 ret = pFoldStringA(MAP_EXPAND_LIGATURES, ligatures_src, -1, dst, 256);
1494 /* NT 4.0 doesn't support MAP_EXPAND_LIGATURES */
1495 if (!(ret == 0 && GetLastError() == ERROR_INVALID_FLAGS)) {
1496 EXPECT_LEN(sizeof(ligatures_dst)); EXPECT_VALID;
1497 ok(strcmp(dst, ligatures_dst) == 0,
1498 "MAP_EXPAND_LIGATURES: Expected '%s', got '%s'\n", ligatures_dst, dst);
1499 for (i = 1; i < 256; i++)
1501 if (!strchr(ligatures_src, i))
1503 src[0] = i;
1504 src[1] = '\0';
1505 SetLastError(0);
1506 ret = pFoldStringA(MAP_EXPAND_LIGATURES, src, -1, dst, 256);
1507 EXPECT_LEN(2); EXPECT_VALID;
1508 ok(dst[0] == src[0],
1509 "MAP_EXPAND_LIGATURES: Expected '%s', got '%s'\n", src, dst);
1514 /* MAP_COMPOSITE */
1515 SetLastError(0);
1516 ret = pFoldStringA(MAP_COMPOSITE, composite_src, -1, dst, 256);
1517 EXPECT_VALID;
1518 todo_wine
1520 /* Wine gets close, but doesn't produce quite the same result as native */
1521 EXPECT_LEN(121);
1522 ok(strcmp(dst, composite_dst) == 0,
1523 "MAP_COMPOSITE: Expected '%s', got '%s'\n", composite_dst, dst);
1526 for (i = 1; i < 256; i++)
1528 if (!strchr(composite_src, i))
1530 src[0] = i;
1531 src[1] = '\0';
1532 SetLastError(0);
1533 ret = pFoldStringA(MAP_COMPOSITE, src, -1, dst, 256);
1534 EXPECT_LEN(2); EXPECT_VALID;
1535 ok(dst[0] == src[0],
1536 "0x%02x, 0x%02x,0x%02x,0x%02x,\n", (unsigned char)src[0],
1537 (unsigned char)dst[0],(unsigned char)dst[1],(unsigned char)dst[2]);
1541 /* MAP_FOLDCZONE */
1542 for (i = 1; i < 256; i++)
1544 src[0] = i;
1545 src[1] = '\0';
1546 SetLastError(0);
1547 ret = pFoldStringA(MAP_FOLDCZONE, src, -1, dst, 256);
1548 EXPECT_LEN(2); EXPECT_VALID;
1549 ok(src[0] == dst[0],
1550 "MAP_FOLDCZONE: Expected 0x%02x, got 0x%02x\n",
1551 (unsigned char)src[0], (unsigned char)dst[0]);
1554 /* MAP_PRECOMPOSED */
1555 for (i = 1; i < 256; i++)
1557 src[0] = i;
1558 src[1] = '\0';
1559 SetLastError(0);
1560 ret = pFoldStringA(MAP_PRECOMPOSED, src, -1, dst, 256);
1561 EXPECT_LEN(2); EXPECT_VALID;
1562 ok(src[0] == dst[0],
1563 "MAP_PRECOMPOSED: Expected 0x%02x, got 0x%02x\n",
1564 (unsigned char)src[0], (unsigned char)dst[0]);
1568 static void test_FoldStringW(void)
1570 int ret;
1571 size_t i, j;
1572 WCHAR src[256], dst[256], ch, prev_ch = 1;
1573 static const DWORD badFlags[] =
1576 MAP_PRECOMPOSED|MAP_COMPOSITE,
1577 MAP_PRECOMPOSED|MAP_EXPAND_LIGATURES,
1578 MAP_COMPOSITE|MAP_EXPAND_LIGATURES
1580 /* Ranges of digits 0-9 : Must be sorted! */
1581 static const WCHAR digitRanges[] =
1583 0x0030, /* '0'-'9' */
1584 0x0660, /* Eastern Arabic */
1585 0x06F0, /* Arabic - Hindu */
1586 0x0966, /* Devengari */
1587 0x09E6, /* Bengalii */
1588 0x0A66, /* Gurmukhi */
1589 0x0AE6, /* Gujarati */
1590 0x0B66, /* Oriya */
1591 0x0BE6, /* Tamil - No 0 */
1592 0x0C66, /* Telugu */
1593 0x0CE6, /* Kannada */
1594 0x0D66, /* Maylayalam */
1595 0x0E50, /* Thai */
1596 0x0ED0, /* Laos */
1597 0x2070, /* Superscript - 1, 2, 3 are out of sequence */
1598 0x2080, /* Subscript */
1599 0x245F, /* Circled - 0 is out of sequence */
1600 0x2473, /* Bracketed */
1601 0x2487, /* Full stop */
1602 0x2775, /* Inverted circled - No 0 */
1603 0x277F, /* Patterned circled - No 0 */
1604 0x2789, /* Inverted Patterned circled - No 0 */
1605 0xff10, /* Pliene chasse (?) */
1606 0xffff /* Terminator */
1608 /* Digits which are represented, but out of sequence */
1609 static const WCHAR outOfSequenceDigits[] =
1611 0xB9, /* Superscript 1 */
1612 0xB2, /* Superscript 2 */
1613 0xB3, /* Superscript 3 */
1614 0x24EA, /* Circled 0 */
1615 '\0' /* Terminator */
1617 /* Digits in digitRanges for which no representation is available */
1618 static const WCHAR noDigitAvailable[] =
1620 0x0BE6, /* No Tamil 0 */
1621 0x2473, /* No Bracketed 0 */
1622 0x2487, /* No 0 Full stop */
1623 0x2775, /* No inverted circled 0 */
1624 0x277F, /* No patterned circled */
1625 0x2789, /* No inverted Patterned circled */
1626 '\0' /* Terminator */
1628 /* Compatibility conversion results */
1629 static const WCHAR compat_F900_FA2F[256+48] =
1631 0x8c48, 0x66f4, 0x8eca, 0x8cc8, 0x6ed1, 0x4e32, 0x53e5, 0x9f9c,
1632 0x9f9c, 0x5951, 0x91d1, 0x5587, 0x5948, 0x61f6, 0x7669, 0x7f85,
1633 0x863f, 0x87ba, 0x88f8, 0x908f, 0x6a02, 0x6d1b, 0x70d9, 0x73de,
1634 0x843d, 0x916a, 0x99f1, 0x4e82, 0x5375, 0x6b04, 0x721b, 0x862d,
1635 0x9e1e, 0x5d50, 0x6feb, 0x85cd, 0x8964, 0x62c9, 0x81d8, 0x881f,
1636 0x5eca, 0x6717, 0x6d6a, 0x72fc, 0x0000, 0x4f86, 0x51b7, 0x52de,
1637 0x64c4, 0x6ad3, 0x7210, 0x76e7, 0x8001, 0x8606, 0x865c, 0x8def,
1638 0x9732, 0x9b6f, 0x9dfa, 0x788c, 0x797f, 0x7da0, 0x83c9, 0x9304,
1639 0x9e7f, 0x8ad6, 0x58df, 0x5f04, 0x7c60, 0x807e, 0x7262, 0x78ca,
1640 0x8cc2, 0x96f7, 0x58d8, 0x5c62, 0x6a13, 0x6dda, 0x6f0f, 0x7d2f,
1641 0x7e37, 0x964b, 0x52d2, 0x808b, 0x51dc, 0x51cc, 0x7a1c, 0x7dbe,
1642 0x83f1, 0x9675, 0x8b80, 0x62cf, 0x6a02, 0x8afe, 0x4e39, 0x5be7,
1643 0x6012, 0x7387, 0x7570, 0x5317, 0x78fb, 0x4fbf, 0x5fa9, 0x4e0d,
1644 0x6ccc, 0x6578, 0x7d22, 0x53c3, 0x585e, 0x7701, 0x8449, 0x8aaa,
1645 0x6bba, 0x8fb0, 0x6c88, 0x62fe, 0x82e5, 0x63a0, 0x7565, 0x4eae,
1646 0x5169, 0x0000, 0x6881, 0x7ce7, 0x826f, 0x8ad2, 0x91cf, 0x52f5,
1647 0x5442, 0x5973, 0x5eec, 0x65c5, 0x6ffe, 0x792a, 0x95ad, 0x9a6a,
1648 0x9e97, 0x9ece, 0x529b, 0x66c6, 0x6b77, 0x8f62, 0x5e74, 0x6190,
1649 0x6200, 0x649a, 0x6f23, 0x7149, 0x7489, 0x0000, 0x7df4, 0x806f,
1650 0x8f26, 0x84ee, 0x9023, 0x934a, 0x5217, 0x52a3, 0x54bd, 0x70c8,
1651 0x88c2, 0x8aaa, 0x5ec9, 0x5ff5, 0x637b, 0x6bae, 0x7c3e, 0x7375,
1652 0x4ee4, 0x56f9, 0x5be7, 0x5dba, 0x601c, 0x73b2, 0x7469, 0x7f9a,
1653 0x8046, 0x9234, 0x96f6, 0x9748, 0x9818, 0x4f8b, 0x79ae, 0x91b4,
1654 0x96b8, 0x60e1, 0x4e86, 0x50da, 0x5bee, 0x5c3f, 0x6599, 0x6a02,
1655 0x71ce, 0x7642, 0x84fc, 0x907c, 0x9f8d, 0x6688, 0x962e, 0x5289,
1656 0x677b, 0x67f3, 0x6d41, 0x6e9c, 0x7409, 0x7559, 0x786b, 0x7d10,
1657 0x985e, 0x516d, 0x622e, 0x9678, 0x502b, 0x5d19, 0x6dea, 0x8f2a,
1658 0x5f8b, 0x6144, 0x6817, 0x7387, 0x9686, 0x5229, 0x540f, 0x5c65,
1659 0x6613, 0x674e, 0x68a8, 0x6ce5, 0x7406, 0x75e2, 0x7f79, 0x0000,
1660 0x88e1, 0x91cc, 0x96e2, 0x533f, 0x6eba, 0x541d, 0x71d0, 0x7498,
1661 0x85fa, 0x0000, 0x9c57, 0x9e9f, 0x6797, 0x6dcb, 0x81e8, 0x7acb,
1662 0x7b20, 0x7c92, 0x72c0, 0x7099, 0x8b58, 0x4ec0, 0x8336, 0x523a,
1663 0x5207, 0x5ea6, 0x62d3, 0x7cd6, 0x5b85, 0x6d1e, 0x66b4, 0x8f3b,
1664 0x884c, 0x964d, 0x898b, 0x5ed3, 0x0000, 0x0000, 0x0000, 0x0000,
1665 0x585a, 0x0000, 0x6674, 0x0000, 0x0000, 0x51de, 0x8c6c, 0x76ca,
1666 0x0000, 0x795e, 0x7965, 0x798f, 0x9756, 0x7cbe, 0x7fbd, 0x0000,
1667 0x0000, 0x0000, 0x8af8, 0x0000, 0x0000, 0x9038, 0x90fd, 0x0000,
1668 0x0000, 0x0000, 0x98ef, 0x98fc, 0x9928, 0x9db4, 0x0000, 0x0000
1670 static const WCHAR compat_FE30_FEF7[200] =
1672 0x2025, 0x2014, 0x2013, 0x005f, 0x005f, 0x0028, 0x0029, 0x007b,
1673 0x007d, 0x3014, 0x3015, 0x3010, 0x3011, 0x300a, 0x300b, 0x3008,
1674 0x3009, 0x300c, 0x300d, 0x300e, 0x300f, 0x0000, 0x0000, 0x0000,
1675 0x0000, 0x203e, 0x203e, 0x203e, 0x203e, 0x005f, 0x005f, 0x005f,
1676 0x002c, 0x3001, 0x002e, 0x0000, 0x003b, 0x003a, 0x003f, 0x0021,
1677 0x2014, 0x0028, 0x0029, 0x007b, 0x007d, 0x3014, 0x3015, 0x0023,
1678 0x0026, 0x002a, 0x002b, 0x002d, 0x003c, 0x003e, 0x003d, 0x0000,
1679 0x0000, 0x0024, 0x0025, 0x0040, 0x0000, 0x0000, 0x0000, 0x0000,
1680 0x064b, 0x064b, 0x064c, 0x0000, 0x064d, 0x0000, 0x064e, 0x064e,
1681 0x064f, 0x064f, 0x0650, 0x0650, 0x0651, 0x0651, 0x0652, 0x0652,
1682 0x0621, 0x0622, 0x0622, 0x0623, 0x0623, 0x0624, 0x0624, 0x0625,
1683 0x0625, 0x0626, 0x0626, 0x0626, 0x0626, 0x0627, 0x0627, 0x0628,
1684 0x0628, 0x0628, 0x0628, 0x0629, 0x0629, 0x062a, 0x062a, 0x062a,
1685 0x062a, 0x062b, 0x062b, 0x062b, 0x062b, 0x062c, 0x062c, 0x062c,
1686 0x062c, 0x062d, 0x062d, 0x062d, 0x062d, 0x062e, 0x062e, 0x062e,
1687 0x062e, 0x062f, 0x062f, 0x0630, 0x0630, 0x0631, 0x0631, 0x0632,
1688 0x0632, 0x0633, 0x0633, 0x0633, 0x0633, 0x0634, 0x0634, 0x0634,
1689 0x0634, 0x0635, 0x0635, 0x0635, 0x0635, 0x0636, 0x0636, 0x0636,
1690 0x0636, 0x0637, 0x0637, 0x0637, 0x0637, 0x0638, 0x0638, 0x0638,
1691 0x0638, 0x0639, 0x0639, 0x0639, 0x0639, 0x063a, 0x063a, 0x063a,
1692 0x063a, 0x0641, 0x0641, 0x0641, 0x0641, 0x0642, 0x0642, 0x0642,
1693 0x0642, 0x0643, 0x0643, 0x0643, 0x0643, 0x0644, 0x0644, 0x0644,
1694 0x0644, 0x0645, 0x0645, 0x0645, 0x0645, 0x0646, 0x0646, 0x0646,
1695 0x0646, 0x0647, 0x0647, 0x0647, 0x0647, 0x0648, 0x0648, 0x0649,
1696 0x0649, 0x064a, 0x064a, 0x064a, 0x064a, 0x0000, 0x0000, 0x0000
1698 static const WCHAR compat_FF00_FFEF[240] =
1700 0x0000, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
1701 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
1702 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
1703 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
1704 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
1705 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
1706 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
1707 0x0058, 0x0059, 0x005a, 0x005b, 0x0000, 0x005d, 0x005e, 0x005f,
1708 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
1709 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
1710 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
1711 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0000,
1712 0x0000, 0x3002, 0x300c, 0x300d, 0x3001, 0x30fb, 0x30f2, 0x30a1,
1713 0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3,
1714 0x30fc, 0x30a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, 0x30ab, 0x30ad,
1715 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, 0x30bd,
1716 0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc,
1717 0x30cd, 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de,
1718 0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9,
1719 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f3, 0x309b, 0x309c,
1720 0x3164, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137,
1721 0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f,
1722 0x3140, 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147,
1723 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x0000,
1724 0x0000, 0x0000, 0x314f, 0x3150, 0x3151, 0x3152, 0x3153, 0x3154,
1725 0x0000, 0x0000, 0x3155, 0x3156, 0x3157, 0x3158, 0x3159, 0x315a,
1726 0x0000, 0x0000, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f, 0x3160,
1727 0x0000, 0x0000, 0x3161, 0x3162, 0x3163, 0x0000, 0x0000, 0x0000,
1728 0x00a2, 0x00a3, 0x00ac, 0x00af, 0x00a6, 0x00a5, 0x20a9, 0x0000,
1729 0x2502, 0x2190, 0x2191, 0x2192, 0x2193, 0x25a0, 0x25cb, 0x0000
1731 static const WCHAR ligatures_src[] =
1733 0x00c6, 0x00de, 0x00df, 0x00e6, 0x00fe, 0x0132, 0x0133, 0x0152,
1734 0x0153, 0x01c4, 0x01c5, 0x01c6, 0x01c7, 0x01c8, 0x01c9, 0x01ca,
1735 0x01cb, 0x01cc, 0x01e2, 0x01e3, 0x01f1, 0x01f2, 0x01f3, 0x01fc,
1736 0x01fd, 0x05f0, 0x05f1, 0x05f2, 0xfb00, 0xfb01, 0xfb02, 0xfb03,
1737 0xfb04, 0xfb05, 0xfb06, '\0'
1739 static const WCHAR ligatures_dst[] =
1741 'A','E','T','H','s','s','a','e','t','h','I','J','i','j','O','E','o','e',
1742 'D',0x017d,'D',0x017e,'d',0x017e,'L','J','L','j','l','j','N','J','N','j',
1743 'n','j',0x0100,0x0112,0x0101,0x0113,'D','Z','D','z','d','z',0x00c1,0x00c9,
1744 0x00e1,0x00e9,0x05d5,0x05d5,0x05d5,0x05d9,0x05d9,0x05d9,'f','f','f','i',
1745 'f','l','f','f','i','f','f','l',0x017f,'t','s','t','\0'
1748 if (!pFoldStringW)
1749 return; /* FoldString is present in NT v3.1+, but not 95/98/Me */
1751 /* Invalid flag combinations */
1752 for (i = 0; i < sizeof(badFlags)/sizeof(badFlags[0]); i++)
1754 src[0] = dst[0] = '\0';
1755 SetLastError(0);
1756 ret = pFoldStringW(badFlags[i], src, 256, dst, 256);
1757 if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
1758 return;
1759 EXPECT_LEN(0); EXPECT_FLAGS;
1762 /* src & dst cannot be the same */
1763 SetLastError(0);
1764 ret = pFoldStringW(MAP_FOLDCZONE, src, -1, src, 256);
1765 EXPECT_LEN(0); EXPECT_INVALID;
1767 /* src can't be NULL */
1768 SetLastError(0);
1769 ret = pFoldStringW(MAP_FOLDCZONE, NULL, -1, dst, 256);
1770 EXPECT_LEN(0); EXPECT_INVALID;
1772 /* srclen can't be 0 */
1773 SetLastError(0);
1774 ret = pFoldStringW(MAP_FOLDCZONE, src, 0, dst, 256);
1775 EXPECT_LEN(0); EXPECT_INVALID;
1777 /* dstlen can't be < 0 */
1778 SetLastError(0);
1779 ret = pFoldStringW(MAP_FOLDCZONE, src, -1, dst, -1);
1780 EXPECT_LEN(0); EXPECT_INVALID;
1782 /* Ret includes terminating NUL which is appended if srclen = -1 */
1783 SetLastError(0);
1784 src[0] = 'A';
1785 src[1] = '\0';
1786 dst[0] = '\0';
1787 ret = pFoldStringW(MAP_FOLDCZONE, src, -1, dst, 256);
1788 EXPECT_LEN(2); EXPECT_VALID;
1789 ok(dst[0] == 'A' && dst[1] == '\0',
1790 "srclen=-1: Expected ret=2 [%d,%d], got ret=%d [%d,%d], err=%ld\n",
1791 'A', '\0', ret, dst[0], dst[1], GetLastError());
1793 /* If size is given, result is not NUL terminated */
1794 SetLastError(0);
1795 src[0] = 'A';
1796 src[1] = 'A';
1797 dst[0] = 'X';
1798 dst[1] = 'X';
1799 ret = pFoldStringW(MAP_FOLDCZONE, src, 1, dst, 256);
1800 EXPECT_LEN(1); EXPECT_VALID;
1801 ok(dst[0] == 'A' && dst[1] == 'X',
1802 "srclen=1: Expected ret=1, [%d,%d], got ret=%d,[%d,%d], err=%ld\n",
1803 'A','X', ret, dst[0], dst[1], GetLastError());
1805 /* MAP_FOLDDIGITS */
1806 for (j = 0; j < sizeof(digitRanges)/sizeof(digitRanges[0]); j++)
1808 /* Check everything before this range */
1809 for (ch = prev_ch; ch < digitRanges[j]; ch++)
1811 SetLastError(0);
1812 src[0] = ch;
1813 src[1] = dst[0] = '\0';
1814 ret = pFoldStringW(MAP_FOLDDIGITS, src, -1, dst, 256);
1815 EXPECT_LEN(2); EXPECT_VALID;
1817 ok(dst[0] == ch || strchrW(outOfSequenceDigits, ch) ||
1818 /* Wine (correctly) maps all Unicode 4.0+ digits */
1819 isdigitW(ch) || (ch >= 0x24F5 && ch <= 0x24FD) || ch == 0x24FF,
1820 "MAP_FOLDDIGITS: ch %d 0x%04x Expected unchanged got %d\n", ch, ch, dst[0]);
1823 if (digitRanges[j] == 0xffff)
1824 break; /* Finished the whole code point space */
1826 for (ch = digitRanges[j]; ch < digitRanges[j] + 10; ch++)
1828 WCHAR c;
1830 /* Map out of sequence characters */
1831 if (ch == 0x2071) c = 0x00B9; /* Superscript 1 */
1832 else if (ch == 0x2072) c = 0x00B2; /* Superscript 2 */
1833 else if (ch == 0x2073) c = 0x00B3; /* Superscript 3 */
1834 else if (ch == 0x245F) c = 0x24EA; /* Circled 0 */
1835 else c = ch;
1836 SetLastError(0);
1837 src[0] = c;
1838 src[1] = dst[0] = '\0';
1839 ret = pFoldStringW(MAP_FOLDDIGITS, src, -1, dst, 256);
1840 EXPECT_LEN(2); EXPECT_VALID;
1842 ok((dst[0] == '0' + ch - digitRanges[j] && dst[1] == '\0') ||
1843 strchrW(noDigitAvailable, c),
1844 "MAP_FOLDDIGITS: ch %d Expected %d got %d\n",
1845 ch, '0' + digitRanges[j] - ch, dst[0]);
1847 prev_ch = ch;
1850 /* MAP_FOLDCZONE */
1851 for (ch = 1; ch <0xffff; ch++)
1853 WCHAR expected = 0;
1855 if (ch >= 0xF900 && ch <= 0xFA2F)
1856 expected = compat_F900_FA2F[ch - 0xF900];
1857 else if (ch >= 0xFE30 && ch <= 0xFEF7)
1858 expected = compat_FE30_FEF7[ch - 0xFE30];
1859 else if (ch >= 0xFF00 && ch <= 0xFFEF)
1860 expected = compat_FF00_FFEF[ch - 0xFF00];
1862 if (!expected)
1863 expected = ch;
1865 SetLastError(0);
1866 src[0] = ch;
1867 src[1] = dst[0] = '\0';
1868 ret = pFoldStringW(MAP_FOLDCZONE, src, -1, dst, 256);
1869 EXPECT_LEN(2); EXPECT_VALID;
1870 ok(dst[0] == expected ||
1871 /* Wine (correctly) uses updated mappings for some Unicode 4.0 chars */
1872 (ch >= 0xFA0D && ch <= 0xFA47) ||
1873 0xf92c || ch == 0xf979 || ch == 0xf995 || ch == 0xf9e7 || ch == 0xf9f1,
1874 "MAP_FOLDCZONE: ch %d 0x%04x Expected 0x%04x got 0x%04x\n",
1875 ch, ch, expected, dst[0]);
1878 /* MAP_EXPAND_LIGATURES */
1879 SetLastError(0);
1880 ret = pFoldStringW(MAP_EXPAND_LIGATURES, ligatures_src, -1, dst, 256);
1881 /* NT 4.0 doesn't support MAP_EXPAND_LIGATURES */
1882 if (!(ret == 0 && GetLastError() == ERROR_INVALID_FLAGS)) {
1883 EXPECT_LEN(sizeof(ligatures_dst)/sizeof(ligatures_dst[0])); EXPECT_VALID;
1884 ok(!memcmp(dst, ligatures_dst, sizeof(ligatures_dst)),
1885 "MAP_EXPAND_LIGATURES: Expanded incorrectly\n");
1886 for (i = 1; i <= 0xffff; i++)
1888 if (!strchrW(ligatures_src, i))
1890 src[0] = i;
1891 src[1] = '\0';
1892 SetLastError(0);
1893 ret = pFoldStringW(MAP_EXPAND_LIGATURES, src, -1, dst, 256);
1894 EXPECT_LEN(2); EXPECT_VALID;
1895 ok(dst[0] == src[0],
1896 "MAP_EXPAND_LIGATURES: 0x%02x : Expected 0x%02x, got 0x%02x\n",
1897 i, src[0], dst[0]);
1902 /* FIXME: MAP_PRECOMPOSED : MAP_COMPOSITE */
1907 #define LCID_OK(l) \
1908 ok(lcid == l, "Expected lcid = %08lx, got %08lx\n", l, lcid)
1909 #define MKLCID(x,y,z) MAKELCID(MAKELANGID(x, y), z)
1910 #define LCID_RES(src, res) lcid = ConvertDefaultLocale(src); LCID_OK(res)
1911 #define TEST_LCIDLANG(a,b) LCID_RES(MAKELCID(a,b), MAKELCID(a,b))
1912 #define TEST_LCID(a,b,c) LCID_RES(MKLCID(a,b,c), MKLCID(a,b,c))
1914 static void test_ConvertDefaultLocale(void)
1916 LCID lcid;
1918 /* Doesn't change lcid, even if non default sublang/sort used */
1919 TEST_LCID(LANG_ENGLISH, SUBLANG_ENGLISH_US, SORT_DEFAULT);
1920 TEST_LCID(LANG_ENGLISH, SUBLANG_ENGLISH_UK, SORT_DEFAULT);
1921 TEST_LCID(LANG_JAPANESE, SUBLANG_DEFAULT, SORT_DEFAULT);
1922 TEST_LCID(LANG_JAPANESE, SUBLANG_DEFAULT, SORT_JAPANESE_UNICODE);
1924 /* SUBLANG_NEUTRAL -> SUBLANG_DEFAULT */
1925 LCID_RES(MKLCID(LANG_ENGLISH, SUBLANG_NEUTRAL, SORT_DEFAULT),
1926 MKLCID(LANG_ENGLISH, SUBLANG_DEFAULT, SORT_DEFAULT));
1927 LCID_RES(MKLCID(LANG_JAPANESE, SUBLANG_NEUTRAL, SORT_DEFAULT),
1928 MKLCID(LANG_JAPANESE, SUBLANG_DEFAULT, SORT_DEFAULT));
1929 LCID_RES(MKLCID(LANG_JAPANESE, SUBLANG_NEUTRAL, SORT_JAPANESE_UNICODE),
1930 MKLCID(LANG_JAPANESE, SUBLANG_DEFAULT, SORT_JAPANESE_UNICODE));
1932 /* Invariant language is not treated specially */
1933 TEST_LCID(LANG_INVARIANT, SUBLANG_DEFAULT, SORT_DEFAULT);
1934 LCID_RES(MKLCID(LANG_INVARIANT, SUBLANG_NEUTRAL, SORT_DEFAULT),
1935 MKLCID(LANG_INVARIANT, SUBLANG_DEFAULT, SORT_DEFAULT));
1937 /* User/system default languages alone are not mapped */
1938 TEST_LCIDLANG(LANG_SYSTEM_DEFAULT, SORT_JAPANESE_UNICODE);
1939 TEST_LCIDLANG(LANG_USER_DEFAULT, SORT_JAPANESE_UNICODE);
1941 /* Default lcids */
1942 LCID_RES(LOCALE_SYSTEM_DEFAULT, GetSystemDefaultLCID());
1943 LCID_RES(LOCALE_USER_DEFAULT, GetUserDefaultLCID());
1944 LCID_RES(LOCALE_NEUTRAL, GetUserDefaultLCID());
1947 static BOOL CALLBACK langgrp_procA(LGRPID lgrpid, LPSTR lpszNum, LPSTR lpszName,
1948 DWORD dwFlags, LONG_PTR lParam)
1950 trace("%08lx, %s, %s, %08lx, %08lx\n",
1951 lgrpid, lpszNum, lpszName, dwFlags, lParam);
1953 ok(pIsValidLanguageGroup(lgrpid, dwFlags) == TRUE,
1954 "Enumerated grp %ld not valid (flags %ld)\n", lgrpid, dwFlags);
1956 /* If lParam is one, we are calling with flags defaulted from 0 */
1957 ok(!lParam || (dwFlags == LGRPID_INSTALLED || dwFlags == LGRPID_SUPPORTED),
1958 "Expected dwFlags == LGRPID_INSTALLED || dwFlags == LGRPID_SUPPORTED, got %ld\n", dwFlags);
1960 return TRUE;
1963 static void test_EnumSystemLanguageGroupsA(void)
1965 if (!pEnumSystemLanguageGroupsA || !pIsValidLanguageGroup)
1966 return;
1968 /* No enumeration proc */
1969 SetLastError(0);
1970 pEnumSystemLanguageGroupsA(0, LGRPID_INSTALLED, 0);
1971 EXPECT_INVALID;
1973 /* Invalid flags */
1974 SetLastError(0);
1975 pEnumSystemLanguageGroupsA(langgrp_procA, LGRPID_INSTALLED|LGRPID_SUPPORTED, 0);
1976 EXPECT_FLAGS;
1978 /* No flags - defaults to LGRPID_INSTALLED */
1979 SetLastError(0);
1980 pEnumSystemLanguageGroupsA(langgrp_procA, 0, 1);
1981 EXPECT_VALID;
1983 pEnumSystemLanguageGroupsA(langgrp_procA, LGRPID_INSTALLED, 0);
1984 pEnumSystemLanguageGroupsA(langgrp_procA, LGRPID_SUPPORTED, 0);
1988 static BOOL CALLBACK lgrplocale_procA(LGRPID lgrpid, LCID lcid, LPSTR lpszNum,
1989 LONG_PTR lParam)
1991 trace("%08lx, %08lx, %s, %08lx\n", lgrpid, lcid, lpszNum, lParam);
1993 ok(pIsValidLanguageGroup(lgrpid, LGRPID_SUPPORTED) == TRUE,
1994 "Enumerated grp %ld not valid\n", lgrpid);
1995 ok(IsValidLocale(lcid, LCID_SUPPORTED) == TRUE,
1996 "Enumerated grp locale %ld not valid\n", lcid);
1997 return TRUE;
2000 static void test_EnumLanguageGroupLocalesA(void)
2002 if (!pEnumLanguageGroupLocalesA || !pIsValidLanguageGroup)
2003 return;
2005 /* No enumeration proc */
2006 SetLastError(0);
2007 pEnumLanguageGroupLocalesA(0, LGRPID_WESTERN_EUROPE, 0, 0);
2008 EXPECT_INVALID;
2010 /* lgrpid too small */
2011 SetLastError(0);
2012 pEnumLanguageGroupLocalesA(lgrplocale_procA, 0, 0, 0);
2013 EXPECT_INVALID;
2015 /* lgrpid too big */
2016 SetLastError(0);
2017 pEnumLanguageGroupLocalesA(lgrplocale_procA, LGRPID_ARMENIAN + 1, 0, 0);
2018 EXPECT_INVALID;
2020 /* dwFlags is reserved */
2021 SetLastError(0);
2022 pEnumLanguageGroupLocalesA(0, LGRPID_WESTERN_EUROPE, 0x1, 0);
2023 EXPECT_INVALID;
2025 pEnumLanguageGroupLocalesA(lgrplocale_procA, LGRPID_WESTERN_EUROPE, 0, 0);
2028 static void test_SetLocaleInfoA(void)
2030 BOOL bRet;
2031 LCID lcid = GetUserDefaultLCID();
2033 /* Null data */
2034 SetLastError(0);
2035 bRet = SetLocaleInfoA(lcid, LOCALE_SDATE, 0);
2036 EXPECT_INVALID;
2038 /* IDATE */
2039 SetLastError(0);
2040 bRet = SetLocaleInfoA(lcid, LOCALE_IDATE, (LPSTR)test_SetLocaleInfoA);
2041 EXPECT_FLAGS;
2043 /* ILDATE */
2044 SetLastError(0);
2045 bRet = SetLocaleInfoA(lcid, LOCALE_ILDATE, (LPSTR)test_SetLocaleInfoA);
2046 EXPECT_FLAGS;
2049 static BOOL CALLBACK luilocale_proc1A(LPSTR value, LONG_PTR lParam) {
2050 trace("%s %08lx\n", value, lParam);
2051 return(TRUE);
2054 static BOOL CALLBACK luilocale_proc2A(LPSTR value, LONG_PTR lParam) {
2055 ok(!enumCount, "callback called again unexpected\n");
2056 enumCount++;
2057 return(FALSE);
2060 static BOOL CALLBACK luilocale_proc3A(LPSTR value, LONG_PTR lParam) {
2061 ok(0,"callback called unexpected\n");
2062 return(FALSE);
2065 static void test_EnumUILanguageA(void)
2066 { BOOL ret;
2067 if (!pEnumUILanguagesA) {
2068 trace("EnumUILanguagesA is not available on Win9x\n");
2069 return;
2072 SetLastError(ERROR_SUCCESS);
2073 ret = pEnumUILanguagesA(luilocale_proc1A, 0, 0);
2074 EXPECT_TRUE; EXPECT_VALID;
2076 enumCount = 0;
2077 SetLastError(ERROR_SUCCESS);
2078 ret = pEnumUILanguagesA(luilocale_proc2A, 0, 0);
2079 EXPECT_TRUE; EXPECT_VALID;
2081 SetLastError(ERROR_SUCCESS);
2082 ret = pEnumUILanguagesA(NULL, 0, 0);
2083 EXPECT_FALSE; EXPECT_INVALID;
2085 SetLastError(ERROR_SUCCESS);
2086 ret = pEnumUILanguagesA(luilocale_proc3A, 0x5a5a5a5a, 0);
2087 EXPECT_FALSE; EXPECT_FLAGS;
2089 SetLastError(ERROR_SUCCESS);
2090 ret = pEnumUILanguagesA(NULL, 0x5a5a5a5a, 0);
2091 EXPECT_FALSE; EXPECT_INVALID;
2094 START_TEST(locale)
2096 InitFunctionPointers();
2098 #if 0
2099 test_EnumTimeFormats();
2100 #endif
2101 test_GetLocaleInfoA();
2102 test_GetTimeFormatA();
2103 test_GetDateFormatA();
2104 test_GetDateFormatW();
2105 test_GetCurrencyFormatA(); /* Also tests the W version */
2106 test_GetNumberFormatA(); /* Also tests the W version */
2107 test_CompareStringA();
2108 test_LCMapStringA();
2109 test_LCMapStringW();
2110 test_FoldStringA();
2111 test_FoldStringW();
2112 test_ConvertDefaultLocale();
2113 test_EnumSystemLanguageGroupsA();
2114 test_EnumLanguageGroupLocalesA();
2115 test_SetLocaleInfoA();
2116 #if 0 /* this requires collation table patch to make it MS compatible */
2117 test_sorting();
2118 #endif
2119 test_EnumUILanguageA();