From 0a3754f8b66fc50dafeb61711679fc85c1e38038 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 4 Feb 2016 14:32:39 -0500 Subject: Implements -daystart. --- bfs.h | 9 ++++++--- eval.c | 2 +- parse.c | 46 +++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/bfs.h b/bfs.h index bf33a33..2a9ba2e 100644 --- a/bfs.h +++ b/bfs.h @@ -63,9 +63,6 @@ struct cmdline { /** The command line expression. */ struct expr *expr; - - /** The current time. */ - struct timespec now; }; /** @@ -109,14 +106,20 @@ struct expr { struct expr *rhs; /** The function that evaluates this expression. */ eval_fn *eval; + /** The optional comparison flag. */ enum cmpflag cmp; + + /** The optional reference time. */ + struct timespec reftime; /** The optional time field. */ enum timefield timefield; /** The optional time unit. */ enum timeunit timeunit; + /** Optional integer data for this expression. */ int idata; + /** Optional string data for this expression. */ const char *sdata; }; diff --git a/eval.c b/eval.c index 258857c..2463d86 100644 --- a/eval.c +++ b/eval.c @@ -108,7 +108,7 @@ bool eval_acmtime(const struct expr *expr, struct eval_state *state) { break; } - time_t diff = timespec_diff(&state->cl->now, time); + time_t diff = timespec_diff(&expr->reftime, time); switch (expr->timeunit) { case MINUTES: diff /= 60; diff --git a/parse.c b/parse.c index 4f6f987..898b5df 100644 --- a/parse.c +++ b/parse.c @@ -3,6 +3,7 @@ #include #include #include +#include #include /** @@ -127,6 +128,9 @@ struct parser_state { bool warn; /** Whether any non-option arguments have been encountered. */ bool non_option_seen; + + /** The current time. */ + struct timespec now; }; /** @@ -308,12 +312,42 @@ static struct expr *parse_test_sdata(struct parser_state *state, const char *tes static struct expr *parse_acmtime(struct parser_state *state, const char *option, enum timefield field, enum timeunit unit) { struct expr *expr = parse_test_icmp(state, option, eval_acmtime); if (expr) { + expr->reftime = state->now; expr->timefield = field; expr->timeunit = unit; } return expr; } +/** + * "Parse" -daystart. + */ +static struct expr *parse_daystart(struct parser_state *state) { + // Should be called before localtime_r() according to POSIX.1-2004 + tzset(); + + struct tm tm; + if (!localtime_r(&state->now.tv_sec, &tm)) { + perror("localtime_r()"); + return NULL; + } + + tm.tm_sec = 0; + tm.tm_min = 0; + tm.tm_hour = 0; + ++tm.tm_mday; + time_t time = mktime(&tm); + if (time == -1) { + perror("mktime()"); + return NULL; + } + + state->now.tv_sec = time; + state->now.tv_nsec = 0; + + return new_positional_option(state); +} + /** * Parse -{min,max}depth N. */ @@ -402,6 +436,8 @@ static struct expr *parse_literal(struct parser_state *state) { } else if (strcmp(arg, "-nocolor") == 0) { state->cl->color = false; return new_option(state, arg); + } else if (strcmp(arg, "-daystart") == 0) { + return parse_daystart(state); } else if (strcmp(arg, "-delete") == 0) { state->cl->flags |= BFTW_DEPTH; return new_action(state, eval_delete); @@ -681,11 +717,6 @@ struct cmdline *parse_cmdline(int argc, char *argv[]) { cl->flags = BFTW_RECOVER; cl->expr = &expr_true; - if (clock_gettime(CLOCK_REALTIME, &cl->now) != 0) { - perror("clock_gettime()"); - goto fail; - } - struct parser_state state = { .cl = cl, .argv = argv, @@ -695,6 +726,11 @@ struct cmdline *parse_cmdline(int argc, char *argv[]) { .non_option_seen = false, }; + if (clock_gettime(CLOCK_REALTIME, &state.now) != 0) { + perror("clock_gettime()"); + goto fail; + } + if (skip_paths(&state)) { cl->expr = parse_expr(&state); if (!cl->expr) { -- cgit v1.2.3