9 #define yyclearin (yychar=(YYEMPTY))
10 #define yyerrok (yyerrflag=0)
11 #define YYRECOVERING() (yyerrflag!=0)
15 ** Originally written by Steven M. Bellovin <smb@research.att.com> while
16 ** at the University of North Carolina at Chapel Hill. Later tweaked by
17 ** a couple of people on Usenet. Completely overhauled by Rich $alz
18 ** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
20 ** This grammar has 10 shift/reduce conflicts.
22 ** This code is in the public domain and has no copyright.
24 /* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
25 /* SUPPRESS 288 on yyerrlab *//* Label unused */
29 #include <sys/types.h>
39 #endif /* STDC_HEADERS */
41 # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
45 #endif /* HAVE_STRING_H */
48 #endif /* HAVE_STRINGS_H */
49 #if TIME_WITH_SYS_TIME
58 #define HOUR(x) ((time_t)(x) * 60)
59 #define SECSPERDAY (24L * 60L * 60L)
63 ** An entry in the lexical lookup table.
65 typedef struct _TABLE {
73 ** Daylight-savings mode: on, off, or not yet known.
75 typedef enum _DSTMODE {
76 DSTon, DSToff, DSTmaybe
80 ** Meridian: am, pm, or 24-hour style.
82 typedef enum _MERIDIAN {
88 ** Global variables. We could get rid of most of these by using a good
89 ** union as the yacc stack. (This routine was originally written before
90 ** yacc had the %union construct.) Maybe someday; right now we only use
91 ** the %union very rarely.
94 static DSTMODE yyDSTmode;
95 static time_t yyDayOrdinal;
96 static time_t yyDayNumber;
97 static int yyHaveDate;
100 static int yyHaveTime;
101 static int yyHaveZone;
102 static time_t yyTimezone;
104 static time_t yyHour;
105 static time_t yyMinutes;
106 static time_t yyMonth;
107 static time_t yySeconds;
108 static time_t yyYear;
109 static MERIDIAN yyMeridian;
110 static time_t yyRelMonth;
111 static time_t yyRelSeconds;
113 static int yyerror __P((char *s));
114 static int yylex __P((void));
115 static int yyparse __P((void));
117 #line 107 "getdate.y"
118 #ifndef YYSTYPE_DEFINED
119 #define YYSTYPE_DEFINED
122 enum _MERIDIAN Meridian;
124 #endif /* YYSTYPE_DEFINED */
130 #define tMERIDIAN 261
131 #define tMINUTE_UNIT 262
133 #define tMONTH_UNIT 264
134 #define tSEC_UNIT 265
139 #define YYERRCODE 256
140 #if defined(__cplusplus) || defined(__STDC__)
141 const short yylhs[] =
146 0, 0, 2, 2, 2, 2, 2, 2, 3, 3,
147 3, 3, 3, 4, 4, 4, 6, 6, 6, 5,
148 5, 5, 5, 5, 5, 5, 5, 7, 7, 9,
149 9, 9, 9, 9, 9, 9, 9, 9, 8, 1,
152 #if defined(__cplusplus) || defined(__STDC__)
153 const short yylen[] =
158 0, 2, 1, 1, 1, 1, 1, 1, 2, 4,
159 4, 6, 6, 1, 1, 2, 1, 2, 2, 3,
160 5, 3, 3, 2, 4, 2, 3, 2, 1, 2,
161 2, 1, 2, 2, 1, 2, 2, 1, 1, 0,
164 #if defined(__cplusplus) || defined(__STDC__)
165 const short yydefred[] =
170 0, 0, 15, 32, 0, 38, 35, 0, 0, 0,
171 2, 3, 4, 5, 6, 7, 8, 0, 18, 0,
172 31, 36, 33, 19, 9, 30, 0, 37, 34, 0,
173 0, 0, 16, 28, 0, 23, 27, 22, 0, 0,
174 25, 41, 11, 0, 10, 0, 0, 21, 13, 12,
176 #if defined(__cplusplus) || defined(__STDC__)
177 const short yydgoto[] =
182 45, 11, 12, 13, 14, 15, 16, 17, 18,
184 #if defined(__cplusplus) || defined(__STDC__)
185 const short yysindex[] =
190 -249, -38, 0, 0, -260, 0, 0, -240, -47, -248,
191 0, 0, 0, 0, 0, 0, 0, -237, 0, -18,
192 0, 0, 0, 0, 0, 0, -262, 0, 0, -239,
193 -238, -236, 0, 0, -235, 0, 0, 0, -56, -19,
194 0, 0, 0, -234, 0, -232, -258, 0, 0, 0,};
195 #if defined(__cplusplus) || defined(__STDC__)
196 const short yyrindex[] =
201 0, 1, 0, 0, 0, 0, 0, 0, 69, 12,
202 0, 0, 0, 0, 0, 0, 0, 23, 0, 34,
203 0, 0, 0, 0, 0, 0, 67, 0, 0, 0,
204 0, 0, 0, 0, 0, 0, 0, 0, 56, 45,
205 0, 0, 0, 0, 0, 0, 56, 0, 0, 0,};
206 #if defined(__cplusplus) || defined(__STDC__)
207 const short yygindex[] =
212 -17, 0, 0, 0, 0, 0, 0, 0, 0,
214 #define YYTABLESIZE 337
215 #if defined(__cplusplus) || defined(__STDC__)
216 const short yytable[] =
221 17, 44, 42, 36, 37, 19, 20, 49, 2, 3,
222 31, 14, 4, 5, 6, 7, 8, 9, 10, 34,
223 33, 21, 29, 22, 23, 35, 38, 46, 39, 50,
224 40, 41, 47, 24, 48, 0, 0, 0, 0, 0,
225 0, 0, 0, 0, 20, 0, 0, 0, 0, 0,
226 0, 0, 0, 0, 0, 40, 0, 0, 0, 0,
227 0, 0, 0, 0, 0, 0, 26, 0, 39, 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, 0, 0, 0, 0, 0, 0,
241 0, 0, 0, 0, 42, 0, 0, 0, 0, 43,
242 24, 0, 0, 25, 26, 27, 28, 29, 30, 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, 0, 0,
246 0, 0, 0, 0, 0, 0, 0, 0, 17, 17,
247 0, 0, 17, 17, 17, 17, 17, 17, 17, 14,
248 14, 0, 0, 14, 14, 14, 14, 14, 14, 14,
249 29, 29, 0, 0, 29, 29, 29, 29, 29, 29,
250 29, 24, 24, 0, 0, 24, 24, 24, 24, 24,
251 24, 24, 20, 20, 0, 0, 20, 20, 20, 20,
252 20, 20, 20, 40, 40, 0, 0, 40, 40, 40,
253 40, 0, 40, 40, 26, 26, 0, 39, 26, 26,
254 26, 26, 0, 0, 26, 39, 39,
256 #if defined(__cplusplus) || defined(__STDC__)
257 const short yycheck[] =
262 0, 58, 261, 266, 267, 44, 267, 266, 258, 259,
263 58, 0, 262, 263, 264, 265, 266, 267, 268, 257,
264 269, 262, 0, 264, 265, 44, 266, 47, 267, 47,
265 267, 267, 267, 0, 267, -1, -1, -1, -1, -1,
266 -1, -1, -1, -1, 0, -1, -1, -1, -1, -1,
267 -1, -1, -1, -1, -1, 0, -1, -1, -1, -1,
268 -1, -1, -1, -1, -1, -1, 0, -1, 0, -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, -1, -1, -1, -1, -1, -1,
282 -1, -1, -1, -1, 261, -1, -1, -1, -1, 266,
283 258, -1, -1, 261, 262, 263, 264, 265, 266, -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, -1, -1,
287 -1, -1, -1, -1, -1, -1, -1, -1, 258, 259,
288 -1, -1, 262, 263, 264, 265, 266, 267, 268, 258,
289 259, -1, -1, 262, 263, 264, 265, 266, 267, 268,
290 258, 259, -1, -1, 262, 263, 264, 265, 266, 267,
291 268, 258, 259, -1, -1, 262, 263, 264, 265, 266,
292 267, 268, 258, 259, -1, -1, 262, 263, 264, 265,
293 266, 267, 268, 258, 259, -1, -1, 262, 263, 264,
294 265, -1, 267, 268, 258, 259, -1, 259, 262, 263,
295 264, 265, -1, -1, 268, 267, 268,
301 #define YYMAXTOKEN 269
303 #if defined(__cplusplus) || defined(__STDC__)
304 const char * const yyname[] =
309 "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,
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,
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,0,0,0,0,0,0,0,0,0,0,0,
315 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",
316 "tDAYZONE","tID","tMERIDIAN","tMINUTE_UNIT","tMONTH","tMONTH_UNIT","tSEC_UNIT",
317 "tSNUMBER","tUNUMBER","tZONE","tDST",
319 #if defined(__cplusplus) || defined(__STDC__)
320 const char * const yyrule[] =
333 "time : tUNUMBER tMERIDIAN",
334 "time : tUNUMBER ':' tUNUMBER o_merid",
335 "time : tUNUMBER ':' tUNUMBER tSNUMBER",
336 "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid",
337 "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER",
343 "day : tUNUMBER tDAY",
344 "date : tUNUMBER '/' tUNUMBER",
345 "date : tUNUMBER '/' tUNUMBER '/' tUNUMBER",
346 "date : tUNUMBER tSNUMBER tSNUMBER",
347 "date : tUNUMBER tMONTH tSNUMBER",
348 "date : tMONTH tUNUMBER",
349 "date : tMONTH tUNUMBER ',' tUNUMBER",
350 "date : tUNUMBER tMONTH",
351 "date : tUNUMBER tMONTH tUNUMBER",
352 "rel : relunit tAGO",
354 "relunit : tUNUMBER tMINUTE_UNIT",
355 "relunit : tSNUMBER tMINUTE_UNIT",
356 "relunit : tMINUTE_UNIT",
357 "relunit : tSNUMBER tSEC_UNIT",
358 "relunit : tUNUMBER tSEC_UNIT",
359 "relunit : tSEC_UNIT",
360 "relunit : tSNUMBER tMONTH_UNIT",
361 "relunit : tUNUMBER tMONTH_UNIT",
362 "relunit : tMONTH_UNIT",
365 "o_merid : tMERIDIAN",
370 #define YYMAXDEPTH YYSTACKSIZE
373 #define YYSTACKSIZE YYMAXDEPTH
375 #define YYSTACKSIZE 10000
376 #define YYMAXDEPTH 10000
379 #define YYINITSTACKSIZE 200
393 #line 326 "getdate.y"
395 /* Month and day table. */
396 static TABLE const MonthDayTable[] = {
397 { "january", tMONTH, 1 },
398 { "february", tMONTH, 2 },
399 { "march", tMONTH, 3 },
400 { "april", tMONTH, 4 },
401 { "may", tMONTH, 5 },
402 { "june", tMONTH, 6 },
403 { "july", tMONTH, 7 },
404 { "august", tMONTH, 8 },
405 { "september", tMONTH, 9 },
406 { "sept", tMONTH, 9 },
407 { "october", tMONTH, 10 },
408 { "november", tMONTH, 11 },
409 { "december", tMONTH, 12 },
410 { "sunday", tDAY, 0 },
411 { "monday", tDAY, 1 },
412 { "tuesday", tDAY, 2 },
414 { "wednesday", tDAY, 3 },
415 { "wednes", tDAY, 3 },
416 { "thursday", tDAY, 4 },
418 { "thurs", tDAY, 4 },
419 { "friday", tDAY, 5 },
420 { "saturday", tDAY, 6 },
424 /* Time units table. */
425 static TABLE const UnitsTable[] = {
426 { "year", tMONTH_UNIT, 12 },
427 { "month", tMONTH_UNIT, 1 },
428 { "fortnight", tMINUTE_UNIT, 14 * 24 * 60 },
429 { "week", tMINUTE_UNIT, 7 * 24 * 60 },
430 { "day", tMINUTE_UNIT, 1 * 24 * 60 },
431 { "hour", tMINUTE_UNIT, 60 },
432 { "minute", tMINUTE_UNIT, 1 },
433 { "min", tMINUTE_UNIT, 1 },
434 { "second", tSEC_UNIT, 1 },
435 { "sec", tSEC_UNIT, 1 },
439 /* Assorted relative-time words. */
440 static TABLE const OtherTable[] = {
441 { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 },
442 { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 },
443 { "today", tMINUTE_UNIT, 0 },
444 { "now", tMINUTE_UNIT, 0 },
445 { "last", tUNUMBER, -1 },
446 { "this", tMINUTE_UNIT, 0 },
447 { "next", tUNUMBER, 2 },
448 { "first", tUNUMBER, 1 },
449 /* { "second", tUNUMBER, 2 }, */
450 { "third", tUNUMBER, 3 },
451 { "fourth", tUNUMBER, 4 },
452 { "fifth", tUNUMBER, 5 },
453 { "sixth", tUNUMBER, 6 },
454 { "seventh", tUNUMBER, 7 },
455 { "eighth", tUNUMBER, 8 },
456 { "ninth", tUNUMBER, 9 },
457 { "tenth", tUNUMBER, 10 },
458 { "eleventh", tUNUMBER, 11 },
459 { "twelfth", tUNUMBER, 12 },
464 /* The timezone table. */
465 /* Some of these are commented out because a time_t can't store a float. */
466 static TABLE const TimezoneTable[] = {
467 { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */
468 { "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */
469 { "utc", tZONE, HOUR( 0) },
470 { "wet", tZONE, HOUR( 0) }, /* Western European */
471 { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */
472 { "wat", tZONE, HOUR( 1) }, /* West Africa */
473 { "at", tZONE, HOUR( 2) }, /* Azores */
475 /* For completeness. BST is also British Summer, and GST is
476 * also Guam Standard. */
477 { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */
478 { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */
481 { "nft", tZONE, HOUR(3.5) }, /* Newfoundland */
482 { "nst", tZONE, HOUR(3.5) }, /* Newfoundland Standard */
483 { "ndt", tDAYZONE, HOUR(3.5) }, /* Newfoundland Daylight */
485 { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */
486 { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */
487 { "est", tZONE, HOUR( 5) }, /* Eastern Standard */
488 { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */
489 { "cst", tZONE, HOUR( 6) }, /* Central Standard */
490 { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */
491 { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */
492 { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */
493 { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */
494 { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */
495 { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */
496 { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */
497 { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */
498 { "hdt", tDAYZONE, HOUR(10) }, /* Hawaii Daylight */
499 { "cat", tZONE, HOUR(10) }, /* Central Alaska */
500 { "ahst", tZONE, HOUR(10) }, /* Alaska-Hawaii Standard */
501 { "nt", tZONE, HOUR(11) }, /* Nome */
502 { "idlw", tZONE, HOUR(12) }, /* International Date Line West */
503 { "cet", tZONE, -HOUR(1) }, /* Central European */
504 { "met", tZONE, -HOUR(1) }, /* Middle European */
505 { "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */
506 { "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */
507 { "swt", tZONE, -HOUR(1) }, /* Swedish Winter */
508 { "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */
509 { "fwt", tZONE, -HOUR(1) }, /* French Winter */
510 { "fst", tDAYZONE, -HOUR(1) }, /* French Summer */
511 { "eet", tZONE, -HOUR(2) }, /* Eastern Europe, USSR Zone 1 */
512 { "bt", tZONE, -HOUR(3) }, /* Baghdad, USSR Zone 2 */
514 { "it", tZONE, -HOUR(3.5) },/* Iran */
516 { "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */
517 { "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */
519 { "ist", tZONE, -HOUR(5.5) },/* Indian Standard */
521 { "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */
523 /* For completeness. NST is also Newfoundland Stanard, and SST is
524 * also Swedish Summer. */
525 { "nst", tZONE, -HOUR(6.5) },/* North Sumatra */
526 { "sst", tZONE, -HOUR(7) }, /* South Sumatra, USSR Zone 6 */
528 { "wast", tZONE, -HOUR(7) }, /* West Australian Standard */
529 { "wadt", tDAYZONE, -HOUR(7) }, /* West Australian Daylight */
531 { "jt", tZONE, -HOUR(7.5) },/* Java (3pm in Cronusland!) */
533 { "cct", tZONE, -HOUR(8) }, /* China Coast, USSR Zone 7 */
534 { "jst", tZONE, -HOUR(9) }, /* Japan Standard, USSR Zone 8 */
536 { "cast", tZONE, -HOUR(9.5) },/* Central Australian Standard */
537 { "cadt", tDAYZONE, -HOUR(9.5) },/* Central Australian Daylight */
539 { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */
540 { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */
541 { "gst", tZONE, -HOUR(10) }, /* Guam Standard, USSR Zone 9 */
542 { "nzt", tZONE, -HOUR(12) }, /* New Zealand */
543 { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */
544 { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */
545 { "idle", tZONE, -HOUR(12) }, /* International Date Line East */
549 /* Military timezone table. */
550 static TABLE const MilitaryTable[] = {
551 { "a", tZONE, HOUR( 1) },
552 { "b", tZONE, HOUR( 2) },
553 { "c", tZONE, HOUR( 3) },
554 { "d", tZONE, HOUR( 4) },
555 { "e", tZONE, HOUR( 5) },
556 { "f", tZONE, HOUR( 6) },
557 { "g", tZONE, HOUR( 7) },
558 { "h", tZONE, HOUR( 8) },
559 { "i", tZONE, HOUR( 9) },
560 { "k", tZONE, HOUR( 10) },
561 { "l", tZONE, HOUR( 11) },
562 { "m", tZONE, HOUR( 12) },
563 { "n", tZONE, HOUR(- 1) },
564 { "o", tZONE, HOUR(- 2) },
565 { "p", tZONE, HOUR(- 3) },
566 { "q", tZONE, HOUR(- 4) },
567 { "r", tZONE, HOUR(- 5) },
568 { "s", tZONE, HOUR(- 6) },
569 { "t", tZONE, HOUR(- 7) },
570 { "u", tZONE, HOUR(- 8) },
571 { "v", tZONE, HOUR(- 9) },
572 { "w", tZONE, HOUR(-10) },
573 { "x", tZONE, HOUR(-11) },
574 { "y", tZONE, HOUR(-12) },
575 { "z", tZONE, HOUR( 0) },
592 ToSeconds(Hours, Minutes, Seconds, Meridian)
598 if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
602 if (Hours < 0 || Hours > 23)
604 return (Hours * 60L + Minutes) * 60L + Seconds;
606 if (Hours < 1 || Hours > 12)
610 return (Hours * 60L + Minutes) * 60L + Seconds;
612 if (Hours < 1 || Hours > 12)
616 return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
625 * A negative number, which means to use its absolute value (why?)
626 * A number from 0 to 99, which means a year from 1900 to 1999, or
627 * The actual year (>=100). */
629 Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
639 static int DaysInMonth[12] = {
640 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
650 else if (Year < 100) {
655 DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
657 /* Checking for 2038 bogusly assumes that time_t is 32 bits. But
658 I'm too lazy to try to check for time_t overflow in another way. */
659 if (Year < EPOCH || Year > 2038
660 || Month < 1 || Month > 12
661 /* Lint fluff: "conversion from long may lose accuracy" */
662 || Day < 1 || Day > DaysInMonth[(int)--Month])
665 for (Julian = Day - 1, i = 0; i < Month; i++)
666 Julian += DaysInMonth[i];
667 for (i = EPOCH; i < Year; i++)
668 Julian += 365 + (i % 4 == 0);
669 Julian *= SECSPERDAY;
670 Julian += yyTimezone * 60L;
671 if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
675 || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
682 DSTcorrect(Start, Future)
689 StartDay = (localtime(&Start)->tm_hour + 1) % 24;
690 FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
691 return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
696 RelativeDate(Start, DayOrdinal, DayNumber)
705 tm = localtime(&now);
706 now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
707 now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
708 return DSTcorrect(Start, now);
713 RelativeMonth(Start, RelMonth)
723 tm = localtime(&Start);
724 Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
726 Month = Month % 12 + 1;
727 return DSTcorrect(Start,
728 Convert(Month, (time_t)tm->tm_mday, Year,
729 (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
744 /* Make it lowercase. */
745 for (p = buff; *p; p++)
746 if (isupper((unsigned char)*p))
747 *p = tolower((unsigned char)*p);
749 if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
750 yylval.Meridian = MERam;
753 if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
754 yylval.Meridian = MERpm;
758 /* See if we have an abbreviation for a month. */
759 if (strlen(buff) == 3)
761 else if (strlen(buff) == 4 && buff[3] == '.') {
768 for (tp = MonthDayTable; tp->name; tp++) {
770 if (strncmp(buff, tp->name, 3) == 0) {
771 yylval.Number = tp->value;
775 else if (strcmp(buff, tp->name) == 0) {
776 yylval.Number = tp->value;
781 for (tp = TimezoneTable; tp->name; tp++)
782 if (strcmp(buff, tp->name) == 0) {
783 yylval.Number = tp->value;
787 if (strcmp(buff, "dst") == 0)
790 for (tp = UnitsTable; tp->name; tp++)
791 if (strcmp(buff, tp->name) == 0) {
792 yylval.Number = tp->value;
796 /* Strip off any plural and try the units table again. */
797 i = strlen(buff) - 1;
798 if (buff[i] == 's') {
800 for (tp = UnitsTable; tp->name; tp++)
801 if (strcmp(buff, tp->name) == 0) {
802 yylval.Number = tp->value;
805 buff[i] = 's'; /* Put back for "this" in OtherTable. */
808 for (tp = OtherTable; tp->name; tp++)
809 if (strcmp(buff, tp->name) == 0) {
810 yylval.Number = tp->value;
814 /* Military timezones. */
815 if (buff[1] == '\0' && isalpha((unsigned char)*buff)) {
816 for (tp = MilitaryTable; tp->name; tp++)
817 if (strcmp(buff, tp->name) == 0) {
818 yylval.Number = tp->value;
823 /* Drop out any periods and try the timezone table again. */
824 for (i = 0, p = q = buff; *q; q++)
831 for (tp = TimezoneTable; tp->name; tp++)
832 if (strcmp(buff, tp->name) == 0) {
833 yylval.Number = tp->value;
851 while (isspace((unsigned char)*yyInput))
854 if (isdigit((unsigned char)(c = *yyInput)) || c == '-' || c == '+') {
855 if (c == '-' || c == '+') {
856 sign = c == '-' ? -1 : 1;
857 if (!isdigit((unsigned char)*++yyInput))
858 /* skip the '-' sign */
863 for (yylval.Number = 0; isdigit((unsigned char)(c = *yyInput++)); )
864 yylval.Number = 10 * yylval.Number + c - '0';
867 yylval.Number = -yylval.Number;
868 return sign ? tSNUMBER : tUNUMBER;
870 if (isalpha((unsigned char)c)) {
871 for (p = buff; isalpha((unsigned char)(c = *yyInput++)) || c == '.'; )
872 if (p < &buff[sizeof buff - 1])
876 return LookupWord(buff);
893 #define TM_YEAR_ORIGIN 1900
895 /* Yield A - B, measured in seconds. */
900 int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
901 int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
903 /* difference in day of year */
904 a->tm_yday - b->tm_yday
905 /* + intervening leap days */
906 + ((ay >> 2) - (by >> 2))
908 + ((ay/100 >> 2) - (by/100 >> 2))
909 /* + difference in years * 365 */
910 + (long)(ay-by) * 365
912 return (60*(60*(24*days + (a->tm_hour - b->tm_hour))
913 + (a->tm_min - b->tm_min))
914 + (a->tm_sec - b->tm_sec));
921 struct tm *tm, *gmt, gmtbuf;
933 /* Make a copy, in case localtime modifies *tm (I think
934 that comment now applies to *gmt, but I am too
935 lazy to dig into how gmtime and locatime allocate the
936 structures they return pointers to). */
941 if (! (tm = localtime (&now)))
945 timezone = difftm (gmt, tm) / 60;
947 /* We are on a system like VMS, where the system clock is
948 in local time and the system has no concept of timezones.
949 Hopefully we can fake this out (for the case in which the
950 user specifies no timezone) by just saying the timezone
957 tm = localtime(&now);
958 yyYear = tm->tm_year + 1900;
959 yyMonth = tm->tm_mon + 1;
961 yyTimezone = timezone;
962 yyDSTmode = DSTmaybe;
976 || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
979 if (yyHaveDate || yyHaveTime || yyHaveDay) {
980 Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
981 yyMeridian, yyDSTmode);
988 Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec;
991 Start += yyRelSeconds;
992 Start += RelativeMonth(Start, yyRelMonth);
994 if (yyHaveDay && !yyHaveDate) {
995 tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
999 /* Have to do *something* with a legitimate -1 so it's distinguishable
1000 * from the error return value. (Alternately could set errno on error.) */
1001 return Start == -1 ? 0 : Start;
1016 (void)printf("Enter date, or blank line to exit.\n\t> ");
1017 (void)fflush(stdout);
1018 while (gets(buff) && buff[0]) {
1021 (void)printf("Bad format - couldn't convert.\n");
1023 (void)printf("%s", ctime(&d));
1024 (void)printf("\t> ");
1025 (void)fflush(stdout);
1030 #endif /* defined(TEST) */
1032 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
1033 #if defined(__cplusplus) || defined(__STDC__)
1034 static int yygrowstack(void)
1036 static int yygrowstack()
1043 if ((newsize = yystacksize) == 0)
1044 newsize = YYINITSTACKSIZE;
1045 else if (newsize >= YYMAXDEPTH)
1047 else if ((newsize *= 2) > YYMAXDEPTH)
1048 newsize = YYMAXDEPTH;
1051 #define YY_SIZE_MAX SIZE_MAX
1053 #define YY_SIZE_MAX 0x7fffffff
1055 if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
1057 newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
1058 (short *)malloc(newsize * sizeof *newss); /* overflow check above */
1063 if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
1065 newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
1066 (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
1071 yystacksize = newsize;
1072 yysslim = yyss + newsize - 1;
1079 yyss = yyssp = NULL;
1080 yyvs = yyvsp = NULL;
1085 #define YYABORT goto yyabort
1086 #define YYREJECT goto yyabort
1087 #define YYACCEPT goto yyaccept
1088 #define YYERROR goto yyerrlab
1090 #if defined(__cplusplus) || defined(__STDC__)
1096 int yym, yyn, yystate;
1098 #if defined(__cplusplus) || defined(__STDC__)
1100 #else /* !(defined(__cplusplus) || defined(__STDC__)) */
1102 #endif /* !(defined(__cplusplus) || defined(__STDC__)) */
1104 if ((yys = getenv("YYDEBUG")))
1107 if (yyn >= '0' && yyn <= '9')
1108 yydebug = yyn - '0';
1110 #endif /* YYDEBUG */
1116 if (yyss == NULL && yygrowstack()) goto yyoverflow;
1119 *yyssp = yystate = 0;
1122 if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1125 if ((yychar = yylex()) < 0) yychar = 0;
1130 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1131 if (!yys) yys = "illegal-symbol";
1132 printf("%sdebug: state %d, reading %d (%s)\n",
1133 YYPREFIX, yystate, yychar, yys);
1137 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1138 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1142 printf("%sdebug: state %d, shifting to state %d\n",
1143 YYPREFIX, yystate, yytable[yyn]);
1145 if (yyssp >= yysslim && yygrowstack())
1149 *++yyssp = yystate = yytable[yyn];
1152 if (yyerrflag > 0) --yyerrflag;
1155 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1156 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1161 if (yyerrflag) goto yyinrecovery;
1162 #if defined(lint) || defined(__GNUC__)
1166 yyerror("syntax error");
1167 #if defined(lint) || defined(__GNUC__)
1178 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1179 yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1183 printf("%sdebug: state %d, error recovery shifting\
1184 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1186 if (yyssp >= yysslim && yygrowstack())
1190 *++yyssp = yystate = yytable[yyn];
1198 printf("%sdebug: error recovery discarding state %d\n",
1201 if (yyssp <= yyss) goto yyabort;
1209 if (yychar == 0) goto yyabort;
1214 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1215 if (!yys) yys = "illegal-symbol";
1216 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1217 YYPREFIX, yystate, yychar, yys);
1226 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1227 YYPREFIX, yystate, yyn, yyrule[yyn]);
1231 yyval = yyvsp[1-yym];
1233 memset(&yyval, 0, sizeof yyval);
1237 #line 125 "getdate.y"
1243 #line 128 "getdate.y"
1249 #line 131 "getdate.y"
1255 #line 134 "getdate.y"
1261 #line 137 "getdate.y"
1267 #line 143 "getdate.y"
1269 yyHour = yyvsp[-1].Number;
1272 yyMeridian = yyvsp[0].Meridian;
1276 #line 149 "getdate.y"
1278 yyHour = yyvsp[-3].Number;
1279 yyMinutes = yyvsp[-1].Number;
1281 yyMeridian = yyvsp[0].Meridian;
1285 #line 155 "getdate.y"
1287 yyHour = yyvsp[-3].Number;
1288 yyMinutes = yyvsp[-1].Number;
1291 yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
1295 #line 162 "getdate.y"
1297 yyHour = yyvsp[-5].Number;
1298 yyMinutes = yyvsp[-3].Number;
1299 yySeconds = yyvsp[-1].Number;
1300 yyMeridian = yyvsp[0].Meridian;
1304 #line 168 "getdate.y"
1306 yyHour = yyvsp[-5].Number;
1307 yyMinutes = yyvsp[-3].Number;
1308 yySeconds = yyvsp[-1].Number;
1311 yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
1315 #line 178 "getdate.y"
1317 yyTimezone = yyvsp[0].Number;
1322 #line 182 "getdate.y"
1324 yyTimezone = yyvsp[0].Number;
1329 #line 187 "getdate.y"
1331 yyTimezone = yyvsp[-1].Number;
1336 #line 193 "getdate.y"
1339 yyDayNumber = yyvsp[0].Number;
1343 #line 197 "getdate.y"
1346 yyDayNumber = yyvsp[-1].Number;
1350 #line 201 "getdate.y"
1352 yyDayOrdinal = yyvsp[-1].Number;
1353 yyDayNumber = yyvsp[0].Number;
1357 #line 207 "getdate.y"
1359 yyMonth = yyvsp[-2].Number;
1360 yyDay = yyvsp[0].Number;
1364 #line 211 "getdate.y"
1366 if (yyvsp[-4].Number >= 100) {
1367 yyYear = yyvsp[-4].Number;
1368 yyMonth = yyvsp[-2].Number;
1369 yyDay = yyvsp[0].Number;
1371 yyMonth = yyvsp[-4].Number;
1372 yyDay = yyvsp[-2].Number;
1373 yyYear = yyvsp[0].Number;
1378 #line 222 "getdate.y"
1380 /* ISO 8601 format. yyyy-mm-dd. */
1381 yyYear = yyvsp[-2].Number;
1382 yyMonth = -yyvsp[-1].Number;
1383 yyDay = -yyvsp[0].Number;
1387 #line 228 "getdate.y"
1389 /* e.g. 17-JUN-1992. */
1390 yyDay = yyvsp[-2].Number;
1391 yyMonth = yyvsp[-1].Number;
1392 yyYear = -yyvsp[0].Number;
1396 #line 234 "getdate.y"
1398 yyMonth = yyvsp[-1].Number;
1399 yyDay = yyvsp[0].Number;
1403 #line 238 "getdate.y"
1405 yyMonth = yyvsp[-3].Number;
1406 yyDay = yyvsp[-2].Number;
1407 yyYear = yyvsp[0].Number;
1411 #line 243 "getdate.y"
1413 yyMonth = yyvsp[0].Number;
1414 yyDay = yyvsp[-1].Number;
1418 #line 247 "getdate.y"
1420 yyMonth = yyvsp[-1].Number;
1421 yyDay = yyvsp[-2].Number;
1422 yyYear = yyvsp[0].Number;
1426 #line 254 "getdate.y"
1428 yyRelSeconds = -yyRelSeconds;
1429 yyRelMonth = -yyRelMonth;
1433 #line 261 "getdate.y"
1435 yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
1439 #line 264 "getdate.y"
1441 yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
1445 #line 267 "getdate.y"
1447 yyRelSeconds += yyvsp[0].Number * 60L;
1451 #line 270 "getdate.y"
1453 yyRelSeconds += yyvsp[-1].Number;
1457 #line 273 "getdate.y"
1459 yyRelSeconds += yyvsp[-1].Number;
1463 #line 276 "getdate.y"
1469 #line 279 "getdate.y"
1471 yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1475 #line 282 "getdate.y"
1477 yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1481 #line 285 "getdate.y"
1483 yyRelMonth += yyvsp[0].Number;
1487 #line 290 "getdate.y"
1489 if (yyHaveTime && yyHaveDate && !yyHaveRel)
1490 yyYear = yyvsp[0].Number;
1492 if(yyvsp[0].Number>10000) {
1494 yyDay= (yyvsp[0].Number)%100;
1495 yyMonth= (yyvsp[0].Number/100)%100;
1496 yyYear = yyvsp[0].Number/10000;
1500 if (yyvsp[0].Number < 100) {
1501 yyHour = yyvsp[0].Number;
1505 yyHour = yyvsp[0].Number / 100;
1506 yyMinutes = yyvsp[0].Number % 100;
1515 #line 317 "getdate.y"
1517 yyval.Meridian = MER24;
1521 #line 320 "getdate.y"
1523 yyval.Meridian = yyvsp[0].Meridian;
1526 #line 1474 "y.tab.c"
1532 if (yystate == 0 && yym == 0)
1536 printf("%sdebug: after reduction, shifting from state 0 to\
1537 state %d\n", YYPREFIX, YYFINAL);
1544 if ((yychar = yylex()) < 0) yychar = 0;
1549 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1550 if (!yys) yys = "illegal-symbol";
1551 printf("%sdebug: state %d, reading %d (%s)\n",
1552 YYPREFIX, YYFINAL, yychar, yys);
1556 if (yychar == 0) goto yyaccept;
1559 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1560 yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1561 yystate = yytable[yyn];
1563 yystate = yydgoto[yym];
1566 printf("%sdebug: after reduction, shifting from state %d \
1567 to state %d\n", YYPREFIX, *yyssp, yystate);
1569 if (yyssp >= yysslim && yygrowstack())
1577 yyerror("yacc stack overflow");
1583 yyss = yyssp = NULL;
1584 yyvs = yyvsp = NULL;
1592 yyss = yyssp = NULL;
1593 yyvs = yyvsp = NULL;