From 0a3754f8b66fc50dafeb61711679fc85c1e38038 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 4 Feb 2016 14:32:39 -0500 Subject: Implements -daystart. --- parse.c | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) (limited to 'parse.c') 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