966{
967
968
969 struct PatternList *curlist = NULL;
970 bool pat_not = false;
971 bool all_addr = false;
972 bool pat_or = false;
973 bool implicit = true;
974 bool is_alias = false;
976 char *p = NULL;
977 char *buf = NULL;
979
980 if (!s || (s[0] == '\0'))
981 {
983 return NULL;
984 }
985
989
992 {
994 {
995 case '^':
997 all_addr = !all_addr;
998 break;
999 case '!':
1001 pat_not = !pat_not;
1002 break;
1003 case '@':
1005 is_alias = !is_alias;
1006 break;
1007 case '|':
1008 if (!pat_or)
1009 {
1010 if (!curlist)
1011 {
1014 return NULL;
1015 }
1016
1019 {
1020
1023 }
1024
1025 pat_or = true;
1026 }
1028 implicit = false;
1032 break;
1033 case '%':
1034 case '=':
1035 case '~':
1036 {
1037 if (ps->
dptr[1] ==
'\0')
1038 {
1040 goto cleanup;
1041 }
1042 short thread_op = 0;
1043 if (ps->
dptr[1] ==
'(')
1045 else if ((ps->
dptr[1] ==
'<') && (ps->
dptr[2] ==
'('))
1047 else if ((ps->
dptr[1] ==
'>') && (ps->
dptr[2] ==
'('))
1049 if (thread_op != 0)
1050 {
1056 {
1058 goto cleanup;
1059 }
1061 leaf->
op = thread_op;
1068
1072 {
1074 goto cleanup;
1075 }
1078 break;
1079 }
1080 if (implicit && pat_or)
1081 {
1082
1085 pat_or = false;
1086 }
1087
1088 char prefix = ps->
dptr[0];
1090 if (!entry)
1091 {
1093 goto cleanup;
1094 }
1095 if (entry->
flags && ((flags & entry->
flags) == 0))
1096 {
1097 buf_printf(err,
_(
"%c%c: not supported in this mode"), prefix, ps->
dptr[1]);
1098 goto cleanup;
1099 }
1100
1106 leaf->
op = entry->
op;
1110
1111
1112
1113
1115 if ((entry->
prefix ==
'~') && (prefix ==
'=') && (eat_arg ==
EAT_REGEX))
1117 else if ((entry->
prefix ==
'~') && (prefix ==
'%') && (eat_arg ==
EAT_REGEX))
1119
1123 if (eat_arg)
1124 {
1125 if (ps->
dptr[0] ==
'\0')
1126 {
1128 goto cleanup;
1129 }
1130 switch (eat_arg)
1131 {
1134 goto cleanup;
1135 break;
1138 goto cleanup;
1139 break;
1142 goto cleanup;
1143 break;
1145 if (!
eat_date(leaf, flags, ps, err))
1146 goto cleanup;
1147 break;
1150 goto cleanup;
1151 break;
1154 goto cleanup;
1155 break;
1157 if (!
eat_query(leaf, flags, ps, err, m))
1158 goto cleanup;
1159 break;
1160 default:
1161 break;
1162 }
1163 }
1164 implicit = true;
1165 break;
1166 }
1167
1168 case '(':
1169 {
1172 {
1174 goto cleanup;
1175 }
1176
1180 if (!sub)
1181 goto cleanup;
1183 if (curlist)
1184 {
1187 }
1188 else
1189 {
1190 curlist = sub;
1191 }
1199 break;
1200 }
1201
1202 default:
1204 goto cleanup;
1205 }
1207 }
1209
1210 if (!curlist)
1211 {
1213 return NULL;
1214 }
1215
1217 {
1220 }
1221
1222 return curlist;
1223
1224cleanup:
1227 return NULL;
1228}
void buf_seek(struct Buffer *buf, size_t offset)
Set current read/write position to offset from beginning.
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
static struct Pattern * attach_new_leaf(struct PatternList **curlist)
Attach a new Pattern to a List.
struct PatternList * mutt_pattern_comp(struct MailboxView *mv, const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
static char * find_matching_paren(char *s)
Find the matching parenthesis.
static bool eat_group(struct Pattern *pat, PatternCompFlags flags, struct Buffer *s, struct Buffer *err)
Parse a group name - Implements eat_arg_t -.
static bool eat_string(struct Pattern *pat, PatternCompFlags flags, struct Buffer *s, struct Buffer *err)
Parse a plain string - Implements eat_arg_t -.
static bool eat_query(struct Pattern *pat, PatternCompFlags flags, struct Buffer *s, struct Buffer *err, struct Mailbox *m)
Parse a query for an external search program - Implements eat_arg_t -.
bool eat_message_range(struct Pattern *pat, PatternCompFlags flags, struct Buffer *s, struct Buffer *err, struct MailboxView *mv)
Parse a range of message numbers - Implements eat_arg_t -.
static bool eat_range(struct Pattern *pat, PatternCompFlags flags, struct Buffer *s, struct Buffer *err)
Parse a number range - Implements eat_arg_t -.
static bool eat_date(struct Pattern *pat, PatternCompFlags flags, struct Buffer *s, struct Buffer *err)
Parse a date pattern - Implements eat_arg_t -.
static bool eat_regex(struct Pattern *pat, PatternCompFlags flags, struct Buffer *s, struct Buffer *err)
Parse a regex - Implements eat_arg_t -.
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
const struct PatternFlags * lookup_tag(char prefix, char tag)
Lookup a pattern modifier.
@ MUTT_PAT_OR
Either pattern can match.
@ MUTT_PAT_CHILDREN
Pattern matches a child email.
@ MUTT_PAT_PARENT
Pattern matches parent.
@ MUTT_PAT_AND
Both patterns must match.
@ MUTT_PAT_THREAD
Pattern matches email thread.
@ MUTT_PC_SEND_MODE_SEARCH
Allow send-mode body searching.
PatternEat
Function to process pattern arguments.
@ EAT_STRING
Process a plain string.
@ EAT_RANGE
Process a number (range)
@ EAT_GROUP
Process a group name.
@ EAT_MESSAGE_RANGE
Process a message number (range)
@ EAT_DATE
Process a date (range)
@ EAT_QUERY
Process a query string.
@ EAT_REGEX
Process a regex.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
String manipulation buffer.
char * dptr
Current read/write position.
struct Mailbox * mailbox
Current Mailbox.
Mapping between user character and internal constant.
enum PatternEat eat_arg
Type of function needed to parse flag, e.g. EAT_DATE.
PatternCompFlags flags
Pattern flags, e.g. MUTT_PC_FULL_MSG.
int op
Operation to perform, e.g. MUTT_PAT_SCORE.
char prefix
Prefix for this pattern, e.g. '~', '', or '='.
bool all_addr
All Addresses in the list must match.
bool is_alias
Is there an alias for this Address?
short op
Operation, e.g. MUTT_PAT_SCORE.
bool sendmode
Evaluate searches in send-mode.
bool pat_not
Pattern should be inverted (not)