0
|
1 %e 2000
|
|
2 %p 5000
|
|
3 %n 1000
|
|
4 %a 4000
|
|
5 %START Z
|
|
6 sun (sun(day)?)
|
|
7 mon (mon(day)?)
|
|
8 tue (tue(sday)?)
|
|
9 wed (wed(nesday)?)
|
|
10 thu (thu(rsday)?)
|
|
11 fri (fri(day)?)
|
|
12 sat (sat(urday)?)
|
|
13
|
|
14 DAY ({sun}|{mon}|{tue}|{wed}|{thu}|{fri}|{sat})
|
|
15
|
|
16 jan (jan(uary)?)
|
|
17 feb (feb(ruary)?)
|
|
18 mar (mar(ch)?)
|
|
19 apr (apr(il)?)
|
|
20 may (may)
|
|
21 jun (jun(e)?)
|
|
22 jul (jul(y)?)
|
|
23 aug (aug(ust)?)
|
|
24 sep (sep(tember)?)
|
|
25 oct (oct(ober)?)
|
|
26 nov (nov(ember)?)
|
|
27 dec (dec(ember)?)
|
|
28
|
|
29 MONTH ({jan}|{feb}|{mar}|{apr}|{may}|{jun}|{jul}|{aug}|{sep}|{oct}|{nov}|{dec})
|
|
30
|
|
31 w ([ \t]*)
|
|
32 W ([ \t]+)
|
|
33 D ([0-9]?[0-9])
|
|
34 d [0-9]
|
|
35 %{
|
|
36 #ifndef lint
|
12
|
37 static char ident[] = "@(#)$Id: dtimep.lex,v 1.1.1.1 2005/04/18 14:46:08 kono Exp $";
|
0
|
38 #endif
|
|
39 #include "tws.h"
|
|
40 #include "../h/strings.h"
|
|
41 #include <ctype.h>
|
|
42 #include <sys/types.h>
|
|
43 #if !defined(SYS5) && !defined(ZONEINFO)
|
|
44 #include <sys/timeb.h>
|
|
45 #endif /* !defined(SYS5) && !defined(ZONEINFO) */
|
|
46
|
|
47 #ifdef SYS5
|
|
48 extern int daylight;
|
|
49 extern long timezone;
|
|
50 extern char *tzname[];
|
|
51 #endif /* SYS5 */
|
|
52
|
|
53 /*
|
|
54 * Patchable flag that says how to interpret NN/NN/NN dates. When
|
|
55 * true, we do it European style: DD/MM/YY. When false, we do it
|
|
56 * American style: MM/DD/YY. Of course, these are all non-RFC822
|
|
57 * compliant.
|
|
58 */
|
|
59 int europeandate = 0;
|
|
60
|
|
61 /*
|
|
62 * Table to convert month names to numeric month. We use the
|
|
63 * fact that the low order 5 bits of the sum of the 2nd & 3rd
|
|
64 * characters of the name is a hash with no collisions for the 12
|
|
65 * valid month names. (The mask to 5 bits maps any combination of
|
|
66 * upper and lower case into the same hash value).
|
|
67 */
|
|
68 static int month_map[] = {
|
|
69 0,
|
|
70 6, /* 1 - Jul */
|
|
71 3, /* 2 - Apr */
|
|
72 5, /* 3 - Jun */
|
|
73 0,
|
|
74 10, /* 5 - Nov */
|
|
75 0,
|
|
76 1, /* 7 - Feb */
|
|
77 11, /* 8 - Dec */
|
|
78 0,
|
|
79 0,
|
|
80 0,
|
|
81 0,
|
|
82 0,
|
|
83 0,
|
|
84 0, /*15 - Jan */
|
|
85 0,
|
|
86 0,
|
|
87 0,
|
|
88 2, /*19 - Mar */
|
|
89 0,
|
|
90 8, /*21 - Sep */
|
|
91 0,
|
|
92 9, /*23 - Oct */
|
|
93 0,
|
|
94 0,
|
|
95 4, /*26 - May */
|
|
96 0,
|
|
97 7 /*28 - Aug */
|
|
98 };
|
|
99 /*
|
|
100 * Same trick for day-of-week using the hash function
|
|
101 * (c1 & 7) + (c2 & 4)
|
|
102 */
|
|
103 static int day_map[] = {
|
|
104 0,
|
|
105 0,
|
|
106 0,
|
|
107 6, /* 3 - Sat */
|
|
108 4, /* 4 - Thu */
|
|
109 0,
|
|
110 5, /* 6 - Fri */
|
|
111 0, /* 7 - Sun */
|
|
112 2, /* 8 - Tue */
|
|
113 1 /* 9 - Mon */,
|
|
114 0,
|
|
115 3 /*11 - Wed */
|
|
116 };
|
|
117 #define SETDAY { tw.tw_wday= day_map[(cp[0] & 7) + (cp[1] & 4)];\
|
|
118 tw.tw_flags &= ~TW_SDAY; tw.tw_flags |= TW_SEXP;\
|
|
119 cp += 2; }
|
|
120 #define SETMONTH { tw.tw_mon = month_map[(cp[0] + cp[1]) & 0x1f]; gotdate++;\
|
|
121 cp += 2;\
|
|
122 SKIPD;}
|
|
123 #define CVT1OR2 (i=(*cp++ - '0'), isdigit(*cp)? i*10 + (*cp++ - '0') : i)
|
|
124 #define CVT2 ((cp[0] - '0')*10 + (cp[1] - '0'))
|
|
125 #define CVT4 ((((cp[0] - '0')*10 + (cp[1] - '0'))*10 + \
|
|
126 (cp[2] - '0'))*10 + (cp[3] - '0'))
|
|
127 #define SKIPD { while ( !isdigit(*cp++) ) ; --cp; }
|
|
128 #define EXPZONE { tw.tw_flags &= ~TW_SZONE; tw.tw_flags |= TW_SZEXP; }
|
|
129 #define ZONE(x) { tw.tw_zone=(x); EXPZONE; }
|
|
130 #define ZONED(x) { ZONE(x); tw.tw_flags |= TW_DST; }
|
|
131 #define LC(c) (isupper (c) ? tolower (c) : (c))
|
|
132
|
|
133 #ifdef DSTXXX
|
|
134 #ifdef _AIX
|
|
135 #include <sys/time.h>
|
|
136 #include <time.h>
|
|
137 #else
|
|
138 #ifndef BSD42
|
|
139 #include <time.h>
|
|
140 #else /* BSD42 */
|
|
141 #include <sys/time.h>
|
|
142 #endif /* BSD42 */
|
|
143 #endif
|
|
144
|
17
|
145 static void zonehack (tw)
|
0
|
146 register struct tws *tw;
|
|
147 {
|
|
148 register struct tm *tm;
|
|
149
|
|
150 if (twclock (tw) == -1L)
|
|
151 return;
|
|
152
|
|
153 tm = localtime (&tw -> tw_clock);
|
|
154 if (tm -> tm_isdst) {
|
|
155 tw -> tw_flags |= TW_DST;
|
|
156 tw -> tw_zone -= 60;
|
|
157 }
|
|
158 }
|
|
159 #endif /* DSTXXX */
|
|
160 %}
|
|
161 %%
|
|
162 %{
|
|
163 struct tws *dparsetime (str)
|
|
164 char *str;
|
|
165 {
|
|
166 register int i;
|
|
167 static struct tws tw;
|
|
168 register char *cp;
|
|
169 register int gotdate = 0;
|
|
170 #ifdef ZONEINFO
|
|
171 struct tm *tm;
|
|
172 time_t clock;
|
|
173 #else
|
|
174 #ifndef SYS5
|
|
175 struct timeb tb;
|
|
176 #endif /* not SYS5 */
|
|
177 #endif /* ZONEINFO */
|
|
178 time_t tclock;
|
|
179
|
|
180 start_cond = 0;
|
|
181
|
|
182 /* Zero out the struct. */
|
|
183 bzero( (char *) &tw, sizeof tw);
|
|
184 tw.tw_year = -1;
|
|
185
|
|
186 /* Set default time zone. */
|
|
187 #ifdef ZONEINFO
|
|
188 time (&clock);
|
|
189 tm = localtime(&clock);
|
|
190 tw.tw_zone = tm->tm_gmtoff / 60;
|
|
191 if (tm -> tm_isdst) /* if DST is in effect */
|
|
192 tw.tw_zone -= 60; /* reset to normal offset */
|
|
193 #else
|
|
194 #ifdef SYS5
|
|
195 tzset( );
|
|
196 tw.tw_zone = -(timezone / 60);
|
|
197 #else
|
|
198 ftime( &tb );
|
|
199 tw.tw_zone = -tb.timezone;
|
|
200 #endif /* SYS5 */
|
|
201 #endif /* ZONEINFO */
|
|
202
|
|
203 while (isspace(*str))
|
|
204 str++;
|
|
205 while ( 1 )
|
|
206 switch (cp = str, *cp ? lex_string( &str, start_cond) : 0) {
|
|
207
|
|
208 case -1:
|
|
209 if (!gotdate || tw.tw_year == -1)
|
|
210 return (struct tws *)0;
|
|
211 /* fall through */
|
|
212 case 0:
|
|
213 if ( tw.tw_year == -1 ) {
|
|
214 /* Set default year. */
|
|
215 time (&tclock);
|
|
216 tw.tw_year = localtime(&tclock)->tm_year + 1900;
|
|
217 }
|
|
218 else if (tw.tw_year < 69) {
|
|
219 tw.tw_year += 2000;
|
|
220 }
|
|
221 else if (tw.tw_year < 100) {
|
|
222 tw.tw_year += 1900;
|
|
223 }
|
|
224 return &tw;
|
|
225
|
|
226 %}
|
|
227 {DAY}","?{w} SETDAY;
|
|
228 "("{DAY}")"(","?) {
|
|
229 cp++;
|
|
230 SETDAY;
|
|
231 }
|
|
232 {D}(("-"{D}"-")|("/"{D}"/")){D}?{d}{d}{w} {
|
|
233 if (europeandate) {
|
|
234 /* European: DD/MM/YY */
|
|
235 tw.tw_mday = CVT1OR2;
|
|
236 cp++;
|
|
237 tw.tw_mon = CVT1OR2 - 1;
|
|
238 } else {
|
|
239 /* American: MM/DD/YY */
|
|
240 tw.tw_mon = CVT1OR2 - 1;
|
|
241 cp++;
|
|
242 tw.tw_mday = CVT1OR2;
|
|
243 }
|
|
244 cp++;
|
|
245 for (i = 0; isdigit(*cp); )
|
|
246 i = i*10 + (*cp++ - '0');
|
|
247 tw.tw_year = i;
|
|
248 gotdate++; /* XXX */
|
|
249 }
|
|
250 {D}("/"|"-"){D}{w} {
|
|
251 if (europeandate) {
|
|
252 tw.tw_mday = CVT1OR2; cp++;
|
|
253 tw.tw_mon = CVT1OR2 - 1;
|
|
254 } else {
|
|
255 tw.tw_mon = CVT1OR2 - 1; cp++;
|
|
256 tw.tw_mday = CVT1OR2;
|
|
257 }
|
|
258 gotdate++;
|
|
259 }
|
|
260 {D}{w}(-)?{w}{MONTH}{w}(-)?{w}{D}?{d}{d}({W}at)?{w} {
|
|
261 tw.tw_mday = CVT1OR2;
|
|
262 while ( !isalpha(*cp++) )
|
|
263 ;
|
|
264 SETMONTH;
|
|
265 for (i = 0; isdigit(*cp); )
|
|
266 i = i*10 + (*cp++ - '0');
|
|
267 tw.tw_year = i;
|
|
268 }
|
|
269 {D}"-"?{MONTH}({W}at)?{w} {
|
|
270 tw.tw_mday = CVT1OR2;
|
|
271 while ( ! isalpha( *cp++ ) )
|
|
272 ;
|
|
273 SETMONTH;
|
|
274 }
|
|
275 {MONTH}{W}{D}","{W}{D}?{d}{d}{w} {
|
|
276 cp++;
|
|
277 SETMONTH;
|
|
278 tw.tw_mday = CVT1OR2;
|
|
279 SKIPD;
|
|
280 for (i = 0; isdigit(*cp); )
|
|
281 i = i*10 + (*cp++ - '0');
|
|
282 tw.tw_year = i;
|
|
283 }
|
|
284 {MONTH}{W}{D}{w} {
|
|
285 cp++;
|
|
286 SETMONTH;
|
|
287 tw.tw_mday = CVT1OR2;
|
|
288 }
|
|
289
|
|
290 {D}:{D}:{D}{W}19[6-9]{d} { /* hack: ctime w/o TZ */
|
|
291 tw.tw_hour = CVT1OR2; cp++;
|
|
292 tw.tw_min = CVT1OR2; cp++;
|
|
293 tw.tw_sec = CVT1OR2;
|
|
294 SKIPD;
|
|
295 tw.tw_year = CVT4; cp+=4;
|
|
296 }
|
|
297 {D}:{D}:{D}{w} {
|
|
298 tw.tw_hour = CVT1OR2; cp++;
|
|
299 tw.tw_min = CVT1OR2; cp++;
|
|
300 tw.tw_sec = CVT1OR2;
|
|
301 BEGIN Z;
|
|
302 }
|
|
303 {D}:{D}{w} {
|
|
304 tw.tw_hour = CVT1OR2; cp++;
|
|
305 tw.tw_min = CVT1OR2;
|
|
306 BEGIN Z;
|
|
307 }
|
|
308 {D}:{D}{w}am{w} {
|
|
309 tw.tw_hour = CVT1OR2; cp++;
|
|
310 if (tw.tw_hour == 12)
|
|
311 tw.tw_hour = 0;
|
|
312 tw.tw_min = CVT1OR2;
|
|
313 BEGIN Z;
|
|
314 }
|
|
315 {D}:{D}:{D}{w}am{w} {
|
|
316 tw.tw_hour = CVT1OR2; cp++;
|
|
317 if (tw.tw_hour == 12)
|
|
318 tw.tw_hour = 0;
|
|
319 tw.tw_min = CVT1OR2; cp++;
|
|
320 tw.tw_sec = CVT1OR2;
|
|
321 BEGIN Z;
|
|
322 }
|
|
323 {D}:{D}{w}pm{w} {
|
|
324 tw.tw_hour = CVT1OR2; cp++;
|
|
325 if (tw.tw_hour != 12)
|
|
326 tw.tw_hour += 12;
|
|
327 tw.tw_min = CVT1OR2;
|
|
328 BEGIN Z;
|
|
329 }
|
|
330 {D}:{D}:{D}{w}pm{w} {
|
|
331 tw.tw_hour = CVT1OR2; cp++;
|
|
332 if (tw.tw_hour != 12)
|
|
333 tw.tw_hour += 12;
|
|
334 tw.tw_min = CVT1OR2; cp++;
|
|
335 tw.tw_sec = CVT1OR2;
|
|
336 BEGIN Z;
|
|
337 }
|
|
338 [0-2]{d}{d}{d}{d}{d}{w} {
|
|
339 tw.tw_hour = CVT2; cp+=2;
|
|
340 tw.tw_min = CVT2; cp+=2;
|
|
341 tw.tw_sec = CVT2; cp+=2;
|
|
342 BEGIN Z;
|
|
343 }
|
|
344 19[6-9]{d}{w} {
|
|
345 /*
|
|
346 * Luckly, 4 digit times in the range
|
|
347 * 1960-1999 aren't legal as hour
|
|
348 * and minutes.
|
|
349 */
|
|
350 tw.tw_year = CVT4; cp+=4;
|
|
351 }
|
|
352 [0-2]{d}{d}{d}{w} {
|
|
353 if (tw.tw_hour || tw.tw_min
|
|
354 || tw.tw_sec) {
|
|
355 tw.tw_year = CVT4; cp+=4;
|
|
356 tw.tw_zone = 0;
|
|
357 } else {
|
|
358 tw.tw_hour = CVT2; cp+=2;
|
|
359 tw.tw_min = CVT2; cp+=2;
|
|
360 BEGIN Z;
|
|
361 }
|
|
362 }
|
|
363 <Z>"-"?ut ZONE(0 * 60);
|
|
364 <Z>"-"?gmt ZONE(0 * 60);
|
|
365 <Z>"-"?jst {
|
|
366 #ifdef JAPAN
|
|
367 ZONE(9 * 60);
|
|
368 #else /* JAPAN */
|
|
369 ZONE(2 * 60);
|
|
370 #endif /* JAPAN */
|
|
371 }
|
|
372 <Z>"-"?jdt ZONED(2 * 60);
|
|
373 <Z>"-"?est ZONE(-5 * 60);
|
|
374 <Z>"-"?edt ZONED(-5 * 60);
|
|
375 <Z>"-"?cst ZONE(-6 * 60);
|
|
376 <Z>"-"?cdt ZONED(-6 * 60);
|
|
377 <Z>"-"?mst ZONE(-7 * 60);
|
|
378 <Z>"-"?mdt ZONED(-7 * 60);
|
|
379 <Z>"-"?pst ZONE(-8 * 60);
|
|
380 <Z>"-"?pdt ZONED(-8 * 60);
|
|
381 <Z>"-"?nst ZONE(-(3 * 60 + 30));
|
|
382 <Z>"-"?ast ZONE(-4 * 60);
|
|
383 <Z>"-"?adt ZONED(-4 * 60);
|
|
384 <Z>"-"?yst ZONE(-9 * 60);
|
|
385 <Z>"-"?ydt ZONED(-9 * 60);
|
|
386 <Z>"-"?hst ZONE(-10 * 60);
|
|
387 <Z>"-"?hdt ZONED(-10 * 60);
|
|
388 <Z>"-"?bst ZONED(-1 * 60);
|
|
389 <Z>[a-i] {
|
|
390 tw.tw_zone = 60 * (('a'-1) - LC(*cp));
|
|
391 EXPZONE;
|
|
392 }
|
|
393 <Z>[k-m] {
|
|
394 tw.tw_zone = 60 * ('a' - LC(*cp));
|
|
395 EXPZONE;
|
|
396 }
|
|
397 <Z>[n-y] {
|
|
398 tw.tw_zone = 60 * (LC(*cp) - 'm');
|
|
399 EXPZONE;
|
|
400 }
|
|
401 <Z>"+"[0-1]{d}{d}{d} {
|
|
402 cp++;
|
|
403 tw.tw_zone = ((cp[0] * 10 + cp[1])
|
|
404 -('0' * 10 + '0'))*60
|
|
405 +((cp[2] * 10 + cp[3])
|
|
406 -('0' * 10 + '0'));
|
|
407 EXPZONE;
|
|
408 #ifdef DSTXXX
|
|
409 zonehack (&tw);
|
|
410 #endif /* DSTXXX */
|
|
411 cp += 4;
|
|
412 }
|
|
413 <Z>"-"[0-1]{d}{d}{d} {
|
|
414 cp++;
|
|
415 tw.tw_zone = (('0' * 10 + '0')
|
|
416 -(cp[0] * 10 + cp[1]))*60
|
|
417 +(('0' * 10 + '0')
|
|
418 -(cp[2] * 10 + cp[3]));
|
|
419 EXPZONE;
|
|
420 #ifdef DSTXXX
|
|
421 zonehack (&tw);
|
|
422 #endif /* DSTXXX */
|
|
423 cp += 4;
|
|
424 }
|
|
425 <Z>{W}{d}{d}{d}{d} {
|
|
426 SKIPD;
|
|
427 tw.tw_year = CVT4; cp+=4;
|
|
428 }
|
|
429 \n |
|
|
430 {W} ;
|
|
431 %%
|