Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / local / lbl / zotnet / tws / dtimep.lex
1 %{
2 #ifndef lint
3 static char rcsid[] =
4 #ifdef FLEX_SCANNER
5     "@(#) $Header: dtimep.lex,v 1.15 90/10/16 14:57:20 leres Exp $ (LBL) (flex generated scanner)";
6 #else
7     "@(#) $Header: dtimep.lex,v 1.15 90/10/16 14:57:20 leres Exp $ (LBL) (lex generated scanner)";
8 #endif
9 #endif
10 %}
11 /*
12 %e 2000
13 %p 5000
14 %n 1000
15 %a 4000
16  */
17
18 %START  Z
19 sun     (sun(day)?)
20 mon     (mon(day)?)
21 tue     (tue(sday)?)
22 wed     (wed(nesday)?)
23 thu     (thu(rsday)?)
24 fri     (fri(day)?)
25 sat     (sat(urday)?)
26
27 DAY     ({sun}|{mon}|{tue}|{wed}|{thu}|{fri}|{sat})
28
29 jan     (jan(uary)?)
30 feb     (feb(ruary)?)
31 mar     (mar(ch)?)
32 apr     (apr(il)?)
33 may     (may)
34 jun     (jun(e)?)
35 jul     (jul(y)?)
36 aug     (aug(ust)?)
37 sep     (sep(tember)?)
38 oct     (oct(ober)?)
39 nov     (nov(ember)?)
40 dec     (dec(ember)?)
41
42 MONTH   ({jan}|{feb}|{mar}|{apr}|{may}|{jun}|{jul}|{aug}|{sep}|{oct}|{nov}|{dec})
43
44 w       ([ \t]*)
45 W       ([ \t]+)
46 D       ([0-9]?[0-9])
47 d       [0-9]
48 %{
49 #include "tws.h"
50 #include <ctype.h>
51
52 /*
53  * Patchable flag that says how to interpret NN/NN/NN dates. When
54  * true, we do it European style: DD/MM/YY. When false, we do it
55  * American style: MM/DD/YY.
56  */
57 int europeandate = 0;
58
59 /*
60  * Table to convert month names to numeric month.  We use the
61  * fact that the low order 5 bits of the sum of the 2nd & 3rd
62  * characters of the name is a hash with no collisions for the 12
63  * valid month names.  (The mask to 5 bits maps any combination of
64  * upper and lower case into the same hash value).
65  */
66 static  int month_map[] = {
67         0,
68         6,      /* 1 - Jul */
69         3,      /* 2 - Apr */
70         5,      /* 3 - Jun */
71         0,
72         10,     /* 5 - Nov */
73         0,
74         1,      /* 7 - Feb */
75         11,     /* 8 - Dec */
76         0,
77         0,
78         0,
79         0,
80         0,
81         0,
82         0,      /*15 - Jan */
83         0,
84         0,
85         0,
86         2,      /*19 - Mar */
87         0,
88         8,      /*21 - Sep */
89         0,
90         9,      /*23 - Oct */
91         0,
92         0,
93         4,      /*26 - May */
94         0,
95         7       /*28 - Aug */
96 };
97 /*
98  * Same trick for day-of-week using the hash function
99  *  (c1 & 7) + (c2 & 4)
100  */
101 static  int day_map[] = {
102         0,
103         0,
104         0,
105         6,      /* 3 - Sat */
106         4,      /* 4 - Thu */
107         0,
108         5,      /* 6 - Fri */
109         0,      /* 7 - Sun */
110         2,      /* 8 - Tue */
111         1       /* 9 - Mon */,
112         0,
113         3       /*11 - Wed */
114 };
115 #define SETDAY  { tw.tw_wday= day_map[(cp[0] & 7) + (cp[1] & 4)];\
116                 tw.tw_flags &= ~TW_SDAY; tw.tw_flags |= TW_SEXP;\
117                 cp += 2; }
118 #define SETMONTH { tw.tw_mon = month_map[(cp[0] + cp[1]) & 0x1f]; gotdate++;\
119                  cp += 2;\
120                  SKIPD;}
121 #define CVT2    (i=(*cp++ - '0'),isdigit(*cp)? i*10 + (*cp++ - '0') : i)
122 #define SKIPD   { while ( !isdigit(*cp++) ) ;  --cp; }
123 #define EXPZONE { tw.tw_flags &= ~TW_SZONE; tw.tw_flags |= TW_SZEXP; }
124 #define ZONE(x) { tw.tw_zone=(x); EXPZONE; }
125 #define ZONED(x) { ZONE(x); tw.tw_flags |= TW_DST; }
126 #define LC(c)   (isupper(c) ? tolower(c) : (c))
127
128 #ifdef FLEX_SCANNER
129 /* We get passed a string and return a pointer to a static tws struct */
130 #undef YY_DECL
131 #define YY_DECL struct tws *dparsetime(str) char *str;
132
133 /* We assume that we're never passed more than max_size characters */
134 #undef YY_INPUT
135 #define YY_INPUT(buf,result,max_size) \
136         if (gstr) { \
137                 register char *xp; \
138                 xp = gstr; \
139                 while (isspace(*xp)) \
140                         xp++; \
141                 gstr = xp; \
142                 while (*xp != '\0') \
143                         ++xp; \
144                 result = xp - gstr; \
145                 bcopy(gstr, buf, result); \
146                 gstr = 0; \
147         } else \
148                 result = YY_NULL;
149
150 /* Date strings aren't usually very long */
151 #undef YY_READ_BUF_SIZE
152 #define YY_READ_BUF_SIZE 128
153
154 /* Use mh error reporting routine */
155 #undef YY_FATAL_ERROR
156 #define YY_FATAL_ERROR(s) adios("dparsetime()", s);
157
158 /* We need a pointer to the matched text we can modify */
159 #undef YY_USER_ACTION
160 #define YY_USER_ACTION cp = yytext
161
162 /* Used to initialize */
163 static struct tws ztw = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
164
165 /* Global for use by YY_INPUT() macro */
166 static char *gstr;
167 #endif
168
169 %}
170
171 %%
172                                         register int i, gotdate;
173                                         register char *cp;
174                                         static struct tws tw;
175                                         static void zonehack();
176
177                                         BEGIN(INITIAL);
178                                         yy_init = 1;
179                                         tw = ztw;
180                                         gstr = str;
181                                         gotdate = 0;
182
183 {DAY}","?{w}                            SETDAY;
184 "("{DAY}")"(","?)                       {
185                                         cp++;
186                                         SETDAY;
187                                         }
188
189 {D}"/"{D}"/"(19)?[0-9][0-9]{w}          {
190                                         if (europeandate) {
191                                                 /* European: DD/MM/YY */
192                                                 tw.tw_mday = CVT2;
193                                                 cp++;
194                                                 tw.tw_mon  = CVT2 - 1;
195                                         } else {
196                                                 /* American: MM/DD/YY */
197                                                 tw.tw_mon  = CVT2 - 1;
198                                                 cp++;
199                                                 tw.tw_mday = CVT2;
200                                         }
201                                         cp++;
202                                         for (i = 0; isdigit(*cp); )
203                                                 i = i*10 + (*cp++ - '0');
204                                         tw.tw_year = i % 100;
205                                         gotdate++;
206                                         }
207 {D}{w}(-)?{w}{MONTH}{w}(-)?{w}(19)?{D}{w}(\,{w}|at{W})? {
208                                         tw.tw_mday = CVT2;
209                                         while (!isalpha(*cp++))
210                                                 ;
211                                         SETMONTH;
212                                         for (i = 0; isdigit(*cp); )
213                                                 i = i*10 + (*cp++ - '0');
214                                         tw.tw_year = i % 100;
215                                         }
216 {MONTH}{W}{D}","{W}(19)?{D}{w}          {
217                                         cp++;
218                                         SETMONTH;
219                                         tw.tw_mday = CVT2;
220                                         SKIPD;
221                                         for (i = 0; isdigit(*cp); )
222                                                 i = i*10 + (*cp++ - '0');
223                                         tw.tw_year = i % 100;
224                                         }
225
226 {MONTH}{W}{D}{w}                        {
227                                         cp++;
228                                         SETMONTH;
229                                         tw.tw_mday = CVT2;
230                                         }
231
232 {D}:{D}:{D}{w}                          {
233                                         tw.tw_hour = CVT2; cp++;
234                                         tw.tw_min  = CVT2; cp++;
235                                         tw.tw_sec  = CVT2;
236                                         BEGIN Z;
237                                         }
238 {D}:{D}{w}                              {
239                                         tw.tw_hour = CVT2; cp++;
240                                         tw.tw_min  = CVT2;
241                                         BEGIN Z;
242                                         }
243 {D}:{D}{w}am{w}                         {
244                                         tw.tw_hour = CVT2; cp++;
245                                         if (tw.tw_hour == 12)
246                                                 tw.tw_hour = 0;
247                                         tw.tw_min  = CVT2;
248                                         BEGIN Z;
249                                         }
250 {D}:{D}{w}pm{w}                         {
251                                         tw.tw_hour = CVT2; cp++;
252                                         if (tw.tw_hour != 12)
253                                                 tw.tw_hour += 12;
254                                         tw.tw_min  = CVT2;
255                                         BEGIN Z;
256                                         }
257 [0-2]{d}{d}{d}{d}{d}{w}                 {
258                                         tw.tw_hour = CVT2;
259                                         tw.tw_min  = CVT2;
260                                         tw.tw_sec  = CVT2;
261                                         BEGIN Z;
262                                         }
263 19[6-9]{d}{w}                           {
264                                         /*
265                                          * Luckly, 4 digit times in the range
266                                          * 1960-1999 aren't legal as hour
267                                          * and minutes. This rule must come
268                                          * the 4 digit hour and minute rule.
269                                          */
270                                         cp += 2;
271                                         tw.tw_year = CVT2;
272                                         }
273 [0-2]{d}{d}{d}{w}                       {
274                                         tw.tw_hour = CVT2;
275                                         tw.tw_min  = CVT2;
276                                         BEGIN Z;
277                                         }
278 <Z>"-"?ut                               ZONE(0 * 60);
279 <Z>"-"?gmt                              ZONE(0 * 60);
280 <Z>"-"?jst                              ZONE(2 * 60);
281 <Z>"-"?jdt                              ZONED(2 * 60);
282 <Z>"-"?est                              ZONE(-5 * 60);
283 <Z>"-"?edt                              ZONED(-5 * 60);
284 <Z>"-"?cst                              ZONE(-6 * 60);
285 <Z>"-"?cdt                              ZONED(-6 * 60);
286 <Z>"-"?mst                              ZONE(-7 * 60);
287 <Z>"-"?mdt                              ZONED(-7 * 60);
288 <Z>"-"?pst                              ZONE(-8 * 60);
289 <Z>"-"?pdt                              ZONED(-8 * 60);
290 <Z>"-"?nst                              ZONE(-(3 * 60 + 30));
291 <Z>"-"?ast                              ZONE(-4 * 60);
292 <Z>"-"?adt                              ZONED(-4 * 60);
293 <Z>"-"?yst                              ZONE(-9 * 60);
294 <Z>"-"?ydt                              ZONED(-9 * 60);
295 <Z>"-"?hst                              ZONE(-10 * 60);
296 <Z>"-"?hdt                              ZONED(-10 * 60);
297 <Z>"-"?bst                              ZONED(-1 * 60);
298 <Z>[a-i]                                {
299                                         tw.tw_zone = 60 * (('a'-1) - LC(*cp));
300                                         EXPZONE; 
301                                         }
302 <Z>[k-m]                                {
303                                         tw.tw_zone = 60 * ('a' - LC(*cp));
304                                         EXPZONE; 
305                                         }
306 <Z>[n-y]                                {
307                                         tw.tw_zone = 60 * (LC(*cp) - 'm');
308                                         EXPZONE; 
309                                         }
310 <Z>"+"[0-1]{d}{d}{d}                    {
311                                         cp++;
312                                         tw.tw_zone = ((cp[0] * 10 + cp[1])
313                                                      -('0' * 10   + '0'))*60
314                                                     +((cp[2] * 10 + cp[3])
315                                                      -('0' * 10   + '0'));
316 #ifdef  DSTXXX
317                                         zonehack (&tw);
318 #endif  DSTXXX
319                                         cp += 4;
320                                         EXPZONE; 
321                                         }
322 <Z>"-"[0-1]{d}{d}{d}                    {
323                                         cp++;
324                                         tw.tw_zone = (('0' * 10   + '0')
325                                                      -(cp[0] * 10 + cp[1]))*60
326                                                     +(('0' * 10   + '0')
327                                                      -(cp[2] * 10 + cp[3]));
328 #ifdef  DSTXXX
329                                         zonehack (&tw);
330 #endif  DSTXXX
331                                         cp += 4;
332                                         EXPZONE; 
333                                         }
334
335 \n                                      |
336 {W}                                     ;
337
338 <INITIAL,Z><<EOF>>                      return(&tw);
339
340 .                                       {
341                                         /*
342                                          * We jammed; it's an error if we
343                                          * didn't parse anything.
344                                          */
345                                         if (!gotdate || tw.tw_year == 0)
346                                                 return(0);
347                                         return(&tw);
348                                         }
349
350 %%
351
352 #ifdef  DSTXXX
353 #include <sys/types.h>
354 #ifndef BSD42
355 #include <time.h>
356 #else   BSD42
357 #include <sys/time.h>
358 #endif  BSD42
359
360 static void
361 zonehack(tw)
362     register struct tws *tw;
363 {
364     register struct tm *tm;
365
366     if (twclock (tw) == -1L)
367         return;
368
369     tm = localtime (&tw -> tw_clock);
370     if (tm -> tm_isdst) {
371         tw -> tw_flags |= TW_DST;
372         tw -> tw_zone -= 60;
373     }
374 }
375 #endif  DSTXXX