1 /*
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright © 2023 Keith Packard
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 *
18 * 3. Neither the name of the copyright holder nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33 * OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 #include <time.h>
37 #include <stdio.h>
38 #include <errno.h>
39 #include <stdbool.h>
40 #include <string.h>
41
42 static struct {
43 struct tm tm;
44 char *result;
45 int _errno;
46 } tests[] = {
47 {
48 .tm = {
49 .tm_sec = 0,
50 .tm_min = 0,
51 .tm_hour = 0,
52 .tm_mday = 0,
53 .tm_mon = 0,
54 .tm_year = 0,
55 .tm_wday = 0,
56 .tm_yday = 0,
57 .tm_isdst = 0,
58 },
59 .result = "Sun Jan 0 00:00:00 1900\n",
60 ._errno = 0,
61 },
62 {
63 .tm = {
64 .tm_sec = 0,
65 .tm_min = 0,
66 .tm_hour = 0,
67 .tm_mday = 0,
68 .tm_mon = 0,
69 .tm_year = 8100,
70 .tm_wday = 0,
71 .tm_yday = 0,
72 .tm_isdst = 0,
73 },
74 .result = NULL,
75 ._errno = EOVERFLOW,
76 },
77 {
78 /* winter time is March, 21st 2022 at 8:15pm and 20 seconds */
79 .tm = {
80 .tm_sec = 20,
81 .tm_min = 15,
82 .tm_hour = 20,
83 .tm_mday = 21,
84 .tm_mon = 3 - 1,
85 .tm_year = 2022 - 1900,
86 .tm_wday = 0,
87 .tm_isdst = 0
88 },
89 .result = "Sun Mar 21 20:15:20 2022\n",
90 ._errno = 0,
91 },
92 {
93 /* summer time is July, 15th 2022 at 10:50am and 40 seconds */
94 .tm = {
95 .tm_sec = 40,
96 .tm_min = 50,
97 .tm_hour = 10,
98 .tm_mday = 15,
99 .tm_mon = 7 - 1,
100 .tm_year = 2022 - 1900,
101 .tm_wday = 0,
102 .tm_isdst = 1
103 },
104 .result = "Sun Jul 15 10:50:40 2022\n",
105 ._errno = 0,
106 },
107 #if defined(__GLIBC__) || defined(__PICOLIBC__)
108 {
109 /* Invalid wday */
110 .tm = {
111 .tm_sec = 40,
112 .tm_min = 50,
113 .tm_hour = 10,
114 .tm_mday = 15,
115 .tm_mon = 7 - 1,
116 .tm_year = 2022 - 1900,
117 .tm_wday = -1,
118 .tm_isdst = 1
119 },
120 .result = "??? Jul 15 10:50:40 2022\n",
121 ._errno = 0,
122 },
123 {
124 /* Invalid mon */
125 .tm = {
126 .tm_sec = 40,
127 .tm_min = 50,
128 .tm_hour = 10,
129 .tm_mday = 15,
130 .tm_mon = 12,
131 .tm_year = 2022 - 1900,
132 .tm_wday = 1,
133 .tm_isdst = 1
134 },
135 .result = "Mon ??? 15 10:50:40 2022\n",
136 ._errno = 0,
137 },
138 #endif
139 };
140
mylen(const char * s)141 static int mylen(const char *s)
142 {
143 if (s == NULL)
144 return -1;
145 return strlen(s);
146 }
147
main(void)148 int main(void)
149 {
150 unsigned n;
151 int err = 0;
152 char buf[26];
153
154 (void) tests;
155 for (n = 0; n < sizeof(tests)/sizeof(tests[0]); n++)
156 {
157 const char *result = asctime_r(&tests[n].tm, buf);
158
159 if (tests[n].result == NULL && result == NULL)
160 continue;
161
162 if (tests[n].result != NULL && result != NULL &&
163 strcmp(tests[n].result, result) == 0)
164 {
165 continue;
166 }
167 printf("expect \"%s\"(%d) result \"%s\"(%d)\n", tests[n].result, mylen(tests[n].result), result, mylen(result));
168 err = 1;
169 }
170 return err;
171 }
172