X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Fpick.c;h=1c195be4249316bccbf73cda589a04f5ac5a7529;hp=3e250a779bb0576a97a80798d9b5297090ec8d3d;hb=e0bd1185d5a6a854a04f3c567195cfe96df112d0;hpb=641a9d953e86685f9ca2f3da72e9a94e5bcfd69e diff --git a/uip/pick.c b/uip/pick.c index 3e250a7..1c195be 100644 --- a/uip/pick.c +++ b/uip/pick.c @@ -9,11 +9,13 @@ #include #include #include +#include +#include #include #include #include -#include -#include +#include +#include #ifdef HAVE_SYS_TIME_H # include @@ -78,11 +80,22 @@ static struct swit switches[] = { char *version=VERSION; +struct nexus { + boolean (*action)(struct field *, int, void *); + void (*free)(struct nexus **); + void (*debug)(void *, size_t); + + void *data; +}; + +static struct nexus *head; +static boolean body = FALSE; + /* ** static prototypes */ static int pcompile(char **, char *); -static int pmatches(FILE *, int, long, long); +static int pmatches(FILE *, int); static int listsw = -1; @@ -293,7 +306,7 @@ main(int argc, char **argv) if (is_selected(mp, msgnum)) { if ((fp = fopen(cp = m_name(msgnum), "r")) == NULL) admonish(cp, "unable to read message"); - if (fp && pmatches(fp, msgnum, 0L, 0L)) { + if (fp && pmatches(fp, msgnum)) { if (msgnum < lo) lo = msgnum; if (msgnum > hi) @@ -311,6 +324,8 @@ main(int argc, char **argv) } } + head->free(&head); + mp->lowsel = lo; mp->hghsel = hi; @@ -434,47 +449,6 @@ static struct swit parswit[] = { #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 */ @@ -484,44 +458,36 @@ static char cc[] = { #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; + +enum nexus_type { + TYPE_GREP, + TYPE_DATE, + TYPE_OR, + TYPE_AND, + TYPE_NOT }; -#define n_L_child un.st1.un_L_child -#define n_R_child un.st1.un_R_child +struct bin_data { + struct nexus *left; + struct nexus *right; + enum nexus_type type; + int oldmsgnum; + boolean leftmatch; + boolean rightmatch; + boolean match; +}; -#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 +struct date_data { + char *datef; + boolean after; + struct tws tws; +}; -#define n_datef un.st3.un_datef -#define n_after un.st3.un_after -#define n_tws un.st3.un_tws +struct grep_data { + char *header; + char *pattern; + regex_t *preg; +}; static int talked; static int pdebug = 0; @@ -529,7 +495,6 @@ static int pdebug = 0; static char *datesw; static char **argp; -static struct nexus *head; /* ** prototypes for date routines @@ -540,24 +505,27 @@ 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 gcompile(struct grep_data *, const char *); 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 struct nexus *newnexus(enum nexus_type); -static int ORaction(); -static int ANDaction(); -static int NOTaction(); -static int GREPaction(); -static int TWSaction(); +static boolean BINaction(struct field *, int, void *); +static boolean NOTaction(struct field *, int, void *); +static boolean GREPaction(struct field *, int, void *); +static boolean DATEaction(struct field *, int, void *); +static void BINfree(struct nexus **); +static void GREPfree(struct nexus **); +static void DATEfree(struct nexus **); + +static void BINdebug(void *, size_t); +static void GREPdebug(void *, size_t); +static void DATEdebug(void *, size_t); static int pcompile(char **vec, char *date) @@ -589,6 +557,7 @@ parse(void) { char *cp; struct nexus *n, *o; + struct bin_data *bin; if ((n = nexp1()) == NULL || (cp = nxtarg()) == NULL) return n; @@ -611,9 +580,10 @@ parse(void) return NULL; case PROR: - o = newnexus(ORaction); - o->n_L_child = n; - if ((o->n_R_child = parse())) + o = newnexus(TYPE_OR); + bin = o->data; + bin->left = n; + if ((bin->right = parse())) return o; padvise(NULL, "missing disjunctive"); return NULL; @@ -630,6 +600,7 @@ nexp1(void) { char *cp; struct nexus *n, *o; + struct bin_data *bin; if ((n = nexp2()) == NULL || (cp = nxtarg()) == NULL) return n; @@ -652,9 +623,10 @@ nexp1(void) return NULL; case PRAND: - o = newnexus(ANDaction); - o->n_L_child = n; - if ((o->n_R_child = nexp1())) + o = newnexus(TYPE_AND); + bin = o->data; + bin->left = n; + if ((bin->right = nexp1())) return o; padvise(NULL, "missing conjunctive"); return NULL; @@ -672,6 +644,7 @@ nexp2(void) { char *cp; struct nexus *n; + struct bin_data *bin; if ((cp = nxtarg()) == NULL) return NULL; @@ -694,8 +667,9 @@ nexp2(void) return NULL; case PRNOT: - n = newnexus(NOTaction); - if ((n->n_L_child = nexp3())) + n = newnexus(TYPE_NOT); + bin = n->data; + if ((bin->left = nexp3())) return n; padvise(NULL, "missing negation"); return NULL; @@ -714,6 +688,8 @@ nexp3(void) char *cp, *dp; char buffer[BUFSIZ], temp[64]; struct nexus *n; + struct grep_data *gdata; + struct date_data *twsd; if ((cp = nxtarg()) == NULL) return NULL; @@ -768,26 +744,28 @@ header: ; padvise(NULL, "missing argument to %s", argp[-2]); return NULL; } - n = newnexus(GREPaction); - n->n_header = 1; - snprintf(buffer, sizeof(buffer), "^%s[ \t]*:.*%s", dp, cp); + n = newnexus(TYPE_GREP); + gdata = n->data; + gdata->header = mh_xstrdup(dp); + snprintf(buffer, sizeof(buffer), "%s", cp); dp = buffer; goto pattern; case PRSRCH: - n = newnexus(GREPaction); - n->n_header = 0; + n = newnexus(TYPE_GREP); + gdata = n->data; + gdata->header = NULL; + body = TRUE; if (!(cp = nxtarg())) { /* allow -xyz arguments */ padvise(NULL, "missing argument to %s", argp[-2]); return NULL; } dp = cp; pattern: ; - if (!gcompile(n, dp)) { - padvise(NULL, "pattern error in %s %s", argp[-2], cp); + if (!gcompile(gdata, dp)) { + padvise("regcomp", "pattern error in %s %s", argp[-2], cp); return NULL; } - n->n_patbuf = mh_xstrdup(dp); return n; case PROTHR: @@ -808,9 +786,10 @@ pattern: ; padvise(NULL, "missing argument to %s", argp[-2]); return NULL; } - n = newnexus(TWSaction); - n->n_datef = datesw; - if (!tcompile(cp, &n->n_tws, n->n_after = i == PRAFTR)) { + n = newnexus(TYPE_DATE); + twsd = n->data; + twsd->datef = datesw; + if (!tcompile(cp, &twsd->tws, twsd->after = i == PRAFTR)) { padvise(NULL, "unable to parse %s %s", argp[-2], cp); return NULL; } @@ -820,386 +799,287 @@ pattern: ; static struct nexus * -newnexus(int (*action)()) +newnexus(enum nexus_type t) { - struct nexus *p; - - p = mh_xcalloc(1, sizeof *p); + struct nexus *p = NULL; + struct bin_data *bin; + + p = mh_xcalloc(1, sizeof(struct nexus)); + + switch (t) { + case TYPE_NOT: + p->action = NOTaction; + p->debug = BINdebug; + p->free = BINfree; + p->data = bin = mh_xcalloc(1, sizeof(struct bin_data)); + bin->type = t; + break; + case TYPE_AND: + case TYPE_OR: + p->action = BINaction; + p->debug = BINdebug; + p->free = BINfree; + p->data = bin = mh_xcalloc(1, sizeof(struct bin_data)); + bin->type = t; + break; + case TYPE_GREP: + p->action = GREPaction; + p->debug = GREPdebug; + p->free = GREPfree; + p->data = mh_xcalloc(1, sizeof(struct grep_data)); + break; + case TYPE_DATE: + p->action = DATEaction; + p->debug = DATEdebug; + p->free = DATEfree; + p->data = mh_xcalloc(1, sizeof(struct date_data)); + break; + default: + adios(EX_SOFTWARE, NULL, "unknown nexus type %d", t); + } - p->n_action = action; return p; -} - -#define args(a) a, fp, msgnum, start, stop -#define params args(n) -#define plist \ - struct nexus *n; \ - FILE *fp; \ - int msgnum; \ - long start, \ - stop; +} static int -pmatches(FILE *fp, int msgnum, long start, long stop) +pmatches(FILE *fp, int msgnum) { + struct field f = {{0}}; + enum state s = FLD2; + if (!head) return 1; - if (!talked++ && pdebug) - PRaction(head, 0); + if (!talked++ && pdebug && head->debug) { + head->debug(head->data, 0); + } - return (*head->n_action) (args(head)); + while (s == FLD2 || s == BODY2) { + switch (s = m_getfld2(s, &f, fp)) { + case LENERR2: + s = FLD2; + /* FALL */ + case FLD2: + if (head->action(&f, msgnum, head->data)) { + return TRUE; + } + break; + case BODY2: + if (!body) { + return FALSE; + } + if (head->action(&f, msgnum, head->data)) { + return TRUE; + } + break; + case IOERR2: + advise(NULL, "IOERR in message %d\n", msgnum); + return FALSE; + case FILEEOF2: + return FALSE; + default: + adios(EX_SOFTWARE, "m_getfld2", "returned unknown state %d at message %d", s, msgnum); + } + } + return FALSE; } +void +print_debug_level(size_t level) +{ + size_t i; -static void -PRaction(struct nexus *n, int level) + for (i = 0; i < level; i++) { + fputs("| ", stderr); + } +} + +void +BINdebug(void *data, size_t level) { - int i; + struct bin_data *bd = data; - for (i = 0; i < level; i++) - fprintf(stderr, "| "); + print_debug_level(level); - if (n->n_action == ORaction) { - fprintf(stderr, "OR\n"); - PRaction(n->n_L_child, level + 1); - PRaction(n->n_R_child, level + 1); - return; - } - if (n->n_action == ANDaction) { - fprintf(stderr, "AND\n"); - PRaction(n->n_L_child, level + 1); - PRaction(n->n_R_child, level + 1); - return; - } - if (n->n_action == NOTaction) { - fprintf(stderr, "NOT\n"); - PRaction(n->n_L_child, level + 1); + switch (bd->type) { + case TYPE_OR: + fputs("OR\n", stderr); + break; + case TYPE_AND: + fputs("AND\n", stderr); + break; + case TYPE_NOT: + fputs("NOT\n", stderr); + break; + default: + advise(NULL, "binary nexus has unknown type: %d\n", bd->type); return; } - if (n->n_action == GREPaction) { - fprintf(stderr, "PATTERN(%s) %s\n", - n->n_header ? "header" : "body", n->n_patbuf); - return; + + if (bd->left && bd->left->debug) { + bd->left->debug(bd->left->data, level+1); + } else { + print_debug_level(level+1); + fputs("can't debug left child\n", stderr); } - if (n->n_action == TWSaction) { - fprintf(stderr, "TEMPORAL(%s) %s: %s\n", - n->n_after ? "after" : "before", n->n_datef, - dasctime(&n->n_tws)); - return; + + if (bd->right && bd->right->debug) { + bd->right->debug(bd->right->data, level+1); + } else if (bd->type != TYPE_NOT) { + print_debug_level(level+1); + fputs("can't debug right child\n", stderr); } - fprintf(stderr, "UNKNOWN(0x%x)\n", - (unsigned int)(unsigned long) (*n->n_action)); } - -static int -ORaction(params) -plist +static boolean +NOTaction(struct field *f, int msgnum, void *data) { - if ((*n->n_L_child->n_action) (args(n->n_L_child))) - return 1; - return (*n->n_R_child->n_action) (args(n->n_R_child)); + struct bin_data *bin = data; + return !bin->left->action(f, msgnum, bin->left->data); } - -static int -ANDaction(params) -plist +static boolean +BINaction(struct field *f, int msgnum, void *data) { - if (!(*n->n_L_child->n_action) (args(n->n_L_child))) - return 0; - return (*n->n_R_child->n_action) (args(n->n_R_child)); -} + struct bin_data *bin = data; + if (bin->oldmsgnum != msgnum) { + bin->oldmsgnum = msgnum; + bin->match = FALSE; + bin->leftmatch = FALSE; + bin->rightmatch = FALSE; + } -static int -NOTaction(params) -plist -{ - return (!(*n->n_L_child->n_action) (args(n->n_L_child))); -} + if (bin->match) { + return bin->match; + } + bin->leftmatch = bin->leftmatch || bin->left->action(f, msgnum, bin->left->data); + bin->rightmatch = bin->rightmatch || bin->right->action(f, msgnum, bin->right->data); -static int -gcompile(struct nexus *n, char *astr) -{ - int c; - int cclcnt; - unsigned char *ep, *dp, *sp, *lastep = 0; - - dp = (ep = n->n_expbuf) + sizeof n->n_expbuf; - sp = astr; - if (*sp == '^') { - n->n_circf = 1; - sp++; - } - else - n->n_circf = 0; - for (;;) { - if (ep >= dp) - goto cerror; - if ((c = *sp++) != '*') - lastep = ep; - switch (c) { - case '\0': - *ep++ = CEOF; - return 1; - - case '.': - *ep++ = CDOT; - continue; - - case '*': - if (lastep == 0) - goto defchar; - *lastep |= STAR; - continue; - - case '$': - if (*sp != '\0') - goto defchar; - *ep++ = CDOL; - continue; - - case '[': - *ep++ = CCL; - *ep++ = 0; - cclcnt = 0; - if ((c = *sp++) == '^') { - c = *sp++; - ep[-2] = NCCL; - } - if (c == '-') { - *ep++ = c; - cclcnt++; - c = *sp++; - } - do { - if (c == '-' && *sp != '\0' && *sp != ']') { - for (c = ep[-1]+1; c < *sp; c++) { - *ep++ = c; - cclcnt++; - if (c == '\0' || ep >= dp) - goto cerror; - } - } else { - *ep++ = c; - cclcnt++; - if (c == '\0' || ep >= dp) - goto cerror; - } - } while ((c = *sp++) != ']'); - if (cclcnt > 255) - goto cerror; - lastep[1] = cclcnt; - continue; - - case '\\': - if ((c = *sp++) == '\0') - goto cerror; -defchar: - default: - *ep++ = CCHR; - *ep++ = c; - } + switch (bin->type) { + case TYPE_OR: + bin->match = bin->leftmatch || bin->rightmatch; + break; + case TYPE_AND: + bin->match = bin->leftmatch && bin->rightmatch; + break; + default: + adios(EX_SOFTWARE, NULL, "unknown nexus type: %d\n", bin->type); } -cerror: ; - return 0; + return bin->match; } - -static int -GREPaction(params) -plist +static void +BINfree(struct nexus **n) { - int c, body, lf; - long pos = start; - char *p1, *p2, *ebp, *cbp; - char ibuf[BUFSIZ]; - - fseek(fp, start, SEEK_SET); - body = 0; - ebp = cbp = ibuf; - for (;;) { - if (body && n->n_header) - return 0; - p1 = linebuf; - p2 = cbp; - lf = 0; - for (;;) { - if (p2 >= ebp) { - if (fgets(ibuf, sizeof ibuf, fp) == NULL - || (stop && pos >= stop)) { - if (lf) - break; - return 0; - } - pos += (long) strlen(ibuf); - p2 = ibuf; - ebp = ibuf + strlen(ibuf); - } - c = *p2++; - if (lf && c != '\n') { - if (c != ' ' && c != '\t') { - --p2; - break; - } - else - lf = 0; - } - if (c == '\n') { - if (body) - break; - else { - if (lf) { - body++; - break; - } - lf++; - c = ' '; - } - } - if (c && p1 < &linebuf[LBSIZE - 1]) - *p1++ = c; - } + struct nexus *bin = *n; + struct bin_data *bd = bin->data; - *p1++ = 0; - cbp = p2; - 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; - continue; - } - - if (*p2 == CCHR) { - c = p2[1]; - do { - if (*p1 == c || cc[(unsigned char)*p1] == c) - if (advance(p1, p2)) - return 1; - } while (*p1++); - continue; - } + if (bd->left && bd->left->free) { + bd->left->free(&bd->left); + } else { + advise(NULL, "BUG: can't free left child"); + } - do { - if (advance(p1, p2)) - return 1; - } while (*p1++); + if (bd->right && bd->right->free) { + bd->right->free(&bd->right); + } else { + advise(NULL, "BUG: can't free right child"); } -} + mh_free0(n); +} static int -advance(char *alp, char *aep) +gcompile(struct grep_data *g, const char *astr) { - unsigned char *lp, *ep, *curlp; - - lp = (unsigned char *)alp; - ep = (unsigned char *)aep; - for (;;) - switch (*ep++) { - case CCHR: - if (*ep++ == *lp++ || ep[-1] == cc[lp[-1]]) - continue; - return 0; - - case CDOT: - if (*lp++) - continue; - return 0; - - case CDOL: - if (*lp == 0) - continue; - return 0; - - case CEOF: - return 1; - - case CCL: - if (cclass(ep, *lp++, 1)) { - ep += *ep + 1; - continue; - } - return 0; + regex_t *preg = mh_xcalloc(1, sizeof(regex_t)); + char *buf; + int ret; + + g->preg = preg; + g->pattern = mh_xstrdup(astr); + ret = regcomp(preg, astr, REG_ICASE | REG_NOSUB); + if (ret != 0) { + buf = mh_xcalloc(BUFSIZ, sizeof(char)); + regerror(ret, g->preg, buf, BUFSIZ*sizeof(char)); + fprintf(stderr, "%s\n", buf); + return FALSE; + } + return TRUE; - case NCCL: - if (cclass(ep, *lp++, 0)) { - ep += *ep + 1; - continue; - } - return 0; +} - case CDOT | STAR: - curlp = lp; - while (*lp++) - continue; - goto star; +static boolean +GREPaction(struct field *f, int msgnum, void *data) +{ + struct grep_data *g = data; + int ret; + char *buf; - case CCHR | STAR: - curlp = lp; - while (*lp++ == *ep || cc[lp[-1]] == *ep) - continue; - ep++; - goto star; + /* check for the write field */ + if (g->header && *g->header && mh_strcasecmp(g->header, f->name)) { + return FALSE; + } - case CCL | STAR: - case NCCL | STAR: - curlp = lp; - while (cclass(ep, *lp++, ep[-1] == (CCL | STAR))) - continue; - ep += *ep + 1; - goto star; + if (!g->header && *f->name) { + return FALSE; + } -star: - do { - lp--; - if (advance(lp, ep)) - return (1); - } while (lp > curlp); - return 0; + ret = regexec(g->preg, f->value, 0, NULL, 0) == REG_NOMATCH; + switch (ret) { + case 0: + return TRUE; + case REG_NOMATCH: + return FALSE; + default: + buf = mh_xcalloc(BUFSIZ, sizeof(char)); + regerror(ret, g->preg, buf, BUFSIZ*sizeof(char)); + fprintf(stderr, "%s\n", buf); + return FALSE; + } - default: - admonish(NULL, "advance() botch -- you lose big"); - return 0; - } } +static void +GREPfree(struct nexus **n) +{ + struct grep_data *gd = (*n)->data; + mh_free0(&gd->header); + regfree(gd->preg); + mh_free0(n); +} -static int -cclass(unsigned char *aset, int ac, int af) +static void +GREPdebug(void *data, size_t level) { - unsigned int n; - unsigned char c, *set; + struct grep_data *gd = data; + char *buf, *buf2, *pbuf, *pbuf2; + + pbuf = pbuf2 = mh_xstrdup(gd->pattern); - set = aset; - if ((c = ac) == 0) - return (0); + for (;*pbuf2; pbuf2++) { + *pbuf2 = tolower(*pbuf2); + } - n = *set++; - while (n--) - if (*set++ == c || set[-1] == cc[c]) - return (af); + print_debug_level(level); - return (!af); + if (gd->header) { + buf = buf2 = mh_xstrdup(gd->header); + for (;*buf2; buf2++) { + *buf2 = tolower(*buf2); + } + fprintf(stderr, "PETTERN(%s) %s\n", buf, pbuf); + } else { + fprintf(stderr, "PETTERN(BODY) %s\n", pbuf); + } + mh_free0(&buf); + mh_free0(&pbuf); } - static int tcompile(char *ap, struct tws *tb, int isafter) { @@ -1293,60 +1173,45 @@ tws_special(char *ap) } -static int -TWSaction(params) -plist +static boolean +DATEaction(struct field *f, int msgnum, void *data) { - enum state state; - struct field f = {{0}}; + struct date_data *dd = data; + boolean state = FALSE; char *bp; struct tws *tw; - fseek(fp, start, SEEK_SET); - for (state = FLD2, bp = NULL;;) { - switch (state = m_getfld2(state, &f, fp)) { - case LENERR2: - state = FLD2; - /* FALL */ - - case FLD2: - if (bp) { - mh_free0(&bp); - } - bp = mh_xstrdup(f.value); - if (mh_strcasecmp(f.name, n->n_datef)==0) { - break; - } - continue; - - case FMTERR2: - advise(NULL, "format error in message %d", msgnum); - state = FLD2; - continue; + if (mh_strcasecmp(f->name, dd->datef)!=0) { + return FALSE; + } + bp = mh_xstrdup(f->value); + if ((tw = dparsetime(bp)) == NULL) { + advise(NULL, "unable to parse %s field in message %d, not matching...", dd->datef, msgnum); + state = FALSE; + } else if (dd->after) { + state = twsort(tw, &dd->tws) > 0; + } else { + state = twsort(tw, &dd->tws) < 0; + } - case IOERR2: - adios(EX_IOERR, "m_getfld2", "io error on message %d", msgnum); - /* FALL */ + mh_free0(&bp); - case BODY2: - case FILEEOF2: - mh_free0(&bp); - return 0; + return state; +} - default: - adios(EX_SOFTWARE, NULL, "internal error -- you lose"); - } - break; - } +static void +DATEfree(struct nexus **n) +{ + struct date_data *dd = (*n)->data; - if ((tw = dparsetime(bp)) == NULL) - advise(NULL, "unable to parse %s field in message %d, matching...", - n->n_datef, msgnum), state = 1; - else - state = n->n_after ? (twsort(tw, &n->n_tws) > 0) - : (twsort(tw, &n->n_tws) < 0); + mh_free0(&dd->datef); + mh_free0(n); +} - if (bp != NULL) - mh_free0(&bp); - return state; +static void +DATEdebug(void *data, size_t level) +{ + struct date_data *dd = data; + print_debug_level(level); + fprintf(stderr, "TEMPORAL(%s) %s: %s\n",dd->after ? "after" : "before", dd->datef, dasctime(&dd->tws)); }