Follow-up Comment #31, bug #12162 (project findutils): >I am totally happy with -filesize option suggestion, yet, it would be >important to also have comparing bigger, smaller or equal. >How would you solve this?
>I suggest: >-size lt 1M: less than one MiB (< 1048576 bytes, 1048575 matches 1048576 does not match) >-size lte 1M: less than or equal one MiB (<= 1048576 bytes) >-size gt 1M: more than one MiB (> 1048576 bytes) >-size gte 1M: more or equal than one MiB (>= 1048576 bytes) >-size eq 1M: exactly one MiB (=1048576 bytes) Your suggestion is interesting and more ambitious. So far i have restricted myself to bring the behaviour that many people are looking for, causing most of the bug reports/stackoverflow questions: A new predicate size without rounding. (Once we have this solved we always could think how to extend these predicates to allow things as <= or >=). I follow the Nigel suggestion (#16 in this thread). Below is my patch: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >From 6ec1877385228aa5cd540c26fbebf09ba283654b Mon Sep 17 00:00:00 2001 From: Tino Calancha <tino.calan...@gmail.com> Date: Fri, 8 Jul 2016 13:01:54 +0900 Subject: [PATCH 1/4] Merge with remote rep --- gnulib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnulib b/gnulib index 97173b2..0ef1689 160000 --- a/gnulib +++ b/gnulib @@ -1 +1 @@ -Subproject commit 97173b26d27d9f31de1789e994dfe014e3a40162 +Subproject commit 0ef1689f914462d778c5e279dfc48702fecbabbf -- 2.8.1 >From 897fe8422701651af0c022aff797ff3aec5ff14d Mon Sep 17 00:00:00 2001 From: Tino Calancha <tino.calan...@gmail.com> Date: Fri, 8 Jul 2016 14:39:27 +0900 Subject: [PATCH 2/4] Predicate size without rounding * find/defs.h: New predicate filesize; as predicate size but without rounding (Bug#12162). * find/parser.c: Idem. * find/pred.c: Idem. * find/tree.c: Idem. --- find/defs.h | 1 + find/parser.c | 15 +++++++++++---- find/pred.c | 28 ++++++++++++++++++++++++++++ find/tree.c | 1 + 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/find/defs.h b/find/defs.h index 52e522f..66e2648 100644 --- a/find/defs.h +++ b/find/defs.h @@ -464,6 +464,7 @@ PREDICATEFUNCTION pred_readable; PREDICATEFUNCTION pred_regex; PREDICATEFUNCTION pred_samefile; PREDICATEFUNCTION pred_size; +PREDICATEFUNCTION pred_filesize; PREDICATEFUNCTION pred_true; PREDICATEFUNCTION pred_type; PREDICATEFUNCTION pred_uid; diff --git a/find/parser.c b/find/parser.c index 3ed5c31..e1e5800 100644 --- a/find/parser.c +++ b/find/parser.c @@ -138,6 +138,7 @@ static bool parse_regex (const struct parser_table*, char *argv[], int * static bool parse_regextype (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_samefile (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_size (const struct parser_table*, char *argv[], int *arg_ptr); +static bool parse_filesize (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_time (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_true (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_type (const struct parser_table*, char *argv[], int *arg_ptr); @@ -303,6 +304,7 @@ static struct parser_table const parse_table[] = PARSE_OPTION ("show-control-chars", show_control_chars), /* GNU, 4.3.0+ */ #endif PARSE_TEST ("size", size), /* POSIX */ + PARSE_TEST ("filesize", filesize), /* GNU */ PARSE_TEST ("type", type), /* POSIX */ PARSE_TEST ("uid", uid), /* GNU */ PARSE_TEST ("used", used), /* GNU */ @@ -2129,7 +2131,7 @@ parse_size (const struct parser_table* entry, char **argv, int *arg_ptr) len = strlen (arg); if (len == 0) - error (EXIT_FAILURE, 0, _("invalid null argument to -size")); + error (EXIT_FAILURE, 0, _("invalid null argument to %s"), argv[*arg_ptr - 1]); suffix = arg[len - 1]; switch (suffix) @@ -2179,7 +2181,7 @@ parse_size (const struct parser_table* entry, char **argv, int *arg_ptr) default: error (EXIT_FAILURE, 0, - _("invalid -size type `%c'"), argv[*arg_ptr][len - 1]); + _("invalid %s type `%c'"), argv[*arg_ptr - 1], argv[*arg_ptr][len - 1]); } /* TODO: accept fractional megabytes etc. ? */ if (!get_num (arg, &num, &c_type)) @@ -2189,8 +2191,8 @@ parse_size (const struct parser_table* entry, char **argv, int *arg_ptr) tail[1] = 0; error (EXIT_FAILURE, 0, - _("Invalid argument `%s%s' to -size"), - arg, tail); + _("Invalid argument `%s%s' to %s"), + arg, tail, argv[*arg_ptr - 1]); return false; } our_pred = insert_primary (entry, arg); @@ -2211,6 +2213,11 @@ parse_size (const struct parser_table* entry, char **argv, int *arg_ptr) return true; } +static bool +parse_filesize (const struct parser_table* entry, char **argv, int *arg_ptr) +{ + return parse_size (entry, argv, arg_ptr); +} static bool parse_samefile (const struct parser_table* entry, char **argv, int *arg_ptr) diff --git a/find/pred.c b/find/pred.c index f7e9b59..f4a4636 100644 --- a/find/pred.c +++ b/find/pred.c @@ -128,6 +128,7 @@ struct pred_assoc pred_table[] = {pred_regex, "regex "}, {pred_samefile,"samefile "}, {pred_size, "size "}, + {pred_filesize, "filesize "}, {pred_true, "true "}, {pred_type, "type "}, {pred_uid, "uid "}, @@ -979,6 +980,33 @@ pred_size (const char *pathname, struct stat *stat_buf, struct predicate *pred_p } bool +pred_filesize (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) +{ + uintmax_t f_val; + + (void) pathname; + f_val = (stat_buf->st_size / pred_ptr->args.size.blocksize); + if (f_val == pred_ptr->args.size.size) + f_val = f_val + (stat_buf->st_size % pred_ptr->args.size.blocksize != 0); + switch (pred_ptr->args.size.kind) + { + case COMP_GT: + if (f_val > pred_ptr->args.size.size) + return (true); + break; + case COMP_LT: + if (f_val < pred_ptr->args.size.size) + return (true); + break; + case COMP_EQ: + if (f_val == pred_ptr->args.size.size) + return (true); + break; + } + return (false); +} + +bool pred_samefile (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) { /* Potential optimisation: because of the loop protection, we always diff --git a/find/tree.c b/find/tree.c index 2bbfbe5..e404721 100644 --- a/find/tree.c +++ b/find/tree.c @@ -980,6 +980,7 @@ static struct pred_cost_lookup costlookup[] = { pred_regex , NeedsNothing }, { pred_samefile , NeedsStatInfo }, { pred_size , NeedsStatInfo }, + { pred_filesize , NeedsStatInfo }, { pred_true , NeedsNothing }, { pred_type , NeedsType }, { pred_uid , NeedsStatInfo }, -- 2.8.1 >From 44c5e3486d2948e4a24070a7eec323ddc20d8d70 Mon Sep 17 00:00:00 2001 From: Tino Calancha <tino.calan...@gmail.com> Date: Fri, 8 Jul 2016 14:58:04 +0900 Subject: [PATCH 3/4] * doc/find.texi (2.4 size): Document predicate filesize --- doc/find.texi | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/find.texi b/doc/find.texi index b3c5d10..812369a 100644 --- a/doc/find.texi +++ b/doc/find.texi @@ -1037,8 +1037,9 @@ indicates that the test should succeed if the file uses less than @var{n} units of storage. Bear in mind that the size is rounded up to the next unit. Therefore @samp{-size -1M} is not equivalent to @samp{-size -1048576c}. The former only matches empty files, the latter -matches files from 1 to 1,048,575 bytes. There is no `=' prefix, because -that's the default anyway. +matches files from 1 to 1,048,575 bytes. If you prefer that the size +not be rounded you may want to use predicate @samp{-filesize}. +There is no `=' prefix, because that's the default anyway. The size does not count indirect blocks, but it does count blocks in sparse files that are not actually allocated. In other words, it's @@ -1048,6 +1049,10 @@ and @samp{%b} format specifiers for the @samp{-printf} predicate. @end deffn +@deffn Test -filesize n@r{[}bckwMG@r{]} +Same as test @samp{-size} but the size is not rounded up to the next unit. +@end deffn + @deffn Test -empty True if the file is empty and is either a regular file or a directory. This might help determine good candidates for deletion. This test is -- 2.8.1 >From f8d116b8f652ef4b806f2bcd798cf7be9ba49d35 Mon Sep 17 00:00:00 2001 From: Tino Calancha <tino.calan...@gmail.com> Date: Fri, 8 Jul 2016 15:31:25 +0900 Subject: [PATCH 4/4] Predicate blocksize alias to predicate size * find/defs.h: New predicate blocksize; alias to predicate size (Bug#12162). * find/parser.c: Idem. * find/pred.c: Idem. * find/tree.c: Idem. * doc/find.texi (2.4 size): Document predicate blocksize; mention that filesize is a GNU extension. --- doc/find.texi | 5 +++++ find/defs.h | 1 + find/parser.c | 8 ++++++++ find/pred.c | 7 +++++++ find/tree.c | 1 + 5 files changed, 22 insertions(+) diff --git a/doc/find.texi b/doc/find.texi index 812369a..281ba70 100644 --- a/doc/find.texi +++ b/doc/find.texi @@ -1049,8 +1049,13 @@ and @samp{%b} format specifiers for the @samp{-printf} predicate. @end deffn +@deffn Test -blocksize n@r{[}bckwMG@r{]} +Same as test @samp{-size}, but not POSIX compliant. +@end deffn + @deffn Test -filesize n@r{[}bckwMG@r{]} Same as test @samp{-size} but the size is not rounded up to the next unit. +This is a GNU extension. @end deffn @deffn Test -empty diff --git a/find/defs.h b/find/defs.h index 66e2648..a850c79 100644 --- a/find/defs.h +++ b/find/defs.h @@ -464,6 +464,7 @@ PREDICATEFUNCTION pred_readable; PREDICATEFUNCTION pred_regex; PREDICATEFUNCTION pred_samefile; PREDICATEFUNCTION pred_size; +PREDICATEFUNCTION pred_blocksize; PREDICATEFUNCTION pred_filesize; PREDICATEFUNCTION pred_true; PREDICATEFUNCTION pred_type; diff --git a/find/parser.c b/find/parser.c index e1e5800..b186bc8 100644 --- a/find/parser.c +++ b/find/parser.c @@ -138,6 +138,7 @@ static bool parse_regex (const struct parser_table*, char *argv[], int * static bool parse_regextype (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_samefile (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_size (const struct parser_table*, char *argv[], int *arg_ptr); +static bool parse_blocksize (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_filesize (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_time (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_true (const struct parser_table*, char *argv[], int *arg_ptr); @@ -304,6 +305,7 @@ static struct parser_table const parse_table[] = PARSE_OPTION ("show-control-chars", show_control_chars), /* GNU, 4.3.0+ */ #endif PARSE_TEST ("size", size), /* POSIX */ + PARSE_TEST ("blocksize", blocksize), /* GNU */ PARSE_TEST ("filesize", filesize), /* GNU */ PARSE_TEST ("type", type), /* POSIX */ PARSE_TEST ("uid", uid), /* GNU */ @@ -2214,6 +2216,12 @@ parse_size (const struct parser_table* entry, char **argv, int *arg_ptr) } static bool +parse_blocksize (const struct parser_table* entry, char **argv, int *arg_ptr) +{ + return parse_size (entry, argv, arg_ptr); +} + +static bool parse_filesize (const struct parser_table* entry, char **argv, int *arg_ptr) { return parse_size (entry, argv, arg_ptr); diff --git a/find/pred.c b/find/pred.c index f4a4636..32a2281 100644 --- a/find/pred.c +++ b/find/pred.c @@ -128,6 +128,7 @@ struct pred_assoc pred_table[] = {pred_regex, "regex "}, {pred_samefile,"samefile "}, {pred_size, "size "}, + {pred_blocksize, "blocksize "}, {pred_filesize, "filesize "}, {pred_true, "true "}, {pred_type, "type "}, @@ -980,6 +981,12 @@ pred_size (const char *pathname, struct stat *stat_buf, struct predicate *pred_p } bool +pred_blocksize (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) +{ + return pred_size (pathname, stat_buf, pred_ptr); +} + +bool pred_filesize (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) { uintmax_t f_val; diff --git a/find/tree.c b/find/tree.c index e404721..c5d2ee4 100644 --- a/find/tree.c +++ b/find/tree.c @@ -980,6 +980,7 @@ static struct pred_cost_lookup costlookup[] = { pred_regex , NeedsNothing }, { pred_samefile , NeedsStatInfo }, { pred_size , NeedsStatInfo }, + { pred_blocksize , NeedsStatInfo }, { pred_filesize , NeedsStatInfo }, { pred_true , NeedsNothing }, { pred_type , NeedsType }, -- 2.8.1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; find (GNU findutils) 4.7.0-git Repository revision: 155c9d1c229aa5d12b6e8919516fd6331a28ba1e _______________________________________________________ Reply to this item at: <http://savannah.gnu.org/bugs/?12162> _______________________________________________ Message sent via/by Savannah http://savannah.gnu.org/