Commit e3a077ec e3a077ec31261e47c4ee7a8babed0e510feaa152 by Sergey Poznyakoff

Implemented --after and --before.

1 parent 0b9696da
......@@ -57,11 +57,11 @@ static struct argp_option options[] = {
{N_("Date constraint operations:"), 0, NULL, OPTION_DOC, NULL, 1},
{"datefield",ARG_DATEFIELD, N_("STRING"), 0,
N_("* Search in the named date header field (default is `Date:')"), 2},
N_("Search in the named date header field (default is `Date:')"), 2},
{"after", ARG_AFTER, N_("DATE"), 0,
N_("* Match messages after the given date"), 2},
N_("Match messages after the given date"), 2},
{"before", ARG_BEFORE, N_("DATE"), 0,
N_("* Match messages before the given date"), 2},
N_("Match messages before the given date"), 2},
{N_("Logical operations and grouping:"), 0, NULL, OPTION_DOC, NULL, 2},
{"and", ARG_AND, NULL, 0,
......
......@@ -21,7 +21,9 @@ typedef enum
node_or,
node_not,
node_regex,
node_datefield
node_datefield,
node_before,
node_after
} node_type;
typedef struct node node_t;
......@@ -50,6 +52,7 @@ struct node
void *a;
void *b;
} gen;
time_t time;
} v;
};
......
......@@ -19,7 +19,7 @@
#include <mh.h>
#include <regex.h>
#include <pick.h>
static node_t *pick_node_create (node_type type, void *a, void *b);
static void set_cflags (char *str);
......@@ -109,13 +109,25 @@ expr : lbrace exprlist rbrace
}
| T_BEFORE T_STRING
{
mh_error (_("--before is not yet supported"));
YYERROR;
time_t t;
if (mu_parse_date ($2, &t, NULL))
{
mh_error (_("bad date format: %s"), $2);
exit (1);
}
$$ = pick_node_create (node_before, NULL, NULL);
$$->v.time = t;
}
| T_AFTER T_STRING
{
mh_error (_("--after is not yet supported"));
YYERROR;
time_t t;
if (mu_parse_date ($2, &t, NULL))
{
mh_error (_("bad date format: %s"), $2);
exit (1);
}
$$ = pick_node_create (node_after, NULL, NULL);
$$->v.time = t;
}
| expr T_AND expr
{
......@@ -320,8 +332,23 @@ match_message (message_t msg, regex_t *regex)
}
static int
get_date_field (struct eval_env *env, time_t *t)
{
header_t hdr;
char buf[128];
if (message_get_header (env->msg, &hdr))
return 1;
if (header_get_value (hdr, env->datefield, buf, sizeof buf, NULL))
return 1;
return mu_parse_date (buf, t, NULL);
}
static int
pick_eval_node (node_t *node, struct eval_env *env)
{
time_t t;
switch (node->type)
{
case node_and:
......@@ -346,8 +373,18 @@ pick_eval_node (node_t *node, struct eval_env *env)
case node_datefield:
env->datefield = node->v.df.datefield;
return 1;
case node_before:
if (get_date_field (env, &t))
break;
return t < node->v.time;
case node_after:
if (get_date_field (env, &t))
break;
return t > node->v.time;
}
/*NOTREACHED*/
return 0;
}
......