From 0609e6f29719a7e88b8233d6bd5b75509a2d59f5 Mon Sep 17 00:00:00 2001
From: Tavian Barnes <tavianator@tavianator.com>
Date: Tue, 20 Dec 2016 21:23:02 -0500
Subject: Implement -sparse from FreeBSD find

---
 bfs.h   |  1 +
 eval.c  | 13 +++++++++++++
 parse.c |  8 ++++++++
 3 files changed, 22 insertions(+)

diff --git a/bfs.h b/bfs.h
index 22fee84..e391428 100644
--- a/bfs.h
+++ b/bfs.h
@@ -292,6 +292,7 @@ bool eval_inum(const struct expr *expr, struct eval_state *state);
 bool eval_links(const struct expr *expr, struct eval_state *state);
 bool eval_samefile(const struct expr *expr, struct eval_state *state);
 bool eval_size(const struct expr *expr, struct eval_state *state);
+bool eval_sparse(const struct expr *expr, struct eval_state *state);
 bool eval_type(const struct expr *expr, struct eval_state *state);
 bool eval_xtype(const struct expr *expr, struct eval_state *state);
 
diff --git a/eval.c b/eval.c
index b62c1b4..2497455 100644
--- a/eval.c
+++ b/eval.c
@@ -817,6 +817,19 @@ bool eval_size(const struct expr *expr, struct eval_state *state) {
 	return do_cmp(expr, size);
 }
 
+/**
+ * -sparse test.
+ */
+bool eval_sparse(const struct expr *expr, struct eval_state *state) {
+	const struct stat *statbuf = fill_statbuf(state);
+	if (!statbuf) {
+		return false;
+	}
+
+	blkcnt_t expected = (statbuf->st_size + 511)/512;
+	return statbuf->st_blocks < expected;
+}
+
 /**
  * -type test.
  */
diff --git a/parse.c b/parse.c
index 33f928b..64ed11b 100644
--- a/parse.c
+++ b/parse.c
@@ -1661,6 +1661,13 @@ fail:
 	return NULL;
 }
 
+/**
+ * Parse -sparse.
+ */
+static struct expr *parse_sparse(struct parser_state *state, int arg1, int arg2) {
+	return parse_nullary_test(state, eval_sparse);
+}
+
 /**
  * Parse -x?type [bcdpfls].
  */
@@ -1837,6 +1844,7 @@ static const struct table_entry parse_table[] = {
 	{"regextype", false, parse_regextype},
 	{"samefile", false, parse_samefile},
 	{"size", false, parse_size},
+	{"sparse", false, parse_sparse},
 	{"true", false, parse_const, true},
 	{"type", false, parse_type, false},
 	{"uid", false, parse_user},
-- 
cgit v1.2.3