msvcrt: Return value from MSVCRT____mb_cur_max_func instead of pointer.
[wine] / dlls / msvcrt / tests / locale.c
1 /*
2  * Unit test suite for locale functions.
3  *
4  * Copyright 2010 Piotr Caban for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <locale.h>
22
23 #include "wine/test.h"
24 #include "winnls.h"
25
26 static BOOL (__cdecl *p__crtGetStringTypeW)(DWORD, DWORD, const wchar_t*, int, WORD*);
27 static int (__cdecl *pmemcpy_s)(void *, size_t, void*, size_t);
28 static int (__cdecl *p___mb_cur_max_func)(void);
29 static int *(__cdecl *p__p___mb_cur_max)(void);
30 void* __cdecl _Gettnames(void);
31
32 static void init(void)
33 {
34     HMODULE hmod = GetModuleHandleA("msvcrt.dll");
35
36     p__crtGetStringTypeW = (void*)GetProcAddress(hmod, "__crtGetStringTypeW");
37     pmemcpy_s = (void*)GetProcAddress(hmod, "memcpy_s");
38     p___mb_cur_max_func = (void*)GetProcAddress(hmod, "___mb_cur_max_func");
39     p__p___mb_cur_max = (void*)GetProcAddress(hmod, "__p___mb_cur_max");
40 }
41
42 static void test_setlocale(void)
43 {
44     static const char lc_all[] = "LC_COLLATE=C;LC_CTYPE=C;"
45         "LC_MONETARY=Greek_Greece.1253;LC_NUMERIC=Polish_Poland.1250;LC_TIME=C";
46
47     char *ret, buf[100];
48
49     ret = setlocale(20, "C");
50     ok(ret == NULL, "ret = %s\n", ret);
51
52     ret = setlocale(LC_ALL, "");
53     ok(ret != NULL, "ret == NULL\n");
54
55     ret = setlocale(LC_ALL, "C");
56     ok(!strcmp(ret, "C"), "ret = %s\n", ret);
57
58     ret = setlocale(LC_ALL, NULL);
59     ok(!strcmp(ret, "C"), "ret = %s\n", ret);
60
61     if(!setlocale(LC_NUMERIC, "Polish")
62             || !setlocale(LC_NUMERIC, "Greek")
63             || !setlocale(LC_NUMERIC, "German")
64             || !setlocale(LC_NUMERIC, "English")) {
65         win_skip("System with limited locales\n");
66         return;
67     }
68
69     ret = setlocale(LC_NUMERIC, "Polish");
70     ok(!strcmp(ret, "Polish_Poland.1250"), "ret = %s\n", ret);
71
72     ret = setlocale(LC_MONETARY, "Greek");
73     ok(!strcmp(ret, "Greek_Greece.1253"), "ret = %s\n", ret);
74
75     ret = setlocale(LC_ALL, NULL);
76     ok(!strcmp(ret, lc_all), "ret = %s\n", ret);
77
78     strcpy(buf, ret);
79     ret = setlocale(LC_ALL, buf);
80     ok(!strcmp(ret, lc_all), "ret = %s\n", ret);
81
82     ret = setlocale(LC_ALL, "German");
83     ok(!strcmp(ret, "German_Germany.1252"), "ret = %s\n", ret);
84
85     ret = setlocale(LC_ALL, "american");
86     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
87     if(ret)
88         ok(!strcmp(ret, "English_United States.1252"), "ret = %s\n", ret);
89
90     ret = setlocale(LC_ALL, "american english");
91     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
92     if(ret)
93         ok(!strcmp(ret, "English_United States.1252"), "ret = %s\n", ret);
94
95     ret = setlocale(LC_ALL, "american-english");
96     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
97     if(ret)
98         ok(!strcmp(ret, "English_United States.1252"), "ret = %s\n", ret);
99
100     ret = setlocale(LC_ALL, "australian");
101     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
102     if(ret)
103         ok(!strcmp(ret, "English_Australia.1252"), "ret = %s\n", ret);
104
105     ret = setlocale(LC_ALL, "belgian");
106     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
107     if(ret)
108         ok(!strcmp(ret, "Dutch_Belgium.1252"), "ret = %s\n", ret);
109
110     ret = setlocale(LC_ALL, "canadian");
111     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
112     if(ret)
113         ok(!strcmp(ret, "English_Canada.1252"), "ret = %s\n", ret);
114
115     ret = setlocale(LC_ALL, "chinese");
116     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
117     if(ret)
118         ok(!strcmp(ret, "Chinese (Simplified)_People's Republic of China.936")
119         || broken(!strcmp(ret, "Chinese_Taiwan.950")), "ret = %s\n", ret);
120
121     ret = setlocale(LC_ALL, "chinese-simplified");
122     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
123     if(ret)
124         ok(!strcmp(ret, "Chinese (Simplified)_People's Republic of China.936")
125         || broken(!strcmp(ret, "Chinese_People's Republic of China.936"))
126         || broken(!strcmp(ret, "Chinese_Taiwan.950")), "ret = %s\n", ret);
127
128     ret = setlocale(LC_ALL, "chinese-traditional");
129     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
130     if(ret)
131         ok(!strcmp(ret, "Chinese (Traditional)_Taiwan.950")
132         || broken(!strcmp(ret, "Chinese_Taiwan.950")), "ret = %s\n", ret);
133
134     ret = setlocale(LC_ALL, "chs");
135     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
136     if(ret)
137         ok(!strcmp(ret, "Chinese (Simplified)_People's Republic of China.936")
138         || broken(!strcmp(ret, "Chinese_People's Republic of China.936")), "ret = %s\n", ret);
139
140     ret = setlocale(LC_ALL, "cht");
141     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
142     if(ret)
143         ok(!strcmp(ret, "Chinese (Traditional)_Taiwan.950")
144         || broken(!strcmp(ret, "Chinese_Taiwan.950")), "ret = %s\n", ret);
145
146     ret = setlocale(LC_ALL, "csy");
147     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
148     if(ret)
149         ok(!strcmp(ret, "Czech_Czech Republic.1250"), "ret = %s\n", ret);
150
151     ret = setlocale(LC_ALL, "czech");
152     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
153     if(ret)
154         ok(!strcmp(ret, "Czech_Czech Republic.1250"), "ret = %s\n", ret);
155
156     ret = setlocale(LC_ALL, "dan");
157     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
158     if(ret)
159         ok(!strcmp(ret, "Danish_Denmark.1252"), "ret = %s\n", ret);
160
161     ret = setlocale(LC_ALL, "danish");
162     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
163     if(ret)
164         ok(!strcmp(ret, "Danish_Denmark.1252"), "ret = %s\n", ret);
165
166     ret = setlocale(LC_ALL, "dea");
167     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
168     if(ret)
169         ok(!strcmp(ret, "German_Austria.1252"), "ret = %s\n", ret);
170
171     ret = setlocale(LC_ALL, "des");
172     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
173     if(ret)
174         ok(!strcmp(ret, "German_Switzerland.1252"), "ret = %s\n", ret);
175
176     ret = setlocale(LC_ALL, "deu");
177     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
178     if(ret)
179         ok(!strcmp(ret, "German_Germany.1252"), "ret = %s\n", ret);
180
181     ret = setlocale(LC_ALL, "dutch");
182     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
183     if(ret)
184         ok(!strcmp(ret, "Dutch_Netherlands.1252"), "ret = %s\n", ret);
185
186     ret = setlocale(LC_ALL, "dutch-belgian");
187     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
188     if(ret)
189         ok(!strcmp(ret, "Dutch_Belgium.1252")
190         || broken(!strcmp(ret, "Dutch_Netherlands.1252")), "ret = %s\n", ret);
191
192     ret = setlocale(LC_ALL, "ena");
193     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
194     if(ret)
195         ok(!strcmp(ret, "English_Australia.1252")
196         || broken(!strcmp(ret, "English_United States.1252")), "ret = %s\n", ret);
197
198     ret = setlocale(LC_ALL, "ell");
199     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
200     if(ret)
201         ok(!strcmp(ret, "Greek_Greece.1253"), "ret = %s\n", ret);
202
203     ret = setlocale(LC_ALL, "enc");
204     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
205     if(ret)
206         ok(!strcmp(ret, "English_Canada.1252")
207         || broken(!strcmp(ret, "English_United States.1252")), "ret = %s\n", ret);
208
209     ret = setlocale(LC_ALL, "eng");
210     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
211     if(ret)
212         ok(!strcmp(ret, "English_United Kingdom.1252")
213         || broken(!strcmp(ret, "English_United States.1252")), "ret = %s\n", ret);
214
215     ret = setlocale(LC_ALL, "enu");
216     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
217     if(ret)
218         ok(!strcmp(ret, "English_United States.1252"), "ret = %s\n", ret);
219
220     ret = setlocale(LC_ALL, "enz");
221     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
222     if(ret)
223         ok(!strcmp(ret, "English_New Zealand.1252")
224         || broken(!strcmp(ret, "English_United States.1252")), "ret = %s\n", ret);
225
226     ret = setlocale(LC_ALL, "english");
227     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
228     if(ret)
229         ok(!strcmp(ret, "English_United States.1252"), "ret = %s\n", ret);
230
231     ret = setlocale(LC_ALL, "english-american");
232     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
233     if(ret)
234         ok(!strcmp(ret, "English_United States.1252"), "ret = %s\n", ret);
235
236     ret = setlocale(LC_ALL, "english-aus");
237     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
238     if(ret)
239         ok(!strcmp(ret, "English_Australia.1252")
240         || broken(!strcmp(ret, "English_United States.1252")), "ret = %s\n", ret);
241
242     ret = setlocale(LC_ALL, "english-can");
243     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
244     if(ret)
245         ok(!strcmp(ret, "English_Canada.1252")
246         || broken(!strcmp(ret, "English_United States.1252")), "ret = %s\n", ret);
247
248     ret = setlocale(LC_ALL, "english-nz");
249     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
250     if(ret)
251         ok(!strcmp(ret, "English_New Zealand.1252")
252         || broken(!strcmp(ret, "English_United States.1252")), "ret = %s\n", ret);
253
254     ret = setlocale(LC_ALL, "english-uk");
255     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
256     if(ret)
257         ok(!strcmp(ret, "English_United Kingdom.1252")
258         || broken(!strcmp(ret, "English_United States.1252")), "ret = %s\n", ret);
259
260     ret = setlocale(LC_ALL, "english-us");
261     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
262     if(ret)
263         ok(!strcmp(ret, "English_United States.1252"), "ret = %s\n", ret);
264
265     ret = setlocale(LC_ALL, "english-usa");
266     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
267     if(ret)
268         ok(!strcmp(ret, "English_United States.1252"), "ret = %s\n", ret);
269
270     ret = setlocale(LC_ALL, "esm");
271     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
272     if(ret)
273         ok(!strcmp(ret, "Spanish_Mexico.1252"), "ret = %s\n", ret);
274
275     ret = setlocale(LC_ALL, "esn");
276     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
277     if(ret)
278         ok(!strcmp(ret, "Spanish_Spain.1252")
279         || broken(!strcmp(ret, "Spanish - Modern Sort_Spain.1252")), "ret = %s\n", ret);
280
281     ret = setlocale(LC_ALL, "esp");
282     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
283     if(ret)
284         ok(!strcmp(ret, "Spanish_Spain.1252")
285         || broken(!strcmp(ret, "Spanish - Traditional Sort_Spain.1252")), "ret = %s\n", ret);
286
287     ret = setlocale(LC_ALL, "fin");
288     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
289     if(ret)
290         ok(!strcmp(ret, "Finnish_Finland.1252"), "ret = %s\n", ret);
291
292     ret = setlocale(LC_ALL, "finnish");
293     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
294     if(ret)
295         ok(!strcmp(ret, "Finnish_Finland.1252"), "ret = %s\n", ret);
296
297     ret = setlocale(LC_ALL, "fra");
298     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
299     if(ret)
300         ok(!strcmp(ret, "French_France.1252"), "ret = %s\n", ret);
301
302     ret = setlocale(LC_ALL, "frb");
303     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
304     if(ret)
305         ok(!strcmp(ret, "French_Belgium.1252")
306         || broken(!strcmp(ret, "French_France.1252")), "ret = %s\n", ret);
307
308     ret = setlocale(LC_ALL, "frc");
309     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
310     if(ret)
311         ok(!strcmp(ret, "French_Canada.1252")
312         || broken(!strcmp(ret, "French_France.1252")), "ret = %s\n", ret);
313
314     ret = setlocale(LC_ALL, "french");
315     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
316     if(ret)
317         ok(!strcmp(ret, "French_France.1252"), "ret = %s\n", ret);
318
319     ret = setlocale(LC_ALL, "french-belgian");
320     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
321     if(ret)
322         ok(!strcmp(ret, "French_Belgium.1252")
323         || broken(!strcmp(ret, "French_France.1252")), "ret = %s\n", ret);
324
325     ret = setlocale(LC_ALL, "french-canadian");
326     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
327     if(ret)
328         ok(!strcmp(ret, "French_Canada.1252")
329         || broken(!strcmp(ret, "French_France.1252")), "ret = %s\n", ret);
330
331     ret = setlocale(LC_ALL, "french-swiss");
332     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
333     if(ret)
334         ok(!strcmp(ret, "French_Switzerland.1252")
335         || broken(!strcmp(ret, "French_France.1252")), "ret = %s\n", ret);
336
337     ret = setlocale(LC_ALL, "frs");
338     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
339     if(ret)
340         ok(!strcmp(ret, "French_Switzerland.1252")
341         || broken(!strcmp(ret, "French_France.1252")), "ret = %s\n", ret);
342
343     ret = setlocale(LC_ALL, "german");
344     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
345     if(ret)
346         ok(!strcmp(ret, "German_Germany.1252"), "ret = %s\n", ret);
347
348     ret = setlocale(LC_ALL, "german-austrian");
349     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
350     if(ret)
351         ok(!strcmp(ret, "German_Austria.1252")
352         || broken(!strcmp(ret, "German_Germany.1252")), "ret = %s\n", ret);
353
354     ret = setlocale(LC_ALL, "german-swiss");
355     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
356     if(ret)
357         ok(!strcmp(ret, "German_Switzerland.1252")
358         || broken(!strcmp(ret, "German_Germany.1252")), "ret = %s\n", ret);
359
360     ret = setlocale(LC_ALL, "greek");
361     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
362     if(ret)
363         ok(!strcmp(ret, "Greek_Greece.1253"), "ret = %s\n", ret);
364
365     ret = setlocale(LC_ALL, "hun");
366     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
367     if(ret)
368         ok(!strcmp(ret, "Hungarian_Hungary.1250"), "ret = %s\n", ret);
369
370     ret = setlocale(LC_ALL, "hungarian");
371     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
372     if(ret)
373         ok(!strcmp(ret, "Hungarian_Hungary.1250"), "ret = %s\n", ret);
374
375     ret = setlocale(LC_ALL, "icelandic");
376     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
377     if(ret)
378         ok(!strcmp(ret, "Icelandic_Iceland.1252"), "ret = %s\n", ret);
379
380     ret = setlocale(LC_ALL, "isl");
381     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
382     if(ret)
383         ok(!strcmp(ret, "Icelandic_Iceland.1252"), "ret = %s\n", ret);
384
385     ret = setlocale(LC_ALL, "ita");
386     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
387     if(ret)
388         ok(!strcmp(ret, "Italian_Italy.1252"), "ret = %s\n", ret);
389
390     ret = setlocale(LC_ALL, "italian");
391     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
392     if(ret)
393         ok(!strcmp(ret, "Italian_Italy.1252"), "ret = %s\n", ret);
394
395     ret = setlocale(LC_ALL, "italian-swiss");
396     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
397     if(ret)
398         ok(!strcmp(ret, "Italian_Switzerland.1252")
399         || broken(!strcmp(ret, "Italian_Italy.1252")), "ret = %s\n", ret);
400
401     ret = setlocale(LC_ALL, "its");
402     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
403     if(ret)
404         ok(!strcmp(ret, "Italian_Switzerland.1252")
405         || broken(!strcmp(ret, "Italian_Italy.1252")), "ret = %s\n", ret);
406
407     ret = setlocale(LC_ALL, "japanese");
408     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
409     if(ret)
410         ok(!strcmp(ret, "Japanese_Japan.932"), "ret = %s\n", ret);
411
412     ret = setlocale(LC_ALL, "jpn");
413     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
414     if(ret)
415         ok(!strcmp(ret, "Japanese_Japan.932"), "ret = %s\n", ret);
416
417     ret = setlocale(LC_ALL, "korean");
418     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
419     if(ret)
420         ok(!strcmp(ret, "Korean_Korea.949"), "ret = %s\n", ret);
421
422     ret = setlocale(LC_ALL, "korean");
423     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
424     if(ret)
425         ok(!strcmp(ret, "Korean_Korea.949"), "ret = %s\n", ret);
426
427     ret = setlocale(LC_ALL, "nlb");
428     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
429     if(ret)
430         ok(!strcmp(ret, "Dutch_Belgium.1252")
431         || broken(!strcmp(ret, "Dutch_Netherlands.1252")), "ret = %s\n", ret);
432
433     ret = setlocale(LC_ALL, "nld");
434     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
435     if(ret)
436         ok(!strcmp(ret, "Dutch_Netherlands.1252"), "ret = %s\n", ret);
437
438     ret = setlocale(LC_ALL, "non");
439     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
440     if(ret)
441         ok(!strcmp( ret, "Norwegian-Nynorsk_Norway.1252")
442         || !strcmp(ret, "Norwegian (Nynorsk)_Norway.1252")
443         || broken(!strcmp(ret, "Norwegian (Bokm\xe5l)_Norway.1252"))
444         || broken(!strcmp(ret, "Norwegian_Norway.1252")), "ret = %s\n", ret);
445
446     ret = setlocale(LC_ALL, "nor");
447     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
448     if(ret)
449         ok(!strcmp(ret, "Norwegian (Bokm\xe5l)_Norway.1252")
450         || !strcmp(ret, "Norwegian (Bokmal)_Norway.1252")
451         || broken(!strcmp(ret, "Norwegian_Norway.1252")), "ret = %s\n", ret);
452
453     ret = setlocale(LC_ALL, "norwegian-bokmal");
454     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
455     if(ret)
456         ok(!strcmp(ret, "Norwegian (Bokm\xe5l)_Norway.1252")
457         || !strcmp(ret, "Norwegian (Bokmal)_Norway.1252")
458         || broken(!strcmp(ret, "Norwegian_Norway.1252")), "ret = %s\n", ret);
459
460     ret = setlocale(LC_ALL, "norwegian-nynorsk");
461     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
462     if(ret)
463         ok(!strcmp(ret, "Norwegian-Nynorsk_Norway.1252")
464         || !strcmp(ret, "Norwegian (Nynorsk)_Norway.1252")
465         || broken(!strcmp(ret, "Norwegian_Norway.1252"))
466         || broken(!strcmp(ret, "Norwegian (Bokmal)_Norway.1252"))
467         || broken(!strcmp(ret, "Norwegian (Bokm\xe5l)_Norway.1252")), "ret = %s\n", ret);
468
469     ret = setlocale(LC_ALL, "plk");
470     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
471     if(ret)
472         ok(!strcmp(ret, "Polish_Poland.1250"), "ret = %s\n", ret);
473
474     ret = setlocale(LC_ALL, "polish");
475     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
476     if(ret)
477         ok(!strcmp(ret, "Polish_Poland.1250"), "ret = %s\n", ret);
478
479     ret = setlocale(LC_ALL, "portuguese");
480     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
481     if(ret)
482         ok(!strcmp(ret, "Portuguese_Brazil.1252")
483         || broken(!strcmp(ret, "Portuguese_Portugal.1252")) /* NT4 */, "ret = %s\n", ret);
484
485     ret = setlocale(LC_ALL, "portuguese-brazil");
486     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
487     if(ret)
488         ok(!strcmp(ret, "Portuguese_Brazil.1252"), "ret = %s\n", ret);
489
490     ret = setlocale(LC_ALL, "ptb");
491     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
492     if(ret)
493         ok(!strcmp(ret, "Portuguese_Brazil.1252"), "ret = %s\n", ret);
494
495     ret = setlocale(LC_ALL, "ptg");
496     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
497     if(ret)
498         ok(!strcmp(ret, "Portuguese_Portugal.1252"), "ret = %s\n", ret);
499
500     ret = setlocale(LC_ALL, "rus");
501     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
502     if(ret)
503         ok(!strcmp(ret, "Russian_Russia.1251"), "ret = %s\n", ret);
504
505     ret = setlocale(LC_ALL, "russian");
506     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
507     if(ret)
508         ok(!strcmp(ret, "Russian_Russia.1251"), "ret = %s\n", ret);
509
510     ret = setlocale(LC_ALL, "sky");
511     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
512     if(ret)
513         ok(!strcmp(ret, "Slovak_Slovakia.1250"), "ret = %s\n", ret);
514
515     ret = setlocale(LC_ALL, "slovak");
516     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
517     if(ret)
518         ok(!strcmp(ret, "Slovak_Slovakia.1250"), "ret = %s\n", ret);
519
520     ret = setlocale(LC_ALL, "spanish");
521     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
522     if(ret)
523         ok(!strcmp(ret, "Spanish_Spain.1252")
524         || broken(!strcmp(ret, "Spanish - Traditional Sort_Spain.1252")), "ret = %s\n", ret);
525
526     ret = setlocale(LC_ALL, "spanish-mexican");
527     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
528     if(ret)
529         ok(!strcmp(ret, "Spanish_Mexico.1252")
530         || broken(!strcmp(ret, "Spanish_Spain.1252")), "ret = %s\n", ret);
531
532     ret = setlocale(LC_ALL, "spanish-modern");
533     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
534     if(ret)
535         ok(!strcmp(ret, "Spanish - Modern Sort_Spain.1252")
536            || !strcmp(ret, "Spanish_Spain.1252"), "ret = %s\n", ret);
537
538     ret = setlocale(LC_ALL, "sve");
539     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
540     if(ret)
541         ok(!strcmp(ret, "Swedish_Sweden.1252"), "ret = %s\n", ret);
542
543     ret = setlocale(LC_ALL, "swedish");
544     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
545     if(ret)
546         ok(!strcmp(ret, "Swedish_Sweden.1252"), "ret = %s\n", ret);
547
548     ret = setlocale(LC_ALL, "swiss");
549     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
550     if(ret)
551         ok(!strcmp(ret, "German_Switzerland.1252"), "ret = %s\n", ret);
552
553     ret = setlocale(LC_ALL, "trk");
554     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
555     if(ret)
556         ok(!strcmp(ret, "Turkish_Turkey.1254"), "ret = %s\n", ret);
557
558     ret = setlocale(LC_ALL, "turkish");
559     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
560     if(ret)
561         ok(!strcmp(ret, "Turkish_Turkey.1254"), "ret = %s\n", ret);
562
563     ret = setlocale(LC_ALL, "uk");
564     ok(ret != NULL, "ret == NULL\n");
565     if(ret)
566         ok(!strcmp(ret, "English_United Kingdom.1252")
567         || broken(!strcmp(ret, "Ukrainian_Ukraine.1251")), "ret = %s\n", ret);
568
569     ret = setlocale(LC_ALL, "us");
570     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
571     if(ret)
572         ok(!strcmp(ret, "English_United States.1252"), "ret = %s\n", ret);
573
574     ret = setlocale(LC_ALL, "usa");
575     ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
576     if(ret)
577         ok(!strcmp(ret, "English_United States.1252"), "ret = %s\n", ret);
578 }
579
580 static void test_crtGetStringTypeW(void)
581 {
582     static const wchar_t str0[] = { '0', '\0' };
583     static const wchar_t strA[] = { 'A', '\0' };
584     static const wchar_t str_space[] = { ' ', '\0' };
585     static const wchar_t str_null[] = { '\0', '\0' };
586     static const wchar_t str_rand[] = { 1234, '\0' };
587
588     const wchar_t *str[] = { str0, strA, str_space, str_null, str_rand };
589
590     WORD out_crt, out;
591     BOOL ret_crt, ret;
592     int i;
593
594     if(!p__crtGetStringTypeW) {
595         win_skip("Skipping __crtGetStringTypeW tests\n");
596         return;
597     }
598
599     if(!pmemcpy_s) {
600         win_skip("Too old version of msvcrt.dll\n");
601         return;
602     }
603
604     for(i=0; i<sizeof(str)/sizeof(*str); i++) {
605         ret_crt = p__crtGetStringTypeW(0, CT_CTYPE1, str[i], 1, &out_crt);
606         ret = GetStringTypeW(CT_CTYPE1, str[i], 1, &out);
607         ok(ret == ret_crt, "%d) ret_crt = %d\n", i, (int)ret_crt);
608         ok(out == out_crt, "%d) out_crt = %x, expected %x\n", i, (int)out_crt, (int)out);
609
610         ret_crt = p__crtGetStringTypeW(0, CT_CTYPE2, str[i], 1, &out_crt);
611         ret = GetStringTypeW(CT_CTYPE2, str[i], 1, &out);
612         ok(ret == ret_crt, "%d) ret_crt = %d\n", i, (int)ret_crt);
613         ok(out == out_crt, "%d) out_crt = %x, expected %x\n", i, (int)out_crt, (int)out);
614
615         ret_crt = p__crtGetStringTypeW(0, CT_CTYPE3, str[i], 1, &out_crt);
616         ret = GetStringTypeW(CT_CTYPE3, str[i], 1, &out);
617         ok(ret == ret_crt, "%d) ret_crt = %d\n", i, (int)ret_crt);
618         ok(out == out_crt, "%d) out_crt = %x, expected %x\n", i, (int)out_crt, (int)out);
619     }
620
621     ret = p__crtGetStringTypeW(0, 3, str[0], 1, &out);
622     ok(!ret, "ret == TRUE\n");
623 }
624
625 static void test__Gettnames(void)
626 {
627     struct {
628         char *str[43];
629         LCID lcid;
630         int  unk[2];
631         wchar_t *wstr[43];
632         char data[1];
633     } *ret;
634     int size;
635
636     if(!setlocale(LC_ALL, "english"))
637         return;
638
639     ret = _Gettnames();
640     size = ret->data-(char*)ret;
641     /* Newer version of the structure stores both ascii and unicode strings.
642      * Unicode strings are only initialized on Windows 7
643      */
644     if(sizeof(void*) == 8)
645         ok(size==0x2c0 || broken(size==0x170), "strucure size: %x\n", size);
646     else
647         ok(size==0x164 || broken(size==0xb8), "strucure size: %x\n", size);
648
649     ok(!strcmp(ret->str[0], "Sun"), "ret->str[0] = %s\n", ret->str[0]);
650     ok(!strcmp(ret->str[1], "Mon"), "ret->str[1] = %s\n", ret->str[1]);
651     ok(!strcmp(ret->str[2], "Tue"), "ret->str[2] = %s\n", ret->str[2]);
652     ok(!strcmp(ret->str[3], "Wed"), "ret->str[3] = %s\n", ret->str[3]);
653     ok(!strcmp(ret->str[4], "Thu"), "ret->str[4] = %s\n", ret->str[4]);
654     ok(!strcmp(ret->str[5], "Fri"), "ret->str[5] = %s\n", ret->str[5]);
655     ok(!strcmp(ret->str[6], "Sat"), "ret->str[6] = %s\n", ret->str[6]);
656     ok(!strcmp(ret->str[7], "Sunday"), "ret->str[7] = %s\n", ret->str[7]);
657     ok(!strcmp(ret->str[8], "Monday"), "ret->str[8] = %s\n", ret->str[8]);
658     ok(!strcmp(ret->str[9], "Tuesday"), "ret->str[9] = %s\n", ret->str[9]);
659     ok(!strcmp(ret->str[10], "Wednesday"), "ret->str[10] = %s\n", ret->str[10]);
660     ok(!strcmp(ret->str[11], "Thursday"), "ret->str[11] = %s\n", ret->str[11]);
661     ok(!strcmp(ret->str[12], "Friday"), "ret->str[12] = %s\n", ret->str[12]);
662     ok(!strcmp(ret->str[13], "Saturday"), "ret->str[13] = %s\n", ret->str[13]);
663     ok(!strcmp(ret->str[14], "Jan"), "ret->str[14] = %s\n", ret->str[14]);
664     ok(!strcmp(ret->str[15], "Feb"), "ret->str[15] = %s\n", ret->str[15]);
665     ok(!strcmp(ret->str[16], "Mar"), "ret->str[16] = %s\n", ret->str[16]);
666     ok(!strcmp(ret->str[17], "Apr"), "ret->str[17] = %s\n", ret->str[17]);
667     ok(!strcmp(ret->str[18], "May"), "ret->str[18] = %s\n", ret->str[18]);
668     ok(!strcmp(ret->str[19], "Jun"), "ret->str[19] = %s\n", ret->str[19]);
669     ok(!strcmp(ret->str[20], "Jul"), "ret->str[20] = %s\n", ret->str[20]);
670     ok(!strcmp(ret->str[21], "Aug"), "ret->str[21] = %s\n", ret->str[21]);
671     ok(!strcmp(ret->str[22], "Sep"), "ret->str[22] = %s\n", ret->str[22]);
672     ok(!strcmp(ret->str[23], "Oct"), "ret->str[23] = %s\n", ret->str[23]);
673     ok(!strcmp(ret->str[24], "Nov"), "ret->str[24] = %s\n", ret->str[24]);
674     ok(!strcmp(ret->str[25], "Dec"), "ret->str[25] = %s\n", ret->str[25]);
675     ok(!strcmp(ret->str[26], "January"), "ret->str[26] = %s\n", ret->str[26]);
676     ok(!strcmp(ret->str[27], "February"), "ret->str[27] = %s\n", ret->str[27]);
677     ok(!strcmp(ret->str[28], "March"), "ret->str[28] = %s\n", ret->str[28]);
678     ok(!strcmp(ret->str[29], "April"), "ret->str[29] = %s\n", ret->str[29]);
679     ok(!strcmp(ret->str[30], "May"), "ret->str[30] = %s\n", ret->str[30]);
680     ok(!strcmp(ret->str[31], "June"), "ret->str[31] = %s\n", ret->str[31]);
681     ok(!strcmp(ret->str[32], "July"), "ret->str[32] = %s\n", ret->str[32]);
682     ok(!strcmp(ret->str[33], "August"), "ret->str[33] = %s\n", ret->str[33]);
683     ok(!strcmp(ret->str[34], "September"), "ret->str[34] = %s\n", ret->str[34]);
684     ok(!strcmp(ret->str[35], "October"), "ret->str[35] = %s\n", ret->str[35]);
685     ok(!strcmp(ret->str[36], "November"), "ret->str[36] = %s\n", ret->str[36]);
686     ok(!strcmp(ret->str[37], "December"), "ret->str[37] = %s\n", ret->str[37]);
687     ok(!strcmp(ret->str[38], "AM"), "ret->str[38] = %s\n", ret->str[38]);
688     ok(!strcmp(ret->str[39], "PM"), "ret->str[39] = %s\n", ret->str[39]);
689     ok(!strcmp(ret->str[40], "M/d/yyyy") || broken(!strcmp(ret->str[40], "M/d/yy"))/*NT*/,
690             "ret->str[40] = %s\n", ret->str[40]);
691     ok(!strcmp(ret->str[41], "dddd, MMMM dd, yyyy"), "ret->str[41] = %s\n", ret->str[41]);
692     free(ret);
693
694     if(!setlocale(LC_TIME, "german"))
695         return;
696
697     ret = _Gettnames();
698     ok(!strcmp(ret->str[0], "So"), "ret->str[0] = %s\n", ret->str[0]);
699     ok(!strcmp(ret->str[1], "Mo"), "ret->str[1] = %s\n", ret->str[1]);
700     ok(!strcmp(ret->str[2], "Di"), "ret->str[2] = %s\n", ret->str[2]);
701     ok(!strcmp(ret->str[3], "Mi"), "ret->str[3] = %s\n", ret->str[3]);
702     ok(!strcmp(ret->str[4], "Do"), "ret->str[4] = %s\n", ret->str[4]);
703     ok(!strcmp(ret->str[5], "Fr"), "ret->str[5] = %s\n", ret->str[5]);
704     ok(!strcmp(ret->str[6], "Sa"), "ret->str[6] = %s\n", ret->str[6]);
705     ok(!strcmp(ret->str[7], "Sonntag"), "ret->str[7] = %s\n", ret->str[7]);
706     ok(!strcmp(ret->str[8], "Montag"), "ret->str[8] = %s\n", ret->str[8]);
707     ok(!strcmp(ret->str[9], "Dienstag"), "ret->str[9] = %s\n", ret->str[9]);
708     ok(!strcmp(ret->str[10], "Mittwoch"), "ret->str[10] = %s\n", ret->str[10]);
709     ok(!strcmp(ret->str[11], "Donnerstag"), "ret->str[11] = %s\n", ret->str[11]);
710     ok(!strcmp(ret->str[12], "Freitag"), "ret->str[12] = %s\n", ret->str[12]);
711     ok(!strcmp(ret->str[13], "Samstag"), "ret->str[13] = %s\n", ret->str[13]);
712     ok(!strcmp(ret->str[14], "Jan"), "ret->str[14] = %s\n", ret->str[14]);
713     ok(!strcmp(ret->str[15], "Feb"), "ret->str[15] = %s\n", ret->str[15]);
714     ok(!strcmp(ret->str[16], "Mrz"), "ret->str[16] = %s\n", ret->str[16]);
715     ok(!strcmp(ret->str[17], "Apr"), "ret->str[17] = %s\n", ret->str[17]);
716     ok(!strcmp(ret->str[18], "Mai"), "ret->str[18] = %s\n", ret->str[18]);
717     ok(!strcmp(ret->str[19], "Jun"), "ret->str[19] = %s\n", ret->str[19]);
718     ok(!strcmp(ret->str[20], "Jul"), "ret->str[20] = %s\n", ret->str[20]);
719     ok(!strcmp(ret->str[21], "Aug"), "ret->str[21] = %s\n", ret->str[21]);
720     ok(!strcmp(ret->str[22], "Sep"), "ret->str[22] = %s\n", ret->str[22]);
721     ok(!strcmp(ret->str[23], "Okt"), "ret->str[23] = %s\n", ret->str[23]);
722     ok(!strcmp(ret->str[24], "Nov"), "ret->str[24] = %s\n", ret->str[24]);
723     ok(!strcmp(ret->str[25], "Dez"), "ret->str[25] = %s\n", ret->str[25]);
724     ok(!strcmp(ret->str[26], "Januar"), "ret->str[26] = %s\n", ret->str[26]);
725     ok(!strcmp(ret->str[27], "Februar"), "ret->str[27] = %s\n", ret->str[27]);
726     ok(!strcmp(ret->str[29], "April"), "ret->str[29] = %s\n", ret->str[29]);
727     ok(!strcmp(ret->str[30], "Mai"), "ret->str[30] = %s\n", ret->str[30]);
728     ok(!strcmp(ret->str[31], "Juni"), "ret->str[31] = %s\n", ret->str[31]);
729     ok(!strcmp(ret->str[32], "Juli"), "ret->str[32] = %s\n", ret->str[32]);
730     ok(!strcmp(ret->str[33], "August"), "ret->str[33] = %s\n", ret->str[33]);
731     ok(!strcmp(ret->str[34], "September"), "ret->str[34] = %s\n", ret->str[34]);
732     ok(!strcmp(ret->str[35], "Oktober"), "ret->str[35] = %s\n", ret->str[35]);
733     ok(!strcmp(ret->str[36], "November"), "ret->str[36] = %s\n", ret->str[36]);
734     ok(!strcmp(ret->str[37], "Dezember"), "ret->str[37] = %s\n", ret->str[37]);
735     ok(!strcmp(ret->str[38], ""), "ret->str[38] = %s\n", ret->str[38]);
736     ok(!strcmp(ret->str[39], ""), "ret->str[39] = %s\n", ret->str[39]);
737     ok(!strcmp(ret->str[40], "dd.MM.yyyy") || broken(!strcmp(ret->str[40], "dd.MM.yy"))/*NT*/,
738             "ret->str[40] = %s\n", ret->str[40]);
739     ok(!strcmp(ret->str[41], "dddd, d. MMMM yyyy"), "ret->str[41] = %s\n", ret->str[41]);
740     free(ret);
741
742     setlocale(LC_ALL, "C");
743 }
744
745 static void test___mb_cur_max_func(void)
746 {
747     int mb_cur_max;
748
749     /* for newer Windows */
750     if(!p___mb_cur_max_func)
751         win_skip("Skipping ___mb_cur_max_func tests\n");
752     else {
753         mb_cur_max = p___mb_cur_max_func();
754         ok(mb_cur_max == 1, "mb_cur_max = %d, expected 1\n", mb_cur_max);
755
756         /* some old Windows don't set chinese */
757         if (!setlocale(LC_ALL, "chinese"))
758             win_skip("Skipping test with chinese locale\n");
759         else {
760             mb_cur_max = p___mb_cur_max_func();
761             ok(mb_cur_max == 2, "mb_cur_max = %d, expected 2\n", mb_cur_max);
762             setlocale(LC_ALL, "C");
763         }
764     }
765
766     /* for older Windows */
767     if (!p__p___mb_cur_max)
768         win_skip("Skipping __p___mb_cur_max tests\n");
769     else {
770         mb_cur_max = *p__p___mb_cur_max();
771         ok(mb_cur_max == 1, "mb_cur_max = %d, expected 1\n", mb_cur_max);
772
773         /* some old Windows don't set chinese */
774         if (!setlocale(LC_ALL, "chinese"))
775             win_skip("Skipping test with chinese locale\n");
776         else {
777             mb_cur_max = *p__p___mb_cur_max();
778             ok(mb_cur_max == 2, "mb_cur_max = %d, expected 2\n", mb_cur_max);
779             setlocale(LC_ALL, "C");
780         }
781     }
782 }
783
784 START_TEST(locale)
785 {
786     init();
787
788     test_crtGetStringTypeW();
789     test_setlocale();
790     test__Gettnames();
791     test___mb_cur_max_func();
792 }