]>
Commit | Line | Data |
---|---|---|
e0e4c321 | 1 | /* Data-driven tests for strftime/strptime. |
581c785b | 2 | Copyright (C) 2019-2022 Free Software Foundation, Inc. This file is |
e0e4c321 DD |
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 | |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
e0e4c321 DD |
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> | |
8260f236 | 28 | #include <libc-diag.h> |
e0e4c321 DD |
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" }, | |
0bd545ee DD |
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" }, | |
e0e4c321 DD |
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 | |
0bd545ee | 408 | printf ("<U%04X>", (int) w[i]); |
e0e4c321 DD |
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 | ||
8260f236 DD |
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 | |
e0e4c321 DD |
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); | |
8260f236 | 460 | DIAG_POP_NEEDS_COMMENT; |
e0e4c321 DD |
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> |