summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2021-03-06 13:40:24 -0500
committerTavian Barnes <tavianator@tavianator.com>2021-03-06 13:40:24 -0500
commit863b70d198f62f28581162473a521208dd67879e (patch)
tree9506283742eef1951ecaa897f4584b3941499a51 /eval.c
parent8f201b2380aef3a566316343e7e71c6fc995cf41 (diff)
downloadbfs-863b70d198f62f28581162473a521208dd67879e.tar.xz
Implement -flags, from FreeBSD find
This is the last BSD-specific primary I'm aware of. Fixes #14.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/eval.c b/eval.c
index a72be86..df047f0 100644
--- a/eval.c
+++ b/eval.c
@@ -442,6 +442,39 @@ done:
}
/**
+ * -flags test.
+ */
+bool eval_flags(const struct expr *expr, struct eval_state *state) {
+ const struct bfs_stat *statbuf = eval_stat(state);
+ if (!statbuf) {
+ return false;
+ }
+
+ if (!(statbuf->mask & BFS_STAT_ATTRS)) {
+ eval_error(state, "Couldn't get file %s.\n", bfs_stat_field_name(BFS_STAT_ATTRS));
+ return false;
+ }
+
+ unsigned long flags = statbuf->attrs;
+ unsigned long set = expr->set_flags;
+ unsigned long clear = expr->clear_flags;
+
+ switch (expr->mode_cmp) {
+ case MODE_EXACT:
+ return flags == set && !(flags & clear);
+
+ case MODE_ALL:
+ return (flags & set) == set && !(flags & clear);
+
+ case MODE_ANY:
+ return (flags & set) || (flags & clear) != clear;
+ }
+
+ assert(!"Invalid comparison mode");
+ return false;
+}
+
+/**
* -fstype test.
*/
bool eval_fstype(const struct expr *expr, struct eval_state *state) {
@@ -590,6 +623,7 @@ bool eval_perm(const struct expr *expr, struct eval_state *state) {
return !(mode & target) == !target;
}
+ assert(!"Invalid comparison mode");
return false;
}