]> diplodocus.org Git - nmh/blob - sbr/dtimep.lex
INSTALL never documented the etc/*.old thing. Documented the new etc/*.prev
[nmh] / sbr / dtimep.lex
1 %option noyywrap
2 %{
3 #include <h/nmh.h>
4 #include <h/tws.h>
5
6 #define YY_NO_UNPUT
7 #define YY_DECL struct tws * dparsetime(char *lexstr)
8
9 #define yyterminate() (void)yy_delete_buffer(lexhandle); \
10 if(!(tw.tw_flags & TW_SUCC)) { \
11 return (struct tws *)NULL; \
12 } \
13 if(tw.tw_year < 1960) \
14 tw.tw_year += 1900; \
15 if(tw.tw_year < 1960) \
16 tw.tw_year += 100; \
17 return(&tw)
18
19 /*
20 * Patchable flag that says how to interpret NN/NN/NN dates. When
21 * true, we do it European style: DD/MM/YY. When false, we do it
22 * American style: MM/DD/YY. Of course, these are all non-RFC822
23 * compliant.
24 */
25 int europeandate = 0;
26
27 /*
28 * Table to convert month names to numeric month. We use the
29 * fact that the low order 5 bits of the sum of the 2nd & 3rd
30 * characters of the name is a hash with no collisions for the 12
31 * valid month names. (The mask to 5 bits maps any combination of
32 * upper and lower case into the same hash value).
33 */
34 static int month_map[] = {
35 0,
36 6, /* 1 - Jul */
37 3, /* 2 - Apr */
38 5, /* 3 - Jun */
39 0,
40 10, /* 5 - Nov */
41 0,
42 1, /* 7 - Feb */
43 11, /* 8 - Dec */
44 0,
45 0,
46 0,
47 0,
48 0,
49 0,
50 0, /*15 - Jan */
51 0,
52 0,
53 0,
54 2, /*19 - Mar */
55 0,
56 8, /*21 - Sep */
57 0,
58 9, /*23 - Oct */
59 0,
60 0,
61 4, /*26 - May */
62 0,
63 7 /*28 - Aug */
64 };
65
66 /*
67 * Same trick for day-of-week using the hash function
68 * (c1 & 7) + (c2 & 4)
69 */
70 static int day_map[] = {
71 0,
72 0,
73 0,
74 6, /* 3 - Sat */
75 4, /* 4 - Thu */
76 0,
77 5, /* 6 - Fri */
78 0, /* 7 - Sun */
79 2, /* 8 - Tue */
80 1 /* 9 - Mon */,
81 0,
82 3 /*11 - Wed */
83 };
84
85 #define INIT() { cp = yytext;}
86 #define SETWDAY() { cp++; \
87 tw.tw_wday= day_map[(cp[0] & 7) + (cp[1] & 4)]; \
88 tw.tw_flags &= ~TW_SDAY; tw.tw_flags |= TW_SEXP; \
89 SKIPA(); }
90 #define SETMON() { cp++; \
91 tw.tw_mon = month_map[(cp[0] + cp[1]) & 0x1f]; \
92 SKIPA(); }
93 #define SETMON_NUM() { tw.tw_mon = atoi(cp)-1; \
94 SKIPD(); }
95 #define SETYEAR() { tw.tw_year = atoi(cp); \
96 SKIPD(); }
97 #define SETDAY() { tw.tw_mday = atoi(cp); \
98 tw.tw_flags |= TW_YES; \
99 SKIPD(); }
100 #define SETTIME() { tw.tw_hour = atoi(cp); \
101 cp += 2; \
102 SKIPTOD(); \
103 tw.tw_min = atoi(cp); \
104 cp += 2; \
105 if(*cp == ':') { tw.tw_sec = atoi(++cp); SKIPD(); } \
106 }
107 #define SETZONE(x) { tw.tw_zone = ((x)/100)*60+(x)%100; \
108 tw.tw_flags |= TW_SZEXP; \
109 SKIPD(); }
110 #define SETDST() { tw.tw_flags |= TW_DST; }
111 #define SKIPD() { while ( isdigit(*cp++) ) ; \
112 --cp; }
113 #define SKIPTOD() { while ( !isdigit(*cp++) ) ; \
114 --cp; }
115 #define SKIPA() { while ( isalpha(*cp++) ) ; \
116 --cp; }
117 #define SKIPTOA() { while ( !isalpha(*cp++) ) ; \
118 --cp; }
119 #define SKIPSP() { while ( isspace(*cp++) ) ; \
120 --cp; }
121 #define SKIPTOSP() { while ( !isspace(*cp++) ) ; \
122 --cp; }
123 %}
124
125 sun (sun(day)?)
126 mon (mon(day)?)
127 tue (tue(sday)?)
128 wed (wed(nesday)?)
129 thu (thu(rsday)?)
130 fri (fri(day)?)
131 sat (sat(urday)?)
132
133 DAY ({sun}|{mon}|{tue}|{wed}|{thu}|{fri}|{sat})
134
135 jan (jan(uary)?)
136 feb (feb(ruary)?)
137 mar (mar(ch)?)
138 apr (apr(il)?)
139 may (may)
140 jun (jun(e)?)
141 jul (jul(y)?)
142 aug (aug(ust)?)
143 sep (sep(tember)?)
144 oct (oct(ober)?)
145 nov (nov(ember)?)
146 dec (dec(ember)?)
147
148 MONTH ({jan}|{feb}|{mar}|{apr}|{may}|{jun}|{jul}|{aug}|{sep}|{oct}|{nov}|{dec})
149
150 TIME ({D}:{d}{d}(:{d}{d})?)
151
152 YEAR (({d}{d})|(1{d}{d})|({d}{4}))
153
154 w ([ \t]*)
155 W ([ \t]+)
156 D ([0-9]?[0-9])
157 d [0-9]
158
159 %%
160 %{
161
162 YY_BUFFER_STATE lexhandle;
163
164 register char *cp; /* *cp is internal to the lexing function yylex() */
165 static struct tws tw;
166
167 memset(&tw,0,sizeof(struct tws));
168 lexhandle = yy_scan_string(lexstr);
169 %}
170
171 {DAY}","?{W}{MONTH}{W}{D}{W}{TIME}{W}{YEAR} {
172 INIT();
173 SETWDAY();
174 SKIPTOA();
175 SETMON();
176 SKIPTOD();
177 SETDAY();
178 SKIPTOD();
179 SETTIME();
180 SKIPTOD();
181 SETYEAR();
182 }
183
184 {DAY}","?{W}{D}{W}{MONTH}{W}{YEAR}{W}{TIME} {
185 INIT();
186 SETWDAY();
187 SKIPTOD();
188 SETDAY();
189 SKIPTOA();
190 SETMON();
191 SKIPTOD();
192 SETYEAR();
193 SKIPTOD();
194 SETTIME();
195 }
196 {D}{W}{MONTH}{W}{YEAR}{W}{TIME} {
197 INIT();
198 SETDAY();
199 SKIPTOA();
200 SETMON();
201 SKIPTOD();
202 SETYEAR();
203 SKIPTOD();
204 SETTIME();
205 }
206 {DAY}","?{W}{MONTH}{W}{D}","?{W}{YEAR}","?{W}{TIME} {
207 INIT();
208 SETWDAY();
209 SKIPTOA();
210 SETMON();
211 SKIPTOD();
212 SETDAY();
213 SKIPTOD();
214 SETYEAR();
215 SKIPTOD();
216 SETTIME();
217 }
218 {DAY}","?{W}{MONTH}{W}{D}","?{W}{YEAR} {
219 INIT();
220 SETWDAY();
221 SKIPTOA();
222 SETMON();
223 SKIPTOD();
224 SETDAY();
225 SKIPTOD();
226 SETYEAR();
227 }
228 {MONTH}{W}{D}","?{W}{YEAR}","?{W}{DAY} {
229 INIT();
230 SETMON();
231 SKIPTOD();
232 SETDAY();
233 SKIPTOD();
234 SETYEAR();
235 SKIPTOA();
236 SETWDAY();
237 }
238 {MONTH}{W}{D}","?{W}{YEAR} {
239 INIT();
240 SETMON();
241 SKIPTOD();
242 SETDAY();
243 SKIPTOD();
244 SETYEAR();
245 }
246 {D}("-"|"/"){D}("-"|"/"){YEAR}{W}{TIME} {
247 INIT();
248 if(europeandate) {
249 /* DD/MM/YY */
250 SETDAY();
251 SKIPTOD();
252 SETMON_NUM();
253 } else {
254 /* MM/DD/YY */
255 SETMON_NUM();
256 SKIPTOD();
257 SETDAY();
258 }
259 SKIPTOD();
260 SETYEAR();
261 SKIPTOD();
262 SETTIME();
263 }
264 {D}("-"|"/"){D}("-"|"/"){YEAR} {
265 INIT();
266 if(europeandate) {
267 /* DD/MM/YY */
268 SETDAY();
269 SKIPTOD();
270 SETMON_NUM();
271 } else {
272 /* MM/DD/YY */
273 SETMON_NUM();
274 SKIPTOD();
275 SETDAY();
276 }
277 SKIPTOD();
278 SETYEAR();
279 }
280
281 "[Aa][Mm]"
282 "[Pp][Mm]" tw.tw_hour += 12;
283
284 "+"{D}{d}{d} {
285 INIT();
286 SKIPTOD();
287 SETZONE(atoi(cp));
288 }
289 "-"{D}{d}{d} {
290 INIT();
291 SKIPTOD();
292 SETZONE(-atoi(cp));
293 }
294 "-"?("ut"|"UT") INIT(); SETZONE(0);
295 "-"?("gmt"|"GMT") INIT(); SETZONE(0);
296 "-"?("jst"|"JST") INIT(); SETZONE(200);
297 "-"?("jdt"|"JDT") INIT(); SETDST(); SETZONE(2);
298 "-"?("est"|"EST") INIT(); SETZONE(-500);
299 "-"?("edt"|"EDT") INIT(); SETDST(); SETZONE(-500);
300 "-"?("cst"|"CST") INIT(); SETZONE(-600);
301 "-"?("cdt"|"CDT") INIT(); SETDST(); SETZONE(-600);
302 "-"?("mst"|"MST") INIT(); SETZONE(-700);
303 "-"?("mdt"|"MDT") INIT(); SETDST(); SETZONE(-700);
304 "-"?("pst"|"PST") INIT(); SETZONE(-800);
305 "-"?("pdt"|"PDT") INIT(); SETDST(); SETZONE(-800);
306 "-"?("nst"|"NST") INIT(); SETZONE(-330);
307 "-"?("ast"|"AST") INIT(); SETZONE(-400);
308 "-"?("adt"|"ADT") INIT(); SETDST(); SETZONE(-400);
309 "-"?("yst"|"YST") INIT(); SETZONE(-900);
310 "-"?("ydt"|"YDT") INIT(); SETDST(); SETZONE(-900);
311 "-"?("hst"|"HST") INIT(); SETZONE(-1000);
312 "-"?("hdt"|"HDT") INIT(); SETDST(); SETZONE(-1000);
313 "-"?("bst"|"BST") INIT(); SETDST(); SETZONE(-100);
314 [a-i] {
315 INIT();
316 SETZONE(100*(('a'-1) - tolower(*cp)));
317 }
318 [k-m] {
319 INIT();
320 SETZONE(100*('a' - tolower(*cp)));
321 }
322 [n-y] {
323 INIT();
324 SETZONE(100*(tolower(*cp) - 'm'));
325 }
326
327
328 \n
329 .
330
331
332