]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/zotnet/tws/dtimep.lex
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / docs / historical / mh-6.8.5 / zotnet / tws / dtimep.lex
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
37 static char ident[] = "@(#)$Id: dtimep.lex,v 2.15 1993/02/26 22:07:40 jromine Exp $";
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
145 static zonehack (tw)
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 #ifndef SYS5
171 #ifdef ZONEINFO
172 struct tm *tm;
173 time_t clock;
174 #else
175 struct timeb tb;
176 #endif /* ZONEINFO */
177 #endif /* not SYS5 */
178 long tclock;
179
180 start_cond = 0;
181
182 /* Zero out the struct. */
183 bzero( (char *) &tw, sizeof tw);
184
185 /* Set default time zone. */
186 #ifdef SYS5
187 tzset( );
188 tw.tw_zone = -(timezone / 60);
189 #else
190 #ifdef ZONEINFO
191 time (&clock);
192 tm = localtime(&clock);
193 tw.tw_zone = tm->tm_gmtoff / 60;
194 if (tm -> tm_isdst) /* if DST is in effect */
195 tw.tw_zone -= 60; /* reset to normal offset */
196 #else
197 ftime( &tb );
198 tw.tw_zone = -tb.timezone;
199 #endif /* ZONEINFO */
200 #endif /* SYS5 */
201
202 while (isspace(*str))
203 str++;
204 while ( 1 )
205 switch (cp = str, *cp ? lex_string( &str, start_cond) : 0) {
206
207 case -1:
208 if (!gotdate || tw.tw_year == 0)
209 return (struct tws *)0;
210 /* fall through */
211 case 0:
212 if ( tw.tw_year == 0 ) {
213 /* Set default year. */
214 time (&tclock);
215 tw.tw_year = localtime(&tclock)->tm_year + 1900;
216 }
217 else if (tw.tw_year < 100) {
218 /* assume no 2-digit years > 1999 */
219 tw.tw_year += 1900;
220 }
221 return &tw;
222
223 %}
224 {DAY}","?{w} SETDAY;
225 "("{DAY}")"(","?) {
226 cp++;
227 SETDAY;
228 }
229 {D}(("-"{D}"-")|("/"{D}"/")){D}?{d}{d}{w} {
230 if (europeandate) {
231 /* European: DD/MM/YY */
232 tw.tw_mday = CVT1OR2;
233 cp++;
234 tw.tw_mon = CVT1OR2 - 1;
235 } else {
236 /* American: MM/DD/YY */
237 tw.tw_mon = CVT1OR2 - 1;
238 cp++;
239 tw.tw_mday = CVT1OR2;
240 }
241 cp++;
242 for (i = 0; isdigit(*cp); )
243 i = i*10 + (*cp++ - '0');
244 tw.tw_year = i;
245 gotdate++; /* XXX */
246 }
247 {D}("/"|"-"){D}{w} {
248 if (europeandate) {
249 tw.tw_mday = CVT1OR2; cp++;
250 tw.tw_mon = CVT1OR2 - 1;
251 } else {
252 tw.tw_mon = CVT1OR2 - 1; cp++;
253 tw.tw_mday = CVT1OR2;
254 }
255 gotdate++;
256 }
257 {D}{w}(-)?{w}{MONTH}{w}(-)?{w}{D}?{d}{d}({W}at)?{w} {
258 tw.tw_mday = CVT1OR2;
259 while ( !isalpha(*cp++) )
260 ;
261 SETMONTH;
262 for (i = 0; isdigit(*cp); )
263 i = i*10 + (*cp++ - '0');
264 tw.tw_year = i;
265 }
266 {D}"-"?{MONTH}({W}at)?{w} {
267 tw.tw_mday = CVT1OR2;
268 while ( ! isalpha( *cp++ ) )
269 ;
270 SETMONTH;
271 }
272 {MONTH}{W}{D}","{W}{D}?{d}{d}{w} {
273 cp++;
274 SETMONTH;
275 tw.tw_mday = CVT1OR2;
276 SKIPD;
277 for (i = 0; isdigit(*cp); )
278 i = i*10 + (*cp++ - '0');
279 tw.tw_year = i;
280 }
281 {MONTH}{W}{D}{w} {
282 cp++;
283 SETMONTH;
284 tw.tw_mday = CVT1OR2;
285 }
286
287 {D}:{D}:{D}{W}19[6-9]{d} { /* hack: ctime w/o TZ */
288 tw.tw_hour = CVT1OR2; cp++;
289 tw.tw_min = CVT1OR2; cp++;
290 tw.tw_sec = CVT1OR2;
291 SKIPD;
292 tw.tw_year = CVT4; cp+=4;
293 }
294 {D}:{D}:{D}{w} {
295 tw.tw_hour = CVT1OR2; cp++;
296 tw.tw_min = CVT1OR2; cp++;
297 tw.tw_sec = CVT1OR2;
298 BEGIN Z;
299 }
300 {D}:{D}{w} {
301 tw.tw_hour = CVT1OR2; cp++;
302 tw.tw_min = CVT1OR2;
303 BEGIN Z;
304 }
305 {D}:{D}{w}am{w} {
306 tw.tw_hour = CVT1OR2; cp++;
307 if (tw.tw_hour == 12)
308 tw.tw_hour = 0;
309 tw.tw_min = CVT1OR2;
310 BEGIN Z;
311 }
312 {D}:{D}:{D}{w}am{w} {
313 tw.tw_hour = CVT1OR2; cp++;
314 if (tw.tw_hour == 12)
315 tw.tw_hour = 0;
316 tw.tw_min = CVT1OR2; cp++;
317 tw.tw_sec = CVT1OR2;
318 BEGIN Z;
319 }
320 {D}:{D}{w}pm{w} {
321 tw.tw_hour = CVT1OR2; cp++;
322 if (tw.tw_hour != 12)
323 tw.tw_hour += 12;
324 tw.tw_min = CVT1OR2;
325 BEGIN Z;
326 }
327 {D}:{D}:{D}{w}pm{w} {
328 tw.tw_hour = CVT1OR2; cp++;
329 if (tw.tw_hour != 12)
330 tw.tw_hour += 12;
331 tw.tw_min = CVT1OR2; cp++;
332 tw.tw_sec = CVT1OR2;
333 BEGIN Z;
334 }
335 [0-2]{d}{d}{d}{d}{d}{w} {
336 tw.tw_hour = CVT2; cp+=2;
337 tw.tw_min = CVT2; cp+=2;
338 tw.tw_sec = CVT2; cp+=2;
339 BEGIN Z;
340 }
341 19[6-9]{d}{w} {
342 /*
343 * Luckly, 4 digit times in the range
344 * 1960-1999 aren't legal as hour
345 * and minutes.
346 */
347 tw.tw_year = CVT4; cp+=4;
348 }
349 [0-2]{d}{d}{d}{w} {
350 if (tw.tw_hour || tw.tw_min
351 || tw.tw_sec) {
352 tw.tw_year = CVT4; cp+=4;
353 tw.tw_zone = 0;
354 } else {
355 tw.tw_hour = CVT2; cp+=2;
356 tw.tw_min = CVT2; cp+=2;
357 BEGIN Z;
358 }
359 }
360 <Z>"-"?ut ZONE(0 * 60);
361 <Z>"-"?gmt ZONE(0 * 60);
362 <Z>"-"?jst ZONE(2 * 60);
363 <Z>"-"?jdt ZONED(2 * 60);
364 <Z>"-"?est ZONE(-5 * 60);
365 <Z>"-"?edt ZONED(-5 * 60);
366 <Z>"-"?cst ZONE(-6 * 60);
367 <Z>"-"?cdt ZONED(-6 * 60);
368 <Z>"-"?mst ZONE(-7 * 60);
369 <Z>"-"?mdt ZONED(-7 * 60);
370 <Z>"-"?pst ZONE(-8 * 60);
371 <Z>"-"?pdt ZONED(-8 * 60);
372 <Z>"-"?nst ZONE(-(3 * 60 + 30));
373 <Z>"-"?ast ZONE(-4 * 60);
374 <Z>"-"?adt ZONED(-4 * 60);
375 <Z>"-"?yst ZONE(-9 * 60);
376 <Z>"-"?ydt ZONED(-9 * 60);
377 <Z>"-"?hst ZONE(-10 * 60);
378 <Z>"-"?hdt ZONED(-10 * 60);
379 <Z>"-"?bst ZONED(-1 * 60);
380 <Z>[a-i] {
381 tw.tw_zone = 60 * (('a'-1) - LC(*cp));
382 EXPZONE;
383 }
384 <Z>[k-m] {
385 tw.tw_zone = 60 * ('a' - LC(*cp));
386 EXPZONE;
387 }
388 <Z>[n-y] {
389 tw.tw_zone = 60 * (LC(*cp) - 'm');
390 EXPZONE;
391 }
392 <Z>"+"[0-1]{d}{d}{d} {
393 cp++;
394 tw.tw_zone = ((cp[0] * 10 + cp[1])
395 -('0' * 10 + '0'))*60
396 +((cp[2] * 10 + cp[3])
397 -('0' * 10 + '0'));
398 EXPZONE;
399 #ifdef DSTXXX
400 zonehack (&tw);
401 #endif /* DSTXXX */
402 cp += 4;
403 }
404 <Z>"-"[0-1]{d}{d}{d} {
405 cp++;
406 tw.tw_zone = (('0' * 10 + '0')
407 -(cp[0] * 10 + cp[1]))*60
408 +(('0' * 10 + '0')
409 -(cp[2] * 10 + cp[3]));
410 EXPZONE;
411 #ifdef DSTXXX
412 zonehack (&tw);
413 #endif /* DSTXXX */
414 cp += 4;
415 }
416 <Z>{W}{d}{d}{d}{d} {
417 SKIPD;
418 tw.tw_year = CVT4; cp+=4;
419 }
420 \n |
421 {W} ;
422 %%