Annotation of 43BSD/contrib/mh/uip/picksbr.c, revision 1.1.1.1

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: 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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.