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