mirror of
https://github.com/beard7n/bsdports.git
synced 2026-04-16 13:31:26 +02:00
172 lines
4.5 KiB
Plaintext
172 lines
4.5 KiB
Plaintext
--- doc/manual.xml.head.orig 2017-05-30 19:27:52 UTC
|
|
+++ doc/manual.xml.head
|
|
@@ -4265,6 +4265,22 @@ variable <quote>all</quote>, which allow
|
|
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 < or one of its childs with >.
|
|
+This example matches all mails which have at least an unread duplicate
|
|
+message:
|
|
+</para>
|
|
+
|
|
+<para>
|
|
+
|
|
+<screen>
|
|
+>(~= ~N)
|
|
+</screen>
|
|
+
|
|
+</para>
|
|
+
|
|
</sect2>
|
|
|
|
<sect2 id="set-myvar">
|
|
--- mutt.h.orig 2017-06-03 23:16:03 UTC
|
|
+++ mutt.h
|
|
@@ -865,6 +865,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 */
|
|
unsigned int isalias : 1;
|
|
int min;
|
|
--- pattern.c.orig 2017-05-30 19:26:40 UTC
|
|
+++ pattern.c
|
|
@@ -46,6 +46,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, pattern_cache_t *cache);
|
|
|
|
static const struct pattern_flags
|
|
{
|
|
@@ -781,6 +782,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 */
|
|
int isalias = 0;
|
|
@@ -810,6 +813,24 @@ pattern_t *mutt_pattern_comp (/* const *
|
|
ps.dptr++;
|
|
isalias = !isalias;
|
|
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)
|
|
{
|
|
@@ -835,6 +856,8 @@ pattern_t *mutt_pattern_comp (/* const *
|
|
implicit = 0;
|
|
not = 0;
|
|
alladdr = 0;
|
|
+ parentmatch = 0;
|
|
+ childsmatch = 0;
|
|
isalias = 0;
|
|
break;
|
|
case '%':
|
|
@@ -865,9 +888,13 @@ pattern_t *mutt_pattern_comp (/* const *
|
|
last = tmp;
|
|
tmp->not ^= not;
|
|
tmp->alladdr |= alladdr;
|
|
+ tmp->parentmatch |= parentmatch;
|
|
+ tmp->childsmatch |= childsmatch;
|
|
tmp->isalias |= isalias;
|
|
not = 0;
|
|
alladdr = 0;
|
|
+ parentmatch = 0;
|
|
+ childsmatch = 0;
|
|
isalias = 0;
|
|
/* compile the sub-expression */
|
|
buf = mutt_substrdup (ps.dptr + 1, p);
|
|
@@ -896,11 +923,15 @@ pattern_t *mutt_pattern_comp (/* const *
|
|
tmp = new_pattern ();
|
|
tmp->not = not;
|
|
tmp->alladdr = alladdr;
|
|
+ tmp->parentmatch = parentmatch;
|
|
+ tmp->childsmatch = childsmatch;
|
|
tmp->isalias = isalias;
|
|
tmp->stringmatch = (*ps.dptr == '=') ? 1 : 0;
|
|
tmp->groupmatch = (*ps.dptr == '%') ? 1 : 0;
|
|
not = 0;
|
|
alladdr = 0;
|
|
+ parentmatch = 0;
|
|
+ childsmatch = 0;
|
|
isalias = 0;
|
|
|
|
if (last)
|
|
@@ -967,9 +998,13 @@ pattern_t *mutt_pattern_comp (/* const *
|
|
last = tmp;
|
|
tmp->not ^= not;
|
|
tmp->alladdr |= alladdr;
|
|
+ tmp->parentmatch |= parentmatch;
|
|
+ tmp->childsmatch |= childsmatch;
|
|
tmp->isalias |= isalias;
|
|
not = 0;
|
|
alladdr = 0;
|
|
+ parentmatch = 0;
|
|
+ childsmatch = 0;
|
|
isalias = 0;
|
|
ps.dptr = p + 1; /* restore location */
|
|
break;
|
|
@@ -1137,6 +1172,37 @@ int
|
|
mutt_pattern_exec (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *h,
|
|
pattern_cache_t *cache)
|
|
{
|
|
+ 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, cache);
|
|
+ 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, cache))
|
|
+ return !pat->not;
|
|
+ }
|
|
+ return pat->not;
|
|
+ }
|
|
+ return pattern_exec (pat, flags, ctx, h, cache);
|
|
+}
|
|
+
|
|
+static int
|
|
+pattern_exec (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *h,
|
|
+ pattern_cache_t *cache)
|
|
+{
|
|
int result;
|
|
int *cache_entry;
|
|
|