xref: /illumos-gate/usr/src/cmd/cron/att1.y (revision cdd3e9a818787b4def17c9f707f435885ce0ed31)
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 
30 #include "stdio.h"
31 #include "ctype.h"
32 #include "time.h"
33 
34 extern int yylex(void);
35 extern int yyerror(const char *);
36 extern void atabort(char *);
37 int yyparse(void);
38 extern	int	gmtflag;
39 extern	int	mday[];
40 extern	struct	tm *tp, at, rt;
41 %}
42 %token	TIME
43 %token	NOW
44 %token	NOON
45 %token	MIDNIGHT
46 %token	MINUTE
47 %token	HOUR
48 %token	DAY
49 %token	WEEK
50 %token	MONTH
51 %token	YEAR
52 %token	UNIT
53 %token	SUFF
54 %token	ZONE
55 %token	AM
56 %token	PM
57 %token	ZULU
58 %token	NEXT
59 %token	NUMB
60 %token	COLON
61 %token	COMMA
62 %token	PLUS
63 %token	UNKNOWN
64 %right	NUMB
65 %%
66 
67 args
68 	: time ampm timezone date incr {
69 		if (at.tm_min >= 60 || at.tm_hour >= 24)
70 			atabort("bad time");
71 		if (at.tm_mon >= 12 || at.tm_mday > mday[at.tm_mon])
72 			atabort("bad date");
73 		if (at.tm_year >= 1900)
74 			at.tm_year -= 1900;
75 		if (at.tm_year < 70 || at.tm_year >= 139)
76 			atabort("bad year");
77 	}
78 	| time ampm timezone date incr UNKNOWN {
79 		(void) yyerror("bad time specification");
80 	}
81 	;
82 
83 time
84 	: hour {
85 		at.tm_hour = $1;
86 	}
87 	| hour COLON number {
88 		at.tm_hour = $1;
89 		at.tm_min = $3;
90 		$3 = $1;
91 	}
92 	| hour minute {
93 		at.tm_hour = $1;
94 		at.tm_min = $2;
95 		$2 = $1;
96 	}
97 	| TIME {
98 		switch ($1) {
99 		case NOON:
100 			at.tm_hour = 12;
101 			break;
102 		case MIDNIGHT:
103 			at.tm_hour = 0;
104 			break;
105 		case NOW:
106 			at.tm_hour = tp->tm_hour;
107 			at.tm_min = tp->tm_min;
108 			at.tm_sec = tp->tm_sec;
109 			break;
110 		}
111 	}
112 	;
113 
114 ampm
115 	: /*empty*/
116 	{
117 	}
118 	| SUFF {
119 		switch ($1) {
120 		case PM:
121 			if (at.tm_hour < 1 || at.tm_hour > 12)
122 				atabort("bad hour");
123 				at.tm_hour %= 12;
124 				at.tm_hour += 12;
125 				break;
126 		case AM:
127 			if (at.tm_hour < 1 || at.tm_hour > 12)
128 				atabort("bad hour");
129 			at.tm_hour %= 12;
130 			break;
131 		}
132 	}
133 	;
134 
135 timezone
136 	: /*empty*/
137 	{
138 	}
139 	| ZONE {
140 		if (at.tm_hour == 24 && at.tm_min != 0)
141 			atabort("bad time");
142 		at.tm_hour %= 24;
143 		gmtflag = 1;
144 	}
145 	;
146 
147 date
148 	: /*empty*/ {
149 		at.tm_mday = tp->tm_mday;
150 		at.tm_mon = tp->tm_mon;
151 		at.tm_year = tp->tm_year;
152 		if ((at.tm_hour < tp->tm_hour)
153 			|| ((at.tm_hour==tp->tm_hour)&&(at.tm_min<tp->tm_min)))
154 			rt.tm_mday++;
155 	}
156 	| MONTH number {
157 		at.tm_mon = $1;
158 		at.tm_mday = $2;
159 		at.tm_year = tp->tm_year;
160 		if (at.tm_mon < tp->tm_mon)
161 			at.tm_year++;
162 	}
163 	| MONTH number COMMA number {
164 		at.tm_mon = $1;
165 		at.tm_mday = $2;
166 		at.tm_year = $4;
167 	}
168 	| DAY {
169 		at.tm_mon = tp->tm_mon;
170 		at.tm_mday = tp->tm_mday;
171 		at.tm_year = tp->tm_year;
172 		if ($1 < 7) {
173 			rt.tm_mday = $1 - tp->tm_wday;
174 			if (rt.tm_mday < 0)
175 				rt.tm_mday += 7;
176 		} else if ($1 == 8)
177 			rt.tm_mday += 1;
178 	}
179 	;
180 
181 incr
182 	: /*empty*/
183 	| NEXT UNIT	{ addincr:
184 		switch ($2) {
185 		case MINUTE:
186 			rt.tm_min += $1;
187 			break;
188 		case HOUR:
189 			rt.tm_hour += $1;
190 			break;
191 		case DAY:
192 			rt.tm_mday += $1;
193 			break;
194 		case WEEK:
195 			rt.tm_mday += $1 * 7;
196 			break;
197 		case MONTH:
198 			rt.tm_mon += $1;
199 			break;
200 		case YEAR:
201 			rt.tm_year += $1;
202 			break;
203 		}
204 	}
205 	| PLUS opt_number UNIT { goto addincr; }
206 	;
207 
208 hour
209 	: NUMB		{ $$ = $1; }
210 	| NUMB NUMB	{ $$ = 10 * $1 + $2; }
211 	;
212 minute
213 	: NUMB NUMB	{ $$ = 10 * $1 + $2; }
214 	;
215 number
216 	: NUMB		{ $$ = $1; }
217 	| number NUMB	{ $$ = 10 * $1 + $2; }
218 	;
219 opt_number
220 	: /* empty */	{ $$ = 1; }
221 	| number	{ $$ = $1; }
222 	;
223 
224 %%
225