home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / gnu / sh-utils-1.12-src.lha / sh-utils-1.12 / lib / getdate.y < prev    next >
Text File  |  1994-10-04  |  24KB  |  985 lines

  1. %{
  2. /*
  3. **  Originally written by Steven M. Bellovin <smb@research.att.com> while
  4. **  at the University of North Carolina at Chapel Hill.  Later tweaked by
  5. **  a couple of people on Usenet.  Completely overhauled by Rich $alz
  6. **  <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
  7. **  send any email to Rich.
  8. **
  9. **  This grammar has 10 shift/reduce conflicts.
  10. **
  11. **  This code is in the public domain and has no copyright.
  12. */
  13. /* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
  14. /* SUPPRESS 288 on yyerrlab *//* Label unused */
  15.  
  16. #ifdef HAVE_CONFIG_H
  17. #include <config.h>
  18. #endif
  19.  
  20. /* Since the code of getdate.y is not included in the Emacs executable
  21.    itself, there is no need to #define static in this file.  Even if
  22.    the code were included in the Emacs executable, it probably
  23.    wouldn't do any harm to #undef it here; this will only cause
  24.    problems if we try to write to a static variable, which I don't
  25.    think this code needs to do.  */
  26. #ifdef emacs
  27. #undef static
  28. #endif
  29.  
  30. #include <stdio.h>
  31. #include <ctype.h>
  32.  
  33. /* The code at the top of get_date which figures out the offset of the
  34.    current time zone checks various CPP symbols to see if special
  35.    tricks are need, but defaults to using the gettimeofday system call.
  36.    Include <sys/time.h> if that will be used.  */
  37.  
  38. #if    defined (vms)
  39.  
  40. #include <types.h>
  41. #include <time.h>
  42.  
  43. #else
  44.  
  45. #include <sys/types.h>
  46.  
  47. #ifdef TIME_WITH_SYS_TIME
  48. #include <sys/time.h>
  49. #include <time.h>
  50. #else
  51. #ifdef HAVE_SYS_TIME_H
  52. #include <sys/time.h>
  53. #else
  54. #include <time.h>
  55. #endif
  56. #endif
  57.  
  58. #ifdef timezone
  59. #undef timezone /* needed for sgi */
  60. #endif
  61.  
  62. #if defined (HAVE_SYS_TIMEB_H)
  63. #include <sys/timeb.h>
  64. #else
  65. /*
  66. ** We use the obsolete `struct timeb' as part of our interface!
  67. ** Since the system doesn't have it, we define it here;
  68. ** our callers must do likewise.
  69. */
  70. struct timeb {
  71.     time_t        time;        /* Seconds since the epoch    */
  72.     unsigned short    millitm;    /* Field not used        */
  73.     short        timezone;    /* Minutes west of GMT        */
  74.     short        dstflag;    /* Field not used        */
  75. };
  76. #endif /* defined (HAVE_SYS_TIMEB_H) */
  77.  
  78. #endif    /* defined (vms) */
  79.  
  80. #if defined (STDC_HEADERS) || defined (USG)
  81. #include <string.h>
  82. #endif
  83.  
  84. /* Some old versions of bison generate parsers that use bcopy.
  85.    That loses on systems that don't provide the function, so we have
  86.    to redefine it here.  */
  87. #if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
  88. #define bcopy(from, to, len) memcpy ((to), (from), (len))
  89. #endif
  90.  
  91. extern struct tm    *gmtime ();
  92. extern struct tm    *localtime ();
  93.  
  94. #define yyparse getdate_yyparse
  95. #define yylex getdate_yylex
  96. #define yyerror getdate_yyerror
  97.  
  98. static int yylex ();
  99. static int yyerror ();
  100.  
  101. #define EPOCH        1970
  102. #define HOUR(x)        ((time_t)(x) * 60)
  103. #define SECSPERDAY    (24L * 60L * 60L)
  104.  
  105. #define MAX_BUFF_LEN    128   /* size of buffer to read the date into */
  106.  
  107. /*
  108. **  An entry in the lexical lookup table.
  109. */
  110. typedef struct _TABLE {
  111.     const char    *name;
  112.     int        type;
  113.     time_t    value;
  114. } TABLE;
  115.  
  116.  
  117. /*
  118. **  Daylight-savings mode:  on, off, or not yet known.
  119. */
  120. typedef enum _DSTMODE {
  121.     DSTon, DSToff, DSTmaybe
  122. } DSTMODE;
  123.  
  124. /*
  125. **  Meridian:  am, pm, or 24-hour style.
  126. */
  127. typedef enum _MERIDIAN {
  128.     MERam, MERpm, MER24
  129. } MERIDIAN;
  130.  
  131.  
  132. /*
  133. **  Global variables.  We could get rid of most of these by using a good
  134. **  union as the yacc stack.  (This routine was originally written before
  135. **  yacc had the %union construct.)  Maybe someday; right now we only use
  136. **  the %union very rarely.
  137. */
  138. static char    *yyInput;
  139. static DSTMODE    yyDSTmode;
  140. static time_t    yyDayOrdinal;
  141. static time_t    yyDayNumber;
  142. static int    yyHaveDate;
  143. static int    yyHaveDay;
  144. static int    yyHaveRel;
  145. static int    yyHaveTime;
  146. static int    yyHaveZone;
  147. static time_t    yyTimezone;
  148. static time_t    yyDay;
  149. static time_t    yyHour;
  150. static time_t    yyMinutes;
  151. static time_t    yyMonth;
  152. static time_t    yySeconds;
  153. static time_t    yyYear;
  154. static MERIDIAN    yyMeridian;
  155. static time_t    yyRelMonth;
  156. static time_t    yyRelSeconds;
  157.  
  158. %}
  159.  
  160. %union {
  161.     time_t        Number;
  162.     enum _MERIDIAN    Meridian;
  163. }
  164.  
  165. %token    tAGO tDAY tDAYZONE tID tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT
  166. %token    tSEC_UNIT tSNUMBER tUNUMBER tZONE tDST
  167.  
  168. %type    <Number>    tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT
  169. %type    <Number>    tSEC_UNIT tSNUMBER tUNUMBER tZONE
  170. %type    <Meridian>    tMERIDIAN o_merid
  171.  
  172. %%
  173.  
  174. spec    : /* NULL */
  175.     | spec item
  176.     ;
  177.  
  178. item    : time {
  179.         yyHaveTime++;
  180.     }
  181.     | zone {
  182.         yyHaveZone++;
  183.     }
  184.     | date {
  185.         yyHaveDate++;
  186.     }
  187.     | day {
  188.         yyHaveDay++;
  189.     }
  190.     | rel {
  191.         yyHaveRel++;
  192.     }
  193.     | number
  194.     ;
  195.  
  196. time    : tUNUMBER tMERIDIAN {
  197.         yyHour = $1;
  198.         yyMinutes = 0;
  199.         yySeconds = 0;
  200.         yyMeridian = $2;
  201.     }
  202.     | tUNUMBER ':' tUNUMBER o_merid {
  203.         yyHour = $1;
  204.         yyMinutes = $3;
  205.         yySeconds = 0;
  206.         yyMeridian = $4;
  207.     }
  208.     | tUNUMBER ':' tUNUMBER tSNUMBER {
  209.         yyHour = $1;
  210.         yyMinutes = $3;
  211.         yyMeridian = MER24;
  212.         yyDSTmode = DSToff;
  213.         yyTimezone = - ($4 % 100 + ($4 / 100) * 60);
  214.     }
  215.     | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid {
  216.         yyHour = $1;
  217.         yyMinutes = $3;
  218.         yySeconds = $5;
  219.         yyMeridian = $6;
  220.     }
  221.     | tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER {
  222.         yyHour = $1;
  223.         yyMinutes = $3;
  224.         yySeconds = $5;
  225.         yyMeridian = MER24;
  226.         yyDSTmode = DSToff;
  227.         yyTimezone = - ($6 % 100 + ($6 / 100) * 60);
  228.     }
  229.     ;
  230.  
  231. zone    : tZONE {
  232.         yyTimezone = $1;
  233.         yyDSTmode = DSToff;
  234.     }
  235.     | tDAYZONE {
  236.         yyTimezone = $1;
  237.         yyDSTmode = DSTon;
  238.     }
  239.     |
  240.       tZONE tDST {
  241.         yyTimezone = $1;
  242.         yyDSTmode = DSTon;
  243.     }
  244.     ;
  245.  
  246. day    : tDAY {
  247.         yyDayOrdinal = 1;
  248.         yyDayNumber = $1;
  249.     }
  250.     | tDAY ',' {
  251.         yyDayOrdinal = 1;
  252.         yyDayNumber = $1;
  253.     }
  254.     | tUNUMBER tDAY {
  255.         yyDayOrdinal = $1;
  256.         yyDayNumber = $2;
  257.     }
  258.     ;
  259.  
  260. date    : tUNUMBER '/' tUNUMBER {
  261.         yyMonth = $1;
  262.         yyDay = $3;
  263.     }
  264.     | tUNUMBER '/' tUNUMBER '/' tUNUMBER {
  265.         yyMonth = $1;
  266.         yyDay = $3;
  267.         yyYear = $5;
  268.     }
  269.     | tUNUMBER tSNUMBER tSNUMBER {
  270.         /* ISO 8601 format.  yyyy-mm-dd.  */
  271.         yyYear = $1;
  272.         yyMonth = -$2;
  273.         yyDay = -$3;
  274.     }
  275.     | tUNUMBER tMONTH tSNUMBER {
  276.         /* e.g. 17-JUN-1992.  */
  277.         yyDay = $1;
  278.         yyMonth = $2;
  279.         yyYear = -$3;
  280.     }
  281.     | tMONTH tUNUMBER {
  282.         yyMonth = $1;
  283.         yyDay = $2;
  284.     }
  285.     | tMONTH tUNUMBER ',' tUNUMBER {
  286.         yyMonth = $1;
  287.         yyDay = $2;
  288.         yyYear = $4;
  289.     }
  290.     | tUNUMBER tMONTH {
  291.         yyMonth = $2;
  292.         yyDay = $1;
  293.     }
  294.     | tUNUMBER tMONTH tUNUMBER {
  295.         yyMonth = $2;
  296.         yyDay = $1;
  297.         yyYear = $3;
  298.     }
  299.     ;
  300.  
  301. rel    : relunit tAGO {
  302.         yyRelSeconds = -yyRelSeconds;
  303.         yyRelMonth = -yyRelMonth;
  304.     }
  305.     | relunit
  306.     ;
  307.  
  308. relunit    : tUNUMBER tMINUTE_UNIT {
  309.         yyRelSeconds += $1 * $2 * 60L;
  310.     }
  311.     | tSNUMBER tMINUTE_UNIT {
  312.         yyRelSeconds += $1 * $2 * 60L;
  313.     }
  314.     | tMINUTE_UNIT {
  315.         yyRelSeconds += $1 * 60L;
  316.     }
  317.     | tSNUMBER tSEC_UNIT {
  318.         yyRelSeconds += $1;
  319.     }
  320.     | tUNUMBER tSEC_UNIT {
  321.         yyRelSeconds += $1;
  322.     }
  323.     | tSEC_UNIT {
  324.         yyRelSeconds++;
  325.     }
  326.     | tSNUMBER tMONTH_UNIT {
  327.         yyRelMonth += $1 * $2;
  328.     }
  329.     | tUNUMBER tMONTH_UNIT {
  330.         yyRelMonth += $1 * $2;
  331.     }
  332.     | tMONTH_UNIT {
  333.         yyRelMonth += $1;
  334.     }
  335.     ;
  336.  
  337. number    : tUNUMBER {
  338.         if (yyHaveTime && yyHaveDate && !yyHaveRel)
  339.         yyYear = $1;
  340.         else {
  341.         if ($1>10000) {
  342.             yyHaveDate++;
  343.             yyDay= ($1)%100;
  344.             yyMonth= ($1/100)%100;
  345.             yyYear = $1/10000;
  346.         }
  347.         else {
  348.             yyHaveTime++;
  349.             if ($1 < 100) {
  350.             yyHour = $1;
  351.             yyMinutes = 0;
  352.             }
  353.             else {
  354.                 yyHour = $1 / 100;
  355.                 yyMinutes = $1 % 100;
  356.             }
  357.             yySeconds = 0;
  358.             yyMeridian = MER24;
  359.             }
  360.         }
  361.     }
  362.     ;
  363.  
  364. o_merid    : /* NULL */ {
  365.         $$ = MER24;
  366.     }
  367.     | tMERIDIAN {
  368.         $$ = $1;
  369.     }
  370.     ;
  371.  
  372. %%
  373.  
  374. /* Month and day table. */
  375. static TABLE const MonthDayTable[] = {
  376.     { "january",    tMONTH,  1 },
  377.     { "february",    tMONTH,  2 },
  378.     { "march",        tMONTH,  3 },
  379.     { "april",        tMONTH,  4 },
  380.     { "may",        tMONTH,  5 },
  381.     { "june",        tMONTH,  6 },
  382.     { "july",        tMONTH,  7 },
  383.     { "august",        tMONTH,  8 },
  384.     { "september",    tMONTH,  9 },
  385.     { "sept",        tMONTH,  9 },
  386.     { "october",    tMONTH, 10 },
  387.     { "november",    tMONTH, 11 },
  388.     { "december",    tMONTH, 12 },
  389.     { "sunday",        tDAY, 0 },
  390.     { "monday",        tDAY, 1 },
  391.     { "tuesday",    tDAY, 2 },
  392.     { "tues",        tDAY, 2 },
  393.     { "wednesday",    tDAY, 3 },
  394.     { "wednes",        tDAY, 3 },
  395.     { "thursday",    tDAY, 4 },
  396.     { "thur",        tDAY, 4 },
  397.     { "thurs",