#include <lib-lib/lib-lib.h>
#include <lib-mime/mime.h>
+#include <lib-crypt/crypt.h>
#include <lib-ui/enter.h>
#include <lib-ui/curses.h>
#include <lib-mx/mx.h>
+#include <imap/imap.h>
-#include "mutt.h"
+#include "pattern.h"
#include "alias.h"
#include "handler.h"
#include "keymap.h"
#include "copy.h"
-#include <imap/imap.h>
-
-#include <lib-crypt/crypt.h>
-
static int eat_regexp (pattern_t * pat, BUFFER *, BUFFER *);
static int eat_date (pattern_t * pat, BUFFER *, BUFFER *);
static int eat_range (pattern_t * pat, BUFFER *, BUFFER *);
static int patmatch (const pattern_t* pat, const char* buf);
-struct pattern_flags {
+static struct pattern_flags {
int tag; /* character used to represent this op */
int op; /* operation to perform */
int class;
int (*eat_arg)(pattern_t *, BUFFER *, BUFFER *);
-} Flags[] = {
+} const Flags[] = {
{'A', M_ALL, 0, NULL},
{'b', M_BODY, M_FULL_MSG, eat_regexp},
{'B', M_WHOLE_MSG, M_FULL_MSG, eat_regexp},
#define M_PDR_ERROR 0x0100
#define M_PDR_ERRORDONE (M_PDR_ERROR | M_PDR_DONE)
+void pattern_wipe(pattern_t *pat)
+{
+ if (pat->rx) {
+ regfree (pat->rx);
+ p_delete(&pat->rx);
+ }
+ p_delete(&pat->str);
+ pattern_list_wipe(&pat->child);
+}
+
/* if no uppercase letters are given, do a case-insensitive search */
int mutt_which_case (const char *s)
{
{
mx_close_message (&msg);
if (fp) {
- fclose (fp);
+ m_fclose(&fp);
unlink (tempfile);
}
return (0);
mx_close_message (&msg);
if (option (OPTTHOROUGHSRC)) {
- fclose (fp);
+ m_fclose(&fp);
unlink (tempfile);
}
}
return (-1);
}
-#if 0
- /* If there are no RE metacharacters, use simple search anyway */
- if (!pat->stringmatch && !strpbrk (buf.data, "|[{.*+?^$"))
- pat->stringmatch = 1;
-#endif
-
if (pat->stringmatch) {
pat->str = m_strdup(buf.data);
p_delete(&buf.data);
return 0;
}
-static struct pattern_flags *lookup_tag (char tag)
+static const struct pattern_flags *lookup_tag (char tag)
{
int i;
return NULL;
}
-static /* const */ char *find_matching_paren ( /* const */ char *s)
+static const char *find_matching_paren (const char *s)
{
- int level = 1;
-
- for (; *s; s++) {
- if (*s == '(')
- level++;
- else if (*s == ')') {
- level--;
- if (!level)
- break;
- }
- }
- return s;
-}
+ int level = 1;
-void mutt_pattern_free (pattern_t ** pat)
-{
- pattern_t *tmp;
-
- while (*pat) {
- tmp = *pat;
- *pat = (*pat)->next;
-
- if (tmp->rx) {
- regfree (tmp->rx);
- p_delete(&tmp->rx);
+ for (; *s; s++) {
+ level += (*s == '(') - (*s == ')');
+ if (!level)
+ break;
}
- p_delete(&tmp->str);
- if (tmp->child)
- mutt_pattern_free (&tmp->child);
- p_delete(&tmp);
- }
+ return s;
}
-pattern_t *mutt_pattern_comp ( /* const */ char *s, int flags, BUFFER * err)
+pattern_t *mutt_pattern_comp(const char *s, int flags, BUFFER *err)
{
pattern_t *curlist = NULL;
pattern_t *tmp;
int alladdr = 0;
int or = 0;
int implicit = 1; /* used to detect logical AND operator */
- struct pattern_flags *entry;
+ const struct pattern_flags *entry;
char *p;
char *buf;
BUFFER ps;
p_clear(&ps, 1);
- ps.dptr = s;
+ ps.dptr = s;
ps.dsize = m_strlen(s);
while (*ps.dptr) {
}
if (curlist->next) {
/* A & B | C == (A & B) | C */
- tmp = new_pattern ();
+ tmp = pattern_new();
tmp->op = M_AND;
tmp->child = curlist;
case '~':
if (implicit && or) {
/* A | B & C == (A | B) & C */
- tmp = new_pattern ();
+ tmp = pattern_new();
tmp->op = M_OR;
tmp->child = curlist;
curlist = tmp;
or = 0;
}
- tmp = new_pattern ();
+ tmp = pattern_new();
tmp->not = not;
tmp->alladdr = alladdr;
tmp->stringmatch = (*ps.dptr == '=') ? 1 : 0;
ps.dptr++; /* move past the ~ */
if ((entry = lookup_tag (*ps.dptr)) == NULL) {
snprintf (err->data, err->dsize, _("%c: invalid command"), *ps.dptr);
- mutt_pattern_free (&curlist);
+ pattern_list_wipe(&curlist);
return NULL;
}
if (entry->class && (flags & entry->class) == 0) {
snprintf (err->data, err->dsize, _("%c: not supported in this mode"),
*ps.dptr);
- mutt_pattern_free (&curlist);
+ pattern_list_wipe(&curlist);
return NULL;
}
tmp->op = entry->op;
if (entry->eat_arg) {
if (!*ps.dptr) {
snprintf (err->data, err->dsize, _("missing parameter"));
- mutt_pattern_free (&curlist);
+ pattern_list_wipe(&curlist);
return NULL;
}
if (entry->eat_arg (tmp, &ps, err) == -1) {
- mutt_pattern_free (&curlist);
+ pattern_list_wipe(&curlist);
return NULL;
}
}
if (*p != ')') {
snprintf (err->data, err->dsize, _("mismatched parenthesis: %s"),
ps.dptr);
- mutt_pattern_free (&curlist);
+ pattern_list_wipe(&curlist);
return NULL;
}
/* compile the sub-expression */
buf = p_dupstr(ps.dptr + 1, p - ps.dptr - 1);
if ((tmp = mutt_pattern_comp (buf, flags, err)) == NULL) {
p_delete(&buf);
- mutt_pattern_free (&curlist);
+ pattern_list_wipe(&curlist);
return NULL;
}
p_delete(&buf);
break;
default:
snprintf (err->data, err->dsize, _("error in pattern at: %s"), ps.dptr);
- mutt_pattern_free (&curlist);
+ pattern_list_wipe(&curlist);
return NULL;
}
}
return NULL;
}
if (curlist->next) {
- tmp = new_pattern ();
+ tmp = pattern_new();
tmp->op = or ? M_OR : M_AND;
tmp->child = curlist;
curlist = tmp;
/* drop previous limit pattern */
p_delete(&Context->pattern);
if (Context->limit_pattern)
- mutt_pattern_free (&Context->limit_pattern);
+ pattern_list_wipe(&Context->limit_pattern);
if (Context->msgcount && !Context->vcount) {
mutt_error _("No messages matched criteria.");
}
}
}
p_delete(&simple);
- mutt_pattern_free (&pat);
+ pattern_list_wipe(&pat);
return 0;
}
m_strcpy(LastSearch, sizeof(LastSearch), buf);
mutt_message _("Compiling search pattern...");
- mutt_pattern_free (&SearchPattern);
+ pattern_list_wipe(&SearchPattern);
err.data = error;
err.dsize = sizeof (error);
if ((SearchPattern =