source: trunk/third/nmh/zotnet/tws/dtimep.lex @ 12455

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