summaryrefslogtreecommitdiff
path: root/top.h
blob: 804eec40c2d2a68472240b70d9a62bc6b44d5c99 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
/* top.h - Header file:         show Linux processes */
/*
 * Copyright (c) 2002-2011, by: James C. Warner
 *    All rights reserved.      8921 Hilloway Road
 *                              Eden Prairie, Minnesota 55347 USA
 *
 * This file may be used subject to the terms and conditions of the
 * GNU Library General Public License Version 2, or any later version
 * at your option, as published by the Free Software Foundation.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 */
/* For contributions to this program, the author wishes to thank:
 *    Craig Small, <csmall@small.dropbear.id.au>
 *    Albert D. Cahalan, <albert@users.sf.net>
 */
#ifndef _Itop
#define _Itop

        /* Development/Debugging defines ----------------------------------- */
//#define ATEOJ_RPTHSH            /* report on hash specifics, at end-of-job */
//#define ATEOJ_RPTSTD            /* report on misc stuff, at end-of-job     */
//#define CASEUP_HEXES            /* show any hex values in upper case       */
//#define CASEUP_SUFIX            /* show time/mem/cnts suffix in upper case */
//#define EQUCOLHDRYES            /* yes, do equalize column header lengths  */
//#define FIELD_CURSOR            /* cursor follows selection w/ fields mgmt */
//#define OFF_HST_HASH            /* use BOTH qsort+bsrch vs. hashing scheme */
//#define OFF_STDIOLBF            /* disable our own stdout _IOFBF override  */
//#define OOMEM_ENABLE            /* enable the SuSE out-of-memory additions *
//#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   */
//#define RCFILE_NOERR            /* rcfile errs silently default, vs. fatal */
//#define RESIZE_LIMIT            /* enable limits on lower sigwinch bounds  */
//#define RMAN_IGNORED            /* don't consider auto right margin glitch */
//#define STRCMPNOCASE            /* use strcasecmp vs. strcmp when sorting  */
//#define TERMIOS_ONLY            /* just limp along with native input only  */
//#define TTYGETENVYES            /* environ vars can override tty col/row   */
//#define USE_X_COLHDR            /* emphasize header vs. whole col, for 'x' */


/*######  Notes, etc.  ###################################################*/

        /* The following convention is used to identify those areas where
           adaptations for hotplugging are to be found ...
              *** hotplug_acclimated ***
           ( hopefully libproc will also be supportive of our efforts ) */

        /* And there are still some of these lurking here and there...
              FIXME - blah, blah... */

        /* For introducing inaugural cgroup support, thanks to:
              Jan Gorig <jgorig@redhat.com> - April, 2011 */


#ifdef PRETEND2_5_X
#define linux_version_code LINUX_VERSION(2,5,43)
#endif

#ifdef STRCMPNOCASE
#define STRSORTCMP  strcasecmp
#else
#define STRSORTCMP  strcmp
#endif

#ifdef OOMEM_ENABLE
        /* FIXME: perhaps making this a function in the suse version of
           sysinfo.c was a prelude to hotpluggable updates -- unfortunately,
           the return value is invariant as currently implemented! */
#define SMP_NUM_CPUS  smp_num_cpus()
#else
#define SMP_NUM_CPUS  smp_num_cpus
#endif


/*######  Some Miscellaneous constants  ##################################*/

        /* The default delay twix updates */
#define DEF_DELAY  3.0

        /* Length of time a 'message' is displayed (in microseconds) */
#define MSG_USLEEP  (useconds_t)1250000

        /* Specific process id monitoring support (command line only) */
#define MONPIDMAX  20

        /* Miscellaneous buffers with liberal values and some other defines
           -- mostly just to pinpoint source code usage/dependancies */
#ifdef RESIZE_LIMIT
#define SCRCOLMIN    16
#define SCRROWMIN     8
#endif
#define SCREENMAX   512
   /* the above might seem pretty stingy, until you consider that with every
      one of top's fields displayed it's less than 200 bytes of column header
      -- so SCREENMAX provides for all fields plus a 300+ byte command line */
#define CAPBUFSIZ    32
#define CLRBUFSIZ    64
#define PFLAGSSIZ    64
#define SMLBUFSIZ   128
#define MEDBUFSIZ   256
#define LRGBUFSIZ   512
#define OURPATHSZ  1024
#define BIGBUFSIZ  2048
   /* in addition to the actual display data, our row might have to accomodate
      many termcap/color transitions - these definitions ensure we have room */
#define ROWMINSIZ  ( SCREENMAX +  4 * (CAPBUFSIZ + CLRBUFSIZ) )
#define ROWMAXSIZ  ( SCREENMAX + 16 * (CAPBUFSIZ + CLRBUFSIZ) )

   // support for keyboard stuff (cursor motion keystrokes, mostly)
#define kbd_ENTER  '\n'
#define kbd_ESC    '\033'
#define kbd_SPACE  ' '
#define kbd_UP     '\x81'
#define kbd_DOWN   '\x82'
#define kbd_RIGHT  '\x83'
#define kbd_LEFT   '\x84'
#define kbd_PGUP   '\x85'
#define kbd_PGDN   '\x86'
#define kbd_END    '\x87'
#define kbd_HOME   '\x88'
#define kbd_BKSP   '\x89'
#define kbd_INS    '\x8a'
#define kbd_DEL    '\x8b'


/* #####  Enum's and Typedef's  ############################################ */

        /* Flags for each possible field (and then some) --
           these MUST be kept in sync with the FLD_t Fieldstab[] array !! */
enum pflag {
   P_PID = 0, P_PPD,
   P_UED, P_UEN, P_URD, P_URN, P_USD, P_USN,
   P_GID, P_GRP, P_PGD, P_TTY, P_TPG, P_SID,
   P_PRI, P_NCE, P_THD,
   P_CPN, P_CPU, P_TME, P_TM2,
   P_MEM, P_VRT, P_SWP, P_RES, P_COD, P_DAT, P_SHR,
   P_FL1, P_FL2, P_DRT,
   P_STA, P_CMD, P_WCH, P_FLG, P_CGR,
#ifdef OOMEM_ENABLE
   P_OOA, P_OOM,
#endif
#ifdef USE_X_COLHDR
   // not really pflags, used with tbl indexing
   P_MAXPFLGS
#else
   // not really pflags, used with tbl indexing & col highlighting
   P_MAXPFLGS, X_XON, X_XOF
#endif
};

        /* The scaling 'type' used with scale_num() -- this is how
           the passed number is interpreted should scaling be necessary */
enum scale_num {
   SK_no, SK_Kb, SK_Mb, SK_Gb, SK_Tb
};

        /* This typedef just ensures consistent 'process flags' handling */
typedef unsigned FLG_t;

        /* These typedefs attempt to ensure consistent 'ticks' handling */
typedef unsigned long long TIC_t;
typedef          long long SIC_t;

        /* Sort support, callback function signature */
typedef int (*QFP_t)(const void *, const void *);

        /* This structure consolidates the information that's used
           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
   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
        /* This structure supports 'history' processing and ultimately records
           one piece of critical information from one frame to the next --
           we don't calc and save data that goes unused like the old top. */
typedef struct HST_t {
   TIC_t tics;                  // last frame's tics count
   int   pid;                   // record 'key'
} HST_t;
#else
        /* This structure supports 'history' processing and ultimately records
           one piece of critical information from one frame to the next --
           we don't calc and save data that goes unused like the old top nor
           do we incure the overhead of sorting to support a binary search
           (or worse, a friggin' for loop) when retrieval is necessary! */
typedef struct HST_t {
   TIC_t tics;                  // last frame's tics count
   int   pid;                   // record 'key'
   int   lnk;                   // next on hash chain
} HST_t;
#endif

        /* This structure stores a frame's cpu tics used in history
           calculations.  It exists primarily for SMP support but serves
           all environments. */
typedef struct CPU_t {
   /* other kernels: u == user/us, n == nice/ni, s == system/sy, i == idle/id
      2.5.41 kernel: w == IO-wait/wa (io wait time)
      2.6.0  kernel: x == hi (hardware irq time), y == si (software irq time)
      2.6.11 kernel: z == st (virtual steal time) */
   TIC_t u, n, s, i, w, x, y, z; // as represented in /proc/stat
   TIC_t u_sav, s_sav, n_sav, i_sav, w_sav, x_sav, y_sav, z_sav; // in the order of our display
   unsigned id;  // the CPU ID number
} CPU_t;


        /* /////////////////////////////////////////////////////////////// */
        /* Special Section: multiple windows/field groups  --------------- */
        /* ( kind of a header within a header: constants, types & macros ) */

#define CAPTABMAX  9             /* max entries in each win's caps table   */
#define GROUPSMAX  4             /* the max number of simultaneous windows */
#define WINNAMSIZ  4             /* size of RCW_t winname buf (incl '\0')  */
#define GRPNAMSIZ  WINNAMSIZ+2   /* window's name + number as in: '#:...'  */

        /* The Persistent 'Mode' flags!
           These are preserved in the rc file, as a single integer and the
           letter shown is the corresponding 'command' toggle */
        // 'View_' flags affect the summary (minimum), taken from 'Curwin'
#define View_CPUSUM  0x008000     // '1' - show combined cpu stats (vs. each)
#define View_LOADAV  0x004000     // 'l' - display load avg and uptime summary
#define View_STATES  0x002000     // 't' - display task/cpu(s) states summary
#define View_MEMORY  0x001000     // 'm' - display memory summary
#define View_NOBOLD  0x000008     // 'B' - disable 'bold' attribute globally
#define View_SCROLL  0x080000     // 'C' - enable coordinates msg w/ scrolling
        // 'Show_' & 'Qsrt_' flags are for task display in a visible window
#define Show_COLORS  0x000800     // 'z' - show in color (vs. mono)
#define Show_HIBOLD  0x000400     // 'b' - rows and/or cols bold (vs. reverse)
#define Show_HICOLS  0x000200     // 'x' - show sort column emphasized
#define Show_HIROWS  0x000100     // 'y' - show running tasks highlighted
#define Show_CMDLIN  0x000080     // 'c' - show cmdline vs. name
#define Show_CTIMES  0x000040     // 'S' - show times as cumulative
#define Show_IDLEPS  0x000020     // 'i' - show idle processes (all tasks)
#define Show_TASKON  0x000010     // '-' - tasks showable when Mode_altscr
#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 EQUWINS_xxx  0x000001     // rebalance all wins & tasks (off 'i'/ 'n')

        // Default flags if there's no rcfile to provide user customizations
#define DEF_WINFLGS ( View_LOADAV | View_STATES | View_CPUSUM | View_MEMORY \
   | Show_HIBOLD | Show_HIROWS | Show_IDLEPS | Show_TASKON | Qsrt_NORMAL )

        /* These are used to direct wins_reflag */
enum reflag_enum {
   Flags_TOG, Flags_SET, Flags_OFF
};

        /* These are used to direct win_warn */
enum warn_enum {
   Warn_ALT, Warn_VIZ
};

        /* This type helps support both a window AND the rcfile */
typedef struct RCW_t {  // the 'window' portion of an rcfile
   FLG_t  sortindx;             // sort field, represented as a procflag
   int    winflags,             // 'view', 'show' and 'sort' mode flags
          maxtasks,             // user requested maximum, 0 equals all
          summclr,                      // color num used in summ info
          msgsclr,                      //        "       in msgs/pmts
          headclr,                      //        "       in cols head
          taskclr;                      //        "       in task rows
   char   winname [WINNAMSIZ],          // window name, user changeable
          fieldscur [PFLAGSSIZ];        // fields displayed and ordered
} RCW_t;

        /* This represents the complete rcfile */
typedef struct RCF_t {
   int    mode_altscr;          // 'A' - Alt display mode (multi task windows)
   int    mode_irixps;          // 'I' - Irix vs. Solaris mode (SMP-only)
   float  delay_time;           // 'd'/'s' - How long to sleep twixt updates
   int    win_index;            // Curwin, as index
   RCW_t  win [GROUPSMAX];      // a 'WIN_t.rc' for each window
} RCF_t;

        /* This structure stores configurable information for each window.
           By expending a little effort in its creation and user requested
           maintainence, the only real additional per frame cost of having
           windows is an extra sort -- but that's just on pointers! */
typedef struct WIN_t {
   FLG_t  pflgsall [PFLAGSSIZ],        // all 'active/on' fieldscur, as enum
          procflgs [PFLAGSSIZ];        // fieldscur subset, as enum
   RCW_t  rc;                          // stuff that gets saved in the rcfile
   int    winnum,          // a window's number (array pos + 1)
          winlines,        // current task window's rows (volatile)
          maxpflgs,        // number of displayed procflgs ("on" in fieldscur)
          totpflgs,        // total of displayable procflgs in pflgsall array
          begpflg,         // scrolled beginning pos into pflgsall array
          endpflg,         // scrolled ending pos into pflgsall array
          begtask,         // scrolled beginning pos into Frame_maxtask
          varcolsz,        // max length of variable width column(s)
          usrseluid,       // validated uid for 'u/U' user selection
          usrseltyp,       // the basis for matching above uid
          hdrcaplen;       // column header xtra caps len, if any
   char   capclr_sum [CLRBUFSIZ],      // terminfo strings built from
          capclr_msg [CLRBUFSIZ],      //   RCW_t colors (& rebuilt too),
          capclr_pmt [CLRBUFSIZ],      //   but NO recurring costs !
          capclr_hdr [CLRBUFSIZ],      //   note: sum, msg and pmt strs
          capclr_rowhigh [CLRBUFSIZ],  //         are only used when this
          capclr_rownorm [CLRBUFSIZ],  //         window is the 'Curwin'!
          cap_bold [CAPBUFSIZ],        // support for View_NOBOLD toggle
          grpname [GRPNAMSIZ],         // window number:name, printable
#ifdef USE_X_COLHDR
          columnhdr [ROWMINSIZ],       // column headings for procflgs
#else
          columnhdr [SCREENMAX],       // column headings for procflgs
#endif
         *captab [CAPTABMAX];          // captab needed by show_special()
   struct WIN_t *next,                 // next window in window stack
                *prev;                 // prior window in window stack
} WIN_t;

        // Used to test/manipulate the window flags
#define CHKw(q,f)    (int)((q)->rc.winflags & (f))
#define TOGw(q,f)    (q)->rc.winflags ^=  (f)
#define SETw(q,f)    (q)->rc.winflags |=  (f)
#define OFFw(q,f)    (q)->rc.winflags &= ~(f)
#define ALTCHKw      (Rc.mode_altscr ? 1 : win_warn(Warn_ALT))
#define VIZISw(q)    (!Rc.mode_altscr || CHKw(q,Show_TASKON))
#define VIZCHKw(q)   (VIZISw(q)) ? 1 : win_warn(Warn_VIZ)
#define VIZTOGw(q,f) (VIZISw(q)) ? TOGw(q,(f)) : win_warn(Warn_VIZ)

        // Used to test/manipulte fieldscur values
#define FLDget(q,i)  ((FLG_t)((q)->rc.fieldscur[i] & 0x7f) - FLD_OFFSET)
#define FLDtog(q,i)  ((q)->rc.fieldscur[i] ^= 0x80)
#define FLDviz(q,i)  ((q)->rc.fieldscur[i] &  0x80)

        /* Special Section: end ------------------------------------------ */
        /* /////////////////////////////////////////////////////////////// */


/*######  Some Miscellaneous Macro definitions  ##########################*/

        /* Yield table size as 'int' */
#define MAXTBL(t)  (int)(sizeof(t) / sizeof(t[0]))

        /* A null-terminating strncpy, assuming strlcpy is not available.
           ( and assuming callers don't need the string length returned ) */
#define STRLCPY(dst,src) { strncpy(dst, src, sizeof(dst)); dst[sizeof(dst) - 1] = '\0'; }

        /* Used to clear all or part of our Pseudo_screen */
#define PSU_CLREOS(y) memset(&Pseudo_screen[ROWMAXSIZ*y], '\0', Pseudo_size-(ROWMAXSIZ*y))

        /* Used as return arguments in *some* of the sort callbacks */
#define SORT_lt  ( Frame_srtflg > 0 ?  1 : -1 )
#define SORT_gt  ( Frame_srtflg > 0 ? -1 :  1 )
#define SORT_eq  0

        /* Used to create *most* of the sort callback functions
           note: some of the callbacks are NOT your father's callbacks, they're
                 highly optimized to save them ol' precious cycles! */
#define SCB_NAME(f) sort_P_ ## f
#define SCB_NUM1(f,n) \
   static int SCB_NAME(f) (const proc_t **P, const proc_t **Q) { \
      if ( (*P)->n < (*Q)->n ) return SORT_lt; \
      if ( (*P)->n > (*Q)->n ) return SORT_gt; \
      return SORT_eq; }
#define SCB_NUM2(f,n1,n2) \
   static int SCB_NAME(f) (const proc_t **P, const proc_t **Q) { \
      if ( ((*P)->n1 - (*P)->n2) < ((*Q)->n1 - (*Q)->n2) ) return SORT_lt; \
      if ( ((*P)->n1 - (*P)->n2) > ((*Q)->n1 - (*Q)->n2) ) return SORT_gt; \
      return SORT_eq; }
#define SCB_NUMx(f,n) \
   static int SCB_NAME(f) (const proc_t **P, const proc_t **Q) { \
      return Frame_srtflg * ( (*Q)->n - (*P)->n ); }
#define SCB_STRS(f,s) \
   static int SCB_NAME(f) (const proc_t **P, const proc_t **Q) { \
      return Frame_srtflg * STRSORTCMP((*Q)->s, (*P)->s); }
#define SCB_STRV(f,b,v,s) \
   static int SCB_NAME(f) (const proc_t **P, const proc_t **Q) { \
      if (b) { \
         if (!(*P)->v || !(*Q)->v) return SORT_eq; \
         return Frame_srtflg * STRSORTCMP((*Q)->v[0], (*P)->v[0]); } \
      return Frame_srtflg * STRSORTCMP((*Q)->s, (*P)->s); }

/*
 * The following two macros are used to 'inline' those portions of the
 * display process requiring formatting, while protecting against any
 * potential embedded 'millesecond delay' escape sequences.
 */
        /**  PUTT - Put to Tty (used in many places)
               . for temporary, possibly interactive, 'replacement' output
               . may contain ANY valid terminfo escape sequences
               . need NOT represent an entire screen row */
#define PUTT(fmt,arg...) do { \
      char _str[ROWMAXSIZ]; \
      snprintf(_str, sizeof(_str), fmt, ## arg); \
      putp(_str); \
   } while (0)

        /**  PUFF - Put for Frame (used in only 3 places)
               . for more permanent frame-oriented 'update' output
               . may NOT contain cursor motion terminfo escapes
               . assumed to represent a complete screen ROW
               . subject to optimization, thus MAY be discarded */
#define PUFF(fmt,arg...) do { \
      char _str[ROWMAXSIZ]; \
      snprintf(_str, sizeof(_str), fmt, ## arg); \
      if (Batch) putp(_str); \
      else { \
         char *_ptr = &Pseudo_screen[Pseudo_row * ROWMAXSIZ]; \
         if (Pseudo_row + 1 < Screen_rows) ++Pseudo_row; \
         if (!strcmp(_ptr, _str)) putp("\n"); \
         else { \
            strcpy(_ptr, _str); \
            putp(_ptr); } } \
   } while (0)

        /* Orderly end, with any sort of message - see fmtmk */
#define debug_END(s) { \
           static void error_exit (const char *); \
           fputs(Cap_clr_scr, stdout); \
           error_exit(s); \
        }

        /* A poor man's breakpoint, if he's too lazy to learn gdb */
#define its_YOUR_fault { *((char *)0) = '!'; }


/*######  Display Support *Data*  ########################################*/

        /* Configuration files support */
#define SYS_RCFILESPEC  "/etc/toprc"
#define RCF_EYECATCHER  "Config File (Linux processes with windows)\n"
#define RCF_VERSION_ID  'f'

        /* The default fields displayed and their order, if nothing is
           specified by the loser, oops user.
           note: any *contiguous* ascii sequence can serve as fieldscur
                 characters as long as the initial value is coordinated
                 with that specified for FLD_OFFSET
           ( we're providing for up to 55 fields initially, )
           ( with values chosen to avoid the need to escape ) */
#define FLD_OFFSET  '%'
   //   seq_fields  "%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ["
#define DEF_FIELDS  "¥¨³´»½ÀÄ·º¹Å&')*+,-./012568<>?ABCFGHIJKLMNOPQRSTUVWXYZ["
        /* Pre-configured windows/field groups */
#define JOB_FIELDS  "¥¦¹·º³´Ä»¼½§Å()*+,-./012568>?@ABCFGHIJKLMNOPQRSTUVWXYZ["
#define MEM_FIELDS  "¥º»¼½¾¿ÀÁÃij´·Å&'()*+,-./0125689BFGHIJKLMNOPQRSTUVWXYZ["
#define USR_FIELDS  "¥¦§¨ª°¹·ºÄÅ)+,-./1234568;<=>?@ABCFGHIJKLMNOPQRSTUVWXYZ["

        /* The default values for the local config file */
#define DEF_RCFILE { \
   0, 1, DEF_DELAY, 0, { \
   { P_CPU, DEF_WINFLGS, 0, \
      COLOR_RED, COLOR_RED, COLOR_YELLOW, COLOR_RED, \
      "Def", DEF_FIELDS }, \
   { P_PID, DEF_WINFLGS, 0, \
      COLOR_CYAN, COLOR_CYAN, COLOR_WHITE, COLOR_CYAN, \
      "Job", JOB_FIELDS }, \
   { P_MEM, DEF_WINFLGS, 0, \
      COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLUE, COLOR_MAGENTA, \
      "Mem", MEM_FIELDS }, \
   { P_UEN, DEF_WINFLGS, 0, \
      COLOR_YELLOW, COLOR_YELLOW, COLOR_GREEN, COLOR_YELLOW, \
      "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"
#define LOADAV_line_alt  "%s\06 -%s\n"
#define STATES_line1  "%s:\03" \
   " %3u \02total,\03 %3u \02running,\03 %3u \02sleeping,\03 %3u \02stopped,\03 %3u \02zombie\03\n"
#define STATES_line2x4  "%%%s\03" \
   " %#5.1f  \02user,\03 %#5.1f  \02system,\03 %#5.1f  \02nice,\03 %#5.1f  \02idle\03\n"
        /* These are the STATES_line evolutions
              lnx 2.5.x, procps-3.0.5  : IO-wait = i/o wait time
              lnx 2.6.x, procps-3.1.12 : IO-wait now wa, hi = hard irq, si = soft irq
              lnx 2.7.x, procps-3.2.7  : st = steal time */
#define STATES_line2x5  "%%%s\03" \
   " %#5.1f  \02user,\03 %#5.1f  \02system,\03 %#5.1f  \02nice,\03 %#5.1f  \02idle,\03 %#5.1f  \02IO-wait\03\n"
#define STATES_line2x6  "%%%s\03" \
   " %#5.1f \02us,\03 %#5.1f \02sy,\03 %#5.1f \02ni,\03 %#5.1f \02id,\03 %#5.1f \02wa,\03 %#5.1f \02hi,\03 %#5.1f \02si\03\n"
#define STATES_line2x7  "%%%s\03" \
   "%#5.1f \02us,\03%#5.1f \02sy,\03%#5.1f \02ni,\03%#5.1f \02id,\03%#5.1f \02wa,\03%#5.1f \02hi,\03%#5.1f \02si,\03%#5.1f \02st\03\n"
#define MEMORY_twolines  \
   "%s Mem: \03 %8lu \02total,\03 %8lu \02used,\03 %8lu \02free,\03 %8lu \02buffers\03\n" \
   "%s Swap:\03 %8lu \02total,\03 %8lu \02used,\03 %8lu \02free,\03 %8lu \02cached\03\n"

        /* Keyboard Help specially formatted string(s) --
           see 'show_special' for syntax details + other cautions. */
#define KEYS_help \
   "Help for Interactive Commands\02 - %s\n" \
   "Window \01%s\06: \01Cumulative mode \03%s\02.  \01System\06: \01Delay \03%.1f secs\02; \01Secure mode \03%s\02.\n" \
   "\n" \
   "  Z\05,\01B\05       Global: '\01Z\02' change color mappings; '\01B\02' disable/enable bold\n" \
   "  l,t,m     Toggle Summaries: '\01l\02' load avg; '\01t\02' task/cpu stats; '\01m\02' mem info\n" \
   "  1,I       Toggle SMP view: '\0011\02' single/separate states; '\01I\02' Irix/Solaris mode\n" \
   "  f,F       Manage Fields: add/remove; change order; select sort field\n" \
   "\n" \
   "  <,>     . Move sort field: '\01<\02' next col left; '\01>\02' next col right\n" \
   "  R,H     . Toggle: '\01R\02' normal/reverse sort; '\01H\02' show threads\n" \
   "  c,i,S   . Toggle: '\01c\02' cmd name/line; '\01i\02' idle tasks; '\01S\02' cumulative time\n" \
   "  x\05,\01y\05     . Toggle highlights: '\01x\02' sort field; '\01y\02' running tasks\n" \
   "  z\05,\01b\05     . Toggle: '\01z\02' color/mono; '\01b\02' bold/reverse (only if 'x' or 'y')\n" \
   "  u,U     . Show: '\01u\02' effective user; '\01U\02' real, saved, file or effective user\n" \
   "  n or #  . Set maximum tasks displayed\n" \
   "  C,...   . Toggle scroll coordinates msg for: \01up\02,\01down\02,\01left\02,right\02,\01home\02,\01end\02\n" \
   "\n" \
   "%s" \
   "  W         Write configuration file\n" \
   "  q         Quit\n" \
   "          ( commands shown with '.' require a \01visible\02 task display \01window\02 ) \n" \
   "Press '\01h\02' or '\01?\02' for help with \01Windows\02,\n" \
   "any other key to continue " \
   ""

        /* This guy goes into the help text (maybe) */
#define KEYS_help_unsecured \
   "  k,r       Manipulate tasks: '\01k\02' kill; '\01r\02' renice\n" \
   "  d or s    Set update interval\n" \
   ""

        /* Fields Management specially formatted string(s) --
           see 'show_special' for syntax details + other cautions */
#define FIELDS_heading \
   "%sFields Management\02 for window \01%s\06, whose current sort field is \01%s\02\n" \
   "   Navigate with Up/Dn, Right selects for move then <Enter> or Left commits,\n" \
   "   'd' or <Space> toggles display, 's' sets sort.  Use 'q' or <Esc> to end! " \
   ""

#ifdef OOMEM_ENABLE
        /* w/ 2 extra lines, no room for additional text on 24x80 terminal */
#define FIELDS_notes  NULL
#else
        /* Extra explanatory text which could accompany the Fields display.
           note: the newlines cannot actually be used, they just serve as
                 substring delimiters for the 'display_fields' routine. */
#define FIELDS_notes \
   "Note(s):\n" \
   "  Use the 'a' & 'w' keys to cycle\n" \
   "  through all available windows.\n" \
   ""
/* no room in FIELDS_notes, sacrificed w/ 35 fields displayed .... */
/* "  If a sort field is not displayed,\n"                         */
/* "  the '<' & '>' keys are inactive.\n"                          */
#endif

#define FIELDS_flags \
   "Flags field:\n" \
   "  0x00000001  PF_ALIGNWARN\n" \
   "  0x00000002  PF_STARTING\n" \
   "  0x00000004  PF_EXITING\n" \
   "  0x00000040  PF_FORKNOEXEC\n" \
   "  0x00000100  PF_SUPERPRIV\n" \
   "  0x00000200  PF_DUMPCORE\n" \
   "  0x00000400  PF_SIGNALED\n" \
   "  0x00000800  PF_MEMALLOC\n" \
   "  0x00002000  PF_FREE_PAGES (2.5)\n" \
   "  0x00008000  debug flag (2.5)\n" \
   "  0x00024000  special threads (2.5)\n" \
   "  0x001D0000  special states (2.5)\n" \
   "  0x00100000  PF_USEDFPU (thru 2.4)\n" \
   ""
/* no room in FIELDS_flags, sacrificed w/ 26 fields displayed .... */
/* ( PF_MEMDIE ==  'Killed for out-of-memory' )                    */
/* "  0x00001000  PF_MEMDIE (2.5)\n"                               */

        /* Colors Help specially formatted string(s) --
           see 'show_special' for syntax details + other cautions. */
#define COLOR_help \
   "Help for color mapping\02 - %s\n" \
   "current window: \01%s\06\n" \
   "\n" \
   "   color - 04:25:44 up 8 days, 50 min,  7 users,  load average:\n" \
   "   Tasks:\03  64 \02total,\03   2 \03running,\03  62 \02sleeping,\03   0 \02stopped,\03\n" \
   "   %%Cpu(s):\03  76.5 \02user,\03  11.2 \02system,\03   0.0 \02nice,\03  12.3 \02idle\03\n" \
   "   \01 Nasty Message! \04  -or-  \01Input Prompt\05\n" \
   "   \01  PID TTY     PR  NI %%CPU    TIME+   VIRT SWAP S COMMAND    \06\n" \
   "   17284 \10pts/2  \07  8   0  0.0   0:00.75  1380    0 S /bin/bash   \10\n" \
   "   \01 8601 pts/1    7 -10  0.4   0:00.03   916    0 R color -b -z\07\n" \
   "   11005 \10?      \07  9   0  0.0   0:02.50  2852 1008 S amor -sessi\10\n" \
   "   available toggles: \01B\02 =disable bold globally (\01%s\02),\n" \
   "       \01z\02 =color/mono (\01%s\02), \01b\02 =tasks \"bold\"/reverse (\01%s\02)\n" \
   "\n" \
   "Select \01target\02 as upper case letter:\n" \
   "   S\02 = Summary Data,\01  M\02 = Messages/Prompts,\n" \
   "   H\02 = Column Heads,\01  T\02 = Task Information\n" \
   "Select \01color\02 as number:\n" \
   "   0\02 = black,\01  1\02 = red,    \01  2\02 = green,\01  3\02 = yellow,\n" \
   "   4\02 = blue, \01  5\02 = magenta,\01  6\02 = cyan, \01  7\02 = white\n" \
   "\n" \
   "Selected: \01target\02 \01 %c \04; \01color\02 \01 %d \04\n" \
   "   press 'q' to abort changes to window '\01%s\02'\n" \
   "   press 'a' or 'w' to commit & change another, <Enter> to commit and end " \
   ""

        /* Windows/Field Group Help specially formatted string(s) --
           see 'show_special' for syntax details + other cautions. */
#define WINDOWS_help \
   "Help for Windows / Field Groups\02 - \"Current Window\" = \01 %s \06\n" \
   "\n" \
   ". Use multiple \01windows\02, each with separate config opts (color,fields,sort,etc)\n" \
   ". The 'current' window controls the \01Summary Area\02 and responds to your \01Commands\02\n" \
   "  . that window's \01task display\02 can be turned \01Off\02 & \01On\02, growing/shrinking others\n" \
   "  . with \01NO\02 task display, some commands will be \01disabled\02 ('i','R','n','c', etc)\n" \
   "    until a \01different window\02 has been activated, making it the 'current' window\n" \
   ". You \01change\02 the 'current' window by: \01 1\02) cycling forward/backward;\01 2\02) choosing\n" \
   "  a specific field group; or\01 3\02) exiting the color mapping or fields screens\n" \
   ". Commands \01available anytime   -------------\02\n" \
   "    A       . Alternate display mode toggle, show \01Single\02 / \01Multiple\02 windows\n" \
   "    g       . Choose another field group and make it 'current', or change now\n" \
   "              by selecting a number from: \01 1\02 =%s;\01 2\02 =%s;\01 3\02 =%s; or\01 4\02 =%s\n" \
   ". Commands \01requiring\02 '\01A\02' mode\01  -------------\02\n" \
   "    G       . Change the \01Name\05 of the 'current' window/field group\n" \
   " \01*\04  a , w   . Cycle through all four windows:  '\01a\05' Forward; '\01w\05' Backward\n" \
   " \01*\04  - , _   . Show/Hide:  '\01-\05' \01Current\02 window; '\01_\05' all \01Visible\02/\01Invisible\02\n" \
   "  The screen will be divided evenly between task displays.  But you can make\n" \
   "  some \01larger\02 or \01smaller\02, using '\01n\02' and '\01i\02' commands.  Then later you could:\n" \
   " \01*\04  = , +   . Rebalance tasks:  '\01=\05' \01Current\02 window; '\01+\05' \01Every\02 window\n" \
   "              (this also forces the \01current\02 or \01every\02 window to become visible)\n" \
   "\n" \
   "In '\01A\02' mode, '\01*\04' keys are your \01essential\02 commands.  Please try the '\01a\02' and '\01w\02'\n" \
   "commands plus the 'g' sub-commands NOW.  Press <Enter> to make 'Current' " \
   ""


/*######  For Piece of mind  #############################################*/

        /* just sanity check(s)... */
#if defined(ATEOJ_RPTHSH) && defined(OFF_HST_HASH)
# error 'ATEOJ_RPTHSH' conflicts with 'OFF_HST_HASH'
#endif
#if defined(PRETEND4CPUS) && defined (OOMEM_ENABLE)
# error 'PRETEND4CPUS' conflicts with 'OOMEM_ENABLE'
#endif


/*######  Some Prototypes (ha!)  #########################################*/

   /* These 'prototypes' are here solely for documentation purposes */
/*------  Sort callbacks  ------------------------------------------------*/
/*        for each possible field, in the form of:                        */
/*atic int           sort_P_XXX (const proc_t **P, const proc_t **Q);     */
/*------  Tiny useful routine(s)  ----------------------------------------*/
//atic const char   *fmtmk (const char *fmts, ...);
//atic inline char  *scat (char *dst, const char *src);
//atic char         *strim (char *str);
//atic const char   *tg2 (int x, int y);
/*------  Exit/Interrput routines  ---------------------------------------*/
//atic void          bye_bye (const char *str);
//atic void          error_exit (const char *str);
//atic void          pause_pgm (void);
//atic void          sig_endpgm (int dont_care_sig);
//atic void          sig_paused (int dont_care_sig);
//atic void          sig_resize (int dont_care_sig);
/*------  Misc Color/Display support  ------------------------------------*/
//atic void          capsmk (WIN_t *q);
//atic void          msg_save (const char *fmts, ...);
//atic void          show_msg (const char *str);
//atic int           show_pmt (const char *str);
//atic inline void   show_scroll (void);
//atic void          show_special (int interact, const char *glob);
/*------  Low Level Memory/Keyboard support  -----------------------------*/
//atic void         *alloc_c (size_t num);
//atic void         *alloc_r (void *ptr, size_t num);
//atic int           chin (int ech, char *buf, unsigned cnt);
//atic int           keyin (int init);
//atic char         *linein (const char *prompt);
/*------  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 const char   *user_certify (WIN_t *q, const char *str, char typ);
//atic inline int    user_matched (WIN_t *q, const proc_t *p);
/*------  Fields Management support  -------------------------------------*/
/*atic FLD_t         Fieldstab[] = { ... }                                */
//atic void          adj_geometry (void);
//atic void          calibrate_fields (void);
//atic void          display_fields (int focus, int extend, const char *xtra);
//atic void          fields_utility (void);
//atic void          zap_fieldstab (void);
/*------  Library Interface  ---------------------------------------------*/
//atic CPU_t        *cpus_refresh (CPU_t *cpus);
#ifdef OFF_HST_HASH
//atic inline HST_t *hstbsrch (HST_t *hst, int max, int pid);
#else
//atic inline HST_t *hstget (int pid);
//atic inline void   hstput (unsigned idx);
#endif
//atic void          prochlp (proc_t *p);
//atic proc_t      **procs_refresh (proc_t **ppt);
/*------  Startup routines  ----------------------------------------------*/
//atic void          before (char *me);
//atic void          configs_read (void);
//atic void          parse_args (char **args);
//atic void          whack_terminal (void);
/*------  Windows/Field Groups support  ----------------------------------*/
//atic void          win_names (WIN_t *q, const char *name);
//atic WIN_t        *win_select (char ch);
//atic int           win_warn (int what);
//atic void          winsclrhlp (WIN_t *q, int save);
//atic void          wins_colors (void);
//atic void          wins_reflag (int what, int flg);
//atic void          wins_stage_1 (void);
//atic void          wins_stage_2 (void);
/*------  Interactive Input support (do_key helpers)  --------------------*/
//atic void          file_writerc (void);
//atic void          help_view (void);
//atic void          keys_global (int ch);
//atic void          keys_summary (int ch);
//atic void          keys_task (int ch);
//atic void          keys_window (int ch);
//atic void          keys_xtra (int ch);
/*------  Main Screen routines  ------------------------------------------*/
//atic void          do_key (int ch);
//atic void          summaryhlp (CPU_t *cpu, const char *pfx);
//atic proc_t      **summary_show (void);
//atic void          task_show (const WIN_t *q, const proc_t *p);
//atic int           window_show (proc_t **ppt, WIN_t *q, int wmax);
/*------  Entry point plus two  ------------------------------------------*/
//atic void          framehlp (int wix, int max);
//atic void          frame_make (void);
//     int           main (int dont_care_argc, char **argv);

#endif /* _Itop */