gnulib-common: prefer _GL_UNUSED over _UNUSED_PARAMETER_
[gnulib.git] / tests / test-getdate.c
1 /* Test of getdate() function.
2    Copyright (C) 2008, 2009 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 /* Written by Simon Josefsson <simon@josefsson.org>, 2008.  */
19
20 #include <config.h>
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "progname.h"
27
28 #include "getdate.h"
29
30 #define ASSERT(expr)                                                    \
31   do                                                                    \
32     {                                                                   \
33       if (!(expr))                                                      \
34         {                                                               \
35           fprintf (stderr, "%s:%d: assertion failed\n",                 \
36                    __FILE__, __LINE__);                                 \
37           fflush (stderr);                                              \
38           abort ();                                                     \
39         }                                                               \
40     }                                                                   \
41   while (0)
42
43 #ifdef DEBUG
44 #define LOG(str, now, res)                                              \
45   printf ("string `%s' diff %d %d\n",                   \
46           str, res.tv_sec - now.tv_sec, res.tv_nsec - now.tv_nsec);
47 #else
48 #define LOG(str, now, res) (void) 0
49 #endif
50
51 static const char* const day_table[] =
52 {
53   "SUNDAY",
54   "MONDAY",
55   "TUESDAY",
56   "WEDNESDAY",
57   "THURSDAY",
58   "FRIDAY",
59   "SATURDAY",
60   NULL
61 };
62
63 int
64 main (int argc _GL_UNUSED, char **argv)
65 {
66   struct timespec result;
67   struct timespec result2;
68   struct timespec now;
69   const char *p;
70   int i;
71
72   set_program_name (argv[0]);
73
74   now.tv_sec = 4711;
75   now.tv_nsec = 1267;
76   p = "now";
77   ASSERT (get_date (&result, p, &now));
78   LOG (p, now, result);
79   ASSERT (now.tv_sec == result.tv_sec && now.tv_nsec == result.tv_nsec);
80
81   now.tv_sec = 4711;
82   now.tv_nsec = 1267;
83   p = "tomorrow";
84   ASSERT (get_date (&result, p, &now));
85   LOG (p, now, result);
86   ASSERT (now.tv_sec + 24 * 60 * 60 == result.tv_sec
87           && now.tv_nsec == result.tv_nsec);
88
89   now.tv_sec = 4711;
90   now.tv_nsec = 1267;
91   p = "yesterday";
92   ASSERT (get_date (&result, p, &now));
93   LOG (p, now, result);
94   ASSERT (now.tv_sec - 24 * 60 * 60 == result.tv_sec
95           && now.tv_nsec == result.tv_nsec);
96
97   now.tv_sec = 4711;
98   now.tv_nsec = 1267;
99   p = "4 hours";
100   ASSERT (get_date (&result, p, &now));
101   LOG (p, now, result);
102   ASSERT (now.tv_sec + 4 * 60 * 60 == result.tv_sec
103           && now.tv_nsec == result.tv_nsec);
104
105   /* test if timezone is not being ignored for day offset */
106   now.tv_sec = 4711;
107   now.tv_nsec = 1267;
108   p = "UTC+400 +24 hours";
109   ASSERT (get_date (&result, p, &now));
110   LOG (p, now, result);
111   p = "UTC+400 +1 day";
112   ASSERT (get_date (&result2, p, &now));
113   LOG (p, now, result2);
114   ASSERT (result.tv_sec == result2.tv_sec
115           && result.tv_nsec == result2.tv_nsec);
116
117   /* test if several time zones formats are handled same way */
118   now.tv_sec = 4711;
119   now.tv_nsec = 1267;
120   p = "UTC+14:00";
121   ASSERT (get_date (&result, p, &now));
122   LOG (p, now, result);
123   p = "UTC+14";
124   ASSERT (get_date (&result2, p, &now));
125   LOG (p, now, result2);
126   ASSERT (result.tv_sec == result2.tv_sec
127           && result.tv_nsec == result2.tv_nsec);
128   p = "UTC+1400";
129   ASSERT (get_date (&result2, p, &now));
130   LOG (p, now, result2);
131   ASSERT (result.tv_sec == result2.tv_sec
132           && result.tv_nsec == result2.tv_nsec);
133
134   now.tv_sec = 4711;
135   now.tv_nsec = 1267;
136   p = "UTC-14:00";
137   ASSERT (get_date (&result, p, &now));
138   LOG (p, now, result);
139   p = "UTC-14";
140   ASSERT (get_date (&result2, p, &now));
141   LOG (p, now, result2);
142   ASSERT (result.tv_sec == result2.tv_sec
143           && result.tv_nsec == result2.tv_nsec);
144   p = "UTC-1400";
145   ASSERT (get_date (&result2, p, &now));
146   LOG (p, now, result2);
147   ASSERT (result.tv_sec == result2.tv_sec
148           && result.tv_nsec == result2.tv_nsec);
149
150   now.tv_sec = 4711;
151   now.tv_nsec = 1267;
152   p = "UTC+0:15";
153   ASSERT (get_date (&result, p, &now));
154   LOG (p, now, result);
155   p = "UTC+0015";
156   ASSERT (get_date (&result2, p, &now));
157   LOG (p, now, result2);
158   ASSERT (result.tv_sec == result2.tv_sec
159           && result.tv_nsec == result2.tv_nsec);
160
161   now.tv_sec = 4711;
162   now.tv_nsec = 1267;
163   p = "UTC-1:30";
164   ASSERT (get_date (&result, p, &now));
165   LOG (p, now, result);
166   p = "UTC-130";
167   ASSERT (get_date (&result2, p, &now));
168   LOG (p, now, result2);
169   ASSERT (result.tv_sec == result2.tv_sec
170           && result.tv_nsec == result2.tv_nsec);
171
172
173   /* TZ out of range should cause get_date failure */
174   now.tv_sec = 4711;
175   now.tv_nsec = 1267;
176   p = "UTC+25:00";
177   ASSERT (!get_date (&result, p, &now));
178
179         /* Check for several invalid countable dayshifts */
180   now.tv_sec = 4711;
181   now.tv_nsec = 1267;
182   p = "UTC+4:00 +40 yesterday";
183   ASSERT (!get_date (&result, p, &now));
184   p = "UTC+4:00 next yesterday";
185   ASSERT (!get_date (&result, p, &now));
186   p = "UTC+4:00 tomorrow ago";
187   ASSERT (!get_date (&result, p, &now));
188   p = "UTC+4:00 40 now ago";
189   ASSERT (!get_date (&result, p, &now));
190   p = "UTC+4:00 last tomorrow";
191   ASSERT (!get_date (&result, p, &now));
192   p = "UTC+4:00 -4 today";
193   ASSERT (!get_date (&result, p, &now));
194
195   /* And check correct usage of dayshifts */
196   now.tv_sec = 4711;
197   now.tv_nsec = 1267;
198   p = "UTC+400 tomorrow";
199   ASSERT (get_date (&result, p, &now));
200   LOG (p, now, result);
201   p = "UTC+400 +1 day";
202   ASSERT (get_date (&result2, p, &now));
203   LOG (p, now, result2);
204   ASSERT (result.tv_sec == result2.tv_sec
205           && result.tv_nsec == result2.tv_nsec);
206   now.tv_sec = 4711;
207   now.tv_nsec = 1267;
208   p = "UTC+400 yesterday";
209   ASSERT (get_date (&result, p, &now));
210   LOG (p, now, result);
211   p = "UTC+400 1 day ago";
212   ASSERT (get_date (&result2, p, &now));
213   LOG (p, now, result2);
214   ASSERT (result.tv_sec == result2.tv_sec
215           && result.tv_nsec == result2.tv_nsec);
216   now.tv_sec = 4711;
217   now.tv_nsec = 1267;
218   p = "UTC+400 now";
219   ASSERT (get_date (&result, p, &now));
220   LOG (p, now, result);
221   p = "UTC+400 +0 minutes"; /* silly, but simple "UTC+400" is different*/
222   ASSERT (get_date (&result2, p, &now));
223   LOG (p, now, result2);
224   ASSERT (result.tv_sec == result2.tv_sec
225           && result.tv_nsec == result2.tv_nsec);
226
227   /* Check that some "next Monday", "last Wednesday", etc. are correct.  */
228   setenv ("TZ", "UTC0", 1);
229   for (i = 0; day_table[i]; i++)
230     {
231       unsigned int thur2 = 7 * 24 * 3600; /* 2nd thursday */
232       char tmp[32];
233       sprintf (tmp, "NEXT %s", day_table[i]);
234       now.tv_sec = thur2 + 4711;
235       now.tv_nsec = 1267;
236       ASSERT (get_date (&result, tmp, &now));
237       LOG (tmp, now, result);
238       ASSERT (result.tv_nsec == 0);
239       ASSERT (result.tv_sec == thur2 + (i == 4 ? 7 : (i + 3) % 7) * 24 * 3600);
240
241       sprintf (tmp, "LAST %s", day_table[i]);
242       now.tv_sec = thur2 + 4711;
243       now.tv_nsec = 1267;
244       ASSERT (get_date (&result, tmp, &now));
245       LOG (tmp, now, result);
246       ASSERT (result.tv_nsec == 0);
247       ASSERT (result.tv_sec == thur2 + ((i + 3) % 7 - 7) * 24 * 3600);
248     }
249
250   p = "THURSDAY UTC+00";  /* The epoch was on Thursday.  */
251   now.tv_sec = 0;
252   now.tv_nsec = 0;
253   ASSERT (get_date (&result, p, &now));
254   LOG (p, now, result);
255   ASSERT (result.tv_sec == now.tv_sec
256           && result.tv_nsec == now.tv_nsec);
257
258   p = "FRIDAY UTC+00";
259   now.tv_sec = 0;
260   now.tv_nsec = 0;
261   ASSERT (get_date (&result, p, &now));
262   LOG (p, now, result);
263   ASSERT (result.tv_sec == 24 * 3600
264           && result.tv_nsec == now.tv_nsec);
265
266   return 0;
267 }