From: Lennart Poettering Date: Tue, 9 Sep 2025 20:52:45 +0000 (+0200) Subject: repart: tweak byte value output X-Git-Tag: v259-rc1~490^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2f5fb752a6f5b19e279220238ef882ad3ecb8848;p=thirdparty%2Fsystemd.git repart: tweak byte value output So far, when outputing information about copy progress we'd suppress the digit after the dot if it is zero. That makes the progress bar a bit "jumpy", because sometimes there are two more character cells used than other times. Let's just always output one digit after the dot here hence, to avoid this. --- diff --git a/src/basic/format-util.c b/src/basic/format-util.c index 021ece9eeb8..4c601e553fe 100644 --- a/src/basic/format-util.c +++ b/src/basic/format-util.c @@ -39,7 +39,8 @@ char* format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag) { (t / table[i + 1].factor * 10 / table[n - 1].factor) % 10 : (t * 10 / table[i].factor) % 10; - if (FLAGS_SET(flag, FORMAT_BYTES_BELOW_POINT) && remainder > 0) + if (FLAGS_SET(flag, FORMAT_BYTES_ALWAYS_POINT) || + (FLAGS_SET(flag, FORMAT_BYTES_BELOW_POINT) && remainder > 0)) (void) snprintf(buf, l, "%" PRIu64 ".%" PRIu64 "%s", t / table[i].factor, diff --git a/src/basic/format-util.h b/src/basic/format-util.h index e42f788ce6f..ab3328e1d21 100644 --- a/src/basic/format-util.h +++ b/src/basic/format-util.h @@ -64,9 +64,10 @@ assert_cc(sizeof(gid_t) == sizeof(uint32_t)); #endif typedef enum { - FORMAT_BYTES_USE_IEC = 1 << 0, - FORMAT_BYTES_BELOW_POINT = 1 << 1, - FORMAT_BYTES_TRAILING_B = 1 << 2, + FORMAT_BYTES_USE_IEC = 1 << 0, /* use base 1024 rather than 1000 */ + FORMAT_BYTES_BELOW_POINT = 1 << 1, /* show one digit after the point, if non-zero */ + FORMAT_BYTES_ALWAYS_POINT = 1 << 2, /* show one digit after the point, always */ + FORMAT_BYTES_TRAILING_B = 1 << 3, /* suffix the expression with a "B" for "bytes" */ } FormatBytesFlag; #define FORMAT_BYTES_MAX 16U @@ -82,6 +83,7 @@ static inline char* format_bytes(char *buf, size_t l, uint64_t t) { * see C11 §6.5.2.5, and * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks */ #define FORMAT_BYTES(t) format_bytes((char[FORMAT_BYTES_MAX]){}, FORMAT_BYTES_MAX, t) -#define FORMAT_BYTES_FULL(t, flag) format_bytes_full((char[FORMAT_BYTES_MAX]){}, FORMAT_BYTES_MAX, t, flag) +#define FORMAT_BYTES_FULL(t, flags) format_bytes_full((char[FORMAT_BYTES_MAX]){}, FORMAT_BYTES_MAX, t, flags) +#define FORMAT_BYTES_WITH_POINT(t) format_bytes_full((char[FORMAT_BYTES_MAX]){}, FORMAT_BYTES_MAX, t, FORMAT_BYTES_USE_IEC|FORMAT_BYTES_ALWAYS_POINT|FORMAT_BYTES_TRAILING_B) #define FORMAT_BYTES_CGROUP_PROTECTION(t) (t == CGROUP_LIMIT_MAX ? "infinity" : FORMAT_BYTES(t)) diff --git a/src/repart/repart.c b/src/repart/repart.c index 1ffa9e9c3e2..5e312ce0861 100644 --- a/src/repart/repart.c +++ b/src/repart/repart.c @@ -5493,9 +5493,9 @@ static int progress_bytes(uint64_t n_bytes, uint64_t bps, void *userdata) { strna(p->copy_blocks_path), glyph(GLYPH_ARROW_RIGHT), strna(p->definition_path), - FORMAT_BYTES(p->copy_blocks_done), - FORMAT_BYTES(p->copy_blocks_size), - FORMAT_BYTES(bps)); + FORMAT_BYTES_WITH_POINT(p->copy_blocks_done), + FORMAT_BYTES_WITH_POINT(p->copy_blocks_size), + FORMAT_BYTES_WITH_POINT(bps)); else (void) draw_progress_barf( percent, @@ -5503,8 +5503,8 @@ static int progress_bytes(uint64_t n_bytes, uint64_t bps, void *userdata) { strna(p->copy_blocks_path), glyph(GLYPH_ARROW_RIGHT), strna(p->definition_path), - FORMAT_BYTES(p->copy_blocks_done), - FORMAT_BYTES(p->copy_blocks_size)); + FORMAT_BYTES_WITH_POINT(p->copy_blocks_done), + FORMAT_BYTES_WITH_POINT(p->copy_blocks_size)); p->last_percent = percent; diff --git a/src/test/test-format-util.c b/src/test/test-format-util.c index 0a95837dbef..1216180e117 100644 --- a/src/test/test-format-util.c +++ b/src/test/test-format-util.c @@ -28,32 +28,41 @@ assert_cc(DECIMAL_STR_MAX(signed char) == STRLEN("-127")+1); assert_cc(DECIMAL_STR_MAX(unsigned char) == STRLEN("255")+1); assert_cc(CONST_MAX(DECIMAL_STR_MAX(int8_t), STRLEN("xxx")) == 5); -static void test_format_bytes_one(uint64_t val, bool trailing_B, const char *iec_with_p, const char *iec_without_p, - const char *si_with_p, const char *si_without_p) { +static void test_format_bytes_one( + uint64_t val, + bool trailing_B, + const char *iec_with_p, + const char *iec_without_p, + const char *iec_always_p, + const char *si_with_p, + const char *si_without_p, + const char *si_always_p) { char buf[FORMAT_BYTES_MAX]; ASSERT_STREQ(format_bytes_full(buf, sizeof buf, val, FORMAT_BYTES_USE_IEC | FORMAT_BYTES_BELOW_POINT | (trailing_B ? FORMAT_BYTES_TRAILING_B : 0)), iec_with_p); ASSERT_STREQ(format_bytes_full(buf, sizeof buf, val, FORMAT_BYTES_USE_IEC | (trailing_B ? FORMAT_BYTES_TRAILING_B : 0)), iec_without_p); + ASSERT_STREQ(format_bytes_full(buf, sizeof buf, val, FORMAT_BYTES_USE_IEC | FORMAT_BYTES_ALWAYS_POINT | (trailing_B ? FORMAT_BYTES_TRAILING_B : 0)), iec_always_p); ASSERT_STREQ(format_bytes_full(buf, sizeof buf, val, FORMAT_BYTES_BELOW_POINT | (trailing_B ? FORMAT_BYTES_TRAILING_B : 0)), si_with_p); ASSERT_STREQ(format_bytes_full(buf, sizeof buf, val, trailing_B ? FORMAT_BYTES_TRAILING_B : 0), si_without_p); + ASSERT_STREQ(format_bytes_full(buf, sizeof buf, val, FORMAT_BYTES_ALWAYS_POINT | (trailing_B ? FORMAT_BYTES_TRAILING_B : 0)), si_always_p); } TEST(format_bytes) { - test_format_bytes_one(900, true, "900B", "900B", "900B", "900B"); - test_format_bytes_one(900, false, "900", "900", "900", "900"); - test_format_bytes_one(1023, true, "1023B", "1023B", "1K", "1K"); - test_format_bytes_one(1023, false, "1023", "1023", "1K", "1K"); - test_format_bytes_one(1024, true, "1K", "1K", "1K", "1K"); - test_format_bytes_one(1024, false, "1K", "1K", "1K", "1K"); - test_format_bytes_one(1100, true, "1K", "1K", "1.1K", "1K"); - test_format_bytes_one(1500, true, "1.4K", "1K", "1.5K", "1K"); - test_format_bytes_one(UINT64_C(3)*1024*1024, true, "3M", "3M", "3.1M", "3M"); - test_format_bytes_one(UINT64_C(3)*1024*1024*1024, true, "3G", "3G", "3.2G", "3G"); - test_format_bytes_one(UINT64_C(3)*1024*1024*1024*1024, true, "3T", "3T", "3.2T", "3T"); - test_format_bytes_one(UINT64_C(3)*1024*1024*1024*1024*1024, true, "3P", "3P", "3.3P", "3P"); - test_format_bytes_one(UINT64_C(3)*1024*1024*1024*1024*1024*1024, true, "3E", "3E", "3.4E", "3E"); - test_format_bytes_one(UINT64_MAX, true, NULL, NULL, NULL, NULL); - test_format_bytes_one(UINT64_MAX, false, NULL, NULL, NULL, NULL); + test_format_bytes_one(900, true, "900B", "900B", "900B", "900B", "900B", "900B"); + test_format_bytes_one(900, false, "900", "900", "900", "900", "900", "900"); + test_format_bytes_one(1023, true, "1023B", "1023B", "1023B", "1K", "1K", "1.0K"); + test_format_bytes_one(1023, false, "1023", "1023", "1023", "1K", "1K", "1.0K"); + test_format_bytes_one(1024, true, "1K", "1K", "1.0K", "1K", "1K", "1.0K"); + test_format_bytes_one(1024, false, "1K", "1K", "1.0K", "1K", "1K", "1.0K"); + test_format_bytes_one(1100, true, "1K", "1K", "1.0K", "1.1K", "1K", "1.1K"); + test_format_bytes_one(1500, true, "1.4K", "1K", "1.4K", "1.5K", "1K", "1.5K"); + test_format_bytes_one(UINT64_C(3)*1024*1024, true, "3M", "3M", "3.0M", "3.1M", "3M", "3.1M"); + test_format_bytes_one(UINT64_C(3)*1024*1024*1024, true, "3G", "3G", "3.0G", "3.2G", "3G", "3.2G"); + test_format_bytes_one(UINT64_C(3)*1024*1024*1024*1024, true, "3T", "3T", "3.0T", "3.2T", "3T", "3.2T"); + test_format_bytes_one(UINT64_C(3)*1024*1024*1024*1024*1024, true, "3P", "3P", "3.0P", "3.3P", "3P", "3.3P"); + test_format_bytes_one(UINT64_C(3)*1024*1024*1024*1024*1024*1024, true, "3E", "3E", "3.0E", "3.4E", "3E", "3.4E"); + test_format_bytes_one(UINT64_MAX, true, NULL, NULL, NULL, NULL, NULL, NULL); + test_format_bytes_one(UINT64_MAX, false, NULL, NULL, NULL, NULL, NULL, NULL); } DEFINE_TEST_MAIN(LOG_INFO);