Description: Improve the "pretty size" display (bytes size display).
 Patch initially written on 2020-04-24, and fixed on 2024-07-10.
 The issue is that mutt_pretty_size is used in different contexts,
 where one may want different behaviors. To make the patch simpler,
 let's assume that one wants small sizes in bytes in general, except
 for the index display (index_format), where space is more limited
 and unsetting $size_show_bytes allows one to get rid of the "K".
 Note that one must not get rid of the "K" everywhere; for instance,
 in handler.c:
          mutt_pretty_size (pretty_size, sizeof (pretty_size),
                            strtol (length, NULL, 10), 1);
          state_printf (s, _("(size %s bytes) "), pretty_size);
 where "%s bytes" would be wrong with the implicit kilobyte unit.
 Moreover, in the multipart_handler function of handler.c, the size
 of the "length" buffer had to be increased to avoid truncation of
 the output (this is a bug independent of this patch).
Author: Vincent Lefevre <vincent@vinc17.net>
Last-Update: 2024-07-10

diff --git a/PATCHES b/PATCHES
index e69de29b..88c2d4e4 100644
--- a/PATCHES
+++ b/PATCHES
@@ -0,0 +1,1 @@
+patch-20240710.vl.pretty_size.2
diff --git a/browser.c b/browser.c
index a4566395..aa9387ef 100644
--- a/browser.c
+++ b/browser.c
@@ -431,7 +431,7 @@ folder_format_str (char *dest, size_t destlen, size_t col, int cols, char op, co
     case 's':
       if (folder->ff->local)
       {
-	mutt_pretty_size(fn, sizeof(fn), folder->ff->size);
+	mutt_pretty_size(fn, sizeof(fn), folder->ff->size, 1);
 	snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
 	snprintf (dest, destlen, tmp, fn);
       }
diff --git a/compose.c b/compose.c
index 4bde12c3..29923cac 100644
--- a/compose.c
+++ b/compose.c
@@ -956,7 +956,7 @@ compose_format_str (char *buf, size_t buflen, size_t col, int cols, char op, con
 
     case 'l': /* approx length of current message in bytes */
       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
-      mutt_pretty_size (tmp, sizeof (tmp), menu ? cum_attachs_size(menu) : 0);
+      mutt_pretty_size (tmp, sizeof (tmp), menu ? cum_attachs_size(menu) : 0, 1);
       snprintf (buf, buflen, fmt, tmp);
       break;
 
diff --git a/curs_lib.c b/curs_lib.c
index 246cb6be..de742aec 100644
--- a/curs_lib.c
+++ b/curs_lib.c
@@ -698,7 +698,7 @@ void mutt_progress_init (progress_t* progress, const char *msg,
   {
     if (progress->flags & MUTT_PROGRESS_SIZE)
       mutt_pretty_size (progress->sizestr, sizeof (progress->sizestr),
-			progress->size);
+			progress->size, 1);
     else
       snprintf (progress->sizestr, sizeof (progress->sizestr), "%ld",
 		progress->size);
@@ -759,7 +759,7 @@ void mutt_progress_update (progress_t* progress, long pos, int percent)
     if (progress->flags & MUTT_PROGRESS_SIZE)
     {
       pos = pos / (progress->inc << 10) * (progress->inc << 10);
-      mutt_pretty_size (posstr, sizeof (posstr), pos);
+      mutt_pretty_size (posstr, sizeof (posstr), pos, 1);
     }
     else
       snprintf (posstr, sizeof (posstr), "%ld", pos);
diff --git a/handler.c b/handler.c
index cedf352a..7cda255c 100644
--- a/handler.c
+++ b/handler.c
@@ -1234,7 +1234,7 @@ int mutt_can_decode (BODY *a)
 static int multipart_handler (BODY *a, STATE *s)
 {
   BODY *b, *p;
-  char length[5];
+  char length[16];
   struct stat st;
   int count;
   int rc = 0;
@@ -1267,7 +1267,7 @@ static int multipart_handler (BODY *a, STATE *s)
       }
       state_puts (" --]\n", s);
 
-      mutt_pretty_size (length, sizeof (length), p->length);
+      mutt_pretty_size (length, sizeof (length), p->length, 1);
 
       state_mark_attach (s);
       state_printf (s, _("[-- Type: %s/%s, Encoding: %s, Size: %s --]\n"),
@@ -1490,7 +1490,7 @@ static int external_body_handler (BODY *b, STATE *s)
       if (length)
       {
 	mutt_pretty_size (pretty_size, sizeof (pretty_size),
-			  strtol (length, NULL, 10));
+			  strtol (length, NULL, 10), 1);
 	state_printf (s, _("(size %s bytes) "), pretty_size);
       }
       state_puts (_("has been deleted --]\n"), s);
diff --git a/hdrline.c b/hdrline.c
index 5c2e351d..795941c0 100644
--- a/hdrline.c
+++ b/hdrline.c
@@ -323,7 +323,7 @@ hdr_format_str (char *dest,
       break;
 
     case 'c':
-      mutt_pretty_size (buf2, sizeof (buf2), (long) hdr->content->length);
+      mutt_pretty_size (buf2, sizeof (buf2), (long) hdr->content->length, 0);
       mutt_format_s (dest, destlen, prefix, buf2);
       break;
 
diff --git a/muttlib.c b/muttlib.c
index 5e2080fe..b7d626b1 100644
--- a/muttlib.c
+++ b/muttlib.c
@@ -1141,39 +1141,48 @@ void mutt_pretty_mailbox (char *s, size_t buflen)
   }
 }
 
-void mutt_pretty_size (char *s, size_t len, LOFF_T n)
+void mutt_pretty_size (char *s, size_t len, LOFF_T n, int showbytes)
 {
-  if (option (OPTSIZESHOWBYTES) && (n < 1024))
+  if (!showbytes)
+    showbytes = option (OPTSIZESHOWBYTES);
+  if (showbytes && (n < 1024))
     snprintf (s, len, "%d", (int)n);
-  else if (n == 0)
-    strfcpy (s,
-             option (OPTSIZEUNITSONLEFT) ? "K0" : "0K",
-             len);
-  else if (option (OPTSIZESHOWFRACTIONS) && (n < 10189)) /* 0.1K - 9.9K */
-  {
-    snprintf (s, len,
-              option (OPTSIZEUNITSONLEFT) ? "K%3.1f" : "%3.1fK",
-              (n < 103) ? 0.1 : n / 1024.0);
-  }
-  else if (!option (OPTSIZESHOWMB) || (n < 1023949)) /* 10K - 999K */
-  {
-    /* 51 is magic which causes 10189/10240 to be rounded up to 10 */
-    snprintf (s, len,
-              option (OPTSIZEUNITSONLEFT) ? ("K" OFF_T_FMT) : (OFF_T_FMT "K"),
-              (n + 51) / 1024);
-  }
-  else if (option (OPTSIZESHOWFRACTIONS) && (n < 10433332)) /* 1.0M - 9.9M */
-  {
-    snprintf (s, len,
-              option (OPTSIZEUNITSONLEFT) ? "M%3.1f" : "%3.1fM",
-              n / 1048576.0);
-  }
-  else /* 10M+ */
+  else
   {
-    /* (10433332 + 52428) / 1048576 = 10 */
-    snprintf (s, len,
-              option (OPTSIZEUNITSONLEFT) ?  ("M" OFF_T_FMT) : (OFF_T_FMT "M"),
-              (n + 52428) / 1048576);
+    const char *fmt[3][2] =
+      {
+        { "%3.1f",  OFF_T_FMT },
+        { "K%3.1f", "K" OFF_T_FMT },
+        { "%3.1fK", OFF_T_FMT "K" },
+      };
+    int i = !showbytes ? 0 : option (OPTSIZEUNITSONLEFT) ? 1 : 2;
+
+    if (n == 0)
+    {
+      snprintf (s, len, fmt[i][1], (LOFF_T) 0);
+    }
+    else if (option (OPTSIZESHOWFRACTIONS) && (n < 10189)) /* 0.1K - 9.9K */
+    {
+      snprintf (s, len, fmt[i][0], (n < 103) ? 0.1 : n / 1024.0);
+    }
+    else if (!option (OPTSIZESHOWMB) || (n < 1023949)) /* 10K - 999K */
+    {
+      /* 51 is magic which causes 10189/10240 to be rounded up to 10 */
+      snprintf (s, len, fmt[i][1], (n + 51) / 1024);
+    }
+    else if (option (OPTSIZESHOWFRACTIONS) && (n < 10433332)) /* 1.0M - 9.9M */
+    {
+      snprintf (s, len,
+                option (OPTSIZEUNITSONLEFT) ? "M%3.1f" : "%3.1fM",
+                n / 1048576.0);
+    }
+    else /* 10M+ */
+    {
+      /* (10433332 + 52428) / 1048576 = 10 */
+      snprintf (s, len,
+                option (OPTSIZEUNITSONLEFT) ?  ("M" OFF_T_FMT) : (OFF_T_FMT "M"),
+                (n + 52428) / 1048576);
+    }
   }
 }
 
diff --git a/protos.h b/protos.h
index d760c7d1..3e624ef8 100644
--- a/protos.h
+++ b/protos.h
@@ -256,7 +256,7 @@ void mutt_unprepare_envelope (ENVELOPE *);
 void mutt_buffer_pretty_mailbox (BUFFER *);
 void mutt_buffer_pretty_multi_mailbox (BUFFER *s, const char *delimiter);
 void mutt_pretty_mailbox (char *, size_t);
-void mutt_pretty_size (char *, size_t, LOFF_T);
+void mutt_pretty_size (char *, size_t, LOFF_T, int);
 void mutt_pipe_message (HEADER *);
 void mutt_print_message (HEADER *);
 void mutt_print_patchlist (void);
diff --git a/recvattach.c b/recvattach.c
index 62024963..5278cb94 100644
--- a/recvattach.c
+++ b/recvattach.c
@@ -322,7 +322,7 @@ const char *mutt_attach_fmt (char *dest,
 
       if (!optional)
       {
-	mutt_pretty_size (tmp, sizeof(tmp), l);
+	mutt_pretty_size (tmp, sizeof(tmp), l, 1);
 	mutt_format_s (dest, destlen, prefix, tmp);
       }
       else if (l == 0)
diff --git a/status.c b/status.c
index 107a739f..ba7ce431 100644
--- a/status.c
+++ b/status.c
@@ -148,7 +148,7 @@ status_format_str (char *buf, size_t buflen, size_t col, int cols, char op, cons
       if (!optional)
       {
 	snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
-	mutt_pretty_size (tmp, sizeof (tmp), Context ? Context->size : 0);
+	mutt_pretty_size (tmp, sizeof (tmp), Context ? Context->size : 0, 1);
 	snprintf (buf, buflen, fmt, tmp);
       }
       else if (!Context || !Context->size)
@@ -159,7 +159,7 @@ status_format_str (char *buf, size_t buflen, size_t col, int cols, char op, cons
       if (!optional)
       {
 	snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
-	mutt_pretty_size (tmp, sizeof (tmp), Context ? Context->vsize: 0);
+	mutt_pretty_size (tmp, sizeof (tmp), Context ? Context->vsize: 0, 1);
 	snprintf (buf, buflen, fmt, tmp);
       }
       else if (!Context || !Context->pattern)
