1 /* Data-driven tests for strftime/strptime.
2 Copyright (C) 2019-2022 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
print_string_hex(const char * header,const char * str)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
compare_strings(const char * got,const char * expected,const char * filename,int lineno)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
tm_to_printed(struct tm * tm,char * buffer)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
do_test(void)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>
523