Rocco Rutte:
[apps/madmutt.git] / pattern.c
index be05a18..a606ab9 100644 (file)
--- a/pattern.c
+++ b/pattern.c
 #endif
 
 #include "mutt.h"
+#include "buffer.h"
+#include "handler.h"
+#include "enter.h"
+#include "ascii.h"
+#include "mx.h"
 #include "mapping.h"
 #include "keymap.h"
-#include "mailbox.h"
 #include "copy.h"
+#include "mime.h"
 
 #include "lib/mem.h"
 #include "lib/intl.h"
@@ -61,6 +66,7 @@ struct pattern_flags {
   'L', M_ADDRESS, 0, eat_regexp}, {
   'l', M_LIST, 0, NULL}, {
   'm', M_MESSAGE, 0, eat_range}, {
+  'M', M_MULTIPART, 0, NULL}, {
   'n', M_SCORE, 0, eat_range}, {
   'N', M_NEW, 0, NULL}, {
   'O', M_OLD, 0, NULL}, {
@@ -74,6 +80,7 @@ struct pattern_flags {
   'T', M_TAG, 0, NULL}, {
   't', M_TO, 0, eat_regexp}, {
   'U', M_UNREAD, 0, NULL}, {
+  'u', M_SUBSCRIBED_LIST, 0, NULL}, {
   'v', M_COLLAPSED, 0, NULL}, {
   'V', M_CRYPT_VERIFIED, 0, NULL},
 #ifdef USE_NNTP
@@ -204,7 +211,7 @@ msg_search (CONTEXT * ctx, regex_t * rx, char *buf, size_t blen, int op,
         match = 1;
         break;
       }
-      lng -= safe_strlen (buf);
+      lng -= str_len (buf);
     }
 
     mx_close_message (&msg);
@@ -229,15 +236,15 @@ int eat_regexp (pattern_t * pat, BUFFER * s, BUFFER * err)
     snprintf (err->data, err->dsize, _("Error in expression: %s"), s->dptr);
     return (-1);
   }
-  pat->rx = safe_malloc (sizeof (regex_t));
+  pat->rx = mem_malloc (sizeof (regex_t));
   r =
     REGCOMP (pat->rx, buf.data,
              REG_NEWLINE | REG_NOSUB | mutt_which_case (buf.data));
-  FREE (&buf.data);
+  mem_free (&buf.data);
   if (r) {
     regerror (r, pat->rx, err->data, err->dsize);
     regfree (pat->rx);
-    FREE (&pat->rx);
+    mem_free (&pat->rx);
     return (-1);
   }
   return 0;
@@ -557,7 +564,7 @@ static int eat_date (pattern_t * pat, BUFFER * s, BUFFER * err)
     if (isdigit ((unsigned char) *pc)) {
       /* mininum date specified */
       if ((pc = getDate (pc, &min, err)) == NULL) {
-        FREE (&buffer.data);
+        mem_free (&buffer.data);
         return (-1);
       }
       haveMin = TRUE;
@@ -590,7 +597,7 @@ static int eat_date (pattern_t * pat, BUFFER * s, BUFFER * err)
       max.tm_mday = min.tm_mday;
 
       if (!parse_date_range (pc, &min, &max, haveMin, &baseMin, err)) { /* bail out on any parsing error */
-        FREE (&buffer.data);
+        mem_free (&buffer.data);
         return (-1);
       }
     }
@@ -602,7 +609,7 @@ static int eat_date (pattern_t * pat, BUFFER * s, BUFFER * err)
   pat->min = mutt_mktime (&min, 1);
   pat->max = mutt_mktime (&max, 1);
 
-  FREE (&buffer.data);
+  mem_free (&buffer.data);
 
   return 0;
 }
@@ -643,11 +650,11 @@ void mutt_pattern_free (pattern_t ** pat)
 
     if (tmp->rx) {
       regfree (tmp->rx);
-      FREE (&tmp->rx);
+      mem_free (&tmp->rx);
     }
     if (tmp->child)
       mutt_pattern_free (&tmp->child);
-    FREE (&tmp);
+    mem_free (&tmp);
   }
 }
 
@@ -667,7 +674,7 @@ pattern_t *mutt_pattern_comp ( /* const */ char *s, int flags, BUFFER * err)
 
   memset (&ps, 0, sizeof (ps));
   ps.dptr = s;
-  ps.dsize = safe_strlen (s);
+  ps.dsize = str_len (s);
 
   while (*ps.dptr) {
     SKIPWS (ps.dptr);
@@ -768,11 +775,11 @@ pattern_t *mutt_pattern_comp ( /* const */ char *s, int flags, BUFFER * err)
       /* compile the sub-expression */
       buf = str_substrdup (ps.dptr + 1, p);
       if ((tmp = mutt_pattern_comp (buf, flags, err)) == NULL) {
-        FREE (&buf);
+        mem_free (&buf);
         mutt_pattern_free (&curlist);
         return NULL;
       }
-      FREE (&buf);
+      mem_free (&buf);
       if (last)
         last->next = tmp;
       else
@@ -1000,6 +1007,11 @@ mutt_pattern_exec (struct pattern_t *pat, pattern_exec_flag flags,
                                      pat->alladdr, 2, h->env->to,
                                      h->env->cc)));
   case M_LIST:
+    return (pat->
+            not ^ (h->env
+                   && mutt_is_list_cc (pat->alladdr, h->env->to,
+                                       h->env->cc)));
+  case M_SUBSCRIBED_LIST:
     return (pat->
             not ^ (h->env
                    && mutt_is_list_recipient (pat->alladdr, h->env->to,
@@ -1043,6 +1055,8 @@ mutt_pattern_exec (struct pattern_t *pat, pattern_exec_flag flags,
     return (pat->not ^ (h->thread && h->thread->duplicate_thread));
   case M_UNREFERENCED:
     return (pat->not ^ (h->thread && !h->thread->child));
+  case M_MULTIPART:
+    return (pat->not ^ (h->content && h->content->type == TYPEMULTIPART));
   case M_REALNAME:
     /* realname filter:
      * we have a match if
@@ -1098,7 +1112,7 @@ void mutt_check_simple (char *s, size_t len, const char *simple)
 
   if (!strchr (s, '~')) {       /* yup, so spoof a real request */
     /* convert old tokens into the new format */
-    if (ascii_strcasecmp ("all", s) == 0 || !safe_strcmp ("^", s) || !safe_strcmp (".", s))     /* ~A is more efficient */
+    if (ascii_strcasecmp ("all", s) == 0 || !str_cmp ("^", s) || !str_cmp (".", s))     /* ~A is more efficient */
       strfcpy (s, "~A", len);
     else if (ascii_strcasecmp ("del", s) == 0)
       strfcpy (s, "~D", len);
@@ -1132,19 +1146,24 @@ int mutt_pattern_func (int op, char *prompt)
 
   strfcpy (buf, NONULL (Context->pattern), sizeof (buf));
   if (prompt || op != M_LIMIT)
-    if (mutt_get_field (prompt, buf, sizeof (buf), M_PATTERN | M_CLEAR) != 0
-        || !buf[0])
+    if (mutt_get_field (prompt, buf, sizeof (buf), M_PATTERN | M_CLEAR) != 0)
       return (-1);
+  if (!buf[0]) {
+    if (op == M_LIMIT)
+      strncpy (buf, "~A", sizeof (buf));
+    else
+      return (-1);
+  }
 
   mutt_message _("Compiling search pattern...");
 
-  simple = safe_strdup (buf);
+  simple = str_dup (buf);
   mutt_check_simple (buf, sizeof (buf), NONULL (SimpleSearch));
 
   err.data = error;
   err.dsize = sizeof (error);
   if ((pat = mutt_pattern_comp (buf, M_FULL_MSG, &err)) == NULL) {
-    FREE (&simple);
+    mem_free (&simple);
     mutt_error ("%s", err.data);
     return (-1);
   }
@@ -1203,28 +1222,22 @@ int mutt_pattern_func (int op, char *prompt)
   mutt_clear_error ();
 
   if (op == M_LIMIT) {
-    FREE (&Context->pattern);
+    /* drop previous limit pattern */
+    mem_free (&Context->pattern);
     if (Context->limit_pattern)
       mutt_pattern_free (&Context->limit_pattern);
-    if (!Context->vcount) {
+    if (Context->msgcount && !Context->vcount) {
       mutt_error _("No messages matched criteria.");
-
-#if 0
-      Context->vcount = Context->msgcount;
-      /* restore full display */
-      for (i = 0; i < Context->msgcount; i++) {
-        Context->hdrs[i]->virtual = i;
-        Context->v2r[i] = i;
-      }
-#endif
     }
-    else if (safe_strncmp (buf, "~A", 2) != 0) {
+
+    /* record new limit pattern, unless match all */
+    if (str_ncmp (buf, "~A", 2) != 0) {
       Context->pattern = simple;
       simple = NULL;            /* don't clobber it */
       Context->limit_pattern = mutt_pattern_comp (buf, M_FULL_MSG, &err);
     }
   }
-  FREE (&simple);
+  mem_free (&simple);
   mutt_pattern_free (&pat);
   return 0;
 }
@@ -1256,7 +1269,7 @@ int mutt_search_command (int cur, int op)
     strfcpy (temp, buf, sizeof (temp));
     mutt_check_simple (temp, sizeof (temp), NONULL (SimpleSearch));
 
-    if (!SearchPattern || safe_strcmp (temp, LastSearchExpn)) {
+    if (!SearchPattern || str_cmp (temp, LastSearchExpn)) {
       set_option (OPTSEARCHINVALID);
       strfcpy (LastSearch, buf, sizeof (LastSearch));
       mutt_message _("Compiling search pattern...");