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