Added all of the MH sources, including RCS files, in
[mmh] / 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 %%