libluna: Add more options to to_dynamic_unit()
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Also, make the output look more like how it is on linux.
This commit is contained in:
parent
a5ad8e16de
commit
5911b052dc
@ -63,6 +63,7 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
bool show_almost_all { false };
|
bool show_almost_all { false };
|
||||||
bool long_list { false };
|
bool long_list { false };
|
||||||
bool human_readable { false };
|
bool human_readable { false };
|
||||||
|
bool si { false };
|
||||||
|
|
||||||
os::ArgumentParser parser;
|
os::ArgumentParser parser;
|
||||||
parser.add_description("List files contained in a directory (defaults to '.', the current directory)"_sv);
|
parser.add_description("List files contained in a directory (defaults to '.', the current directory)"_sv);
|
||||||
@ -73,6 +74,7 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
parser.add_switch_argument(long_list, 'l', ""_sv, "use a long listing format"_sv);
|
parser.add_switch_argument(long_list, 'l', ""_sv, "use a long listing format"_sv);
|
||||||
parser.add_switch_argument(human_readable, 'h', "human-readable"_sv,
|
parser.add_switch_argument(human_readable, 'h', "human-readable"_sv,
|
||||||
"with -l, show human-readable sizes e.g. 2KiB, 6GiB"_sv);
|
"with -l, show human-readable sizes e.g. 2KiB, 6GiB"_sv);
|
||||||
|
parser.add_switch_argument(si, ' ', "si"_sv, "same as -h, but show sizes in powers of 10"_sv);
|
||||||
parser.parse(argc, argv);
|
parser.parse(argc, argv);
|
||||||
|
|
||||||
Vector<String> files;
|
Vector<String> files;
|
||||||
@ -116,15 +118,15 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
|
|
||||||
TRY(find_user_and_group(st, owner, group));
|
TRY(find_user_and_group(st, owner, group));
|
||||||
|
|
||||||
if (!human_readable)
|
if (!human_readable && !si)
|
||||||
{
|
{
|
||||||
os::println("%6o %u %4s %4s %10lu %s", st.st_mode, st.st_nlink, owner.chars(), group.chars(),
|
os::println("%6o %u %4s %4s %10lu %s", st.st_mode, st.st_nlink, owner.chars(), group.chars(),
|
||||||
st.st_size, file.chars());
|
st.st_size, file.chars());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto size = TRY(to_dynamic_unit(st.st_size));
|
auto size = TRY(to_dynamic_unit(st.st_size, 10, false, si ? Unit::SI : Unit::Binary, false));
|
||||||
os::println("%6o %u %4s %4s %10s %s", st.st_mode, st.st_nlink, owner.chars(), group.chars(),
|
os::println("%6o %u %4s %4s %6s %s", st.st_mode, st.st_nlink, owner.chars(), group.chars(),
|
||||||
size.chars(), file.chars());
|
size.chars(), file.chars());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,11 @@
|
|||||||
#include <luna/Result.h>
|
#include <luna/Result.h>
|
||||||
#include <luna/String.h>
|
#include <luna/String.h>
|
||||||
|
|
||||||
Result<String> to_dynamic_unit(usize value);
|
enum class Unit : usize
|
||||||
|
{
|
||||||
|
SI = 1000,
|
||||||
|
Binary = 1024
|
||||||
|
};
|
||||||
|
|
||||||
|
Result<String> to_dynamic_unit(usize value, usize round_after = 1000, bool separate = true, Unit unit = Unit::Binary,
|
||||||
|
bool display_unit = true);
|
||||||
|
@ -1,18 +1,44 @@
|
|||||||
#include <luna/Alloc.h>
|
#include <luna/Alloc.h>
|
||||||
|
#include <luna/CType.h>
|
||||||
#include <luna/Result.h>
|
#include <luna/Result.h>
|
||||||
#include <luna/ScopeGuard.h>
|
#include <luna/ScopeGuard.h>
|
||||||
#include <luna/Units.h>
|
#include <luna/Units.h>
|
||||||
|
|
||||||
Result<String> to_dynamic_unit(usize value)
|
Result<String> to_dynamic_unit(usize value, usize round_after, bool separate, Unit unit, bool display_unit)
|
||||||
{
|
{
|
||||||
if (value < 1024) { return String::format("%zu bytes"_sv, value); }
|
const usize multiplier = (usize)unit;
|
||||||
|
if (value < multiplier) { return String::format("%zu%s"_sv, value, display_unit ? " bytes" : ""); }
|
||||||
|
|
||||||
|
bool si = unit == Unit::SI;
|
||||||
|
|
||||||
const char* unit_prefixes = "KMGTPE";
|
const char* unit_prefixes = "KMGTPE";
|
||||||
while (value > (1024 * 1024))
|
if (si) unit_prefixes = "kMGTPE";
|
||||||
|
while (value > (multiplier * multiplier))
|
||||||
{
|
{
|
||||||
value /= 1024;
|
value /= multiplier;
|
||||||
unit_prefixes++;
|
unit_prefixes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return String::format("%zu.%zu %ciB"_sv, value / 1024, (value % 1024) / 103, *unit_prefixes);
|
const usize divider = (si ? 100 : 103);
|
||||||
|
|
||||||
|
usize fixed = value / multiplier;
|
||||||
|
usize rest = (value % multiplier) / divider;
|
||||||
|
bool round = fixed >= round_after;
|
||||||
|
|
||||||
|
if (round)
|
||||||
|
{
|
||||||
|
if (value % multiplier) fixed++;
|
||||||
|
return String::format("%zu%s%c%s"_sv, fixed, separate ? " " : "", *unit_prefixes,
|
||||||
|
display_unit ? (si ? "B" : "iB") : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((value % multiplier) % divider) rest++;
|
||||||
|
if (rest > 9)
|
||||||
|
{
|
||||||
|
rest = 0;
|
||||||
|
fixed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return String::format("%zu.%zu%s%c%s"_sv, fixed, rest, separate ? " " : "", *unit_prefixes,
|
||||||
|
display_unit ? (si ? "B" : "iB") : "");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user