]> diplodocus.org Git - nmh/blobdiff - uip/picksbr.c
The start of the use of argsplit() to process command strings.
[nmh] / uip / picksbr.c
index 4afd0941e9029a836ac1c393838ae7bc93ad5856..c572cde01ff82a6b53bf8c6b7ad80ef165f36d37 100644 (file)
 #endif
 #include <time.h>
 
-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 }
-};
+#define PARSE_SWITCHES \
+    X("and", 0, PRAND) \
+    X("or", 0, PROR) \
+    X("not", 0, PRNOT) \
+    X("lbrace", 0, PRLBR) \
+    X("rbrace", 0, PRRBR) \
+    X("cc  pattern", 0, PRCC) \
+    X("date  pattern", 0, PRDATE) \
+    X("from  pattern", 0, PRFROM) \
+    X("search  pattern", 0, PRSRCH) \
+    X("subject  pattern", 0, PRSUBJ) \
+    X("to  pattern", 0, PRTO) \
+    X("-othercomponent  pattern", 15, PROTHR) \
+    X("after date", 0, PRAFTR) \
+    X("before date", 0, PRBEFR) \
+    X("datefield field", 5, PRDATF) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(PARSE);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(PARSE, parswit);
+#undef X
 
 /* DEFINITIONS FOR PATTERN MATCHING */
 
@@ -78,9 +69,10 @@ static struct swit parswit[] = {
 
 
 static char linebuf[LBSIZE + 1];
+static char decoded_linebuf[LBSIZE + 1];
 
 /* the magic array for case-independence */
-static char cc[] = {
+static unsigned 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,
@@ -175,23 +167,23 @@ static struct nexus *head;
 /*
  * prototypes for date routines
  */
-static struct tws *tws_parse();
-static struct tws *tws_special();
+static struct tws *tws_parse(char *, int);
+static struct tws *tws_special(char *);
 
 /*
  * static prototypes
  */
-static void PRaction();
-static int gcompile();
-static int advance();
-static int cclass();
-static int tcompile();
-
-static struct nexus *parse();
-static struct nexus *nexp1();
-static struct nexus *nexp2();
-static struct nexus *nexp3();
-static struct nexus *newnexus();
+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();
@@ -660,6 +652,7 @@ plist
     long pos = start;
     register char *p1, *p2, *ebp, *cbp;
     char ibuf[BUFSIZ];
+    NMH_UNUSED (msgnum);
 
     fseek (fp, start, SEEK_SET);
     body = 0;
@@ -700,7 +693,8 @@ plist
                        break;
                    }
                    lf++;
-                   c = ' ';
+                   /* Unfold by skipping the newline. */
+                   c = 0;
                }
            }
            if (c && p1 < &linebuf[LBSIZE - 1])
@@ -712,6 +706,13 @@ plist
        p1 = linebuf;
        p2 = n->n_expbuf;
 
+       /* Attempt to decode as a MIME header.  If it's the last header,
+          body will be 1 and lf will be at least 1. */
+       if ((body == 0 || lf > 0)  &&
+           decode_rfc2047 (linebuf, decoded_linebuf, sizeof decoded_linebuf)) {
+           p1 = decoded_linebuf;
+       }
+
        if (n->n_circf) {
            if (advance (p1, p2))
                return 1;
@@ -933,27 +934,28 @@ plist
     register char *bp;
     char buf[BUFSIZ], name[NAMESZ];
     register struct tws *tw;
+    m_getfld_state_t gstate = 0;
+    NMH_UNUSED (stop);
 
     fseek (fp, start, SEEK_SET);
-    for (state = FLD, bp = NULL;;) {
-       switch (state = m_getfld (state, name, buf, sizeof buf, fp)) {
+    for (bp = NULL;;) {
+       int bufsz = sizeof buf;
+       switch (state = m_getfld (&gstate, name, buf, &bufsz, fp)) {
            case FLD: 
-           case FLDEOF: 
            case FLDPLUS: 
                if (bp != NULL)
                    free (bp), bp = NULL;
                bp = add (buf, NULL);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name, buf, sizeof buf, fp);
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, fp);
                    bp = add (buf, bp);
                }
                if (!mh_strcasecmp (name, n->n_datef))
                    break;
-               if (state != FLDEOF)
-                   continue;
+               continue;
 
            case BODY: 
-           case BODYEOF: 
            case FILEEOF: 
            case LENERR: 
            case FMTERR: 
@@ -968,6 +970,7 @@ plist
        }
        break;
     }
+    m_getfld_state_destroy (&gstate);
 
     if ((tw = dparsetime (bp)) == NULL)
        advise (NULL, "unable to parse %s field in message %d, matching...",