|
|
1.1 ! root 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: static 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: static struct nexus *parse(), *exp1(), *exp2(), *exp3(), *newnexus(); ! 153: ! 154: static int ORaction(), ANDaction(), NOTaction(), GREPaction(), TWSaction(); ! 155: static int gcompile(), advance(), cclass(), tcompile(); ! 156: ! 157: static void PRaction(); ! 158: ! 159: /* */ ! 160: ! 161: pcompile(vec, date) ! 162: register char **vec, *date; ! 163: { ! 164: register char *cp; ! 165: ! 166: if ((cp = getenv ("MHPDEBUG")) && *cp) ! 167: pdebug++; ! 168: ! 169: argp = vec; ! 170: if ((datesw = date) == NULL) ! 171: datesw = "date"; ! 172: talked = 0; ! 173: ! 174: if ((head = parse ()) == NULL) ! 175: return (talked ? 0 : 1); ! 176: ! 177: if (*argp) { ! 178: padvise (NULLCP, "%s unexpected", *argp); ! 179: return 0; ! 180: } ! 181: ! 182: return 1; ! 183: } ! 184: ! 185: /* */ ! 186: ! 187: static struct nexus * ! 188: parse() ! 189: { ! 190: register char *cp; ! 191: register struct nexus *n, ! 192: *o; ! 193: ! 194: if ((n = exp1 ()) == NULL || (cp = nxtarg ()) == NULL) ! 195: return n; ! 196: ! 197: if (*cp != '-') { ! 198: padvise (NULLCP, "%s unexpected", cp); ! 199: return NULL; ! 200: } ! 201: ! 202: if (*++cp == '-') ! 203: goto header; ! 204: switch (smatch (cp, parswit)) { ! 205: case AMBIGSW: ! 206: ambigsw (cp, parswit); ! 207: talked++; ! 208: return NULL; ! 209: case UNKWNSW: ! 210: fprintf (stderr, "-%s unknown\n", cp); ! 211: talked++; ! 212: return NULL; ! 213: ! 214: case PROR: ! 215: o = newnexus (ORaction); ! 216: o -> n_L_child = n; ! 217: if (o -> n_R_child = parse ()) ! 218: return o; ! 219: padvise (NULLCP, "missing disjunctive"); ! 220: return NULL; ! 221: ! 222: header: ; ! 223: default: ! 224: prvarg (); ! 225: return n; ! 226: } ! 227: } ! 228: ! 229: /* */ ! 230: ! 231: static struct nexus * ! 232: exp1() ! 233: { ! 234: register char *cp; ! 235: register struct nexus *n, ! 236: *o; ! 237: ! 238: if ((n = exp2 ()) == NULL || (cp = nxtarg ()) == NULL) ! 239: return n; ! 240: ! 241: if (*cp != '-') { ! 242: padvise (NULLCP, "%s unexpected", cp); ! 243: return NULL; ! 244: } ! 245: ! 246: if (*++cp == '-') ! 247: goto header; ! 248: switch (smatch (cp, parswit)) { ! 249: case AMBIGSW: ! 250: ambigsw (cp, parswit); ! 251: talked++; ! 252: return NULL; ! 253: case UNKWNSW: ! 254: fprintf (stderr, "-%s unknown\n", cp); ! 255: talked++; ! 256: return NULL; ! 257: ! 258: case PRAND: ! 259: o = newnexus (ANDaction); ! 260: o -> n_L_child = n; ! 261: if (o -> n_R_child = exp1 ()) ! 262: return o; ! 263: padvise (NULLCP, "missing conjunctive"); ! 264: return NULL; ! 265: ! 266: header: ; ! 267: default: ! 268: prvarg (); ! 269: return n; ! 270: } ! 271: } ! 272: ! 273: /* */ ! 274: ! 275: static struct nexus * ! 276: exp2() ! 277: { ! 278: register char *cp; ! 279: register struct nexus *n; ! 280: ! 281: if ((cp = nxtarg ()) == NULL) ! 282: return NULL; ! 283: ! 284: if (*cp != '-') { ! 285: prvarg (); ! 286: return exp3 (); ! 287: } ! 288: ! 289: if (*++cp == '-') ! 290: goto header; ! 291: switch (smatch (cp, parswit)) { ! 292: case AMBIGSW: ! 293: ambigsw (cp, parswit); ! 294: talked++; ! 295: return NULL; ! 296: case UNKWNSW: ! 297: fprintf (stderr, "-%s unknown\n", cp); ! 298: talked++; ! 299: return NULL; ! 300: ! 301: case PRNOT: ! 302: n = newnexus (NOTaction); ! 303: if (n -> n_L_child = exp3 ()) ! 304: return n; ! 305: padvise (NULLCP, "missing negation"); ! 306: return NULL; ! 307: ! 308: header: ; ! 309: default: ! 310: prvarg (); ! 311: return exp3 (); ! 312: } ! 313: } ! 314: ! 315: /* */ ! 316: ! 317: static struct nexus * ! 318: exp3() ! 319: { ! 320: int i; ! 321: register char *cp, ! 322: *dp; ! 323: char buffer[BUFSIZ], temp[64]; ! 324: register struct nexus *n; ! 325: ! 326: if ((cp = nxtarg ()) == NULL) ! 327: return NULL; ! 328: ! 329: if (*cp != '-') { ! 330: padvise (NULLCP, "%s unexpected", cp); ! 331: return NULL; ! 332: } ! 333: ! 334: if (*++cp == '-') { ! 335: dp = ++cp; ! 336: goto header; ! 337: } ! 338: switch (i = smatch (cp, parswit)) { ! 339: case AMBIGSW: ! 340: ambigsw (cp, parswit); ! 341: talked++; ! 342: return NULL; ! 343: case UNKWNSW: ! 344: fprintf (stderr, "-%s unknown\n", cp); ! 345: talked++; ! 346: return NULL; ! 347: ! 348: case PRLBR: ! 349: if ((n = parse ()) == NULL) { ! 350: padvise (NULLCP, "missing group"); ! 351: return NULL; ! 352: } ! 353: if ((cp = nxtarg ()) == NULL) { ! 354: padvise (NULLCP, "missing -rbrace"); ! 355: return NULL; ! 356: } ! 357: if (*cp++ == '-' && smatch (cp, parswit) == PRRBR) ! 358: return n; ! 359: padvise (NULLCP, "%s unexpected", --cp); ! 360: return NULL; ! 361: ! 362: default: ! 363: prvarg (); ! 364: return NULL; ! 365: ! 366: case PRCC: ! 367: case PRDATE: ! 368: case PRFROM: ! 369: case PRTO: ! 370: case PRSUBJ: ! 371: strncpy(temp, parswit[i].sw, sizeof(temp)); ! 372: temp[sizeof(temp) - 1] = '\0'; ! 373: dp = *brkstring (temp, " ", NULLCP); ! 374: header: ; ! 375: if (!(cp = nxtarg ())) {/* allow -xyz arguments */ ! 376: padvise (NULLCP, "missing argument to %s", argp[-2]); ! 377: return NULL; ! 378: } ! 379: n = newnexus (GREPaction); ! 380: n -> n_header = 1; ! 381: (void) sprintf (buffer, "^%s[ \t]*:.*%s", dp, cp); ! 382: dp = buffer; ! 383: goto pattern; ! 384: ! 385: case PRSRCH: ! 386: n = newnexus (GREPaction); ! 387: n -> n_header = 0; ! 388: if (!(cp = nxtarg ())) {/* allow -xyz arguments */ ! 389: padvise (NULLCP, "missing argument to %s", argp[-2]); ! 390: return NULL; ! 391: } ! 392: dp = cp; ! 393: pattern: ; ! 394: if (!gcompile (n, dp)) { ! 395: padvise (NULLCP, "pattern error in %s %s", argp[-2], cp); ! 396: return NULL; ! 397: } ! 398: n -> n_patbuf = getcpy (dp); ! 399: return n; ! 400: ! 401: case PROTHR: ! 402: padvise (NULLCP, "internal error!"); ! 403: return NULL; ! 404: ! 405: case PRDATF: ! 406: if (!(datesw = nxtarg ()) || *datesw == '-') { ! 407: padvise (NULLCP, "missing argument to %s", argp[-2]); ! 408: return NULL; ! 409: } ! 410: return exp3 (); ! 411: ! 412: case PRAFTR: ! 413: case PRBEFR: ! 414: if (!(cp = nxtarg ())) {/* allow -xyz arguments */ ! 415: padvise (NULLCP, "missing argument to %s", argp[-2]); ! 416: return NULL; ! 417: } ! 418: n = newnexus (TWSaction); ! 419: n -> n_datef = datesw; ! 420: if (!tcompile (cp, &n -> n_tws, n -> n_after = i == PRAFTR)) { ! 421: padvise (NULLCP, "unable to parse %s %s", argp[-2], cp); ! 422: return NULL; ! 423: } ! 424: return n; ! 425: } ! 426: } ! 427: ! 428: /* */ ! 429: ! 430: static struct nexus * ! 431: newnexus(action) ! 432: register int (*action)(); ! 433: { ! 434: register struct nexus *p; ! 435: ! 436: if ((p = (struct nexus *) calloc ((unsigned) 1, sizeof *p)) == NULL) ! 437: adios (NULLCP, "unable to allocate component storage"); ! 438: ! 439: p -> n_action = action; ! 440: return p; ! 441: } ! 442: ! 443: /* */ ! 444: ! 445: #define args(a) a, fp, msgnum, start, stop ! 446: #define params args (n) ! 447: #define plist \ ! 448: register struct nexus *n; \ ! 449: register FILE *fp; \ ! 450: int msgnum; \ ! 451: long start, \ ! 452: stop; ! 453: ! 454: pmatches(fp, msgnum, start, stop) ! 455: register FILE *fp; ! 456: int msgnum; ! 457: long start, stop; ! 458: { ! 459: if (!head) ! 460: return 1; ! 461: ! 462: if (!talked++ && pdebug) ! 463: PRaction (head, 0); ! 464: ! 465: return (*head -> n_action) (args (head)); ! 466: } ! 467: ! 468: /* */ ! 469: ! 470: static void ! 471: PRaction(n, level) ! 472: register struct nexus *n; ! 473: register int level; ! 474: { ! 475: register int i; ! 476: ! 477: for (i = 0; i < level; i++) ! 478: fprintf (stderr, "| "); ! 479: ! 480: if (n -> n_action == ORaction) { ! 481: fprintf (stderr, "OR\n"); ! 482: PRaction (n -> n_L_child, level + 1); ! 483: PRaction (n -> n_R_child, level + 1); ! 484: return; ! 485: } ! 486: if (n -> n_action == ANDaction) { ! 487: fprintf (stderr, "AND\n"); ! 488: PRaction (n -> n_L_child, level + 1); ! 489: PRaction (n -> n_R_child, level + 1); ! 490: return; ! 491: } ! 492: if (n -> n_action == NOTaction) { ! 493: fprintf (stderr, "NOT\n"); ! 494: PRaction (n -> n_L_child, level + 1); ! 495: return; ! 496: } ! 497: if (n -> n_action == GREPaction) { ! 498: fprintf (stderr, "PATTERN(%s) %s\n", ! 499: n -> n_header ? "header" : "body", n -> n_patbuf); ! 500: return; ! 501: } ! 502: if (n -> n_action == TWSaction) { ! 503: fprintf (stderr, "TEMPORAL(%s) %s: %s\n", ! 504: n -> n_after ? "after" : "before", n -> n_datef, ! 505: dasctime (&n -> n_tws, TW_NULL)); ! 506: return; ! 507: } ! 508: fprintf (stderr, "UNKNOWN(0x%x)\n", (*n -> n_action)); ! 509: } ! 510: ! 511: /* */ ! 512: ! 513: static int ! 514: ORaction(params) ! 515: plist ! 516: { ! 517: if ((*n -> n_L_child -> n_action) (args (n -> n_L_child))) ! 518: return 1; ! 519: return (*n -> n_R_child -> n_action) (args (n -> n_R_child)); ! 520: } ! 521: ! 522: ! 523: static int ! 524: ANDaction(params) ! 525: plist ! 526: { ! 527: if (!(*n -> n_L_child -> n_action) (args (n -> n_L_child))) ! 528: return 0; ! 529: return (*n -> n_R_child -> n_action) (args (n -> n_R_child)); ! 530: } ! 531: ! 532: ! 533: static int ! 534: NOTaction(params) ! 535: plist ! 536: { ! 537: return (!(*n -> n_L_child -> n_action) (args (n -> n_L_child))); ! 538: } ! 539: ! 540: /* */ ! 541: ! 542: static int ! 543: gcompile(n, astr) ! 544: register struct nexus *n; ! 545: register char *astr; ! 546: { ! 547: register int c; ! 548: int cclcnt; ! 549: register char *ep, ! 550: *dp, ! 551: *sp, ! 552: *lastep; ! 553: ! 554: dp = (ep = n -> n_expbuf) + sizeof n -> n_expbuf; ! 555: sp = astr; ! 556: if (*sp == '^') { ! 557: n -> n_circf = 1; ! 558: sp++; ! 559: } ! 560: else ! 561: n -> n_circf = 0; ! 562: for (;;) { ! 563: if (ep >= dp) ! 564: goto cerror; ! 565: if ((c = *sp++) != '*') ! 566: lastep = ep; ! 567: switch (c) { ! 568: case '\0': ! 569: *ep++ = CEOF; ! 570: return 1; ! 571: ! 572: case '.': ! 573: *ep++ = CDOT; ! 574: continue; ! 575: ! 576: case '*': ! 577: if (lastep == 0) ! 578: goto defchar; ! 579: *lastep |= STAR; ! 580: continue; ! 581: ! 582: case '$': ! 583: if (*sp != '\0') ! 584: goto defchar; ! 585: *ep++ = CDOL; ! 586: continue; ! 587: ! 588: case '[': ! 589: *ep++ = CCL; ! 590: *ep++ = 0; ! 591: cclcnt = 1; ! 592: if ((c = *sp++) == '^') { ! 593: c = *sp++; ! 594: ep[-2] = NCCL; ! 595: } ! 596: do { ! 597: *ep++ = c; ! 598: cclcnt++; ! 599: if (c == '\0' || ep >= dp) ! 600: goto cerror; ! 601: } while ((c = *sp++) != ']'); ! 602: lastep[1] = cclcnt; ! 603: continue; ! 604: ! 605: case '\\': ! 606: if ((c = *sp++) == '\0') ! 607: goto cerror; ! 608: defchar: ! 609: default: ! 610: *ep++ = CCHR; ! 611: *ep++ = c; ! 612: } ! 613: } ! 614: ! 615: cerror: ; ! 616: return 0; ! 617: } ! 618: ! 619: /* */ ! 620: ! 621: /* ARGSUSED */ ! 622: ! 623: static int ! 624: GREPaction(params) ! 625: plist ! 626: { ! 627: int c, ! 628: body, ! 629: lf; ! 630: long pos = start; ! 631: register char *p1, ! 632: *p2, ! 633: *ebp, ! 634: *cbp; ! 635: char ibuf[BUFSIZ]; ! 636: ! 637: (void) fseek (fp, start, 0); ! 638: body = 0; ! 639: ebp = cbp = ibuf; ! 640: for (;;) { ! 641: if (body && n -> n_header) ! 642: return 0; ! 643: p1 = linebuf; ! 644: p2 = cbp; ! 645: lf = 0; ! 646: for (;;) { ! 647: if (p2 >= ebp) { ! 648: if (fgets (ibuf, sizeof ibuf, fp) == NULL ! 649: || (stop && pos >= stop)) { ! 650: if (lf) ! 651: break; ! 652: return 0; ! 653: } ! 654: pos += (long) strlen (ibuf); ! 655: p2 = ibuf; ! 656: ebp = ibuf + strlen (ibuf); ! 657: } ! 658: c = *p2++; ! 659: if (lf && c != '\n') ! 660: if (c != ' ' && c != '\t') { ! 661: --p2; ! 662: break; ! 663: } ! 664: else ! 665: lf = 0; ! 666: if (c == '\n') ! 667: if (body) ! 668: break; ! 669: else { ! 670: if (lf) { ! 671: body++; ! 672: break; ! 673: } ! 674: lf++; ! 675: c = ' '; ! 676: } ! 677: if (c && p1 < &linebuf[LBSIZE - 1]) ! 678: *p1++ = c; ! 679: } ! 680: ! 681: *p1++ = NULL; ! 682: cbp = p2; ! 683: p1 = linebuf; ! 684: p2 = n -> n_expbuf; ! 685: ! 686: if (n -> n_circf) { ! 687: if (advance (p1, p2)) ! 688: return 1; ! 689: continue; ! 690: } ! 691: ! 692: if (*p2 == CCHR) { ! 693: c = p2[1]; ! 694: do { ! 695: if (*p1 == c || cc[*p1] == c) ! 696: if (advance (p1, p2)) ! 697: return 1; ! 698: } while (*p1++); ! 699: continue; ! 700: } ! 701: ! 702: do { ! 703: if (advance (p1, p2)) ! 704: return 1; ! 705: } while (*p1++); ! 706: } ! 707: } ! 708: ! 709: /* */ ! 710: ! 711: static int ! 712: advance(alp, aep) ! 713: register char *alp, *aep; ! 714: { ! 715: register char *lp, ! 716: *ep, ! 717: *curlp; ! 718: ! 719: lp = alp; ! 720: ep = aep; ! 721: for (;;) ! 722: switch (*ep++) { ! 723: case CCHR: ! 724: if (*ep++ == *lp++ || ep[-1] == cc[lp[-1]]) ! 725: continue; ! 726: return 0; ! 727: ! 728: case CDOT: ! 729: if (*lp++) ! 730: continue; ! 731: return 0; ! 732: ! 733: case CDOL: ! 734: if (*lp == 0) ! 735: continue; ! 736: return 0; ! 737: ! 738: case CEOF: ! 739: return 1; ! 740: ! 741: case CCL: ! 742: if (cclass (ep, *lp++, 1)) { ! 743: ep += *ep; ! 744: continue; ! 745: } ! 746: return 0; ! 747: ! 748: case NCCL: ! 749: if (cclass (ep, *lp++, 0)) { ! 750: ep += *ep; ! 751: continue; ! 752: } ! 753: return 0; ! 754: ! 755: case CDOT | STAR: ! 756: curlp = lp; ! 757: while (*lp++) ! 758: continue; ! 759: goto star; ! 760: ! 761: case CCHR | STAR: ! 762: curlp = lp; ! 763: while (*lp++ == *ep || cc[lp[-1]] == *ep) ! 764: continue; ! 765: ep++; ! 766: goto star; ! 767: ! 768: case CCL | STAR: ! 769: case NCCL | STAR: ! 770: curlp = lp; ! 771: while (cclass (ep, *lp++, ep[-1] == (CCL | STAR))) ! 772: continue; ! 773: ep += *ep; ! 774: goto star; ! 775: ! 776: star: ! 777: do { ! 778: lp--; ! 779: if (advance (lp, ep)) ! 780: return (1); ! 781: } while (lp > curlp); ! 782: return 0; ! 783: ! 784: default: ! 785: admonish (NULLCP, "advance() botch -- you lose big"); ! 786: return 0; ! 787: } ! 788: } ! 789: ! 790: /* */ ! 791: ! 792: static int ! 793: cclass(aset, ac, af) ! 794: register char *aset; ! 795: { ! 796: register int n; ! 797: register char c, ! 798: *set; ! 799: ! 800: set = aset; ! 801: if ((c = ac) == 0) ! 802: return (0); ! 803: ! 804: n = *set++; ! 805: while (--n) ! 806: if (*set++ == c) ! 807: return (af); ! 808: ! 809: return (!af); ! 810: } ! 811: ! 812: /* */ ! 813: ! 814: static int ! 815: tcompile(ap, tb, isafter) ! 816: register char *ap; ! 817: register struct tws *tb; ! 818: int isafter; ! 819: { ! 820: register struct tws *tw; ! 821: ! 822: if ((tw = tws_parse (ap, isafter)) == NULL) ! 823: return 0; ! 824: ! 825: twscopy (tb, tw); ! 826: return 1; ! 827: } ! 828: ! 829: /* */ ! 830: ! 831: static struct tws * ! 832: tws_parse(ap, isafter) ! 833: register char *ap; ! 834: int isafter; ! 835: { ! 836: char buffer[BUFSIZ]; ! 837: register struct tws *tw, ! 838: *ts; ! 839: ! 840: if ((tw = tws_special (ap)) != NULL) { ! 841: tw -> tw_sec = tw -> tw_min = isafter ? 59 : 0; ! 842: tw -> tw_hour = isafter ? 23 : 0; ! 843: return tw; ! 844: } ! 845: if ((tw = dparsetime (ap)) != NULL) ! 846: return tw; ! 847: ! 848: if ((ts = dtwstime ()) == NULL) ! 849: return NULL; ! 850: ! 851: (void) sprintf (buffer, "%s %s", ap, dtwszone (ts)); ! 852: if ((tw = dparsetime (buffer)) != NULL) ! 853: return tw; ! 854: ! 855: (void) sprintf (buffer, "%s %02d:%02d:%02d %s", ap, ! 856: ts -> tw_hour, ts -> tw_min, ts -> tw_sec, dtwszone (ts)); ! 857: if ((tw = dparsetime (buffer)) != NULL) ! 858: return tw; ! 859: ! 860: (void) sprintf (buffer, "%02d %s %02d %s", ! 861: ts -> tw_mday, tw_moty[ts -> tw_mon], ts -> tw_year, ap); ! 862: if ((tw = dparsetime (buffer)) != NULL) ! 863: return tw; ! 864: ! 865: (void) sprintf (buffer, "%02d %s %02d %s %s", ! 866: ts -> tw_mday, tw_moty[ts -> tw_mon], ts -> tw_year, ! 867: ap, dtwszone (ts)); ! 868: if ((tw = dparsetime (buffer)) != NULL) ! 869: return tw; ! 870: ! 871: return NULL; ! 872: } ! 873: ! 874: /* */ ! 875: ! 876: static struct tws * ! 877: tws_special(ap) ! 878: register char *ap; ! 879: { ! 880: int i; ! 881: long clock; ! 882: register struct tws *tw; ! 883: ! 884: (void) time (&clock); ! 885: if (uleq (ap, "Today")) ! 886: return dlocaltime (&clock); ! 887: if (uleq (ap, "Yesterday")) { ! 888: clock -= (long) (60 * 60 * 24); ! 889: return dlocaltime (&clock); ! 890: } ! 891: if (uleq (ap, "Tomorrow")) { ! 892: clock += (long) (60 * 60 * 24); ! 893: return dlocaltime (&clock); ! 894: } ! 895: ! 896: for (i = 0; tw_ldotw[i]; i++) ! 897: if (uleq (ap, tw_ldotw[i])) ! 898: break; ! 899: if (tw_ldotw[i]) { ! 900: if ((tw = dlocaltime (&clock)) == NULL) ! 901: return NULL; ! 902: if ((i -= tw -> tw_wday) > 0) ! 903: i -= 7; ! 904: } ! 905: else ! 906: if (*ap != '-') ! 907: return NULL; ! 908: else /* -ddd days ago */ ! 909: i = atoi (ap); /* we should error check this */ ! 910: ! 911: clock += (long) ((60 * 60 * 24) * i); ! 912: return dlocaltime (&clock); ! 913: } ! 914: ! 915: /* */ ! 916: ! 917: /* ARGSUSED */ ! 918: ! 919: static int ! 920: TWSaction(params) ! 921: plist ! 922: { ! 923: int state; ! 924: register char *bp; ! 925: char buf[BUFSIZ], ! 926: name[NAMESZ]; ! 927: register struct tws *tw; ! 928: ! 929: (void) fseek (fp, start, 0); ! 930: for (state = FLD, bp = NULL;;) { ! 931: switch (state = m_getfld (state, name, buf, sizeof buf, fp)) { ! 932: case FLD: ! 933: case FLDEOF: ! 934: case FLDPLUS: ! 935: if (bp != NULL) ! 936: free (bp), bp = NULL; ! 937: bp = add (buf, NULLCP); ! 938: while (state == FLDPLUS) { ! 939: state = m_getfld (state, name, buf, sizeof buf, fp); ! 940: bp = add (buf, bp); ! 941: } ! 942: if (uleq (name, n -> n_datef)) ! 943: break; ! 944: if (state != FLDEOF) ! 945: continue; ! 946: ! 947: case BODY: ! 948: case BODYEOF: ! 949: case FILEEOF: ! 950: case LENERR: ! 951: case FMTERR: ! 952: if (state == LENERR || state == FMTERR) ! 953: advise (NULLCP, "format error in message %d", msgnum); ! 954: if (bp != NULL) ! 955: free (bp); ! 956: return 0; ! 957: ! 958: default: ! 959: adios (NULLCP, "internal error -- you lose"); ! 960: } ! 961: break; ! 962: } ! 963: ! 964: /* */ ! 965: ! 966: if ((tw = dparsetime (bp)) == NULL) ! 967: advise (NULLCP, "unable to parse %s field in message %d, matching...", ! 968: n -> n_datef, msgnum), state = 1; ! 969: else ! 970: state = n -> n_after ? (twsort (tw, &n -> n_tws) > 0) ! 971: : (twsort (tw, &n -> n_tws) < 0); ! 972: ! 973: if (bp != NULL) ! 974: free (bp); ! 975: return state; ! 976: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.