diff options
-rw-r--r-- | bfs.h | 35 | ||||
-rw-r--r-- | eval.c | 101 | ||||
-rw-r--r-- | parse.c | 24 |
3 files changed, 68 insertions, 92 deletions
@@ -80,6 +80,28 @@ enum cmpflag { CMP_GREATER, }; +/** + * Available struct stat time fields. + */ +enum timefield { + /** Access time. */ + ATIME, + /** Status change time. */ + CTIME, + /** Modification time. */ + MTIME, +}; + +/** + * Possible time units. + */ +enum timeunit { + /** Minutes. */ + MINUTES, + /** Days. */ + DAYS, +}; + struct expr { /** The left hand side of the expression. */ struct expr *lhs; @@ -87,8 +109,12 @@ struct expr { struct expr *rhs; /** The function that evaluates this expression. */ eval_fn *eval; - /** The comparison flag. */ + /** The optional comparison flag. */ enum cmpflag cmp; + /** 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. */ @@ -116,12 +142,7 @@ bool eval_false(const struct expr *expr, struct eval_state *state); bool eval_access(const struct expr *expr, struct eval_state *state); -bool eval_amin(const struct expr *expr, struct eval_state *state); -bool eval_atime(const struct expr *expr, struct eval_state *state); -bool eval_cmin(const struct expr *expr, struct eval_state *state); -bool eval_ctime(const struct expr *expr, struct eval_state *state); -bool eval_mmin(const struct expr *expr, struct eval_state *state); -bool eval_mtime(const struct expr *expr, struct eval_state *state); +bool eval_acmtime(const struct expr *expr, struct eval_state *state); bool eval_gid(const struct expr *expr, struct eval_state *state); bool eval_uid(const struct expr *expr, struct eval_state *state); @@ -49,20 +49,6 @@ static time_t timespec_diff(const struct timespec *lhs, const struct timespec *r } /** - * Convert a second count to minutes. - */ -static time_t to_minutes(time_t seconds) { - return seconds/60; -} - -/** - * Convert a second count to days. - */ -static time_t to_days(time_t seconds) { - return seconds/60/60/24; -} - -/** * Perform a comparison. */ static bool do_cmp(const struct expr *expr, int n) { @@ -101,81 +87,38 @@ bool eval_access(const struct expr *expr, struct eval_state *state) { } /** - * -amin test. + * -[acm]{min,time} tests. */ -bool eval_amin(const struct expr *expr, struct eval_state *state) { +bool eval_acmtime(const struct expr *expr, struct eval_state *state) { const struct stat *statbuf = fill_statbuf(state); if (!statbuf) { return false; } - time_t diff = timespec_diff(&state->cl->now, &statbuf->st_atim); - return do_cmp(expr, to_minutes(diff)); -} - -/** - * -atime test. - */ -bool eval_atime(const struct expr *expr, struct eval_state *state) { - const struct stat *statbuf = fill_statbuf(state); - if (!statbuf) { - return false; - } - - time_t diff = timespec_diff(&state->cl->now, &statbuf->st_atim); - return do_cmp(expr, to_days(diff)); -} - -/** - * -cmin test. - */ -bool eval_cmin(const struct expr *expr, struct eval_state *state) { - const struct stat *statbuf = fill_statbuf(state); - if (!statbuf) { - return false; + const struct timespec *time; + switch (expr->timefield) { + case ATIME: + time = &statbuf->st_atim; + break; + case CTIME: + time = &statbuf->st_ctim; + break; + case MTIME: + time = &statbuf->st_mtim; + break; } - time_t diff = timespec_diff(&state->cl->now, &statbuf->st_ctim); - return do_cmp(expr, to_minutes(diff)); -} - -/** - * -ctime test. - */ -bool eval_ctime(const struct expr *expr, struct eval_state *state) { - const struct stat *statbuf = fill_statbuf(state); - if (!statbuf) { - return false; - } - - time_t diff = timespec_diff(&state->cl->now, &statbuf->st_ctim); - return do_cmp(expr, to_days(diff)); -} - -/** - * -mmin test. - */ -bool eval_mmin(const struct expr *expr, struct eval_state *state) { - const struct stat *statbuf = fill_statbuf(state); - if (!statbuf) { - return false; - } - - time_t diff = timespec_diff(&state->cl->now, &statbuf->st_mtim); - return do_cmp(expr, to_minutes(diff)); -} - -/** - * -mtime test. - */ -bool eval_mtime(const struct expr *expr, struct eval_state *state) { - const struct stat *statbuf = fill_statbuf(state); - if (!statbuf) { - return false; + time_t diff = timespec_diff(&state->cl->now, time); + switch (expr->timeunit) { + case MINUTES: + diff /= 60; + break; + case DAYS: + diff /= 60*60*24; + break; } - time_t diff = timespec_diff(&state->cl->now, &statbuf->st_mtim); - return do_cmp(expr, to_days(diff)); + return do_cmp(expr, diff); } /** @@ -303,6 +303,18 @@ static struct expr *parse_test_sdata(struct parser_state *state, const char *tes } /** + * Parse -[acm]{min,time}. + */ +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->timefield = field; + expr->timeunit = unit; + } + return expr; +} + +/** * Parse -{min,max}depth N. */ static struct expr *parse_depth(struct parser_state *state, const char *option, int *depth) { @@ -377,13 +389,13 @@ static struct expr *parse_literal(struct parser_state *state) { const char *arg = state->argv[state->i++]; if (strcmp(arg, "-amin") == 0) { - return parse_test_icmp(state, arg, eval_amin); + return parse_acmtime(state, arg, ATIME, MINUTES); } else if (strcmp(arg, "-atime") == 0) { - return parse_test_icmp(state, arg, eval_atime); + return parse_acmtime(state, arg, ATIME, DAYS); } else if (strcmp(arg, "-cmin") == 0) { - return parse_test_icmp(state, arg, eval_cmin); + return parse_acmtime(state, arg, CTIME, MINUTES); } else if (strcmp(arg, "-ctime") == 0) { - return parse_test_icmp(state, arg, eval_ctime); + return parse_acmtime(state, arg, CTIME, DAYS); } else if (strcmp(arg, "-color") == 0) { state->cl->color = true; return new_option(state, arg); @@ -415,9 +427,9 @@ static struct expr *parse_literal(struct parser_state *state) { } else if (strcmp(arg, "-maxdepth") == 0) { return parse_depth(state, arg, &state->cl->maxdepth); } else if (strcmp(arg, "-mmin") == 0) { - return parse_test_icmp(state, arg, eval_mmin); + return parse_acmtime(state, arg, MTIME, MINUTES); } else if (strcmp(arg, "-mtime") == 0) { - return parse_test_icmp(state, arg, eval_mtime); + return parse_acmtime(state, arg, MTIME, DAYS); } else if (strcmp(arg, "-name") == 0) { return parse_test_sdata(state, arg, eval_name); } else if (strcmp(arg, "-path") == 0 || strcmp(arg, "-wholename") == 0) { |