aboutsummaryrefslogblamecommitdiff
path: root/mail/mutt-devel/files/extra-patch-parent-child-match
blob: f9e95e46742a4dc8978c45ca6ba0675e7f3dd087 (plain) (tree)








































































































































































                                                                                                   
--- mutt-1.5.20/doc/manual.xml.head	2009-05-30 19:20:08.000000000 +0200
+++ mutt-1.5.20-parentchildmatch/doc/manual.xml.head	2009-07-18 01:09:23.000000000 +0200
@@ -3947,6 +3947,22 @@ With the <command>reset</command> comman
 which allows you to reset all variables to their system defaults.
 </para>
 
+<para>
+<emphasis role="bold">Parent and child match</emphasis>.
+You can tell mutt that the following pattern has to be matched against
+the parent message with &lt; or one of its childs with &gt;.
+This example matches all mails which have at least an unread duplicate
+message:
+</para>
+
+<para>
+
+<screen>
+>(~= ~N)
+</screen>
+
+</para>
+
 </sect2>
 
 <sect2 id="set-myvar">
diff -urNp mutt-1.5.20/mutt.h mutt-1.5.20-parentchildmatch/mutt.h
--- mutt-1.5.20/mutt.h	2009-06-13 00:15:42.000000000 +0200
+++ mutt-1.5.20-parentchildmatch/mutt.h	2009-07-18 01:14:21.000000000 +0200
@@ -819,6 +819,8 @@ typedef struct pattern_t
   unsigned int alladdr : 1;
   unsigned int stringmatch : 1;
   unsigned int groupmatch : 1;
+  unsigned int parentmatch : 1;
+  unsigned int childsmatch : 1;
   unsigned int ign_case : 1;		/* ignore case for local stringmatch searches */
   int min;
   int max;
diff -urNp mutt-1.5.20/pattern.c mutt-1.5.20-parentchildmatch/pattern.c
--- mutt-1.5.20/pattern.c	2009-06-03 22:48:31.000000000 +0200
+++ mutt-1.5.20-parentchildmatch/pattern.c	2009-07-18 01:09:23.000000000 +0200
@@ -45,6 +45,7 @@ static int eat_regexp (pattern_t *pat, B
 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);
+static int pattern_exec (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *h);
 
 static struct pattern_flags
 {
@@ -769,6 +770,8 @@ pattern_t *mutt_pattern_comp (/* const *
   pattern_t *last = NULL;
   int not = 0;
   int alladdr = 0;
+  int parentmatch = 0;
+  int childsmatch = 0;
   int or = 0;
   int implicit = 1;	/* used to detect logical AND operator */
   struct pattern_flags *entry;
@@ -793,6 +796,24 @@ pattern_t *mutt_pattern_comp (/* const *
 	ps.dptr++;
 	not = !not;
 	break;
+      case '<':
+	ps.dptr++;
+	if (childsmatch) {
+	  snprintf (err->data, err->dsize, _("cannot use both < and > as a pattern modifier"));
+	  mutt_pattern_free (&curlist);
+	  return NULL;
+	}
+	parentmatch = 1;
+	break;
+      case '>':
+	ps.dptr++;
+	if (parentmatch) {
+	  snprintf (err->data, err->dsize, _("cannot use both < and > as a pattern modifier"));
+	  mutt_pattern_free (&curlist);
+	  return NULL;
+	}
+	childsmatch = 1;
+	break;
       case '|':
 	if (!or)
 	{
@@ -818,6 +839,8 @@ pattern_t *mutt_pattern_comp (/* const *
 	implicit = 0;
 	not = 0;
 	alladdr = 0;
+	parentmatch = 0;
+	childsmatch = 0;
 	break;
       case '%':
       case '=':
@@ -841,8 +864,12 @@ pattern_t *mutt_pattern_comp (/* const *
 	  last = tmp;
 	  tmp->not ^= not;
 	  tmp->alladdr |= alladdr;
+	  tmp->parentmatch |= parentmatch;
+	  tmp->childsmatch |= childsmatch;
 	  not = 0;
 	  alladdr = 0;
+	  parentmatch = 0;
+	  childsmatch = 0;
 	  /* compile the sub-expression */
 	  buf = mutt_substrdup (ps.dptr + 1, p);
 	  if ((tmp2 = mutt_pattern_comp (buf, flags, err)) == NULL)
@@ -870,10 +897,14 @@ pattern_t *mutt_pattern_comp (/* const *
 	tmp = new_pattern ();
 	tmp->not = not;
 	tmp->alladdr = alladdr;
+	tmp->parentmatch = parentmatch;
+	tmp->childsmatch = childsmatch;
         tmp->stringmatch = (*ps.dptr == '=') ? 1 : 0;
         tmp->groupmatch  = (*ps.dptr == '%') ? 1 : 0;
 	not = 0;
 	alladdr = 0;
+	parentmatch = 0;
+	childsmatch = 0;
 
 	if (last)
 	  last->next = tmp;
@@ -939,8 +970,12 @@ pattern_t *mutt_pattern_comp (/* const *
 	last = tmp;
 	tmp->not ^= not;
 	tmp->alladdr |= alladdr;
+	tmp->parentmatch |= parentmatch;
+	tmp->childsmatch |= childsmatch;
 	not = 0;
 	alladdr = 0;
+	parentmatch = 0;
+	childsmatch = 0;
 	ps.dptr = p + 1; /* restore location */
 	break;
       default:
@@ -1081,6 +1116,36 @@ static int match_threadcomplete(struct p
 int
 mutt_pattern_exec (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *h)
 {
+  THREAD *t;
+
+  if (pat->parentmatch) {
+    if (h->thread && h->thread->parent && h->thread->parent->message)
+      return pattern_exec (pat, flags, ctx, h->thread->parent->message);
+    else
+      return pat->not;
+  }
+  if (pat->childsmatch) {
+    if (!h->thread)
+      return pat->not;
+    if (!h->thread->child)
+      return pat->not;
+    t = h->thread->child;
+    while (t->prev)
+      t = t->prev;
+    for (; t; t = t->next) {
+      if (!t->message)
+	continue;
+      if (pattern_exec (pat, flags, ctx, t->message))
+	return !pat->not;
+    }
+    return pat->not;
+  }
+  return pattern_exec (pat, flags, ctx, h);
+}
+
+static int
+pattern_exec (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *h)
+{
   switch (pat->op)
   {
     case M_AND: