]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
repart: tweak byte value output 38995/head
authorLennart Poettering <lennart@poettering.net>
Tue, 9 Sep 2025 20:52:45 +0000 (22:52 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 19 Sep 2025 14:46:07 +0000 (16:46 +0200)
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.

src/basic/format-util.c
src/basic/format-util.h
src/repart/repart.c
src/test/test-format-util.c

index 021ece9eeb860cccbd017e2a358653975f9b7829..4c601e553feb446c95328289618bdbd4d6ce0d17 100644 (file)
@@ -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,
index e42f788ce6f26b2893e71c5ca88e15b08f814882..ab3328e1d21efadf02841edba9e2ab2403c52af9 100644 (file)
@@ -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))
index 1ffa9e9c3e20a8e241963412f905a41dfe326fe1..5e312ce0861e296557f9d8d2396bd925239be388 100644 (file)
@@ -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;
 
index 0a95837dbef2c3415fce0ce2b9f6822bfa2b5acd..1216180e1178fea07eaa31f91216629f1a3ff6b8 100644 (file)
@@ -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);