1: /* picksbr.c - routines to help pick along... */
   2: 
   3: #include "../h/mh.h"
   4: #include "../zotnet/tws.h"
   5: #include <stdio.h>
   6: 
   7: /*  */
   8: 
   9: static struct swit parswit[] = {
  10: #define PRAND   0
  11:     "and", 0,
  12: #define PROR    1
  13:     "or", 0,
  14: #define PRNOT   2
  15:     "not", 0,
  16: #define PRLBR   3
  17:     "lbrace", 0,
  18: #define PRRBR   4
  19:     "rbrace", 0,
  20: 
  21: #define PRCC    5
  22:     "cc  pattern", 0,
  23: #define PRDATE  6
  24:     "date  pattern", 0,
  25: #define PRFROM  7
  26:     "from  pattern", 0,
  27: #define PRSRCH  8
  28:     "search  pattern", 0,
  29: #define PRSUBJ  9
  30:     "subject  pattern", 0,
  31: #define PRTO    10
  32:     "to  pattern", 0,
  33: #define PROTHR  11
  34:     "-othercomponent  pattern", 15,
  35: 
  36: #define PRAFTR  12
  37:     "after date", 0,
  38: #define PRBEFR  13
  39:     "before date", 0,
  40: #define PRDATF  14
  41:     "datefield field", 5,
  42: 
  43:     NULL, NULL
  44: };
  45: 
  46: /*    DEFINITIONS FOR PATTERN MATCHING */
  47: 
  48: /* We really should be using re_comp() and re_exec() here.  Unfortunately,
  49:    pick advertises that lowercase characters matches characters of both
  50:    cases.  Since re_exec() doesn't exhibit this behavior, we are stuck
  51:    with this version.  Furthermore, we need to be able to save and restore
  52:    the state of the pattern matcher in order to do things "efficiently".
  53: 
  54:    The matching power of this algorithm isn't as powerful as the re_xxx()
  55:    routines (no \(xxx\) and \n constructs).  Such is life.
  56:  */
  57: 
  58: 
  59: #define CCHR    2
  60: #define CDOT    4
  61: #define CCL 6
  62: #define NCCL    8
  63: #define CDOL    10
  64: #define CEOF    11
  65: 
  66: #define STAR    01
  67: 
  68: #define LBSIZE  1024
  69: #define ESIZE   256
  70: 
  71: 
  72: static char linebuf[LBSIZE + 1];
  73: 
  74: static char cc[] = {        /* the magic array for case-independence */
  75:     0000,0001,0002,0003,0004,0005,0006,0007,
  76:     0010,0011,0012,0013,0014,0015,0016,0017,
  77:     0020,0021,0022,0023,0024,0025,0026,0027,
  78:     0030,0031,0032,0033,0034,0035,0036,0037,
  79:     0040,0041,0042,0043,0044,0045,0046,0047,
  80:     0050,0051,0052,0053,0054,0055,0056,0057,
  81:     0060,0061,0062,0063,0064,0065,0066,0067,
  82:     0070,0071,0072,0073,0074,0075,0076,0077,
  83:     0100,0141,0142,0143,0144,0145,0146,0147,
  84:     0150,0151,0152,0153,0154,0155,0156,0157,
  85:     0160,0161,0162,0163,0164,0165,0166,0167,
  86:     0170,0171,0172,0133,0134,0135,0136,0137,
  87:     0140,0141,0142,0143,0144,0145,0146,0147,
  88:     0150,0151,0152,0153,0154,0155,0156,0157,
  89:     0160,0161,0162,0163,0164,0165,0166,0167,
  90:     0170,0171,0172,0173,0174,0175,0176,0177,
  91: };
  92: 
  93: /*    DEFINITIONS FOR DATE MATCHING */
  94: 
  95: struct tws *tws_parse (), *tws_special ();
  96: 
  97: 
  98: long   time ();
  99: 
 100: /*    DEFINITIONS FOR NEXUS */
 101: 
 102: #define nxtarg()    (*argp ? *argp++ : NULL)
 103: #define prvarg()    argp--
 104: 
 105: 
 106: #define padvise     if (!talked++) advise
 107: 
 108: 
 109: struct nexus {
 110:     int     (*n_action) ();
 111: 
 112:     union {
 113:     struct {        /* for {OR,AND,NOT}action */
 114:         struct nexus   *un_L_child;
 115:         struct nexus   *un_R_child;
 116:     }       st1;
 117: #define n_L_child   un.st1.un_L_child
 118: #define n_R_child   un.st1.un_R_child
 119: 
 120:     struct {        /* for GREPaction */
 121:         int     un_header;
 122:         int     un_circf;
 123:         char    un_expbuf[ESIZE];
 124:         char   *un_patbuf;
 125:     }       st2;
 126: #define n_header    un.st2.un_header
 127: #define n_circf     un.st2.un_circf
 128: #define n_expbuf    un.st2.un_expbuf
 129: #define n_patbuf    un.st2.un_patbuf
 130: 
 131:     struct {        /* for TWSaction */
 132:         char   *un_datef;
 133:         int     un_after;
 134:         struct tws un_tws;
 135:     }   st3;
 136: #define n_datef     un.st3.un_datef
 137: #define n_after     un.st3.un_after
 138: #define n_tws       un.st3.un_tws
 139: 
 140:     }   un;
 141: };
 142: 
 143: static  int   talked;
 144: static  int   pdebug = 0;
 145: 
 146: static  char *datesw;
 147: static  char **argp;
 148: 
 149: static  struct nexus *head;
 150: 
 151: 
 152: struct  nexus *parse (), *exp1 (), *exp2 (), *exp3 (), *newnexus ();
 153: 
 154: int ORaction (), ANDaction (), NOTaction (), GREPaction (), TWSaction ();
 155: 
 156: /*  */
 157: 
 158: int pcompile (vec, date)
 159: register char  **vec,
 160:             *date;
 161: {
 162:     register char  *cp;
 163: 
 164:     if ((cp = getenv ("MHPDEBUG")) && *cp)
 165:     pdebug++;
 166: 
 167:     argp = vec;
 168:     if ((datesw = date) == NULL)
 169:     datesw = "date";
 170:     talked = 0;
 171: 
 172:     if ((head = parse ()) == NULL)
 173:     return (talked ? 0 : 1);
 174: 
 175:     if (*argp) {
 176:     padvise (NULLCP, "%s unexpected", *argp);
 177:     return 0;
 178:     }
 179: 
 180:     return 1;
 181: }
 182: 
 183: /*  */
 184: 
 185: static struct nexus *parse () {
 186:     register char  *cp;
 187:     register struct nexus  *n,
 188:                            *o;
 189: 
 190:     if ((n = exp1 ()) == NULL || (cp = nxtarg ()) == NULL)
 191:     return n;
 192: 
 193:     if (*cp != '-') {
 194:     padvise (NULLCP, "%s unexpected", cp);
 195:     return NULL;
 196:     }
 197: 
 198:     if (*++cp == '-')
 199:     goto header;
 200:     switch (smatch (cp, parswit)) {
 201:     case AMBIGSW:
 202:         ambigsw (cp, parswit);
 203:         talked++;
 204:         return NULL;
 205:     case UNKWNSW:
 206:         fprintf (stderr, "-%s unknown\n", cp);
 207:         talked++;
 208:         return NULL;
 209: 
 210:     case PROR:
 211:         o = newnexus (ORaction);
 212:         o -> n_L_child = n;
 213:         if (o -> n_R_child = parse ())
 214:         return o;
 215:         padvise (NULLCP, "missing disjunctive");
 216:         return NULL;
 217: 
 218: header: ;
 219:     default:
 220:         prvarg ();
 221:         return n;
 222:     }
 223: }
 224: 
 225: /*  */
 226: 
 227: static struct nexus *exp1 () {
 228:     register char  *cp;
 229:     register struct nexus  *n,
 230:                            *o;
 231: 
 232:     if ((n = exp2 ()) == NULL || (cp = nxtarg ()) == NULL)
 233:     return n;
 234: 
 235:     if (*cp != '-') {
 236:     padvise (NULLCP, "%s unexpected", cp);
 237:     return NULL;
 238:     }
 239: 
 240:     if (*++cp == '-')
 241:     goto header;
 242:     switch (smatch (cp, parswit)) {
 243:     case AMBIGSW:
 244:         ambigsw (cp, parswit);
 245:         talked++;
 246:         return NULL;
 247:     case UNKWNSW:
 248:         fprintf (stderr, "-%s unknown\n", cp);
 249:         talked++;
 250:         return NULL;
 251: 
 252:     case PRAND:
 253:         o = newnexus (ANDaction);
 254:         o -> n_L_child = n;
 255:         if (o -> n_R_child = exp1 ())
 256:         return o;
 257:         padvise (NULLCP, "missing conjunctive");
 258:         return NULL;
 259: 
 260: header: ;
 261:     default:
 262:         prvarg ();
 263:         return n;
 264:     }
 265: }
 266: 
 267: /*  */
 268: 
 269: static struct nexus *exp2 () {
 270:     register char  *cp;
 271:     register struct nexus  *n;
 272: 
 273:     if ((cp = nxtarg ()) == NULL)
 274:     return NULL;
 275: 
 276:     if (*cp != '-') {
 277:     prvarg ();
 278:     return exp3 ();
 279:     }
 280: 
 281:     if (*++cp == '-')
 282:     goto header;
 283:     switch (smatch (cp, parswit)) {
 284:     case AMBIGSW:
 285:         ambigsw (cp, parswit);
 286:         talked++;
 287:         return NULL;
 288:     case UNKWNSW:
 289:         fprintf (stderr, "-%s unknown\n", cp);
 290:         talked++;
 291:         return NULL;
 292: 
 293:     case PRNOT:
 294:         n = newnexus (NOTaction);
 295:         if (n -> n_L_child = exp3 ())
 296:         return n;
 297:         padvise (NULLCP, "missing negation");
 298:         return NULL;
 299: 
 300: header: ;
 301:     default:
 302:         prvarg ();
 303:         return exp3 ();
 304:     }
 305: }
 306: 
 307: /*  */
 308: 
 309: static struct nexus *exp3 () {
 310:     int     i;
 311:     register char  *cp,
 312:                    *dp;
 313:     char    buffer[BUFSIZ];
 314:     register struct nexus  *n;
 315: 
 316:     if ((cp = nxtarg ()) == NULL)
 317:     return NULL;
 318: 
 319:     if (*cp != '-') {
 320:     padvise (NULLCP, "%s unexpected", cp);
 321:     return NULL;
 322:     }
 323: 
 324:     if (*++cp == '-') {
 325:     dp = ++cp;
 326:     goto header;
 327:     }
 328:     switch (i = smatch (cp, parswit)) {
 329:     case AMBIGSW:
 330:         ambigsw (cp, parswit);
 331:         talked++;
 332:         return NULL;
 333:     case UNKWNSW:
 334:         fprintf (stderr, "-%s unknown\n", cp);
 335:         talked++;
 336:         return NULL;
 337: 
 338:     case PRLBR:
 339:         if ((n = parse ()) == NULL) {
 340:         padvise (NULLCP, "missing group");
 341:         return NULL;
 342:         }
 343:         if ((cp = nxtarg ()) == NULL) {
 344:         padvise (NULLCP, "missing -rbrace");
 345:         return NULL;
 346:         }
 347:         if (*cp++ == '-' && smatch (cp, parswit) == PRRBR)
 348:         return n;
 349:         padvise (NULLCP, "%s unexpected", --cp);
 350:         return NULL;
 351: 
 352:     default:
 353:         prvarg ();
 354:         return NULL;
 355: 
 356:     case PRCC:
 357:     case PRDATE:
 358:     case PRFROM:
 359:     case PRTO:
 360:     case PRSUBJ:
 361:         dp = *brkstring (parswit[i].sw, " ", NULLCP);
 362:     header: ;
 363:         if (!(cp = nxtarg ())) {/* allow -xyz arguments */
 364:         padvise (NULLCP, "missing argument to %s", argp[-2]);
 365:         return NULL;
 366:         }
 367:         n = newnexus (GREPaction);
 368:         n -> n_header = 1;
 369:         (void) sprintf (buffer, "^%s[ \t]*:.*%s", dp, cp);
 370:         dp = buffer;
 371:         goto pattern;
 372: 
 373:     case PRSRCH:
 374:         n = newnexus (GREPaction);
 375:         n -> n_header = 0;
 376:         if (!(cp = nxtarg ())) {/* allow -xyz arguments */
 377:         padvise (NULLCP, "missing argument to %s", argp[-2]);
 378:         return NULL;
 379:         }
 380:         dp = cp;
 381:     pattern: ;
 382:         if (!gcompile (n, dp)) {
 383:         padvise (NULLCP, "pattern error in %s %s", argp[-2], cp);
 384:         return NULL;
 385:         }
 386:         n -> n_patbuf = getcpy (dp);
 387:         return n;
 388: 
 389:     case PROTHR:
 390:         padvise (NULLCP, "internal error!");
 391:         return NULL;
 392: 
 393:     case PRDATF:
 394:         if (!(datesw = nxtarg ()) || *datesw == '-') {
 395:         padvise (NULLCP, "missing argument to %s", argp[-2]);
 396:         return NULL;
 397:         }
 398:         return exp3 ();
 399: 
 400:     case PRAFTR:
 401:     case PRBEFR:
 402:         if (!(cp = nxtarg ())) {/* allow -xyz arguments */
 403:         padvise (NULLCP, "missing argument to %s", argp[-2]);
 404:         return NULL;
 405:         }
 406:         n = newnexus (TWSaction);
 407:         n -> n_datef = datesw;
 408:         if (!tcompile (cp, &n -> n_tws, n -> n_after = i == PRAFTR)) {
 409:         padvise (NULLCP, "unable to parse %s %s", argp[-2], cp);
 410:         return NULL;
 411:         }
 412:         return n;
 413:     }
 414: }
 415: 
 416: /*  */
 417: 
 418: static struct nexus *newnexus (action)
 419: register int    (*action) ();
 420: {
 421:     register struct nexus   *p;
 422: 
 423:     if ((p = (struct nexus *) calloc ((unsigned) 1, sizeof *p)) == NULL)
 424:     adios (NULLCP, "unable to allocate component storage");
 425: 
 426:     p -> n_action = action;
 427:     return p;
 428: }
 429: 
 430: /*  */
 431: 
 432: #define args(a) a, fp, msgnum, start, stop
 433: #define params  args (n)
 434: #define plist   \
 435:         register struct nexus  *n; \
 436:         register FILE *fp; \
 437:         int msgnum; \
 438:         long    start, \
 439:             stop;
 440: 
 441: int pmatches (fp, msgnum, start, stop)
 442: register FILE *fp;
 443: int msgnum;
 444: long    start,
 445:     stop;
 446: {
 447:     if (!head)
 448:     return 1;
 449: 
 450:     if (!talked++ && pdebug)
 451:     PRaction (head, 0);
 452: 
 453:     return (*head -> n_action) (args (head));
 454: }
 455: 
 456: /*  */
 457: 
 458: static  PRaction (n, level)
 459: register struct nexus *n;
 460: register int    level;
 461: {
 462:     register int    i;
 463: 
 464:     for (i = 0; i < level; i++)
 465:     fprintf (stderr, "| ");
 466: 
 467:     if (n -> n_action == ORaction) {
 468:     fprintf (stderr, "OR\n");
 469:     PRaction (n -> n_L_child, level + 1);
 470:     PRaction (n -> n_R_child, level + 1);
 471:     return;
 472:     }
 473:     if (n -> n_action == ANDaction) {
 474:     fprintf (stderr, "AND\n");
 475:     PRaction (n -> n_L_child, level + 1);
 476:     PRaction (n -> n_R_child, level + 1);
 477:     return;
 478:     }
 479:     if (n -> n_action == NOTaction) {
 480:     fprintf (stderr, "NOT\n");
 481:     PRaction (n -> n_L_child, level + 1);
 482:     return;
 483:     }
 484:     if (n -> n_action == GREPaction) {
 485:     fprintf (stderr, "PATTERN(%s) %s\n",
 486:         n -> n_header ? "header" : "body", n -> n_patbuf);
 487:     return;
 488:     }
 489:     if (n -> n_action == TWSaction) {
 490:     fprintf (stderr, "TEMPORAL(%s) %s: %s\n",
 491:         n -> n_after ? "after" : "before", n -> n_datef,
 492:         dasctime (&n -> n_tws, TW_NULL));
 493:     return;
 494:     }
 495:     fprintf (stderr, "UNKNOWN(0x%x)\n", (*n -> n_action));
 496: }
 497: 
 498: /*  */
 499: 
 500: static int  ORaction (params)
 501: plist
 502: {
 503:     if ((*n -> n_L_child -> n_action) (args (n -> n_L_child)))
 504:     return 1;
 505:     return (*n -> n_R_child -> n_action) (args (n -> n_R_child));
 506: }
 507: 
 508: 
 509: static int  ANDaction (params)
 510: plist
 511: {
 512:     if (!(*n -> n_L_child -> n_action) (args (n -> n_L_child)))
 513:     return 0;
 514:     return (*n -> n_R_child -> n_action) (args (n -> n_R_child));
 515: }
 516: 
 517: 
 518: static int  NOTaction (params)
 519: plist
 520: {
 521:     return (!(*n -> n_L_child -> n_action) (args (n -> n_L_child)));
 522: }
 523: 
 524: /*  */
 525: 
 526: static  int gcompile (n, astr)
 527: register struct nexus *n;
 528: register char *astr;
 529: {
 530:     register int    c;
 531:     int     cclcnt;
 532:     register char  *ep,
 533:            *dp,
 534:                    *sp,
 535:                    *lastep;
 536: 
 537:     dp = (ep = n -> n_expbuf) + sizeof n -> n_expbuf;
 538:     sp = astr;
 539:     if (*sp == '^') {
 540:     n -> n_circf = 1;
 541:     sp++;
 542:     }
 543:     else
 544:     n -> n_circf = 0;
 545:     for (;;) {
 546:     if (ep >= dp)
 547:         goto cerror;
 548:     if ((c = *sp++) != '*')
 549:         lastep = ep;
 550:     switch (c) {
 551:         case '\0':
 552:         *ep++ = CEOF;
 553:         return 1;
 554: 
 555:         case '.':
 556:         *ep++ = CDOT;
 557:         continue;
 558: 
 559:         case '*':
 560:         if (lastep == 0)
 561:             goto defchar;
 562:         *lastep |= STAR;
 563:         continue;
 564: 
 565:         case '$':
 566:         if (*sp != '\0')
 567:             goto defchar;
 568:         *ep++ = CDOL;
 569:         continue;
 570: 
 571:         case '[':
 572:         *ep++ = CCL;
 573:         *ep++ = 0;
 574:         cclcnt = 1;
 575:         if ((c = *sp++) == '^') {
 576:             c = *sp++;
 577:             ep[-2] = NCCL;
 578:         }
 579:         do {
 580:             *ep++ = c;
 581:             cclcnt++;
 582:             if (c == '\0' || ep >= dp)
 583:             goto cerror;
 584:         } while ((c = *sp++) != ']');
 585:         lastep[1] = cclcnt;
 586:         continue;
 587: 
 588:         case '\\':
 589:         if ((c = *sp++) == '\0')
 590:             goto cerror;
 591:     defchar:
 592:         default:
 593:         *ep++ = CCHR;
 594:         *ep++ = c;
 595:     }
 596:     }
 597: 
 598: cerror: ;
 599:     return 0;
 600: }
 601: 
 602: /*  */
 603: 
 604: /* ARGSUSED */
 605: 
 606: static int  GREPaction (params)
 607: plist
 608: {
 609:     int     c,
 610:             body,
 611:             lf;
 612:     long    pos = start;
 613:     register char  *p1,
 614:                    *p2,
 615:                    *ebp,
 616:                    *cbp;
 617:     char    ibuf[BUFSIZ];
 618: 
 619:     (void) fseek (fp, start, 0);
 620:     body = 0;
 621:     ebp = cbp = ibuf;
 622:     for (;;) {
 623:     if (body && n -> n_header)
 624:         return 0;
 625:     p1 = linebuf;
 626:     p2 = cbp;
 627:     lf = 0;
 628:     for (;;) {
 629:         if (p2 >= ebp) {
 630:         if (fgets (ibuf, sizeof ibuf, fp) == NULL
 631:             || (stop && pos >= stop)) {
 632:             if (lf)
 633:             break;
 634:             return 0;
 635:         }
 636:         pos += (long) strlen (ibuf);
 637:         p2 = ibuf;
 638:         ebp = ibuf + strlen (ibuf);
 639:         }
 640:         c = *p2++;
 641:         if (lf && c != '\n')
 642:         if (c != ' ' && c != '\t') {
 643:             --p2;
 644:             break;
 645:         }
 646:         else
 647:             lf = 0;
 648:         if (c == '\n')
 649:         if (body)
 650:             break;
 651:         else {
 652:             if (lf) {
 653:             body++;
 654:             break;
 655:             }
 656:             lf++;
 657:             c = ' ';
 658:         }
 659:         if (c && p1 < &linebuf[LBSIZE - 1])
 660:         *p1++ = c;
 661:     }
 662: 
 663:     *p1++ = NULL;
 664:     cbp = p2;
 665:     p1 = linebuf;
 666:     p2 = n -> n_expbuf;
 667: 
 668:     if (n -> n_circf) {
 669:         if (advance (p1, p2))
 670:         return 1;
 671:         continue;
 672:     }
 673: 
 674:     if (*p2 == CCHR) {
 675:         c = p2[1];
 676:         do {
 677:         if (*p1 == c || cc[*p1] == c)
 678:             if (advance (p1, p2))
 679:             return 1;
 680:         } while (*p1++);
 681:         continue;
 682:     }
 683: 
 684:     do {
 685:         if (advance (p1, p2))
 686:         return 1;
 687:     } while (*p1++);
 688:     }
 689: }
 690: 
 691: /*  */
 692: 
 693: static  int advance (alp, aep)
 694: register char  *alp,
 695:                *aep;
 696: {
 697:     register char  *lp,
 698:                    *ep,
 699:                    *curlp;
 700: 
 701:     lp = alp;
 702:     ep = aep;
 703:     for (;;)
 704:     switch (*ep++) {
 705:         case CCHR:
 706:         if (*ep++ == *lp++ || ep[-1] == cc[lp[-1]])
 707:             continue;
 708:         return 0;
 709: 
 710:         case CDOT:
 711:         if (*lp++)
 712:             continue;
 713:         return 0;
 714: 
 715:         case CDOL:
 716:         if (*lp == 0)
 717:             continue;
 718:         return 0;
 719: 
 720:         case CEOF:
 721:         return 1;
 722: 
 723:         case CCL:
 724:         if (cclass (ep, *lp++, 1)) {
 725:             ep += *ep;
 726:             continue;
 727:         }
 728:         return 0;
 729: 
 730:         case NCCL:
 731:         if (cclass (ep, *lp++, 0)) {
 732:             ep += *ep;
 733:             continue;
 734:         }
 735:         return 0;
 736: 
 737:         case CDOT | STAR:
 738:         curlp = lp;
 739:         while (*lp++)
 740:             continue;
 741:         goto star;
 742: 
 743:         case CCHR | STAR:
 744:         curlp = lp;
 745:         while (*lp++ == *ep || cc[lp[-1]] == *ep)
 746:             continue;
 747:         ep++;
 748:         goto star;
 749: 
 750:         case CCL | STAR:
 751:         case NCCL | STAR:
 752:         curlp = lp;
 753:         while (cclass (ep, *lp++, ep[-1] == (CCL | STAR)))
 754:             continue;
 755:         ep += *ep;
 756:         goto star;
 757: 
 758:     star:
 759:         do {
 760:             lp--;
 761:             if (advance (lp, ep))
 762:             return (1);
 763:         } while (lp > curlp);
 764:         return 0;
 765: 
 766:         default:
 767:         admonish (NULLCP, "advance() botch -- you lose big");
 768:         return 0;
 769:     }
 770: }
 771: 
 772: /*  */
 773: 
 774: static  int cclass (aset, ac, af)
 775: register char   *aset;
 776: {
 777:     register int    n;
 778:     register char   c,
 779:                    *set;
 780: 
 781:     set = aset;
 782:     if ((c = ac) == 0)
 783:     return (0);
 784: 
 785:     n = *set++;
 786:     while (--n)
 787:     if (*set++ == c)
 788:         return (af);
 789: 
 790:     return (!af);
 791: }
 792: 
 793: /*  */
 794: 
 795: static  int tcompile (ap, tb, isafter)
 796: register char   *ap;
 797: register struct tws *tb;
 798: int     isafter;
 799: {
 800:     register struct tws *tw;
 801: 
 802:     if ((tw = tws_parse (ap, isafter)) == NULL)
 803:     return 0;
 804: 
 805:     twscopy (tb, tw);
 806:     return 1;
 807: }
 808: 
 809: /*  */
 810: 
 811: static struct tws  *tws_parse (ap, isafter)
 812: register char   *ap;
 813: int     isafter;
 814: {
 815:     char    buffer[BUFSIZ];
 816:     register struct tws *tw,
 817:                         *ts;
 818: 
 819:     if ((tw = tws_special (ap)) != NULL) {
 820:     tw -> tw_sec = tw -> tw_min = isafter ? 59 : 0;
 821:     tw -> tw_hour = isafter ? 23 : 0;
 822:     return tw;
 823:     }
 824:     if ((tw = dparsetime (ap)) != NULL)
 825:     return tw;
 826: 
 827:     if ((ts = dtwstime ()) == NULL)
 828:     return NULL;
 829: 
 830:     (void) sprintf (buffer, "%s %s", ap, dtwszone (ts));
 831:     if ((tw = dparsetime (buffer)) != NULL)
 832:     return tw;
 833: 
 834:     (void) sprintf (buffer, "%s %02d:%02d:%02d %s", ap,
 835:         ts -> tw_hour, ts -> tw_min, ts -> tw_sec, dtwszone (ts));
 836:     if ((tw = dparsetime (buffer)) != NULL)
 837:     return tw;
 838: 
 839:     (void) sprintf (buffer, "%02d %s %02d %s",
 840:         ts -> tw_mday, tw_moty[ts -> tw_mon], ts -> tw_year, ap);
 841:     if ((tw = dparsetime (buffer)) != NULL)
 842:     return tw;
 843: 
 844:     (void) sprintf (buffer, "%02d %s %02d %s %s",
 845:         ts -> tw_mday, tw_moty[ts -> tw_mon], ts -> tw_year,
 846:         ap, dtwszone (ts));
 847:     if ((tw = dparsetime (buffer)) != NULL)
 848:     return tw;
 849: 
 850:     return NULL;
 851: }
 852: 
 853: /*  */
 854: 
 855: static struct tws  *tws_special (ap)
 856: register char   *ap;
 857: {
 858:     int     i;
 859:     long    clock;
 860:     register struct tws *tw;
 861: 
 862:     (void) time (&clock);
 863:     if (uleq (ap, "Today"))
 864:     return dlocaltime (&clock);
 865:     if (uleq (ap, "Yesterday")) {
 866:     clock -= (long) (60 * 60 * 24);
 867:     return dlocaltime (&clock);
 868:     }
 869:     if (uleq (ap, "Tomorrow")) {
 870:     clock += (long) (60 * 60 * 24);
 871:     return dlocaltime (&clock);
 872:     }
 873: 
 874:     for (i = 0; tw_ldotw[i]; i++)
 875:     if (uleq (ap, tw_ldotw[i]))
 876:         break;
 877:     if (tw_ldotw[i]) {
 878:     if ((tw = dlocaltime (&clock)) == NULL)
 879:         return NULL;
 880:     if ((i -= tw -> tw_wday) > 0)
 881:         i -= 7;
 882:     }
 883:     else
 884:     if (*ap != '-')
 885:         return NULL;
 886:     else            /* -ddd days ago */
 887:         i = atoi (ap);  /* we should error check this */
 888: 
 889:     clock += (long) ((60 * 60 * 24) * i);
 890:     return dlocaltime (&clock);
 891: }
 892: 
 893: /*  */
 894: 
 895: /* ARGSUSED */
 896: 
 897: static int  TWSaction (params)
 898: plist
 899: {
 900:     int     state;
 901:     register char  *bp;
 902:     char    buf[BUFSIZ],
 903:             name[NAMESZ];
 904:     register struct tws *tw;
 905: 
 906:     (void) fseek (fp, start, 0);
 907:     for (state = FLD, bp = NULL;;) {
 908:     switch (state = m_getfld (state, name, buf, sizeof buf, fp)) {
 909:         case FLD:
 910:         case FLDEOF:
 911:         case FLDPLUS:
 912:         if (bp != NULL)
 913:             free (bp), bp = NULL;
 914:         bp = add (buf, NULLCP);
 915:         while (state == FLDPLUS) {
 916:             state = m_getfld (state, name, buf, sizeof buf, fp);
 917:             bp = add (buf, bp);
 918:         }
 919:         if (uleq (name, n -> n_datef))
 920:             break;
 921:         if (state != FLDEOF)
 922:             continue;
 923: 
 924:         case BODY:
 925:         case BODYEOF:
 926:         case FILEEOF:
 927:         case LENERR:
 928:         case FMTERR:
 929:         if (state == LENERR || state == FMTERR)
 930:             advise (NULLCP, "format error in message %d", msgnum);
 931:         if (bp != NULL)
 932:             free (bp);
 933:         return 0;
 934: 
 935:         default:
 936:         adios (NULLCP, "internal error -- you lose");
 937:     }
 938:     break;
 939:     }
 940: 
 941: /*  */
 942: 
 943:     if ((tw = dparsetime (bp)) == NULL)
 944:     advise (NULLCP, "unable to parse %s field in message %d, matching...",
 945:         n -> n_datef, msgnum), state = 1;
 946:     else
 947:     state = n -> n_after ? (twsort (tw, &n -> n_tws) > 0)
 948:         : (twsort (tw, &n -> n_tws) < 0);
 949: 
 950:     if (bp != NULL)
 951:     free (bp);
 952:     return state;
 953: }

Defined functions

ANDaction defined in line 509; used 3 times
GREPaction defined in line 606; used 4 times
NOTaction defined in line 518; used 3 times
ORaction defined in line 500; used 3 times
PRaction defined in line 458; used 6 times
TWSaction defined in line 897; used 3 times
advance defined in line 693; used 4 times
cclass defined in line 774; used 3 times
exp1 defined in line 227; used 3 times
exp2 defined in line 269; used 2 times
exp3 defined in line 309; used 5 times
gcompile defined in line 526; used 1 times
newnexus defined in line 418; used 7 times
parse defined in line 185; used 4 times
pcompile defined in line 158; used 2 times
pmatches defined in line 441; used 2 times
tcompile defined in line 795; used 1 times
tws_parse defined in line 811; used 2 times
tws_special defined in line 855; used 2 times

Defined variables

argp defined in line 147; used 12 times
cc defined in line 74; used 3 times
datesw defined in line 146; used 5 times
head defined in line 149; used 5 times
linebuf defined in line 72; used 3 times
parswit defined in line 9; used 10 times
pdebug defined in line 144; used 2 times
talked defined in line 143; used 12 times

Defined struct's

nexus defined in line 109; used 34 times

Defined macros

CCHR defined in line 59; used 3 times
CCL defined in line 61; used 3 times
CDOL defined in line 63; used 1 times
CDOT defined in line 60; used 2 times
CEOF defined in line 64; used 1 times
ESIZE defined in line 69; used 1 times
LBSIZE defined in line 68; used 2 times
NCCL defined in line 62; used 2 times
PRAFTR defined in line 36; used 1 times
PRAND defined in line 10; never used
PRBEFR defined in line 38; never used
PRCC defined in line 21; never used
PRDATE defined in line 23; never used
PRDATF defined in line 40; never used
PRFROM defined in line 25; never used
PRLBR defined in line 16; never used
PRNOT defined in line 14; never used
PROR defined in line 12; never used
PROTHR defined in line 33; never used
PRRBR defined in line 18; used 1 times
PRSRCH defined in line 27; never used
PRSUBJ defined in line 29; never used
PRTO defined in line 31; never used
STAR defined in line 66; used 2 times
args defined in line 432; used 7 times
n_L_child defined in line 117; used 12 times
n_R_child defined in line 118; used 8 times
n_after defined in line 137; used 3 times
n_circf defined in line 127; used 3 times
n_datef defined in line 136; used 4 times
n_expbuf defined in line 128; used 3 times
n_header defined in line 126; used 4 times
n_patbuf defined in line 129; used 2 times
n_tws defined in line 138; used 4 times
nxtarg defined in line 102; used 9 times
padvise defined in line 106; used 17 times
params defined in line 433; used 5 times
plist defined in line 434; used 5 times
prvarg defined in line 103; used 5 times
Last modified: 1986-02-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2987
Valid CSS Valid XHTML 1.0 Strict