Remove 'grp' and merge into 'nss' and 'posix'
[platform/upstream/glibc.git] / time / tst-strftime3.c
1 /* Data-driven tests for strftime/strptime.
2    Copyright (C) 2019-2023 Free Software Foundation, Inc.  This file is
3    part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <time.h>
23 #include <locale.h>
24 #include <wchar.h>
25
26 #include <support/check.h>
27 #include <array_length.h>
28 #include <libc-diag.h>
29
30 /* These exist for the convenience of writing the test data, because
31    zero-based vs one-based.  */
32 typedef enum
33   {
34     Sun, Mon, Tue, Wed, Thu, Fri, Sat
35   } WeekDay;
36
37 typedef enum
38   {
39     Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
40   } Month;
41
42 typedef struct
43 {
44   /* A descriptive name of the test.  */
45   const char *name;
46
47   /* The specific date and time to be tested.  */
48   int y, m, d;
49   WeekDay w;
50   int hh, mm, ss;
51
52   /* The locale under which the conversion is done.  */
53   const char *locale;
54
55   /* Format passed to strftime.  */
56   const char *format;
57
58   /* Expected data, NUL terminated.  */
59   const char *printed;
60
61 } Data;
62
63 /* Notes:
64
65    Years are full 4-digit years, the code compensates.  Likewise,
66    use month and weekday enums (above) which are zero-based.
67
68    The encoded strings are multibyte strings in the C locale which
69    reflect the same binary data as the expected strings.  When you run
70    the test, the strings are printed as-is to stdout, so if your
71    terminal is set for the correct encoding, they'll be printed
72    "correctly".  Put the Unicode codes and UTF-8 samples in the
73    comments.
74
75    For convenience, mis-matched strings are printed in
76    paste-compatible format, raw text format, and Unicode format.  Use
77    "" between a hex escape sequence (like \xe8) and a following hex
78    digit which should be considered as a printable character.
79
80    To verify text, save the correct text in a file, and use "od -tx1
81    -tc file" to see the raw hex values.  */
82
83 const Data data[] = {
84
85   { "Baseline test",
86     2019, Mar, 27, Wed, 14,  3, 22, "en_US.ISO-8859-1", "%Y-%m-%d %T",
87     "2019-03-27 14:03:22" },
88
89
90   { "Japanese era change, BCE/CE, before transition",
91     0, Dec, 31, Sun, 12, 00, 00, "ja_JP.UTF-8", "%EY",
92     /* <U7D00><U5143><U524D>01<U5E74> 紀元前01年 */
93     "\xe7\xb4\x80\xe5\x85\x83\xe5\x89\x8d""01\xe5\xb9\xb4" },
94   { "Japanese era change, BCE/CE, after transition",
95     1, Jan,  1, Mon, 12, 00, 00, "ja_JP.UTF-8", "%EY",
96     /* <U897F><U66A6>01<U5E74> 西暦01年 */
97     "\xe8\xa5\xbf\xe6\x9a\xa6""01\xe5\xb9\xb4" },
98
99   { "Japanese era change, BCE/CE, before transition",
100     0, Dec, 31, Sun, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
101     /* <U7D00><U5143><U524D>01<U5E74> 紀元前01年 */
102     "\xb5\xaa\xb8\xb5\xc1\xb0""01\xc7\xaf" },
103   { "Japanese era change, BCE/CE, after transition",
104     1, Jan,  1, Mon, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
105     /* <U897F><U66A6>01<U5E74> 西暦01年 */
106     "\xc0\xbe\xce\xf1""01\xc7\xaf" },
107
108
109   { "Japanese era change, 1873, before transition",
110     1872, Dec, 31, Tue, 12, 00, 00, "ja_JP.UTF-8", "%EY",
111     /* <U897F><U66A6>1872<U5E74> 西暦1872年 */
112     "\xe8\xa5\xbf\xe6\x9a\xa6""1872\xe5\xb9\xb4" },
113   { "Japanese era change, 1873, after transition",
114     1873, Jan,  1, Wed, 12, 00, 00, "ja_JP.UTF-8", "%EY",
115     /* <U660E><U6CBB>06<U5E74> 明治06年 */
116     "\xe6\x98\x8e\xe6\xb2\xbb""06\xe5\xb9\xb4" },
117
118
119   { "Japanese era change, 1873, before transition",
120     1872, Dec, 31, Tue, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
121     /* <U897F><U66A6>1872<U5E74> 西暦1872年 */
122     "\xc0\xbe\xce\xf1""1872\xc7\xaf" },
123   { "Japanese era change, 1873, after transition",
124     1873, Jan,  1, Wed, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
125     /* <U660E><U6CBB>06<U5E74> 明治06年 */
126     "\xcc\xc0\xbc\xa3""06\xc7\xaf" },
127
128
129   { "Japanese era change, 1912, before transition year",
130     1911, Dec, 31, Sun, 12, 00, 00, "ja_JP.UTF-8", "%EY",
131     /* <U660E><U6CBB>44<U5E74> 明治44年 */
132     "\xe6\x98\x8e\xe6\xb2\xbb""44\xe5\xb9\xb4" },
133   { "Japanese era change, 1912, start of transition year",
134     1912, Jan,  1, Mon, 12, 00, 00, "ja_JP.UTF-8", "%EY",
135     /* <U660E><U6CBB>45<U5E74> 明治45年 */
136     "\xe6\x98\x8e\xe6\xb2\xbb""45\xe5\xb9\xb4" },
137
138   { "Japanese era change, 1912, before transition",
139     1912, Jul, 29, Mon, 12, 00, 00, "ja_JP.UTF-8", "%EY",
140     /* <U660E><U6CBB>45<U5E74> 明治45年 */
141     "\xe6\x98\x8e\xe6\xb2\xbb""45\xe5\xb9\xb4" },
142   { "Japanese era change, 1912, after transition",
143     1912, Jul, 30, Tue, 12, 00, 00, "ja_JP.UTF-8", "%EY",
144     /* <U5927><U6B63><U5143><U5E74> 大正元年 */
145     "\xe5\xa4\xa7\xe6\xad\xa3\xe5\x85\x83\xe5\xb9\xb4" },
146
147   { "Japanese era change, 1912, before end of transition year",
148     1912, Dec, 31, Tue, 12, 00, 00, "ja_JP.UTF-8", "%EY",
149     /* <U5927><U6B63><U5143><U5E74> 大正元年 */
150     "\xe5\xa4\xa7\xe6\xad\xa3\xe5\x85\x83\xe5\xb9\xb4" },
151   { "Japanese era change, 1912, after transition year",
152     1913, Jan,  1, Wed, 12, 00, 00, "ja_JP.UTF-8", "%EY",
153     /* <U5927><U6B63>02<U5E74> 大正02年 */
154     "\xe5\xa4\xa7\xe6\xad\xa3""02\xe5\xb9\xb4" },
155
156
157   { "Japanese era change, 1912, before transition year",
158     1911, Dec, 31, Sun, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
159     /* <U660E><U6CBB>44<U5E74> 明治44年 */
160     "\xcc\xc0\xbc\xa3""44\xc7\xaf" },
161   { "Japanese era change, 1912, start of transition year",
162     1912, Jan,  1, Mon, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
163     /* <U660E><U6CBB>45<U5E74> 明治45年 */
164     "\xcc\xc0\xbc\xa3""45\xc7\xaf" },
165
166   { "Japanese era change, 1912, before transition",
167     1912, Jul, 29, Mon, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
168     /* <U660E><U6CBB>45<U5E74> 明治45年 */
169     "\xcc\xc0\xbc\xa3""45\xc7\xaf" },
170   { "Japanese era change, 1912, after transition",
171     1912, Jul, 30, Tue, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
172     /* <U5927><U6B63><U5143><U5E74> 大正元年 */
173     "\xc2\xe7\xc0\xb5\xb8\xb5\xc7\xaf" },
174
175   { "Japanese era change, 1912, before end of transition year",
176     1912, Dec, 31, Tue, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
177     /* <U5927><U6B63><U5143><U5E74> 大正元年 */
178     "\xc2\xe7\xc0\xb5\xb8\xb5\xc7\xaf" },
179   { "Japanese era change, 1912, after transition year",
180     1913, Jan,  1, Wed, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
181     /* <U5927><U6B63>02<U5E74> 大正02年 */
182     "\xc2\xe7\xc0\xb5""02\xc7\xaf" },
183
184
185   { "Japanese era change, 1926, before transition year",
186     1925, Dec, 31, Thu, 12, 00, 00, "ja_JP.UTF-8", "%EY",
187     /* <U5927><U6B63>14<U5E74> 大正14年 */
188     "\xe5\xa4\xa7\xe6\xad\xa3""14\xe5\xb9\xb4" },
189   { "Japanese era change, 1926, start of transition year",
190     1926, Jan,  1, Fri, 12, 00, 00, "ja_JP.UTF-8", "%EY",
191     /* <U5927><U6B63>15<U5E74> 大正15年 */
192     "\xe5\xa4\xa7\xe6\xad\xa3""15\xe5\xb9\xb4" },
193
194   { "Japanese era change, 1926, before transition",
195     1926, Dec, 24, Fri, 12, 00, 00, "ja_JP.UTF-8", "%EY",
196     /* <U5927><U6B63>15<U5E74> 大正15年 */
197     "\xe5\xa4\xa7\xe6\xad\xa3""15\xe5\xb9\xb4" },
198   { "Japanese era change, 1926, after transition",
199     1926, Dec, 25, Sat, 12, 00, 00, "ja_JP.UTF-8", "%EY",
200     /* <U662D><U548C><U5143><U5E74> 昭和元年 */
201     "\xe6\x98\xad\xe5\x92\x8c\xe5\x85\x83\xe5\xb9\xb4" },
202
203   { "Japanese era change, 1926, before end of transition year",
204     1926, Dec, 31, Fri, 12, 00, 00, "ja_JP.UTF-8", "%EY",
205     /* <U662D><U548C><U5143><U5E74> 昭和元年 */
206     "\xe6\x98\xad\xe5\x92\x8c\xe5\x85\x83\xe5\xb9\xb4" },
207   { "Japanese era change, 1926, after transition year",
208     1927, Jan,  1, Sat, 12, 00, 00, "ja_JP.UTF-8", "%EY",
209     /*  <U662D><U548C>02<U5E74> 昭和02年 */
210     "\xe6\x98\xad\xe5\x92\x8c""02\xe5\xb9\xb4" },
211
212
213   { "Japanese era change, 1926, before transition year",
214     1925, Dec, 31, Thu, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
215     /* <U5927><U6B63>14<U5E74> 大正14年 */
216     "\xc2\xe7\xc0\xb5""14\xc7\xaf" },
217   { "Japanese era change, 1926, start of transition year",
218     1926, Jan,  1, Fri, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
219     /* <U5927><U6B63>15<U5E74> 大正15年 */
220     "\xc2\xe7\xc0\xb5""15\xc7\xaf" },
221
222   { "Japanese era change, 1926, before transition",
223     1926, Dec, 24, Fri, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
224     /* <U5927><U6B63>15<U5E74> 大正15年 */
225     "\xc2\xe7\xc0\xb5""15\xc7\xaf" },
226   { "Japanese era change, 1926, after transition",
227     1926, Dec, 25, Sat, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
228     /* <U662D><U548C><U5143><U5E74> 昭和元年 */
229     "\xbe\xbc\xcf\xc2\xb8\xb5\xc7\xaf" },
230
231   { "Japanese era change, 1926, before end of transition year",
232     1926, Dec, 31, Fri, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
233     /* <U662D><U548C><U5143><U5E74> 昭和元年 */
234     "\xbe\xbc\xcf\xc2\xb8\xb5\xc7\xaf" },
235   { "Japanese era change, 1926, after transition year",
236     1927, Jan,  1, Sat, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
237     /*  <U662D><U548C>02<U5E74> 昭和02年 */
238     "\xbe\xbc\xcf\xc2""02\xc7\xaf" },
239
240
241   { "Japanese era change, 1989, before transition year",
242     1988, Dec, 31, Sat, 12, 00, 00, "ja_JP.UTF-8", "%EY",
243     /* <U662D><U548C>63<U5E74> 昭和63年 */
244     "\xe6\x98\xad\xe5\x92\x8c""63\xe5\xb9\xb4" },
245   { "Japanese era change, 1989, start of transition year",
246     1989, Jan,  1, Sun, 12, 00, 00, "ja_JP.UTF-8", "%EY",
247     /* <U662D><U548C>64<U5E74> 昭和64年 */
248     "\xe6\x98\xad\xe5\x92\x8c""64\xe5\xb9\xb4" },
249
250   { "Japanese era change, 1989, before transition",
251     1989, Jan,  7, Sat, 12, 00, 00, "ja_JP.UTF-8", "%EY",
252     /* <U662D><U548C>64<U5E74> 昭和64年 */
253     "\xe6\x98\xad\xe5\x92\x8c""64\xe5\xb9\xb4" },
254   { "Japanese era change, 1989, after transition",
255     1989, Jan,  8, Sun, 12, 00, 00, "ja_JP.UTF-8", "%EY",
256     /* <U5E73><U6210><U5143><U5E74> 平成元年 */
257     "\xe5\xb9\xb3\xe6\x88\x90\xe5\x85\x83\xe5\xb9\xb4" },
258
259   { "Japanese era change, 1989, end of transition year",
260     1989, Dec, 31, Sun, 12, 00, 00, "ja_JP.UTF-8", "%EY",
261     /* <U5E73><U6210><U5143><U5E74> 平成元年 */
262     "\xe5\xb9\xb3\xe6\x88\x90\xe5\x85\x83\xe5\xb9\xb4" },
263   { "Japanese era change, 1989, after transition year",
264     1990, Jan,  1, Mon, 12, 00, 00, "ja_JP.UTF-8", "%EY",
265     /* <U5E73><U6210>02<U5E74> 平成02年 */
266     "\xe5\xb9\xb3\xe6\x88\x90""02\xe5\xb9\xb4" },
267
268
269   { "Japanese era change, 1989, before transition year",
270     1988, Dec, 31, Sat, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
271     /* <U662D><U548C>63<U5E74> 昭和63年 */
272     "\xbe\xbc\xcf\xc2""63\xc7\xaf" },
273   { "Japanese era change, 1989, start of transition year",
274     1989, Jan,  1, Sun, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
275     /* <U662D><U548C>64<U5E74> 昭和64年 */
276     "\xbe\xbc\xcf\xc2""64\xc7\xaf" },
277
278   { "Japanese era change, 1989, before transition",
279     1989, Jan,  7, Sat, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
280     /* <U662D><U548C>64<U5E74> 昭和64年 */
281     "\xbe\xbc\xcf\xc2""64\xc7\xaf" },
282   { "Japanese era change, 1989, after transition",
283     1989, Jan,  8, Sun, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
284     /* <U5E73><U6210><U5143><U5E74> 平成元年 */
285     "\xca\xbf\xc0\xae\xb8\xb5\xc7\xaf" },
286
287   { "Japanese era change, 1989, end of transition year",
288     1989, Dec, 31, Sun, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
289     /* <U5E73><U6210><U5143><U5E74> 平成元年 */
290     "\xca\xbf\xc0\xae\xb8\xb5\xc7\xaf" },
291   { "Japanese era change, 1989, after transition year",
292     1990, Jan,  1, Mon, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
293     /* <U5E73><U6210>02<U5E74> 平成02年 */
294     "\xca\xbf\xc0\xae""02\xc7\xaf" },
295
296
297   { "Japanese era change, 2019, before transition year",
298     2018, Dec, 31, Mon, 12, 00, 00, "ja_JP.UTF-8", "%EY",
299     /* <U5E73><U6210>30<U5E74> 昭和30年 */
300     "\xe5\xb9\xb3\xe6\x88\x90""30\xe5\xb9\xb4" },
301   { "Japanese era change, 2019, start of transition year",
302     2019, Jan,  1, Tue, 12, 00, 00, "ja_JP.UTF-8", "%EY",
303     /* <U5E73><U6210>30<U5E74> 昭和31年 */
304     "\xe5\xb9\xb3\xe6\x88\x90""31\xe5\xb9\xb4" },
305
306   { "Japanese era change, 2019, before transition",
307     2019, Apr, 30, Tue, 12, 00, 00, "ja_JP.UTF-8", "%EY",
308     /* <U5E73><U6210>30<U5E74> 昭和31年 */
309     "\xe5\xb9\xb3\xe6\x88\x90""31\xe5\xb9\xb4" },
310   { "Japanese era change, 2019, after transition",
311     2019, May,  1, Wed, 12, 00, 00, "ja_JP.UTF-8", "%EY",
312     /* <U4EE4><U548C><U5143><U5E74> 令和元年 */
313     "\xe4\xbb\xa4\xe5\x92\x8c\xe5\x85\x83\xe5\xb9\xb4" },
314
315   { "Japanese era change, 2019, end of transition year",
316     2019, Dec, 31, Tue, 12, 00, 00, "ja_JP.UTF-8", "%EY",
317     /* <U4EE4><U548C><U5143><U5E74> 令和元年 */
318     "\xe4\xbb\xa4\xe5\x92\x8c\xe5\x85\x83\xe5\xb9\xb4" },
319   { "Japanese era change, 2019, after transition year",
320     2020, Jan,  1, Wed, 12, 00, 00, "ja_JP.UTF-8", "%EY",
321     /* <U4EE4><U548C>02<U5E74> 令和02年 */
322     "\xe4\xbb\xa4\xe5\x92\x8c""02\xe5\xb9\xb4" },
323
324
325   { "Japanese era change, 2019, before transition year",
326     2018, Dec, 31, Mon, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
327     /* <U5E73><U6210>30<U5E74> 昭和30年 */
328     "\xca\xbf\xc0\xae""30\xc7\xaf" },
329   { "Japanese era change, 2019, start of transition year",
330     2019, Jan,  1, Tue, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
331     /* <U5E73><U6210>30<U5E74> 昭和31年 */
332     "\xca\xbf\xc0\xae""31\xc7\xaf" },
333
334   { "Japanese era change, 2019, before transition",
335     2019, Apr, 30, Tue, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
336     /* <U5E73><U6210>30<U5E74> 昭和31年 */
337     "\xca\xbf\xc0\xae""31\xc7\xaf" },
338   { "Japanese era change, 2019, after transition",
339     2019, May,  1, Wed, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
340     /* <U4EE4><U548C><U5143><U5E74> 令和元年 */
341     "\xce\xe1\xcf\xc2\xb8\xb5\xc7\xaf" },
342
343   { "Japanese era change, 2019, end of transition year",
344     2019, Dec, 31, Tue, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
345     /* <U4EE4><U548C><U5143><U5E74> 令和元年 */
346     "\xce\xe1\xcf\xc2\xb8\xb5\xc7\xaf" },
347   { "Japanese era change, 2019, after transition year",
348     2020, Jan,  1, Wed, 12, 00, 00, "ja_JP.EUC-JP", "%EY",
349     /* <U4EE4><U548C>02<U5E74> 令和02年 */
350     "\xce\xe1\xcf\xc2""02\xc7\xaf" },
351 };
352
353 #define NDATA array_length(data)
354
355 /* Size of buffer passed to strftime.  */
356 #define STRBUFLEN 1000
357 /* Size of buffer passed to tm_to_printed.  */
358 #define TMBUFLEN 50
359
360 /* Helper function to compare strings and print out mismatches in a
361    format suitable for maintaining this test.  TEST_COMPARE_STRINGS
362    prints out a less suitable format.  */
363
364 static void
365 print_string_hex (const char *header, const char *str)
366 {
367   int tictoc = 0;
368   const char *s = str;
369   wchar_t w[STRBUFLEN];
370   size_t i, wlen;
371
372   printf ("%s : ", header);
373
374   if (str == NULL)
375     {
376       printf ("<NULL>\n");
377       return;
378     }
379
380   while (*s)
381     {
382       /* isgraph equivalent, but independent of current locale.  */
383       if (' ' <= *s && *s <= '~')
384         putchar (*s);
385       else
386         {
387           if (tictoc)
388             printf ("\033[36m");
389           else
390             printf ("\033[31m");
391           tictoc = ! tictoc;
392
393           printf ("\\x%02x\033[0m", (unsigned char) *s);
394         }
395
396       ++ s;
397     }
398   printf (" - %s\n", str);
399
400   s = str;
401   wlen = mbsrtowcs (w, &s, strlen (s), NULL);
402   printf ("%*s", (int) strlen (header) + 3, " ");
403   for (i = 0; i < wlen && i < strlen (str); i ++)
404     {
405       if (' ' <= w[i] && w[i] <= '~')
406         putchar (w[i]);
407       else
408         printf ("<U%04X>", (int) w[i]);
409     }
410   printf ("\n");
411 }
412
413 static void
414 compare_strings (const char *got, const char *expected,
415                  const char *filename, int lineno)
416 {
417   if (got && expected && strcmp (got, expected) == 0)
418     return;
419   support_record_failure ();
420   printf ("%s:%d: error: strftime output incorrect\n", filename, lineno);
421   print_string_hex ("Got", got);
422   print_string_hex ("Exp", expected);
423 }
424 #define COMPARE_STRINGS(g,e) compare_strings (g, e, __FILE__, __LINE__)
425
426 const char *weekday_name[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri",
427                                "Sat" };
428
429 /* Helper function to create a printable version of struct tm.  */
430 static void
431 tm_to_printed (struct tm *tm, char *buffer)
432 {
433   const char *wn;
434   char temp[50];
435
436   if (0 <= tm->tm_wday && tm->tm_wday <= 6)
437     wn = weekday_name[tm->tm_wday];
438   else
439     {
440       wn = temp;
441       sprintf (temp, "%d", tm->tm_wday);
442     }
443
444   DIAG_PUSH_NEEDS_COMMENT;
445 #if __GNUC_PREREQ (9, 0)
446   /* GCC 9 warns that strncmp may truncate its output, but that's why
447      we're using it.  When it needs to truncate, it got corrupted
448      data, and we only care that the string is different than valid
449      data, which won't truncate.  */
450   DIAG_IGNORE_NEEDS_COMMENT (9, "-Wformat-truncation=");
451 #endif
452   snprintf (buffer, TMBUFLEN, "%04d/%02d/%02d %02d:%02d:%02d %s",
453             tm->tm_year + 1900,
454             tm->tm_mon + 1,
455             tm->tm_mday,
456             tm->tm_hour,
457             tm->tm_min,
458             tm->tm_sec,
459             wn);
460   DIAG_POP_NEEDS_COMMENT;
461 }
462
463 static int
464 do_test (void)
465 {
466   int i;
467   char buffer[STRBUFLEN];
468   char expected_time[TMBUFLEN];
469   char got_time[TMBUFLEN];
470
471   for (i = 0; i < NDATA; i ++)
472     {
473       const Data *d = &(data[i]);
474       struct tm tm;
475       struct tm tm2;
476       size_t rv;
477       char *rvp;
478
479       /* Print this just to help debug failures.  */
480       printf ("%s:\n\t%s %s %s\n", d->name, d->locale, d->format, d->printed);
481
482       tm.tm_year = d->y - 1900;
483       tm.tm_mon = d->m;
484       tm.tm_mday = d->d;
485       tm.tm_wday = d->w;
486       tm.tm_hour = d->hh;
487       tm.tm_min = d->mm;
488       tm.tm_sec = d->ss;
489       tm.tm_isdst = -1;
490
491       /* LC_ALL may interfere with the snprintf in tm_to_printed.  */
492       if (setlocale (LC_TIME, d->locale) == NULL)
493         {
494           /* See the LOCALES list in the Makefile.  */
495           printf ("locale %s does not exist!\n", d->locale);
496           exit (EXIT_FAILURE);
497         }
498       /* This is just for printing wide characters if there's an error.  */
499       setlocale (LC_CTYPE, d->locale);
500
501       rv = strftime (buffer, sizeof (buffer), d->format, &tm);
502
503       TEST_COMPARE (rv, strlen (d->printed));
504       COMPARE_STRINGS (buffer, d->printed);
505
506       /* Copy the original time, so that any fields not affected by
507          the call to strptime will match.  */
508       tm2 = tm;
509
510       rvp = strptime (d->printed, d->format, &tm2);
511
512       TEST_COMPARE_STRING (rvp, "");
513
514       tm_to_printed (&tm, expected_time);
515       tm_to_printed (&tm2, got_time);
516       TEST_COMPARE_STRING (got_time, expected_time);
517     }
518
519   return 0;
520 }
521
522 #include <support/test-driver.c>