Hello tech@,

Since my brain is incapable of quickly processing numbers larger than a
million (even with the thousand separators enabled), I would like to
introduce the -h flag to systat.
In order not to loose too much information I do the rollover at values  
from 10.0000 up.
I didn't use fmt_scaled, because it's intended for bytecounts and it's
inside libutil, which isn't linked to systat.

It's possible to toggle it at runtime via the "human" command, but I
didn't add a single letter switch, since that space is already quite
crammed.

OK?

martijn@

Index: engine.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/engine.c,v
retrieving revision 1.22
diff -u -p -r1.22 engine.c
--- engine.c    8 Feb 2018 07:00:33 -0000       1.22
+++ engine.c    11 Feb 2018 11:28:15 -0000
@@ -52,6 +52,7 @@ struct view_ent {
 
 useconds_t udelay = 5000000;
 int dispstart = 0;
+int humanreadable = 0;
 int interactive = 1;
 int averageonly = 0;
 int maxprint = 0;
@@ -717,6 +718,8 @@ void
 print_fld_sdiv(field_def *fld, u_int64_t size, int d)
 {
        int len;
+       char *mult = "KMGTPE";
+       int i = -1;
 
        if (fld == NULL)
                return;
@@ -726,35 +729,21 @@ print_fld_sdiv(field_def *fld, u_int64_t
                return;
 
        tb_start();
-       if (tbprintft("%llu", size) <= len)
-               goto ok;
-
-       tb_start();
-       size /= d;
-       if (tbprintft("%lluK", size) <= len)
-               goto ok;
-       if (size == 0)
-               goto err;
-
-       tb_start();
-       size /= d;
-       if (tbprintft("%lluM", size) <= len)
-               goto ok;
-       if (size == 0)
-               goto err;
-
-       tb_start();
-       size /= d;
-       if (tbprintft("%lluG", size) <= len)
-               goto ok;
-       if (size == 0)
-               goto err;
-
-       tb_start();
-       size /= d;
-       if (tbprintft("%lluT", size) <= len)
-               goto ok;
-       
+       if (humanreadable) {
+               while (size >= 10000 && sizeof(mult) >= i + 1) {
+                       i++;
+                       size /= d;
+               }
+               if (tbprintft("%llu%.1s", size, i == -1 ? "" : mult + i) <= len)
+                       goto ok;
+       }
+       while (size != 0 && sizeof(mult) >= i + 1) {
+               tb_start();
+               if (tbprintft("%llu%.1s", size, i == -1 ? "" : mult + i) <= len)
+                       goto ok;
+               i++;
+               size /= d;
+       }
 err:
        print_fld_str(fld, "*");
        tb_end();
Index: engine.h
===================================================================
RCS file: /cvs/src/usr.bin/systat/engine.h,v
retrieving revision 1.9
diff -u -p -r1.9 engine.h
--- engine.h    8 Feb 2018 07:00:33 -0000       1.9
+++ engine.h    11 Feb 2018 11:28:15 -0000
@@ -148,6 +148,7 @@ void foreach_view(void (*callback)(field
 extern int sortdir;
 extern useconds_t udelay;
 extern int dispstart;
+extern int humanreadable;
 extern int interactive;
 extern int averageonly;
 extern int maxprint;
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/main.c,v
retrieving revision 1.67
diff -u -p -r1.67 main.c
--- main.c      8 Feb 2018 07:00:33 -0000       1.67
+++ main.c      11 Feb 2018 11:28:15 -0000
@@ -305,6 +305,10 @@ cmd_compat(const char *buf)
                need_update = 1;
                return;
        }
+       if (strncasecmp(buf, "human", 5) == 0) {
+               humanreadable = !humanreadable;
+               return;
+       }
 
        for (s = buf; *s && strchr("0123456789+-.eE", *s) != NULL; s++)
                ;
@@ -437,7 +441,7 @@ main(int argc, char *argv[])
        if (setresgid(gid, gid, gid) == -1)
                err(1, "setresgid");
 
-       while ((ch = getopt(argc, argv, "BNabd:ins:w:")) != -1) {
+       while ((ch = getopt(argc, argv, "BNabd:hins:w:")) != -1) {
                switch (ch) {
                case 'a':
                        maxlines = -1;
@@ -455,6 +459,9 @@ main(int argc, char *argv[])
                        countmax = strtonum(optarg, 1, INT_MAX, &errstr);
                        if (errstr)
                                errx(1, "-d %s: %s", optarg, errstr);
+                       break;
+               case 'h':
+                       humanreadable = 1;
                        break;
                case 'i':
                        interactive = 1;
Index: systat.1
===================================================================
RCS file: /cvs/src/usr.bin/systat/systat.1,v
retrieving revision 1.103
diff -u -p -r1.103 systat.1
--- systat.1    8 Feb 2018 07:00:33 -0000       1.103
+++ systat.1    11 Feb 2018 11:28:15 -0000
@@ -38,7 +38,7 @@
 .Nd display system statistics
 .Sh SYNOPSIS
 .Nm systat
-.Op Fl aBbiNn
+.Op Fl aBbhiNn
 .Op Fl d Ar count
 .Op Fl s Ar delay
 .Op Fl w Ar width
@@ -103,6 +103,8 @@ Exit after
 screen updates.
 .It Fl i
 Interactive mode.
+.It Fl h
+Human readable mode.
 .It Fl N
 Resolve network addresses to names.
 This is the opposite of the
@@ -219,6 +221,8 @@ command interpreter.
 .Bl -tag -width Fl
 .It Ic help
 Print the names of the available views on the command line.
+.It Ic human
+Toggle human readable mode.
 .It Ic order
 Print the names of the available orderings on the command line.
 .It Ic quit

Reply via email to