NeoMutt  2019-12-07-168-gc45f47
Teaching an old dog new tricks
DOXYGEN
pattern.h File Reference

Match patterns to emails. More...

#include "config.h"
#include <regex.h>
#include <stdbool.h>
#include <stdint.h>
#include "mutt/lib.h"
#include "mutt.h"
+ Include dependency graph for pattern.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Pattern
 A simple (non-regex) pattern. More...
 
struct  PatternCache
 Cache commonly-used patterns. More...
 

Macros

#define MUTT_PC_NO_FLAGS   0
 No flags are set. More...
 
#define MUTT_PC_FULL_MSG   (1<<0)
 Enable body and header matching. More...
 
#define MUTT_PC_PATTERN_DYNAMIC   (1<<1)
 Enable runtime date range evaluation. More...
 
#define MUTT_PC_SEND_MODE_SEARCH   (1<<2)
 Allow send-mode body searching. More...
 
#define MUTT_PAT_EXEC_NO_FLAGS   0
 No flags are set. More...
 
#define MUTT_MATCH_FULL_ADDRESS   (1 << 0)
 Match the full address. More...
 

Typedefs

typedef uint8_t PatternCompFlags
 Flags for mutt_pattern_comp(), e.g. MUTT_PC_FULL_MSG. More...
 
typedef uint8_t PatternExecFlags
 Flags for mutt_pattern_exec(), e.g. MUTT_MATCH_FULL_ADDRESS. More...
 

Enumerations

enum  PatternType {
  MUTT_PAT_AND = MUTT_MT_MAX, MUTT_PAT_OR, MUTT_PAT_THREAD, MUTT_PAT_PARENT,
  MUTT_PAT_CHILDREN, MUTT_PAT_TO, MUTT_PAT_CC, MUTT_PAT_COLLAPSED,
  MUTT_PAT_SUBJECT, MUTT_PAT_FROM, MUTT_PAT_DATE, MUTT_PAT_DATE_RECEIVED,
  MUTT_PAT_DUPLICATED, MUTT_PAT_UNREFERENCED, MUTT_PAT_BROKEN, MUTT_PAT_ID,
  MUTT_PAT_ID_EXTERNAL, MUTT_PAT_BODY, MUTT_PAT_HEADER, MUTT_PAT_HORMEL,
  MUTT_PAT_WHOLE_MSG, MUTT_PAT_SENDER, MUTT_PAT_MESSAGE, MUTT_PAT_SCORE,
  MUTT_PAT_SIZE, MUTT_PAT_REFERENCE, MUTT_PAT_RECIPIENT, MUTT_PAT_LIST,
  MUTT_PAT_SUBSCRIBED_LIST, MUTT_PAT_PERSONAL_RECIP, MUTT_PAT_PERSONAL_FROM, MUTT_PAT_ADDRESS,
  MUTT_PAT_CRYPT_SIGN, MUTT_PAT_CRYPT_VERIFIED, MUTT_PAT_CRYPT_ENCRYPT, MUTT_PAT_PGP_KEY,
  MUTT_PAT_XLABEL, MUTT_PAT_SERVERSEARCH, MUTT_PAT_DRIVER_TAGS, MUTT_PAT_MIMEATTACH,
  MUTT_PAT_MIMETYPE, MUTT_PAT_NEWSGROUPS, MUTT_PAT_MAX
}
 Types of pattern to match. More...
 

Functions

 SLIST_HEAD (PatternList, Pattern)
 
int mutt_pattern_exec (struct Pattern *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct PatternCache *cache)
 Match a pattern against an email header. More...
 
struct PatternList * mutt_pattern_comp (const char *s, PatternCompFlags flags, struct Buffer *err)
 Create a Pattern. More...
 
void mutt_check_simple (struct Buffer *s, const char *simple)
 Convert a simple search into a real request. More...
 
void mutt_pattern_free (struct PatternList **pat)
 Free a Pattern. More...
 
int mutt_which_case (const char *s)
 
int mutt_is_list_recipient (bool all_addr, struct Envelope *e)
 Matches known mailing lists. More...
 
int mutt_is_subscribed_list_recipient (bool all_addr, struct Envelope *e)
 Matches subscribed mailing lists. More...
 
int mutt_pattern_func (int op, char *prompt)
 Perform some Pattern matching. More...
 
int mutt_search_command (int cur, int op)
 Perform a search. More...
 
bool mutt_limit_current_thread (struct Email *e)
 Limit the email view to the current thread. More...
 

Variables

bool C_ThoroughSearch
 Config: Decode headers and messages before searching them. More...
 

Detailed Description

Match patterns to emails.

Authors
  • Richard Russon
  • Pietro Cerutti

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file pattern.h.

Macro Definition Documentation

◆ MUTT_PC_NO_FLAGS

#define MUTT_PC_NO_FLAGS   0

No flags are set.

Definition at line 42 of file pattern.h.

◆ MUTT_PC_FULL_MSG

#define MUTT_PC_FULL_MSG   (1<<0)

Enable body and header matching.

Definition at line 43 of file pattern.h.

◆ MUTT_PC_PATTERN_DYNAMIC

#define MUTT_PC_PATTERN_DYNAMIC   (1<<1)

Enable runtime date range evaluation.

Definition at line 44 of file pattern.h.

◆ MUTT_PC_SEND_MODE_SEARCH

#define MUTT_PC_SEND_MODE_SEARCH   (1<<2)

Allow send-mode body searching.

Definition at line 45 of file pattern.h.

◆ MUTT_PAT_EXEC_NO_FLAGS

#define MUTT_PAT_EXEC_NO_FLAGS   0

No flags are set.

Definition at line 76 of file pattern.h.

◆ MUTT_MATCH_FULL_ADDRESS

#define MUTT_MATCH_FULL_ADDRESS   (1 << 0)

Match the full address.

Definition at line 77 of file pattern.h.

Typedef Documentation

◆ PatternCompFlags

typedef uint8_t PatternCompFlags

Flags for mutt_pattern_comp(), e.g. MUTT_PC_FULL_MSG.

Definition at line 41 of file pattern.h.

◆ PatternExecFlags

typedef uint8_t PatternExecFlags

Flags for mutt_pattern_exec(), e.g. MUTT_MATCH_FULL_ADDRESS.

Definition at line 75 of file pattern.h.

Enumeration Type Documentation

◆ PatternType

Types of pattern to match.

Note
This enum piggy-backs on top of MessageType
See also
mutt_pattern_comp(), mutt_pattern_exec()
Enumerator
MUTT_PAT_AND 

Both patterns must match.

MUTT_PAT_OR 

Either pattern can match.

MUTT_PAT_THREAD 

Pattern matches email thread.

MUTT_PAT_PARENT 

Pattern matches parent.

MUTT_PAT_CHILDREN 

Pattern matches a child email.

MUTT_PAT_TO 

Pattern matches 'To:' field.

MUTT_PAT_CC 

Pattern matches 'Cc:' field.

MUTT_PAT_COLLAPSED 

Thread is collapsed.

MUTT_PAT_SUBJECT 

Pattern matches 'Subject:' field.

MUTT_PAT_FROM 

Pattern matches 'From:' field.

MUTT_PAT_DATE 

Pattern matches 'Date:' field.

MUTT_PAT_DATE_RECEIVED 

Pattern matches date received.

MUTT_PAT_DUPLICATED 

Duplicate message.

MUTT_PAT_UNREFERENCED 

Message is unreferenced in the thread.

MUTT_PAT_BROKEN 

Message is part of a broken thread.

MUTT_PAT_ID 

Pattern matches email's Message-Id.

MUTT_PAT_ID_EXTERNAL 

Message-Id is among results from an external query.

MUTT_PAT_BODY 

Pattern matches email's body.

MUTT_PAT_HEADER 

Pattern matches email's header.

MUTT_PAT_HORMEL 

Pattern matches email's spam score.

MUTT_PAT_WHOLE_MSG 

Pattern matches raw email text.

MUTT_PAT_SENDER 

Pattern matches sender.

MUTT_PAT_MESSAGE 

Pattern matches message number.

MUTT_PAT_SCORE 

Pattern matches email's score.

MUTT_PAT_SIZE 

Pattern matches email's size.

MUTT_PAT_REFERENCE 

Pattern matches 'References:' or 'In-Reply-To:' field.

MUTT_PAT_RECIPIENT 

User is a recipient of the email.

MUTT_PAT_LIST 

Email is on mailing list.

MUTT_PAT_SUBSCRIBED_LIST 

Email is on subscribed mailing list.

MUTT_PAT_PERSONAL_RECIP 

Email is addressed to the user.

MUTT_PAT_PERSONAL_FROM 

Email is from the user.

MUTT_PAT_ADDRESS 

Pattern matches any address field.

MUTT_PAT_CRYPT_SIGN 

Message is signed.

MUTT_PAT_CRYPT_VERIFIED 

Message is crypographically verified.

MUTT_PAT_CRYPT_ENCRYPT 

Message is encrypted.

MUTT_PAT_PGP_KEY 

Message has PGP key.

MUTT_PAT_XLABEL 

Pattern matches keyword/label.

MUTT_PAT_SERVERSEARCH 

Server-side pattern matches.

MUTT_PAT_DRIVER_TAGS 

Pattern matches message tags.

MUTT_PAT_MIMEATTACH 

Pattern matches number of attachments.

MUTT_PAT_MIMETYPE 

Pattern matches MIME type.

MUTT_PAT_NEWSGROUPS 

Pattern matches newsgroup.

MUTT_PAT_MAX 

Definition at line 106 of file pattern.h.

107 {
109  MUTT_PAT_OR,
113  MUTT_PAT_TO,
114  MUTT_PAT_CC,
117  MUTT_PAT_FROM,
118  MUTT_PAT_DATE,
123  MUTT_PAT_ID,
125  MUTT_PAT_BODY,
132  MUTT_PAT_SIZE,
135  MUTT_PAT_LIST,
149 #ifdef USE_NNTP
151 #endif
152  MUTT_PAT_MAX,
153 };
Pattern matches date received.
Definition: pattern.h:119
Pattern matches email&#39;s header.
Definition: pattern.h:126
Pattern matches MIME type.
Definition: pattern.h:148
Pattern matches &#39;Date:&#39; field.
Definition: pattern.h:118
Pattern matches newsgroup.
Definition: pattern.h:150
Pattern matches email&#39;s score.
Definition: pattern.h:131
Message is part of a broken thread.
Definition: pattern.h:122
Pattern matches email&#39;s size.
Definition: pattern.h:132
Pattern matches &#39;From:&#39; field.
Definition: pattern.h:117
Email is from the user.
Definition: pattern.h:138
Email is on mailing list.
Definition: pattern.h:135
Pattern matches a child email.
Definition: pattern.h:112
Pattern matches email&#39;s Message-Id.
Definition: pattern.h:123
Pattern matches message number.
Definition: pattern.h:130
Email is on subscribed mailing list.
Definition: pattern.h:136
Duplicate message.
Definition: pattern.h:120
Server-side pattern matches.
Definition: pattern.h:145
Pattern matches &#39;Cc:&#39; field.
Definition: pattern.h:114
Message is unreferenced in the thread.
Definition: pattern.h:121
Pattern matches keyword/label.
Definition: pattern.h:144
Either pattern can match.
Definition: pattern.h:109
Pattern matches email&#39;s spam score.
Definition: pattern.h:127
Message is encrypted.
Definition: pattern.h:142
Pattern matches &#39;Subject:&#39; field.
Definition: pattern.h:116
Email is addressed to the user.
Definition: pattern.h:137
Message has PGP key.
Definition: pattern.h:143
Pattern matches parent.
Definition: pattern.h:111
Pattern matches email&#39;s body.
Definition: pattern.h:125
Message is signed.
Definition: pattern.h:140
Thread is collapsed.
Definition: pattern.h:115
Pattern matches sender.
Definition: pattern.h:129
Both patterns must match.
Definition: pattern.h:108
Message is crypographically verified.
Definition: pattern.h:141
Pattern matches &#39;References:&#39; or &#39;In-Reply-To:&#39; field.
Definition: pattern.h:133
Pattern matches message tags.
Definition: pattern.h:146
Pattern matches any address field.
Definition: pattern.h:139
User is a recipient of the email.
Definition: pattern.h:134
Pattern matches email thread.
Definition: pattern.h:110
Pattern matches &#39;To:&#39; field.
Definition: pattern.h:113
Pattern matches raw email text.
Definition: pattern.h:128
Pattern matches number of attachments.
Definition: pattern.h:147
Message-Id is among results from an external query.
Definition: pattern.h:124

Function Documentation

◆ SLIST_HEAD()

SLIST_HEAD ( PatternList  ,
Pattern   
)

◆ mutt_pattern_exec()

int mutt_pattern_exec ( struct Pattern pat,
PatternExecFlags  flags,
struct Mailbox m,
struct Email e,
struct PatternCache cache 
)

Match a pattern against an email header.

Parameters
patPattern to match
flagsFlags, e.g. MUTT_MATCH_FULL_ADDRESS
mMailbox
eEmail
cacheCache for common Patterns
Return values
1Success, pattern matched
0Pattern did not match
-1Error

flags: MUTT_MATCH_FULL_ADDRESS - match both personal and machine address cache: For repeated matches against the same Header, passing in non-NULL will store some of the cacheable pattern matches in this structure.

Definition at line 2124 of file pattern.c.

2126 {
2127  switch (pat->op)
2128  {
2129  case MUTT_PAT_AND:
2130  return pat->pat_not ^ (perform_and(pat->child, flags, m, e, cache) > 0);
2131  case MUTT_PAT_OR:
2132  return pat->pat_not ^ (perform_or(pat->child, flags, m, e, cache) > 0);
2133  case MUTT_PAT_THREAD:
2134  return pat->pat_not ^
2135  match_threadcomplete(pat->child, flags, m, e->thread, 1, 1, 1, 1);
2136  case MUTT_PAT_PARENT:
2137  return pat->pat_not ^ match_threadparent(pat->child, flags, m, e->thread);
2138  case MUTT_PAT_CHILDREN:
2139  return pat->pat_not ^ match_threadchildren(pat->child, flags, m, e->thread);
2140  case MUTT_ALL:
2141  return !pat->pat_not;
2142  case MUTT_EXPIRED:
2143  return pat->pat_not ^ e->expired;
2144  case MUTT_SUPERSEDED:
2145  return pat->pat_not ^ e->superseded;
2146  case MUTT_FLAG:
2147  return pat->pat_not ^ e->flagged;
2148  case MUTT_TAG:
2149  return pat->pat_not ^ e->tagged;
2150  case MUTT_NEW:
2151  return pat->pat_not ? e->old || e->read : !(e->old || e->read);
2152  case MUTT_UNREAD:
2153  return pat->pat_not ? e->read : !e->read;
2154  case MUTT_REPLIED:
2155  return pat->pat_not ^ e->replied;
2156  case MUTT_OLD:
2157  return pat->pat_not ? (!e->old || e->read) : (e->old && !e->read);
2158  case MUTT_READ:
2159  return pat->pat_not ^ e->read;
2160  case MUTT_DELETED:
2161  return pat->pat_not ^ e->deleted;
2162  case MUTT_PAT_MESSAGE:
2163  return pat->pat_not ^ ((EMSG(e) >= pat->min) && (EMSG(e) <= pat->max));
2164  case MUTT_PAT_DATE:
2165  if (pat->dynamic)
2167  return pat->pat_not ^ (e->date_sent >= pat->min && e->date_sent <= pat->max);
2169  if (pat->dynamic)
2171  return pat->pat_not ^ (e->received >= pat->min && e->received <= pat->max);
2172  case MUTT_PAT_BODY:
2173  case MUTT_PAT_HEADER:
2174  case MUTT_PAT_WHOLE_MSG:
2175  if (pat->sendmode)
2176  {
2177  if (!e->content || !e->content->filename)
2178  return 0;
2179  return pat->pat_not ^ msg_search_sendmode(e, pat);
2180  }
2181  /* m can be NULL in certain cases, such as when replying to a message
2182  * from the attachment menu and the user has a reply-hook using "~e".
2183  * This is also the case when message scoring. */
2184  if (!m)
2185  return 0;
2186 #ifdef USE_IMAP
2187  /* IMAP search sets e->matched at search compile time */
2188  if ((m->magic == MUTT_IMAP) && pat->string_match)
2189  return e->matched;
2190 #endif
2191  return pat->pat_not ^ msg_search(m, pat, e->msgno);
2192  case MUTT_PAT_SERVERSEARCH:
2193 #ifdef USE_IMAP
2194  if (!m)
2195  return 0;
2196  if (m->magic == MUTT_IMAP)
2197  {
2198  if (pat->string_match)
2199  return e->matched;
2200  return 0;
2201  }
2202  mutt_error(_("error: server custom search only supported with IMAP"));
2203  return 0;
2204 #else
2205  mutt_error(_("error: server custom search only supported with IMAP"));
2206  return -1;
2207 #endif
2208  case MUTT_PAT_SENDER:
2209  if (!e->env)
2210  return 0;
2211  return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
2212  1, &e->env->sender);
2213  case MUTT_PAT_FROM:
2214  if (!e->env)
2215  return 0;
2216  return pat->pat_not ^
2217  match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->from);
2218  case MUTT_PAT_TO:
2219  if (!e->env)
2220  return 0;
2221  return pat->pat_not ^
2222  match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->to);
2223  case MUTT_PAT_CC:
2224  if (!e->env)
2225  return 0;
2226  return pat->pat_not ^
2227  match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS), 1, &e->env->cc);
2228  case MUTT_PAT_SUBJECT:
2229  if (!e->env)
2230  return 0;
2231  return pat->pat_not ^ (e->env->subject && patmatch(pat, e->env->subject));
2232  case MUTT_PAT_ID:
2233  case MUTT_PAT_ID_EXTERNAL:
2234  if (!e->env)
2235  return 0;
2236  return pat->pat_not ^ (e->env->message_id && patmatch(pat, e->env->message_id));
2237  case MUTT_PAT_SCORE:
2238  return pat->pat_not ^ (e->score >= pat->min &&
2239  (pat->max == MUTT_MAXRANGE || e->score <= pat->max));
2240  case MUTT_PAT_SIZE:
2241  return pat->pat_not ^
2242  (e->content->length >= pat->min &&
2243  (pat->max == MUTT_MAXRANGE || e->content->length <= pat->max));
2244  case MUTT_PAT_REFERENCE:
2245  if (!e->env)
2246  return 0;
2247  return pat->pat_not ^ (match_reference(pat, &e->env->references) ||
2248  match_reference(pat, &e->env->in_reply_to));
2249  case MUTT_PAT_ADDRESS:
2250  if (!e->env)
2251  return 0;
2252  return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
2253  4, &e->env->from, &e->env->sender,
2254  &e->env->to, &e->env->cc);
2255  case MUTT_PAT_RECIPIENT:
2256  if (!e->env)
2257  return 0;
2258  return pat->pat_not ^ match_addrlist(pat, (flags & MUTT_MATCH_FULL_ADDRESS),
2259  2, &e->env->to, &e->env->cc);
2260  case MUTT_PAT_LIST: /* known list, subscribed or not */
2261  {
2262  if (!e->env)
2263  return 0;
2264 
2265  int result;
2266  if (cache)
2267  {
2268  int *cache_entry = pat->all_addr ? &cache->list_all : &cache->list_one;
2269  if (!is_pattern_cache_set(*cache_entry))
2270  {
2271  set_pattern_cache_value(cache_entry,
2272  mutt_is_list_recipient(pat->all_addr, e->env));
2273  }
2274  result = get_pattern_cache_value(*cache_entry);
2275  }
2276  else
2277  result = mutt_is_list_recipient(pat->all_addr, e->env);
2278  return pat->pat_not ^ result;
2279  }
2281  {
2282  if (!e->env)
2283  return 0;
2284 
2285  int result;
2286  if (cache)
2287  {
2288  int *cache_entry = pat->all_addr ? &cache->sub_all : &cache->sub_one;
2289  if (!is_pattern_cache_set(*cache_entry))
2290  {
2292  cache_entry, mutt_is_subscribed_list_recipient(pat->all_addr, e->env));
2293  }
2294  result = get_pattern_cache_value(*cache_entry);
2295  }
2296  else
2297  result = mutt_is_subscribed_list_recipient(pat->all_addr, e->env);
2298  return pat->pat_not ^ result;
2299  }
2301  {
2302  if (!e->env)
2303  return 0;
2304 
2305  int result;
2306  if (cache)
2307  {
2308  int *cache_entry = pat->all_addr ? &cache->pers_recip_all : &cache->pers_recip_one;
2309  if (!is_pattern_cache_set(*cache_entry))
2310  {
2312  cache_entry, match_user(pat->all_addr, &e->env->to, &e->env->cc));
2313  }
2314  result = get_pattern_cache_value(*cache_entry);
2315  }
2316  else
2317  result = match_user(pat->all_addr, &e->env->to, &e->env->cc);
2318  return pat->pat_not ^ result;
2319  }
2321  {
2322  if (!e->env)
2323  return 0;
2324 
2325  int result;
2326  if (cache)
2327  {
2328  int *cache_entry = pat->all_addr ? &cache->pers_from_all : &cache->pers_from_one;
2329  if (!is_pattern_cache_set(*cache_entry))
2330  {
2331  set_pattern_cache_value(cache_entry,
2332  match_user(pat->all_addr, &e->env->from, NULL));
2333  }
2334  result = get_pattern_cache_value(*cache_entry);
2335  }
2336  else
2337  result = match_user(pat->all_addr, &e->env->from, NULL);
2338  return pat->pat_not ^ result;
2339  }
2340  case MUTT_PAT_COLLAPSED:
2341  return pat->pat_not ^ (e->collapsed && e->num_hidden > 1);
2342  case MUTT_PAT_CRYPT_SIGN:
2343  if (!WithCrypto)
2344  break;
2345  return pat->pat_not ^ ((e->security & SEC_SIGN) ? 1 : 0);
2347  if (!WithCrypto)
2348  break;
2349  return pat->pat_not ^ ((e->security & SEC_GOODSIGN) ? 1 : 0);
2351  if (!WithCrypto)
2352  break;
2353  return pat->pat_not ^ ((e->security & SEC_ENCRYPT) ? 1 : 0);
2354  case MUTT_PAT_PGP_KEY:
2355  if (!(WithCrypto & APPLICATION_PGP))
2356  break;
2357  return pat->pat_not ^ ((e->security & PGP_KEY) == PGP_KEY);
2358  case MUTT_PAT_XLABEL:
2359  if (!e->env)
2360  return 0;
2361  return pat->pat_not ^ (e->env->x_label && patmatch(pat, e->env->x_label));
2362  case MUTT_PAT_DRIVER_TAGS:
2363  {
2364  char *tags = driver_tags_get(&e->tags);
2365  bool rc = (pat->pat_not ^ (tags && patmatch(pat, tags)));
2366  FREE(&tags);
2367  return rc;
2368  }
2369  case MUTT_PAT_HORMEL:
2370  if (!e->env)
2371  return 0;
2372  return pat->pat_not ^ (e->env->spam.data && patmatch(pat, e->env->spam.data));
2373  case MUTT_PAT_DUPLICATED:
2374  return pat->pat_not ^ (e->thread && e->thread->duplicate_thread);
2375  case MUTT_PAT_MIMEATTACH:
2376  if (!m)
2377  return 0;
2378  {
2379  int count = mutt_count_body_parts(m, e);
2380  return pat->pat_not ^ (count >= pat->min &&
2381  (pat->max == MUTT_MAXRANGE || count <= pat->max));
2382  }
2383  case MUTT_PAT_MIMETYPE:
2384  if (!m)
2385  return 0;
2386  return pat->pat_not ^ match_mime_content_type(pat, m, e);
2387  case MUTT_PAT_UNREFERENCED:
2388  return pat->pat_not ^ (e->thread && !e->thread->child);
2389  case MUTT_PAT_BROKEN:
2390  return pat->pat_not ^ (e->thread && e->thread->fake_thread);
2391 #ifdef USE_NNTP
2392  case MUTT_PAT_NEWSGROUPS:
2393  if (!e->env)
2394  return 0;
2395  return pat->pat_not ^ (e->env->newsgroups && patmatch(pat, e->env->newsgroups));
2396 #endif
2397  }
2398  mutt_error(_("error: unknown op %d (report this error)"), pat->op);
2399  return -1;
2400 }
Pattern matches date received.
Definition: pattern.h:119
struct PatternList * child
Arguments to logical operation.
Definition: pattern.h:64
Deleted messages.
Definition: mutt.h:105
Pattern matches email&#39;s header.
Definition: pattern.h:126
Pattern matches MIME type.
Definition: pattern.h:148
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
Pattern matches &#39;Date:&#39; field.
Definition: pattern.h:118
#define WithCrypto
Definition: lib.h:161
static bool match_reference(struct Pattern *pat, struct ListHead *refs)
Match references against a Pattern.
Definition: pattern.c:1772
static bool perform_and(struct PatternList *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct PatternCache *cache)
Perform a logical AND on a set of Patterns.
Definition: pattern.c:1698
Pattern matches newsgroup.
Definition: pattern.h:150
Pattern matches email&#39;s score.
Definition: pattern.h:131
int pers_recip_all
^~p
Definition: pattern.h:93
struct MuttThread * thread
Thread of Emails.
Definition: email.h:94
static int match_threadchildren(struct PatternList *pat, PatternExecFlags flags, struct Mailbox *m, struct MuttThread *t)
Match Pattern against an email&#39;s children.
Definition: pattern.c:1934
static int match_addrlist(struct Pattern *pat, bool match_personal, int n,...)
Match a Pattern against and Address list.
Definition: pattern.c:1742
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:123
Message is part of a broken thread.
Definition: pattern.h:122
Pattern matches email&#39;s size.
Definition: pattern.h:132
struct Body * content
List of MIME parts.
Definition: email.h:90
Flagged messages.
Definition: mutt.h:106
Pattern matches &#39;From:&#39; field.
Definition: pattern.h:117
#define MUTT_MAXRANGE
Definition: pattern.c:97
Email is from the user.
Definition: pattern.h:138
#define _(a)
Definition: message.h:28
Email is on mailing list.
Definition: pattern.h:135
Pattern matches a child email.
Definition: pattern.h:112
static int match_user(int all_addr, struct AddressList *al1, struct AddressList *al2)
Matches the user&#39;s email Address.
Definition: pattern.c:1841
bool expired
Already expired?
Definition: email.h:52
Pattern matches email&#39;s Message-Id.
Definition: pattern.h:123
Messages that have been replied to.
Definition: mutt.h:99
int sub_all
^~u
Definition: pattern.h:91
Pattern matches message number.
Definition: pattern.h:130
static int match_threadcomplete(struct PatternList *pat, PatternExecFlags flags, struct Mailbox *m, struct MuttThread *t, int left, int up, int right, int down)
Match a Pattern against an email thread.
Definition: pattern.c:1877
Email is on subscribed mailing list.
Definition: pattern.h:136
static int msg_search_sendmode(struct Email *e, struct Pattern *pat)
Search in send-mode.
Definition: pattern.c:2043
static int is_pattern_cache_set(int cache_entry)
Is a given Pattern cached?
Definition: pattern.c:2030
All messages.
Definition: mutt.h:95
bool tagged
Email is tagged.
Definition: email.h:44
bool read
Email is read.
Definition: email.h:51
bool dynamic
Evaluate date ranges at run time.
Definition: pattern.h:59
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:82
char * message_id
Message ID.
Definition: envelope.h:69
bool all_addr
All Addresses in the list must match.
Definition: pattern.h:54
bool old
Email is seen, but unread.
Definition: email.h:50
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
Duplicate message.
Definition: pattern.h:120
struct Envelope * env
Envelope information.
Definition: email.h:89
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
bool string_match
Check a string for a match.
Definition: pattern.h:55
bool pat_not
Pattern should be inverted (not)
Definition: pattern.h:53
bool superseded
Got superseded?
Definition: email.h:53
int min
Minimum for range checks.
Definition: pattern.h:62
struct TagList tags
For drivers that support server tagging.
Definition: email.h:102
int score
Message score.
Definition: email.h:88
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:81
Old messages.
Definition: mutt.h:98
int pers_from_one
~P
Definition: pattern.h:96
struct MuttThread * child
Child of this Thread.
Definition: thread.h:46
bool duplicate_thread
Duplicated Email in Thread.
Definition: thread.h:37
Server-side pattern matches.
Definition: pattern.h:145
Pattern matches &#39;Cc:&#39; field.
Definition: pattern.h:114
int pers_recip_one
~p
Definition: pattern.h:94
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:135
Message is unreferenced in the thread.
Definition: pattern.h:121
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
bool fake_thread
Emails grouped by Subject.
Definition: thread.h:36
Pattern matches keyword/label.
Definition: pattern.h:144
Either pattern can match.
Definition: pattern.h:109
char * driver_tags_get(struct TagList *list)
Get tags.
Definition: tags.c:142
size_t num_hidden
Number of hidden messages in this view.
Definition: email.h:75
Pattern matches email&#39;s spam score.
Definition: pattern.h:127
Superseded messages.
Definition: mutt.h:111
Tagged messages.
Definition: mutt.h:107
Message is encrypted.
Definition: pattern.h:142
char * data
Pointer to data.
Definition: buffer.h:35
Pattern matches &#39;Subject:&#39; field.
Definition: pattern.h:116
int list_all
^~l
Definition: pattern.h:89
New messages.
Definition: mutt.h:97
Messages that have been read.
Definition: mutt.h:100
static int get_pattern_cache_value(int cache_entry)
Get pattern cache value.
Definition: pattern.c:2020
Email is addressed to the user.
Definition: pattern.h:137
Message has PGP key.
Definition: pattern.h:143
bool collapsed
Is this message part of a collapsed thread?
Definition: email.h:73
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition: pattern.h:52
Pattern matches parent.
Definition: pattern.h:111
static int perform_or(struct PatternList *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct PatternCache *cache)
Perform a logical OR on a set of Patterns.
Definition: pattern.c:1720
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
#define MUTT_MATCH_FULL_ADDRESS
Match the full address.
Definition: pattern.h:77
Expired messages.
Definition: mutt.h:110
int pers_from_all
^~P
Definition: pattern.h:95
#define SEC_SIGN
Email is signed.
Definition: lib.h:124
Unread messages.
Definition: mutt.h:101
Pattern matches email&#39;s body.
Definition: pattern.h:125
static bool msg_search(struct Mailbox *m, struct Pattern *pat, int msgno)
Search an email.
Definition: pattern.c:1135
char * subject
Email&#39;s subject.
Definition: envelope.h:66
#define PGP_KEY
Definition: lib.h:144
bool flagged
Marked important?
Definition: email.h:43
char * newsgroups
List of newsgroups.
Definition: envelope.h:75
#define EMSG(e)
Definition: pattern.c:95
Message is signed.
Definition: pattern.h:140
bool deleted
Email is deleted.
Definition: email.h:45
bool sendmode
Evaluate searches in send-mode.
Definition: pattern.h:60
#define mutt_error(...)
Definition: logging.h:84
bool replied
Email has been replied to.
Definition: email.h:54
static int match_threadparent(struct PatternList *pat, PatternExecFlags flags, struct Mailbox *m, struct MuttThread *t)
Match Pattern against an email&#39;s parent.
Definition: pattern.c:1915
Thread is collapsed.
Definition: pattern.h:115
int mutt_is_subscribed_list_recipient(bool all_addr, struct Envelope *e)
Matches subscribed mailing lists.
Definition: pattern.c:1816
Pattern matches sender.
Definition: pattern.h:129
Both patterns must match.
Definition: pattern.h:108
#define FREE(x)
Definition: memory.h:40
Message is crypographically verified.
Definition: pattern.h:141
int max
Maximum for range checks.
Definition: pattern.h:63
Pattern matches &#39;References:&#39; or &#39;In-Reply-To:&#39; field.
Definition: pattern.h:133
static bool match_update_dynamic_date(struct Pattern *pat)
Update a dynamic date pattern.
Definition: pattern.c:1977
Pattern matches message tags.
Definition: pattern.h:146
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
struct AddressList sender
Email&#39;s sender.
Definition: envelope.h:61
Pattern matches any address field.
Definition: pattern.h:139
User is a recipient of the email.
Definition: pattern.h:134
static bool match_mime_content_type(const struct Pattern *pat, struct Mailbox *m, struct Email *e)
Match a Pattern against an email&#39;s Content-Type.
Definition: pattern.c:1995
Pattern matches email thread.
Definition: pattern.h:110
int mutt_count_body_parts(struct Mailbox *m, struct Email *e)
Count the MIME Body parts.
Definition: mutt_parse.c:206
Pattern matches &#39;To:&#39; field.
Definition: pattern.h:113
static void set_pattern_cache_value(int *cache_entry, int value)
Sets a value in the PatternCache cache entry.
Definition: pattern.c:2009
Pattern matches raw email text.
Definition: pattern.h:128
struct ListHead references
message references (in reverse order)
Definition: envelope.h:81
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
char * x_label
X-Label.
Definition: envelope.h:72
int mutt_is_list_recipient(bool all_addr, struct Envelope *e)
Matches known mailing lists.
Definition: pattern.c:1828
Pattern matches number of attachments.
Definition: pattern.h:147
#define SEC_GOODSIGN
Email has a valid signature.
Definition: lib.h:125
int list_one
~l
Definition: pattern.h:90
time_t received
Time when the message was placed in the mailbox.
Definition: email.h:82
Message-Id is among results from an external query.
Definition: pattern.h:124
static bool patmatch(const struct Pattern *pat, const char *buf)
Compare a string to a Pattern.
Definition: pattern.c:1116
struct Buffer spam
Spam header.
Definition: envelope.h:80
bool matched
Search matches this Email.
Definition: email.h:68
int msgno
Number displayed to the user.
Definition: email.h:86
int sub_one
~u
Definition: pattern.h:92
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pattern_comp()

struct PatternList* mutt_pattern_comp ( const char *  s,
PatternCompFlags  flags,
struct Buffer err 
)

Create a Pattern.

Parameters
sPattern string
flagsFlags, e.g. MUTT_PC_FULL_MSG
errBuffer for error messages
Return values
ptrNewly allocated Pattern

Definition at line 1438 of file pattern.c.

1439 {
1440  /* curlist when assigned will always point to a list containing at least one node
1441  * with a Pattern value. */
1442  struct PatternList *curlist = NULL;
1443  struct PatternList *tmp = NULL, *tmp2 = NULL;
1444  struct PatternList *last = NULL;
1445  bool pat_not = false;
1446  bool all_addr = false;
1447  bool pat_or = false;
1448  bool implicit = true; /* used to detect logical AND operator */
1449  bool is_alias = false;
1450  short thread_op;
1451  const struct PatternFlags *entry = NULL;
1452  char *p = NULL;
1453  char *buf = NULL;
1454  struct Buffer ps;
1455 
1456  mutt_buffer_init(&ps);
1457  ps.dptr = (char *) s;
1458  ps.dsize = mutt_str_strlen(s);
1459 
1460  while (*ps.dptr)
1461  {
1462  SKIPWS(ps.dptr);
1463  switch (*ps.dptr)
1464  {
1465  case '^':
1466  ps.dptr++;
1467  all_addr = !all_addr;
1468  break;
1469  case '!':
1470  ps.dptr++;
1471  pat_not = !pat_not;
1472  break;
1473  case '@':
1474  ps.dptr++;
1475  is_alias = !is_alias;
1476  break;
1477  case '|':
1478  if (!pat_or)
1479  {
1480  if (!curlist)
1481  {
1482  mutt_buffer_printf(err, _("error in pattern at: %s"), ps.dptr);
1483  return NULL;
1484  }
1485 
1486  struct Pattern *pat = SLIST_FIRST(curlist);
1487 
1488  if (SLIST_NEXT(pat, entries))
1489  {
1490  /* A & B | C == (A & B) | C */
1491  tmp = mutt_pattern_node_new();
1492  pat = SLIST_FIRST(tmp);
1493  pat->op = MUTT_PAT_AND;
1494  pat->child = curlist;
1495 
1496  curlist = tmp;
1497  last = curlist;
1498  }
1499 
1500  pat_or = true;
1501  }
1502  ps.dptr++;
1503  implicit = false;
1504  pat_not = false;
1505  all_addr = false;
1506  is_alias = false;
1507  break;
1508  case '%':
1509  case '=':
1510  case '~':
1511  {
1512  struct Pattern *pat = NULL;
1513  if (ps.dptr[1] == '\0')
1514  {
1515  mutt_buffer_printf(err, _("missing pattern: %s"), ps.dptr);
1516  goto cleanup;
1517  }
1518  thread_op = 0;
1519  if (ps.dptr[1] == '(')
1520  thread_op = MUTT_PAT_THREAD;
1521  else if ((ps.dptr[1] == '<') && (ps.dptr[2] == '('))
1522  thread_op = MUTT_PAT_PARENT;
1523  else if ((ps.dptr[1] == '>') && (ps.dptr[2] == '('))
1524  thread_op = MUTT_PAT_CHILDREN;
1525  if (thread_op)
1526  {
1527  ps.dptr++; /* skip ~ */
1528  if ((thread_op == MUTT_PAT_PARENT) || (thread_op == MUTT_PAT_CHILDREN))
1529  ps.dptr++;
1530  p = find_matching_paren(ps.dptr + 1);
1531  if (p[0] != ')')
1532  {
1533  mutt_buffer_printf(err, _("mismatched parentheses: %s"), ps.dptr);
1534  goto cleanup;
1535  }
1536  tmp = mutt_pattern_node_new();
1537  pat = SLIST_FIRST(tmp);
1538  pat->op = thread_op;
1539  if (last)
1540  SLIST_NEXT(SLIST_FIRST(last), entries) = pat;
1541  else
1542  curlist = tmp;
1543  last = tmp;
1544  pat->pat_not ^= pat_not;
1545  pat->all_addr |= all_addr;
1546  pat->is_alias |= is_alias;
1547  pat_not = false;
1548  all_addr = false;
1549  is_alias = false;
1550  /* compile the sub-expression */
1551  buf = mutt_str_substr_dup(ps.dptr + 1, p);
1552  tmp2 = mutt_pattern_comp(buf, flags, err);
1553  if (!tmp2)
1554  {
1555  FREE(&buf);
1556  goto cleanup;
1557  }
1558  FREE(&buf);
1559  pat->child = tmp2;
1560  ps.dptr = p + 1; /* restore location */
1561  break;
1562  }
1563  if (implicit && pat_or)
1564  {
1565  /* A | B & C == (A | B) & C */
1566  tmp = mutt_pattern_node_new();
1567  pat = SLIST_FIRST(tmp);
1568  pat->op = MUTT_PAT_OR;
1569  pat->child = curlist;
1570  curlist = tmp;
1571  last = tmp;
1572  pat_or = false;
1573  }
1574 
1575  tmp = mutt_pattern_node_new();
1576  pat = SLIST_FIRST(tmp);
1577  pat->pat_not = pat_not;
1578  pat->all_addr = all_addr;
1579  pat->is_alias = is_alias;
1580  pat->string_match = (ps.dptr[0] == '=');
1581  pat->group_match = (ps.dptr[0] == '%');
1582  pat_not = false;
1583  all_addr = false;
1584  is_alias = false;
1585 
1586  if (last)
1587  SLIST_NEXT(SLIST_FIRST(last), entries) = pat;
1588  else
1589  curlist = tmp;
1590  if (curlist != last)
1591  FREE(&last);
1592  last = tmp;
1593 
1594  ps.dptr++; /* move past the ~ */
1595  entry = lookup_tag(*ps.dptr);
1596  if (!entry)
1597  {
1598  mutt_buffer_printf(err, _("%c: invalid pattern modifier"), *ps.dptr);
1599  goto cleanup;
1600  }
1601  if (entry->flags && ((flags & entry->flags) == 0))
1602  {
1603  mutt_buffer_printf(err, _("%c: not supported in this mode"), *ps.dptr);
1604  goto cleanup;
1605  }
1606  if (flags & MUTT_PC_SEND_MODE_SEARCH)
1607  pat->sendmode = true;
1608 
1609  pat->op = entry->op;
1610 
1611  ps.dptr++; /* eat the operator and any optional whitespace */
1612  SKIPWS(ps.dptr);
1613 
1614  if (entry->eat_arg)
1615  {
1616  if (ps.dptr[0] == '\0')
1617  {
1618  mutt_buffer_printf(err, "%s", _("missing parameter"));
1619  goto cleanup;
1620  }
1621  if (!entry->eat_arg(pat, flags, &ps, err))
1622  {
1623  goto cleanup;
1624  }
1625  }
1626  implicit = true;
1627  break;
1628  }
1629 
1630  case '(':
1631  {
1632  p = find_matching_paren(ps.dptr + 1);
1633  if (p[0] != ')')
1634  {
1635  mutt_buffer_printf(err, _("mismatched parentheses: %s"), ps.dptr);
1636  goto cleanup;
1637  }
1638  /* compile the sub-expression */
1639  buf = mutt_str_substr_dup(ps.dptr + 1, p);
1640  tmp = mutt_pattern_comp(buf, flags, err);
1641  FREE(&buf);
1642  if (!tmp)
1643  goto cleanup;
1644  struct Pattern *pat = SLIST_FIRST(tmp);
1645  if (last)
1646  SLIST_NEXT(SLIST_FIRST(last), entries) = pat;
1647  else
1648  curlist = tmp;
1649  last = tmp;
1650  pat = SLIST_FIRST(tmp);
1651  pat->pat_not ^= pat_not;
1652  pat->all_addr |= all_addr;
1653  pat->is_alias |= is_alias;
1654  pat_not = false;
1655  all_addr = false;
1656  is_alias = false;
1657  ps.dptr = p + 1; /* restore location */
1658  break;
1659  }
1660 
1661  default:
1662  mutt_buffer_printf(err, _("error in pattern at: %s"), ps.dptr);
1663  goto cleanup;
1664  }
1665  }
1666  if (!curlist)
1667  {
1668  mutt_buffer_strcpy(err, _("empty pattern"));
1669  return NULL;
1670  }
1671  if (curlist != tmp)
1672  FREE(&tmp);
1673  if (SLIST_NEXT(SLIST_FIRST(curlist), entries))
1674  {
1675  tmp = mutt_pattern_node_new();
1676  struct Pattern *pat = SLIST_FIRST(tmp);
1677  pat->op = pat_or ? MUTT_PAT_OR : MUTT_PAT_AND;
1678  pat->child = curlist;
1679  curlist = tmp;
1680  }
1681 
1682  return curlist;
1683 
1684 cleanup:
1685  mutt_pattern_free(&curlist);
1686  return NULL;
1687 }
struct PatternList * child
Arguments to logical operation.
Definition: pattern.h:64
pattern_eat_t * eat_arg
Callback function to parse the argument.
Definition: pattern.c:181
int flags
Pattern flags, e.g. MUTT_PC_FULL_MSG.
Definition: pattern.c:180
bool group_match
Check a group of Addresses.
Definition: pattern.h:56
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
static char * find_matching_paren(char *s)
Find the matching parenthesis.
Definition: pattern.c:1364
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
Pattern matches a child email.
Definition: pattern.h:112
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
A simple (non-regex) pattern.
Definition: pattern.h:50
bool is_alias
Is there an alias for this Address?
Definition: pattern.h:58
int op
Operation to perform, e.g. MUTT_PAT_SCORE.
Definition: pattern.c:179
bool all_addr
All Addresses in the list must match.
Definition: pattern.h:54
static const struct PatternFlags * lookup_tag(char tag)
Lookup a pattern modifier.
Definition: pattern.c:1350
#define SKIPWS(ch)
Definition: string2.h:47
bool string_match
Check a string for a match.
Definition: pattern.h:55
bool pat_not
Pattern should be inverted (not)
Definition: pattern.h:53
static struct PatternList * mutt_pattern_node_new(void)
Create a new list containing a Pattern.
Definition: pattern.c:1422
#define SLIST_NEXT(elm, field)
Definition: queue.h:269
struct PatternList * mutt_pattern_comp(const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: pattern.c:1438
#define SLIST_FIRST(head)
Definition: queue.h:228
Either pattern can match.
Definition: pattern.h:109
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: pattern.c:1386
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition: pattern.h:52
Pattern matches parent.
Definition: pattern.h:111
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
bool sendmode
Evaluate searches in send-mode.
Definition: pattern.h:60
#define MUTT_PC_SEND_MODE_SEARCH
Allow send-mode body searching.
Definition: pattern.h:45
Both patterns must match.
Definition: pattern.h:108
#define FREE(x)
Definition: memory.h:40
Pattern matches email thread.
Definition: pattern.h:110
Mapping between user character and internal constant.
Definition: pattern.c:176
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
char * mutt_str_substr_dup(const char *begin, const char *end)
Duplicate a sub-string.
Definition: string.c:602
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_check_simple()

void mutt_check_simple ( struct Buffer buf,
const char *  simple 
)

Convert a simple search into a real request.

Parameters
bufBuffer for the result
simpleSearch string to convert

Definition at line 2425 of file pattern.c.

2426 {
2427  bool do_simple = true;
2428 
2429  for (const char *p = mutt_b2s(buf); p && (p[0] != '\0'); p++)
2430  {
2431  if ((p[0] == '\\') && (p[1] != '\0'))
2432  p++;
2433  else if ((p[0] == '~') || (p[0] == '=') || (p[0] == '%'))
2434  {
2435  do_simple = false;
2436  break;
2437  }
2438  }
2439 
2440  /* XXX - is mutt_str_strcasecmp() right here, or should we use locale's
2441  * equivalences? */
2442 
2443  if (do_simple) /* yup, so spoof a real request */
2444  {
2445  /* convert old tokens into the new format */
2446  if ((mutt_str_strcasecmp("all", mutt_b2s(buf)) == 0) ||
2447  (mutt_str_strcmp("^", mutt_b2s(buf)) == 0) ||
2448  (mutt_str_strcmp(".", mutt_b2s(buf)) == 0)) /* ~A is more efficient */
2449  {
2450  mutt_buffer_strcpy(buf, "~A");
2451  }
2452  else if (mutt_str_strcasecmp("del", mutt_b2s(buf)) == 0)
2453  mutt_buffer_strcpy(buf, "~D");
2454  else if (mutt_str_strcasecmp("flag", mutt_b2s(buf)) == 0)
2455  mutt_buffer_strcpy(buf, "~F");
2456  else if (mutt_str_strcasecmp("new", mutt_b2s(buf)) == 0)
2457  mutt_buffer_strcpy(buf, "~N");
2458  else if (mutt_str_strcasecmp("old", mutt_b2s(buf)) == 0)
2459  mutt_buffer_strcpy(buf, "~O");
2460  else if (mutt_str_strcasecmp("repl", mutt_b2s(buf)) == 0)
2461  mutt_buffer_strcpy(buf, "~Q");
2462  else if (mutt_str_strcasecmp("read", mutt_b2s(buf)) == 0)
2463  mutt_buffer_strcpy(buf, "~R");
2464  else if (mutt_str_strcasecmp("tag", mutt_b2s(buf)) == 0)
2465  mutt_buffer_strcpy(buf, "~T");
2466  else if (mutt_str_strcasecmp("unread", mutt_b2s(buf)) == 0)
2467  mutt_buffer_strcpy(buf, "~U");
2468  else
2469  {
2470  struct Buffer *tmp = mutt_buffer_pool_get();
2471  quote_simple(mutt_b2s(buf), tmp);
2472  mutt_file_expand_fmt(buf, simple, mutt_b2s(tmp));
2474  }
2475  }
2476 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
static void quote_simple(const char *str, struct Buffer *buf)
Apply simple quoting to a string.
Definition: pattern.c:2407
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
#define mutt_b2s(buf)
Definition: buffer.h:41
void mutt_file_expand_fmt(struct Buffer *dest, const char *fmt, const char *src)
Replace s in a string with a filename.
Definition: file.c:1438
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
union Pattern::@2 p
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pattern_free()

void mutt_pattern_free ( struct PatternList **  pat)

Free a Pattern.

Parameters
[out]patPattern to free

Definition at line 1386 of file pattern.c.

1387 {
1388  if (!pat || !*pat)
1389  return;
1390 
1391  struct Pattern *np = SLIST_FIRST(*pat), *next = NULL;
1392 
1393  while (np)
1394  {
1395  next = SLIST_NEXT(np, entries);
1396 
1397  if (np->is_multi)
1399  else if (np->string_match || np->dynamic)
1400  FREE(&np->p.str);
1401  else if (np->group_match)
1402  np->p.group = NULL;
1403  else if (np->p.regex)
1404  {
1405  regfree(np->p.regex);
1406  FREE(&np->p.regex);
1407  }
1408 
1409  mutt_pattern_free(&np->child);
1410  FREE(&np);
1411 
1412  np = next;
1413  }
1414 
1415  FREE(pat);
1416 }
struct PatternList * child
Arguments to logical operation.
Definition: pattern.h:64
regex_t * regex
Compiled regex, for non-pattern matching.
Definition: pattern.h:66
bool group_match
Check a group of Addresses.
Definition: pattern.h:56
bool is_multi
Multiple case (only for ~I pattern now)
Definition: pattern.h:61
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:123
A simple (non-regex) pattern.
Definition: pattern.h:50
bool dynamic
Evaluate date ranges at run time.
Definition: pattern.h:59
bool string_match
Check a string for a match.
Definition: pattern.h:55
#define SLIST_NEXT(elm, field)
Definition: queue.h:269
#define SLIST_FIRST(head)
Definition: queue.h:228
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: pattern.c:1386
union Pattern::@2 p
char * str
String, if string_match is set.
Definition: pattern.h:68
struct Group * group
Address group if group_match is set.
Definition: pattern.h:67
#define FREE(x)
Definition: memory.h:40
struct ListHead multi_cases
Multiple strings for ~I pattern.
Definition: pattern.h:69
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_which_case()

int mutt_which_case ( const char *  s)

◆ mutt_is_list_recipient()

int mutt_is_list_recipient ( bool  all_addr,
struct Envelope e 
)

Matches known mailing lists.

Parameters
all_addrIf true, ALL Addresses must be mailing lists
eEnvelope
Return values
trueOne Address is a mailing list (all_addr is false)
trueAll the Addresses are mailing lists (all_addr is true)

Definition at line 1828 of file pattern.c.

1829 {
1831 }
bool mutt_is_mail_list(const struct Address *addr)
Is this the email address of a mailing list?
Definition: hdrline.c:114
bool all_addr
All Addresses in the list must match.
Definition: pattern.h:54
static int mutt_is_predicate_recipient(bool all_addr, struct Envelope *e, addr_predicate_t p)
Test an Envelopes Addresses using a predicate function.
Definition: pattern.c:1793
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_subscribed_list_recipient()

int mutt_is_subscribed_list_recipient ( bool  all_addr,
struct Envelope e 
)

Matches subscribed mailing lists.

Parameters
all_addrIf true, ALL Addresses must be on the subscribed list
eEnvelope
Return values
trueOne Address is subscribed (all_addr is false)
trueAll the Addresses are subscribed (all_addr is true)

Definition at line 1816 of file pattern.c.

1817 {
1819 }
bool all_addr
All Addresses in the list must match.
Definition: pattern.h:54
static int mutt_is_predicate_recipient(bool all_addr, struct Envelope *e, addr_predicate_t p)
Test an Envelopes Addresses using a predicate function.
Definition: pattern.c:1793
bool mutt_is_subscribed_list(const struct Address *addr)
Is this the email address of a user-subscribed mailing list?
Definition: hdrline.c:126
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pattern_func()

int mutt_pattern_func ( int  op,
char *  prompt 
)

Perform some Pattern matching.

Parameters
opOperation to perform, e.g. MUTT_LIMIT
promptPrompt to show the user
Return values
0Success
-1Failure

Definition at line 2550 of file pattern.c.

2551 {
2552  if (!Context || !Context->mailbox)
2553  return -1;
2554 
2555  struct Buffer err;
2556  int rc = -1;
2557  struct Progress progress;
2558  struct Buffer *buf = mutt_buffer_pool_get();
2559  struct Mailbox *m = Context->mailbox;
2560 
2562  if (prompt || (op != MUTT_LIMIT))
2563  {
2564  if ((mutt_buffer_get_field(prompt, buf, MUTT_PATTERN | MUTT_CLEAR) != 0) ||
2565  mutt_buffer_is_empty(buf))
2566  {
2568  return -1;
2569  }
2570  }
2571 
2572  mutt_message(_("Compiling search pattern..."));
2573 
2574  char *simple = mutt_buffer_strdup(buf);
2576 
2577  mutt_buffer_init(&err);
2578  err.dsize = 256;
2579  err.data = mutt_mem_malloc(err.dsize);
2580  struct PatternList *pat = mutt_pattern_comp(buf->data, MUTT_PC_FULL_MSG, &err);
2581  if (!pat)
2582  {
2583  mutt_error("%s", err.data);
2584  goto bail;
2585  }
2586 
2587 #ifdef USE_IMAP
2588  if ((m->magic == MUTT_IMAP) && (imap_search(m, pat) < 0))
2589  goto bail;
2590 #endif
2591 
2592  mutt_progress_init(&progress, _("Executing command on matching messages..."),
2593  MUTT_PROGRESS_READ, (op == MUTT_LIMIT) ? m->msg_count : m->vcount);
2594 
2595  if (op == MUTT_LIMIT)
2596  {
2597  m->vcount = 0;
2598  Context->vsize = 0;
2599  Context->collapsed = false;
2600  int padding = mx_msg_padding_size(m);
2601 
2602  for (int i = 0; i < m->msg_count; i++)
2603  {
2604  struct Email *e = m->emails[i];
2605  if (!e)
2606  break;
2607 
2608  mutt_progress_update(&progress, i, -1);
2609  /* new limit pattern implicitly uncollapses all threads */
2610  e->vnum = -1;
2611  e->limited = false;
2612  e->collapsed = false;
2613  e->num_hidden = 0;
2614  if (mutt_pattern_exec(SLIST_FIRST(pat), MUTT_MATCH_FULL_ADDRESS, m, e, NULL))
2615  {
2616  e->vnum = m->vcount;
2617  e->limited = true;
2618  m->v2r[m->vcount] = i;
2619  m->vcount++;
2620  struct Body *b = e->content;
2621  Context->vsize += b->length + b->offset - b->hdr_offset + padding;
2622  }
2623  }
2624  }
2625  else
2626  {
2627  for (int i = 0; i < m->vcount; i++)
2628  {
2629  struct Email *e = mutt_get_virt_email(Context->mailbox, i);
2630  if (!e)
2631  continue;
2632  mutt_progress_update(&progress, i, -1);
2633  if (mutt_pattern_exec(SLIST_FIRST(pat), MUTT_MATCH_FULL_ADDRESS, m, e, NULL))
2634  {
2635  switch (op)
2636  {
2637  case MUTT_UNDELETE:
2638  mutt_set_flag(m, e, MUTT_PURGE, false);
2639  /* fallthrough */
2640  case MUTT_DELETE:
2641  mutt_set_flag(m, e, MUTT_DELETE, (op == MUTT_DELETE));
2642  break;
2643  case MUTT_TAG:
2644  case MUTT_UNTAG:
2645  mutt_set_flag(m, e, MUTT_TAG, (op == MUTT_TAG));
2646  break;
2647  }
2648  }
2649  }
2650  }
2651 
2652  mutt_clear_error();
2653 
2654  if (op == MUTT_LIMIT)
2655  {
2656  /* drop previous limit pattern */
2657  FREE(&Context->pattern);
2659 
2660  if (m->msg_count && !m->vcount)
2661  mutt_error(_("No messages matched criteria"));
2662 
2663  /* record new limit pattern, unless match all */
2664  const char *pbuf = buf->data;
2665  while (*pbuf == ' ')
2666  pbuf++;
2667  if (mutt_str_strcmp(pbuf, "~A") != 0)
2668  {
2669  Context->pattern = simple;
2670  simple = NULL; /* don't clobber it */
2672  }
2673  }
2674 
2675  rc = 0;
2676 
2677 bail:
2679  FREE(&simple);
2680  mutt_pattern_free(&pat);
2681  FREE(&err.data);
2682 
2683  return rc;
2684 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
The "current" mailbox.
Definition: context.h:36
#define NONULL(x)
Definition: string2.h:37
int msg_count
Total number of messages.
Definition: mailbox.h:90
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:70
The envelope/body of an email.
Definition: email.h:37
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:68
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
struct Email * mutt_get_virt_email(struct Mailbox *m, int vnum)
Get a virtual Email.
Definition: context.c:414
#define mutt_message(...)
Definition: logging.h:83
void mutt_check_simple(struct Buffer *buf, const char *simple)
Convert a simple search into a real request.
Definition: pattern.c:2425
Messages in limited view.
Definition: mutt.h:109
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Body * content
List of MIME parts.
Definition: email.h:90
int imap_search(struct Mailbox *m, const struct PatternList *pat)
Find a matching mailbox.
Definition: imap.c:1365
char * mutt_buffer_strdup(struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
String manipulation buffer.
Definition: buffer.h:33
Messages to be un-deleted.
Definition: mutt.h:103
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define _(a)
Definition: message.h:28
Messages to be purged (bypass trash)
Definition: mutt.h:104
A progress bar.
Definition: progress.h:49
#define MUTT_PATTERN
Pattern mode - only used for history classes.
Definition: mutt.h:70
int vcount
The number of virtual messages.
Definition: mailbox.h:101
The body of an email.
Definition: body.h:34
void mutt_progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:212
struct Mailbox * mailbox
Definition: context.h:50
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
Progress tracks elements, according to C_ReadInc.
Definition: progress.h:41
bool limited
Is this message in a limited view?
Definition: email.h:74
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
off_t vsize
Definition: context.h:38
int mutt_pattern_exec(struct Pattern *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct PatternCache *cache)
Match a pattern against an email header.
Definition: pattern.c:2124
struct PatternList * mutt_pattern_comp(const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: pattern.c:1438
#define SLIST_FIRST(head)
Definition: queue.h:228
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
Messages to be deleted.
Definition: mutt.h:102
A mailbox.
Definition: mailbox.h:80
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
size_t num_hidden
Number of hidden messages in this view.
Definition: email.h:75
struct PatternList * limit_pattern
Compiled limit pattern.
Definition: context.h:40
Tagged messages.
Definition: mutt.h:107
char * data
Pointer to data.
Definition: buffer.h:35
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: pattern.c:1386
bool collapsed
Is this message part of a collapsed thread?
Definition: email.h:73
int vnum
Virtual message number.
Definition: email.h:87
void mutt_progress_init(struct Progress *progress, const char *msg, enum ProgressType type, size_t size)
Set up a progress bar.
Definition: progress.c:153
#define MUTT_MATCH_FULL_ADDRESS
Match the full address.
Definition: pattern.h:77
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
#define mutt_buffer_get_field(field, buf, complete)
Definition: curs_lib.h:84
WHERE char * C_SimpleSearch
Config: Pattern to search for when search doesn&#39;t contain ~&#39;s.
Definition: globals.h:140
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:100
bool collapsed
Are all threads collapsed?
Definition: context.h:48
#define mutt_error(...)
Definition: logging.h:84
#define FREE(x)
Definition: memory.h:40
#define MUTT_PC_FULL_MSG
Enable body and header matching.
Definition: pattern.h:43
Messages to be un-tagged.
Definition: mutt.h:108
int mx_msg_padding_size(struct Mailbox *m)
Bytes of padding between messages - Wrapper for MxOps::msg_padding_size()
Definition: mx.c:1520
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:42
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
char * pattern
Limit pattern string.
Definition: context.h:39
static unsigned char * pbuf
Cache PGP data packet.
Definition: pgppacket.c:38
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_search_command()

int mutt_search_command ( int  cur,
int  op 
)

Perform a search.

Parameters
curIndex number of current email
opOperation to perform, e.g. OP_SEARCH_NEXT
Return values
>=0 Index of matching email
-1No match, or error

Definition at line 2693 of file pattern.c.

2694 {
2695  struct Progress progress;
2696 
2697  if (!*LastSearch || ((op != OP_SEARCH_NEXT) && (op != OP_SEARCH_OPPOSITE)))
2698  {
2699  char buf[256];
2700  mutt_str_strfcpy(buf, (LastSearch[0] != '\0') ? LastSearch : "", sizeof(buf));
2701  if ((mutt_get_field(((op == OP_SEARCH) || (op == OP_SEARCH_NEXT)) ?
2702  _("Search for: ") :
2703  _("Reverse search for: "),
2704  buf, sizeof(buf), MUTT_CLEAR | MUTT_PATTERN) != 0) ||
2705  !buf[0])
2706  {
2707  return -1;
2708  }
2709 
2710  if ((op == OP_SEARCH) || (op == OP_SEARCH_NEXT))
2711  OptSearchReverse = false;
2712  else
2713  OptSearchReverse = true;
2714 
2715  /* compare the *expanded* version of the search pattern in case
2716  * $simple_search has changed while we were searching */
2717  struct Buffer *tmp = mutt_buffer_pool_get();
2718  mutt_buffer_strcpy(tmp, buf);
2720 
2721  if (!SearchPattern || (mutt_str_strcmp(mutt_b2s(tmp), LastSearchExpn) != 0))
2722  {
2723  struct Buffer err;
2724  mutt_buffer_init(&err);
2725  OptSearchInvalid = true;
2726  mutt_str_strfcpy(LastSearch, buf, sizeof(LastSearch));
2728  mutt_message(_("Compiling search pattern..."));
2730  err.dsize = 256;
2731  err.data = mutt_mem_malloc(err.dsize);
2733  if (!SearchPattern)
2734  {
2736  mutt_error("%s", err.data);
2737  FREE(&err.data);
2738  LastSearch[0] = '\0';
2739  LastSearchExpn[0] = '\0';
2740  return -1;
2741  }
2742  FREE(&err.data);
2743  mutt_clear_error();
2744  }
2745 
2747  }
2748 
2749  if (OptSearchInvalid)
2750  {
2751  for (int i = 0; i < Context->mailbox->msg_count; i++)
2752  Context->mailbox->emails[i]->searched = false;
2753 #ifdef USE_IMAP
2754  if ((Context->mailbox->magic == MUTT_IMAP) &&
2756  return -1;
2757 #endif
2758  OptSearchInvalid = false;
2759  }
2760 
2761  int incr = OptSearchReverse ? -1 : 1;
2762  if (op == OP_SEARCH_OPPOSITE)
2763  incr = -incr;
2764 
2765  mutt_progress_init(&progress, _("Searching..."), MUTT_PROGRESS_READ,
2766  Context->mailbox->vcount);
2767 
2768  for (int i = cur + incr, j = 0; j != Context->mailbox->vcount; j++)
2769  {
2770  const char *msg = NULL;
2771  mutt_progress_update(&progress, j, -1);
2772  if (i > Context->mailbox->vcount - 1)
2773  {
2774  i = 0;
2775  if (C_WrapSearch)
2776  msg = _("Search wrapped to top");
2777  else
2778  {
2779  mutt_message(_("Search hit bottom without finding match"));
2780  return -1;
2781  }
2782  }
2783  else if (i < 0)
2784  {
2785  i = Context->mailbox->vcount - 1;
2786  if (C_WrapSearch)
2787  msg = _("Search wrapped to bottom");
2788  else
2789  {
2790  mutt_message(_("Search hit top without finding match"));
2791  return -1;
2792  }
2793  }
2794 
2795  struct Email *e = mutt_get_virt_email(Context->mailbox, i);
2796  if (e->searched)
2797  {
2798  /* if we've already evaluated this message, use the cached value */
2799  if (e->matched)
2800  {
2801  mutt_clear_error();
2802  if (msg && *msg)
2803  mutt_message(msg);
2804  return i;
2805  }
2806  }
2807  else
2808  {
2809  /* remember that we've already searched this message */
2810  e->searched = true;
2812  Context->mailbox, e, NULL);
2813  if (e->matched > 0)
2814  {
2815  mutt_clear_error();
2816  if (msg && *msg)
2817  mutt_message(msg);
2818  return i;
2819  }
2820  }
2821 
2822  if (SigInt)
2823  {
2824  mutt_error(_("Search interrupted"));
2825  SigInt = 0;
2826  return -1;
2827  }
2828 
2829  i += incr;
2830  }
2831 
2832  mutt_error(_("Not found"));
2833  return -1;
2834 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
The "current" mailbox.
Definition: context.h:36
#define NONULL(x)
Definition: string2.h:37
int msg_count
Total number of messages.
Definition: mailbox.h:90
The envelope/body of an email.
Definition: email.h:37
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:68
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
struct Email * mutt_get_virt_email(struct Mailbox *m, int vnum)
Get a virtual Email.
Definition: context.c:414
#define mutt_message(...)
Definition: logging.h:83
void mutt_check_simple(struct Buffer *buf, const char *simple)
Convert a simple search into a real request.
Definition: pattern.c:2425
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: globals.h:79
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
int imap_search(struct Mailbox *m, const struct PatternList *pat)
Find a matching mailbox.
Definition: imap.c:1365
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
static char LastSearch[256]
last pattern searched for
Definition: pattern.c:200
WHERE bool C_WrapSearch
Config: Wrap around when the search hits the end.
Definition: globals.h:261
bool searched
Email has been searched.
Definition: email.h:67
A progress bar.
Definition: progress.h:49
#define MUTT_PATTERN
Pattern mode - only used for history classes.
Definition: mutt.h:70
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:90
int vcount
The number of virtual messages.
Definition: mailbox.h:101
void mutt_progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:212
struct Mailbox * mailbox
Definition: context.h:50
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
Progress tracks elements, according to C_ReadInc.
Definition: progress.h:41
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
#define mutt_b2s(buf)
Definition: buffer.h:41
int mutt_pattern_exec(struct Pattern *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct PatternCache *cache)
Match a pattern against an email header.
Definition: pattern.c:2124
struct PatternList * mutt_pattern_comp(const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: pattern.c:1438
static char LastSearchExpn[1024]
expanded version of LastSearch
Definition: pattern.c:201
#define SLIST_FIRST(head)
Definition: queue.h:228
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
char * data
Pointer to data.
Definition: buffer.h:35
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: pattern.c:1386
WHERE bool OptSearchInvalid
(pseudo) used to invalidate the search pattern
Definition: options.h:51
void mutt_progress_init(struct Progress *progress, const char *msg, enum ProgressType type, size_t size)
Set up a progress bar.
Definition: progress.c:153
#define MUTT_MATCH_FULL_ADDRESS
Match the full address.
Definition: pattern.h:77
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
WHERE char * C_SimpleSearch
Config: Pattern to search for when search doesn&#39;t contain ~&#39;s.
Definition: globals.h:140
static struct PatternList * SearchPattern
current search pattern
Definition: pattern.c:199
#define mutt_error(...)
Definition: logging.h:84
#define FREE(x)
Definition: memory.h:40
#define MUTT_PC_FULL_MSG
Enable body and header matching.
Definition: pattern.h:43
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
WHERE bool OptSearchReverse
(pseudo) used by ci_search_command
Definition: options.h:52
bool matched
Search matches this Email.
Definition: email.h:68
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_limit_current_thread()

bool mutt_limit_current_thread ( struct Email e)

Limit the email view to the current thread.

Parameters
eCurrent Email
Return values
trueSuccess
falseFailure

Definition at line 2503 of file pattern.c.

2504 {
2505  if (!e || !Context || !Context->mailbox)
2506  return false;
2507 
2508  struct MuttThread *me = top_of_thread(e);
2509  if (!me)
2510  return false;
2511 
2512  struct Mailbox *m = Context->mailbox;
2513 
2514  m->vcount = 0;
2515  Context->vsize = 0;
2516  Context->collapsed = false;
2517 
2518  for (int i = 0; i < m->msg_count; i++)
2519  {
2520  e = m->emails[i];
2521  if (!e)
2522  break;
2523 
2524  e->vnum = -1;
2525  e->limited = false;
2526  e->collapsed = false;
2527  e->num_hidden = 0;
2528 
2529  if (top_of_thread(e) == me)
2530  {
2531  struct Body *body = e->content;
2532 
2533  e->vnum = m->vcount;
2534  e->limited = true;
2535  m->v2r[m->vcount] = i;
2536  m->vcount++;
2537  Context->vsize += (body->length + body->offset - body->hdr_offset);
2538  }
2539  }
2540  return true;
2541 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
The "current" mailbox.
Definition: context.h:36
int msg_count
Total number of messages.
Definition: mailbox.h:90
struct Body * content
List of MIME parts.
Definition: email.h:90
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
int vcount
The number of virtual messages.
Definition: mailbox.h:101
The body of an email.
Definition: body.h:34
struct Mailbox * mailbox
Definition: context.h:50
bool limited
Is this message in a limited view?
Definition: email.h:74
off_t vsize
Definition: context.h:38
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
A mailbox.
Definition: mailbox.h:80
static struct MuttThread * top_of_thread(struct Email *e)
Find the first email in the current thread.
Definition: pattern.c:2484
size_t num_hidden
Number of hidden messages in this view.
Definition: email.h:75
bool collapsed
Is this message part of a collapsed thread?
Definition: email.h:73
int vnum
Virtual message number.
Definition: email.h:87
An Email conversation.
Definition: thread.h:34
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:100
bool collapsed
Are all threads collapsed?
Definition: context.h:48
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_ThoroughSearch

bool C_ThoroughSearch

Config: Decode headers and messages before searching them.

Definition at line 73 of file pattern.c.