#include "imap/imap.h"
#endif
-static int eat_regexp (pattern_t *pat, BUFFER *, BUFFER *);
-static int eat_date (pattern_t *pat, BUFFER *, BUFFER *);
-static int eat_range (pattern_t *pat, BUFFER *, BUFFER *);
+static int eat_regexp (pattern_t *pat, int, BUFFER *, BUFFER *);
+static int eat_date (pattern_t *pat, int, BUFFER *, BUFFER *);
+static int eat_range (pattern_t *pat, int, BUFFER *, BUFFER *);
static int patmatch (const pattern_t *pat, const char *buf);
static const struct pattern_flags
int tag; /* character used to represent this op */
int op; /* operation to perform */
int class;
- int (*eat_arg) (pattern_t *, BUFFER *, BUFFER *);
+ int (*eat_arg) (pattern_t *, int, BUFFER *, BUFFER *);
}
Flags[] =
{
return match;
}
-static int eat_regexp (pattern_t *pat, BUFFER *s, BUFFER *err)
+static int eat_regexp (pattern_t *pat, int flags, BUFFER *s, BUFFER *err)
{
BUFFER buf;
char errmsg[STRING];
return 0;
}
-int eat_range (pattern_t *pat, BUFFER *s, BUFFER *err)
+static int eat_range (pattern_t *pat, int flags, BUFFER *s, BUFFER *err)
{
char *tmp;
int do_exclusive = 0;
return ((flag & MUTT_PDR_ERROR) ? NULL : pc);
}
-static int eat_date (pattern_t *pat, BUFFER *s, BUFFER *err)
+static int eval_date_minmax (pattern_t *pat, const char *s, BUFFER *err)
{
- BUFFER buffer;
struct tm min, max;
- char *pexpr;
-
- mutt_buffer_init (&buffer);
- pexpr = s->dptr;
- if (mutt_extract_token (&buffer, s, MUTT_TOKEN_COMMENT | MUTT_TOKEN_PATTERN) != 0
- || !buffer.data)
- {
- FREE (&buffer.data);
- snprintf (err->data, err->dsize, _("Error in expression: %s"), pexpr);
- return (-1);
- }
- if (!*buffer.data)
- {
- FREE (&buffer.data);
- snprintf (err->data, err->dsize, "%s", _("Empty expression"));
- return (-1);
- }
memset (&min, 0, sizeof (min));
/* the `0' time is Jan 1, 1970 UTC, so in order to prevent a negative time
max.tm_min = 59;
max.tm_sec = 59;
- if (strchr ("<>=", buffer.data[0]))
+ if (strchr ("<>=", s[0]))
{
/* offset from current time
<3d less than three days ago
struct tm *tm = localtime (&now);
int exact = 0;
- if (buffer.data[0] == '<')
+ if (s[0] == '<')
{
memcpy (&min, tm, sizeof (min));
tm = &min;
memcpy (&max, tm, sizeof (max));
tm = &max;
- if (buffer.data[0] == '=')
+ if (s[0] == '=')
exact++;
}
tm->tm_hour = 23;
tm->tm_min = tm->tm_sec = 59;
/* force negative offset */
- get_offset (tm, buffer.data + 1, -1);
+ get_offset (tm, s + 1, -1);
if (exact)
{
}
else
{
- const char *pc = buffer.data;
+ const char *pc = s;
int haveMin = FALSE;
int untilNow = FALSE;
/* minimum date specified */
if ((pc = getDate (pc, &min, err)) == NULL)
{
- FREE (&buffer.data);
return (-1);
}
haveMin = TRUE;
memcpy (&min, tm, sizeof (min));
min.tm_hour = min.tm_sec = min.tm_min = 0;
}
-
+
/* preset max date for relative offsets,
if nothing follows we search for messages on a specific day */
max.tm_year = min.tm_year;
if (!parse_date_range (pc, &min, &max, haveMin, &baseMin, err))
{ /* bail out on any parsing error */
- FREE (&buffer.data);
return (-1);
}
}
pat->min = mutt_mktime (&min, 1);
pat->max = mutt_mktime (&max, 1);
+ return 0;
+}
+
+static int eat_date (pattern_t *pat, int flags, BUFFER *s, BUFFER *err)
+{
+ BUFFER buffer;
+ char *pexpr;
+ int rc = -1;
+
+ mutt_buffer_init (&buffer);
+ pexpr = s->dptr;
+ if (mutt_extract_token (&buffer, s, MUTT_TOKEN_COMMENT | MUTT_TOKEN_PATTERN) != 0
+ || !buffer.data)
+ {
+ snprintf (err->data, err->dsize, _("Error in expression: %s"), pexpr);
+ goto out;
+ }
+ if (!*buffer.data)
+ {
+ snprintf (err->data, err->dsize, "%s", _("Empty expression"));
+ goto out;
+ }
+
+ if (flags & MUTT_PATTERN_DYNAMIC)
+ {
+ pat->dynamic = 1;
+ pat->p.str = safe_strdup (buffer.data);
+ }
+
+ rc = eval_date_minmax (pat, buffer.data, err);
+
+out:
FREE (&buffer.data);
- return 0;
+ return rc;
}
static int patmatch (const pattern_t* pat, const char* buf)
tmp = *pat;
*pat = (*pat)->next;
- if (tmp->stringmatch)
+ if (tmp->stringmatch || tmp->dynamic)
FREE (&tmp->p.str);
else if (tmp->groupmatch)
tmp->p.g = NULL;
mutt_pattern_free (&curlist);
return NULL;
}
- if (entry->eat_arg (tmp, &ps, err) == -1)
+ if (entry->eat_arg (tmp, flags, &ps, err) == -1)
{
mutt_pattern_free (&curlist);
return NULL;
return 0;
}
+static int match_update_dynamic_date (pattern_t *pat)
+{
+ BUFFER err;
+ int rc;
+
+ mutt_buffer_init (&err);
+ rc = eval_date_minmax (pat, pat->p.str, &err);
+ FREE (&err.data);
+
+ return rc;
+}
+
static int match_mime_content_type(const pattern_t *pat, CONTEXT *ctx, HEADER *hdr)
{
mutt_parse_mime_message(ctx, hdr);
return (pat->not ^ (h->msgno >= pat->min - 1 && (pat->max == MUTT_MAXRANGE ||
h->msgno <= pat->max - 1)));
case MUTT_DATE:
+ if (pat->dynamic)
+ match_update_dynamic_date (pat);
return (pat->not ^ (h->date_sent >= pat->min && h->date_sent <= pat->max));
case MUTT_DATE_RECEIVED:
+ if (pat->dynamic)
+ match_update_dynamic_date (pat);
return (pat->not ^ (h->received >= pat->min && h->received <= pat->max));
case MUTT_BODY:
case MUTT_HEADER: