9 date 92.12.15.00.20.22; author jromine; state Exp;
14 date 92.02.10.23.54.32; author jromine; state Exp;
19 date 92.01.31.22.20.19; author jromine; state Exp;
24 date 90.04.05.15.01.50; author sources; state Exp;
29 date 90.02.09.11.05.30; author sources; state Exp;
34 date 90.02.09.09.53.17; author sources; state Exp;
39 date 90.02.06.13.24.31; author sources; state Exp;
44 date 90.02.06.13.23.48; author sources; state Exp;
58 @/* picksbr.c - routines to help pick along... */
60 static char ident[] = "@@(#)$Id: picksbr.c,v 1.7 1992/02/10 23:54:32 jromine Exp jromine $";
64 #include "../zotnet/tws.h"
69 static struct swit parswit[] = {
94 "-othercomponent pattern", 15,
101 "datefield field", 5,
106 /*
\f DEFINITIONS FOR PATTERN MATCHING */
108 /* We really should be using re_comp() and re_exec() here. Unfortunately,
109 pick advertises that lowercase characters matches characters of both
110 cases. Since re_exec() doesn't exhibit this behavior, we are stuck
111 with this version. Furthermore, we need to be able to save and restore
112 the state of the pattern matcher in order to do things "efficiently".
114 The matching power of this algorithm isn't as powerful as the re_xxx()
115 routines (no \(xxx\) and \n constructs). Such is life.
132 static char linebuf[LBSIZE + 1];
134 static char cc[] = { /* the magic array for case-independence */
135 0000,0001,0002,0003,0004,0005,0006,0007,
136 0010,0011,0012,0013,0014,0015,0016,0017,
137 0020,0021,0022,0023,0024,0025,0026,0027,
138 0030,0031,0032,0033,0034,0035,0036,0037,
139 0040,0041,0042,0043,0044,0045,0046,0047,
140 0050,0051,0052,0053,0054,0055,0056,0057,
141 0060,0061,0062,0063,0064,0065,0066,0067,
142 0070,0071,0072,0073,0074,0075,0076,0077,
143 0100,0141,0142,0143,0144,0145,0146,0147,
144 0150,0151,0152,0153,0154,0155,0156,0157,
145 0160,0161,0162,0163,0164,0165,0166,0167,
146 0170,0171,0172,0133,0134,0135,0136,0137,
147 0140,0141,0142,0143,0144,0145,0146,0147,
148 0150,0151,0152,0153,0154,0155,0156,0157,
149 0160,0161,0162,0163,0164,0165,0166,0167,
150 0170,0171,0172,0173,0174,0175,0176,0177,
153 /*
\f DEFINITIONS FOR DATE MATCHING */
155 static struct tws *tws_parse (), *tws_special ();
160 /*
\f DEFINITIONS FOR NEXUS */
162 #define nxtarg() (*argp ? *argp++ : NULL)
163 #define prvarg() argp--
166 #define padvise if (!talked++) advise
173 struct { /* for {OR,AND,NOT}action */
174 struct nexus *un_L_child;
175 struct nexus *un_R_child;
177 #define n_L_child un.st1.un_L_child
178 #define n_R_child un.st1.un_R_child
180 struct { /* for GREPaction */
183 char un_expbuf[ESIZE];
186 #define n_header un.st2.un_header
187 #define n_circf un.st2.un_circf
188 #define n_expbuf un.st2.un_expbuf
189 #define n_patbuf un.st2.un_patbuf
191 struct { /* for TWSaction */
196 #define n_datef un.st3.un_datef
197 #define n_after un.st3.un_after
198 #define n_tws un.st3.un_tws
204 static int pdebug = 0;
209 static struct nexus *head;
211 static void PRaction();
212 static int gcompile(), advance(), cclass(), tcompile();
214 static struct nexus *parse (), *exp1 (), *exp2 (), *exp3 (), *newnexus ();
216 static int ORaction (), ANDaction (), NOTaction (), GREPaction (),
221 int pcompile (vec, date)
227 if ((cp = getenv ("MHPDEBUG")) && *cp)
231 if ((datesw = date) == NULL)
235 if ((head = parse ()) == NULL)
236 return (talked ? 0 : 1);
239 padvise (NULLCP, "%s unexpected", *argp);
248 static struct nexus *parse () {
250 register struct nexus *n,
253 if ((n = exp1 ()) == NULL || (cp = nxtarg ()) == NULL)
257 padvise (NULLCP, "%s unexpected", cp);
263 switch (smatch (cp, parswit)) {
265 ambigsw (cp, parswit);
269 fprintf (stderr, "-%s unknown\n", cp);
274 o = newnexus (ORaction);
276 if (o -> n_R_child = parse ())
278 padvise (NULLCP, "missing disjunctive");
290 static struct nexus *exp1 () {
292 register struct nexus *n,
295 if ((n = exp2 ()) == NULL || (cp = nxtarg ()) == NULL)
299 padvise (NULLCP, "%s unexpected", cp);
305 switch (smatch (cp, parswit)) {
307 ambigsw (cp, parswit);
311 fprintf (stderr, "-%s unknown\n", cp);
316 o = newnexus (ANDaction);
318 if (o -> n_R_child = exp1 ())
320 padvise (NULLCP, "missing conjunctive");
332 static struct nexus *exp2 () {
334 register struct nexus *n;
336 if ((cp = nxtarg ()) == NULL)
346 switch (smatch (cp, parswit)) {
348 ambigsw (cp, parswit);
352 fprintf (stderr, "-%s unknown\n", cp);
357 n = newnexus (NOTaction);
358 if (n -> n_L_child = exp3 ())
360 padvise (NULLCP, "missing negation");
372 static struct nexus *exp3 () {
376 char buffer[BUFSIZ], temp[64];
377 register struct nexus *n;
379 if ((cp = nxtarg ()) == NULL)
383 padvise (NULLCP, "%s unexpected", cp);
391 switch (i = smatch (cp, parswit)) {
393 ambigsw (cp, parswit);
397 fprintf (stderr, "-%s unknown\n", cp);
402 if ((n = parse ()) == NULL) {
403 padvise (NULLCP, "missing group");
406 if ((cp = nxtarg ()) == NULL) {
407 padvise (NULLCP, "missing -rbrace");
410 if (*cp++ == '-' && smatch (cp, parswit) == PRRBR)
412 padvise (NULLCP, "%s unexpected", --cp);
424 strncpy(temp, parswit[i].sw, sizeof(temp));
425 temp[sizeof(temp) - 1] = '\0';
426 dp = *brkstring (temp, " ", NULLCP);
428 if (!(cp = nxtarg ())) {/* allow -xyz arguments */
429 padvise (NULLCP, "missing argument to %s", argp[-2]);
432 n = newnexus (GREPaction);
434 (void) sprintf (buffer, "^%s[ \t]*:.*%s", dp, cp);
439 n = newnexus (GREPaction);
441 if (!(cp = nxtarg ())) {/* allow -xyz arguments */
442 padvise (NULLCP, "missing argument to %s", argp[-2]);
447 if (!gcompile (n, dp)) {
448 padvise (NULLCP, "pattern error in %s %s", argp[-2], cp);
451 n -> n_patbuf = getcpy (dp);
455 padvise (NULLCP, "internal error!");
459 if (!(datesw = nxtarg ()) || *datesw == '-') {
460 padvise (NULLCP, "missing argument to %s", argp[-2]);
467 if (!(cp = nxtarg ())) {/* allow -xyz arguments */
468 padvise (NULLCP, "missing argument to %s", argp[-2]);
471 n = newnexus (TWSaction);
472 n -> n_datef = datesw;
473 if (!tcompile (cp, &n -> n_tws, n -> n_after = i == PRAFTR)) {
474 padvise (NULLCP, "unable to parse %s %s", argp[-2], cp);
483 static struct nexus *newnexus (action)
484 register int (*action) ();
486 register struct nexus *p;
488 if ((p = (struct nexus *) calloc ((unsigned) 1, sizeof *p)) == NULL)
489 adios (NULLCP, "unable to allocate component storage");
491 p -> n_action = action;
497 #define args(a) a, fp, msgnum, start, stop
498 #define params args (n)
500 register struct nexus *n; \
506 int pmatches (fp, msgnum, start, stop)
515 if (!talked++ && pdebug)
518 return (*head -> n_action) (args (head));
523 static void PRaction (n, level)
524 register struct nexus *n;
529 for (i = 0; i < level; i++)
530 fprintf (stderr, "| ");
532 if (n -> n_action == ORaction) {
533 fprintf (stderr, "OR\n");
534 PRaction (n -> n_L_child, level + 1);
535 PRaction (n -> n_R_child, level + 1);
538 if (n -> n_action == ANDaction) {
539 fprintf (stderr, "AND\n");
540 PRaction (n -> n_L_child, level + 1);
541 PRaction (n -> n_R_child, level + 1);
544 if (n -> n_action == NOTaction) {
545 fprintf (stderr, "NOT\n");
546 PRaction (n -> n_L_child, level + 1);
549 if (n -> n_action == GREPaction) {
550 fprintf (stderr, "PATTERN(%s) %s\n",
551 n -> n_header ? "header" : "body", n -> n_patbuf);
554 if (n -> n_action == TWSaction) {
555 fprintf (stderr, "TEMPORAL(%s) %s: %s\n",
556 n -> n_after ? "after" : "before", n -> n_datef,
557 dasctime (&n -> n_tws, TW_NULL));
560 fprintf (stderr, "UNKNOWN(0x%x)\n", (*n -> n_action));
565 static int ORaction (params)
568 if ((*n -> n_L_child -> n_action) (args (n -> n_L_child)))
570 return (*n -> n_R_child -> n_action) (args (n -> n_R_child));
574 static int ANDaction (params)
577 if (!(*n -> n_L_child -> n_action) (args (n -> n_L_child)))
579 return (*n -> n_R_child -> n_action) (args (n -> n_R_child));
583 static int NOTaction (params)
586 return (!(*n -> n_L_child -> n_action) (args (n -> n_L_child)));
591 static int gcompile (n, astr)
592 register struct nexus *n;
602 dp = (ep = n -> n_expbuf) + sizeof n -> n_expbuf;
613 if ((c = *sp++) != '*')
640 if ((c = *sp++) == '^') {
647 if (c == '\0' || ep >= dp)
649 } while ((c = *sp++) != ']');
654 if ((c = *sp++) == '\0')
671 static int GREPaction (params)
684 (void) fseek (fp, start, 0);
688 if (body && n -> n_header)
695 if (fgets (ibuf, sizeof ibuf, fp) == NULL
696 || (stop && pos >= stop)) {
701 pos += (long) strlen (ibuf);
703 ebp = ibuf + strlen (ibuf);
707 if (c != ' ' && c != '\t') {
724 if (c && p1 < &linebuf[LBSIZE - 1])
734 if (advance (p1, p2))
742 if (*p1 == c || cc[*p1] == c)
743 if (advance (p1, p2))
750 if (advance (p1, p2))
758 static int advance (alp, aep)
771 if (*ep++ == *lp++ || ep[-1] == cc[lp[-1]])
789 if (cclass (ep, *lp++, 1)) {
796 if (cclass (ep, *lp++, 0)) {
810 while (*lp++ == *ep || cc[lp[-1]] == *ep)
818 while (cclass (ep, *lp++, ep[-1] == (CCL | STAR)))
826 if (advance (lp, ep))
828 } while (lp > curlp);
832 admonish (NULLCP, "advance() botch -- you lose big");
839 static int cclass (aset, ac, af)
860 static int tcompile (ap, tb, isafter)
862 register struct tws *tb;
865 register struct tws *tw;
867 if ((tw = tws_parse (ap, isafter)) == NULL)
876 static struct tws *tws_parse (ap, isafter)
881 register struct tws *tw,
884 if ((tw = tws_special (ap)) != NULL) {
885 tw -> tw_sec = tw -> tw_min = isafter ? 59 : 0;
886 tw -> tw_hour = isafter ? 23 : 0;
889 if ((tw = dparsetime (ap)) != NULL)
892 if ((ts = dtwstime ()) == NULL)
895 (void) sprintf (buffer, "%s %s", ap, dtwszone (ts));
896 if ((tw = dparsetime (buffer)) != NULL)
899 (void) sprintf (buffer, "%s %02d:%02d:%02d %s", ap,
900 ts -> tw_hour, ts -> tw_min, ts -> tw_sec, dtwszone (ts));
901 if ((tw = dparsetime (buffer)) != NULL)
904 (void) sprintf (buffer, "%02d %s %04d %s",
905 ts -> tw_mday, tw_moty[ts -> tw_mon], ts -> tw_year, ap);
906 if ((tw = dparsetime (buffer)) != NULL)
909 (void) sprintf (buffer, "%02d %s %04d %s %s",
910 ts -> tw_mday, tw_moty[ts -> tw_mon], ts -> tw_year,
912 if ((tw = dparsetime (buffer)) != NULL)
920 static struct tws *tws_special (ap)
925 register struct tws *tw;
927 (void) time (&clock);
928 if (uleq (ap, "Today"))
929 return dlocaltime (&clock);
930 if (uleq (ap, "Yesterday")) {
931 clock -= (long) (60 * 60 * 24);
932 return dlocaltime (&clock);
934 if (uleq (ap, "Tomorrow")) {
935 clock += (long) (60 * 60 * 24);
936 return dlocaltime (&clock);
939 for (i = 0; tw_ldotw[i]; i++)
940 if (uleq (ap, tw_ldotw[i]))
943 if ((tw = dlocaltime (&clock)) == NULL)
945 if ((i -= tw -> tw_wday) > 0)
951 else /* -ddd days ago */
952 i = atoi (ap); /* we should error check this */
954 clock += (long) ((60 * 60 * 24) * i);
955 return dlocaltime (&clock);
962 static int TWSaction (params)
969 register struct tws *tw;
971 (void) fseek (fp, start, 0);
972 for (state = FLD, bp = NULL;;) {
973 switch (state = m_getfld (state, name, buf, sizeof buf, fp)) {
978 free (bp), bp = NULL;
979 bp = add (buf, NULLCP);
980 while (state == FLDPLUS) {
981 state = m_getfld (state, name, buf, sizeof buf, fp);
984 if (uleq (name, n -> n_datef))
994 if (state == LENERR || state == FMTERR)
995 advise (NULLCP, "format error in message %d", msgnum);
1001 adios (NULLCP, "internal error -- you lose");
1008 if ((tw = dparsetime (bp)) == NULL)
1009 advise (NULLCP, "unable to parse %s field in message %d, matching...",
1010 n -> n_datef, msgnum), state = 1;
1012 state = n -> n_after ? (twsort (tw, &n -> n_tws) > 0)
1013 : (twsort (tw, &n -> n_tws) < 0);
1029 static char ident[] = "@@(#)$Id: picksbr.c,v 1.6 1992/01/31 22:20:19 jromine Exp $";
1041 static char ident[] = "@@(#)$Id: picksbr.c,v 1.5 1990/04/05 15:01:50 sources Exp jromine $";
1044 (void) sprintf (buffer, "%02d %s %02d %s",
1047 (void) sprintf (buffer, "%02d %s %02d %s %s",
1058 static char ident[] = "@@(#)$Id:$";
1079 @Fixes from Van Jacobson
1087 static PRaction (n, level)
1098 char buffer[BUFSIZ];
1101 dp = *brkstring (parswit[i].sw, " ", NULLCP);
1112 struct tws *tws_parse (), *tws_special ();
1116 struct nexus *parse (), *exp1 (), *exp2 (), *exp3 (), *newnexus ();
1119 int ORaction (), ANDaction (), NOTaction (), GREPaction (), TWSaction ();