roken: Fix parse flags bug

This commit is contained in:
Nicolas Williams
2021-06-22 12:54:32 -05:00
parent 1870584d22
commit f6ac4ee864

View File

@@ -190,9 +190,10 @@ parse_flags (const char *s, const struct units *units,
*/ */
static int static int
unparse_something (int num, const struct units *units, char *s, size_t len, unparse_something (int64_t num, const struct units *units, char *s, size_t len,
int (*print) (char *, size_t, int, const char *, int), long long (*get_divisor) (long long, unsigned long long),
int (*update) (int, unsigned), int (*print) (char *, size_t, long long, const char *, int),
int (*update) (long long, unsigned long long),
const char *zero_string) const char *zero_string)
{ {
const struct units *u; const struct units *u;
@@ -202,9 +203,8 @@ unparse_something (int num, const struct units *units, char *s, size_t len,
return snprintf (s, len, "%s", zero_string); return snprintf (s, len, "%s", zero_string);
for (u = units; num > 0 && u->name; ++u) { for (u = units; num > 0 && u->name; ++u) {
int divisor; long long divisor = get_divisor(num, u->mult);
divisor = num / u->mult;
if (divisor) { if (divisor) {
num = (*update) (num, u->mult); num = (*update) (num, u->mult);
tmp = (*print) (s, len, divisor, u->name, num); tmp = (*print) (s, len, divisor, u->name, num);
@@ -224,22 +224,28 @@ unparse_something (int num, const struct units *units, char *s, size_t len,
} }
static int static int
print_unit (char *s, size_t len, int divisor, const char *name, int rem) print_unit(char *s, size_t len, long long divisor, const char *name, int rem)
{ {
return snprintf (s, len, "%u %s%s%s", return snprintf (s, len, "%lld %s%s%s",
divisor, name, divisor, name,
divisor == 1 ? "" : "s", divisor == 1 ? "" : "s",
rem > 0 ? " " : ""); rem > 0 ? " " : "");
} }
static long long
get_divisor_unit(long long in, unsigned long long mult)
{
return in / mult;
}
static int static int
update_unit (int in, unsigned mult) update_unit(long long in, unsigned long long mult)
{ {
return in % mult; return in % mult;
} }
static int static int
update_unit_approx (int in, unsigned mult) update_unit_approx (long long in, unsigned long long mult)
{ {
if (in / mult > 0) if (in / mult > 0)
return 0; return 0;
@@ -251,6 +257,7 @@ ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
unparse_units (int num, const struct units *units, char *s, size_t len) unparse_units (int num, const struct units *units, char *s, size_t len)
{ {
return unparse_something (num, units, s, len, return unparse_something (num, units, s, len,
get_divisor_unit,
print_unit, print_unit,
update_unit, update_unit,
"0"); "0");
@@ -260,6 +267,7 @@ ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
unparse_units_approx (int num, const struct units *units, char *s, size_t len) unparse_units_approx (int num, const struct units *units, char *s, size_t len)
{ {
return unparse_something (num, units, s, len, return unparse_something (num, units, s, len,
get_divisor_unit,
print_unit, print_unit,
update_unit_approx, update_unit_approx,
"0"); "0");
@@ -298,22 +306,29 @@ print_units_table (const struct units *units, FILE *f)
} }
} }
static long long
get_divisor_flag(long long in, unsigned long long mult)
{
return in & mult;
}
static int static int
print_flag (char *s, size_t len, int divisor, const char *name, int rem) print_flag (char *s, size_t len, long long divisor, const char *name, int rem)
{ {
return snprintf (s, len, "%s%s", name, rem > 0 ? ", " : ""); return snprintf (s, len, "%s%s", name, rem > 0 ? ", " : "");
} }
static int static int
update_flag (int in, unsigned mult) update_flag (long long in, unsigned long long mult)
{ {
return in - mult; return in & ~mult;
} }
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
unparse_flags (int num, const struct units *units, char *s, size_t len) unparse_flags (int num, const struct units *units, char *s, size_t len)
{ {
return unparse_something (num, units, s, len, return unparse_something (num, units, s, len,
get_divisor_flag,
print_flag, print_flag,
update_flag, update_flag,
""); "");