X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/64cc8937ff11ffd37736f27ceed5f4ff93161ca7..9f1e781a5c2beb9df943c832300a3f5bee1e4ed3:/uip/pick.c diff --git a/uip/pick.c b/uip/pick.c index 66198ff2..b5a7cdd6 100644 --- a/uip/pick.c +++ b/uip/pick.c @@ -1,18 +1,21 @@ - -/* - * pick.c -- search for messages by content +/* pick.c -- search for messages by content * * This code is Copyright (c) 2002, 2008, by the authors of nmh. See the * COPYRIGHT file in the root directory of the nmh distribution for * complete copyright information. */ -#include -#include -#include -#include +#include "h/mh.h" +#include "sbr/seq_add.h" +#include "sbr/error.h" +#include "h/tws.h" +#include "h/picksbr.h" +#include "h/done.h" +#include "h/utils.h" +#include "sbr/m_maildir.h" #define PICK_SWITCHES \ + X("reverse", 0, REVSW) \ X("and", 0, ANDSW) \ X("or", 0, ORSW) \ X("not", 0, NOTSW) \ @@ -36,6 +39,7 @@ X("nozero", 0, NZEROSW) \ X("list", 0, LISTSW) \ X("nolist", 0, NLISTSW) \ + X("debug", 0, DEBUGSW) \ X("version", 0, VERSIONSW) \ X("help", 0, HELPSW) \ @@ -54,26 +58,26 @@ static void putzero_done (int) NORETURN; int main (int argc, char **argv) { - int publicsw = -1, zerosw = 1, vecp = 0; + int publicsw = -1; + bool zerosw = true; + int vecp = 0; size_t seqp = 0; int msgnum; char *maildir, *folder = NULL, buf[100]; char *cp, **argp, **arguments; - char *seqs[NUMATTRS + 1], *vec[MAXARGS]; + svector_t seqs = svector_create (0); + char *vec[MAXARGS]; struct msgs_array msgs = { 0, 0, NULL }; struct msgnum_array nums = { 0, 0, NULL }; struct msgs *mp, *mp2; - register FILE *fp; - - done=putzero_done; + FILE *fp; + int debug = 0; + bool reverse = false; + int start, end, inc; -#ifdef LOCALE - setlocale(LC_ALL, ""); -#endif - invo_name = r1bindex (argv[0], '/'); + if (nmh_init(argv[0], true, true)) { return 1; } - /* read user profile/context */ - context_read(); + set_done(putzero_done); arguments = getarguments (invo_name, argc, argv, 1); argp = arguments; @@ -90,7 +94,7 @@ main (int argc, char **argv) listsw = 0; /* HACK */ done (1); case UNKWNSW: - adios (NULL, "-%s unknown", cp); + die("-%s unknown", cp); case HELPSW: snprintf (buf, sizeof(buf), "%s [+folder] [msgs] [switches]", @@ -103,6 +107,10 @@ main (int argc, char **argv) listsw = 0; /* HACK */ done (0); + case REVSW: + reverse = true; + continue; + case CCSW: case DATESW: case FROMSW: @@ -115,11 +123,11 @@ main (int argc, char **argv) vec[vecp++] = --cp; pattern: if (!(cp = *argp++))/* allow -xyz arguments */ - adios (NULL, "missing argument to %s", argp[-2]); + die("missing argument to %s", argp[-2]); vec[vecp++] = cp; continue; case OTHRSW: - adios (NULL, "internal error!"); + die("internal error!"); case ANDSW: case ORSW: @@ -131,16 +139,13 @@ main (int argc, char **argv) case SEQSW: if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - - /* check if too many sequences specified */ - if (seqp >= NUMATTRS) - adios (NULL, "too many sequences (more than %d) specified", NUMATTRS); + die("missing argument to %s", argp[-2]); if (!seq_nameok (cp)) done (1); - seqs[seqp++] = cp; + svector_push_back (seqs, cp); + seqp++; continue; case NSEQSW: seqp = 0; @@ -152,10 +157,10 @@ main (int argc, char **argv) publicsw = 0; continue; case ZEROSW: - zerosw++; + zerosw = true; continue; case NZEROSW: - zerosw = 0; + zerosw = false; continue; case LISTSW: @@ -164,13 +169,16 @@ main (int argc, char **argv) case NLISTSW: listsw = 0; continue; + + case DEBUGSW: + ++debug; + continue; } } if (*cp == '+' || *cp == '@') { if (folder) - adios (NULL, "only one folder at a time!"); - else - folder = pluspath (cp); + die("only one folder at a time!"); + folder = pluspath (cp); } else app_msgarg(&msgs, cp); } @@ -195,11 +203,11 @@ main (int argc, char **argv) /* read folder and create message structure */ if (!(mp = folder_read (folder, 0))) - adios (NULL, "unable to read folder %s", folder); + die("unable to read folder %s", folder); /* check for empty folder */ if (mp->nummsg == 0) - adios (NULL, "no messages in %s", folder); + die("no messages in %s", folder); /* parse all the message ranges/sequences and set SELECTED */ for (msgnum = 0; msgnum < msgs.size; msgnum++) @@ -214,7 +222,7 @@ main (int argc, char **argv) listsw = !seqp; if (publicsw == 1 && is_readonly(mp)) - adios (NULL, "folder %s is read-only, so -public not allowed", folder); + die("folder %s is read-only, so -public not allowed", folder); if (!pcompile (vec, NULL)) done (1); @@ -229,13 +237,22 @@ main (int argc, char **argv) * match. If there is NOT a match, then add it to a list to * remove from the final sequence (it will make sense later) */ - for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) { + if (!reverse) { /* Overflow or underflow is fine. */ + start = mp->lowsel; + end = mp->hghsel + 1; + inc = 1; + } else { + start = mp->hghsel; + end = mp->lowsel - 1; + inc = -1; + } + for (msgnum = start; msgnum != end; msgnum += inc) { 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, 0L, 0L, debug)) { if (listsw) - printf ("%s\n", m_name (msgnum)); + puts(m_name (msgnum)); } else { app_msgnum(&nums, msgnum); } @@ -245,9 +262,7 @@ main (int argc, char **argv) } if (nums.size >= mp->numsel) - adios (NULL, "no messages match specification"); - - seqs[seqp] = NULL; + die("no messages match specification"); /* * So, what's happening here? @@ -260,7 +275,7 @@ main (int argc, char **argv) */ if (!(mp2 = folder_read (folder, 1))) - adios (NULL, "unable to reread folder %s", folder); + die("unable to reread folder %s", folder); for (msgnum = 0; msgnum < msgs.size; msgnum++) if (!m_convert (mp2, msgs.msgs[msgnum])) @@ -280,17 +295,20 @@ main (int argc, char **argv) /* * Add the matching messages to sequences */ - for (seqp = 0; seqs[seqp]; seqp++) - if (!seq_addsel (mp2, seqs[seqp], publicsw, zerosw)) - done (1); + if (seqp > 0) { + for (seqp = 0; seqp < svector_size (seqs); seqp++) + if (!seq_addsel (mp2, svector_at (seqs, seqp), publicsw, zerosw)) + done (1); + } /* * Print total matched if not printing each matched message number. */ if (!listsw) { - printf ("%d hit%s\n", mp2->numsel, mp2->numsel == 1 ? "" : "s"); + printf ("%d hit%s\n", mp2->numsel, PLURALS(mp2->numsel)); } + svector_free (seqs); context_replace (pfolder, folder); /* update current folder */ seq_save (mp2); /* synchronize message sequences */ context_save (); /* save the context file */ @@ -301,10 +319,10 @@ main (int argc, char **argv) } -static void +static void NORETURN putzero_done (int status) { if (listsw && status && !isatty (fileno (stdout))) - printf ("0\n"); + puts("0"); exit (status); }