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(char *s);
114 static int yylex(void);
117 #line 107 "getdate.y"
118 #ifndef YYSTYPE_DEFINED
119 #define YYSTYPE_DEFINED
122 enum _MERIDIAN Meridian;
124 #endif /* YYSTYPE_DEFINED */
125 #line 125 "getdate.c"
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 /* 32-bit time_t cannot represent years past 2038 */
658 if (Year < EPOCH || (sizeof(time_t) == sizeof(int) && 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) */
1030 #line 978 "getdate.c"
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 newsize = yystacksize ? yystacksize : YYINITSTACKSIZE;
1043 if (newsize >= YYMAXDEPTH)
1045 else if ((newsize *= 2) > YYMAXDEPTH)
1046 newsize = YYMAXDEPTH;
1048 #define YY_SIZE_MAX SIZE_MAX
1050 #define YY_SIZE_MAX 0x7fffffff
1052 if (YY_SIZE_MAX / newsize < sizeof *newss)
1055 newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
1056 (short *)malloc(newsize * sizeof *newss); /* overflow check above */
1061 newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
1062 (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
1067 yystacksize = newsize;
1068 yysslim = yyss + newsize - 1;
1075 yyss = yyssp = NULL;
1076 yyvs = yyvsp = NULL;
1081 #define YYABORT goto yyabort
1082 #define YYREJECT goto yyabort
1083 #define YYACCEPT goto yyaccept
1084 #define YYERROR goto yyerrlab
1086 #if defined(__cplusplus) || defined(__STDC__)
1092 int yym, yyn, yystate;
1094 #if defined(__cplusplus) || defined(__STDC__)
1096 #else /* !(defined(__cplusplus) || defined(__STDC__)) */
1098 #endif /* !(defined(__cplusplus) || defined(__STDC__)) */
1100 if ((yys = getenv("YYDEBUG")))
1103 if (yyn >= '0' && yyn <= '9')
1104 yydebug = yyn - '0';
1106 #endif /* YYDEBUG */
1112 if (yyss == NULL && yygrowstack()) goto yyoverflow;
1115 *yyssp = yystate = 0;
1118 if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1121 if ((yychar = yylex()) < 0) yychar = 0;
1126 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1127 if (!yys) yys = "illegal-symbol";
1128 printf("%sdebug: state %d, reading %d (%s)\n",
1129 YYPREFIX, yystate, yychar, yys);
1133 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1134 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1138 printf("%sdebug: state %d, shifting to state %d\n",
1139 YYPREFIX, yystate, yytable[yyn]);
1141 if (yyssp >= yysslim && yygrowstack())
1145 *++yyssp = yystate = yytable[yyn];
1148 if (yyerrflag > 0) --yyerrflag;
1151 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1152 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1157 if (yyerrflag) goto yyinrecovery;
1158 #if defined(lint) || defined(__GNUC__)
1162 yyerror("syntax error");
1163 #if defined(lint) || defined(__GNUC__)
1174 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1175 yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1179 printf("%sdebug: state %d, error recovery shifting\
1180 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1182 if (yyssp >= yysslim && yygrowstack())
1186 *++yyssp = yystate = yytable[yyn];
1194 printf("%sdebug: error recovery discarding state %d\n",
1197 if (yyssp <= yyss) goto yyabort;
1205 if (yychar == 0) goto yyabort;
1210 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1211 if (!yys) yys = "illegal-symbol";
1212 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1213 YYPREFIX, yystate, yychar, yys);
1222 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1223 YYPREFIX, yystate, yyn, yyrule[yyn]);
1227 yyval = yyvsp[1-yym];
1229 memset(&yyval, 0, sizeof yyval);
1233 #line 125 "getdate.y"
1239 #line 128 "getdate.y"
1245 #line 131 "getdate.y"
1251 #line 134 "getdate.y"
1257 #line 137 "getdate.y"
1263 #line 143 "getdate.y"
1265 yyHour = yyvsp[-1].Number;
1268 yyMeridian = yyvsp[0].Meridian;
1272 #line 149 "getdate.y"
1274 yyHour = yyvsp[-3].Number;
1275 yyMinutes = yyvsp[-1].Number;
1277 yyMeridian = yyvsp[0].Meridian;
1281 #line 155 "getdate.y"
1283 yyHour = yyvsp[-3].Number;
1284 yyMinutes = yyvsp[-1].Number;
1287 yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
1291 #line 162 "getdate.y"
1293 yyHour = yyvsp[-5].Number;
1294 yyMinutes = yyvsp[-3].Number;
1295 yySeconds = yyvsp[-1].Number;
1296 yyMeridian = yyvsp[0].Meridian;
1300 #line 168 "getdate.y"
1302 yyHour = yyvsp[-5].Number;
1303 yyMinutes = yyvsp[-3].Number;
1304 yySeconds = yyvsp[-1].Number;
1307 yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
1311 #line 178 "getdate.y"
1313 yyTimezone = yyvsp[0].Number;
1318 #line 182 "getdate.y"
1320 yyTimezone = yyvsp[0].Number;
1325 #line 187 "getdate.y"
1327 yyTimezone = yyvsp[-1].Number;
1332 #line 193 "getdate.y"
1335 yyDayNumber = yyvsp[0].Number;
1339 #line 197 "getdate.y"
1342 yyDayNumber = yyvsp[-1].Number;
1346 #line 201 "getdate.y"
1348 yyDayOrdinal = yyvsp[-1].Number;
1349 yyDayNumber = yyvsp[0].Number;
1353 #line 207 "getdate.y"
1355 yyMonth = yyvsp[-2].Number;
1356 yyDay = yyvsp[0].Number;
1360 #line 211 "getdate.y"
1362 if (yyvsp[-4].Number >= 100) {
1363 yyYear = yyvsp[-4].Number;
1364 yyMonth = yyvsp[-2].Number;
1365 yyDay = yyvsp[0].Number;
1367 yyMonth = yyvsp[-4].Number;
1368 yyDay = yyvsp[-2].Number;
1369 yyYear = yyvsp[0].Number;
1374 #line 222 "getdate.y"
1376 /* ISO 8601 format. yyyy-mm-dd. */
1377 yyYear = yyvsp[-2].Number;
1378 yyMonth = -yyvsp[-1].Number;
1379 yyDay = -yyvsp[0].Number;
1383 #line 228 "getdate.y"
1385 /* e.g. 17-JUN-1992. */
1386 yyDay = yyvsp[-2].Number;
1387 yyMonth = yyvsp[-1].Number;
1388 yyYear = -yyvsp[0].Number;
1392 #line 234 "getdate.y"
1394 yyMonth = yyvsp[-1].Number;
1395 yyDay = yyvsp[0].Number;
1399 #line 238 "getdate.y"
1401 yyMonth = yyvsp[-3].Number;
1402 yyDay = yyvsp[-2].Number;
1403 yyYear = yyvsp[0].Number;
1407 #line 243 "getdate.y"
1409 yyMonth = yyvsp[0].Number;
1410 yyDay = yyvsp[-1].Number;
1414 #line 247 "getdate.y"
1416 yyMonth = yyvsp[-1].Number;
1417 yyDay = yyvsp[-2].Number;
1418 yyYear = yyvsp[0].Number;
1422 #line 254 "getdate.y"
1424 yyRelSeconds = -yyRelSeconds;
1425 yyRelMonth = -yyRelMonth;
1429 #line 261 "getdate.y"
1431 yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
1435 #line 264 "getdate.y"
1437 yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
1441 #line 267 "getdate.y"
1443 yyRelSeconds += yyvsp[0].Number * 60L;
1447 #line 270 "getdate.y"
1449 yyRelSeconds += yyvsp[-1].Number;
1453 #line 273 "getdate.y"
1455 yyRelSeconds += yyvsp[-1].Number;
1459 #line 276 "getdate.y"
1465 #line 279 "getdate.y"
1467 yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1471 #line 282 "getdate.y"
1473 yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1477 #line 285 "getdate.y"
1479 yyRelMonth += yyvsp[0].Number;
1483 #line 290 "getdate.y"
1485 if (yyHaveTime && yyHaveDate && !yyHaveRel)
1486 yyYear = yyvsp[0].Number;
1488 if(yyvsp[0].Number>10000) {
1490 yyDay= (yyvsp[0].Number)%100;
1491 yyMonth= (yyvsp[0].Number/100)%100;
1492 yyYear = yyvsp[0].Number/10000;
1496 if (yyvsp[0].Number < 100) {
1497 yyHour = yyvsp[0].Number;
1501 yyHour = yyvsp[0].Number / 100;
1502 yyMinutes = yyvsp[0].Number % 100;
1511 #line 317 "getdate.y"
1513 yyval.Meridian = MER24;
1517 #line 320 "getdate.y"
1519 yyval.Meridian = yyvsp[0].Meridian;
1522 #line 1470 "getdate.c"
1528 if (yystate == 0 && yym == 0)
1532 printf("%sdebug: after reduction, shifting from state 0 to\
1533 state %d\n", YYPREFIX, YYFINAL);
1540 if ((yychar = yylex()) < 0) yychar = 0;
1545 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1546 if (!yys) yys = "illegal-symbol";
1547 printf("%sdebug: state %d, reading %d (%s)\n",
1548 YYPREFIX, YYFINAL, yychar, yys);
1552 if (yychar == 0) goto yyaccept;
1555 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1556 yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1557 yystate = yytable[yyn];
1559 yystate = yydgoto[yym];
1562 printf("%sdebug: after reduction, shifting from state %d \
1563 to state %d\n", YYPREFIX, *yyssp, yystate);
1565 if (yyssp >= yysslim && yygrowstack())
1573 yyerror("yacc stack overflow");
1579 yyss = yyssp = NULL;
1580 yyvs = yyvsp = NULL;
1588 yyss = yyssp = NULL;
1589 yyvs = yyvsp = NULL;