summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bfs.h35
-rw-r--r--eval.c101
-rw-r--r--parse.c24
3 files changed, 68 insertions, 92 deletions
diff --git a/bfs.h b/bfs.h
index 15f25ee..bf33a33 100644
--- a/bfs.h
+++ b/bfs.h
@@ -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);
diff --git a/eval.c b/eval.c
index 7de11bf..258857c 100644
--- a/eval.c
+++ b/eval.c
@@ -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);
}
/**
diff --git a/parse.c b/parse.c
index a64f32c..4f6f987 100644
--- a/parse.c
+++ b/parse.c
@@ -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) {