]> granicus.if.org Git - procps-ng/commitdiff
top: refactor and enhance column width management
authorJim Warner <james.warner@comcast.net>
Wed, 19 Sep 2012 06:01:01 +0000 (01:01 -0500)
committerCraig Small <csmall@enc.com.au>
Tue, 2 Oct 2012 10:56:39 +0000 (20:56 +1000)
This commit accomplishes the following objectives:
 * remove extra task_show parm added with 'Locate'
 * avoid column overflow with subsequent misalignment
 * eliminate spaces for column heading padding
 * decouple column headings from column data formats
 * eliminate all hardcoded column format specifiers
 * generalize the inter-column spacing management
 * remove Fieldstab.desc in favor of direct nls access
 * set the stage for nls support of column headings
 * set the stage for dynamic changes to justification

Signed-off-by: Jim Warner <james.warner@comcast.net>
top/top.c
top/top.h

index 6725f7eb86bab9f0c2517ab21ef6eeaf54881a91..10586a045b6d88589317145302d3550441c4cdb6 100644 (file)
--- a/top/top.c
+++ b/top/top.c
@@ -1076,90 +1076,22 @@ static int get_int (const char *prompt) {
 
 
         /*
-         * Do some scaling stuff.
-         * We'll interpret 'num' as one of the following types and
-         * try to format it to fit 'width'.
-         *    SK_no (0) it's a byte count
-         *    SK_Kb (1) it's kilobytes
-         *    SK_Mb (2) it's megabytes
-         *    SK_Gb (3) it's gigabytes
-         *    SK_Tb (4) it's terabytes  */
-static const char *scale_num (unsigned long num, const int width, const int type) {
-      // kilobytes, megabytes, gigabytes, terabytes, duh!
-   static double scale[] = { 1024.0, 1024.0*1024, 1024.0*1024*1024, 1024.0*1024*1024*1024, 0 };
-      // kilo, mega, giga, tera, none
-#ifdef CASEUP_SUFIX
-   static char nextup[] =  { 'K', 'M', 'G', 'T', 0 };
-#else
-   static char nextup[] =  { 'k', 'm', 'g', 't', 0 };
-#endif
+         * Make a hex value, and maybe suppress zeroes. */
+static inline const char *hex_make (KLONG num, int noz) {
    static char buf[SMLBUFSIZ];
-   double *dp;
-   char *up;
-
-   // try an unscaled version first...
-   if (width >= snprintf(buf, sizeof(buf), "%lu", num)) return buf;
-
-   // now try successively higher types until it fits
-   for (up = nextup + type, dp = scale; 0 < *dp; ++dp, ++up) {
-      // the most accurate version
-      if (width >= snprintf(buf, sizeof(buf), "%.1f%c", num / *dp, *up))
-         return buf;
-      // the integer version
-      if (width >= snprintf(buf, sizeof(buf), "%lu%c", (unsigned long)(num / *dp), *up))
-         return buf;
-   }
-   // well shoot, this outta' fit...
-   return "?";
-} // end: scale_num
-
+   int i;
 
-        /*
-         * Do some scaling stuff.
-         * format 'tics' to fit 'width'. */
-static const char *scale_tics (TIC_t tics, const int width) {
-#ifdef CASEUP_SUFIX
- #define HH "%uH"                                                  // nls_maybe
- #define DD "%uD"
- #define WW "%uW"
+#ifdef CASEUP_HEXES
+   snprintf(buf, sizeof(buf), "%08" KLF "X", num);
 #else
- #define HH "%uh"                                                  // nls_maybe
- #define DD "%ud"
- #define WW "%uw"
+   snprintf(buf, sizeof(buf), "%08" KLF "x", num);
 #endif
-   static char buf[SMLBUFSIZ];
-   unsigned long nt;    // narrow time, for speed on 32-bit
-   unsigned cc;         // centiseconds
-   unsigned nn;         // multi-purpose whatever
-
-   nt  = (tics * 100ull) / Hertz;               // up to 68 weeks of cpu time
-   cc  = nt % 100;                              // centiseconds past second
-   nt /= 100;                                   // total seconds
-   nn  = nt % 60;                               // seconds past the minute
-   nt /= 60;                                    // total minutes
-   if (width >= snprintf(buf, sizeof(buf), "%lu:%02u.%02u", nt, nn, cc))
-      return buf;
-   if (width >= snprintf(buf, sizeof(buf), "%lu:%02u", nt, nn))
-      return buf;
-   nn  = nt % 60;                               // minutes past the hour
-   nt /= 60;                                    // total hours
-   if (width >= snprintf(buf, sizeof(buf), "%lu,%02u", nt, nn))
-      return buf;
-   nn = nt;                                     // now also hours
-   if (width >= snprintf(buf, sizeof(buf), HH, nn))
-      return buf;
-   nn /= 24;                                    // now days
-   if (width >= snprintf(buf, sizeof(buf), DD, nn))
-      return buf;
-   nn /= 7;                                     // now weeks
-   if (width >= snprintf(buf, sizeof(buf), WW, nn))
-      return buf;
-      // well shoot, this outta' fit...
-   return "?";
- #undef HH
- #undef DD
- #undef WW
-} // end: scale_tics
+   if (noz)
+      for (i = 0; buf[i]; i++)
+         if ('0' == buf[i])
+            buf[i] = '.';
+   return buf;
+} // end: hex_make
 
 
         /*
@@ -1208,6 +1140,169 @@ static inline int user_matched (WIN_t *q, const proc_t *p) {
    return 0;
 } // end: user_matched
 \f
+/*######  Basic Formatting support  ######################################*/
+
+        /*
+         * Just do some justify stuff, then add post column padding. */
+static inline const char *justify_pad (const char *str, int width, int justr) {
+   static char l_fmt[]  = "%-*.*s%s", r_fmt[] = "%*.*s%s";
+   static char buf[SCREENMAX];
+
+   snprintf(buf, sizeof(buf), justr ? r_fmt : l_fmt, width, width, str, COLPADSTR);
+   return buf;
+} // end: justify_pad
+
+
+        /*
+         * Make and then justify a single character. */
+static const char *make_chr (const char ch, int width, int justr) {
+   static char buf[SMLBUFSIZ];
+
+   snprintf(buf, sizeof(buf), "%c", ch);
+   return justify_pad(buf, width, justr);
+} // end: make_chr
+
+
+        /*
+         * Make and then justify an integer NOT subject to scaling,
+         * and include a visual clue should tuncation be necessary. */
+static const char *make_num (long num, int width, int justr) {
+   static char buf[SMLBUFSIZ];
+
+   if (width < snprintf(buf, sizeof(buf), "%ld", num))
+      buf[width-1] = COLPLUSCH;
+   return justify_pad(buf, width, justr);
+} // end: make_num
+
+
+        /*
+         * Make and then justify a character string,
+         * and include a visual clue should tuncation be necessary. */
+static const char *make_str (const char *str, int width, int justr) {
+   static char buf[SCREENMAX];
+
+   if (width < snprintf(buf, sizeof(buf), "%s", str))
+      buf[width-1] = COLPLUSCH;
+   return justify_pad(buf, width, justr);
+} // end: make_str
+
+
+        /*
+         * Make and then justify a percentage, with decreasing precision. */
+static const char *scale_pcnt (float num, int width, int justr) {
+   static char buf[SMLBUFSIZ];
+
+#ifdef PERCENTBOOST
+   if (width >= snprintf(buf, sizeof(buf), "%#.3f", num))
+      goto end_justifies;
+   if (width >= snprintf(buf, sizeof(buf), "%#.2f", num))
+      goto end_justifies;
+#endif
+   if (width >= snprintf(buf, sizeof(buf), "%#.1f", num))
+      goto end_justifies;
+   if (width >= snprintf(buf, sizeof(buf), "%*.0f", width, num))
+      goto end_justifies;
+
+   // well shoot, this outta' fit...
+   snprintf(buf, sizeof(buf), "?");
+end_justifies:
+   return justify_pad(buf, width, justr);
+} // end: scale_pcnt
+
+
+        /*
+         * Do some scaling stuff.
+         * Format 'tics' to fit 'width', then justify it. */
+static const char *scale_tics (TIC_t tics, int width, int justr) {
+#ifdef CASEUP_SUFIX
+ #define HH "%uH"                                                  // nls_maybe
+ #define DD "%uD"
+ #define WW "%uW"
+#else
+ #define HH "%uh"                                                  // nls_maybe
+ #define DD "%ud"
+ #define WW "%uw"
+#endif
+   static char buf[SMLBUFSIZ];
+   unsigned long nt;    // narrow time, for speed on 32-bit
+   unsigned cc;         // centiseconds
+   unsigned nn;         // multi-purpose whatever
+
+   nt  = (tics * 100ull) / Hertz;               // up to 68 weeks of cpu time
+   cc  = nt % 100;                              // centiseconds past second
+   nt /= 100;                                   // total seconds
+   nn  = nt % 60;                               // seconds past the minute
+   nt /= 60;                                    // total minutes
+   if (width >= snprintf(buf, sizeof(buf), "%lu:%02u.%02u", nt, nn, cc))
+      goto end_justifies;
+   if (width >= snprintf(buf, sizeof(buf), "%lu:%02u", nt, nn))
+      goto end_justifies;
+   nn  = nt % 60;                               // minutes past the hour
+   nt /= 60;                                    // total hours
+   if (width >= snprintf(buf, sizeof(buf), "%lu,%02u", nt, nn))
+      goto end_justifies;
+   nn = nt;                                     // now also hours
+   if (width >= snprintf(buf, sizeof(buf), HH, nn))
+      goto end_justifies;
+   nn /= 24;                                    // now days
+   if (width >= snprintf(buf, sizeof(buf), DD, nn))
+      goto end_justifies;
+   nn /= 7;                                     // now weeks
+   if (width >= snprintf(buf, sizeof(buf), WW, nn))
+      goto end_justifies;
+
+   // well shoot, this outta' fit...
+   snprintf(buf, sizeof(buf), "?");
+end_justifies:
+   return justify_pad(buf, width, justr);
+ #undef HH
+ #undef DD
+ #undef WW
+} // end: scale_tics
+
+
+        /*
+         * Do some scaling then justify stuff.
+         * We'll interpret 'num' as one of the following types and
+         * try to format it to fit 'width'.
+         *    SK_no (0) it's a byte count
+         *    SK_Kb (1) it's kilobytes
+         *    SK_Mb (2) it's megabytes
+         *    SK_Gb (3) it's gigabytes
+         *    SK_Tb (4) it's terabytes  */
+static const char *scale_unum (unsigned long num, int type, int width, int justr) {
+      // kilobytes, megabytes, gigabytes, terabytes, duh!
+   static double scale[] = { 1024.0, 1024.0*1024, 1024.0*1024*1024, 1024.0*1024*1024*1024, 0 };
+      // kilo, mega, giga, tera, none
+#ifdef CASEUP_SUFIX
+   static char nextup[] =  { 'K', 'M', 'G', 'T', 0 };
+#else
+   static char nextup[] =  { 'k', 'm', 'g', 't', 0 };
+#endif
+   static char buf[SMLBUFSIZ];
+   double *dp;
+   char *up;
+
+   // try an unscaled version first...
+   if (width >= snprintf(buf, sizeof(buf), "%lu", num))
+      goto end_justifies;
+
+   // now try successively higher types until it fits
+   for (up = nextup + type, dp = scale; 0 < *dp; ++dp, ++up) {
+      // the most accurate version
+      if (width >= snprintf(buf, sizeof(buf), "%.1f%c", num / *dp, *up))
+         goto end_justifies;
+      // the integer version
+      if (width >= snprintf(buf, sizeof(buf), "%lu%c", (unsigned long)(num / *dp), *up))
+         goto end_justifies;
+   }
+
+   // well shoot, this outta' fit...
+   snprintf(buf, sizeof(buf), "?");
+end_justifies:
+   return justify_pad(buf, width, justr);
+} // end: scale_unum
+\f
 /*######  Fields Management support  #####################################*/
 
    /* These are the Fieldstab.lflg values used here and in calibrate_fields.
@@ -1230,82 +1325,79 @@ static inline int user_matched (WIN_t *q, const proc_t *p) {
 #define L_DEFAULT  PROC_FILLSTAT
 
         /* These are our gosh darn 'Fields' !
-           They MUST be kept in sync with pflags !!
-           note: for integer data, the length modifiers found in .fmts may
-                 NOT reflect the true field type found in proc_t -- this plus
-                 a cast when/if displayed provides minimal width protection. */
+           They MUST be kept in sync with pflags !! */
 static FLD_t Fieldstab[] = {
    // a temporary macro, soon to be undef'd...
  #define SF(f) (QFP_t)SCB_NAME(f)
+   // these identifiers reflect the default column alignment
+ #define A_right 1
+ #define A_left  0
 
-/* .head + .fmts anomalies:
-        entries shown with NULL are either valued at runtime (see zap_fieldstab)
-        or, in the case of .fmts, may represent variable width fields
-   .desc anomalies:
-        the .desc field is always null initially, under nls support
+/* .width anomalies:
+        entries with a -1 .width represent variable width columns
+        entries with zero .width are valued at runtime (see zap_fieldstab)
    .lflg anomalies:
         P_UED, L_NONE  - natural outgrowth of 'stat()' in readproc        (euid)
         P_CPU, L_stat  - never filled by libproc, but requires times      (pcpu)
         P_CMD, L_stat  - may yet require L_CMDLINE in calibrate_fields    (cmd/cmdline)
         L_EITHER       - must L_status, else L_stat == 64-bit math (__udivdi3) on 32-bit !
-     .head          .fmts     .width  .scale  .sort     .lflg      .desc
-     ------------   --------  ------  ------  --------  --------   ------ */
-   { NULL,          NULL,        -1,     -1,  SF(PID),  L_NONE,    NULL },
-   { NULL,          NULL,        -1,     -1,  SF(PPD),  L_EITHER,  NULL },
-   { "  UID ",      "%5d ",      -1,     -1,  SF(UED),  L_NONE,    NULL },
-   { "USER     ",   "%-8.8s ",   -1,     -1,  SF(UEN),  L_EUSER,   NULL },
-   { " RUID ",      "%5d ",      -1,     -1,  SF(URD),  L_status,  NULL },
-   { "RUSER    ",   "%-8.8s ",   -1,     -1,  SF(URN),  L_OUSER,   NULL },
-   { " SUID ",      "%5d ",      -1,     -1,  SF(USD),  L_status,  NULL },
-   { "SUSER    ",   "%-8.8s ",   -1,     -1,  SF(USN),  L_OUSER,   NULL },
-   { "  GID ",      "%5d ",      -1,     -1,  SF(GID),  L_NONE,    NULL },
-   { "GROUP    ",   "%-8.8s ",   -1,     -1,  SF(GRP),  L_EGROUP,  NULL },
-   { NULL,          NULL,        -1,     -1,  SF(PGD),  L_stat,    NULL },
-   { "TTY      ",   "%-8.8s ",    8,     -1,  SF(TTY),  L_stat,    NULL },
-   { NULL,          NULL,        -1,     -1,  SF(TPG),  L_stat,    NULL },
-   { NULL,          NULL,        -1,     -1,  SF(SID),  L_stat,    NULL },
-   { " PR ",        "%3d ",      -1,     -1,  SF(PRI),  L_stat,    NULL },
-   { " NI ",        "%3d ",      -1,     -1,  SF(NCE),  L_stat,    NULL },
-   { "nTH ",        "%3d ",      -1,     -1,  SF(THD),  L_EITHER,  NULL },
-   { NULL,          NULL,        -1,     -1,  SF(CPN),  L_stat,    NULL },
-   { " %CPU ",      NULL,        -1,     -1,  SF(CPU),  L_stat,    NULL },
-   { "  TIME ",     "%6.6s ",     6,     -1,  SF(TME),  L_stat,    NULL },
-   { "   TIME+  ",  "%9.9s ",     9,     -1,  SF(TME),  L_stat,    NULL },
-   { "%MEM ",       "%#4.1f ",   -1,     -1,  SF(RES),  L_statm,   NULL },
-   { " VIRT ",      "%5.5s ",     5,  SK_Kb,  SF(VRT),  L_statm,   NULL },
-   { "SWAP ",       "%4.4s ",     4,  SK_Kb,  SF(SWP),  L_status,  NULL },
-   { " RES ",       "%4.4s ",     4,  SK_Kb,  SF(RES),  L_statm,   NULL },
-   { "CODE ",       "%4.4s ",     4,  SK_Kb,  SF(COD),  L_statm,   NULL },
-   { "DATA ",       "%4.4s ",     4,  SK_Kb,  SF(DAT),  L_statm,   NULL },
-   { " SHR ",       "%4.4s ",     4,  SK_Kb,  SF(SHR),  L_statm,   NULL },
-   { "nMaj ",       "%4.4s ",     4,  SK_no,  SF(FL1),  L_stat,    NULL },
-   { "nMin ",       "%4.4s ",     4,  SK_no,  SF(FL2),  L_stat,    NULL },
-   { "nDRT ",       "%4.4s ",     4,  SK_no,  SF(DRT),  L_statm,   NULL },
-   { "S ",          "%c ",       -1,     -1,  SF(STA),  L_EITHER,  NULL },
-   // next 2 entries are special: '.head' is variable width (see calibrate_fields)
-   { "COMMAND  ",   NULL,        -1,     -1,  SF(CMD),  L_EITHER,  NULL },
-   { "WCHAN    ",   NULL,        -1,     -1,  SF(WCH),  L_stat,    NULL },
-   // next entry's special: the 0's will be replaced with '.'!
-#ifdef CASEUP_HEXES
-   { "Flags    ",   "%08lX ",    -1,     -1,  SF(FLG),  L_stat,    NULL },
+     .head      .width  .scale  .align    .sort     .lflg
+     ---------  ------  ------  -------   --------  --------   */
+   { "PID",         0,     -1,  A_right,  SF(PID),  L_NONE    },
+   { "PPID",        0,     -1,  A_right,  SF(PPD),  L_EITHER  },
+   { "UID",         5,     -1,  A_right,  SF(UED),  L_NONE    },
+   { "USER",        8,     -1,  A_left,   SF(UEN),  L_EUSER   },
+   { "RUID",        5,     -1,  A_right,  SF(URD),  L_status  },
+   { "RUSER",       8,     -1,  A_left,   SF(URN),  L_OUSER   },
+   { "SUID",        5,     -1,  A_right,  SF(USD),  L_status  },
+   { "SUSER",       8,     -1,  A_left,   SF(USN),  L_OUSER   },
+   { "GID",         5,     -1,  A_right,  SF(GID),  L_NONE    },
+   { "GROUP",       8,     -1,  A_left,   SF(GRP),  L_EGROUP  },
+   { "PGRP",        0,     -1,  A_right,  SF(PGD),  L_stat    },
+   { "TTY",         8,     -1,  A_left,   SF(TTY),  L_stat    },
+   { "TPGID",       0,     -1,  A_right,  SF(TPG),  L_stat    },
+   { "SID",         0,     -1,  A_right,  SF(SID),  L_stat    },
+   { "PR",          3,     -1,  A_right,  SF(PRI),  L_stat    },
+   { "NI",          3,     -1,  A_right,  SF(NCE),  L_stat    },
+   { "nTH",         3,     -1,  A_right,  SF(THD),  L_EITHER  },
+   { "P",           0,     -1,  A_right,  SF(CPN),  L_stat    },
+   { "%CPU",        0,     -1,  A_right,  SF(CPU),  L_stat    },
+   { "TIME",        6,     -1,  A_right,  SF(TME),  L_stat    },
+   { "TIME+",       9,     -1,  A_right,  SF(TME),  L_stat    },
+#ifdef PERCENTBOOST
+   { "%MEM",        5,     -1,  A_right,  SF(RES),  L_statm   },
 #else
-   { "Flags    ",   "%08lx ",    -1,     -1,  SF(FLG),  L_stat,    NULL },
+   { "%MEM",        4,     -1,  A_right,  SF(RES),  L_statm   },
 #endif
-   // next 3 entries as P_CMD/P_WCH: '.head' must be same length -- they share varcolsz
-   { "CGROUPS  ",   NULL,        -1,     -1,  SF(CGR),  L_CGROUP,  NULL },
-   { "SUPGIDS  ",   NULL,        -1,     -1,  SF(SGD),  L_status,  NULL },
-   { "SUPGRPS  ",   NULL,        -1,     -1,  SF(SGN),  L_SUPGRP,  NULL },
-   { NULL,          NULL,        -1,     -1,  SF(TGD),  L_status,  NULL },
+   { "VIRT",        5,  SK_Kb,  A_right,  SF(VRT),  L_statm   },
+   { "SWAP",        4,  SK_Kb,  A_right,  SF(SWP),  L_status  },
+   { "RES",         4,  SK_Kb,  A_right,  SF(RES),  L_statm   },
+   { "CODE",        4,  SK_Kb,  A_right,  SF(COD),  L_statm   },
+   { "DATA",        4,  SK_Kb,  A_right,  SF(DAT),  L_statm   },
+   { "SHR",         4,  SK_Kb,  A_right,  SF(SHR),  L_statm   },
+   { "nMaj",        4,  SK_no,  A_right,  SF(FL1),  L_stat    },
+   { "nMin",        4,  SK_no,  A_right,  SF(FL2),  L_stat    },
+   { "nDRT",        4,  SK_no,  A_right,  SF(DRT),  L_statm   },
+   { "S",           1,     -1,  A_right,  SF(STA),  L_EITHER  },
+   { "COMMAND",    -1,     -1,  A_left,   SF(CMD),  L_EITHER  },
+   { "WCHAN",      -1,     -1,  A_left,   SF(WCH),  L_stat    },
+   { "Flags",       8,     -1,  A_left,   SF(FLG),  L_stat    },
+   { "CGROUPS",    -1,     -1,  A_left,   SF(CGR),  L_CGROUP  },
+   { "SUPGIDS",    -1,     -1,  A_left,   SF(SGD),  L_status  },
+   { "SUPGRPS",    -1,     -1,  A_left,   SF(SGN),  L_SUPGRP  },
+   { "TGID",        0,     -1,  A_right,  SF(TGD),  L_status  },
 #ifdef OOMEM_ENABLE
 #define L_oom      PROC_FILLOOM
-   { "Adj ",        "%3d ",      -1,     -1,  SF(OOA),  L_oom,     NULL },
-   { " Badness ",   "%8d ",      -1,     -1,  SF(OOM),  L_oom,     NULL },
+   { "Adj",         3,     -1,  A_right,  SF(OOA),  L_oom     },
+   { "Badness",     8,     -1,  A_right,  SF(OOM),  L_oom     },
 #undef L_oom
 #endif
-   { "ENVIRON  ",   NULL,        -1,     -1,  SF(ENV),  L_ENVIRON, NULL },
-   { "vMj ",        "%3.3s ",     3,  SK_no,  SF(FV1),  L_stat,    NULL },
-   { "vMn ",        "%3.3s ",     3,  SK_no,  SF(FV2),  L_stat,    NULL }
+   { "ENVIRON",    -1,     -1,  A_left,   SF(ENV),  L_ENVIRON },
+   { "vMj",         3,  SK_no,  A_right,  SF(FV1),  L_stat    },
+   { "vMn",         3,  SK_no,  A_right,  SF(FV2),  L_stat    }
  #undef SF
+ #undef A_left
+ #undef A_right
 };
 
 
@@ -1392,7 +1484,6 @@ static void adj_geometry (void) {
 static void build_headers (void) {
    FLG_t f;
    char *s;
-   const char *h;
    WIN_t *w = Curwin;
 #ifdef EQUCOLHDRYES
    int x, hdrmax = 0;
@@ -1415,12 +1506,12 @@ static void build_headers (void) {
 #else
             if (P_MAXPFLGS <= f) continue;
 #endif
-            h = Fieldstab[f].head;
             if (P_WCH == f) needpsdb = 1;
             if (P_CMD == f && CHKw(w, Show_CMDLIN)) Frames_libflags |= L_CMDLINE;
-            if (!VARcol(f)) s = scat(s, h);
-            else s = scat(s, fmtmk(VARCOL_fmts, w->varcolsz, w->varcolsz, h));
             Frames_libflags |= Fieldstab[w->procflgs[i]].lflg;
+            s = scat(s, justify_pad(N_col(f)
+               , VARcol(f) ? w->varcolsz : Fieldstab[f].width
+               , CHKw(w, Fieldstab[f].align)));
 #ifdef USE_X_COLHDR
             if (CHKw(w, Show_HICOLS) && f == w->rc.sortindx) {
                s = scat(s, fmtmk("%s%s", Caps_off, w->capclr_hdr));
@@ -1490,7 +1581,7 @@ static void calibrate_fields (void) {
    char *s;
    const char *h;
    WIN_t *w = Curwin;
-   int i, varcolcnt;
+   int i, varcolcnt, len;
 
    // block SIGWINCH signals while we do our thing...
    sigemptyset(&newss);
@@ -1531,11 +1622,12 @@ static void calibrate_fields (void) {
 #ifndef USE_X_COLHDR
             if (P_MAXPFLGS <= f) continue;
 #endif
-            h = Fieldstab[f].head;
+            h = N_col(f);
+            len = (VARcol(f) ? (int)strlen(h) : Fieldstab[f].width) + COLPADSIZ;
             // oops, won't fit -- we're outta here...
-            if (Screen_cols < ((int)(s - w->columnhdr) + (int)strlen(h))) break;
-            if (VARcol(f)) { ++varcolcnt; w->varcolsz += strlen(h) - 1; }
-            s = scat(s, h);
+            if (Screen_cols < ((int)(s - w->columnhdr) + len)) break;
+            if (VARcol(f)) { ++varcolcnt; w->varcolsz += strlen(h); }
+            s = scat(s, fmtmk("%*.*s", len, len, h));
          }
 #ifndef USE_X_COLHDR
          if (X_XON == w->procflgs[i - 1]) --i;
@@ -1546,7 +1638,7 @@ static void calibrate_fields (void) {
             encountered, but that's ok because they won't be displayed anyway */
          w->maxpflgs = i;
          w->varcolsz += Screen_cols - strlen(w->columnhdr);
-         if (varcolcnt) w->varcolsz = w->varcolsz / varcolcnt;
+         if (varcolcnt) w->varcolsz /= varcolcnt;
 
          /* establish the field where all remaining fields would still
             fit within screen width, including a leading window number */
@@ -1557,9 +1649,10 @@ static void calibrate_fields (void) {
 #ifndef USE_X_COLHDR
             if (P_MAXPFLGS <= f) { w->endpflg = i; continue; }
 #endif
-            h = Fieldstab[f].head;
-            if (Screen_cols < ((int)(s - w->columnhdr) + (int)strlen(h))) break;
-            s = scat(s, h);
+            h = N_col(f);
+            len = (VARcol(f) ? (int)strlen(h) : Fieldstab[f].width) + COLPADSIZ;
+            if (Screen_cols < ((int)(s - w->columnhdr) + len)) break;
+            s = scat(s, fmtmk("%*.*s", len, len, h));
             w->endpflg = i;
          }
 #ifndef USE_X_COLHDR
@@ -1636,11 +1729,10 @@ static void display_fields (int focus, int extend) {
       char sbuf[xSUFX+1];
       int b = FLDviz(w, i);
       FLG_t f = FLDget(w, i);
-      const char *h, *e = (i == focus && extend) ? w->capclr_hdr : "";
+      const char *e = (i == focus && extend) ? w->capclr_hdr : "";
 
-      // advance past leading header spaces and prep sacrificial suffix
-      for (h = Fieldstab[f].head; ' ' == *h; ++h) ;
-      snprintf(sbuf, sizeof(sbuf), "= %s", Fieldstab[f].desc);
+      // prep sacrificial suffix
+      snprintf(sbuf, sizeof(sbuf), "= %s", N_fld(f));
 
       PUTT("%s%c%s%s %s%-7.7s%s%s%s %-*.*s%s"
          , tg2((i / rmax) * cmax, (i % rmax) + yRSVD)
@@ -1648,7 +1740,7 @@ static void display_fields (int focus, int extend) {
          , b ? w->cap_bold : Cap_norm
          , e
          , i == focus ? w->capclr_hdr : ""
-         , h
+         , Fieldstab[f].head
          , Cap_norm
          , b ? w->cap_bold : ""
          , e
@@ -1689,8 +1781,7 @@ static void fields_utility (void) {
    spewFI
 
    do {
-      // advance past leading spaces, if any
-      if (!h) for (h = Fieldstab[f].head; ' ' == *h; ++h) ;
+      if (!h) h = Fieldstab[f].head;
       display_fields(i, (p != NULL));
       putp(Cap_home);
       show_special(1, fmtmk(N_unq(FIELD_header_fmt)
@@ -1746,75 +1837,58 @@ static void fields_utility (void) {
 
 
         /*
-         * This routine exists just to consolidate all the messin' around
-         * with Fieldstab '.head' and '.fmts' members -- until we devise
-         * a more elegant soultion. */
+         * This routine exists just to consolidate all the messin'
+         * around with the Fieldstab array and some related stuff. */
 static void zap_fieldstab (void) {
-   static char fmts_pid[8];
-   static char fmts_cpu[8];
    static int once;
-   unsigned i, digits;
+   unsigned digits;
    char buf[8];
 
-   if (once) goto always;
-
-   Fieldstab[P_PID].head = "  PID ";
-   Fieldstab[P_PID].fmts = "%5d ";
-   Fieldstab[P_PPD].head = " PPID ";
-   Fieldstab[P_PPD].fmts = "%5d ";
-   Fieldstab[P_PGD].head = " PGRP ";
-   Fieldstab[P_PGD].fmts = "%5d ";
-   Fieldstab[P_SID].head = "  SID ";
-   Fieldstab[P_SID].fmts = "%5d ";
-   Fieldstab[P_TGD].head = " TGID ";
-   Fieldstab[P_TGD].fmts = "%5d ";
-   Fieldstab[P_TPG].head = "TPGID ";
-   Fieldstab[P_TPG].fmts = "%5d ";
-   if (5 < (digits = get_pid_digits())) {
-      if (10 < digits) error_exit(N_txt(FAIL_widepid_txt));
-      snprintf(fmts_pid, sizeof(fmts_pid), "%%%uu ", digits);
-      Fieldstab[P_PID].head = "       PID " + 10 - digits;
-      Fieldstab[P_PID].fmts = fmts_pid;
-      Fieldstab[P_PPD].head = "      PPID " + 10 - digits;
-      Fieldstab[P_PPD].fmts = fmts_pid;
-      Fieldstab[P_PGD].head = "      PGRP " + 10 - digits;
-      Fieldstab[P_PGD].fmts = fmts_pid;
-      Fieldstab[P_SID].head = "       SID " + 10 - digits;
-      Fieldstab[P_SID].fmts = fmts_pid;
-      Fieldstab[P_TGD].head = "      TGID " + 10 - digits;
-      Fieldstab[P_TGD].fmts = fmts_pid;
-      Fieldstab[P_TPG].head = "     TPGID " + 10 - digits;
-      Fieldstab[P_TPG].fmts = fmts_pid;
-   }
-
-   for (i = 0; i < P_MAXPFLGS; i++)
-      Fieldstab[i].desc = N_fld(i);
-
-   once = 1;
+   if (!once) {
+      Fieldstab[P_PID].width = Fieldstab[P_PPD].width
+         = Fieldstab[P_PGD].width = Fieldstab[P_SID].width
+         = Fieldstab[P_TGD].width = Fieldstab[P_TPG].width = 5;
+      if (5 < (digits = get_pid_digits())) {
+         if (10 < digits) error_exit(N_txt(FAIL_widepid_txt));
+         Fieldstab[P_PID].width = Fieldstab[P_PPD].width
+            = Fieldstab[P_PGD].width = Fieldstab[P_SID].width
+            = Fieldstab[P_TGD].width = Fieldstab[P_TPG].width = digits;
+      }
+      once = 1;
+   }
 
    /*** hotplug_acclimated ***/
-always:
-   Fieldstab[P_CPN].head = "P ";
-   Fieldstab[P_CPN].fmts = "%1d ";
+
+   Fieldstab[P_CPN].width = 1;
    if (1 < (digits = (unsigned)snprintf(buf, sizeof(buf), "%u", (unsigned)smp_num_cpus))) {
       if (5 < digits) error_exit(N_txt(FAIL_widecpu_txt));
-      snprintf(fmts_cpu, sizeof(fmts_cpu), "%%%ud ", digits);
-      Fieldstab[P_CPN].head = "    P " + 5 - digits;
-      Fieldstab[P_CPN].fmts = fmts_cpu;
+      Fieldstab[P_CPN].width = digits;
    }
 
+#ifdef PERCENTBOOST
    Cpu_pmax = 99.9;
-   Fieldstab[P_CPU].fmts = " %#4.1f ";
+   Fieldstab[P_CPU].width = 5;
    if (Rc.mode_irixps && smp_num_cpus > 1 && !Thread_mode) {
       Cpu_pmax = 100.0 * smp_num_cpus;
       if (smp_num_cpus > 10) {
          if (Cpu_pmax > 99999.0) Cpu_pmax = 99999.0;
-         Fieldstab[P_CPU].fmts = "%5.0f ";
       } else {
          if (Cpu_pmax > 999.9) Cpu_pmax = 999.9;
-         Fieldstab[P_CPU].fmts = "%#5.1f ";
       }
    }
+#else
+   Cpu_pmax = 99.9;
+   Fieldstab[P_CPU].width = 4;
+   if (Rc.mode_irixps && smp_num_cpus > 1 && !Thread_mode) {
+      Cpu_pmax = 100.0 * smp_num_cpus;
+      if (smp_num_cpus > 10) {
+         if (Cpu_pmax > 99999.0) Cpu_pmax = 99999.0;
+      } else {
+         if (Cpu_pmax > 999.9) Cpu_pmax = 999.9;
+      }
+      Fieldstab[P_CPU].width = 5;
+   }
+#endif
 
    // lastly, ensure we've got proper column headers...
    calibrate_fields();
@@ -2884,13 +2958,12 @@ static void file_writerc (void) {
    /* This is currently the one true prototype require by top.
       It is placed here, instead of top.h, so as to avoid a compiler
       warning when top_nls.c is compiled. */
-static void task_show (const WIN_t *q, const proc_t *p, char *ptr);
+static const char *task_show (const WIN_t *q, const proc_t *p);
 
 static void find_string (int ch) {
  #define reDUX (found) ? N_txt(WORD_another_txt) : ""
    static char str[SCREENMAX];
    static int found;
-   char buf[ROWMINSIZ];
    int i;
 
    if ('&' == ch && !str[0]) {
@@ -2902,9 +2975,9 @@ static void find_string (int ch) {
       found = 0;
    }
    if (str[0]) {
+      SETw(Curwin, INFINDS_xxx);
       for (i = Curwin->begtask; i < Frame_maxtask; i++) {
-         task_show(Curwin, Curwin->ppt[i], buf);
-         if (STRSTR(buf, str)) {
+         if (STRSTR(task_show(Curwin, Curwin->ppt[i]), str)) {
             found = 1;
             if (i == Curwin->begtask) continue;
             Curwin->begtask = i;
@@ -3523,8 +3596,8 @@ static void do_key (int ch) {
          'F' - likely
          'f' - likely
          'g' - likely
-         'H' - likely (%CPU .fmts)
-         'I' - likely (%CPU .fmts)
+         'H' - likely
+         'I' - likely
          'Z' - likely, if 'Curwin' changed when !Mode_altscr
          '-' - likely (restricted to Mode_altscr)
          '_' - likely (restricted to Mode_altscr)
@@ -3661,127 +3734,123 @@ static void summary_show (void) {
         /*
          * Build the information for a single task row and
          * display the results or return them to the caller. */
-static void task_show (const WIN_t *q, const proc_t *p, char *ptr) {
- #define makeCOL(va...)  snprintf(cbuf, sizeof(cbuf), f, ## va)
+static const char *task_show (const WIN_t *q, const proc_t *p) {
 #ifndef SCROLLVAR_NO
- #define makeVAR(v)  { const char *pv = v; f = VARCOL_fmts; \
-    if (!q->varcolbeg) makeCOL(q->varcolsz, q->varcolsz, pv); \
-    else makeCOL(q->varcolsz, q->varcolsz, q->varcolbeg < (int)strlen(pv) ? pv + q->varcolbeg : ""); }
+ #define makeVAR(v)  { const char *pv = v; \
+    if (!q->varcolbeg) cp = make_str(pv, q->varcolsz, Js); \
+    else cp = make_str(q->varcolbeg < (int)strlen(pv) ? pv + q->varcolbeg : "", q->varcolsz, Js); }
 #else
- #define makeVAR(v)  { f = VARCOL_fmts; makeCOL(q->varcolsz, q->varcolsz, v); }
+ #define makeVAR(v) cp = make_str(v, q->varcolsz, Js)
 #endif
  #define pages2K(n)  (unsigned long)( (n) << Pg2K_shft )
-   char rbuf[ROWMINSIZ], *rp;
-   int j, x;
+   static char rbuf[ROWMINSIZ];
+   char *rp;
+   int x;
 
    // we must begin a row with a possible window number in mind...
    *(rp = rbuf) = '\0';
    if (Rc.mode_altscr) rp = scat(rp, " ");
 
    for (x = 0; x < q->maxpflgs; x++) {
-      char        cbuf[SCREENMAX];
-      FLG_t       i = q->procflgs[x];           // support for our field/column
-      const char *f = Fieldstab[i].fmts;        // macro AND sometimes the fmt
-      int         s = Fieldstab[i].scale;       // string must be altered !
-      int         w = Fieldstab[i].width;
+      const char *cp;
+      FLG_t       i = q->procflgs[x];
+      #define S   Fieldstab[i].scale
+      #define W   Fieldstab[i].width
+      #define Js  0                             // left justify string data
+      #define Jn  1                             // right justify numeric data
 
       switch (i) {
 #ifndef USE_X_COLHDR
          // these 2 aren't real procflgs, they're used in column highlighting!
          case X_XON:
          case X_XOF:
-            if (ptr) continue;
-            /* treat running tasks specially - entire row may get highlighted
-               so we needn't turn it on and we MUST NOT turn it off */
-            if (!('R' == p->state && CHKw(q, Show_HIROWS)))
-               rp = scat(rp, X_XON == i ? q->capclr_rowhigh : q->capclr_rownorm);
-            continue;
+            cp = NULL;
+            if (!CHKw(q, INFINDS_xxx)) {
+               /* treat running tasks specially - entire row may get highlighted
+                  so we needn't turn it on and we MUST NOT turn it off */
+               if (!('R' == p->state && CHKw(q, Show_HIROWS)))
+                  cp = (X_XON == i ? q->capclr_rowhigh : q->capclr_rownorm);
+            }
+            break;
 #endif
          case P_CGR:
             makeVAR(p->cgroup[0]);
-            break;
          case P_CMD:
             makeVAR(forest_display(q, p));
             break;
          case P_COD:
-            makeCOL(scale_num(pages2K(p->trs), w, s));
+            cp = scale_unum(pages2K(p->trs), S, W, Jn);
             break;
          case P_CPN:
-            makeCOL(p->processor);
+            cp = make_num(p->processor, W, Jn);
             break;
          case P_CPU:
          {  float u = (float)p->pcpu * Frame_etscale;
             if (u > Cpu_pmax) u = Cpu_pmax;
-            makeCOL(u);
+            cp = scale_pcnt(u, W, Jn);
          }
             break;
          case P_DAT:
-            makeCOL(scale_num(pages2K(p->drs), w, s));
+            cp = scale_unum(pages2K(p->drs), S, W, Jn);
             break;
          case P_DRT:
-            makeCOL(scale_num((unsigned long)p->dt, w, s));
+            cp = scale_unum(p->dt, S, W, Jn);
             break;
          case P_ENV:
-            makeVAR(*p->environ);
+            makeVAR(p->environ[0]);
             break;
          case P_FLG:
-         {  char tmp[SMLBUFSIZ];
-            snprintf(tmp, sizeof(tmp), f, (long)p->flags);
-            for (j = 0; tmp[j]; j++) if ('0' == tmp[j]) tmp[j] = '.';
-            f = tmp;
-            makeCOL("");
-         }
+            cp = make_str(hex_make(p->flags, 1), W, Js);
             break;
          case P_FL1:
-            makeCOL(scale_num(p->maj_flt, w, s));
+            cp = scale_unum(p->maj_flt, S, W, Jn);
             break;
          case P_FL2:
-            makeCOL(scale_num(p->min_flt, w, s));
+            cp = scale_unum(p->min_flt, S, W, Jn);
             break;
          case P_FV1:
-            makeCOL(scale_num(p->maj_delta, w, s));
+            cp = scale_unum(p->maj_delta, S, W, Jn);
             break;
          case P_FV2:
-            makeCOL(scale_num(p->min_delta, w, s));
+            cp = scale_unum(p->min_delta, S, W, Jn);
             break;
          case P_GID:
-            makeCOL(p->egid);
+            cp = make_num(p->egid, W, Jn);
             break;
          case P_GRP:
-            makeCOL(p->egroup);
+            cp = make_str(p->egroup, W, Js);
             break;
          case P_MEM:
-            makeCOL((float)pages2K(p->resident) * 100 / kb_main_total);
+            cp = scale_pcnt((float)pages2K(p->resident) * 100 / kb_main_total, W, Jn);
             break;
          case P_NCE:
-            makeCOL((int)p->nice);
+            cp = make_num(p->nice, W, Jn);
             break;
 #ifdef OOMEM_ENABLE
          case P_OOA:
-            makeCOL((int)p->oom_adj);
+            cp = make_num(p->oom_adj, W, Jn);
             break;
          case P_OOM:
-            makeCOL((long)p->oom_score);
+            cp = make_num(p->oom_score, W, Jn);
             break;
 #endif
          case P_PGD:
-            makeCOL(p->pgrp);
+            cp = make_num(p->pgrp, W, Jn);
             break;
          case P_PID:
-            makeCOL(p->tid);
+            cp = make_num(p->tid, W, Jn);
             break;
          case P_PPD:
-            makeCOL(p->ppid);
+            cp = make_num(p->ppid, W, Jn);
             break;
          case P_PRI:
             if (-99 > p->priority || 999 < p->priority) {
-               f = " rt ";
-               makeCOL("");
+               cp = make_str("rt", W, Jn);
             } else
-               makeCOL((int)p->priority);
+               cp = make_num(p->priority, W, Jn);
             break;
          case P_RES:
-            makeCOL(scale_num(pages2K(p->resident), w, s));
+            cp = scale_unum(pages2K(p->resident), S, W, Jn);
             break;
          case P_SGD:
             makeVAR(p->supgid);
@@ -3790,89 +3859,91 @@ static void task_show (const WIN_t *q, const proc_t *p, char *ptr) {
             makeVAR(p->supgrp);
             break;
          case P_SHR:
-            makeCOL(scale_num(pages2K(p->share), w, s));
+            cp = scale_unum(pages2K(p->share), S, W, Jn);
             break;
          case P_SID:
-            makeCOL(p->session);
+            cp = make_num(p->session, W, Jn);
             break;
          case P_STA:
-            makeCOL(p->state);
+            cp = make_chr(p->state, W, Js);
             break;
          case P_SWP:
-            makeCOL(scale_num(p->vm_swap, w, s));
+            cp = scale_unum(p->vm_swap, S, W, Jn);
             break;
          case P_TGD:
-            makeCOL(p->tgid);
+            cp = make_num(p->tgid, W, Jn);
             break;
          case P_THD:
-            makeCOL(p->nlwp);
+            cp = make_num(p->nlwp, W, Jn);
             break;
          case P_TME:
          case P_TM2:
          {  TIC_t t = p->utime + p->stime;
             if (CHKw(q, Show_CTIMES)) t += (p->cutime + p->cstime);
-            makeCOL(scale_tics(t, w));
+            cp = scale_tics(t, W, Jn);
          }
             break;
          case P_TPG:
-            makeCOL(p->tpgid);
+            cp = make_num(p->tpgid, W, Jn);
             break;
          case P_TTY:
          {  char tmp[SMLBUFSIZ];
-            dev_to_tty(tmp, w, p->tty, p->tid, ABBREV_DEV);
-            makeCOL(tmp);
+            dev_to_tty(tmp, W, p->tty, p->tid, ABBREV_DEV);
+            cp = make_str(tmp, W, Js);
          }
             break;
          case P_UED:
-            makeCOL(p->euid);
+            cp = make_num(p->euid, W, Jn);
             break;
          case P_UEN:
-            makeCOL(p->euser);
+            cp = make_str(p->euser, W, Js);
             break;
          case P_URD:
-            makeCOL(p->ruid);
+            cp = make_num(p->ruid, W, Jn);
             break;
          case P_URN:
-            makeCOL(p->ruser);
+            cp = make_str(p->ruser, W, Js);
             break;
          case P_USD:
-            makeCOL(p->suid);
+            cp = make_num(p->suid, W, Jn);
             break;
          case P_USN:
-            makeCOL(p->suser);
+            cp = make_str(p->suser, W, Js);
             break;
          case P_VRT:
-            makeCOL(scale_num(pages2K(p->size), w, s));
+            cp = scale_unum(pages2K(p->size), S, W, Jn);
             break;
          case P_WCH:
          {  const char *u;
             if (No_ksyms)
-#ifdef CASEUP_HEXES
-               u = fmtmk("%08" KLF "X", p->wchan);
-#else
-               u = fmtmk("%08" KLF "x", p->wchan);
-#endif
+               u = hex_make(p->wchan, 0);
             else
                u = lookup_wchan(p->wchan, p->tid);
             makeVAR(u);
          }
             break;
          default:                 // keep gcc happy
+            continue;
             break;
 
-        } // end: switch 'procflag'
+      } // end: switch 'procflag'
 
-        rp = scat(rp, cbuf);
+      if (cp)
+         rp = scat(rp, cp);
+
+      #undef S
+      #undef W
+      #undef Js
+      #undef Jn
    } // end: for 'maxpflgs'
 
-   if (ptr)
-      strcpy(ptr, rbuf);
-   else
+   if (!CHKw(q, INFINDS_xxx)) {
       PUFF("\n%s%s%s", (CHKw(q, Show_HIROWS) && 'R' == p->state)
          ? q->capclr_rowhigh : q->capclr_rownorm
          , rbuf
          , q->eolcap);
- #undef makeCOL
+   }
+   return rbuf;
  #undef makeVAR
  #undef pages2K
 } // end: task_show
@@ -3910,14 +3981,14 @@ static int window_show (WIN_t *q, int wmax) {
       checking some stuff with each iteration and check it just once... */
    if (CHKw(q, Show_IDLEPS) && !q->usrseltyp)
       while (i < Frame_maxtask && lwin < wmax) {
-         task_show(q, q->ppt[i++], NULL);
+         task_show(q, q->ppt[i++]);
          ++lwin;
       }
    else
       while (i < Frame_maxtask && lwin < wmax) {
          if ((CHKw(q, Show_IDLEPS) || isBUSY(q->ppt[i]))
          && user_matched(q, q->ppt[i])) {
-            task_show(q, q->ppt[i], NULL);
+            task_show(q, q->ppt[i]);
             ++lwin;
          }
          ++i;
@@ -3992,6 +4063,7 @@ static void frame_make (void) {
    Tree_idx = Pseudo_row = Msg_row = scrlins = 0;
    summary_show();
    Max_lines = (Screen_rows - Msg_row) - 1;
+   OFFw(Curwin, INFINDS_xxx);
 
    if (!Rc.mode_altscr) {
       // only 1 window to show so, piece o' cake
index 2a82c698f75aaa45311d32e63130923588a5493f..45e4417d358e09a6101c7cba58c93ca89dee63a7 100644 (file)
--- a/top/top.h
+++ b/top/top.h
@@ -34,6 +34,7 @@
 //#define EQUCOLHDRYES            /* yes, do equalize column header lengths  */
 //#define OFF_HST_HASH            /* use BOTH qsort+bsrch vs. hashing scheme */
 //#define OFF_STDIOLBF            /* disable our own stdout _IOFBF override  */
+//#define PERCENTBOOST            /* enable extended precision for % fields  */
 //#define PRETEND2_5_X            /* pretend we're linux 2.5.x (for IO-wait) */
 //#define PRETEND4CPUS            /* pretend we're smp with 4 ticsers (sic)  */
 //#define PRETENDNOCAP            /* use a terminal without essential caps   */
@@ -120,6 +121,12 @@ char *strcasestr(const char *haystack, const char *needle);
 #define ROWMINSIZ  ( SCREENMAX +  4 * (CAPBUFSIZ + CLRBUFSIZ) )
 #define ROWMAXSIZ  ( SCREENMAX + 16 * (CAPBUFSIZ + CLRBUFSIZ) )
 
+   // space between task fields/columns
+#define COLPADSTR   " "
+#define COLPADSIZ   ( sizeof(COLPADSTR) - 1 )
+   // continuation ch when field/column truncated
+#define COLPLUSCH   '+'
+
    // support for keyboard stuff (cursor motion keystrokes, mostly)
 #define kbd_ENTER  '\n'
 #define kbd_ESC    '\033'
@@ -176,9 +183,9 @@ enum pflag {
 #endif
 };
 
-        /* The scaling 'type' used with scale_num() -- this is how
+        /* The scaling 'type' used with scale_unum() -- this is how
            the passed number is interpreted should scaling be necessary */
-enum scale_num {
+enum scale_unum {
    SK_no, SK_Kb, SK_Mb, SK_Gb, SK_Tb
 };
 
@@ -196,12 +203,11 @@ typedef int (*QFP_t)(const void *, const void *);
            in a variety of display roles. */
 typedef struct FLD_t {
    const char   *head;          // name for col heads + toggle/reorder fields
-   const char   *fmts;          // snprintf format string for field display
-   const int     width;         // field width, if applicable
-   const int     scale;         // scale_num type, if applicable
+   int           width;         // field width, if applicable
+   const int     scale;         // scale_unum type, if applicable
+   const int     align;         // the default column alignment flag
    const QFP_t   sort;          // sort function
    const int     lflg;          // PROC_FILLxxx flag(s) needed by this field
-   const char   *desc;          // description for fields management
 } FLD_t;
 
 #ifdef OFF_HST_HASH
@@ -281,6 +287,7 @@ typedef struct CPU_t {
 #define Show_FOREST  0x000002     // 'V' - show cmd/cmdlines with ascii art
 #define Qsrt_NORMAL  0x000004     // 'R' - reversed column sort (high to low)
         // these flag(s) have no command as such - they're for internal use
+#define INFINDS_xxx  0x010000     // build rows for find_string, not display
 #define EQUWINS_xxx  0x000001     // rebalance all wins & tasks (off i,n,u/U)
 
         // Default flags if there's no rcfile to provide user customizations
@@ -387,7 +394,7 @@ typedef struct WIN_t {
 #define ENUpos(w,E)  ((int)((FLG_t*)memchr((w)->pflgsall, E, (w)->totpflgs) - (w)->pflgsall))
 
         // Support for variable width columns (and potentially scrolling too)
-#define VARcol(E)    (NULL == Fieldstab[E].fmts)
+#define VARcol(E)    (-1 == Fieldstab[E].width)
 #ifndef SCROLLVAR_NO
 #ifdef USE_X_COLHDR
 #define VARright(w)  (1 == w->maxpflgs && VARcol(w->procflgs[0]))
@@ -544,10 +551,6 @@ typedef struct WIN_t {
       "Usr", USR_FIELDS } \
    } }
 
-        /* The format string used with variable width columns --
-           see 'calibrate_fields' for supporting logic. */
-#define VARCOL_fmts  "%-*.*s "
-
         /* Summary Lines specially formatted string(s) --
            see 'show_special' for syntax details + other cautions. */
 #define LOADAV_line  "%s -%s\n"
@@ -601,10 +604,17 @@ typedef struct WIN_t {
 /*------  Small Utility routines  ----------------------------------------*/
 //atic float         get_float (const char *prompt);
 //atic int           get_int (const char *prompt);
-//atic const char   *scale_num (unsigned long num, const int width, const int type);
-//atic const char   *scale_tics (TIC_t tics, const int width);
+//atic inline const char *hex_make (KLONG num, int noz);
 //atic const char   *user_certify (WIN_t *q, const char *str, char typ);
 //atic inline int    user_matched (WIN_t *q, const proc_t *p);
+/*------  Basic Formatting support  --------------------------------------*/
+//atic inline const char *justify_pad (const char *str, int width, int justr);
+//atic const char   *make_chr (const char ch, int width, int justr);
+//atic const char   *make_num (long num, int width, int justr);
+//atic const char   *make_str (const char *str, int width, int justr);
+//atic const char   *scale_pcnt (float num, int width, int justr);
+//atic const char   *scale_tics (TIC_t tics, int width, int justr);
+//atic const char   *scale_unum (unsigned long num, int type, int width, int justr);
 /*------  Fields Management support  -------------------------------------*/
 /*atic FLD_t         Fieldstab[] = { ... }                                */
 //atic void          adj_geometry (void);
@@ -657,7 +667,7 @@ typedef struct WIN_t {
 //atic void          do_key (int ch);
 //atic void          summary_hlp (CPU_t *cpu, const char *pfx);
 //atic void          summary_show (void);
-//atic void          task_show (const WIN_t *q, const proc_t *p, char *ptr);
+//atic const char   *task_show (const WIN_t *q, const proc_t *p);
 //atic int           window_show (WIN_t *q, int wmax);
 /*------  Entry point plus two  ------------------------------------------*/
 //atic void          frame_hlp (int wix, int max);