home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume8 / phoon / dtimep.lex < prev    next >
Encoding:
Text File  |  1987-02-26  |  7.2 KB  |  357 lines

  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 <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}{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}"-")|(" "{MONTH}" ")|({MONTH})){D}?{d}{d}({W}at)?{w}    {
  206.                     tw.tw_mday = CVT1OR2;
  207.                     while ( ! isalpha( *cp++ ) )
  208.                         ;
  209.                     SETMONTH;
  210.                     for ( i = 0; isdigit( *cp ); )
  211.                         i = i * 10 + (*cp++ - '0');
  212.                     tw.tw_year = i;
  213.                     gotdate++;
  214.                     }
  215. {D}"-"?{MONTH}({W}at)?{w}        {
  216.                     tw.tw_mday = CVT1OR2;
  217.                     while ( ! isalpha( *cp++ ) )
  218.                         ;
  219.                     SETMONTH;
  220.                     gotdate++;
  221.                     }
  222. {MONTH}{W}{D}","{W}{D}?{d}{d}{w}    {
  223.                     cp++;
  224.                     SETMONTH;
  225.                     tw.tw_mday = CVT1OR2;
  226.                     SKIPD;
  227.                     for ( i = 0; isdigit( *cp ); )
  228.                         i = i * 10 + (*cp++ - '0');
  229.                     tw.tw_year = i;
  230.                     gotdate++;
  231.                     }
  232. {MONTH}{W}{D}{w}            {
  233.                     cp++;
  234.                     SETMONTH;
  235.                     tw.tw_mday = CVT1OR2;
  236.                     gotdate++;
  237.                     }
  238.  
  239. {D}:{D}:{D}({w}am)?{w}            {
  240.                     tw.tw_hour = CVT1OR2; cp++;
  241.                     tw.tw_min  = CVT1OR2; cp++;
  242.                     tw.tw_sec  = CVT1OR2;
  243.                     BEGIN Z;
  244.                     }
  245. {D}:{D}:{D}{w}pm{w}            {
  246.                     tw.tw_hour = CVT1OR2 + 12; cp++;
  247.                     tw.tw_min  = CVT1OR2; cp++;
  248.                     tw.tw_sec  = CVT1OR2;
  249.                     BEGIN Z;
  250.                     }
  251. {D}:{D}({w}am)?{w}            {
  252.                     tw.tw_hour = CVT1OR2; cp++;
  253.                     tw.tw_min  = CVT1OR2;
  254.                     BEGIN Z;
  255.                     }
  256. {D}:{D}{w}pm{w}                {
  257.                     tw.tw_hour = CVT1OR2 + 12; cp++;
  258.                     tw.tw_min  = CVT1OR2;
  259.                     BEGIN Z;
  260.                     }
  261. [0-2]{d}{d}{d}{d}{d}{w}            {
  262.                     tw.tw_hour = CVT1OR2;
  263.                     tw.tw_min  = CVT1OR2;
  264.                     tw.tw_sec  = CVT1OR2;
  265.                     BEGIN Z;
  266.                     }
  267. [0-2]{d}{d}{d}{w}            {
  268.                     tw.tw_hour = CVT1OR2;
  269.                     tw.tw_min  = CVT1OR2;
  270.                     BEGIN Z;
  271.                     }
  272. <Z>"-"?ut                ZONE(0 * 60);
  273. <Z>"-"?gmt                ZONE(0 * 60);
  274. <Z>"-"?jst                ZONE(2 * 60);
  275. <Z>"-"?jdt                ZONED(2 * 60);
  276. <Z>"-"?est                ZONE(-5 * 60);
  277. <Z>"-"?edt                ZONED(-5 * 60);
  278. <Z>"-"?cst                ZONE(-6 * 60);
  279. <Z>"-"?cdt                ZONED(-6 * 60);
  280. <Z>"-"?mst                ZONE(-7 * 60);
  281. <Z>"-"?mdt                ZONED(-7 * 60);
  282. <Z>"-"?pst                ZONE(-8 * 60);
  283. <Z>"-"?pdt                ZONED(-8 * 60);
  284. <Z>"-"?nst                ZONE(-(3 * 60 + 30));
  285. <Z>"-"?ast                ZONE(-4 * 60);
  286. <Z>"-"?adt                ZONED(-4 * 60);
  287. <Z>"-"?yst                ZONE(-9 * 60);
  288. <Z>"-"?ydt                ZONED(-9 * 60);
  289. <Z>"-"?hst                ZONE(-10 * 60);
  290. <Z>"-"?hdt                ZONED(-10 * 60);
  291. <Z>"-"?bst                ZONED(-1 * 60);
  292. <Z>[a-i]                tw.tw_zone = 60 * (('a'-1) - LC (*cp));
  293. <Z>[k-m]                tw.tw_zone = 60 * ('a' - LC (*cp));
  294. <Z>[n-y]                tw.tw_zone = 60 * (LC (*cp) - 'm');
  295. <Z>"+"[0-1]{d}{d}{d}            {
  296.                     cp++;
  297.                     tw.tw_zone = ((cp[0] * 10 + cp[1])
  298.                              -('0' * 10   + '0'))*60
  299.                             +((cp[2] * 10 + cp[3])
  300.                              -('0' * 10   + '0'));
  301. #ifdef DSTXXX
  302.                     zonehack (&tw);
  303. #endif DSTXXX
  304.                     cp += 4;
  305.                     }
  306. <Z>"-"[0-1]{d}{d}{d}            {
  307.                     cp++;
  308.                     tw.tw_zone = (('0' * 10   + '0')
  309.                              -(cp[0] * 10 + cp[1]))*60
  310.                             +(('0' * 10   + '0')
  311.                              -(cp[2] * 10 + cp[3]));
  312. #ifdef DSTXXX
  313.                     zonehack (&tw);
  314. #endif DSTXXX
  315.                     cp += 4;
  316.                     }
  317.  
  318. <Z>{W}{d}{d}{d}{d}            {
  319.                     SKIPD;
  320.                     tw.tw_year = CVT4;
  321.                     }
  322. \n    |
  323. {W}    ;
  324. %%
  325.  
  326. #ifdef DSTXXX
  327. static
  328. zonehack( tw )
  329. register struct tws *tw;
  330.     {
  331.     register struct tm *tm;
  332.  
  333.     if ( twclock( tw ) == -1L )
  334.     return;
  335.  
  336.     tm = localtime( &tw -> tw_clock );
  337.     if ( tm -> tm_isdst )
  338.     {
  339.     tw -> tw_flags |= TW_DST;
  340.     tw -> tw_zone -= 60;
  341.     }
  342.     }
  343. #endif DSTXXX
  344.  
  345.  
  346. #ifdef SYS5
  347. /* Not all SYS5's have bzero( ). */
  348.  
  349. bzero( b, length )
  350. char *b;
  351. int length;
  352.     {
  353.     while ( length-- > 0 )
  354.     *b++ = 0;
  355.     }
  356. #endif
  357.