+ printf("%d hit%s\n", mp->numsel, mp->numsel == 1 ? "" : "s");
+ }
+
+ context_replace(curfolder, folder); /* update current folder */
+ seq_save(mp); /* synchronize message sequences */
+ context_save(); /* save the context file */
+ folder_free(mp); /* free folder/message structure */
+ listsw = 0; /* HACK */
+ return 0;
+}
+
+
+void
+putzero_done()
+{
+ if (listsw && !isatty(fileno(stdout)))
+ printf("0\n");
+}
+
+
+static struct swit parswit[] = {
+#define PRAND 0
+ { "and", 0 },
+#define PROR 1
+ { "or", 0 },
+#define PRNOT 2
+ { "not", 0 },
+#define PRLBR 3
+ { "lbrace", 0 },
+#define PRRBR 4
+ { "rbrace", 0 },
+#define PRCC 5
+ { "cc pattern", 0 },
+#define PRDATE 6
+ { "date pattern", 0 },
+#define PRFROM 7
+ { "from pattern", 0 },
+#define PRSRCH 8
+ { "search pattern", 0 },
+#define PRSUBJ 9
+ { "subject pattern", 0 },
+#define PRTO 10
+ { "to pattern", 0 },
+#define PROTHR 11
+ { "-othercomponent pattern", 15 },
+#define PRAFTR 12
+ { "after date", 0 },
+#define PRBEFR 13
+ { "before date", 0 },
+#define PRDATF 14
+ { "datefield field", 5 },
+ { NULL, 0 }
+};
+
+/* DEFINITIONS FOR PATTERN MATCHING */
+
+/*
+** We really should be using re_comp() and re_exec() here. Unfortunately,
+** pick advertises that lowercase characters matches characters of both
+** cases. Since re_exec() doesn't exhibit this behavior, we are stuck
+** with this version. Furthermore, we need to be able to save and restore
+** the state of the pattern matcher in order to do things "efficiently".
+**
+** The matching power of this algorithm isn't as powerful as the re_xxx()
+** routines (no \(xxx\) and \n constructs). Such is life.
+*/
+
+#define CCHR 2
+#define CDOT 4
+#define CCL 6
+#define NCCL 8
+#define CDOL 10
+#define CEOF 11
+
+#define STAR 01
+
+#define LBSIZE 1024
+#define ESIZE 1024
+
+
+static char linebuf[LBSIZE + 1];
+static char decoded_linebuf[LBSIZE + 1];
+
+/* the magic array for case-independence */
+static char cc[] = {
+ 0000,0001,0002,0003,0004,0005,0006,0007,
+ 0010,0011,0012,0013,0014,0015,0016,0017,
+ 0020,0021,0022,0023,0024,0025,0026,0027,
+ 0030,0031,0032,0033,0034,0035,0036,0037,
+ 0040,0041,0042,0043,0044,0045,0046,0047,
+ 0050,0051,0052,0053,0054,0055,0056,0057,
+ 0060,0061,0062,0063,0064,0065,0066,0067,
+ 0070,0071,0072,0073,0074,0075,0076,0077,
+ 0100,0141,0142,0143,0144,0145,0146,0147,
+ 0150,0151,0152,0153,0154,0155,0156,0157,
+ 0160,0161,0162,0163,0164,0165,0166,0167,
+ 0170,0171,0172,0133,0134,0135,0136,0137,
+ 0140,0141,0142,0143,0144,0145,0146,0147,
+ 0150,0151,0152,0153,0154,0155,0156,0157,
+ 0160,0161,0162,0163,0164,0165,0166,0167,
+ 0170,0171,0172,0173,0174,0175,0176,0177,
+
+ 0200,0201,0202,0203,0204,0205,0206,0207,
+ 0210,0211,0212,0213,0214,0215,0216,0217,
+ 0220,0221,0222,0223,0224,0225,0226,0227,
+ 0230,0231,0232,0233,0234,0235,0236,0237,
+ 0240,0241,0242,0243,0244,0245,0246,0247,
+ 0250,0251,0252,0253,0254,0255,0256,0257,
+ 0260,0261,0262,0263,0264,0265,0266,0267,
+ 0270,0271,0272,0273,0274,0275,0276,0277,
+ 0300,0301,0302,0303,0304,0305,0306,0307,
+ 0310,0311,0312,0313,0314,0315,0316,0317,
+ 0320,0321,0322,0323,0324,0325,0326,0327,
+ 0330,0331,0332,0333,0334,0335,0336,0337,
+ 0340,0341,0342,0343,0344,0345,0346,0347,
+ 0350,0351,0352,0353,0354,0355,0356,0357,
+ 0360,0361,0362,0363,0364,0365,0366,0367,
+ 0370,0371,0372,0373,0374,0375,0376,0377,
+};
+
+/*
+** DEFINITIONS FOR NEXUS
+*/
+
+#define nxtarg() (*argp ? *argp++ : NULL)
+#define prvarg() argp--
+
+#define padvise if (!talked++) advise
+
+struct nexus {
+ int (*n_action)();
+
+ union {
+ /* for {OR,AND,NOT}action */
+ struct {
+ struct nexus *un_L_child;
+ struct nexus *un_R_child;
+ } st1;
+
+ /* for GREPaction */
+ struct {
+ int un_header;
+ int un_circf;
+ char un_expbuf[ESIZE];
+ char *un_patbuf;
+ } st2;
+
+ /* for TWSaction */
+ struct {
+ char *un_datef;
+ int un_after;
+ struct tws un_tws;
+ } st3;
+ } un;
+};
+
+#define n_L_child un.st1.un_L_child
+#define n_R_child un.st1.un_R_child
+
+#define n_header un.st2.un_header
+#define n_circf un.st2.un_circf
+#define n_expbuf un.st2.un_expbuf
+#define n_patbuf un.st2.un_patbuf
+
+#define n_datef un.st3.un_datef
+#define n_after un.st3.un_after
+#define n_tws un.st3.un_tws
+
+static int talked;
+static int pdebug = 0;
+
+static char *datesw;
+static char **argp;
+
+static struct nexus *head;
+
+/*
+** prototypes for date routines
+*/
+static struct tws *tws_parse(char *, int);
+static struct tws *tws_special(char *);
+
+/*
+** static prototypes
+*/
+static void PRaction(struct nexus *, int);
+static int gcompile(struct nexus *, char *);
+static int advance(char *, char *);
+static int cclass(unsigned char *, int, int);
+static int tcompile(char *, struct tws *, int);
+
+static struct nexus *parse(void);
+static struct nexus *nexp1(void);
+static struct nexus *nexp2(void);
+static struct nexus *nexp3(void);
+static struct nexus *newnexus(int (*)());
+
+static int ORaction();
+static int ANDaction();
+static int NOTaction();
+static int GREPaction();
+static int TWSaction();
+
+
+static int
+pcompile(char **vec, char *date)
+{
+ char *cp;
+
+ if ((cp = getenv("MHPDEBUG")) && *cp)
+ pdebug++;
+
+ argp = vec;
+ if ((datesw = date) == NULL)
+ datesw = "date";
+ talked = 0;
+
+ if ((head = parse()) == NULL)
+ return (talked ? 0 : 1);
+
+ if (*argp) {
+ padvise(NULL, "%s unexpected", *argp);
+ return 0;