X-Git-Url: http://git.marmaro.de/?a=blobdiff_plain;f=uip%2Fpick.c;fp=uip%2Fpick.c;h=464a7345db4d23485fe54f0bff0ff9137e3d0eb1;hb=3ec7019fb0a1c08f1c866f0a84fa75fe5b498596;hp=1c195be4249316bccbf73cda589a04f5ac5a7529;hpb=e0bd1185d5a6a854a04f3c567195cfe96df112d0;p=mmh diff --git a/uip/pick.c b/uip/pick.c index 1c195be..464a734 100644 --- a/uip/pick.c +++ b/uip/pick.c @@ -71,9 +71,11 @@ static struct swit switches[] = { { "format format", 0 }, #define WIDTHSW 23 { "width columns", 0 }, -#define VERSIONSW 24 +#define THREADSW 24 + { "thread", 0 }, +#define VERSIONSW 25 { "Version", 0 }, -#define HELPSW 25 +#define HELPSW 26 { "help", 0 }, { NULL, 0 } }; @@ -96,6 +98,8 @@ static boolean body = FALSE; */ static int pcompile(char **, char *); static int pmatches(FILE *, int); +static struct nexus * createonethread(char *); +static struct nexus * createpickthread(char *); static int listsw = -1; @@ -169,6 +173,7 @@ main(int argc, char **argv) case AFTRSW: case BEFRSW: case SRCHSW: + case THREADSW: vec[vecp++] = --cp; pattern: if (!(cp = *argp++)) /* allow -xyz arguments */ @@ -324,7 +329,9 @@ main(int argc, char **argv) } } - head->free(&head); + if (head) { + head->free(&head); + } mp->lowsel = lo; mp->hghsel = hi; @@ -421,6 +428,8 @@ static struct swit parswit[] = { { "before date", 0 }, #define PRDATF 14 { "datefield field", 5 }, +#define PRTHREAD 15 + { "thread msg", 0 }, { NULL, 0 } }; @@ -731,6 +740,11 @@ nexp3(void) prvarg(); return NULL; + case PRTHREAD: + if (!(cp = nxtarg())) { /* allow -xyz arguments */ + padvise(NULL, "missing argument to %s", argp[-2]); + } + return createpickthread(cp); case PRCC: case PRDATE: case PRFROM: @@ -975,8 +989,13 @@ BINaction(struct field *f, int msgnum, void *data) static void BINfree(struct nexus **n) { - struct nexus *bin = *n; - struct bin_data *bd = bin->data; + struct bin_data *bd; + + if (!(*n)) { + return; + } + + bd = (*n)->data; if (bd->left && bd->left->free) { bd->left->free(&bd->left); @@ -1020,12 +1039,12 @@ GREPaction(struct field *f, int msgnum, void *data) int ret; char *buf; - /* check for the write field */ - if (g->header && *g->header && mh_strcasecmp(g->header, f->name)) { + if (!g->header && *f->name) { return FALSE; } - if (!g->header && *f->name) { + /* check for the right field */ + if (g->header && *g->header && mh_strcasecmp(g->header, f->name)==0) { return FALSE; } @@ -1047,7 +1066,11 @@ GREPaction(struct field *f, int msgnum, void *data) static void GREPfree(struct nexus **n) { - struct grep_data *gd = (*n)->data; + struct grep_data *gd; + if (!(*n)) { + return; + } + gd = (*n)->data; mh_free0(&gd->header); regfree(gd->preg); mh_free0(n); @@ -1202,7 +1225,11 @@ DATEaction(struct field *f, int msgnum, void *data) static void DATEfree(struct nexus **n) { - struct date_data *dd = (*n)->data; + struct date_data *dd; + if (!(*n)) { + return; + } + dd = (*n)->data; mh_free0(&dd->datef); mh_free0(n); @@ -1215,3 +1242,100 @@ DATEdebug(void *data, size_t level) print_debug_level(level); fprintf(stderr, "TEMPORAL(%s) %s: %s\n",dd->after ? "after" : "before", dd->datef, dasctime(&dd->tws)); } + +static struct nexus * +createpickthread(char *msgs) +{ + char *folder = NULL; + struct msgs_array msgarray = {0}; + struct msgs_array files = {0}; + struct nexus *ret = NULL; + struct nexus *c; + struct nexus *or; + struct bin_data *bd; + char *buf; + char **cp = brkstring(msgs, " \t", NULL); + int i; + + for (; cp && *cp; cp++) { + switch (**cp) { + case '@': + case '+': + if (folder) { + advise("",""); + break; + } + folder = mh_xstrdup(*cp); + break; + default: + app_msgarg(&msgarray, mh_xstrdup(*cp)); + } + } + + parse_msgs(&msgarray, folder, &files); + + for (i = 0; i < files.size; i++) { + buf = getthreadid(files.msgs[i]); + if (!buf) { + continue; + } + + c = createonethread(buf); + + if (!ret) { + ret = c; + continue; + } + + + or = newnexus(TYPE_OR); + bd = or->data; + bd->right = ret; + bd->left = c; + ret = or; + } + + mh_free0(&(files.msgs)); + mh_free0(&(msgarray.msgs)); + + return ret; +} + +static struct nexus * +createonethread(char *c) +{ + struct nexus *ret = newnexus(TYPE_OR); + struct nexus *left = newnexus(TYPE_GREP); + struct nexus *right = newnexus(TYPE_GREP); + struct bin_data *bd = ret->data; + struct grep_data *gd = left->data; + char buf[BUFSIZ]; + + bd->left = left; + bd->right = right; + gd->header = "message-id"; + + snprintf(buf, sizeof(buf), "^[ \t]*<%s>", c); + if(!gcompile(gd, buf)) { + padvise(NULL, "pattern error %s", c); + goto error; + } + + gd = right->data; + gd->header = "references"; + + snprintf(buf, sizeof(buf), "^[ \t]*<%s>", c); + if(!gcompile(gd, buf)) { + padvise(NULL, "pattern error in %s", c); + goto error; + } + + return ret; + +error: + GREPfree(&left); + GREPfree(&right); + BINfree(&ret); + return NULL; + +}