Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / zotnet / tws / phoon / 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 /* dtimep.lex - routines to do ``ARPA-style'' time parsing
37
38 ver  date   who remarks
39 --- ------- --- -------------------------------------------------------------
40 01B 15nov86 JP  Thouroughly hacked by Jef Poskanzer.
41 01A ??????? MTR Original version from the MH 6.5 distribution, courtesy
42                   of Marshall Rose.
43
44 */
45
46 #include "tws.h"
47 #include <ctype.h>
48 #include <sys/types.h>
49 #include <sys/time.h>
50 #ifdef SYS5
51 #include <string.h>
52 #else SYS5
53 #include <strings.h>
54 #include <sys/timeb.h>
55 #endif SYS5
56
57 #ifdef SYS5
58 extern int  daylight;
59 extern long timezone;
60 extern char *tzname[];
61 #endif SYS5
62
63 /*
64  * Table to convert month names to numeric month.  We use the
65  * fact that the low order 5 bits of the sum of the 2nd & 3rd
66  * characters of the name is a hash with no collisions for the 12
67  * valid month names.  (The mask to 5 bits maps any combination of
68  * upper and lower case into the same hash value).
69  */
70 static int month_map[] = {
71         0,
72         6,      /* 1 - Jul */
73         3,      /* 2 - Apr */
74         5,      /* 3 - Jun */
75         0,
76         10,     /* 5 - Nov */
77         0,
78         1,      /* 7 - Feb */
79         11,     /* 8 - Dec */
80         0,
81         0,
82         0,
83         0,
84         0,
85         0,
86         0,      /*15 - Jan */
87         0,
88         0,
89         0,
90         2,      /*19 - Mar */
91         0,
92         8,      /*21 - Sep */
93         0,
94         9,      /*23 - Oct */
95         0,
96         0,
97         4,      /*26 - May */
98         0,
99         7 };    /*28 - Aug */
100 /*
101  * Same trick for day-of-week using the hash function
102  *  (c1 & 7) + (c2 & 4)
103  */
104 static int day_map[] = {
105         0,
106         0,
107         0,
108         6,      /* 3 - Sat */
109         4,      /* 4 - Thu */
110         0,
111         5,      /* 6 - Fri */
112         0,      /* 7 - Sun */
113         2,      /* 8 - Tue */
114         1       /* 9 - Mon */,
115         0,
116         3 };    /*11 - Wed */
117 #define SETDAY tw.tw_wday= day_map[(cp[0] & 7) + (cp[1] & 4)];\
118                 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')*10 + (*cp++ - '0') )
125 #define CVT3 ( ( (*cp++ - '0')*10 + (*cp++ - '0') )*10 + (*cp++ - '0') )
126 #define CVT4 ( ( ( (*cp++ - '0')*10 + (*cp++ - '0') )*10 + (*cp++ - '0') )*10 + (*cp++ - '0') )
127 #define SKIPD while ( ! isdigit( *cp++ ) ) ; --cp;
128 #define ZONE(x) tw.tw_zone=(x);
129 #define ZONED(x) tw.tw_zone=(x); tw.tw_flags |= TW_DST;
130 #define LC(c) (isupper( c ) ? tolower( c ) : ( c ))
131 %}
132 %%
133 %{
134 struct tws *
135 dparsetime( str )
136 char *str;
137     {
138     register int i;
139     static struct tws tw;
140     register char *cp;
141     register int gotdate = 0;
142 #ifndef SYS5
143     struct timeb        tb;
144 #endif not SYS5
145     long clock;
146
147     start_cond = 0;
148
149     /* Zero out the struct. */
150     bzero( (char *) &tw, sizeof tw );
151
152     /* Set default time zone. */
153 #ifndef SYS5
154     ftime( &tb );
155     tw.tw_zone = -tb.timezone;
156 #else SYS5
157     tzset( );
158     tw.tw_zone = -(timezone / 60);
159 #endif SYS5
160
161     for ( ; ; )
162         switch ( cp = str, lex_string( &str, start_cond ) )
163             {
164             case -1:
165                 if ( ! gotdate )
166                         return ( NULL );
167                 tw.tw_flags |= TW_JUNK;
168                 /* fall through */
169             case 0:
170                 if ( tw.tw_year == 0 )
171                     {
172                     /* Set default year. */
173                     time( &clock );
174                     tw.tw_year = localtime( &clock ) -> tm_year;
175                     }
176                 return ( &tw );
177
178 %}
179 {DAY}","?{w}                            SETDAY;
180 "("{DAY}")"(","?)                       cp++, SETDAY;
181
182 {D}"/"{D}"/"{D}?{d}{d}{w}               {
183 #ifdef EUROPE
184                                         tw.tw_mday = CVT1OR2; cp++;
185                                         tw.tw_mon  = CVT1OR2 - 1; cp++;
186 #else EUROPE
187                                         tw.tw_mon = CVT1OR2 - 1; cp++;
188                                         tw.tw_mday  = CVT1OR2; cp++;
189 #endif EUROPE
190                                         for ( i = 0; isdigit( *cp ); )
191                                                 i = i * 10 + (*cp++ - '0');
192                                         tw.tw_year = i;
193                                         gotdate++;
194                                         }
195 {D}"/"{D}{w}                            {
196 #ifdef EUROPE
197                                         tw.tw_mday = CVT1OR2; cp++;
198                                         tw.tw_mon  = CVT1OR2 - 1;
199 #else EUROPE
200                                         tw.tw_mon = CVT1OR2 - 1; cp++;
201                                         tw.tw_mday  = CVT1OR2;
202 #endif EUROPE
203                                         gotdate++;
204                                         }
205 {D}"-"?{MONTH}"-"?{D}?{d}{d}({W}at)?{w} |
206 {D}" "{MONTH}" "{D}?{d}{d}({W}at)?{w}   {
207                                         tw.tw_mday = CVT1OR2;
208                                         while ( ! isalpha( *cp++ ) )
209                                                 ;
210                                         SETMONTH;
211                                         for ( i = 0; isdigit( *cp ); )
212                                                 i = i * 10 + (*cp++ - '0');
213                                         tw.tw_year = i;
214                                         gotdate++;
215                                         }
216 {D}"-"?{MONTH}({W}at)?{w}               {
217                                         tw.tw_mday = CVT1OR2;
218                                         while ( ! isalpha( *cp++ ) )
219                                                 ;
220                                         SETMONTH;
221                                         gotdate++;
222                                         }
223 {MONTH}{W}{D}","{W}{D}?{d}{d}{w}        {
224                                         cp++;
225                                         SETMONTH;
226                                         tw.tw_mday = CVT1OR2;
227                                         SKIPD;
228                                         for ( i = 0; isdigit( *cp ); )
229                                                 i = i * 10 + (*cp++ - '0');
230                                         tw.tw_year = i;
231                                         gotdate++;
232                                         }
233 {MONTH}{W}{D}{w}                        {
234                                         cp++;
235                                         SETMONTH;
236                                         tw.tw_mday = CVT1OR2;
237                                         gotdate++;
238                                         }
239
240 {D}:{D}:{D}({w}am)?{w}                  {
241                                         tw.tw_hour = CVT1OR2; cp++;
242                                         tw.tw_min  = CVT1OR2; cp++;
243                                         tw.tw_sec  = CVT1OR2;
244                                         BEGIN Z;
245                                         }
246 {D}:{D}:{D}{w}pm{w}                     {
247                                         tw.tw_hour = CVT1OR2 + 12; cp++;
248                                         tw.tw_min  = CVT1OR2; cp++;
249                                         tw.tw_sec  = CVT1OR2;
250                                         BEGIN Z;
251                                         }
252 {D}:{D}({w}am)?{w}                      {
253                                         tw.tw_hour = CVT1OR2; cp++;
254                                         tw.tw_min  = CVT1OR2;
255                                         BEGIN Z;
256                                         }
257 {D}:{D}{w}pm{w}                         {
258                                         tw.tw_hour = CVT1OR2 + 12; cp++;
259                                         tw.tw_min  = CVT1OR2;
260                                         BEGIN Z;
261                                         }
262 [0-2]{d}{d}{d}{d}{d}{w}                 {
263                                         tw.tw_hour = CVT1OR2;
264                                         tw.tw_min  = CVT1OR2;
265                                         tw.tw_sec  = CVT1OR2;
266                                         BEGIN Z;
267                                         }
268 [0-2]{d}{d}{d}{w}                       {
269                                         tw.tw_hour = CVT1OR2;
270                                         tw.tw_min  = CVT1OR2;
271                                         BEGIN Z;
272                                         }
273 <Z>"-"?ut                               ZONE(0 * 60);
274 <Z>"-"?gmt                              ZONE(0 * 60);
275 <Z>"-"?jst                              ZONE(2 * 60);
276 <Z>"-"?jdt                              ZONED(2 * 60);
277 <Z>"-"?est                              ZONE(-5 * 60);
278 <Z>"-"?edt                              ZONED(-5 * 60);
279 <Z>"-"?cst                              ZONE(-6 * 60);
280 <Z>"-"?cdt                              ZONED(-6 * 60);
281 <Z>"-"?mst                              ZONE(-7 * 60);
282 <Z>"-"?mdt                              ZONED(-7 * 60);
283 <Z>"-"?pst                              ZONE(-8 * 60);
284 <Z>"-"?pdt                              ZONED(-8 * 60);
285 <Z>"-"?nst                              ZONE(-(3 * 60 + 30));
286 <Z>"-"?ast                              ZONE(-4 * 60);
287 <Z>"-"?adt                              ZONED(-4 * 60);
288 <Z>"-"?yst                              ZONE(-9 * 60);
289 <Z>"-"?ydt                              ZONED(-9 * 60);
290 <Z>"-"?hst                              ZONE(-10 * 60);
291 <Z>"-"?hdt                              ZONED(-10 * 60);
292 <Z>"-"?bst                              ZONED(-1 * 60);
293 <Z>[a-i]                                tw.tw_zone = 60 * (('a'-1) - LC (*cp));
294 <Z>[k-m]                                tw.tw_zone = 60 * ('a' - LC (*cp));
295 <Z>[n-y]                                tw.tw_zone = 60 * (LC (*cp) - 'm');
296 <Z>"+"[0-1]{d}{d}{d}                    {
297                                         cp++;
298                                         tw.tw_zone = ((cp[0] * 10 + cp[1])
299                                                      -('0' * 10   + '0'))*60
300                                                     +((cp[2] * 10 + cp[3])
301                                                      -('0' * 10   + '0'));
302 #ifdef DSTXXX
303                                         zonehack (&tw);
304 #endif DSTXXX
305                                         cp += 4;
306                                         }
307 <Z>"-"[0-1]{d}{d}{d}                    {
308                                         cp++;
309                                         tw.tw_zone = (('0' * 10   + '0')
310                                                      -(cp[0] * 10 + cp[1]))*60
311                                                     +(('0' * 10   + '0')
312                                                      -(cp[2] * 10 + cp[3]));
313 #ifdef DSTXXX
314                                         zonehack (&tw);
315 #endif DSTXXX
316                                         cp += 4;
317                                         }
318
319 <Z>{W}{d}{d}{d}{d}                      {
320                                         SKIPD;
321                                         tw.tw_year = CVT4;
322                                         }
323 \n      |
324 {W}     ;
325 %%
326
327 #ifdef DSTXXX
328 static
329 zonehack( tw )
330 register struct tws *tw;
331     {
332     register struct tm *tm;
333
334     if ( twclock( tw ) == -1L )
335         return;
336
337     tm = localtime( &tw -> tw_clock );
338     if ( tm -> tm_isdst )
339         {
340         tw -> tw_flags |= TW_DST;
341         tw -> tw_zone -= 60;
342         }
343     }
344 #endif DSTXXX