diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2022-05-09 20:51:07 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2022-05-20 13:54:46 -0400 |
commit | 6790c202cebf315e7eda1829ef64e871d5d7b316 (patch) | |
tree | 49c065fd0326fac5a85c96fc22a6312b96d1e5c3 | |
parent | ee99ff04cf54f6416e105308eb7d2e9da7142bd7 (diff) |
lib/printbuf: Unit specifiers
This adds options to printbuf for specifying whether units should be
printed raw (default) or with human readable units, and for controlling
whether human-readable units should be base 2 (default), or base 10.
This also adds new helpers that obey these options:
- pr_human_readable_u64
- pr_human_readable_s64
These obey printbuf->si_units
- pr_units_u64
- pr_units_s64
These obey both printbuf-human_readable_units and printbuf->si_units
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | include/linux/printbuf.h | 15 | ||||
-rw-r--r-- | lib/printbuf.c | 57 |
2 files changed, 72 insertions, 0 deletions
diff --git a/include/linux/printbuf.h b/include/linux/printbuf.h index 798e067457b0..c7919ae72105 100644 --- a/include/linux/printbuf.h +++ b/include/linux/printbuf.h @@ -53,10 +53,19 @@ * * Make sure you use pr_newline() instead of \n in the format string for indent * level and tabstops to work corretly. + * + * Output units: printbuf->units exists to tell pretty-printers how to output + * numbers: a raw value (e.g. directly from a superblock field), as bytes, or as + * human readable bytes. pr_units() and pr_sectors() obey it. */ #include <linux/string.h> +enum printbuf_si { + PRINTBUF_UNITS_2, /* use binary powers of 2^10 */ + PRINTBUF_UNITS_10, /* use powers of 10^3 (standard SI) */ +}; + struct printbuf { char *buf; unsigned size; @@ -70,6 +79,8 @@ struct printbuf { u8 atomic; bool allocation_failure:1; bool heap_allocated:1; + enum printbuf_si si_units:1; + bool human_readable_units:1; u8 tabstop; u8 tabstops[4]; }; @@ -83,6 +94,10 @@ void pr_indent_add(struct printbuf *, unsigned); void pr_indent_sub(struct printbuf *, unsigned); void pr_tab(struct printbuf *); void pr_tab_rjust(struct printbuf *); +void pr_human_readable_u64(struct printbuf *, u64); +void pr_human_readable_s64(struct printbuf *, s64); +void pr_units_u64(struct printbuf *, u64); +void pr_units_s64(struct printbuf *, s64); /* Initializer for a heap allocated printbuf: */ #define PRINTBUF ((struct printbuf) { .heap_allocated = true }) diff --git a/lib/printbuf.c b/lib/printbuf.c index 519b32decee7..66879f165c74 100644 --- a/lib/printbuf.c +++ b/lib/printbuf.c @@ -9,6 +9,7 @@ #endif #include <linux/slab.h> +#include <linux/string_helpers.h> #include <linux/printbuf.h> static inline size_t printbuf_linelen(struct printbuf *buf) @@ -193,3 +194,59 @@ void pr_tab_rjust(struct printbuf *buf) buf->tabstop++; } EXPORT_SYMBOL(pr_tab_rjust); + +/** + * pr_human_readable_u64 - Print out a u64 in human readable units + * + * Units of 2^10 (default) or 10^3 are controlled via @buf->si_units + */ +void pr_human_readable_u64(struct printbuf *buf, u64 v) +{ + printbuf_make_room(buf, 10); + buf->pos += string_get_size(v, 1, !buf->si_units, + buf->buf + buf->pos, + printbuf_remaining(buf)); +} +EXPORT_SYMBOL(pr_human_readable_u64); + +/** + * pr_human_readable_s64 - Print out a s64 in human readable units + * + * Units of 2^10 (default) or 10^3 are controlled via @buf->si_units + */ +void pr_human_readable_s64(struct printbuf *buf, s64 v) +{ + if (v < 0) + pr_char(buf, '-'); + pr_human_readable_u64(buf, abs(v)); +} +EXPORT_SYMBOL(pr_human_readable_s64); + +/** + * pr_human_readable_u64 - Print out a u64 according to printbuf unit options + * + * Units are either raw (default), or human reabable units (controlled via + * @buf->human_readable_units) + */ +void pr_units_u64(struct printbuf *out, u64 v) +{ + if (out->human_readable_units) + pr_human_readable_u64(out, v); + else + pr_buf(out, "%llu", v); +} +EXPORT_SYMBOL(pr_units_u64); + +/** + * pr_human_readable_s64 - Print out a s64 according to printbuf unit options + * + * Units are either raw (default), or human reabable units (controlled via + * @buf->human_readable_units) + */ +void pr_units_s64(struct printbuf *out, s64 v) +{ + if (v < 0) + pr_char(out, '-'); + pr_units_u64(out, abs(v)); +} +EXPORT_SYMBOL(pr_units_s64); |