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