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