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