7 #define YY_DECL struct tws * dparsetime(char *lexstr)
9 #define yyterminate() (void)yy_delete_buffer(lexhandle); \
10 if(!(tw.tw_flags & TW_SUCC)) { \
11 return (struct tws *)NULL; \
13 if(tw.tw_year < 1960) \
15 if(tw.tw_year < 1960) \
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
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).
34 static int month_map[] = {
67 * Same trick for day-of-week using the hash function
70 static int day_map[] = {
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; \
90 #define SETMON() { cp++; \
91 tw.tw_mon = month_map[(cp[0] + cp[1]) & 0x1f]; \
93 #define SETMON_NUM() { tw.tw_mon = atoi(cp)-1; \
95 #define SETYEAR() { tw.tw_year = atoi(cp); \
97 #define SETDAY() { tw.tw_mday = atoi(cp); \
98 tw.tw_flags |= TW_YES; \
100 #define SETTIME() { tw.tw_hour = atoi(cp); \
103 tw.tw_min = atoi(cp); \
105 if(*cp == ':') { tw.tw_sec = atoi(++cp); SKIPD(); } \
107 #define SETZONE(x) { tw.tw_zone = ((x)/100)*60+(x)%100; \
108 tw.tw_flags |= TW_SZEXP; \
110 #define SETDST() { tw.tw_flags |= TW_DST; }
111 #define SKIPD() { while ( isdigit(*cp++) ) ; \
113 #define SKIPTOD() { while ( !isdigit(*cp++) ) ; \
115 #define SKIPA() { while ( isalpha(*cp++) ) ; \
117 #define SKIPTOA() { while ( !isalpha(*cp++) ) ; \
119 #define SKIPSP() { while ( isspace(*cp++) ) ; \
121 #define SKIPTOSP() { while ( !isspace(*cp++) ) ; \
133 DAY ({sun}|{mon}|{tue}|{wed}|{thu}|{fri}|{sat})
148 MONTH ({jan}|{feb}|{mar}|{apr}|{may}|{jun}|{jul}|{aug}|{sep}|{oct}|{nov}|{dec})
150 TIME ({D}:{d}{d}(:{d}{d})?)
152 YEAR (({d}{d})|(1{d}{d})|({d}{4}))
162 YY_BUFFER_STATE lexhandle;
164 register char *cp; /* *cp is internal to the lexing function yylex() */
165 static struct tws tw;
167 memset(&tw,0,sizeof(struct tws));
168 lexhandle = yy_scan_string(lexstr);
171 {DAY}","?{W}{MONTH}{W}{D}{W}{TIME}{W}{YEAR} {
184 {DAY}","?{W}{D}{W}{MONTH}{W}{YEAR}{W}{TIME} {
196 {D}{W}{MONTH}{W}{YEAR}{W}{TIME} {
206 {DAY}","?{W}{MONTH}{W}{D}","?{W}{YEAR}","?{W}{TIME} {
218 {DAY}","?{W}{MONTH}{W}{D}","?{W}{YEAR} {
228 {MONTH}{W}{D}","?{W}{YEAR}","?{W}{DAY} {
238 {MONTH}{W}{D}","?{W}{YEAR} {
246 {D}("-"|"/"){D}("-"|"/"){YEAR}{W}{TIME} {
264 {D}("-"|"/"){D}("-"|"/"){YEAR} {
282 "[Pp][Mm]" tw.tw_hour += 12;
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);
316 SETZONE(100*(('a'-1) - tolower(*cp)));
320 SETZONE(100*('a' - tolower(*cp)));
324 SETZONE(100*(tolower(*cp) - 'm'));