xref: /illumos-gate/usr/src/cmd/cron/att1.y (revision 75eba5b6d79ed4d2ce3daf7b2806306b6b69a938)
1 %{
2 /*
3  * CDDL HEADER START
4  *
5  * The contents of this file are subject to the terms of the
6  * Common Development and Distribution License, Version 1.0 only
7  * (the "License").  You may not use this file except in compliance
8  * with the License.
9  *
10  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11  * or http://www.opensolaris.org/os/licensing.
12  * See the License for the specific language governing permissions
13  * and limitations under the License.
14  *
15  * When distributing Covered Code, include this CDDL HEADER in each
16  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17  * If applicable, add the following below this CDDL HEADER, with the
18  * fields enclosed by brackets "[]" replaced with your own identifying
19  * information: Portions Copyright [yyyy] [name of copyright owner]
20  *
21  * CDDL HEADER END
22  */
23 %}
24 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
25 /*	  All Rights Reserved  	*/
26 
27 
28 %{
29 #ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.4	*/
30 %}
31 %{
32 
33 #include "stdio.h"
34 #include "ctype.h"
35 #include "time.h"
36 
37 extern int yylex(void);
38 extern void yyerror();
39 extern void atabort(char *);
40 int yyparse(void);
41 extern	int	gmtflag;
42 extern	int	mday[];
43 extern	struct	tm *tp, at, rt;
44 %}
45 %token	TIME
46 %token	NOW
47 %token	NOON
48 %token	MIDNIGHT
49 %token	MINUTE
50 %token	HOUR
51 %token	DAY
52 %token	WEEK
53 %token	MONTH
54 %token	YEAR
55 %token	UNIT
56 %token	SUFF
57 %token	ZONE
58 %token	AM
59 %token	PM
60 %token	ZULU
61 %token	NEXT
62 %token	NUMB
63 %token	COLON
64 %token	COMMA
65 %token	PLUS
66 %token	UNKNOWN
67 %right	NUMB
68 %%
69 
70 args
71 	: time ampm timezone date incr {
72 		if (at.tm_min >= 60 || at.tm_hour >= 24)
73 			atabort("bad time");
74 		if (at.tm_mon >= 12 || at.tm_mday > mday[at.tm_mon])
75 			atabort("bad date");
76 		if (at.tm_year >= 1900)
77 			at.tm_year -= 1900;
78 		if (at.tm_year < 70 || at.tm_year >= 139)
79 			atabort("bad year");
80 	}
81 	| time ampm timezone date incr UNKNOWN {
82 		yyerror();
83 	}
84 	;
85 
86 time
87 	: hour {
88 		at.tm_hour = $1;
89 	}
90 	| hour COLON number {
91 		at.tm_hour = $1;
92 		at.tm_min = $3;
93 		$3 = $1;
94 	}
95 	| hour minute {
96 		at.tm_hour = $1;
97 		at.tm_min = $2;
98 		$2 = $1;
99 	}
100 	| TIME {
101 		switch ($1) {
102 		case NOON:
103 			at.tm_hour = 12;
104 			break;
105 		case MIDNIGHT:
106 			at.tm_hour = 0;
107 			break;
108 		case NOW:
109 			at.tm_hour = tp->tm_hour;
110 			at.tm_min = tp->tm_min;
111 			at.tm_sec = tp->tm_sec;
112 			break;
113 		}
114 	}
115 	;
116 
117 ampm
118 	: /*empty*/
119 	{
120 	}
121 	| SUFF {
122 		switch ($1) {
123 		case PM:
124 			if (at.tm_hour < 1 || at.tm_hour > 12)
125 				atabort("bad hour");
126 				at.tm_hour %= 12;
127 				at.tm_hour += 12;
128 				break;
129 		case AM:
130 			if (at.tm_hour < 1 || at.tm_hour > 12)
131 				atabort("bad hour");
132 			at.tm_hour %= 12;
133 			break;
134 		}
135 	}
136 	;
137 
138 timezone
139 	: /*empty*/
140 	{
141 	}
142 	| ZONE {
143 		if (at.tm_hour == 24 && at.tm_min != 0)
144 			atabort("bad time");
145 		at.tm_hour %= 24;
146 		gmtflag = 1;
147 	}
148 	;
149 
150 date
151 	: /*empty*/ {
152 		at.tm_mday = tp->tm_mday;
153 		at.tm_mon = tp->tm_mon;
154 		at.tm_year = tp->tm_year;
155 		if ((at.tm_hour < tp->tm_hour)
156 			|| ((at.tm_hour==tp->tm_hour)&&(at.tm_min<tp->tm_min)))
157 			rt.tm_mday++;
158 	}
159 	| MONTH number {
160 		at.tm_mon = $1;
161 		at.tm_mday = $2;
162 		at.tm_year = tp->tm_year;
163 		if (at.tm_mon < tp->tm_mon)
164 			at.tm_year++;
165 	}
166 	| MONTH number COMMA number {
167 		at.tm_mon = $1;
168 		at.tm_mday = $2;
169 		at.tm_year = $4;
170 	}
171 	| DAY {
172 		at.tm_mon = tp->tm_mon;
173 		at.tm_mday = tp->tm_mday;
174 		at.tm_year = tp->tm_year;
175 		if ($1 < 7) {
176 			rt.tm_mday = $1 - tp->tm_wday;
177 			if (rt.tm_mday < 0)
178 				rt.tm_mday += 7;
179 		} else if ($1 == 8)
180 			rt.tm_mday += 1;
181 	}
182 	;
183 
184 incr
185 	: /*empty*/
186 	| NEXT UNIT	{ addincr:
187 		switch ($2) {
188 		case MINUTE:
189 			rt.tm_min += $1;
190 			break;
191 		case HOUR:
192 			rt.tm_hour += $1;
193 			break;
194 		case DAY:
195 			rt.tm_mday += $1;
196 			break;
197 		case WEEK:
198 			rt.tm_mday += $1 * 7;
199 			break;
200 		case MONTH:
201 			rt.tm_mon += $1;
202 			break;
203 		case YEAR:
204 			rt.tm_year += $1;
205 			break;
206 		}
207 	}
208 	| PLUS opt_number UNIT { goto addincr; }
209 	;
210 
211 hour
212 	: NUMB		{ $$ = $1; }
213 	| NUMB NUMB	{ $$ = 10 * $1 + $2; }
214 	;
215 minute
216 	: NUMB NUMB	{ $$ = 10 * $1 + $2; }
217 	;
218 number
219 	: NUMB		{ $$ = $1; }
220 	| number NUMB	{ $$ = 10 * $1 + $2; }
221 	;
222 opt_number
223 	: /* empty */	{ $$ = 1; }
224 	| number	{ $$ = $1; }
225 	;
226 
227 %%
228