1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 07:47:37 +00:00

find: Allow unit suffixes to be used with the -size option

The argument supplied to the `-size` option may now be one of the
following suffixes:

* b: 512-byte blocks. This is the default unit if no suffix is used.
* c: bytes
* w: two-byte words
* k: kibibytes (1024 bytes)
* M: mebibytes (1024 kibibytes)
* G: gibibytes (1024 mebibytes)

Sizes are rounded to the specified unit before comparison. The unit
suffixes are case-sensitive.
This commit is contained in:
Tim Ledbetter 2023-08-28 22:01:10 +01:00 committed by Andrew Kaster
parent 9b884a9605
commit aa7c2f1f0d
2 changed files with 46 additions and 14 deletions

View file

@ -226,28 +226,51 @@ public:
SizeCommand(char const* arg)
{
StringView view { arg, strlen(arg) };
if (view.ends_with('c')) {
m_is_bytes = true;
auto suffix = view[view.length() - 1];
if (!is_ascii_digit(suffix)) {
switch (suffix) {
case 'c':
m_unit_size = 1;
break;
case 'w':
m_unit_size = 2;
break;
case 'k':
m_unit_size = KiB;
break;
case 'M':
m_unit_size = MiB;
break;
case 'G':
m_unit_size = GiB;
break;
case 'b':
// The behavior of this suffix is the same as no suffix.
break;
default:
fatal_error("Invalid -size type '{}'", suffix);
}
view = view.substring_view(0, view.length() - 1);
}
auto number = view.to_uint();
if (!number.has_value())
auto number = view.to_uint<u64>();
if (!number.has_value() || number.value() > AK::NumericLimits<off_t>::max())
fatal_error("Invalid size: \033[1m{}", arg);
m_size = number.value();
m_number_of_units = number.value();
}
private:
virtual bool evaluate(const struct stat& stat) const override
{
if (m_is_bytes)
return stat.st_size == m_size;
if (m_unit_size == 1)
return stat.st_size == m_number_of_units;
auto size_divided_by_512_rounded_up = (stat.st_size + 511) / 512;
return size_divided_by_512_rounded_up == m_size;
auto size_divided_by_unit_rounded_up = (stat.st_size + m_unit_size - 1) / m_unit_size;
return size_divided_by_unit_rounded_up == m_number_of_units;
}
off_t m_size { 0 };
bool m_is_bytes { false };
off_t m_number_of_units { 0 };
off_t m_unit_size { 512 };
};
class NameCommand : public Command {