Added pipe.ok.
[wine] / dlls / kernel / tests / locale.c
1 /*
2  * Very basic unit test for locale functions
3  * Test run on win2K (French)
4  *
5  * Copyright (c) 2002 YASAR Mehmet
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "wine/test.h"
23 #include "winbase.h"
24 #include "winerror.h"
25 #include "winnls.h"
26
27 #define eq(received, expected, label, type) \
28         ok((received) == (expected), "%s: got " type " instead of " type, (label),(received),(expected))
29
30 #define BUFFER_SIZE             128
31 /* Buffer used by callback function */
32 char GlobalBuffer[BUFFER_SIZE];
33 #define COUNTOF(x) (sizeof(x)/sizeof(x)[0])
34
35 /* TODO :
36  * Unicode versions
37  * EnumTimeFormatsA
38  * EnumDateFormatsA
39  * LCMapStringA
40  * GetUserDefaultLangID
41  * ...
42  */
43
44 void TestGetLocaleInfoA()
45 {
46         int ret, cmp;
47         LCID lcid;
48         char buffer[BUFFER_SIZE], Expected[BUFFER_SIZE];
49
50         strcpy(Expected, "Monday");
51         lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
52         ok (lcid == 0x409, "wrong LCID calculated");
53
54         /* HTMLKit and "Font xplorer lite" expect GetLocaleInfoA to
55         * partially fill the buffer even if it is too short. See bug 637.
56         */
57         strcpy(Expected, "xxxxx");
58         memset( buffer, 'x', sizeof(buffer) );
59         ret = GetLocaleInfoA(lcid, LOCALE_SDAYNAME1, buffer, 0);
60         cmp = strncmp (buffer, Expected, strlen(Expected));
61         ok (cmp == 0, "GetLocaleInfoA got %s instead of %s", buffer, Expected);
62         eq (ret, lstrlenA("Monday") + 1, "GetLocaleInfoA with len=0", "%d");
63
64         strcpy(Expected, "Monxx");
65         memset( buffer, 'x', sizeof(buffer) );
66         ret = GetLocaleInfoA(lcid, LOCALE_SDAYNAME1, buffer, 3);
67         cmp = strncmp (buffer, Expected, strlen(Expected));
68         ok (cmp == 0, "GetLocaleInfoA got %s instead of %s", buffer, Expected);
69         eq (ret, 0, "GetLocaleInfoA with len = 3", "%d");
70
71         strcpy(Expected, "Monday");
72         memset( buffer, 'x', sizeof(buffer) );
73         ret = GetLocaleInfoA(lcid, LOCALE_SDAYNAME1, buffer, 10);
74         /* We check also presence of '\0' */
75         cmp = strncmp (buffer, Expected, strlen(Expected) + 1);
76         ok (cmp == 0, "GetLocaleInfoA got %s instead of %s", buffer, Expected);
77         eq (ret, lstrlenA(Expected)+1, "GetLocaleInfoA with len = 10", "%d" );
78
79         /* We check the whole buffer with strncmp */
80         memset( Expected, 'x', sizeof(Expected) );
81         strcpy(Expected, "Monday");
82         memset( buffer, 'x', sizeof(buffer) );
83         ret = GetLocaleInfoA(lcid, LOCALE_SDAYNAME1, buffer, BUFFER_SIZE);
84         cmp = strncmp (buffer, Expected, BUFFER_SIZE);
85         ok (cmp == 0, "GetLocaleInfoA got %s instead of %s", buffer, Expected);
86         eq (ret, lstrlenA(Expected)+1, "GetLocaleInfoA with len = 10", "%d" );
87
88 }
89
90
91 void TestGetTimeFormatA()
92 {
93   int ret, error, cmp;
94   SYSTEMTIME  curtime;
95   char buffer[BUFFER_SIZE], format[BUFFER_SIZE], Expected[BUFFER_SIZE];
96   LCID lcid;
97
98   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
99   strcpy(format, "tt HH':'mm'@'ss");
100
101   /* fill curtime with dummy data */
102   memset(&curtime, 2, sizeof(SYSTEMTIME));
103   memset(buffer, '0', sizeof(buffer));
104   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, format, buffer, COUNTOF(buffer));
105   error = GetLastError ();
106   ok (ret == 0, "GetTimeFormat should fail on dummy data");
107   eq (error, ERROR_INVALID_PARAMETER, "GetTimeFormat GetLastError()", "%d");
108   SetLastError(NO_ERROR);   /* clear out the last error */
109
110   /* test that we can correctly produce the expected output, not a very */
111   /* demanding test ;-) */
112   strcpy(Expected, "AM 08:56@13");
113   curtime.wHour = 8;  curtime.wMinute = 56;
114   curtime.wSecond = 13; curtime.wMilliseconds = 22;
115   memset(buffer, '0', sizeof(buffer));
116   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, format, buffer, COUNTOF(buffer));
117   cmp = strncmp (Expected, buffer, strlen(Expected)+1);
118   ok (cmp == 0, "GetTimeFormat got %s instead of %s", buffer, Expected);
119   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
120
121   /* check that the size reported by the above call is accuate */
122   memset(buffer, 'x', sizeof(buffer));
123   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, format, buffer, ret);
124   ok(ret==lstrlenA(Expected)+1 && GetLastError()==0,
125            "GetTimeFormat(right size): ret=%d error=%ld\n",ret,GetLastError());
126   ok(buffer[0] != 'x',"GetTimeFormat(right size): buffer=[%s]\n",buffer);
127
128   /* test failure due to insufficent buffer */
129   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, format, buffer, 2);
130   ok(ret==0 && GetLastError()==ERROR_INSUFFICIENT_BUFFER,
131            "GetTimeFormat(len=2): ret=%d error=%ld", ret, GetLastError());
132
133   /* test with too small buffers */
134   SetLastError(0);
135   memset(buffer, '0', sizeof(buffer));
136   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, format, NULL, 0);
137   ok(ret==lstrlenA(Expected)+1 && GetLastError()==0,
138            "GetTimeFormat(len=0): ret=%d error=%ld\n",ret,GetLastError());
139
140   /************************************/
141   /* test out TIME_NOMINUTESORSECONDS */
142   strcpy(Expected, "8 AM");
143   memset(buffer, '0', sizeof(buffer));
144   ret = GetTimeFormatA(lcid, TIME_NOMINUTESORSECONDS, &curtime, NULL, buffer, sizeof(buffer));
145   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
146   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
147   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
148
149   /* test out TIME_NOMINUTESORSECONDS with complex format strings */
150   strcpy(Expected, "4");
151   memset(buffer, '0', sizeof(buffer));
152   ret = GetTimeFormatA(lcid, TIME_NOMINUTESORSECONDS, &curtime, "m1s2m3s4", buffer, sizeof(buffer));
153   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
154   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
155   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
156
157
158   /************************************/
159   /* test out TIME_NOSECONDS */
160   strcpy(Expected, "8:56 AM");
161   ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, NULL, buffer, sizeof(buffer));
162   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
163   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
164   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
165
166   /* test out TIME_NOSECONDS with a format string of "h:m:s tt" */
167   strcpy(Expected, "8:56 AM");
168   memset(buffer, '0', sizeof(buffer));
169   ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, "h:m:s tt", buffer, sizeof(buffer));
170   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
171   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
172   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
173
174   /* test out TIME_NOSECONDS a strange format string of multiple delimiters "h@:m@:s tt" */
175   /* expected behavior is to turn "hD1D2...mD3D4...sD5D6...tt" and turn this into */
176   /* "hD1D2...mD3D4...tt" */
177   strcpy(Expected, "8.@:56.@:AM");
178   memset(buffer, '0', sizeof(buffer));
179   ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, "h.@:m.@:s.@:tt", buffer, sizeof(buffer));
180   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
181   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
182   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
183
184   /* test out TIME_NOSECONDS with an string of "1s2s3s4" */
185   /* expect to see only "3" */
186   strcpy(Expected, "3");
187   memset(buffer, '0', sizeof(buffer));
188   ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, "s1s2s3", buffer, sizeof(buffer));
189   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
190   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
191   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
192
193   /************************/
194   /* Test out time marker */
195   /* test out time marker(AM/PM) behavior */
196   strcpy(Expected, "A/AM");
197   memset(buffer, '0', sizeof(buffer));
198   ret = GetTimeFormatA(lcid, 0, &curtime, "t/tt", buffer, sizeof(buffer));
199   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
200   ok (cmp == 0, "GetTimeFormat got '%s' instead of %s", buffer, Expected);
201   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
202
203   /* time marker testing part 2 */
204   curtime.wHour = 13;
205   strcpy(Expected, "P/PM");
206   memset(buffer, '0', sizeof(buffer));
207   ret = GetTimeFormatA(lcid, 0, &curtime, "t/tt", buffer, sizeof(buffer));
208   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
209   ok (cmp == 0, "GetTimeFormat got '%s' instead of %s", buffer, Expected);
210   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
211
212   /******************************/
213   /* test out TIME_NOTIMEMARKER */
214   /* NOTE: TIME_NOTIMEMARKER elminates all text around any time marker */
215   /*      formatting character until the previous or next formatting character */
216   strcpy(Expected, "156");
217   memset(buffer, '0', sizeof(buffer));
218   ret = GetTimeFormatA(lcid, TIME_NOTIMEMARKER, &curtime, "h1t2tt3m", buffer, sizeof(buffer));
219   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
220   ok (cmp == 0, "GetTimeFormat got '%s' instead of %s", buffer, Expected);
221   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
222
223   /***********************************/
224   /* test out TIME_FORCE24HOURFORMAT */
225   strcpy(Expected, "13:56:13 PM");
226   memset(buffer, '0', sizeof(buffer));
227   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, "h:m:s tt", buffer, sizeof(buffer));
228   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
229   ok (cmp == 0, "GetTimeFormat got '%s' instead of %s", buffer, Expected);
230   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
231
232   /* check to confirm that unlike what msdn documentation suggests, the time marker */
233   /* is not added under TIME_FORCE24HOURFORMAT */
234   strcpy(Expected, "13:56:13");
235   memset(buffer, '0', sizeof(buffer));
236   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, "h:m:s", buffer, sizeof(buffer));
237   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
238   ok (cmp == 0, "GetTimeFormat got '%s' instead of %s", buffer, Expected);
239   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
240
241
242   /*********************************************/
243   /* test advanced formatting of GetTimeFormat */
244
245   /* test for 24 hour conversion and for leading zero */
246   /* NOTE: we do not test the "hh or HH" case since hours is two digits */
247   /* "h hh H HH m mm s ss t tt" */
248   curtime.wHour = 14; /* change this to 14 or 2pm */
249   curtime.wMinute = 5;
250   curtime.wSecond = 3;
251   strcpy(Expected, "2 02 14 14 5 05 3 03 P PM");
252   memset(buffer, '0', sizeof(buffer));
253   ret = GetTimeFormatA(lcid, 0, &curtime, "h hh H HH m mm s ss t tt", 
254 buffer, sizeof(buffer));
255   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
256   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
257   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
258
259   /* complete testing on the advanced formatting by testing "hh" and "HH" */
260   /* 0 hour is 12 o'clock or 00 hundred hours */
261   curtime.wHour = 0;
262   strcpy(Expected, "12/0/12/00");
263   memset(buffer, '0', sizeof(buffer));
264   ret = GetTimeFormatA(lcid, 0, &curtime, "h/H/hh/HH", buffer, sizeof(buffer));
265   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
266   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
267   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
268
269   /* test for LOCALE_NOUSEROVERRIDE set, lpFormat must be NULL */
270   strcpy(Expected, "0:5:3 AM");
271   memset(buffer, '0', sizeof(buffer));
272   ret = GetTimeFormatA(lcid, LOCALE_NOUSEROVERRIDE, &curtime, "h:m:s tt", buffer, sizeof(buffer));
273   /* NOTE: we expect this to FAIL */
274   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
275   ok (ret == 0, "GetTimeFormat succeeded instead of failing for LOCALE_NOUSEROVERRIDE and a non-null lpFormat\n");
276
277   /* try to convert formatting strings with more than two letters */
278   /* "h:hh:hhh:H:HH:HHH:m:mm:mmm:M:MM:MMM:s:ss:sss:S:SS:SSS" */
279   /* NOTE: we expect any letter for which there is an upper case value */
280   /*    we should expect to see a replacement.  For letters that DO NOT */
281   /*    have upper case values we expect to see NO REPLACEMENT */
282   curtime.wHour = 8;  curtime.wMinute = 56;
283   curtime.wSecond = 13; curtime.wMilliseconds = 22;
284   strcpy(Expected, "8:08:08 8:08:08 56:56:56 M:MM:MMM 13:13:13 S:SS:SSS");
285   memset(buffer, '0', sizeof(buffer));
286   ret = GetTimeFormatA(lcid, 0, &curtime, "h:hh:hhh H:HH:HHH m:mm:mmm M:MM:MMM s:ss:sss S:SS:SSS", buffer, sizeof(buffer));
287   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
288   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
289   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
290
291   /* test that if the size of the buffer is zero that the buffer is not modified */
292   /* and that the number of necessary characters is returned */
293   /* NOTE: The count includes the terminating null. */
294   strcpy(buffer, "THIS SHOULD NOT BE MODIFIED");
295   strcpy(Expected, "THIS SHOULD NOT BE MODIFIED");
296   ret = GetTimeFormatA(lcid, 0, &curtime, "h", buffer, 0);
297   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
298   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
299   eq (ret, 2, "GetTimeFormat", "%d"); /* we expect to require two characters of space from "h" */
300
301   /* test that characters in single quotation marks are ignored and left in */
302   /* the same location in the output string */
303   strcpy(Expected, "8 h 8 H 08 HH 56 m 13 s A t AM tt");
304   memset(buffer, '0', sizeof(buffer));
305   ret = GetTimeFormatA(lcid, 0, &curtime, "h 'h' H 'H' HH 'HH' m 'm' s 's' t 't' tt 'tt'", buffer, sizeof(buffer));
306   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
307   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
308   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
309
310   /* test the printing of the single quotation marks when */
311   /* we use an invalid formatting string of "'''" instead of "''''" */
312   strcpy(Expected, "'");
313   memset(buffer, '0', sizeof(buffer));
314   ret = GetTimeFormatA(lcid, 0, &curtime, "'''", buffer, sizeof(buffer));
315   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
316   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
317   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
318
319   /* test that msdn suggested single quotation usage works as expected */
320   strcpy(Expected, "'");
321   memset(buffer, '0', sizeof(buffer));
322   ret = GetTimeFormatA(lcid, 0, &curtime, "''''", buffer, sizeof(buffer));
323   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
324   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
325   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
326
327   /* test for more normal use of single quotation mark */
328   strcpy(Expected, "08");
329   memset(buffer, '0', sizeof(buffer));
330   ret = GetTimeFormatA(lcid, 0, &curtime, "''HHHHHH", buffer, sizeof(buffer));
331   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
332   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
333   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
334
335   /* and test for normal use of the single quotation mark */
336   strcpy(Expected, "'HHHHHH");
337   memset(buffer, '0', sizeof(buffer));
338   ret = GetTimeFormatA(lcid, 0, &curtime, "'''HHHHHH'", buffer, sizeof(buffer));
339   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
340   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
341   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
342
343   /* test for more odd use of the single quotation mark */
344   strcpy(Expected, "'HHHHHH");
345   memset(buffer, '0', sizeof(buffer));
346   ret = GetTimeFormatA(lcid, 0, &curtime, "'''HHHHHH", buffer, sizeof(buffer));
347   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
348   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
349   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
350
351   /* test that with TIME_NOTIMEMARKER that even if something is defined */
352   /* as a literal we drop it before and after the markers until the next */
353   /* formatting character */
354   strcpy(Expected, "");
355   memset(buffer, '0', sizeof(buffer));
356   ret = GetTimeFormatA(lcid, TIME_NOTIMEMARKER, &curtime, "'123'tt", buffer, sizeof(buffer));
357   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
358   ok (cmp == 0, "GetTimeFormat got '%s' instead of '%s'", buffer, Expected);
359   eq (ret, lstrlenA(Expected)+1, "GetTimeFormat", "%d");
360
361   /* test for expected return and error value when we have a */
362   /* non-null format and LOCALE_NOUSEROVERRIDE for flags */
363   SetLastError(NO_ERROR); /* reset last error value */
364   memset(buffer, '0', sizeof(buffer));
365   ret = GetTimeFormatA(lcid, LOCALE_NOUSEROVERRIDE, &curtime, "'123'tt", buffer, sizeof(buffer));
366   error = GetLastError();
367   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
368   ok ((ret == 0) && (error == ERROR_INVALID_FLAGS), "GetTimeFormat got ret of '%d' and error of '%d'", ret, error);
369
370   /* test that invalid time values result in ERROR_INVALID_PARAMETER */
371   /* and a return value of 0 */
372   curtime.wHour = 25;
373   SetLastError(NO_ERROR); /* reset last error value */
374   memset(buffer, '0', sizeof(buffer));
375   ret = GetTimeFormatA(lcid, 0, &curtime, "'123'tt", buffer, sizeof(buffer));
376   error = GetLastError();
377   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
378   ok ((ret == 0) && (error == ERROR_INVALID_PARAMETER), "GetTimeFormat got ret of '%d' and error of '%d'", ret, error);
379
380   /* test that invalid information in the date section of the current time */
381   /* doesn't result in an error since GetTimeFormat() should ignore this information */
382   curtime.wHour = 12; /* valid wHour */
383   curtime.wMonth = 60; /* very invalid wMonth */
384   strcpy(Expected, "12:56:13");
385   SetLastError(NO_ERROR); /* reset last error value */
386   ret = GetTimeFormatA(lcid, 0, &curtime, "h:m:s", buffer, sizeof(buffer));
387   error = GetLastError();
388   cmp = strncmp(buffer, Expected, BUFFER_SIZE);
389   ok ((ret == lstrlenA(Expected)+1) && (error == NO_ERROR), "GetTimeFormat got ret of '%d' and error of '%d' and a buffer of '%s'", ret, error, buffer);
390 }
391
392 void TestGetDateFormatA()
393 {
394   int ret, error, cmp;
395   SYSTEMTIME  curtime;
396   char buffer[BUFFER_SIZE], format[BUFFER_SIZE], Expected[BUFFER_SIZE];
397   LCID lcid;
398
399   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
400   strcpy(format, "ddd',' MMM dd yy");
401
402   /* test for failure on dummy data */
403   memset(&curtime, 2, sizeof(SYSTEMTIME));
404   memset(buffer, '0', sizeof(buffer));
405   SetLastError(NO_ERROR);
406   ret = GetDateFormatA(lcid, 0, &curtime, format, buffer, COUNTOF(buffer));
407   error = GetLastError ();
408   ok(ret == 0, "GetDateFormat should fail on dummy data");
409   eq(error, ERROR_INVALID_PARAMETER, "GetDateFormat", "%d");
410
411   /* test for a simple case of date conversion */
412   strcpy(Expected, "Sat, May 04 02");
413   curtime.wYear = 2002;
414   curtime.wMonth = 5;
415   curtime.wDay = 4;
416   curtime.wDayOfWeek = 3;
417   memset(buffer, 0, sizeof(buffer));
418   ret = GetDateFormatA(lcid, 0, &curtime, format, buffer, COUNTOF(buffer));
419   cmp = strncmp (Expected, buffer, strlen(Expected)+1);
420   ok (cmp == 0, "GetDateFormat got %s instead of %s", buffer, Expected);
421   eq (ret, lstrlenA(Expected)+1, "GetDateFormat", "%d");
422
423   /* test format with "'" */
424   strcpy(format, "ddd',' MMM dd ''''yy");
425   strcpy(Expected, "Sat, May 04 '02");
426   memset(buffer, 0, sizeof(buffer));
427   ret = GetDateFormatA(lcid, 0, &curtime, format, buffer, COUNTOF(buffer));
428   cmp = strncmp (Expected, buffer, strlen(Expected)+1);
429   ok (cmp == 0, "GetDateFormat got %s instead of %s", buffer, Expected);
430   eq (ret, lstrlenA(Expected)+1, "GetDateFormat", "%d");
431
432   /* test for success with dummy time data */
433   curtime.wHour = 36;
434   memset(buffer, 0, sizeof(buffer));
435   ret = GetDateFormatA(lcid, 0, &curtime, format, buffer, COUNTOF(buffer));
436   cmp = strncmp (Expected, buffer, strlen(Expected)+1);
437   ok (cmp == 0, "GetDateFormat got %s instead of %s", buffer, Expected);
438   eq (ret, lstrlenA(Expected)+1, "GetDateFormat", "%d");
439
440   /* test that we retrieve the expected size for the necessary output of this string */
441   SetLastError(NO_ERROR);
442   memset(buffer, 0, sizeof(buffer));
443   ret = GetDateFormatA(lcid, 0, &curtime, format, NULL, 0);
444   ok(ret==lstrlenA(Expected)+1 && GetLastError() == 0,
445           "GetDateFormat(len=0): ret=%d error=%ld buffer='%s', expected NO_ERROR(0)\n",ret,GetLastError(), buffer);
446
447   /* test that the expected size matches the actual required size by passing */
448   /* in the expected size */
449   memset(buffer, '0', sizeof(buffer));
450   ret = GetDateFormatA(lcid, 0, &curtime, format, buffer, ret);
451   ok(ret==lstrlenA(Expected)+1 && GetLastError()==0,
452            "GetDateFormat(right size): ret=%d error=%ld, buffer = '%s'\n",ret,GetLastError(), buffer);
453   ok(buffer[0]!='x',"GetDateFormat(right size): buffer=[%s]\n",buffer);
454
455   /* test that a buffer shorter than the necessary size results in ERROR_INSUFFICIENT_BUFFER */
456   ret = GetDateFormatA(lcid, 0, &curtime, format, buffer, 2);
457   ok(ret==0 && GetLastError()==ERROR_INSUFFICIENT_BUFFER,
458            "GetDateFormat(len=2): ret=%d error=%ld", ret, GetLastError());
459
460   /* test for default behavior being DATE_SHORTDATE */
461   todo_wine {
462     strcpy(Expected, "5/4/02");
463     memset(buffer, '0', sizeof(buffer));
464     ret = GetDateFormat(lcid, 0, &curtime, NULL, buffer, sizeof(buffer));
465     cmp = strncmp (Expected, buffer, strlen(Expected)+1);
466     ok (cmp == 0, "GetDateFormat got '%s' instead of '%s'", buffer, Expected);
467     eq (ret, lstrlenA(Expected)+1, "GetDateFormat", "%d");
468   }
469
470
471   /* test for expected DATE_LONGDATE behavior with null format */
472   strcpy(Expected, "Saturday, May 04, 2002");
473   memset(buffer, '0', sizeof(buffer));
474   ret = GetDateFormat(lcid, DATE_LONGDATE, &curtime, NULL, buffer, sizeof(buffer));
475   cmp = strncmp (Expected, buffer, strlen(Expected)+1);
476   ok (cmp == 0, "GetDateFormat got '%s' instead of '%s'", buffer, Expected);
477   eq (ret, lstrlenA(Expected)+1, "GetDateFormat", "%d");
478
479   /* test for expected DATE_YEARMONTH behavior with null format */
480   /* NT4 returns ERROR_INVALID_FLAGS for DATE_YEARMONTH */
481   todo_wine {
482     strcpy(Expected, "");
483     buffer[0] = 0;
484     SetLastError(NO_ERROR);
485     memset(buffer, '0', sizeof(buffer));
486     ret = GetDateFormat(lcid, DATE_YEARMONTH, &curtime, NULL, buffer, sizeof(buffer));
487     error = GetLastError();
488     cmp = strncmp (Expected, buffer, strlen(Expected)+1);
489     ok (ret == 0 && (error == ERROR_INVALID_FLAGS), "GetDateFormat check DATE_YEARMONTH with null format expected ERROR_INVALID_FLAGS got return of '%d' and error of '%d'", ret, error);
490   }
491
492   /* Test that using invalid DATE_* flags results in the correct error */
493   /* and return values */
494   strcpy(format, "m/d/y");
495   strcpy(Expected, "Saturday May 2002");
496   SetLastError(NO_ERROR);
497   memset(buffer, '0', sizeof(buffer));
498   ret = GetDateFormat(lcid, DATE_YEARMONTH | DATE_SHORTDATE | DATE_LONGDATE, &curtime, format, buffer, sizeof(buffer));
499   error = GetLastError();
500   cmp = strncmp (Expected, buffer, strlen(Expected)+1);
501   ok ((ret == 0) && (error == ERROR_INVALID_FLAGS), "GetDateFormat checking for mutually exclusive flags got '%s' instead of '%s', got error of %d, expected ERROR_INVALID_FLAGS", buffer, Expected, error);
502 }
503
504 void TestGetDateFormatW()
505 {
506     int ret, error, cmp;
507     SYSTEMTIME  curtime;
508     WCHAR buffer[BUFFER_SIZE], format[BUFFER_SIZE], Expected[BUFFER_SIZE];
509     LCID lcid;
510
511     lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
512
513     /* 1. Error cases */
514
515     /* 1a If flags is not zero then format must be null. */
516     ret = GetDateFormatW (LOCALE_SYSTEM_DEFAULT, DATE_LONGDATE, NULL, format, buffer, COUNTOF(buffer));
517     if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
518         return;
519     error = ret ? 0 : GetLastError();
520     ok (ret == 0 && error == ERROR_INVALID_FLAGS, "GetDateFormatW allowed flags and format");
521
522     /* 1b The buffer can only be null if the count is zero */
523     /* For the record other bad pointers result in a page fault (Win98) */
524     ret = GetDateFormatW (lcid, 0, NULL, format, NULL, COUNTOF(buffer));
525     error = ret ? 0 : GetLastError();
526     ok (ret == 0 && error == ERROR_INVALID_PARAMETER, "GetDateFormatW did not detect null buffer pointer.");
527     ret = GetDateFormatW (lcid, 0, NULL, format, NULL, 0);
528     error = ret ? 0 : GetLastError();
529     ok (ret != 0 && error == 0, "GetDateFormatW did not permit null buffer pointer when counting.");
530
531     /* 1c An incorrect day of week is corrected. */
532     /* 1d The incorrect day of week can even be out of range. */
533     /* 1e The time doesn't matter */
534     curtime.wYear = 2002;
535     curtime.wMonth = 10;
536     curtime.wDay = 23;
537     curtime.wDayOfWeek = 45612; /* should be 3 - Wednesday */
538     curtime.wHour = 65432;
539     curtime.wMinute = 34512;
540     curtime.wSecond = 65535;
541     curtime.wMilliseconds = 12345;
542     MultiByteToWideChar (CP_ACP, 0, "dddd d MMMM yyyy", -1, format, COUNTOF(format));
543     ret = GetDateFormatW (lcid, 0, &curtime, format, buffer, COUNTOF(buffer));
544     error = ret ? 0 : GetLastError();
545     MultiByteToWideChar (CP_ACP, 0, "Wednesday 23 October 2002", -1, Expected, COUNTOF(Expected));
546     cmp = ret ? lstrcmpW (buffer, Expected) : 2;
547     ok (ret == lstrlenW(Expected)+1 && error == 0 && cmp == 0, "Day of week correction failed\n");
548 }
549
550
551 void TestGetCurrencyFormat()
552 {
553 int ret, error, cmp;
554 char buffer[BUFFER_SIZE], Expected[BUFFER_SIZE], format[BUFFER_SIZE];
555 LCID lcid;
556
557         lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
558 #if 0
559         lcid = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT );
560 #endif
561
562         memset( buffer, 'x', sizeof(buffer) );
563         ret = GetCurrencyFormatA(lcid, 0, "23,65", NULL, buffer, COUNTOF(buffer));
564         error = GetLastError ();
565         cmp = strncmp ("xxxx", buffer, 4);
566
567         ok (cmp == 0, "GetCurrencyFormat should fail with ','");
568         eq (ret, 0, "GetCurrencyFormat with ','", "%d");
569         eq (error, ERROR_INVALID_PARAMETER, "GetCurrencyFormat", "%d");
570
571         /* We check the whole buffer with strncmp */
572         strcpy (Expected, "$23.53");
573         strcpy (format, "23.53");
574         memset( buffer, 'x', sizeof(buffer) );
575         ret = GetCurrencyFormatA(lcid, 0, format, NULL, buffer, COUNTOF(buffer));
576         cmp = strncmp (Expected, buffer, BUFFER_SIZE);
577         ok (cmp == 0, "GetCurrencyFormatA got %s instead of %s", buffer, Expected);
578         eq (ret, lstrlenA(Expected)+1, "GetCurrencyFormatA","%d");
579
580         /* Test too small buffers */
581         SetLastError(0);
582         ret = GetCurrencyFormatA(lcid, 0, format, NULL, NULL, 0);
583         ok(ret==lstrlenA(Expected)+1 && GetLastError()==0,
584        "GetCurrencyFormatA(size=0): ret=%d error=%ld", ret, GetLastError());
585
586         memset( buffer, 'x', sizeof(buffer) );
587         ret = GetCurrencyFormatA(lcid, 0, format, NULL, buffer, ret);
588         ok(strcmp(buffer,Expected)==0,
589            "GetCurrencyFormatA(right size): got [%s] instead of [%s]", buffer, Expected);
590         eq (ret, lstrlenA(Expected)+1, "GetCurrencyFormatA(right size)", "%d");
591
592         ret = GetCurrencyFormatA(lcid, 0, format, NULL, buffer, 2);
593         ok(ret==0 && GetLastError()==ERROR_INSUFFICIENT_BUFFER,
594            "GetCurrencyFormatA(size=2): ret=%d error=%ld", ret, GetLastError());
595 }
596
597
598 void TestGetNumberFormat()
599 {
600 int ret, error, cmp;
601 char buffer[BUFFER_SIZE], Expected[BUFFER_SIZE], input[BUFFER_SIZE];
602 LCID lcid;
603 NUMBERFMTA format;
604
605         lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
606
607         memset( buffer, 'x', sizeof(buffer) );
608         ret = GetNumberFormatA(lcid, 0, "23,65", NULL, buffer, COUNTOF(buffer));
609         error = GetLastError ();
610         cmp = strncmp ("xxx", buffer, 3);
611         ok (cmp == 0, "GetNumberFormat");
612         ok (ret == 0, "GetNumberFormat should return 0");
613         eq (error, ERROR_INVALID_PARAMETER, "GetNumberFormat", "%d");
614
615         strcpy(input, "2353");
616         strcpy(Expected, "2,353.00");
617         SetLastError(0);
618         ret = GetNumberFormatA(lcid, 0, input, NULL, NULL, 0);
619         ok(ret==lstrlenA(Expected)+1 && GetLastError()==0,
620        "GetNumberFormatA(size=0): ret=%d error=%ld", ret, GetLastError());
621
622         memset( buffer, 'x', sizeof(buffer) );
623         ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, ret);
624         ok(strcmp(buffer,Expected)==0,
625            "GetNumberFormatA(right size): got [%s] instead of [%s]", buffer, Expected);
626         eq(ret, lstrlenA(Expected)+1, "GetNumberFormat", "%d");
627
628         ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, 2);
629         ok(ret==0 && GetLastError()==ERROR_INSUFFICIENT_BUFFER,
630            "GetNumberFormatA(size=2): ret=%d error=%ld", ret, GetLastError());
631
632         /* We check the whole buffer with strncmp */
633         memset(Expected, 'x', sizeof(Expected) );
634         strcpy(Expected, "2,353.00");
635         memset( buffer, 'x', sizeof(buffer) );
636         ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
637         cmp = strncmp (Expected, buffer, BUFFER_SIZE);
638         ok (cmp == 0, "GetNumberFormat got %s instead of %s", buffer, Expected);
639         eq (ret, lstrlenA(Expected)+1, "GetNumberFormat", "%d");
640
641         /* If the number of decimals is zero there should be no decimal
642          * separator.
643          * If the grouping size is zero there should be no grouping symbol
644          */
645         format.NumDigits = 0;
646         format.LeadingZero = 0;
647         format.Grouping = 0;
648         format.NegativeOrder = 0;
649         format.lpDecimalSep = ".";
650         format.lpThousandSep = ",";
651         strcpy (Expected, "123456789");
652         memset( buffer, 'x', sizeof(buffer) );
653         ret = GetNumberFormatA (0, 0, "123456789.0", &format, buffer, COUNTOF(buffer));
654         cmp = strncmp (Expected, buffer, sizeof(buffer));
655         ok (cmp == 0, "GetNumberFormat got %s instead of %s", buffer, Expected);
656
657 }
658
659
660 /* Callback function used by TestEnumTimeFormats */
661 BOOL CALLBACK EnumTimeFormatsProc(char * lpTimeFormatString)
662 {
663         trace("%s\n", lpTimeFormatString);
664         strcpy(GlobalBuffer, lpTimeFormatString);
665 #if 0
666         return TRUE;
667 #endif
668         return FALSE;
669 }
670
671 void TestEnumTimeFormats()
672 {
673 int ret;
674 LCID lcid;
675 char Expected[BUFFER_SIZE];
676
677         lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
678         memset( GlobalBuffer, 'x', sizeof(GlobalBuffer) );
679         strcpy(Expected, "h:mm:ss tt");
680         ret = EnumTimeFormatsA(EnumTimeFormatsProc, lcid, 0);
681
682         eq (ret, 1, "EnumTimeFormats should return 1", "%d");
683         ok (strncmp (GlobalBuffer, Expected, strlen(Expected)) == 0,
684                                 "EnumTimeFormats failed");
685         ok (ret == 1, "EnumTimeFormats should return 1");
686 }
687
688
689 void TestCompareStringA()
690 {
691 int ret;
692 LCID lcid;
693 char buffer1[BUFFER_SIZE], buffer2[BUFFER_SIZE];
694
695         lcid = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT );
696
697         strcpy(buffer1, "Salut"); strcpy(buffer2, "Salute");
698         ret = CompareStringA(lcid, NORM_IGNORECASE, buffer1, -1, buffer2, -1);
699         ok (ret== 1, "CompareStringA (st1=%s str2=%s) expected result=1", buffer1, buffer2);
700
701         strcpy(buffer1, "Salut"); strcpy(buffer2, "saLuT");
702         ret = CompareStringA(lcid, NORM_IGNORECASE, buffer1, -1, buffer2, -1);
703         ok (ret== 2, "CompareStringA (st1=%s str2=%s) expected result=2", buffer1, buffer2);
704
705         strcpy(buffer1, "Salut"); strcpy(buffer2, "hola");
706         ret = CompareStringA(lcid, NORM_IGNORECASE, buffer1, -1, buffer2, -1);
707         ok (ret== 3, "CompareStringA (st1=%s str2=%s) expected result=3", buffer1, buffer2);
708
709         strcpy(buffer1, "héhé"); strcpy(buffer2, "hèhè");
710         ret = CompareStringA(lcid, NORM_IGNORECASE, buffer1, -1, buffer2, -1);
711         ok (ret== 1, "CompareStringA (st1=%s str2=%s) expected result=1", buffer1, buffer2);
712
713         lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
714
715         strcpy(buffer1, "héhé"); strcpy(buffer2, "hèhè");
716         ret = CompareStringA(lcid, NORM_IGNORECASE, buffer1, -1, buffer2, -1);
717         ok (ret== 1, "CompareStringA (st1=%s str2=%s) expected result=1", buffer1, buffer2);
718
719         ret = CompareStringA(lcid, NORM_IGNORECASE, buffer1, -1, buffer2, 0);
720         ok (ret== 3, "CompareStringA (st1=%s str2=%s) expected result=3", buffer1, buffer2);
721 }
722
723
724 START_TEST(locale)
725 {
726 #if 0
727         TestEnumTimeFormats();
728 #endif
729         TestGetLocaleInfoA();
730         TestGetTimeFormatA();
731         TestGetDateFormatA();
732         TestGetDateFormatW();
733         TestGetNumberFormat();
734         TestGetCurrencyFormat();
735         TestCompareStringA();
736 }