GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/cvs/date.c Lines: 0 214 0.0 %
Date: 2017-11-13 Branches: 0 138 0.0 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <string.h>
3
#define YYBYACC 1
4
#define YYMAJOR 1
5
#define YYMINOR 9
6
#define YYLEX yylex()
7
#define YYEMPTY -1
8
#define yyclearin (yychar=(YYEMPTY))
9
#define yyerrok (yyerrflag=0)
10
#define YYRECOVERING() (yyerrflag!=0)
11
#define YYPREFIX "yy"
12
#line 2 "date.y"
13
/*	$OpenBSD: date.y,v 1.26 2017/07/20 13:39:11 okan Exp $	*/
14
15
/*
16
**  Originally written by Steven M. Bellovin <smb@research.att.com> while
17
**  at the University of North Carolina at Chapel Hill.  Later tweaked by
18
**  a couple of people on Usenet.  Completely overhauled by Rich $alz
19
**  <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
20
**
21
**  This grammar has 10 shift/reduce conflicts.
22
**
23
**  This code is in the public domain and has no copyright.
24
*/
25
/* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
26
/* SUPPRESS 288 on yyerrlab *//* Label unused */
27
28
#include <ctype.h>
29
#include <string.h>
30
#include <time.h>
31
32
#include "cvs.h"
33
34
#define YEAR_EPOCH	1970
35
#define YEAR_TMORIGIN	1900
36
#define HOUR(x)		((time_t)(x) * 60)
37
#define SECSPERDAY	(24L * 60L * 60L)
38
39
40
/* An entry in the lexical lookup table */
41
typedef struct _TABLE {
42
	char	*name;
43
	int	type;
44
	time_t	value;
45
} TABLE;
46
47
48
/*  Daylight-savings mode:  on, off, or not yet known. */
49
typedef enum _DSTMODE {
50
	DSTon, DSToff, DSTmaybe
51
} DSTMODE;
52
53
/*  Meridian:  am, pm, or 24-hour style. */
54
typedef enum _MERIDIAN {
55
	MERam, MERpm, MER24
56
} MERIDIAN;
57
58
59
/*
60
 *  Global variables.  We could get rid of most of these by using a good
61
 *  union as the yacc stack.  (This routine was originally written before
62
 *  yacc had the %union construct.)  Maybe someday; right now we only use
63
 *  the %union very rarely.
64
 */
65
static const char	*yyInput;
66
static DSTMODE	yyDSTmode;
67
static time_t	yyDayOrdinal;
68
static time_t	yyDayNumber;
69
static int	yyHaveDate;
70
static int	yyHaveDay;
71
static int	yyHaveRel;
72
static int	yyHaveTime;
73
static int	yyHaveZone;
74
static time_t	yyTimezone;
75
static time_t	yyDay;
76
static time_t	yyHour;
77
static time_t	yyMinutes;
78
static time_t	yyMonth;
79
static time_t	yySeconds;
80
static time_t	yyYear;
81
static MERIDIAN	yyMeridian;
82
static time_t	yyRelMonth;
83
static time_t	yyRelSeconds;
84
85
86
static int	yyerror(const char *);
87
static int	yylex(void);
88
static int	yyparse(void);
89
static int	lookup(char *);
90
91
#line 82 "date.y"
92
#ifndef YYSTYPE_DEFINED
93
#define YYSTYPE_DEFINED
94
typedef union {
95
	time_t		Number;
96
	enum _MERIDIAN	Meridian;
97
} YYSTYPE;
98
#endif /* YYSTYPE_DEFINED */
99
#line 100 "date.c"
100
#define tAGO 257
101
#define tDAY 258
102
#define tDAYZONE 259
103
#define tID 260
104
#define tMERIDIAN 261
105
#define tMINUTE_UNIT 262
106
#define tMONTH 263
107
#define tMONTH_UNIT 264
108
#define tSEC_UNIT 265
109
#define tSNUMBER 266
110
#define tUNUMBER 267
111
#define tZONE 268
112
#define tDST 269
113
#define YYERRCODE 256
114
const short yylhs[] =
115
	{                                        -1,
116
    0,    0,    2,    2,    2,    2,    2,    2,    3,    3,
117
    3,    3,    3,    4,    4,    4,    6,    6,    6,    5,
118
    5,    5,    5,    5,    5,    5,    5,    7,    7,    9,
119
    9,    9,    9,    9,    9,    9,    9,    9,    8,    1,
120
    1,
121
};
122
const short yylen[] =
123
	{                                         2,
124
    0,    2,    1,    1,    1,    1,    1,    1,    2,    4,
125
    4,    6,    6,    1,    1,    2,    1,    2,    2,    3,
126
    5,    3,    3,    2,    4,    2,    3,    2,    1,    2,
127
    2,    1,    2,    2,    1,    2,    2,    1,    1,    0,
128
    1,
129
};
130
const short yydefred[] =
131
	{                                      1,
132
    0,    0,   15,   32,    0,   38,   35,    0,    0,    0,
133
    2,    3,    4,    5,    6,    7,    8,    0,   18,    0,
134
   31,   36,   33,   19,    9,   30,    0,   37,   34,    0,
135
    0,    0,   16,   28,    0,   23,   27,   22,    0,    0,
136
   25,   41,   11,    0,   10,    0,    0,   21,   13,   12,
137
};
138
const short yydgoto[] =
139
	{                                       1,
140
   45,   11,   12,   13,   14,   15,   16,   17,   18,
141
};
142
const short yysindex[] =
143
	{                                      0,
144
 -249,  -38,    0,    0, -260,    0,    0, -240,  -47, -248,
145
    0,    0,    0,    0,    0,    0,    0, -237,    0,  -18,
146
    0,    0,    0,    0,    0,    0, -262,    0,    0, -239,
147
 -238, -236,    0,    0, -235,    0,    0,    0,  -56,  -19,
148
    0,    0,    0, -234,    0, -232, -258,    0,    0,    0,};
149
const short yyrindex[] =
150
	{                                      0,
151
    0,    1,    0,    0,    0,    0,    0,    0,   69,   12,
152
    0,    0,    0,    0,    0,    0,    0,   23,    0,   34,
153
    0,    0,    0,    0,    0,    0,   67,    0,    0,    0,
154
    0,    0,    0,    0,    0,    0,    0,    0,   56,   45,
155
    0,    0,    0,    0,    0,    0,   56,    0,    0,    0,};
156
const short yygindex[] =
157
	{                                      0,
158
  -17,    0,    0,    0,    0,    0,    0,    0,    0,
159
};
160
#define YYTABLESIZE 337
161
const short yytable[] =
162
	{                                      32,
163
   17,   44,   42,   36,   37,   19,   20,   49,    2,    3,
164
   31,   14,    4,    5,    6,    7,    8,    9,   10,   34,
165
   33,   21,   29,   22,   23,   35,   38,   46,   39,   50,
166
   40,   41,   47,   24,   48,    0,    0,    0,    0,    0,
167
    0,    0,    0,    0,   20,    0,    0,    0,    0,    0,
168
    0,    0,    0,    0,    0,   40,    0,    0,    0,    0,
169
    0,    0,    0,    0,    0,    0,   26,    0,   39,    0,
170
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
171
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
172
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
173
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
174
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
175
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
176
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
177
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
178
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
179
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
180
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
181
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
182
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
183
    0,    0,    0,    0,   42,    0,    0,    0,    0,   43,
184
   24,    0,    0,   25,   26,   27,   28,   29,   30,    0,
185
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
186
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
187
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
188
    0,    0,    0,    0,    0,    0,    0,    0,   17,   17,
189
    0,    0,   17,   17,   17,   17,   17,   17,   17,   14,
190
   14,    0,    0,   14,   14,   14,   14,   14,   14,   14,
191
   29,   29,    0,    0,   29,   29,   29,   29,   29,   29,
192
   29,   24,   24,    0,    0,   24,   24,   24,   24,   24,
193
   24,   24,   20,   20,    0,    0,   20,   20,   20,   20,
194
   20,   20,   20,   40,   40,    0,    0,   40,   40,   40,
195
   40,    0,   40,   40,   26,   26,    0,   39,   26,   26,
196
   26,   26,    0,    0,   26,   39,   39,
197
};
198
const short yycheck[] =
199
	{                                      47,
200
    0,   58,  261,  266,  267,   44,  267,  266,  258,  259,
201
   58,    0,  262,  263,  264,  265,  266,  267,  268,  257,
202
  269,  262,    0,  264,  265,   44,  266,   47,  267,   47,
203
  267,  267,  267,    0,  267,   -1,   -1,   -1,   -1,   -1,
204
   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,   -1,
205
   -1,   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,
206
   -1,   -1,   -1,   -1,   -1,   -1,    0,   -1,    0,   -1,
207
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
208
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
209
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
210
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
211
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
212
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
213
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
214
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
215
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
216
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
217
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
218
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
219
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
220
   -1,   -1,   -1,   -1,  261,   -1,   -1,   -1,   -1,  266,
221
  258,   -1,   -1,  261,  262,  263,  264,  265,  266,   -1,
222
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
223
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
224
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
225
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  258,  259,
226
   -1,   -1,  262,  263,  264,  265,  266,  267,  268,  258,
227
  259,   -1,   -1,  262,  263,  264,  265,  266,  267,  268,
228
  258,  259,   -1,   -1,  262,  263,  264,  265,  266,  267,
229
  268,  258,  259,   -1,   -1,  262,  263,  264,  265,  266,
230
  267,  268,  258,  259,   -1,   -1,  262,  263,  264,  265,
231
  266,  267,  268,  258,  259,   -1,   -1,  262,  263,  264,
232
  265,   -1,  267,  268,  258,  259,   -1,  259,  262,  263,
233
  264,  265,   -1,   -1,  268,  267,  268,
234
};
235
#define YYFINAL 1
236
#ifndef YYDEBUG
237
#define YYDEBUG 0
238
#endif
239
#define YYMAXTOKEN 269
240
#if YYDEBUG
241
const char * const yyname[] =
242
	{
243
"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,
244
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,
245
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,
246
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,
247
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,
248
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,
249
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",
250
"tDAYZONE","tID","tMERIDIAN","tMINUTE_UNIT","tMONTH","tMONTH_UNIT","tSEC_UNIT",
251
"tSNUMBER","tUNUMBER","tZONE","tDST",
252
};
253
const char * const yyrule[] =
254
	{"$accept : spec",
255
"spec :",
256
"spec : spec item",
257
"item : time",
258
"item : zone",
259
"item : date",
260
"item : day",
261
"item : rel",
262
"item : number",
263
"time : tUNUMBER tMERIDIAN",
264
"time : tUNUMBER ':' tUNUMBER o_merid",
265
"time : tUNUMBER ':' tUNUMBER tSNUMBER",
266
"time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid",
267
"time : tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER",
268
"zone : tZONE",
269
"zone : tDAYZONE",
270
"zone : tZONE tDST",
271
"day : tDAY",
272
"day : tDAY ','",
273
"day : tUNUMBER tDAY",
274
"date : tUNUMBER '/' tUNUMBER",
275
"date : tUNUMBER '/' tUNUMBER '/' tUNUMBER",
276
"date : tUNUMBER tSNUMBER tSNUMBER",
277
"date : tUNUMBER tMONTH tSNUMBER",
278
"date : tMONTH tUNUMBER",
279
"date : tMONTH tUNUMBER ',' tUNUMBER",
280
"date : tUNUMBER tMONTH",
281
"date : tUNUMBER tMONTH tUNUMBER",
282
"rel : relunit tAGO",
283
"rel : relunit",
284
"relunit : tUNUMBER tMINUTE_UNIT",
285
"relunit : tSNUMBER tMINUTE_UNIT",
286
"relunit : tMINUTE_UNIT",
287
"relunit : tSNUMBER tSEC_UNIT",
288
"relunit : tUNUMBER tSEC_UNIT",
289
"relunit : tSEC_UNIT",
290
"relunit : tSNUMBER tMONTH_UNIT",
291
"relunit : tUNUMBER tMONTH_UNIT",
292
"relunit : tMONTH_UNIT",
293
"number : tUNUMBER",
294
"o_merid :",
295
"o_merid : tMERIDIAN",
296
};
297
#endif
298
#ifdef YYSTACKSIZE
299
#undef YYMAXDEPTH
300
#define YYMAXDEPTH YYSTACKSIZE
301
#else
302
#ifdef YYMAXDEPTH
303
#define YYSTACKSIZE YYMAXDEPTH
304
#else
305
#define YYSTACKSIZE 10000
306
#define YYMAXDEPTH 10000
307
#endif
308
#endif
309
#define YYINITSTACKSIZE 200
310
/* LINTUSED */
311
int yydebug;
312
int yynerrs;
313
int yyerrflag;
314
int yychar;
315
short *yyssp;
316
YYSTYPE *yyvsp;
317
YYSTYPE yyval;
318
YYSTYPE yylval;
319
short *yyss;
320
short *yysslim;
321
YYSTYPE *yyvs;
322
unsigned int yystacksize;
323
int yyparse(void);
324
#line 298 "date.y"
325
326
/* Month and day table. */
327
static TABLE const MonthDayTable[] = {
328
	{ "january",	tMONTH,	1 },
329
	{ "february",	tMONTH,	2 },
330
	{ "march",	tMONTH,	3 },
331
	{ "april",	tMONTH,	4 },
332
	{ "may",	tMONTH,	5 },
333
	{ "june",	tMONTH,	6 },
334
	{ "july",	tMONTH,	7 },
335
	{ "august",	tMONTH,	8 },
336
	{ "september",	tMONTH,	9 },
337
	{ "sept",	tMONTH,	9 },
338
	{ "october",	tMONTH,	10 },
339
	{ "november",	tMONTH,	11 },
340
	{ "december",	tMONTH,	12 },
341
	{ "sunday",	tDAY,	0 },
342
	{ "monday",	tDAY,	1 },
343
	{ "tuesday",	tDAY,	2 },
344
	{ "tues",	tDAY,	2 },
345
	{ "wednesday",	tDAY,	3 },
346
	{ "wednes",	tDAY,	3 },
347
	{ "thursday",	tDAY,	4 },
348
	{ "thur",	tDAY,	4 },
349
	{ "thurs",	tDAY,	4 },
350
	{ "friday",	tDAY,	5 },
351
	{ "saturday",	tDAY,	6 },
352
	{ NULL }
353
};
354
355
/* Time units table. */
356
static TABLE const UnitsTable[] = {
357
	{ "year",	tMONTH_UNIT,	12 },
358
	{ "month",	tMONTH_UNIT,	1 },
359
	{ "fortnight",	tMINUTE_UNIT,	14 * 24 * 60 },
360
	{ "week",	tMINUTE_UNIT,	7 * 24 * 60 },
361
	{ "day",	tMINUTE_UNIT,	1 * 24 * 60 },
362
	{ "hour",	tMINUTE_UNIT,	60 },
363
	{ "minute",	tMINUTE_UNIT,	1 },
364
	{ "min",	tMINUTE_UNIT,	1 },
365
	{ "second",	tSEC_UNIT,	1 },
366
	{ "sec",	tSEC_UNIT,	1 },
367
	{ NULL }
368
};
369
370
/* Assorted relative-time words. */
371
static TABLE const OtherTable[] = {
372
	{ "tomorrow",	tMINUTE_UNIT,	1 * 24 * 60 },
373
	{ "yesterday",	tMINUTE_UNIT,	-1 * 24 * 60 },
374
	{ "today",	tMINUTE_UNIT,	0 },
375
	{ "now",	tMINUTE_UNIT,	0 },
376
	{ "last",	tUNUMBER,	-1 },
377
	{ "this",	tMINUTE_UNIT,	0 },
378
	{ "next",	tUNUMBER,	2 },
379
	{ "first",	tUNUMBER,	1 },
380
/*  { "second",		tUNUMBER,	2 }, */
381
	{ "third",	tUNUMBER,	3 },
382
	{ "fourth",	tUNUMBER,	4 },
383
	{ "fifth",	tUNUMBER,	5 },
384
	{ "sixth",	tUNUMBER,	6 },
385
	{ "seventh",	tUNUMBER,	7 },
386
	{ "eighth",	tUNUMBER,	8 },
387
	{ "ninth",	tUNUMBER,	9 },
388
	{ "tenth",	tUNUMBER,	10 },
389
	{ "eleventh",	tUNUMBER,	11 },
390
	{ "twelfth",	tUNUMBER,	12 },
391
	{ "ago",	tAGO,	1 },
392
	{ NULL }
393
};
394
395
/* The timezone table. */
396
/* Some of these are commented out because a time_t can't store a float. */
397
static TABLE const TimezoneTable[] = {
398
	{ "gmt",	tZONE,     HOUR( 0) },	/* Greenwich Mean */
399
	{ "ut",		tZONE,     HOUR( 0) },	/* Universal (Coordinated) */
400
	{ "utc",	tZONE,     HOUR( 0) },
401
	{ "wet",	tZONE,     HOUR( 0) },	/* Western European */
402
	{ "bst",	tDAYZONE,  HOUR( 0) },	/* British Summer */
403
	{ "wat",	tZONE,     HOUR( 1) },	/* West Africa */
404
	{ "at",		tZONE,     HOUR( 2) },	/* Azores */
405
#if	0
406
	/* For completeness.  BST is also British Summer, and GST is
407
	 * also Guam Standard. */
408
	{ "bst",	tZONE,     HOUR( 3) },	/* Brazil Standard */
409
	{ "gst",	tZONE,     HOUR( 3) },	/* Greenland Standard */
410
#endif
411
#if 0
412
	{ "nft",	tZONE,     HOUR(3.5) },	/* Newfoundland */
413
	{ "nst",	tZONE,     HOUR(3.5) },	/* Newfoundland Standard */
414
	{ "ndt",	tDAYZONE,  HOUR(3.5) },	/* Newfoundland Daylight */
415
#endif
416
	{ "ast",	tZONE,     HOUR( 4) },	/* Atlantic Standard */
417
	{ "adt",	tDAYZONE,  HOUR( 4) },	/* Atlantic Daylight */
418
	{ "est",	tZONE,     HOUR( 5) },	/* Eastern Standard */
419
	{ "edt",	tDAYZONE,  HOUR( 5) },	/* Eastern Daylight */
420
	{ "cst",	tZONE,     HOUR( 6) },	/* Central Standard */
421
	{ "cdt",	tDAYZONE,  HOUR( 6) },	/* Central Daylight */
422
	{ "mst",	tZONE,     HOUR( 7) },	/* Mountain Standard */
423
	{ "mdt",	tDAYZONE,  HOUR( 7) },	/* Mountain Daylight */
424
	{ "pst",	tZONE,     HOUR( 8) },	/* Pacific Standard */
425
	{ "pdt",	tDAYZONE,  HOUR( 8) },	/* Pacific Daylight */
426
	{ "yst",	tZONE,     HOUR( 9) },	/* Yukon Standard */
427
	{ "ydt",	tDAYZONE,  HOUR( 9) },	/* Yukon Daylight */
428
	{ "hst",	tZONE,     HOUR(10) },	/* Hawaii Standard */
429
	{ "hdt",	tDAYZONE,  HOUR(10) },	/* Hawaii Daylight */
430
	{ "cat",	tZONE,     HOUR(10) },	/* Central Alaska */
431
	{ "ahst",	tZONE,     HOUR(10) },	/* Alaska-Hawaii Standard */
432
	{ "nt",		tZONE,     HOUR(11) },	/* Nome */
433
	{ "idlw",	tZONE,     HOUR(12) },	/* International Date Line West */
434
	{ "cet",	tZONE,     -HOUR(1) },	/* Central European */
435
	{ "met",	tZONE,     -HOUR(1) },	/* Middle European */
436
	{ "mewt",	tZONE,     -HOUR(1) },	/* Middle European Winter */
437
	{ "mest",	tDAYZONE,  -HOUR(1) },	/* Middle European Summer */
438
	{ "swt",	tZONE,     -HOUR(1) },	/* Swedish Winter */
439
	{ "sst",	tDAYZONE,  -HOUR(1) },	/* Swedish Summer */
440
	{ "fwt",	tZONE,     -HOUR(1) },	/* French Winter */
441
	{ "fst",	tDAYZONE,  -HOUR(1) },	/* French Summer */
442
	{ "eet",	tZONE,     -HOUR(2) },	/* Eastern Europe, USSR Zone 1 */
443
	{ "bt",		tZONE,     -HOUR(3) },	/* Baghdad, USSR Zone 2 */
444
#if 0
445
	{ "it",		tZONE,     -HOUR(3.5) },/* Iran */
446
#endif
447
	{ "zp4",	tZONE,     -HOUR(4) },	/* USSR Zone 3 */
448
	{ "zp5",	tZONE,     -HOUR(5) },	/* USSR Zone 4 */
449
#if 0
450
	{ "ist",	tZONE,     -HOUR(5.5) },/* Indian Standard */
451
#endif
452
	{ "zp6",	tZONE,     -HOUR(6) },	/* USSR Zone 5 */
453
#if	0
454
	/* For completeness.  NST is also Newfoundland Stanard, and SST is
455
	 * also Swedish Summer. */
456
	{ "nst",	tZONE,     -HOUR(6.5) },/* North Sumatra */
457
	{ "sst",	tZONE,     -HOUR(7) },	/* South Sumatra, USSR Zone 6 */
458
#endif	/* 0 */
459
	{ "wast",	tZONE,     -HOUR(7) },	/* West Australian Standard */
460
	{ "wadt",	tDAYZONE,  -HOUR(7) },	/* West Australian Daylight */
461
#if 0
462
	{ "jt",		tZONE,     -HOUR(7.5) },/* Java (3pm in Cronusland!) */
463
#endif
464
	{ "cct",	tZONE,     -HOUR(8) },	/* China Coast, USSR Zone 7 */
465
	{ "jst",	tZONE,     -HOUR(9) },	/* Japan Standard, USSR Zone 8 */
466
#if 0
467
	{ "cast",	tZONE,     -HOUR(9.5) },/* Central Australian Standard */
468
	{ "cadt",	tDAYZONE,  -HOUR(9.5) },/* Central Australian Daylight */
469
#endif
470
	{ "east",	tZONE,     -HOUR(10) },	/* Eastern Australian Standard */
471
	{ "eadt",	tDAYZONE,  -HOUR(10) },	/* Eastern Australian Daylight */
472
	{ "gst",	tZONE,     -HOUR(10) },	/* Guam Standard, USSR Zone 9 */
473
	{ "nzt",	tZONE,     -HOUR(12) },	/* New Zealand */
474
	{ "nzst",	tZONE,     -HOUR(12) },	/* New Zealand Standard */
475
	{ "nzdt",	tDAYZONE,  -HOUR(12) },	/* New Zealand Daylight */
476
	{ "idle",	tZONE,     -HOUR(12) },	/* International Date Line East */
477
	{  NULL  }
478
};
479
480
/* Military timezone table. */
481
static TABLE const MilitaryTable[] = {
482
	{ "a",	tZONE,	HOUR(  1) },
483
	{ "b",	tZONE,	HOUR(  2) },
484
	{ "c",	tZONE,	HOUR(  3) },
485
	{ "d",	tZONE,	HOUR(  4) },
486
	{ "e",	tZONE,	HOUR(  5) },
487
	{ "f",	tZONE,	HOUR(  6) },
488
	{ "g",	tZONE,	HOUR(  7) },
489
	{ "h",	tZONE,	HOUR(  8) },
490
	{ "i",	tZONE,	HOUR(  9) },
491
	{ "k",	tZONE,	HOUR( 10) },
492
	{ "l",	tZONE,	HOUR( 11) },
493
	{ "m",	tZONE,	HOUR( 12) },
494
	{ "n",	tZONE,	HOUR(- 1) },
495
	{ "o",	tZONE,	HOUR(- 2) },
496
	{ "p",	tZONE,	HOUR(- 3) },
497
	{ "q",	tZONE,	HOUR(- 4) },
498
	{ "r",	tZONE,	HOUR(- 5) },
499
	{ "s",	tZONE,	HOUR(- 6) },
500
	{ "t",	tZONE,	HOUR(- 7) },
501
	{ "u",	tZONE,	HOUR(- 8) },
502
	{ "v",	tZONE,	HOUR(- 9) },
503
	{ "w",	tZONE,	HOUR(-10) },
504
	{ "x",	tZONE,	HOUR(-11) },
505
	{ "y",	tZONE,	HOUR(-12) },
506
	{ "z",	tZONE,	HOUR(  0) },
507
	{ NULL }
508
};
509
510
511
static int
512
yyerror(const char *s)
513
{
514
#if !defined(TEST)
515
	char *str;
516
517
	(void)xasprintf(&str, "parsing date string: %s", s);
518
	cvs_log(LP_ERR, "%s", str);
519
	free(str);
520
#endif
521
	return (0);
522
}
523
524
525
static time_t
526
ToSeconds(time_t Hours, time_t Minutes, time_t	Seconds, MERIDIAN Meridian)
527
{
528
	if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
529
		return (-1);
530
531
	switch (Meridian) {
532
	case MER24:
533
		if (Hours < 0 || Hours > 23)
534
			return (-1);
535
		return (Hours * 60L + Minutes) * 60L + Seconds;
536
	case MERam:
537
		if (Hours < 1 || Hours > 12)
538
			return (-1);
539
		if (Hours == 12)
540
			Hours = 0;
541
		return (Hours * 60L + Minutes) * 60L + Seconds;
542
	case MERpm:
543
		if (Hours < 1 || Hours > 12)
544
			return (-1);
545
		if (Hours == 12)
546
			Hours = 0;
547
		return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
548
	default:
549
		return (-1);
550
	}
551
	/* NOTREACHED */
552
}
553
554
555
/* Year is either
556
 * A negative number, which means to use its absolute value (why?)
557
 * A number from 0 to 99, which means a year from 1900 to 1999, or
558
 * The actual year (>=100).
559
 */
560
static time_t
561
Convert(time_t Month, time_t Day, time_t Year, time_t Hours, time_t Minutes,
562
    time_t Seconds, MERIDIAN Meridian, DSTMODE DSTmode)
563
{
564
	static int DaysInMonth[12] = {
565
		31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
566
	};
567
	time_t	tod;
568
	time_t	julian;
569
	int	i;
570
571
	if (Year < 0)
572
		Year = -Year;
573
	if (Year < 69)
574
		Year += 2000;
575
	else if (Year < 100) {
576
		Year += 1900;
577
		if (Year < YEAR_EPOCH)
578
			Year += 100;
579
	}
580
	DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
581
	    ? 29 : 28;
582
	/* XXX Sloppily check for 2038 if time_t is 32 bits */
583
	if (Year < YEAR_EPOCH ||
584
	    (sizeof(time_t) == sizeof(int) && Year > 2038) ||
585
	    Month < 1 || Month > 12 ||
586
	    /* Lint fluff:  "conversion from long may lose accuracy" */
587
	     Day < 1 || Day > DaysInMonth[(int)--Month])
588
		return (-1);
589
590
	for (julian = Day - 1, i = 0; i < Month; i++)
591
		julian += DaysInMonth[i];
592
593
	for (i = YEAR_EPOCH; i < Year; i++)
594
		julian += 365 + (i % 4 == 0);
595
	julian *= SECSPERDAY;
596
	julian += yyTimezone * 60L;
597
598
	if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
599
		return (-1);
600
	julian += tod;
601
	if ((DSTmode == DSTon) ||
602
	    (DSTmode == DSTmaybe && localtime(&julian)->tm_isdst))
603
	julian -= 60 * 60;
604
	return (julian);
605
}
606
607
608
static time_t
609
DSTcorrect(time_t Start, time_t Future)
610
{
611
	time_t	StartDay;
612
	time_t	FutureDay;
613
614
	StartDay = (localtime(&Start)->tm_hour + 1) % 24;
615
	FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
616
	return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
617
}
618
619
620
static time_t
621
RelativeDate(time_t Start, time_t DayOrdinal, time_t DayNumber)
622
{
623
	struct tm	*tm;
624
	time_t	now;
625
626
	now = Start;
627
	tm = localtime(&now);
628
	now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
629
	now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
630
	return DSTcorrect(Start, now);
631
}
632
633
634
static time_t
635
RelativeMonth(time_t Start, time_t RelMonth)
636
{
637
	struct tm	*tm;
638
	time_t	Month;
639
	time_t	Year;
640
641
	if (RelMonth == 0)
642
		return (0);
643
	tm = localtime(&Start);
644
	Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
645
	Year = Month / 12;
646
	Month = Month % 12 + 1;
647
	return DSTcorrect(Start,
648
	    Convert(Month, (time_t)tm->tm_mday, Year,
649
	    (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
650
	    MER24, DSTmaybe));
651
}
652
653
654
static int
655
lookup(char *buff)
656
{
657
	size_t		len;
658
	char		*p, *q;
659
	int		i, abbrev;
660
	const TABLE	*tp;
661
662
	/* Make it lowercase. */
663
	for (p = buff; *p; p++)
664
		if (isupper(*p))
665
			*p = tolower(*p);
666
667
	if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
668
		yylval.Meridian = MERam;
669
		return (tMERIDIAN);
670
	}
671
	if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
672
		yylval.Meridian = MERpm;
673
		return (tMERIDIAN);
674
	}
675
676
	len = strlen(buff);
677
	/* See if we have an abbreviation for a month. */
678
	if (len == 3)
679
		abbrev = 1;
680
	else if (len == 4 && buff[3] == '.') {
681
		abbrev = 1;
682
		buff[3] = '\0';
683
		--len;
684
	} else
685
		abbrev = 0;
686
687
	for (tp = MonthDayTable; tp->name; tp++) {
688
		if (abbrev) {
689
			if (strncmp(buff, tp->name, 3) == 0) {
690
				yylval.Number = tp->value;
691
				return (tp->type);
692
			}
693
		} else if (strcmp(buff, tp->name) == 0) {
694
			yylval.Number = tp->value;
695
			return (tp->type);
696
		}
697
	}
698
699
	for (tp = TimezoneTable; tp->name; tp++)
700
		if (strcmp(buff, tp->name) == 0) {
701
			yylval.Number = tp->value;
702
			return (tp->type);
703
		}
704
705
	if (strcmp(buff, "dst") == 0)
706
		return (tDST);
707
708
	for (tp = UnitsTable; tp->name; tp++)
709
		if (strcmp(buff, tp->name) == 0) {
710
			yylval.Number = tp->value;
711
			return (tp->type);
712
		}
713
714
	/* Strip off any plural and try the units table again. */
715
	if (len != 0 && buff[len - 1] == 's') {
716
		buff[len - 1] = '\0';
717
		for (tp = UnitsTable; tp->name; tp++)
718
			if (strcmp(buff, tp->name) == 0) {
719
				yylval.Number = tp->value;
720
				return (tp->type);
721
			}
722
		buff[len - 1] = 's';	/* Put back for "this" in OtherTable. */
723
	}
724
725
	for (tp = OtherTable; tp->name; tp++)
726
		if (strcmp(buff, tp->name) == 0) {
727
			yylval.Number = tp->value;
728
			return (tp->type);
729
		}
730
731
	/* Military timezones. */
732
	if (len == 1 && isalpha(*buff)) {
733
		for (tp = MilitaryTable; tp->name; tp++)
734
			if (strcmp(buff, tp->name) == 0) {
735
				yylval.Number = tp->value;
736
				return (tp->type);
737
			}
738
	}
739
740
	/* Drop out any periods and try the timezone table again. */
741
	for (i = 0, p = q = buff; *q; q++)
742
		if (*q != '.')
743
			*p++ = *q;
744
		else
745
			i++;
746
	*p = '\0';
747
	if (i)
748
		for (tp = TimezoneTable; tp->name; tp++)
749
			if (strcmp(buff, tp->name) == 0) {
750
				yylval.Number = tp->value;
751
				return (tp->type);
752
			}
753
754
	return (tID);
755
}
756
757
758
static int
759
yylex(void)
760
{
761
	char	c, *p, buff[20];
762
	int	count, sign;
763
764
	for (;;) {
765
		while (isspace(*yyInput))
766
			yyInput++;
767
768
		if (isdigit(c = *yyInput) || c == '-' || c == '+') {
769
			if (c == '-' || c == '+') {
770
				sign = c == '-' ? -1 : 1;
771
				if (!isdigit(*++yyInput))
772
					/* skip the '-' sign */
773
					continue;
774
			}
775
			else
776
				sign = 0;
777
778
			for (yylval.Number = 0; isdigit(c = *yyInput++); )
779
				yylval.Number = 10 * yylval.Number + c - '0';
780
			yyInput--;
781
			if (sign < 0)
782
				yylval.Number = -yylval.Number;
783
			return sign ? tSNUMBER : tUNUMBER;
784
		}
785
786
		if (isalpha(c)) {
787
			for (p = buff; isalpha(c = *yyInput++) || c == '.'; )
788
				if (p < &buff[sizeof buff - 1])
789
					*p++ = c;
790
			*p = '\0';
791
			yyInput--;
792
			return lookup(buff);
793
		}
794
		if (c != '(')
795
			return *yyInput++;
796
797
		count = 0;
798
		do {
799
			c = *yyInput++;
800
			if (c == '\0')
801
				return (c);
802
			if (c == '(')
803
				count++;
804
			else if (c == ')')
805
				count--;
806
		} while (count > 0);
807
	}
808
}
809
810
/* Yield A - B, measured in seconds.  */
811
static long
812
difftm(struct tm *a, struct tm *b)
813
{
814
	int ay = a->tm_year + (YEAR_TMORIGIN - 1);
815
	int by = b->tm_year + (YEAR_TMORIGIN - 1);
816
	int days = (
817
	    /* difference in day of year */
818
	    a->tm_yday - b->tm_yday
819
	    /* + intervening leap days */
820
	    +  ((ay >> 2) - (by >> 2))
821
	    -  (ay/100 - by/100)
822
	    +  ((ay/100 >> 2) - (by/100 >> 2))
823
	    /* + difference in years * 365 */
824
	    +  (long)(ay-by) * 365);
825
	return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
826
	    + (a->tm_min - b->tm_min)) + (a->tm_sec - b->tm_sec));
827
}
828
829
/*
830
 * date_parse()
831
 *
832
 * Returns the number of seconds since the Epoch corresponding to the date.
833
 */
834
time_t
835
date_parse(const char *p)
836
{
837
	struct tm	gmt, tm;
838
	time_t		Start, tod, nowtime, tz;
839
840
	yyInput = p;
841
842
	if (time(&nowtime) == -1 || !gmtime_r(&nowtime, &gmt) ||
843
	    !localtime_r(&nowtime, &tm))
844
		return -1;
845
846
	tz = difftm(&gmt, &tm) / 60;
847
848
	if (tm.tm_isdst)
849
		tz += 60;
850
851
	yyYear = tm.tm_year + 1900;
852
	yyMonth = tm.tm_mon + 1;
853
	yyDay = tm.tm_mday;
854
	yyTimezone = tz;
855
	yyDSTmode = DSTmaybe;
856
	yyHour = 0;
857
	yyMinutes = 0;
858
	yySeconds = 0;
859
	yyMeridian = MER24;
860
	yyRelSeconds = 0;
861
	yyRelMonth = 0;
862
	yyHaveDate = 0;
863
	yyHaveDay = 0;
864
	yyHaveRel = 0;
865
	yyHaveTime = 0;
866
	yyHaveZone = 0;
867
868
	if (yyparse() || yyHaveTime > 1 || yyHaveZone > 1 ||
869
	    yyHaveDate > 1 || yyHaveDay > 1)
870
		return (-1);
871
872
	if (yyHaveDate || yyHaveTime || yyHaveDay) {
873
		Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes,
874
		    yySeconds, yyMeridian, yyDSTmode);
875
		if (Start < 0)
876
			return (-1);
877
	} else {
878
		Start = nowtime;
879
		if (!yyHaveRel)
880
			Start -= ((tm.tm_hour * 60L + tm.tm_min) * 60L) +
881
			    tm.tm_sec;
882
	}
883
884
	Start += yyRelSeconds;
885
	Start += RelativeMonth(Start, yyRelMonth);
886
887
	if (yyHaveDay && !yyHaveDate) {
888
		tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
889
		Start += tod;
890
	}
891
892
	return Start;
893
}
894
895
#if defined(TEST)
896
/* ARGSUSED */
897
int
898
main(int argc, char **argv)
899
{
900
	char	buff[128];
901
	time_t	d;
902
903
	(void)printf("Enter date, or blank line to exit.\n\t> ");
904
	(void)fflush(stdout);
905
	while (fgets(buff, sizeof(buff), stdin) && buff[0]) {
906
		d = date_parse(buff);
907
		if (d == -1)
908
			(void)printf("Bad format - couldn't convert.\n");
909
		else
910
			(void)printf("%s", ctime(&d));
911
		(void)printf("\t> ");
912
		(void)fflush(stdout);
913
	}
914
915
	return (0);
916
}
917
#endif	/* defined(TEST) */
918
#line 911 "date.c"
919
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
920
static int yygrowstack(void)
921
{
922
    unsigned int newsize;
923
    long sslen;
924
    short *newss;
925
    YYSTYPE *newvs;
926
927
    if ((newsize = yystacksize) == 0)
928
        newsize = YYINITSTACKSIZE;
929
    else if (newsize >= YYMAXDEPTH)
930
        return -1;
931
    else if ((newsize *= 2) > YYMAXDEPTH)
932
        newsize = YYMAXDEPTH;
933
    sslen = yyssp - yyss;
934
#ifdef SIZE_MAX
935
#define YY_SIZE_MAX SIZE_MAX
936
#else
937
#define YY_SIZE_MAX 0xffffffffU
938
#endif
939
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
940
        goto bail;
941
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
942
      (short *)malloc(newsize * sizeof *newss); /* overflow check above */
943
    if (newss == NULL)
944
        goto bail;
945
    yyss = newss;
946
    yyssp = newss + sslen;
947
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
948
        goto bail;
949
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
950
      (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
951
    if (newvs == NULL)
952
        goto bail;
953
    yyvs = newvs;
954
    yyvsp = newvs + sslen;
955
    yystacksize = newsize;
956
    yysslim = yyss + newsize - 1;
957
    return 0;
958
bail:
959
    if (yyss)
960
            free(yyss);
961
    if (yyvs)
962
            free(yyvs);
963
    yyss = yyssp = NULL;
964
    yyvs = yyvsp = NULL;
965
    yystacksize = 0;
966
    return -1;
967
}
968
969
#define YYABORT goto yyabort
970
#define YYREJECT goto yyabort
971
#define YYACCEPT goto yyaccept
972
#define YYERROR goto yyerrlab
973
int
974
yyparse(void)
975
{
976
    int yym, yyn, yystate;
977
#if YYDEBUG
978
    const char *yys;
979
980
    if ((yys = getenv("YYDEBUG")))
981
    {
982
        yyn = *yys;
983
        if (yyn >= '0' && yyn <= '9')
984
            yydebug = yyn - '0';
985
    }
986
#endif /* YYDEBUG */
987
988
    yynerrs = 0;
989
    yyerrflag = 0;
990
    yychar = (-1);
991
992
    if (yyss == NULL && yygrowstack()) goto yyoverflow;
993
    yyssp = yyss;
994
    yyvsp = yyvs;
995
    *yyssp = yystate = 0;
996
997
yyloop:
998
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
999
    if (yychar < 0)
1000
    {
1001
        if ((yychar = yylex()) < 0) yychar = 0;
1002
#if YYDEBUG
1003
        if (yydebug)
1004
        {
1005
            yys = 0;
1006
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1007
            if (!yys) yys = "illegal-symbol";
1008
            printf("%sdebug: state %d, reading %d (%s)\n",
1009
                    YYPREFIX, yystate, yychar, yys);
1010
        }
1011
#endif
1012
    }
1013
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1014
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1015
    {
1016
#if YYDEBUG
1017
        if (yydebug)
1018
            printf("%sdebug: state %d, shifting to state %d\n",
1019
                    YYPREFIX, yystate, yytable[yyn]);
1020
#endif
1021
        if (yyssp >= yysslim && yygrowstack())
1022
        {
1023
            goto yyoverflow;
1024
        }
1025
        *++yyssp = yystate = yytable[yyn];
1026
        *++yyvsp = yylval;
1027
        yychar = (-1);
1028
        if (yyerrflag > 0)  --yyerrflag;
1029
        goto yyloop;
1030
    }
1031
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1032
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1033
    {
1034
        yyn = yytable[yyn];
1035
        goto yyreduce;
1036
    }
1037
    if (yyerrflag) goto yyinrecovery;
1038
#if defined(__GNUC__)
1039
    goto yynewerror;
1040
#endif
1041
yynewerror:
1042
    yyerror("syntax error");
1043
#if defined(__GNUC__)
1044
    goto yyerrlab;
1045
#endif
1046
yyerrlab:
1047
    ++yynerrs;
1048
yyinrecovery:
1049
    if (yyerrflag < 3)
1050
    {
1051
        yyerrflag = 3;
1052
        for (;;)
1053
        {
1054
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1055
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1056
            {
1057
#if YYDEBUG
1058
                if (yydebug)
1059
                    printf("%sdebug: state %d, error recovery shifting\
1060
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1061
#endif
1062
                if (yyssp >= yysslim && yygrowstack())
1063
                {
1064
                    goto yyoverflow;
1065
                }
1066
                *++yyssp = yystate = yytable[yyn];
1067
                *++yyvsp = yylval;
1068
                goto yyloop;
1069
            }
1070
            else
1071
            {
1072
#if YYDEBUG
1073
                if (yydebug)
1074
                    printf("%sdebug: error recovery discarding state %d\n",
1075
                            YYPREFIX, *yyssp);
1076
#endif
1077
                if (yyssp <= yyss) goto yyabort;
1078
                --yyssp;
1079
                --yyvsp;
1080
            }
1081
        }
1082
    }
1083
    else
1084
    {
1085
        if (yychar == 0) goto yyabort;
1086
#if YYDEBUG
1087
        if (yydebug)
1088
        {
1089
            yys = 0;
1090
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1091
            if (!yys) yys = "illegal-symbol";
1092
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1093
                    YYPREFIX, yystate, yychar, yys);
1094
        }
1095
#endif
1096
        yychar = (-1);
1097
        goto yyloop;
1098
    }
1099
yyreduce:
1100
#if YYDEBUG
1101
    if (yydebug)
1102
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1103
                YYPREFIX, yystate, yyn, yyrule[yyn]);
1104
#endif
1105
    yym = yylen[yyn];
1106
    if (yym)
1107
        yyval = yyvsp[1-yym];
1108
    else
1109
        memset(&yyval, 0, sizeof yyval);
1110
    switch (yyn)
1111
    {
1112
case 3:
1113
#line 100 "date.y"
1114
{
1115
		yyHaveTime++;
1116
	}
1117
break;
1118
case 4:
1119
#line 103 "date.y"
1120
{
1121
		yyHaveZone++;
1122
	}
1123
break;
1124
case 5:
1125
#line 106 "date.y"
1126
{
1127
		yyHaveDate++;
1128
	}
1129
break;
1130
case 6:
1131
#line 109 "date.y"
1132
{
1133
		yyHaveDay++;
1134
	}
1135
break;
1136
case 7:
1137
#line 112 "date.y"
1138
{
1139
		yyHaveRel++;
1140
	}
1141
break;
1142
case 9:
1143
#line 118 "date.y"
1144
{
1145
		yyHour = yyvsp[-1].Number;
1146
		yyMinutes = 0;
1147
		yySeconds = 0;
1148
		yyMeridian = yyvsp[0].Meridian;
1149
	}
1150
break;
1151
case 10:
1152
#line 124 "date.y"
1153
{
1154
		yyHour = yyvsp[-3].Number;
1155
		yyMinutes = yyvsp[-1].Number;
1156
		yySeconds = 0;
1157
		yyMeridian = yyvsp[0].Meridian;
1158
	}
1159
break;
1160
case 11:
1161
#line 130 "date.y"
1162
{
1163
		yyHour = yyvsp[-3].Number;
1164
		yyMinutes = yyvsp[-1].Number;
1165
		yyMeridian = MER24;
1166
		yyDSTmode = DSToff;
1167
		yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
1168
	}
1169
break;
1170
case 12:
1171
#line 137 "date.y"
1172
{
1173
		yyHour = yyvsp[-5].Number;
1174
		yyMinutes = yyvsp[-3].Number;
1175
		yySeconds = yyvsp[-1].Number;
1176
		yyMeridian = yyvsp[0].Meridian;
1177
	}
1178
break;
1179
case 13:
1180
#line 143 "date.y"
1181
{
1182
		yyHour = yyvsp[-5].Number;
1183
		yyMinutes = yyvsp[-3].Number;
1184
		yySeconds = yyvsp[-1].Number;
1185
		yyMeridian = MER24;
1186
		yyDSTmode = DSToff;
1187
		yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
1188
	}
1189
break;
1190
case 14:
1191
#line 153 "date.y"
1192
{
1193
		yyTimezone = yyvsp[0].Number;
1194
		yyDSTmode = DSToff;
1195
	}
1196
break;
1197
case 15:
1198
#line 157 "date.y"
1199
{
1200
		yyTimezone = yyvsp[0].Number;
1201
		yyDSTmode = DSTon;
1202
	}
1203
break;
1204
case 16:
1205
#line 161 "date.y"
1206
{
1207
		yyTimezone = yyvsp[-1].Number;
1208
		yyDSTmode = DSTon;
1209
	}
1210
break;
1211
case 17:
1212
#line 167 "date.y"
1213
{
1214
		yyDayOrdinal = 1;
1215
		yyDayNumber = yyvsp[0].Number;
1216
	}
1217
break;
1218
case 18:
1219
#line 171 "date.y"
1220
{
1221
		yyDayOrdinal = 1;
1222
		yyDayNumber = yyvsp[-1].Number;
1223
	}
1224
break;
1225
case 19:
1226
#line 175 "date.y"
1227
{
1228
		yyDayOrdinal = yyvsp[-1].Number;
1229
		yyDayNumber = yyvsp[0].Number;
1230
	}
1231
break;
1232
case 20:
1233
#line 181 "date.y"
1234
{
1235
		yyMonth = yyvsp[-2].Number;
1236
		yyDay = yyvsp[0].Number;
1237
	}
1238
break;
1239
case 21:
1240
#line 185 "date.y"
1241
{
1242
		if (yyvsp[-4].Number >= 100) {
1243
			yyYear = yyvsp[-4].Number;
1244
			yyMonth = yyvsp[-2].Number;
1245
			yyDay = yyvsp[0].Number;
1246
		} else {
1247
			yyMonth = yyvsp[-4].Number;
1248
			yyDay = yyvsp[-2].Number;
1249
			yyYear = yyvsp[0].Number;
1250
		}
1251
	}
1252
break;
1253
case 22:
1254
#line 196 "date.y"
1255
{
1256
		/* ISO 8601 format.  yyyy-mm-dd.  */
1257
		yyYear = yyvsp[-2].Number;
1258
		yyMonth = -yyvsp[-1].Number;
1259
		yyDay = -yyvsp[0].Number;
1260
	}
1261
break;
1262
case 23:
1263
#line 202 "date.y"
1264
{
1265
		/* e.g. 17-JUN-1992.  */
1266
		yyDay = yyvsp[-2].Number;
1267
		yyMonth = yyvsp[-1].Number;
1268
		yyYear = -yyvsp[0].Number;
1269
	}
1270
break;
1271
case 24:
1272
#line 208 "date.y"
1273
{
1274
		yyMonth = yyvsp[-1].Number;
1275
		yyDay = yyvsp[0].Number;
1276
	}
1277
break;
1278
case 25:
1279
#line 212 "date.y"
1280
{
1281
		yyMonth = yyvsp[-3].Number;
1282
		yyDay = yyvsp[-2].Number;
1283
		yyYear = yyvsp[0].Number;
1284
	}
1285
break;
1286
case 26:
1287
#line 217 "date.y"
1288
{
1289
		yyMonth = yyvsp[0].Number;
1290
		yyDay = yyvsp[-1].Number;
1291
	}
1292
break;
1293
case 27:
1294
#line 221 "date.y"
1295
{
1296
		yyMonth = yyvsp[-1].Number;
1297
		yyDay = yyvsp[-2].Number;
1298
		yyYear = yyvsp[0].Number;
1299
	}
1300
break;
1301
case 28:
1302
#line 228 "date.y"
1303
{
1304
		yyRelSeconds = -yyRelSeconds;
1305
		yyRelMonth = -yyRelMonth;
1306
	}
1307
break;
1308
case 30:
1309
#line 235 "date.y"
1310
{
1311
		yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
1312
	}
1313
break;
1314
case 31:
1315
#line 238 "date.y"
1316
{
1317
		yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
1318
	}
1319
break;
1320
case 32:
1321
#line 241 "date.y"
1322
{
1323
		yyRelSeconds += yyvsp[0].Number * 60L;
1324
	}
1325
break;
1326
case 33:
1327
#line 244 "date.y"
1328
{
1329
		yyRelSeconds += yyvsp[-1].Number;
1330
	}
1331
break;
1332
case 34:
1333
#line 247 "date.y"
1334
{
1335
		yyRelSeconds += yyvsp[-1].Number;
1336
	}
1337
break;
1338
case 35:
1339
#line 250 "date.y"
1340
{
1341
		yyRelSeconds++;
1342
	}
1343
break;
1344
case 36:
1345
#line 253 "date.y"
1346
{
1347
		yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1348
	}
1349
break;
1350
case 37:
1351
#line 256 "date.y"
1352
{
1353
		yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1354
	}
1355
break;
1356
case 38:
1357
#line 259 "date.y"
1358
{
1359
		yyRelMonth += yyvsp[0].Number;
1360
	}
1361
break;
1362
case 39:
1363
#line 264 "date.y"
1364
{
1365
		if (yyHaveTime && yyHaveDate && !yyHaveRel)
1366
			yyYear = yyvsp[0].Number;
1367
		else {
1368
			if (yyvsp[0].Number > 10000) {
1369
				yyHaveDate++;
1370
				yyDay= (yyvsp[0].Number)%100;
1371
				yyMonth= (yyvsp[0].Number/100)%100;
1372
				yyYear = yyvsp[0].Number/10000;
1373
			} else {
1374
				yyHaveTime++;
1375
				if (yyvsp[0].Number < 100) {
1376
					yyHour = yyvsp[0].Number;
1377
					yyMinutes = 0;
1378
				} else {
1379
					yyHour = yyvsp[0].Number / 100;
1380
					yyMinutes = yyvsp[0].Number % 100;
1381
				}
1382
				yySeconds = 0;
1383
				yyMeridian = MER24;
1384
			}
1385
		}
1386
	}
1387
break;
1388
case 40:
1389
#line 289 "date.y"
1390
{
1391
		yyval.Meridian = MER24;
1392
	}
1393
break;
1394
case 41:
1395
#line 292 "date.y"
1396
{
1397
		yyval.Meridian = yyvsp[0].Meridian;
1398
	}
1399
break;
1400
#line 1393 "date.c"
1401
    }
1402
    yyssp -= yym;
1403
    yystate = *yyssp;
1404
    yyvsp -= yym;
1405
    yym = yylhs[yyn];
1406
    if (yystate == 0 && yym == 0)
1407
    {
1408
#if YYDEBUG
1409
        if (yydebug)
1410
            printf("%sdebug: after reduction, shifting from state 0 to\
1411
 state %d\n", YYPREFIX, YYFINAL);
1412
#endif
1413
        yystate = YYFINAL;
1414
        *++yyssp = YYFINAL;
1415
        *++yyvsp = yyval;
1416
        if (yychar < 0)
1417
        {
1418
            if ((yychar = yylex()) < 0) yychar = 0;
1419
#if YYDEBUG
1420
            if (yydebug)
1421
            {
1422
                yys = 0;
1423
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1424
                if (!yys) yys = "illegal-symbol";
1425
                printf("%sdebug: state %d, reading %d (%s)\n",
1426
                        YYPREFIX, YYFINAL, yychar, yys);
1427
            }
1428
#endif
1429
        }
1430
        if (yychar == 0) goto yyaccept;
1431
        goto yyloop;
1432
    }
1433
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1434
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1435
        yystate = yytable[yyn];
1436
    else
1437
        yystate = yydgoto[yym];
1438
#if YYDEBUG
1439
    if (yydebug)
1440
        printf("%sdebug: after reduction, shifting from state %d \
1441
to state %d\n", YYPREFIX, *yyssp, yystate);
1442
#endif
1443
    if (yyssp >= yysslim && yygrowstack())
1444
    {
1445
        goto yyoverflow;
1446
    }
1447
    *++yyssp = yystate;
1448
    *++yyvsp = yyval;
1449
    goto yyloop;
1450
yyoverflow:
1451
    yyerror("yacc stack overflow");
1452
yyabort:
1453
    if (yyss)
1454
            free(yyss);
1455
    if (yyvs)
1456
            free(yyvs);
1457
    yyss = yyssp = NULL;
1458
    yyvs = yyvsp = NULL;
1459
    yystacksize = 0;
1460
    return (1);
1461
yyaccept:
1462
    if (yyss)
1463
            free(yyss);
1464
    if (yyvs)
1465
            free(yyvs);
1466
    yyss = yyssp = NULL;
1467
    yyvs = yyvsp = NULL;
1468
    yystacksize = 0;
1469
    return (0);
1470
}