8 #define yyclearin (yychar=(YYEMPTY))
9 #define yyerrok (yyerrflag=0)
10 #define YYRECOVERING() (yyerrflag!=0)
14 ** Originally written by Steven M. Bellovin <smb@research.att.com> while
15 ** at the University of North Carolina at Chapel Hill. Later tweaked by
16 ** a couple of people on Usenet. Completely overhauled by Rich $alz
17 ** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
19 ** This grammar has 10 shift/reduce conflicts.
21 ** This code is in the public domain and has no copyright.
23 /* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
24 /* SUPPRESS 288 on yyerrlab *//* Label unused */
28 #include <sys/types.h>
38 #endif /* STDC_HEADERS */
40 # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
44 #endif /* HAVE_STRING_H */
47 #endif /* HAVE_STRINGS_H */
48 #if TIME_WITH_SYS_TIME
57 #define HOUR(x) ((time_t)(x) * 60)
58 #define SECSPERDAY (24L * 60L * 60L)
62 ** An entry in the lexical lookup table.
64 typedef struct _TABLE {
72 ** Daylight-savings mode: on, off, or not yet known.
74 typedef enum _DSTMODE {
75 DSTon, DSToff, DSTmaybe
79 ** Meridian: am, pm, or 24-hour style.
81 typedef enum _MERIDIAN {
87 ** Global variables. We could get rid of most of these by using a good
88 ** union as the yacc stack. (This routine was originally written before
89 ** yacc had the %union construct.) Maybe someday; right now we only use
90 ** the %union very rarely.
93 static DSTMODE yyDSTmode;
94 static time_t yyDayOrdinal;
95 static time_t yyDayNumber;
96 static int yyHaveDate;
99 static int yyHaveTime;
100 static int yyHaveZone;
101 static time_t yyTimezone;
103 static time_t yyHour;
104 static time_t yyMinutes;
105 static time_t yyMonth;
106 static time_t yySeconds;
107 static time_t yyYear;
108 static MERIDIAN yyMeridian;
109 static time_t yyRelMonth;
110 static time_t yyRelSeconds;
112 static int yyerror __P((char *s));
113 static int yylex __P((void));
114 static int yyparse __P((void));
116 #line 107 "getdate.y"
117 #ifndef YYSTYPE_DEFINED
118 #define YYSTYPE_DEFINED
121 enum _MERIDIAN Meridian;
123 #endif /* YYSTYPE_DEFINED */
129 #define tMERIDIAN 261
130 #define tMINUTE_UNIT 262
132 #define tMONTH_UNIT 264
133 #define tSEC_UNIT 265
138 #define YYERRCODE 256
139 #if defined(__cplusplus) || defined(__STDC__)
140 const short yylhs[] =
145 0, 0, 2, 2, 2, 2, 2, 2, 3, 3,
146 3, 3, 3, 4, 4, 4, 6, 6, 6, 5,
147 5, 5, 5, 5, 5, 5, 5, 7, 7, 9,
148 9, 9, 9, 9, 9, 9, 9, 9, 8, 1,
151 #if defined(__cplusplus) || defined(__STDC__)
152 const short yylen[] =
157 0, 2, 1, 1, 1, 1, 1, 1, 2, 4,
158 4, 6, 6, 1, 1, 2, 1, 2, 2, 3,
159 5, 3, 3, 2, 4, 2, 3, 2, 1, 2,
160 2, 1, 2, 2, 1, 2, 2, 1, 1, 0,
163 #if defined(__cplusplus) || defined(__STDC__)
164 const short yydefred[] =
169 0, 0, 15, 32, 0, 38, 35, 0, 0, 0,
170 2, 3, 4, 5, 6, 7, 8, 0, 18, 0,
171 31, 36, 33, 19, 9, 30, 0, 37, 34, 0,
172 0, 0, 16, 28, 0, 23, 27, 22, 0, 0,
173 25, 41, 11, 0, 10, 0, 0, 21, 13, 12,
175 #if defined(__cplusplus) || defined(__STDC__)
176 const short yydgoto[] =
181 45, 11, 12, 13, 14, 15, 16, 17, 18,
183 #if defined(__cplusplus) || defined(__STDC__)
184 const short yysindex[] =
189 -249, -38, 0, 0, -260, 0, 0, -240, -47, -248,
190 0, 0, 0, 0, 0, 0, 0, -237, 0, -18,
191 0, 0, 0, 0, 0, 0, -262, 0, 0, -239,
192 -238, -236, 0, 0, -235, 0, 0, 0, -56, -19,
193 0, 0, 0, -234, 0, -232, -258, 0, 0, 0,};
194 #if defined(__cplusplus) || defined(__STDC__)
195 const short yyrindex[] =
200 0, 1, 0, 0, 0, 0, 0, 0, 69, 12,
201 0, 0, 0, 0, 0, 0, 0, 23, 0, 34,
202 0, 0, 0, 0, 0, 0, 67, 0, 0, 0,
203 0, 0, 0, 0, 0, 0, 0, 0, 56, 45,
204 0, 0, 0, 0, 0, 0, 56, 0, 0, 0,};
205 #if defined(__cplusplus) || defined(__STDC__)
206 const short yygindex[] =
211 -17, 0, 0, 0, 0, 0, 0, 0, 0,
213 #define YYTABLESIZE 337
214 #if defined(__cplusplus) || defined(__STDC__)
215 const short yytable[] =
220 17, 44, 42, 36, 37, 19, 20, 49, 2, 3,
221 31, 14, 4, 5, 6, 7, 8, 9, 10, 34,
222 33, 21, 29, 22, 23, 35, 38, 46, 39, 50,
223 40, 41, 47, 24, 48, 0, 0, 0, 0, 0,
224 0, 0, 0, 0, 20, 0, 0, 0, 0, 0,
225 0, 0, 0, 0, 0, 40, 0, 0, 0, 0,
226 0, 0, 0, 0, 0, 0, 26, 0, 39, 0,
227 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
228 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
229 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
230 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
231 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
232 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
233 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
234 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
235 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
236 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
237 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
238 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
239 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
240 0, 0, 0, 0, 42, 0, 0, 0, 0, 43,
241 24, 0, 0, 25, 26, 27, 28, 29, 30, 0,
242 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
243 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
244 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
245 0, 0, 0, 0, 0, 0, 0, 0, 17, 17,
246 0, 0, 17, 17, 17, 17, 17, 17, 17, 14,
247 14, 0, 0, 14, 14, 14, 14, 14, 14, 14,
248 29, 29, 0, 0, 29, 29, 29, 29, 29, 29,
249 29, 24, 24, 0, 0, 24, 24, 24, 24, 24,
250 24, 24, 20, 20, 0, 0, 20, 20, 20, 20,
251 20, 20, 20, 40, 40, 0, 0, 40, 40, 40,
252 40, 0, 40, 40, 26, 26, 0, 39, 26, 26,
253 26, 26, 0, 0, 26, 39, 39,
255 #if defined(__cplusplus) || defined(__STDC__)
256 const short yycheck[] =
261 0, 58, 261, 266, 267, 44, 267, 266, 258, 259,
262 58, 0, 262, 263, 264, 265, 266, 267, 268, 257,
263 269, 262, 0, 264, 265, 44, 266, 47, 267, 47,
264 267, 267, 267, 0, 267, -1, -1, -1, -1, -1,
265 -1, -1, -1, -1, 0, -1, -1, -1, -1, -1,
266 -1, -1, -1, -1, -1, 0, -1, -1, -1, -1,
267 -1, -1, -1, -1, -1, -1, 0, -1, 0, -1,
268 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
269 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
270 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
271 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
272 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
273 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
274 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
275 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
276 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
277 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
278 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
279 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
280 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
281 -1, -1, -1, -1, 261, -1, -1, -1, -1, 266,
282 258, -1, -1, 261, 262, 263, 264, 265, 266, -1,
283 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
284 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
285 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
286 -1, -1, -1, -1, -1, -1, -1, -1, 258, 259,
287 -1, -1, 262, 263, 264, 265, 266, 267, 268, 258,
288 259, -1, -1, 262, 263, 264, 265, 266, 267, 268,
289 258, 259, -1, -1, 262, 263, 264, 265, 266, 267,
290 268, 258, 259, -1, -1, 262, 263, 264, 265, 266,
291 267, 268, 258, 259, -1, -1, 262, 263, 264, 265,
292 266, 267, 268, 258, 259, -1, -1, 262, 263, 264,
293 265, -1, 267, 268, 258, 259, -1, 259, 262, 263,
294 264, 265, -1, -1, 268, 267, 268,
300 #define YYMAXTOKEN 269
302 #if defined(__cplusplus) || defined(__STDC__)
303 const char * const yyname[] =
308 "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
309 0,0,0,0,0,0,0,0,0,0,"','",0,0,"'/'",0,0,0,0,0,0,0,0,0,0,"':'",0,0,0,0,0,0,0,0,0,
310 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
311 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
312 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
313 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
314 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"tAGO","tDAY",
315 "tDAYZONE","tID","tMERIDIAN","tMINUTE_UNIT","tMONTH","tMONTH_UNIT","tSEC_UNIT",
316 "tSNUMBER","tUNUMBER","tZONE","tDST",
318 #if defined(__cplusplus) || defined(__STDC__)
319 const char * const yyrule[] =
332 "time : tUNUMBER tMERIDIAN",
333 "time : tUNUMBER ':' tUNUMBER o_merid",
334 "time : tUNUMBER ':' tUNUMBER tSNUMBER",
335 "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid",
336 "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER",
342 "day : tUNUMBER tDAY",
343 "date : tUNUMBER '/' tUNUMBER",
344 "date : tUNUMBER '/' tUNUMBER '/' tUNUMBER",
345 "date : tUNUMBER tSNUMBER tSNUMBER",
346 "date : tUNUMBER tMONTH tSNUMBER",
347 "date : tMONTH tUNUMBER",
348 "date : tMONTH tUNUMBER ',' tUNUMBER",
349 "date : tUNUMBER tMONTH",
350 "date : tUNUMBER tMONTH tUNUMBER",
351 "rel : relunit tAGO",
353 "relunit : tUNUMBER tMINUTE_UNIT",
354 "relunit : tSNUMBER tMINUTE_UNIT",
355 "relunit : tMINUTE_UNIT",
356 "relunit : tSNUMBER tSEC_UNIT",
357 "relunit : tUNUMBER tSEC_UNIT",
358 "relunit : tSEC_UNIT",
359 "relunit : tSNUMBER tMONTH_UNIT",
360 "relunit : tUNUMBER tMONTH_UNIT",
361 "relunit : tMONTH_UNIT",
364 "o_merid : tMERIDIAN",
369 #define YYMAXDEPTH YYSTACKSIZE
372 #define YYSTACKSIZE YYMAXDEPTH
374 #define YYSTACKSIZE 10000
375 #define YYMAXDEPTH 10000
378 #define YYINITSTACKSIZE 200
392 #line 326 "getdate.y"
394 /* Month and day table. */
395 static TABLE const MonthDayTable[] = {
396 { "january", tMONTH, 1 },
397 { "february", tMONTH, 2 },
398 { "march", tMONTH, 3 },
399 { "april", tMONTH, 4 },
400 { "may", tMONTH, 5 },
401 { "june", tMONTH, 6 },
402 { "july", tMONTH, 7 },
403 { "august", tMONTH, 8 },
404 { "september", tMONTH, 9 },
405 { "sept", tMONTH, 9 },
406 { "october", tMONTH, 10 },
407 { "november", tMONTH, 11 },
408 { "december", tMONTH, 12 },
409 { "sunday", tDAY, 0 },
410 { "monday", tDAY, 1 },
411 { "tuesday", tDAY, 2 },
413 { "wednesday", tDAY, 3 },
414 { "wednes", tDAY, 3 },
415 { "thursday", tDAY, 4 },
417 { "thurs", tDAY, 4 },
418 { "friday", tDAY, 5 },
419 { "saturday", tDAY, 6 },
423 /* Time units table. */
424 static TABLE const UnitsTable[] = {
425 { "year", tMONTH_UNIT, 12 },
426 { "month", tMONTH_UNIT, 1 },
427 { "fortnight", tMINUTE_UNIT, 14 * 24 * 60 },
428 { "week", tMINUTE_UNIT, 7 * 24 * 60 },
429 { "day", tMINUTE_UNIT, 1 * 24 * 60 },
430 { "hour", tMINUTE_UNIT, 60 },
431 { "minute", tMINUTE_UNIT, 1 },
432 { "min", tMINUTE_UNIT, 1 },
433 { "second", tSEC_UNIT, 1 },
434 { "sec", tSEC_UNIT, 1 },
438 /* Assorted relative-time words. */
439 static TABLE const OtherTable[] = {
440 { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 },
441 { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 },
442 { "today", tMINUTE_UNIT, 0 },
443 { "now", tMINUTE_UNIT, 0 },
444 { "last", tUNUMBER, -1 },
445 { "this", tMINUTE_UNIT, 0 },
446 { "next", tUNUMBER, 2 },
447 { "first", tUNUMBER, 1 },
448 /* { "second", tUNUMBER, 2 }, */
449 { "third", tUNUMBER, 3 },
450 { "fourth", tUNUMBER, 4 },
451 { "fifth", tUNUMBER, 5 },
452 { "sixth", tUNUMBER, 6 },
453 { "seventh", tUNUMBER, 7 },
454 { "eighth", tUNUMBER, 8 },
455 { "ninth", tUNUMBER, 9 },
456 { "tenth", tUNUMBER, 10 },
457 { "eleventh", tUNUMBER, 11 },
458 { "twelfth", tUNUMBER, 12 },
463 /* The timezone table. */
464 /* Some of these are commented out because a time_t can't store a float. */
465 static TABLE const TimezoneTable[] = {
466 { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */
467 { "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */
468 { "utc", tZONE, HOUR( 0) },
469 { "wet", tZONE, HOUR( 0) }, /* Western European */
470 { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */
471 { "wat", tZONE, HOUR( 1) }, /* West Africa */
472 { "at", tZONE, HOUR( 2) }, /* Azores */
474 /* For completeness. BST is also British Summer, and GST is
475 * also Guam Standard. */
476 { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */
477 { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */
480 { "nft", tZONE, HOUR(3.5) }, /* Newfoundland */
481 { "nst", tZONE, HOUR(3.5) }, /* Newfoundland Standard */
482 { "ndt", tDAYZONE, HOUR(3.5) }, /* Newfoundland Daylight */
484 { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */
485 { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */
486 { "est", tZONE, HOUR( 5) }, /* Eastern Standard */
487 { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */
488 { "cst", tZONE, HOUR( 6) }, /* Central Standard */
489 { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */
490 { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */
491 { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */
492 { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */
493 { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */
494 { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */
495 { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */
496 { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */
497 { "hdt", tDAYZONE, HOUR(10) }, /* Hawaii Daylight */
498 { "cat", tZONE, HOUR(10) }, /* Central Alaska */
499 { "ahst", tZONE, HOUR(10) }, /* Alaska-Hawaii Standard */
500 { "nt", tZONE, HOUR(11) }, /* Nome */
501 { "idlw", tZONE, HOUR(12) }, /* International Date Line West */
502 { "cet", tZONE, -HOUR(1) }, /* Central European */
503 { "met", tZONE, -HOUR(1) }, /* Middle European */
504 { "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */
505 { "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */
506 { "swt", tZONE, -HOUR(1) }, /* Swedish Winter */
507 { "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */
508 { "fwt", tZONE, -HOUR(1) }, /* French Winter */
509 { "fst", tDAYZONE, -HOUR(1) }, /* French Summer */
510 { "eet", tZONE, -HOUR(2) }, /* Eastern Europe, USSR Zone 1 */
511 { "bt", tZONE, -HOUR(3) }, /* Baghdad, USSR Zone 2 */
513 { "it", tZONE, -HOUR(3.5) },/* Iran */
515 { "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */
516 { "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */
518 { "ist", tZONE, -HOUR(5.5) },/* Indian Standard */
520 { "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */
522 /* For completeness. NST is also Newfoundland Stanard, and SST is
523 * also Swedish Summer. */
524 { "nst", tZONE, -HOUR(6.5) },/* North Sumatra */
525 { "sst", tZONE, -HOUR(7) }, /* South Sumatra, USSR Zone 6 */
527 { "wast", tZONE, -HOUR(7) }, /* West Australian Standard */
528 { "wadt", tDAYZONE, -HOUR(7) }, /* West Australian Daylight */
530 { "jt", tZONE, -HOUR(7.5) },/* Java (3pm in Cronusland!) */
532 { "cct", tZONE, -HOUR(8) }, /* China Coast, USSR Zone 7 */
533 { "jst", tZONE, -HOUR(9) }, /* Japan Standard, USSR Zone 8 */
535 { "cast", tZONE, -HOUR(9.5) },/* Central Australian Standard */
536 { "cadt", tDAYZONE, -HOUR(9.5) },/* Central Australian Daylight */
538 { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */
539 { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */
540 { "gst", tZONE, -HOUR(10) }, /* Guam Standard, USSR Zone 9 */
541 { "nzt", tZONE, -HOUR(12) }, /* New Zealand */
542 { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */
543 { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */
544 { "idle", tZONE, -HOUR(12) }, /* International Date Line East */
548 /* Military timezone table. */
549 static TABLE const MilitaryTable[] = {
550 { "a", tZONE, HOUR( 1) },
551 { "b", tZONE, HOUR( 2) },
552 { "c", tZONE, HOUR( 3) },
553 { "d", tZONE, HOUR( 4) },
554 { "e", tZONE, HOUR( 5) },
555 { "f", tZONE, HOUR( 6) },
556 { "g", tZONE, HOUR( 7) },
557 { "h", tZONE, HOUR( 8) },
558 { "i", tZONE, HOUR( 9) },
559 { "k", tZONE, HOUR( 10) },
560 { "l", tZONE, HOUR( 11) },
561 { "m", tZONE, HOUR( 12) },
562 { "n", tZONE, HOUR(- 1) },
563 { "o", tZONE, HOUR(- 2) },
564 { "p", tZONE, HOUR(- 3) },
565 { "q", tZONE, HOUR(- 4) },
566 { "r", tZONE, HOUR(- 5) },
567 { "s", tZONE, HOUR(- 6) },
568 { "t", tZONE, HOUR(- 7) },
569 { "u", tZONE, HOUR(- 8) },
570 { "v", tZONE, HOUR(- 9) },
571 { "w", tZONE, HOUR(-10) },
572 { "x", tZONE, HOUR(-11) },
573 { "y", tZONE, HOUR(-12) },
574 { "z", tZONE, HOUR( 0) },
591 ToSeconds(Hours, Minutes, Seconds, Meridian)
597 if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
601 if (Hours < 0 || Hours > 23)
603 return (Hours * 60L + Minutes) * 60L + Seconds;
605 if (Hours < 1 || Hours > 12)
609 return (Hours * 60L + Minutes) * 60L + Seconds;
611 if (Hours < 1 || Hours > 12)
615 return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
624 * A negative number, which means to use its absolute value (why?)
625 * A number from 0 to 99, which means a year from 1900 to 1999, or
626 * The actual year (>=100). */
628 Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
638 static int DaysInMonth[12] = {
639 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
649 else if (Year < 100) {
654 DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
656 /* Checking for 2038 bogusly assumes that time_t is 32 bits. But
657 I'm too lazy to try to check for time_t overflow in another way. */
658 if (Year < EPOCH || Year > 2038
659 || Month < 1 || Month > 12
660 /* Lint fluff: "conversion from long may lose accuracy" */
661 || Day < 1 || Day > DaysInMonth[(int)--Month])
664 for (Julian = Day - 1, i = 0; i < Month; i++)
665 Julian += DaysInMonth[i];
666 for (i = EPOCH; i < Year; i++)
667 Julian += 365 + (i % 4 == 0);
668 Julian *= SECSPERDAY;
669 Julian += yyTimezone * 60L;
670 if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
674 || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
681 DSTcorrect(Start, Future)
688 StartDay = (localtime(&Start)->tm_hour + 1) % 24;
689 FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
690 return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
695 RelativeDate(Start, DayOrdinal, DayNumber)
704 tm = localtime(&now);
705 now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
706 now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
707 return DSTcorrect(Start, now);
712 RelativeMonth(Start, RelMonth)
722 tm = localtime(&Start);
723 Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
725 Month = Month % 12 + 1;
726 return DSTcorrect(Start,
727 Convert(Month, (time_t)tm->tm_mday, Year,
728 (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
743 /* Make it lowercase. */
744 for (p = buff; *p; p++)
745 if (isupper((unsigned char)*p))
746 *p = tolower((unsigned char)*p);
748 if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
749 yylval.Meridian = MERam;
752 if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
753 yylval.Meridian = MERpm;
757 /* See if we have an abbreviation for a month. */
758 if (strlen(buff) == 3)
760 else if (strlen(buff) == 4 && buff[3] == '.') {
767 for (tp = MonthDayTable; tp->name; tp++) {
769 if (strncmp(buff, tp->name, 3) == 0) {
770 yylval.Number = tp->value;
774 else if (strcmp(buff, tp->name) == 0) {
775 yylval.Number = tp->value;
780 for (tp = TimezoneTable; tp->name; tp++)
781 if (strcmp(buff, tp->name) == 0) {
782 yylval.Number = tp->value;
786 if (strcmp(buff, "dst") == 0)
789 for (tp = UnitsTable; tp->name; tp++)
790 if (strcmp(buff, tp->name) == 0) {
791 yylval.Number = tp->value;
795 /* Strip off any plural and try the units table again. */
796 i = strlen(buff) - 1;
797 if (buff[i] == 's') {
799 for (tp = UnitsTable; tp->name; tp++)
800 if (strcmp(buff, tp->name) == 0) {
801 yylval.Number = tp->value;
804 buff[i] = 's'; /* Put back for "this" in OtherTable. */
807 for (tp = OtherTable; tp->name; tp++)
808 if (strcmp(buff, tp->name) == 0) {
809 yylval.Number = tp->value;
813 /* Military timezones. */
814 if (buff[1] == '\0' && isalpha((unsigned char)*buff)) {
815 for (tp = MilitaryTable; tp->name; tp++)
816 if (strcmp(buff, tp->name) == 0) {
817 yylval.Number = tp->value;
822 /* Drop out any periods and try the timezone table again. */
823 for (i = 0, p = q = buff; *q; q++)
830 for (tp = TimezoneTable; tp->name; tp++)
831 if (strcmp(buff, tp->name) == 0) {
832 yylval.Number = tp->value;
850 while (isspace((unsigned char)*yyInput))
853 if (isdigit((unsigned char)(c = *yyInput)) || c == '-' || c == '+') {
854 if (c == '-' || c == '+') {
855 sign = c == '-' ? -1 : 1;
856 if (!isdigit((unsigned char)*++yyInput))
857 /* skip the '-' sign */
862 for (yylval.Number = 0; isdigit((unsigned char)(c = *yyInput++)); )
863 yylval.Number = 10 * yylval.Number + c - '0';
866 yylval.Number = -yylval.Number;
867 return sign ? tSNUMBER : tUNUMBER;
869 if (isalpha((unsigned char)c)) {
870 for (p = buff; isalpha((unsigned char)(c = *yyInput++)) || c == '.'; )
871 if (p < &buff[sizeof buff - 1])
875 return LookupWord(buff);
892 #define TM_YEAR_ORIGIN 1900
894 /* Yield A - B, measured in seconds. */
899 int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
900 int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
902 /* difference in day of year */
903 a->tm_yday - b->tm_yday
904 /* + intervening leap days */
905 + ((ay >> 2) - (by >> 2))
907 + ((ay/100 >> 2) - (by/100 >> 2))
908 /* + difference in years * 365 */
909 + (long)(ay-by) * 365
911 return (60*(60*(24*days + (a->tm_hour - b->tm_hour))
912 + (a->tm_min - b->tm_min))
913 + (a->tm_sec - b->tm_sec));
920 struct tm *tm, *gmt, gmtbuf;
932 /* Make a copy, in case localtime modifies *tm (I think
933 that comment now applies to *gmt, but I am too
934 lazy to dig into how gmtime and locatime allocate the
935 structures they return pointers to). */
940 if (! (tm = localtime (&now)))
944 timezone = difftm (gmt, tm) / 60;
946 /* We are on a system like VMS, where the system clock is
947 in local time and the system has no concept of timezones.
948 Hopefully we can fake this out (for the case in which the
949 user specifies no timezone) by just saying the timezone
956 tm = localtime(&now);
957 yyYear = tm->tm_year + 1900;
958 yyMonth = tm->tm_mon + 1;
960 yyTimezone = timezone;
961 yyDSTmode = DSTmaybe;
975 || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
978 if (yyHaveDate || yyHaveTime || yyHaveDay) {
979 Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
980 yyMeridian, yyDSTmode);
987 Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec;
990 Start += yyRelSeconds;
991 Start += RelativeMonth(Start, yyRelMonth);
993 if (yyHaveDay && !yyHaveDate) {
994 tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
998 /* Have to do *something* with a legitimate -1 so it's distinguishable
999 * from the error return value. (Alternately could set errno on error.) */
1000 return Start == -1 ? 0 : Start;
1015 (void)printf("Enter date, or blank line to exit.\n\t> ");
1016 (void)fflush(stdout);
1017 while (gets(buff) && buff[0]) {
1020 (void)printf("Bad format - couldn't convert.\n");
1022 (void)printf("%s", ctime(&d));
1023 (void)printf("\t> ");
1024 (void)fflush(stdout);
1029 #endif /* defined(TEST) */
1031 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
1032 #if defined(__cplusplus) || defined(__STDC__)
1033 static int yygrowstack(void)
1035 static int yygrowstack()
1042 if ((newsize = yystacksize) == 0)
1043 newsize = YYINITSTACKSIZE;
1044 else if (newsize >= YYMAXDEPTH)
1046 else if ((newsize *= 2) > YYMAXDEPTH)
1047 newsize = YYMAXDEPTH;
1050 #define YY_SIZE_MAX SIZE_MAX
1052 #define YY_SIZE_MAX 0x7fffffff
1054 if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
1056 newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
1057 (short *)malloc(newsize * sizeof *newss); /* overflow check above */
1062 if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
1064 newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
1065 (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
1070 yystacksize = newsize;
1071 yysslim = yyss + newsize - 1;
1078 yyss = yyssp = NULL;
1079 yyvs = yyvsp = NULL;
1084 #define YYABORT goto yyabort
1085 #define YYREJECT goto yyabort
1086 #define YYACCEPT goto yyaccept
1087 #define YYERROR goto yyerrlab
1089 #if defined(__cplusplus) || defined(__STDC__)
1095 int yym, yyn, yystate;
1097 #if defined(__cplusplus) || defined(__STDC__)
1099 #else /* !(defined(__cplusplus) || defined(__STDC__)) */
1101 #endif /* !(defined(__cplusplus) || defined(__STDC__)) */
1103 if ((yys = getenv("YYDEBUG")))
1106 if (yyn >= '0' && yyn <= '9')
1107 yydebug = yyn - '0';
1109 #endif /* YYDEBUG */
1115 if (yyss == NULL && yygrowstack()) goto yyoverflow;
1118 *yyssp = yystate = 0;
1121 if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1124 if ((yychar = yylex()) < 0) yychar = 0;
1129 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1130 if (!yys) yys = "illegal-symbol";
1131 printf("%sdebug: state %d, reading %d (%s)\n",
1132 YYPREFIX, yystate, yychar, yys);
1136 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1137 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1141 printf("%sdebug: state %d, shifting to state %d\n",
1142 YYPREFIX, yystate, yytable[yyn]);
1144 if (yyssp >= yysslim && yygrowstack())
1148 *++yyssp = yystate = yytable[yyn];
1151 if (yyerrflag > 0) --yyerrflag;
1154 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1155 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1160 if (yyerrflag) goto yyinrecovery;
1161 #if defined(lint) || defined(__GNUC__)
1165 yyerror("syntax error");
1166 #if defined(lint) || defined(__GNUC__)
1177 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1178 yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1182 printf("%sdebug: state %d, error recovery shifting\
1183 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1185 if (yyssp >= yysslim && yygrowstack())
1189 *++yyssp = yystate = yytable[yyn];
1197 printf("%sdebug: error recovery discarding state %d\n",
1200 if (yyssp <= yyss) goto yyabort;
1208 if (yychar == 0) goto yyabort;
1213 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1214 if (!yys) yys = "illegal-symbol";
1215 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1216 YYPREFIX, yystate, yychar, yys);
1225 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1226 YYPREFIX, yystate, yyn, yyrule[yyn]);
1230 yyval = yyvsp[1-yym];
1232 memset(&yyval, 0, sizeof yyval);
1236 #line 125 "getdate.y"
1242 #line 128 "getdate.y"
1248 #line 131 "getdate.y"
1254 #line 134 "getdate.y"
1260 #line 137 "getdate.y"
1266 #line 143 "getdate.y"
1268 yyHour = yyvsp[-1].Number;
1271 yyMeridian = yyvsp[0].Meridian;
1275 #line 149 "getdate.y"
1277 yyHour = yyvsp[-3].Number;
1278 yyMinutes = yyvsp[-1].Number;
1280 yyMeridian = yyvsp[0].Meridian;
1284 #line 155 "getdate.y"
1286 yyHour = yyvsp[-3].Number;
1287 yyMinutes = yyvsp[-1].Number;
1290 yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
1294 #line 162 "getdate.y"
1296 yyHour = yyvsp[-5].Number;
1297 yyMinutes = yyvsp[-3].Number;
1298 yySeconds = yyvsp[-1].Number;
1299 yyMeridian = yyvsp[0].Meridian;
1303 #line 168 "getdate.y"
1305 yyHour = yyvsp[-5].Number;
1306 yyMinutes = yyvsp[-3].Number;
1307 yySeconds = yyvsp[-1].Number;
1310 yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
1314 #line 178 "getdate.y"
1316 yyTimezone = yyvsp[0].Number;
1321 #line 182 "getdate.y"
1323 yyTimezone = yyvsp[0].Number;
1328 #line 187 "getdate.y"
1330 yyTimezone = yyvsp[-1].Number;
1335 #line 193 "getdate.y"
1338 yyDayNumber = yyvsp[0].Number;
1342 #line 197 "getdate.y"
1345 yyDayNumber = yyvsp[-1].Number;
1349 #line 201 "getdate.y"
1351 yyDayOrdinal = yyvsp[-1].Number;
1352 yyDayNumber = yyvsp[0].Number;
1356 #line 207 "getdate.y"
1358 yyMonth = yyvsp[-2].Number;
1359 yyDay = yyvsp[0].Number;
1363 #line 211 "getdate.y"
1365 if (yyvsp[-4].Number >= 100) {
1366 yyYear = yyvsp[-4].Number;
1367 yyMonth = yyvsp[-2].Number;
1368 yyDay = yyvsp[0].Number;
1370 yyMonth = yyvsp[-4].Number;
1371 yyDay = yyvsp[-2].Number;
1372 yyYear = yyvsp[0].Number;
1377 #line 222 "getdate.y"
1379 /* ISO 8601 format. yyyy-mm-dd. */
1380 yyYear = yyvsp[-2].Number;
1381 yyMonth = -yyvsp[-1].Number;
1382 yyDay = -yyvsp[0].Number;
1386 #line 228 "getdate.y"
1388 /* e.g. 17-JUN-1992. */
1389 yyDay = yyvsp[-2].Number;
1390 yyMonth = yyvsp[-1].Number;
1391 yyYear = -yyvsp[0].Number;
1395 #line 234 "getdate.y"
1397 yyMonth = yyvsp[-1].Number;
1398 yyDay = yyvsp[0].Number;
1402 #line 238 "getdate.y"
1404 yyMonth = yyvsp[-3].Number;
1405 yyDay = yyvsp[-2].Number;
1406 yyYear = yyvsp[0].Number;
1410 #line 243 "getdate.y"
1412 yyMonth = yyvsp[0].Number;
1413 yyDay = yyvsp[-1].Number;
1417 #line 247 "getdate.y"
1419 yyMonth = yyvsp[-1].Number;
1420 yyDay = yyvsp[-2].Number;
1421 yyYear = yyvsp[0].Number;
1425 #line 254 "getdate.y"
1427 yyRelSeconds = -yyRelSeconds;
1428 yyRelMonth = -yyRelMonth;
1432 #line 261 "getdate.y"
1434 yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
1438 #line 264 "getdate.y"
1440 yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
1444 #line 267 "getdate.y"
1446 yyRelSeconds += yyvsp[0].Number * 60L;
1450 #line 270 "getdate.y"
1452 yyRelSeconds += yyvsp[-1].Number;
1456 #line 273 "getdate.y"
1458 yyRelSeconds += yyvsp[-1].Number;
1462 #line 276 "getdate.y"
1468 #line 279 "getdate.y"
1470 yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1474 #line 282 "getdate.y"
1476 yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1480 #line 285 "getdate.y"
1482 yyRelMonth += yyvsp[0].Number;
1486 #line 290 "getdate.y"
1488 if (yyHaveTime && yyHaveDate && !yyHaveRel)
1489 yyYear = yyvsp[0].Number;
1491 if(yyvsp[0].Number>10000) {
1493 yyDay= (yyvsp[0].Number)%100;
1494 yyMonth= (yyvsp[0].Number/100)%100;
1495 yyYear = yyvsp[0].Number/10000;
1499 if (yyvsp[0].Number < 100) {
1500 yyHour = yyvsp[0].Number;
1504 yyHour = yyvsp[0].Number / 100;
1505 yyMinutes = yyvsp[0].Number % 100;
1514 #line 317 "getdate.y"
1516 yyval.Meridian = MER24;
1520 #line 320 "getdate.y"
1522 yyval.Meridian = yyvsp[0].Meridian;
1525 #line 1474 "y.tab.c"
1531 if (yystate == 0 && yym == 0)
1535 printf("%sdebug: after reduction, shifting from state 0 to\
1536 state %d\n", YYPREFIX, YYFINAL);
1543 if ((yychar = yylex()) < 0) yychar = 0;
1548 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1549 if (!yys) yys = "illegal-symbol";
1550 printf("%sdebug: state %d, reading %d (%s)\n",
1551 YYPREFIX, YYFINAL, yychar, yys);
1555 if (yychar == 0) goto yyaccept;
1558 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1559 yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1560 yystate = yytable[yyn];
1562 yystate = yydgoto[yym];
1565 printf("%sdebug: after reduction, shifting from state %d \
1566 to state %d\n", YYPREFIX, *yyssp, yystate);
1568 if (yyssp >= yysslim && yygrowstack())
1576 yyerror("yacc stack overflow");
1582 yyss = yyssp = NULL;
1583 yyvs = yyvsp = NULL;
1591 yyss = yyssp = NULL;
1592 yyvs = yyvsp = NULL;