home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.bin / SourceCode / libcs / parsedate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-15  |  41.3 KB  |  1,600 lines

  1. # define NUMBER 257
  2. # define NUMBER4 258
  3. # define WEEKDAY 259
  4. # define MONTH 260
  5. # define HOUR 261
  6. # define SHOUR 262
  7. # define TODAY 263
  8. # define NOW 264
  9. # define TONIGHT 265
  10. # define NEXT 266
  11. # define THIS 267
  12. # define DAY 268
  13. # define WEEK 269
  14. # define FORTNIGHT 270
  15. # define UPCOMING 271
  16. # define EVERY 272
  17. # define FROM 273
  18. # define BEFORE 274
  19. # define THE 275
  20. # define A 276
  21. # define AT 277
  22. # define ON 278
  23. # define LAST 279
  24. # define AFTER 280
  25. # define IN 281
  26. # define OF 282
  27. # define AGO 283
  28. # define WORD_MONTH 284
  29. # define NOON 285
  30. # define AMPM 286
  31. # define TIMEKEY 287
  32. # define AND 288
  33. # define NWORD 289
  34. # define NTHWORD 290
  35. # define ST 291
  36. # define ND 292
  37. # define RD 293
  38. # define TH 294
  39. # define CHRISTMAS 295
  40. # define NEW 296
  41. # define YEAR 297
  42. # define ALL 298
  43. # define FOOLS 299
  44. # define JUNK 300
  45.  
  46. # line 124 "parsedate.y"
  47. #include <sys/types.h>
  48. #include <setjmp.h>
  49. #include <sys/time.h>
  50. #include <c.h>
  51.  
  52. # define MAXPEEP 3
  53. # define NDTMS 10
  54. # define NOYEAR -1901
  55. /* PTM: indicates ptm */
  56. # define PTM -1
  57. /* CURRTM: indicates current time */
  58. # define CURRTM -2
  59. /* CURRDATE: indicates current date (time set to -1). */
  60. # define CURRDATE -3
  61. /* PAST, FUTURE: logical values for past and future */
  62. # define PAST 1
  63. # define FUTURE 0
  64.  
  65. static int junk_err;            /* junk token give error? */
  66. static int ppf;                /* past, or future */
  67. static int nottoday;            /* future doesn't include today */
  68. static struct tm scurrtm;
  69. static struct tm *currtm = &scurrtm;    /* current time */
  70. static char *strp;            /* current position in date string */
  71. static int delim;            /* previous field delimiter */
  72. static jmp_buf errbuf;            /* jump location for parse errors */
  73. extern char *nxtarg();
  74. struct stable { char *text;  int token;  int lexval; };
  75. static int shour, tmkey;
  76. static struct tm ptm;
  77. static int pcount;
  78. static int result;
  79.  
  80. /* Date structure for constraining dates */
  81. struct dtm 
  82. { int repn;                      /* Current representation */
  83.   int days;
  84.   struct tm tm;
  85.   int count;
  86. };
  87.  
  88. static struct dtm dtm[NDTMS];
  89. static int dtmused[NDTMS];
  90.  
  91. /* Representations */
  92. # define RDAYS 0
  93. # define RTM 1
  94.  
  95. /*
  96.  *  Month and week day names (upper case only) and other words.
  97.  */
  98. static
  99. struct stable strings[] =
  100. {
  101.   { "JAN*UARY", MONTH, 0 },        /* months (0-11) */
  102.   { "FEB*RUARY", MONTH, 1 },
  103.   { "MAR*CH", MONTH, 2 },
  104.   { "APR*IL", MONTH, 3 },
  105.   { "MAY", MONTH, 4 },
  106.   { "JUN*E", MONTH, 5 },
  107.   { "JUL*Y", MONTH, 6 },
  108.   { "AUG*UST", MONTH, 7 },
  109.   { "SEP*TEMBER", MONTH, 8 },
  110.   { "OCT*OBER", MONTH, 9 },
  111.   { "NOV*EMBER", MONTH, 10 },
  112.   { "DEC*EMBER", MONTH, 11 },
  113.   { "SUN*DAY", WEEKDAY, 0 },    /* days of the week (0-6) */
  114.   { "MON*DAY", WEEKDAY, 1 },
  115.   { "TUE*SDAY", WEEKDAY, 2 },
  116.   { "WED*NESDAY", WEEKDAY, 3 },
  117.   { "THU*RSDAY", WEEKDAY, 4 },
  118.   { "FRI*DAY", WEEKDAY, 5 },
  119.   { "SAT*URDAY", WEEKDAY, 6 },
  120.   { "YESTERDAY", TODAY, -1 },    /* relative to today */
  121.   { "TODAY", TODAY, 0 },
  122.   { "TONIGHT", TONIGHT, 0 },
  123.   { "NOW", NOW, 0 },
  124.   { "AGO", AGO, 0 },
  125.   { "TOMORROW", TODAY, 1 },
  126.   { "NEXT", NEXT, 0 },        /* keywords */
  127.   { "THIS", THIS, 0 },
  128.   { "UPCOMING", UPCOMING, 0 },
  129.   { "DAY*S", DAY, 0 },
  130.   { "WEEK*S", WEEK, 0 },
  131.   { "MONTH*S", WORD_MONTH, 0 },
  132.   { "YEAR*S", YEAR, 0 },
  133.   { "ALL", ALL, 0 },
  134.   { "FOOL*S", FOOLS, 0 },
  135.   { "FORTNIGHT", FORTNIGHT, 0 },    /* two weeks (Australian) */
  136. /*  { "EVERY", EVERY, 0 }, */
  137.   { "FROM", FROM, 0 },
  138.   { "AFTER", AFTER, 0 },
  139.   { "BEFORE", BEFORE, 0 },
  140.   { "LAST", LAST, 0 },
  141.   { "THE", THE, 0 },
  142.   { "A", A, 0 },
  143.   { "AT", AT, 0 },
  144.   { "ON", ON, 0 },
  145.   { "IN", IN, 0 },
  146.   { "OF", OF, 0 },
  147. /*  { "AND", AND, 0 }, */
  148.   { "MORNING", TIMEKEY, 0 },    /* time keywords. Morning is 0:00 - 11:59 */
  149.   { "AFTERNOON", TIMEKEY, 12 }, /* Afternoon is 12:00 - 23:59 */
  150.   { "EVENING", TIMEKEY, 15 },    /* Evening is 15:00 - 02:59 */
  151.   { "NIGHT", TIMEKEY, 17 },    /* Night is 17:00 - 04:59 */
  152.   { "NOON", NOON, 12 },        /* time specifications */
  153.   { "MIDNIGHT", NOON, 24 },
  154.   { "ONE", NWORD, 1 },        /* numbers up to 19 */
  155.   { "TWO", NWORD, 2 },
  156.   { "THREE", NWORD, 3 },
  157.   { "FOUR", NWORD, 4 },
  158.   { "FIVE", NWORD, 5 },
  159.   { "SIX", NWORD, 6 },
  160.   { "SEVEN", NWORD, 7 },
  161.   { "EIGHT", NWORD, 8 },
  162.   { "NINE", NWORD, 9 },
  163.   { "TEN", NWORD, 10 },
  164.   { "ELEVEN", NWORD, 11 },
  165.   { "TWELVE", NWORD, 12 },
  166.   { "THIRTEEN", NWORD, 13 },
  167.   { "FOURTEEN", NWORD, 14 },
  168.   { "FIFTEEN", NWORD, 15 },
  169.   { "SIXTEEN", NWORD, 16 },
  170.   { "SEVENTEEN", NWORD, 17 },
  171.   { "EIGHTEEN", NWORD, 18 },
  172.   { "NINETEEN", NWORD, 19 },
  173.   { "FIRST", NTHWORD, 1 },        /* number up to 19th */
  174.   { "SECOND", NTHWORD, 2 },
  175.   { "THIRD", NTHWORD, 3 },
  176.   { "FOURTH", NTHWORD, 4 },
  177.   { "FIFTH", NTHWORD, 5 },
  178.   { "SIXTH", NTHWORD, 6 },
  179.   { "SEVENTH", NTHWORD, 7 },
  180.   { "EIGHT", NTHWORD, 8 },
  181.   { "NINTH", NTHWORD, 9 },
  182.   { "TENTH", NTHWORD, 10 },
  183.   { "ELEVENTH", NTHWORD, 11 },
  184.   { "TWELFTH", NTHWORD, 12 },
  185.   { "THIRTEENTH", NTHWORD, 13 },
  186.   { "FOURTEENTH", NTHWORD, 14 },
  187.   { "FIFTEENTH", NTHWORD, 15 },
  188.   { "SIXTEENTH", NTHWORD, 16 },
  189.   { "SEVENTEENTH", NTHWORD, 17 },
  190.   { "EIGHTEENTH", NTHWORD, 18 },
  191.   { "NINETEENTH", NTHWORD, 19 },
  192.   { "ST", ST, 0 },        /* for 1st */
  193.   { "ND", ND, 0 },        /* 2nd */
  194.   { "RD", RD, 0 },        /* 3rd */
  195.   { "TH", TH, 0 },        /* nth */
  196.   { "AM", AMPM, 0 },        /* time qualifiers */
  197.   { "A.M.", AMPM, 0 },
  198.   { "PM", AMPM, 12 },
  199.   { "P.M.", AMPM, 12 },
  200.   { "CHRISTMAS", CHRISTMAS, 1225 },    /* special dates */
  201.   { "NEW", NEW, 101 },
  202.   { 0, 0, 0 }
  203. };
  204.  
  205. #define yyclearin yychar = -1
  206. #define yyerrok yyerrflag = 0
  207. #ifndef YYMAXDEPTH
  208. #define YYMAXDEPTH 150
  209. #endif
  210. #ifndef YYSTYPE
  211. #define YYSTYPE int
  212. #endif
  213. static YYSTYPE yylval, yyval;
  214. # define YYERRCODE 256
  215.  
  216. # line 742 "parsedate.y"
  217.  
  218.  
  219. parsedate (str, tmp, settm, select, err)
  220. char *str;
  221. struct tm *tmp;
  222. int settm, select, err;
  223. {   long time (), curtim;
  224.     struct tm *localtime ();
  225.     char tstr[81];
  226.     int i;
  227.     register struct tm *rtm;
  228.  
  229.     junk_err = err;
  230.     if (settm)
  231.     { curtim = time (0);
  232.       rtm = localtime (&curtim);
  233.       *currtm = *rtm;
  234.     }
  235.     else
  236.     { *currtm = *tmp;
  237.     }
  238.  
  239.     /*  initialize lexical analyzer  */
  240.     for (i = 0; i < NDTMS; i++)
  241.       dtmused[i] = 0;
  242.     strcpyn(strp = tstr, str, 80);
  243.     tstr[80] = 0;
  244.     ptm.tm_year = NOYEAR;
  245.     ptm.tm_mon = -1;
  246.     ptm.tm_mday = -1;
  247.     ptm.tm_wday = -1;
  248.     ptm.tm_yday = -1;
  249.     ptm.tm_hour = -1;
  250.     ptm.tm_min = -1;
  251.     ptm.tm_sec = -1;
  252.     pcount = 0;
  253.     currtm->tm_yday = currtm->tm_wday = -1;
  254.     shour = -1;
  255.     tmkey = -1;
  256.     delim = 0;
  257.     ppf = select;
  258.     nottoday = 0;
  259.  
  260.     if (setjmp(errbuf) == 0)
  261.     {
  262.     yyparse();
  263.     rtm = &(dtm[result].tm);
  264.     setrep (&dtm[result], RTM);
  265.     rtm->tm_hour = ptm.tm_hour;
  266.     rtm->tm_min = ptm.tm_min;
  267.     rtm->tm_sec = ptm.tm_sec;
  268.     time_def (rtm, currtm);
  269.     /* If time is 24:00 or later, advance date to next day. */
  270.     if (rtm->tm_hour >= 24)
  271.     { incr (result, rtm->tm_hour / 24);
  272.       setrep (&dtm[result], RTM);
  273.       rtm->tm_hour = rtm->tm_hour % 24;
  274.     }
  275.     if (dtm[result].repn == RTM && dtm[result].tm.tm_yday == -1)
  276.       setrep (&dtm[result], RDAYS);
  277.     setrep (&dtm[result], RTM);
  278.     *tmp = dtm[result].tm;
  279.     return(0);            /* return here on successful parse */
  280.     }
  281.     else
  282.     return(CERROR);            /* return here on error */
  283.  
  284. }
  285.  
  286. /*
  287.  *  yyerror - error routine (called by yyparse)
  288.  *
  289.  *     Performs a jump to the error return location established
  290.  *  by pdate().
  291.  */
  292.  
  293. static yyerror()
  294. {
  295.  
  296.     longjmp(errbuf, 1);
  297.  
  298. }
  299.  
  300. static int prelval;
  301. static struct { int token; int val; } peep[MAXPEEP];
  302. static int peepb = 0, peepe = 0;
  303. static int lead0;
  304.  
  305. /*  yylex - return next token in date string.
  306.  * 
  307.  *  Obtains the tokens from nextlex() and returns them. Checks for
  308.  *  NUMBER tokens which are really HOURs. This is done by peeping ahead.
  309.  *  It gives more lookahead than yacc can support.
  310.  */
  311.  
  312. static int yylex ()
  313. { register int ctoken, htoken;
  314.   ctoken = nextlex();
  315.   htoken = lead0 ? HOUR : SHOUR;
  316.   if (ctoken == NUMBER && yylval <= 24)
  317.   { /* Possible hour - check it out */
  318.     peeper (1);                  /* Allow 1 token peeping */
  319.     if (peep[0].token == AMPM || peep[0].token == NOON)
  320.       return (htoken);                  /* NN AM or NN PM or 12 NOON */
  321.     if (peep[0].token == ':' || peep[0].token == '.')
  322.     { peeper (2);
  323.       if (peep[1].token == NUMBER)
  324.     return (htoken);             /* NN:NN or NN.NN */
  325.     }
  326.   }
  327.   return (ctoken);
  328. }
  329.  
  330. static int nextlex ()
  331. { register int token;
  332.   if (peepb < peepe)
  333.   { token = peep[peepb].token;
  334.     yylval = peep[peepb].val;
  335.     peepb++;
  336.   }
  337.   else
  338.   { token = prelex ();
  339.     yylval = prelval;
  340.   }
  341.   return (token);
  342. }
  343.  
  344. static peeper (n)
  345. int n;
  346. { register int i;
  347.   if (peepb != 0)
  348.   { for (i = peepb; i < peepe; i++)
  349.       peep[i-peepb] = peep[i];
  350.     peepe -= peepb;
  351.   }
  352.   peepb = 0;
  353.   while (peepe < n)
  354.   { peep[peepe].token = prelex ();
  355.     peep[peepe].val = prelval;
  356.     peepe++;
  357.   }
  358. }
  359.  
  360. /*
  361.  *  prelex - return next token in date string
  362.  *
  363.  *     Uses nxtarg() to parse the next field of the date string.
  364.  *  If a non-space, tab, comma or newline delimiter terminated the
  365.  *  previous field it is returned before the next field is parsed.
  366.  *
  367.  *     Returns either one of the delimiter characters " -:/.", the token
  368.  *  from a match on the table (with the associated value in yylval), or
  369.  *  NUMBER, or JUNK.
  370.  *  JUNK is any unrecognized token (depending on the call arguments to
  371.  *  parsedate - an unrecognized token may instead be returned as -1 simply
  372.  *  terminating the parse.)
  373.  *  NUMBER is a numeric string.  NUMBER4 is a 4-digit number.
  374.  *  If the numeric string commences with 0, then lead0 is true.
  375.  *  '@' sign is treated as the token AT.
  376.  */
  377.  
  378. static int wasabb;            /* tabfind indicates abbrev. */
  379.  
  380. static int prelex()
  381. {
  382.  
  383.   register int ret;            /* temp for previous delimiter */
  384.   register char *fp;            /* current field */
  385.   register int find, ndig;
  386.   extern char _argbreak;        /* current delimiter */
  387.  
  388.   while (1)
  389.   { if (ret=delim)
  390.     {
  391.     delim = 0;
  392.         if (ret == '@')
  393.         return (AT);
  394.         /* 
  395.          * Ignore all but the good characters
  396.          */
  397.     if (ret != ':' && ret != '/' && ret != '-' && ret != '.')
  398.         ret = 0;
  399.         if (ret != 0)
  400.       return (ret);
  401.     }
  402.     if (*strp == 0) return (0);
  403.     while (*strp == ' ' || *strp == '\t' || *strp == '\n')
  404.       strp++;
  405.  
  406.     if (*strp >= '0' && *strp <= '9')
  407.     { prelval = 0;
  408.       ndig = 0;
  409.       lead0 = *strp == '0';
  410.       while (*strp >= '0' && *strp <= '9')
  411.       { prelval = prelval * 10 + *strp - '0';
  412.     strp++;
  413.     ndig++;
  414.       }
  415.       if (ndig == 4)
  416.         return (NUMBER4);
  417.       return (NUMBER);
  418.     }
  419.     fp = nxtarg (&strp, " \t,-:/.@()[]\n");
  420.     delim = _argbreak;
  421.     if (*fp == 0 && delim == 0) return (0);  /* End of input string */
  422.     if (*fp != 0)                  /* skip null tokens */
  423.     { foldup(fp, fp);
  424.       /* Because of the embedded period, a.m. and p.m. do not work.
  425.        * Solution is to recognize them explicitly.
  426.        */
  427.       if (fp[1] == '\0' && (delim == '.' || delim == ' ') &&
  428.         (*fp == 'A' || *fp == 'P') && (*strp == 'M' || *strp == 'm') && 
  429.         (strp[1] == '.' || strp[1] == ' ' || strp[1] == '\t' ||
  430.           strp[1] == '\0'))
  431.       { /* It is a.m. or p.m. */
  432.         prelval = *fp == 'A' ? 0 : 12;
  433.         strp += 2;    /* Skip the m. */
  434.         delim = 0;
  435.         return (AMPM);
  436.       }
  437.       if ((find = tabfind(fp, strings)) >= 0)
  438.       {
  439.     if (wasabb && delim == '.')    /* If tabfind found abbrev */
  440.       delim = 0;            /* Discard period after abbrev. */
  441.         prelval = strings[find].lexval;
  442.         return(strings[find].token);
  443.       }
  444.       if (junk_err)
  445.         return (JUNK);
  446.       else
  447.     return (0);
  448.     }
  449.   }
  450. }
  451.  
  452. /* subroutines useful for manipulating dates and used by
  453.  * parsedate.y.
  454.  * 
  455.  * Copyright (c) Leonard G C Hamey, December 1983.
  456.  * 
  457.  * date_days (tm): converts the date portion of tm structure to days since
  458.  *   1 jan 1900 + 693960. Also can be used to obtain weekday (sunday == 0)
  459.  *   by taking modulo 7.
  460.  *
  461.  * days_date: converts days since 1/1/1900 + 693960 to date in tm structre.
  462.  * 
  463.  * tabfind: searches a table of keywords for date parsing.
  464.  * 
  465.  * constrain: fills in default fields under control of past/future
  466.  *     parameter.
  467.  */
  468.  
  469. static int date_days (tm)
  470. struct tm *tm;
  471. {   /* Number of days since 1/1/1900 + 693960 */
  472.     int dd = tm->tm_mday, mm = tm->tm_mon + 1, yyyy = tm->tm_year + 1900;
  473.     int f;
  474.  
  475.     if (mm >= 3)
  476.     {   f=365*yyyy+dd+31*mm-31-(4*mm+23)/10+yyyy/4-(75+(yyyy/100)*75)/100;
  477.     }
  478.     else
  479.     {   f=365*yyyy+dd+31*mm-31+(yyyy-1)/4-(75+((yyyy-1)/100)*75)/100;
  480.     }
  481.  
  482.     return (f-1);
  483. }
  484.  
  485. static int monthend[] =
  486. { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };
  487.  
  488. static days_date (d, tm)
  489. int d;
  490. struct tm *tm;
  491. {   /* Number of days since 1/1/1900 -> mm/dd/yyyy and weekday */
  492.     int t = d - 693960, leap;
  493.     int mm, yyyy;
  494.     tm->tm_year = 0;                  /* 1900 */
  495.     tm->tm_mon = 0;                  /* Jan */
  496.     tm->tm_mday = 1;
  497.     while (t < 0)                 /* handle dates before 1900 */
  498.     {   tm->tm_year += t / 366 - 1;
  499.         t = d - date_days (tm);
  500.     }
  501.     while (t >= 366)
  502.     {   tm->tm_year += t / 366;
  503.         t = d - date_days (tm);
  504.     }
  505.     yyyy = tm->tm_year + 1900;
  506.     leap = yearsize (yyyy) == 366;
  507.     if (! leap && t == 365)
  508.     { tm->tm_year++;
  509.       t = 0;
  510.     }
  511.     tm->tm_yday = t;                 /* Day in year (0-365) */
  512.     if (! leap && t >= 59)              /* If after Feb non leap */
  513.         t++;                      /* Fudge as if leap */
  514.     mm = t / 31;                  /* Guess the month */
  515.     if (t >= monthend[mm+1])              /* Check the guess */
  516.         mm++;
  517.     tm->tm_mday = t - monthend[mm] + 1;         /* Compute day in month */
  518.     tm->tm_mon = mm;
  519.     tm->tm_wday = d % 7;              /* Sunday = 0 */
  520. }
  521.  
  522. static int tabfind (text, table)
  523. char *text;
  524. struct stable *table;
  525. { int tp;
  526.   char *tep, *txp;
  527.   int find = -1, foundstar;
  528.   wasabb = 0;
  529.   for (tp = 0; table[tp].text; tp++)
  530.   { tep = table[tp].text;
  531.     txp = text;
  532.     foundstar = 0;
  533.     while (1)
  534.     { if (*tep == '*')
  535.       { foundstar = 1;
  536.     tep++;
  537.       }
  538.       if (! *txp)                  /* If end of text */
  539.       { if (! *tep)                  /* If also end of table entry */
  540.       return (tp);                 /* then found */
  541.     if (foundstar)
  542.     { if (find >= 0)
  543.         return (-2);              /* Ambiguous */
  544.       find = tp;                  /* Remember partial match */
  545.       wasabb = 1;                 /* Was abbrev. */
  546.       break;
  547.     }
  548.       }
  549.       if (*txp != *tep)
  550.     break;                      /* No match */
  551.       tep++;  txp++;
  552.     }
  553.   }
  554.   return (find);
  555. }
  556.  
  557. /* check: check that a date is valid. each of the constraint processing
  558.  *   routines is called in turn and if any of them do anything then the
  559.  *   date is invalid.
  560.  */
  561.  
  562. static check (date)
  563. int date;
  564. { register int did;
  565.   register struct dtm *d = &dtm[date];
  566.   if (d->repn != RTM)
  567.     return;
  568.   did = month (d, d->tm.tm_mon, FUTURE);
  569.   if (! did)
  570.     did = mday (d, d->tm.tm_mday, FUTURE);
  571.   if (! did && d->tm.tm_wday >= 0)
  572.     did = weekday (d, d->tm.tm_wday, FUTURE);
  573.   if (did)
  574.     yyerror ();
  575.   return;
  576. }
  577.  
  578. /* constrain: fill in defaults info in date. con is a dtm containing the 
  579.  *   constraints (or -1 indicating to use ptm). date is the dtm containing
  580.  *   the date to be constrained. repeat is the loop count. */
  581.  
  582. static constrain (con, date, past, repeat)
  583. int con, date;
  584. int past, repeat;
  585. { register int n;
  586.   register int did;
  587.   register struct tm *c;
  588.   register struct dtm *d = &dtm[date];
  589.   if (con >= 0)
  590.     c = &(dtm[con].tm);
  591.   else
  592.     c = &ptm;
  593.   if (c->tm_year != NOYEAR)
  594.     yyerror ();
  595.  
  596.   for (n = 1000, did = 0; ; did = 0)
  597.   { if (c->tm_mon >= 0)
  598.     { did |= month (d, c->tm_mon, past);
  599.     }
  600.     if (c->tm_mday >= 0)
  601.     { did |= mday (d, c->tm_mday, past);
  602.     }
  603.     if (c->tm_wday >= 0)
  604.     { did |= weekday (d, c->tm_wday, past);
  605.     }
  606.     if (! did)
  607.     { if (repeat-- <= 1)
  608.         break;
  609.       incr (date, past ? -1 : 1);
  610.     }
  611.     if (--n <= 0)
  612.       yyerror ();
  613.   }
  614.  
  615.   if (con >= 0)
  616.     dtmused[con] = 0;
  617.   else
  618.   { ptm.tm_year = NOYEAR;
  619.     ptm.tm_mon = -1;
  620.     ptm.tm_mday = -1;
  621.     ptm.tm_wday = -1;
  622.     ptm.tm_yday = -1;
  623.   }
  624. }
  625.  
  626. static time_def (tm, currtm)
  627. struct tm *tm, *currtm;
  628. { if (shour >= 0)            /* Handle simple hour specification */
  629.   { if (tmkey == -1)            /* and combine it with time key. */
  630.       tmkey = 8;            /* Default is 8:00 - 19:59 */
  631.     if (shour == 12)
  632.       shour = 0;
  633.     if (shour < tmkey)
  634.       shour += 12;
  635.     if (shour < tmkey)
  636.       shour += 12;
  637.     tm->tm_hour = shour;
  638.   }
  639.   if (tm->tm_hour >= 0)
  640.   { /* If time specified and fields left out, assume zero. */
  641.     if (tm->tm_min < 0)
  642.       tm->tm_min = 0;
  643.     if (tm->tm_sec < 0)
  644.       tm->tm_sec = 0;
  645.   }
  646. }
  647.  
  648. /* date constraint processing routines.
  649.  * 
  650.  * These routines allow determination of the first date after/before
  651.  * (but possibly equal to the existing date) which satisfies the given
  652.  * constraint(s).
  653.  */
  654.  
  655. /* The constraints are implemented by calling the appropriate routine(s)
  656.  * which check whether the particular constraint is satisfied, and if it
  657.  * is not, advances the date until the constraint is satisfied.
  658.  * 
  659.  * The date is stored in the dtm structure.
  660.  */
  661.  
  662. /* weekday: constrains the day of the week. */
  663.  
  664. static int weekday (dtm, wkday, past)
  665. struct dtm *dtm;
  666. int wkday;                      /* 0 = Sunday */
  667. int past;                      /* true = past */
  668. { int n;
  669.   setrep (dtm, RDAYS);
  670.   n = wkday - dtm->days % 7;          /* adjustment */
  671.   if (past)
  672.   { if (n > 0)
  673.       n -= 7;
  674.   }
  675.   else {
  676.     if (n < 0 || (nottoday && n == 0))
  677.       n += 7;
  678.     nottoday = 0;
  679.   }
  680.   dtm->days += n;
  681.   return (n != 0);
  682. }
  683.  
  684. /* month: constrains the month to the specified value. */
  685.  
  686. static int month (dtm, mon, past)
  687. struct dtm *dtm;
  688. int mon;
  689. int past;
  690. { setrep (dtm, RTM);
  691.   if (mon < 0 || mon > 11)
  692.     yyerror ();
  693.   if (dtm->tm.tm_mon != mon)
  694.   { if (past)
  695.     { if (dtm->tm.tm_mon < mon)          /* If earlier month */
  696.     dtm->tm.tm_year--;              /* Back up a year */
  697.       dtm->tm.tm_mday = monthend[mon+1] - monthend[mon];
  698.       if (mon == 1 && yearsize (dtm->tm.tm_year+1900) == 365)  /* Feb */
  699.     dtm->tm.tm_mday--;
  700.     }
  701.     else
  702.     { if (dtm->tm.tm_mon > mon)          /* If later month */
  703.     dtm->tm.tm_year++;              /* Advance a year */
  704.       dtm->tm.tm_mday = 1;
  705.     }
  706.     dtm->tm.tm_mon = mon;
  707.     dtm->tm.tm_wday = dtm->tm.tm_yday = -1;
  708.     return (1);
  709.   }
  710.   return (0);
  711. }
  712.  
  713. /* mday: constrains the month day to the specified value. Also
  714.  *   checks the validity of the specified value and, if it is invalid,
  715.  *   adjusts the month to compensate. */
  716.  
  717. static int mday (dtm, day, past)
  718. struct dtm *dtm;
  719. int day;
  720. int past;
  721. { register int maxday;
  722.   register int status = 0;
  723.   setrep (dtm, RTM);
  724.   if (dtm->tm.tm_mday != day)
  725.   { if (past)
  726.     { if (dtm->tm.tm_mday < day)           /* Earlier day */
  727.         if (dtm->tm.tm_mon-- == 0)         /* Back up a month */
  728.     { dtm->tm.tm_mon = 11;
  729.       dtm->tm.tm_year--;
  730.     }
  731.     }
  732.     else
  733.     { if (dtm->tm.tm_mday > day)           /* Later day */
  734.     if (dtm->tm.tm_mon++ == 11)           /* Advance month */
  735.     { dtm->tm.tm_mon = 0;
  736.       dtm->tm.tm_year++;
  737.     }
  738.     }
  739.     dtm->tm.tm_mday = day;
  740.     dtm->tm.tm_wday = dtm->tm.tm_yday = -1;
  741.     status = 1;
  742.   }
  743.   if (day >= 28)
  744.   { maxday = monthend[dtm->tm.tm_mon+1] - monthend[dtm->tm.tm_mon];
  745.     if (dtm->tm.tm_mon == 1 && yearsize (dtm->tm.tm_year + 1900) == 365)
  746.       maxday--;
  747.     if (day > maxday)
  748.     { if (past)
  749.         dtm->tm.tm_mday = maxday;
  750.       else
  751.       { dtm->tm.tm_mday = 1;
  752.     if (dtm->tm.tm_mon++ == 11)
  753.     { dtm->tm.tm_mon = 0;
  754.       dtm->tm.tm_year++;
  755.     }
  756.       }
  757.       dtm->tm.tm_wday = dtm->tm.tm_yday = -1;
  758.       return (1);
  759.     }
  760.   }
  761.   return (status);
  762. }
  763.  
  764. /* setrep: sets the representation of the date in a dtm structure. */
  765.  
  766. static setrep (dtm, rep)
  767. struct dtm *dtm;
  768. int rep;
  769. { if (dtm->repn == rep)
  770.     return;
  771.   if (dtm->repn == RDAYS)
  772.   { if (rep == RTM)
  773.       days_date (dtm->days, &(dtm->tm));
  774.   }
  775.   else if (dtm->repn == RTM)
  776.   { if (rep == RDAYS)
  777.       dtm->days = date_days (&(dtm->tm));
  778.   }
  779.   dtm->repn = rep;
  780.   return;
  781. }
  782.  
  783. /* yearsize: returns nuber of days in year. */
  784.  
  785. static yearsize (year)
  786. int year;
  787. { return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) ? 366 : 365);
  788. }
  789.  
  790. /* new_dtm: returns the index of a new dtm structure. If current is CURRTM,
  791.  *   the structure will contain a copy of the current date-time, else it
  792.  *   will contain a copy of ptm, and ptm will be reset to all -1.
  793.  */
  794.  
  795. static int new_dtm (current)
  796. int current;
  797. { register int i;
  798.   for (i = 0; i < NDTMS; i++)
  799.     if (! dtmused[i])
  800.     { dtmused[i] = 1;
  801.       if (current == CURRTM || current == CURRDATE)
  802.       { dtm[i].tm = *currtm;
  803.         if (current == CURRDATE)
  804.     { dtm[i].tm.tm_hour = -1;
  805.       dtm[i].tm.tm_min = -1;
  806.       dtm[i].tm.tm_sec = -1;
  807.     }
  808.     dtm[i].repn = RTM;
  809.     dtm[i].count = 0;
  810.       }
  811.       else
  812.       { dtm[i].tm = ptm;
  813.     dtm[i].count = pcount;
  814.     dtm[i].repn = RTM;
  815.     ptm.tm_year = NOYEAR;
  816.     ptm.tm_mon = -1;
  817.     ptm.tm_mday = -1;
  818.     ptm.tm_wday = -1;
  819.     ptm.tm_yday = -1;
  820.     pcount = 0;
  821.       }
  822.       return (i);
  823.     }
  824.   yyerror ();
  825. }
  826.  
  827. /* incr: increment date in dtm structure. */
  828.  
  829. static incr (ndtm, days)
  830. int ndtm;
  831. int days;
  832. { setrep (&dtm[ndtm], RDAYS);
  833.   dtm[ndtm].days += days;
  834. }
  835.  
  836. static incryear (ndtm, years)
  837. int ndtm;
  838. int years;
  839. { setrep (&dtm[ndtm], RTM);
  840.   dtm[ndtm].tm.tm_year += years;
  841.   dtm[ndtm].tm.tm_wday = -1;        /* Unknown */
  842.   dtm[ndtm].tm.tm_yday = -1;        /* Unknown */
  843. }
  844.  
  845. /* incrmonth: increment date in dtm structure by a number of months.*/
  846.  
  847. static incrmonth (ndtm, months)
  848. int ndtm;
  849. int months;
  850. { int inc;
  851.   inc = months > 0 ? 1 : -1;
  852.   setrep (&dtm[ndtm], RTM);        /* Use tm structure repn */
  853.   for ( ; months != 0; months -= inc)
  854.   { dtm[ndtm].tm.tm_mon += inc;
  855.     if (dtm[ndtm].tm.tm_mon < 0)
  856.     { dtm[ndtm].tm.tm_mon = 11;
  857.       dtm[ndtm].tm.tm_year--;
  858.     }
  859.     else if (dtm[ndtm].tm.tm_mon > 11)
  860.     { dtm[ndtm].tm.tm_mon = 0;
  861.       dtm[ndtm].tm.tm_year++;
  862.     }
  863.   }
  864.   dtm[ndtm].tm.tm_wday = -1;         /* Day of week is unknown */
  865.   dtm[ndtm].tm.tm_yday = -1;        /* Day of year is unknown */
  866. }
  867. static short yyexca[] ={
  868. -1, 1,
  869.     0, -1,
  870.     -2, 0,
  871. -1, 21,
  872.     285, 132,
  873.     286, 132,
  874.     -2, 137,
  875. -1, 22,
  876.     260, 127,
  877.     282, 127,
  878.     45, 127,
  879.     47, 124,
  880.     -2, 138,
  881. -1, 34,
  882.     274, 37,
  883.     280, 37,
  884.     -2, 39,
  885. -1, 35,
  886.     257, 33,
  887.     258, 33,
  888.     266, 33,
  889.     267, 33,
  890.     279, 33,
  891.     45, 33,
  892.     47, 33,
  893.     -2, 40,
  894. -1, 43,
  895.     257, 32,
  896.     258, 32,
  897.     266, 32,
  898.     267, 32,
  899.     279, 32,
  900.     45, 32,
  901.     47, 32,
  902.     -2, 41,
  903. -1, 44,
  904.     260, 128,
  905.     282, 128,
  906.     45, 128,
  907.     -2, 43,
  908. -1, 81,
  909.     47, 124,
  910.     -2, 127,
  911. -1, 109,
  912.     45, 128,
  913.     -2, 43,
  914. -1, 112,
  915.     274, 35,
  916.     -2, 20,
  917. -1, 116,
  918.     260, 128,
  919.     282, 128,
  920.     45, 128,
  921.     -2, 44,
  922. -1, 117,
  923.     257, 32,
  924.     258, 32,
  925.     266, 32,
  926.     267, 32,
  927.     279, 32,
  928.     45, 32,
  929.     47, 32,
  930.     -2, 45,
  931. -1, 178,
  932.     45, 128,
  933.     -2, 44,
  934.     };
  935. # define YYNPROD 148
  936. # define YYLAST 498
  937. static short yyact[]={
  938.  
  939.   22,  20,  36,  58,  32,  33,  30,   6,  41,  25,
  940.   24,  50,  51,  52, 169, 166, 198, 197,  10,  49,
  941.   12,  81,  26,  36,  58, 196, 168, 149,  19, 149,
  942.   15,  15,  21,  57,  22, 106,  36,  58,  60,  61,
  943.   30,  62,  41,  25,  24,  50,  51,  52, 101, 100,
  944.  155,  15,  10,  49,  57,  68,  26,  75,  81,  60,
  945.   61,  58,  62, 137,  15, 138,  71,  57,  22, 157,
  946.   36,  58,  60,  61,  30,  62,  41,  25,  24,  50,
  947.   51,  52, 102, 103, 104, 105,  10,  49, 156, 201,
  948.   26,  57,  81,  72,  36,  58,  60,  61,  15,  62,
  949.   71,  57,  22, 152,  36,  58,  60,  61,  30,  62,
  950.   41,  25,  24,  50,  51,  52,  81, 163,  36,  58,
  951.  174,  49,  57, 180,  26,  57,  81,  78,  36,  58,
  952.   60,  61, 172,  62,  71,  57,  57,  78,  83, 164,
  953.   60,  61, 146,  62,  93,  94,  15,  95,  83,  57,
  954.   81,  97,  96,  58,  60,  61, 214,  62, 213,  57,
  955.   91, 152, 113, 114,  60,  61, 167,  62, 119, 160,
  956.  161, 162, 204,  92,  90,  20,  55,  20,  32,  33,
  957.   32,  33, 182,  57, 221, 158, 183, 184,  60,  61,
  958.   36,  62, 207, 150,  57, 204,  12, 219, 159, 122,
  959.  123, 148,  19, 181,  19, 165,  21, 155,  67, 129,
  960.  134, 129, 131, 129, 126,  99, 128,  15, 128, 135,
  961.  128, 132,  36, 127, 139, 140,  45,  98,  64,   9,
  962.   41, 146,  65, 143, 141,  18,  43,  86,  73, 152,
  963.   76, 152, 144,  11,   8, 220, 142,  84,  40, 136,
  964.   47,  86,  86,  86, 108,  46,  87, 147,  48,  77,
  965.  124,  84,  84,  84, 117,   5,  79,  17, 125,  80,
  966.   66, 150,  57, 150,  57, 139, 140,  16, 120,  27,
  967.  110, 110, 110, 176, 143, 141, 121,  75,  34,  35,
  968.   85,   7,   4,  74, 124, 108,   3, 142,  69,  82,
  969.   31, 151,  39, 185,  85,  85,  85, 130, 133,  88,
  970.   86,  38,  86, 107, 111, 112, 170, 118,  37, 173,
  971.   84,  59, 179,  29, 145,  70,  13,  63, 115,  56,
  972.  154,  44, 206,  86,  53,  54,  42,  28,  89, 110,
  973.   23, 110, 151,  84,  14,   2,   1,   0,   0,   0,
  974.    0, 202,   0,   0,   0,   0, 109, 109, 109, 116,
  975.  175, 171, 110,  85,   0,   0,   0, 212,   0,   0,
  976.    0, 189, 177, 190, 191, 187, 192, 153,  80, 193,
  977.    0, 203, 205, 208, 209,   0,  85, 194, 195,   0,
  978.    0,   0,   0,   0,   0, 186,   0,   0,   0,   0,
  979.    0,  86, 215, 217,   0, 151,   0,   0, 210, 211,
  980.  218,  84,   0,   0,   0, 109,   0, 178, 153,   0,
  981.  216, 151,   0,  77, 199,   0,   0,   0,   0,   0,
  982.   79,   0,   0,  80,   0,   0,   0,   0, 109,   0,
  983.    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  984.    0, 188,   0,   0,  85,   0,   0,   0,   0,   0,
  985.    0,   0,   0,  82,   0,   0,   0,   0,   0,   0,
  986.    0,   0,   0,   0,   0,   0,   0,   0,   0, 200,
  987.    0, 153,   0,   0,   0,   0,   0,   0,   0,   0,
  988.    0,   0,   0,   0,   0,   0,   0, 153 };
  989. static short yypact[]={
  990.  
  991. -257,-1000,-1000, -35, -81,-223,-1000,-188,-256,-225,
  992. -141,-1000, -83,-124,-1000,-1000,-134, 169,-237,-1000,
  993. -1000,-1000,-209,-1000,-236,-165,-165,-107,-1000,-1000,
  994.  -70,-1000,-1000,-1000,-1000,-1000,-1000, -60, -62, -64,
  995. -1000,-1000,  18,-1000, -37, -18,   5,-194,-213, -99,
  996. -1000,-1000,-1000,-163,-135, 158,-1000,-1000,-284,-1000,
  997. -102,-271,-285,-1000,-256,-256, -33,-1000,-189,-1000,
  998. -124,-1000,-143,-1000,-155,-1000,-225,-1000,-1000,   5,
  999. -1000,-209,-1000,-165,-1000,-199, -16,-1000,-1000,-1000,
  1000. -1000,-1000,-1000,-1000,-1000,-152,-1000,-1000, -75, -75,
  1001. -1000,-1000,-1000,-1000,-1000,-1000,-165,-1000,-1000,-1000,
  1002.  162,-1000,-1000,-1000,-1000,-1000,-126,-1000,-1000,-154,
  1003. -194,-213,-1000,-1000,-1000,-1000,-155,-1000,-155,-155,
  1004. -1000,-155,-1000,-1000,-155,-1000,-1000, -33, -33,-1000,
  1005. -1000,-272,-280,-281, -69,-1000,-1000,-168,-1000, -96,
  1006. -1000,-1000,-209,-1000, -88, -65, -88, -88,-1000,-1000,
  1007. -1000,-1000,-1000,-155,-155, -96,-110,-1000,-1000,-112,
  1008. -1000,-1000,-256,-1000,-131,-155, -88,-1000,-1000,-1000,
  1009. -256, 139,-1000,-1000,-1000,-1000,-1000,-225,-126,-1000,
  1010. -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
  1011. -1000,-209,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
  1012. -1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, -73,
  1013. -1000,-1000 };
  1014. static short yypgo[]={
  1015.  
  1016.    0, 346, 345, 296, 292, 265, 249, 323, 244, 229,
  1017.  283, 344, 340, 288, 279, 337, 300, 336, 236, 289,
  1018.  335, 334, 331, 329, 321, 268, 318, 311, 302, 248,
  1019.  325, 258, 250, 226, 255, 176, 201, 243, 291, 277,
  1020.  267, 203, 245, 235 };
  1021. static short yyr1[]={
  1022.  
  1023.    0,   1,   2,   2,   2,   2,   2,   2,   2,   2,
  1024.    2,   4,   4,   4,   4,   8,  11,  11,  11,  11,
  1025.   11,  11,  11,  11,  11,  11,  11,  11,  11,  16,
  1026.   16,  16,  17,  17,  20,  20,  20,  21,  21,  12,
  1027.   12,  13,  13,  13,  13,  13,  14,  23,  24,  24,
  1028.   24,  24,  24,  24,  24,  25,  25,  15,  15,  15,
  1029.   15,  15,  15,  15,  15,  15,  15,  15,  29,  29,
  1030.    7,   7,   7,   7,  27,  27,  28,  28,  26,  26,
  1031.   26,  26,  26,  26,  26,  26,  26,  26,  26,  19,
  1032.   19,  19,  19,  19,  18,  18,  18,  18,  18,  18,
  1033.    5,   5,   5,   3,   3,  38,   9,  37,  37,  37,
  1034.   37,  37,  37,  37,  37,  37,  39,  39,  33,   6,
  1035.    6,   6,   6,   6,  35,  36,  36,  34,  34,  40,
  1036.   40,  43,  43,  41,  41,  41,  42,  30,  30,  22,
  1037.   22,  22,  22,  22,  10,  10,  32,  31 };
  1038. static short yyr2[]={
  1039.  
  1040.    0,   1,   1,   2,   3,   3,   2,   1,   1,   2,
  1041.    1,   1,   3,   4,   2,   1,   1,   3,   2,   2,
  1042.    2,   2,   2,   1,   1,   2,   2,   1,   2,   2,
  1043.    3,   3,   1,   1,   1,   2,   3,   1,   2,   1,
  1044.    1,   1,   1,   1,   2,   2,   1,   1,   1,   2,
  1045.    2,   2,   3,   2,   3,   2,   2,   2,   3,   2,
  1046.    2,   3,   2,   2,   3,   2,   1,   2,   3,   3,
  1047.    1,   1,   2,   2,   2,   2,   2,   2,   2,   1,
  1048.    1,   2,   2,   1,   2,   2,   1,   2,   1,   3,
  1049.    3,   4,   3,   3,   3,   2,   3,   3,   3,   1,
  1050.    1,   2,   2,   1,   4,   1,   1,   1,   4,   5,
  1051.    2,   2,   1,   2,   2,   1,   3,   3,   1,   1,
  1052.    1,   2,   2,   2,   1,   1,   1,   1,   1,   1,
  1053.    1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
  1054.    2,   2,   2,   2,   1,   0,   2,   2 };
  1055. static short yychk[]={
  1056.  
  1057. -1000,  -1,  -2,  -3,  -4,  -5, 264, -38,  -8,  -9,
  1058.  275, -37, 277, -30, -11, 287, -39, -40, -43, 285,
  1059.  258, 289, 257, -12, 267, 266, 279, -14, -15,  -7,
  1060.  263, -16, 261, 262, -13, -19, 259, -26, -27, -28,
  1061.  -29, 265, -17, -18, -22, -33, -34, -32, -31, 276,
  1062.  268, 269, 270, -21, -20, -35, -23, 290, 260, -24,
  1063.  295, 296, 298,  -7, 263, 267,  -5, 289, 278,  -4,
  1064.  -30, 289, 281,  -9, -10, 282,  -9, -29, 268, -34,
  1065.  -31, 257, -13, 279, -18, -14, -33, -37,  -3, -30,
  1066.  257, 284, 297, 268, 269, 281, 286, 285,  58,  46,
  1067.  286, 285, 291, 292, 293, 294, 271, -13,  -9, -22,
  1068.  -34, -13, -13, 269, 270, -16, -22, -18, -19, 275,
  1069.  -32, -31, 269, 270,  -9, -25, 274, 283, 280, 273,
  1070.  -25, 274, 283, -25, 274, 283,  -6,  45,  47, 257,
  1071.  258, 267, 279, 266, 279, -14, 268, 275, -36,  45,
  1072.  289, -34, 257, -22, -10,  45, 282, 282, 284, 297,
  1073.  268, 269, 270, 280, 274,  47, 299, 268, 297, 299,
  1074.   -6,  -4, 275,  -8, 275, -10, -10, -13, -22, -18,
  1075.  275, -41, 257, 261, 262, -41, -13, -34, -22,  -8,
  1076.   -8,  -8,  -8,  -8,  -6,  -6, 297, 297, 297, -14,
  1077.  -22, 257, -36, -33, 260, -33, -35, 257, -33, -33,
  1078.   -8,  -8, -36, 268, 268,  -9,  -8, -33,  -9,  58,
  1079.  -42, 257 };
  1080. static short yydef[]={
  1081.  
  1082.    0,  -2,   1,   2,   7,   8,  10, 103,  11, 145,
  1083.    0, 100,   0, 105,  15, 106, 107, 131,   0, 112,
  1084.  115,  -2,  -2,  16,   0,   0,   0,  42,  23,  24,
  1085.   70,  27, 129, 130,  -2,  -2,  46,   0,   0,   0,
  1086.   66,  71,   0,  -2,  -2,   0, 145,  80,  79,   0,
  1087.   83,  86,  88,  34,   0,   0,  99, 139, 118,  47,
  1088.   48,   0,   0,   9,  70,   0,   3, 132,   0,   6,
  1089.    0, 137,   0,  14,   0, 144, 145,  67,  81, 145,
  1090.  146,  -2,  37,   0,  41,  42,   0, 101, 102, 105,
  1091.  138,  74,  76,  78,  84,   0, 111, 114,   0,   0,
  1092.  110, 113, 140, 141, 142, 143,   0,  18,  72,  -2,
  1093.    0,  19,  -2,  21,  22,  28,  -2,  -2,  33,   0,
  1094.    0,   0,  25,  26,  73,  57,   0,  59,   0,   0,
  1095.   60,   0,  62,  63,   0,  65,  29,   0,   0, 119,
  1096.  120,   0,   0,   0,   0,  38, 147,   0,  95,   0,
  1097.  125, 126, 127, 128,   0,   0,   0,   0,  75,  77,
  1098.   82,  85,  87,   0,   0,   0,  53,  49,  50,  51,
  1099.    4,   5,   0,  12,   0,   0,   0,  35,  -2,  45,
  1100.    0, 116, 133, 134, 135, 117,  17, 145, 128,  58,
  1101.   55,  56,  61,  64,  30,  31, 121, 122, 123,  36,
  1102.   89,   0,  96,  90, 118,  97,  98, 124,  92,  93,
  1103.   68,  69,  94,  54,  52, 104,  13,  91, 108,   0,
  1104.  109, 136 };
  1105. # line 1 "/usr/lib/yaccpar"
  1106. #ifndef lint
  1107. static char yaccpar_sccsid[] = "@(#)yaccpar    4.1    (Berkeley)    2/11/83";
  1108. #endif not lint
  1109.  
  1110. # define YYFLAG -1000
  1111. # define YYERROR goto yyerrlab
  1112. # define YYACCEPT return(0)
  1113. # define YYABORT return(1)
  1114.  
  1115. /*    parser for yacc output    */
  1116.  
  1117. #ifdef YYDEBUG
  1118. static int yydebug = 0; /* 1 for debugging */
  1119. #endif
  1120. static YYSTYPE yyv[YYMAXDEPTH]; /* where the values are stored */
  1121. static int yychar = -1; /* current input token number */
  1122. static int yynerrs = 0;  /* number of errors */
  1123. static short yyerrflag = 0;  /* error recovery flag */
  1124.  
  1125. static yyparse() {
  1126.  
  1127.     short yys[YYMAXDEPTH];
  1128.     short yyj, yym;
  1129.     register YYSTYPE *yypvt;
  1130.     register short yystate, *yyps, yyn;
  1131.     register YYSTYPE *yypv;
  1132.     register short *yyxi;
  1133.  
  1134.     yystate = 0;
  1135.     yychar = -1;
  1136.     yynerrs = 0;
  1137.     yyerrflag = 0;
  1138.     yyps= &yys[-1];
  1139.     yypv= &yyv[-1];
  1140.  
  1141.  yystack:    /* put a state and value onto the stack */
  1142.  
  1143. #ifdef YYDEBUG
  1144.     if( yydebug  ) printf( "state %d, char 0%o\n", yystate, yychar );
  1145. #endif
  1146.         if( ++yyps>= &yys[YYMAXDEPTH] ) { yyerror( "yacc stack overflow" ); return(1); }
  1147.         *yyps = yystate;
  1148.         ++yypv;
  1149.         *yypv = yyval;
  1150.  
  1151.  yynewstate:
  1152.  
  1153.     yyn = yypact[yystate];
  1154.  
  1155.     if( yyn<= YYFLAG ) goto yydefault; /* simple state */
  1156.  
  1157.     if( yychar<0 ) if( (yychar=yylex())<0 ) yychar=0;
  1158.     if( (yyn += yychar)<0 || yyn >= YYLAST ) goto yydefault;
  1159.  
  1160.     if( yychk[ yyn=yyact[ yyn ] ] == yychar ){ /* valid shift */
  1161.         yychar = -1;
  1162.         yyval = yylval;
  1163.         yystate = yyn;
  1164.         if( yyerrflag > 0 ) --yyerrflag;
  1165.         goto yystack;
  1166.         }
  1167.  
  1168.  yydefault:
  1169.     /* default state action */
  1170.  
  1171.     if( (yyn=yydef[yystate]) == -2 ) {
  1172.         if( yychar<0 ) if( (yychar=yylex())<0 ) yychar = 0;
  1173.         /* look through exception table */
  1174.  
  1175.         for( yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=yystate) ; yyxi += 2 ) ; /* VOID */
  1176.  
  1177.         while( *(yyxi+=2) >= 0 ){
  1178.             if( *yyxi == yychar ) break;
  1179.             }
  1180.         if( (yyn = yyxi[1]) < 0 ) return(0);   /* accept */
  1181.         }
  1182.  
  1183.     if( yyn == 0 ){ /* error */
  1184.         /* error ... attempt to resume parsing */
  1185.  
  1186.         switch( yyerrflag ){
  1187.  
  1188.         case 0:   /* brand new error */
  1189.  
  1190.             yyerror( "syntax error" );
  1191.         yyerrlab:
  1192.             ++yynerrs;
  1193.  
  1194.         case 1:
  1195.         case 2: /* incompletely recovered error ... try again */
  1196.  
  1197.             yyerrflag = 3;
  1198.  
  1199.             /* find a state where "error" is a legal shift action */
  1200.  
  1201.             while ( yyps >= yys ) {
  1202.                yyn = yypact[*yyps] + YYERRCODE;
  1203.                if( yyn>= 0 && yyn < YYLAST && yychk[yyact[yyn]] == YYERRCODE ){
  1204.                   yystate = yyact[yyn];  /* simulate a shift of "error" */
  1205.                   goto yystack;
  1206.                   }
  1207.                yyn = yypact[*yyps];
  1208.  
  1209.                /* the current yyps has no shift onn "error", pop stack */
  1210.  
  1211. #ifdef YYDEBUG
  1212.                if( yydebug ) printf( "error recovery pops state %d, uncovers %d\n", *yyps, yyps[-1] );
  1213. #endif
  1214.                --yyps;
  1215.                --yypv;
  1216.                }
  1217.  
  1218.             /* there is no state on the stack with an error shift ... abort */
  1219.  
  1220.     yyabort:
  1221.             return(1);
  1222.  
  1223.  
  1224.         case 3:  /* no shift yet; clobber input char */
  1225.  
  1226. #ifdef YYDEBUG
  1227.             if( yydebug ) printf( "error recovery discards char %d\n", yychar );
  1228. #endif
  1229.  
  1230.             if( yychar == 0 ) goto yyabort; /* don't discard EOF, quit */
  1231.             yychar = -1;
  1232.             goto yynewstate;   /* try again in the same state */
  1233.  
  1234.             }
  1235.  
  1236.         }
  1237.  
  1238.     /* reduction by production yyn */
  1239.  
  1240. #ifdef YYDEBUG
  1241.         if( yydebug ) printf("reduce %d\n",yyn);
  1242. #endif
  1243.         yyps -= yyr2[yyn];
  1244.         yypvt = yypv;
  1245.         yypv -= yyr2[yyn];
  1246.         yyval = yypv[1];
  1247.         yym=yyn;
  1248.             /* consult goto table to find next state */
  1249.         yyn = yyr1[yyn];
  1250.         yyj = yypgo[yyn] + *yyps + 1;
  1251.         if( yyj>=YYLAST || yychk[ yystate = yyact[yyj] ] != -yyn ) yystate = yyact[yypgo[yyn]];
  1252.         switch(yym){
  1253.             
  1254. case 1:
  1255. # line 290 "parsedate.y"
  1256. { result = yyval;
  1257.               check (yyval); } break;
  1258. case 2:
  1259. # line 295 "parsedate.y"
  1260. { yyval = new_dtm (CURRDATE); } break;
  1261. case 4:
  1262. # line 304 "parsedate.y"
  1263. { setrep (&(dtm[yyval]), RTM);
  1264.               dtm[yyval].tm.tm_year = ptm.tm_year;
  1265.               dtm[yyval].tm.tm_wday = -1;
  1266.               dtm[yyval].tm.tm_yday = -1; } break;
  1267. case 5:
  1268. # line 309 "parsedate.y"
  1269. { yyval = yypvt[-0]; } break;
  1270. case 6:
  1271. # line 311 "parsedate.y"
  1272. { yyval = yypvt[-0]; } break;
  1273. case 8:
  1274. # line 314 "parsedate.y"
  1275. { yyval = new_dtm (CURRDATE); } break;
  1276. case 9:
  1277. # line 316 "parsedate.y"
  1278. { yyval = new_dtm (CURRDATE);
  1279.               incr (yyval, yypvt[-0]); } break;
  1280. case 10:
  1281. # line 319 "parsedate.y"
  1282. { yyval = new_dtm (CURRDATE);
  1283.               ptm.tm_hour = currtm->tm_hour;
  1284.               ptm.tm_min = currtm->tm_min;
  1285.               ptm.tm_sec = currtm->tm_sec; } break;
  1286. case 12:
  1287. # line 327 "parsedate.y"
  1288. { yyval = yypvt[-0]; } break;
  1289. case 13:
  1290. # line 329 "parsedate.y"
  1291. { yyval = yypvt[-0]; } break;
  1292. case 15:
  1293. # line 334 "parsedate.y"
  1294. { check (yyval); } break;
  1295. case 16:
  1296. # line 338 "parsedate.y"
  1297. { yyval = new_dtm (CURRDATE);
  1298.               constrain (PTM, yyval, ppf, 1); } break;
  1299. case 17:
  1300. # line 341 "parsedate.y"
  1301. { yyval = new_dtm (CURRDATE);
  1302.               nottoday = 1;
  1303.               constrain (PTM, yyval, FUTURE, 1); } break;
  1304. case 18:
  1305. # line 345 "parsedate.y"
  1306. { yyval = new_dtm (CURRDATE);
  1307.               constrain (PTM, yyval, FUTURE, 1); } break;
  1308. case 19:
  1309. # line 348 "parsedate.y"
  1310. { yyval = new_dtm (CURRDATE);
  1311.               constrain (PTM, yyval, FUTURE, 2); } break;
  1312. case 20:
  1313. # line 351 "parsedate.y"
  1314. { yyval = new_dtm (CURRDATE);
  1315.               incr (yyval, -1);
  1316.               constrain (PTM, yyval, PAST, 1); } break;
  1317. case 21:
  1318. # line 355 "parsedate.y"
  1319. { yyval = new_dtm (CURRDATE);
  1320.               constrain (PTM, yyval, FUTURE, 1);
  1321.               incr (yyval, 7); } break;
  1322. case 22:
  1323. # line 359 "parsedate.y"
  1324. { yyval = new_dtm (CURRDATE);
  1325.               constrain (PTM, yyval, FUTURE, 1);
  1326.               incr (yyval, 14); } break;
  1327. case 24:
  1328. # line 364 "parsedate.y"
  1329. { yyval = new_dtm (CURRDATE);
  1330.               incr (yyval, yypvt[-0]); } break;
  1331. case 25:
  1332. # line 367 "parsedate.y"
  1333. { yyval = new_dtm (CURRDATE);
  1334.               incr (yyval, yypvt[-1] + 7); } break;
  1335. case 26:
  1336. # line 370 "parsedate.y"
  1337. { yyval = new_dtm (CURRDATE);
  1338.               incr (yyval, yypvt[-1] + 14); } break;
  1339. case 27:
  1340. # line 373 "parsedate.y"
  1341. { yyval = new_dtm (PTM); } break;
  1342. case 28:
  1343. # line 375 "parsedate.y"
  1344. { yyval = new_dtm (PTM); } break;
  1345. case 35:
  1346. # line 394 "parsedate.y"
  1347. { yyval = new_dtm (PTM); } break;
  1348. case 36:
  1349. # line 396 "parsedate.y"
  1350. { yyval = new_dtm (PTM);
  1351.               dtm[yyval].count = yypvt[-2]; } break;
  1352. case 37:
  1353. # line 401 "parsedate.y"
  1354. { yyval = new_dtm (PTM); } break;
  1355. case 38:
  1356. # line 403 "parsedate.y"
  1357. { yyval = new_dtm (PTM);
  1358.               dtm[yyval].count = yypvt[-1]; } break;
  1359. case 43:
  1360. # line 418 "parsedate.y"
  1361. { ptm.tm_mday = yypvt[-0]; } break;
  1362. case 44:
  1363. # line 420 "parsedate.y"
  1364. { ptm.tm_mday = yypvt[-0]; } break;
  1365. case 46:
  1366. # line 425 "parsedate.y"
  1367. { ptm.tm_wday = yypvt[-0]; } break;
  1368. case 47:
  1369. # line 429 "parsedate.y"
  1370. { ptm.tm_mon = yypvt[-0]/100-1; ptm.tm_mday = yypvt[-0]%100; } break;
  1371. case 51:
  1372. # line 436 "parsedate.y"
  1373. { yyval = 401; } break;
  1374. case 52:
  1375. # line 438 "parsedate.y"
  1376. { yyval = 401; } break;
  1377. case 53:
  1378. # line 440 "parsedate.y"
  1379. { if (yypvt[-1] != 3)  yyerror ();
  1380.               yyval = 401; } break;
  1381. case 54:
  1382. # line 443 "parsedate.y"
  1383. { if (yypvt[-2] != 3)  yyerror ();
  1384.               yyval = 401; } break;
  1385. case 55:
  1386. # line 452 "parsedate.y"
  1387. { yyval = yypvt[-0]; } break;
  1388. case 56:
  1389. # line 454 "parsedate.y"
  1390. { yyval = yypvt[-0]; } break;
  1391. case 57:
  1392. # line 462 "parsedate.y"
  1393. { yyval = yypvt[-0];
  1394.               incr (yyval, yypvt[-1]); } break;
  1395. case 58:
  1396. # line 465 "parsedate.y"
  1397. { yyval = yypvt[-0];
  1398.               incr (yyval, -yypvt[-2]); } break;
  1399. case 59:
  1400. # line 468 "parsedate.y"
  1401. { yyval = new_dtm (CURRTM);
  1402.               incr (yyval, -yypvt[-1]); } break;
  1403. case 60:
  1404. # line 471 "parsedate.y"
  1405. { yyval = yypvt[-0];
  1406.               incrmonth (yyval, yypvt[-1]); } break;
  1407. case 61:
  1408. # line 474 "parsedate.y"
  1409. { yyval = yypvt[-0];
  1410.               incrmonth (yyval, -yypvt[-2]); } break;
  1411. case 62:
  1412. # line 477 "parsedate.y"
  1413. { yyval = new_dtm (CURRDATE);
  1414.               incrmonth (yyval, -yypvt[-1]); } break;
  1415. case 63:
  1416. # line 480 "parsedate.y"
  1417. { yyval = yypvt[-0];
  1418.               incryear (yyval, yypvt[-1]); } break;
  1419. case 64:
  1420. # line 483 "parsedate.y"
  1421. { yyval = yypvt[-0];
  1422.               incryear (yyval, -yypvt[-2]); } break;
  1423. case 65:
  1424. # line 486 "parsedate.y"
  1425. { yyval = new_dtm (CURRDATE);
  1426.               incryear (yyval, -yypvt[-1]); } break;
  1427. case 67:
  1428. # line 490 "parsedate.y"
  1429. { yyval = yypvt[-0]; } break;
  1430. case 68:
  1431. # line 499 "parsedate.y"
  1432. { yyval = yypvt[-0];
  1433.               incr (yyval, 1);
  1434.               constrain (yypvt[-2], yyval, FUTURE, dtm[yypvt[-2]].count); } break;
  1435. case 69:
  1436. # line 503 "parsedate.y"
  1437. { yyval = yypvt[-0];
  1438.               incr (yyval, -1);
  1439.               constrain (yypvt[-2], yyval, PAST, dtm[yypvt[-2]].count); } break;
  1440. case 71:
  1441. # line 515 "parsedate.y"
  1442. { tmkey = 17; } break;
  1443. case 73:
  1444. # line 518 "parsedate.y"
  1445. { if (yypvt[-1] == 0) yyerror (); } break;
  1446. case 74:
  1447. # line 526 "parsedate.y"
  1448. { yyval = yypvt[-1]; } break;
  1449. case 75:
  1450. # line 528 "parsedate.y"
  1451. { yyval = 1; } break;
  1452. case 76:
  1453. # line 536 "parsedate.y"
  1454. { yyval = yypvt[-1]; } break;
  1455. case 77:
  1456. # line 538 "parsedate.y"
  1457. { yyval = 1; } break;
  1458. case 81:
  1459. # line 549 "parsedate.y"
  1460. { yyval = 1; } break;
  1461. case 82:
  1462. # line 551 "parsedate.y"
  1463. { yyval = 1; } break;
  1464. case 83:
  1465. # line 553 "parsedate.y"
  1466. { yyval = 1; } break;
  1467. case 84:
  1468. # line 555 "parsedate.y"
  1469. { yyval = yypvt[-1] * 7; } break;
  1470. case 85:
  1471. # line 557 "parsedate.y"
  1472. { yyval = 7; } break;
  1473. case 86:
  1474. # line 559 "parsedate.y"
  1475. { yyval = 7; } break;
  1476. case 87:
  1477. # line 561 "parsedate.y"
  1478. { yyval = 14; } break;
  1479. case 88:
  1480. # line 563 "parsedate.y"
  1481. { yyval = 14; } break;
  1482. case 89:
  1483. # line 572 "parsedate.y"
  1484. { ptm.tm_mday = yypvt[-0]; } break;
  1485. case 92:
  1486. # line 576 "parsedate.y"
  1487. { ptm.tm_mday = yypvt[-2]; } break;
  1488. case 93:
  1489. # line 578 "parsedate.y"
  1490. { ptm.tm_mday = yypvt[-2]; } break;
  1491. case 105:
  1492. # line 607 "parsedate.y"
  1493. { if (yypvt[-0] < 1 || yypvt[-0] > 12) yyerror ();
  1494.               shour = yypvt[-0]; } break;
  1495. case 106:
  1496. # line 612 "parsedate.y"
  1497. { tmkey = yypvt[-0]; } break;
  1498. case 110:
  1499. # line 620 "parsedate.y"
  1500. { tmkey = yypvt[-0]; } break;
  1501. case 111:
  1502. # line 622 "parsedate.y"
  1503. { tmkey = yypvt[-0]; } break;
  1504. case 112:
  1505. # line 624 "parsedate.y"
  1506. { ptm.tm_hour = yypvt[-0]; } break;
  1507. case 113:
  1508. # line 626 "parsedate.y"
  1509. { if (yypvt[-1] != 12) yyerror ();
  1510.               shour = -1;
  1511.               ptm.tm_hour = yypvt[-0]; } break;
  1512. case 114:
  1513. # line 630 "parsedate.y"
  1514. { if (shour != 12 || ptm.tm_min != 0) yyerror ();
  1515.               shour = -1;
  1516.               ptm.tm_hour = yypvt[-0]; } break;
  1517. case 115:
  1518. # line 634 "parsedate.y"
  1519. { ptm.tm_hour = yypvt[-0] / 100;
  1520.               ptm.tm_min = yypvt[-0] % 100;
  1521.               if (ptm.tm_min > 59) yyerror ();
  1522.               if (yypvt[-0] > 2400) yyerror (); } break;
  1523. case 118:
  1524. # line 645 "parsedate.y"
  1525. { ptm.tm_mon = yypvt[-0]; } break;
  1526. case 119:
  1527. # line 654 "parsedate.y"
  1528. { ptm.tm_year = yypvt[-0] + ((yypvt[-0]>=100)?-1900:0); } break;
  1529. case 120:
  1530. # line 656 "parsedate.y"
  1531. { ptm.tm_year = yypvt[-0] - 1900; } break;
  1532. case 121:
  1533. # line 658 "parsedate.y"
  1534. { ptm.tm_year = currtm->tm_year; } break;
  1535. case 122:
  1536. # line 660 "parsedate.y"
  1537. { ptm.tm_year = currtm->tm_year - 1; } break;
  1538. case 123:
  1539. # line 662 "parsedate.y"
  1540. { ptm.tm_year = currtm->tm_year + 1; } break;
  1541. case 124:
  1542. # line 670 "parsedate.y"
  1543. { ptm.tm_mon = yypvt[-0] - 1; } break;
  1544. case 125:
  1545. # line 674 "parsedate.y"
  1546. { ptm.tm_mday = yypvt[-0]; } break;
  1547. case 127:
  1548. # line 679 "parsedate.y"
  1549. { ptm.tm_mday = yypvt[-0]; } break;
  1550. case 128:
  1551. # line 681 "parsedate.y"
  1552. { ptm.tm_mday = yypvt[-0]; } break;
  1553. case 129:
  1554. # line 685 "parsedate.y"
  1555. { ptm.tm_hour = yypvt[-0]; } break;
  1556. case 130:
  1557. # line 687 "parsedate.y"
  1558. { shour = yypvt[-0]; } break;
  1559. case 132:
  1560. # line 692 "parsedate.y"
  1561. { shour = yypvt[-0]; } break;
  1562. case 133:
  1563. # line 696 "parsedate.y"
  1564. { ptm.tm_min = yypvt[-0]; } break;
  1565. case 134:
  1566. # line 698 "parsedate.y"
  1567. { ptm.tm_min = yypvt[-0]; } break;
  1568. case 135:
  1569. # line 700 "parsedate.y"
  1570. { ptm.tm_min = yypvt[-0]; } break;
  1571. case 136:
  1572. # line 704 "parsedate.y"
  1573. { ptm.tm_sec = yypvt[-0]; } break;
  1574. case 140:
  1575. # line 718 "parsedate.y"
  1576. { if (yypvt[-1] % 10 != 1 || yypvt[-1] % 100 == 11) yyerror ();
  1577.               yyval = yypvt[-1]; } break;
  1578. case 141:
  1579. # line 721 "parsedate.y"
  1580. { if (yypvt[-1] % 10 != 2 || yypvt[-1] % 100 == 12) yyerror ();
  1581.               yyval = yypvt[-1]; } break;
  1582. case 142:
  1583. # line 724 "parsedate.y"
  1584. { if (yypvt[-1] % 10 != 3 || yypvt[-1] % 100 == 13) yyerror ();
  1585.               yyval = yypvt[-1]; } break;
  1586. case 143:
  1587. # line 727 "parsedate.y"
  1588. { if ((yypvt[-1] + 9) % 10 <= 2 && (yypvt[-1] % 100) / 10 != 1)
  1589.                 yyerror ();
  1590.               yyval = yypvt[-1]; } break;
  1591. case 146:
  1592. # line 737 "parsedate.y"
  1593. { yyval = yypvt[-0]; } break;
  1594. # line 148 "/usr/lib/yaccpar"
  1595.  
  1596.         }
  1597.         goto yystack;  /* stack new state and value */
  1598.  
  1599.     }
  1600.