top: provides a new user 'message log' display ability

Messages issued by top will be displayed for only 1.25
seconds. And while this length of time would appear to
be acceptable (given the absence of complaints), there
will be times when a specific message might be missed.

So, this commit offers users the opportunity to recall
up to 10 of the most recent messages that were issued.

[ we'll just exploit top's new bottom window feature ]

Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
Jim Warner 2022-06-02 00:00:00 -05:00 committed by Craig Small
parent 15a6203b00
commit 3901dcb9c9
4 changed files with 47 additions and 8 deletions

View File

@ -105,14 +105,17 @@ static int Screen_cols, Screen_rows, Max_lines;
/* These 'SCREEN_ROWS', 'BOT_ and 'Bot_' guys are used
in managing the special separate bottom 'window' ... */
#define SCREEN_ROWS ( Screen_rows - Bot_rsvd )
#define BOT_MAXIMUM 10 // Bot_item array's max size
#define BOT_DELIMIT -1 // fencepost with item array
#define BOT_ITEMMAX 10 // Bot_item array's max size
#define BOT_MSGSMAX 10 // total entries for Msg_tab
#define BOT_UNFOCUS -1 // tab focus not established
// a negative 'item' won't be seen by build_headers() ...
// negative 'item' values won't be seen by build_headers() ...
#define BOT_DELIMIT -1 // fencepost with item array
#define BOT_ITEM_NS -2 // data for namespaces req'd
#define BOT_MSG_LOG -3 // show the most recent msgs
// next 4 are used when toggling window contents
#define BOT_SEP_CMA ','
#define BOT_SEP_SLS '/'
#define BOT_SEP_SMI ';'
#define BOT_SEP_SPC ' '
// 1 for horizontal separator
#define BOT_RSVD 1
@ -125,7 +128,7 @@ static int Bot_task,
Bot_what,
Bot_rsvd,
Bot_indx = BOT_UNFOCUS,
Bot_item[BOT_MAXIMUM] = { BOT_DELIMIT };
Bot_item[BOT_ITEMMAX] = { BOT_DELIMIT };
static char Bot_sep,
*Bot_head,
Bot_buf[BOTBUFSIZ]; // the 'environ' can be huge
@ -843,9 +846,19 @@ static void capsmk (WIN_t *q) {
} // end: capsmk
static struct msg_node {
char msg[SMLBUFSIZ];
struct msg_node *prev;
} Msg_tab[BOT_MSGSMAX];
static struct msg_node *Msg_this = Msg_tab;
/*
* Show an error message (caller may include '\a' for sound) */
static void show_msg (const char *str) {
STRLCPY(Msg_this->msg, str);
if (++Msg_this > &Msg_tab[BOT_MSGSMAX - 1]) Msg_this = Msg_tab;
PUTT("%s%s %.*s %s%s%s"
, tg2(0, Msg_row)
, Curwin->capclr_msg
@ -4619,6 +4632,10 @@ static void wins_stage_1 (void) {
Winstk[GROUPSMAX - 1].next = &Winstk[0];
Winstk[0].prev = &Winstk[GROUPSMAX - 1];
Curwin = Winstk;
for (i = 1; i < BOT_MSGSMAX; i++)
Msg_tab[i].prev = &Msg_tab[i - 1];
Msg_tab[0].prev = &Msg_tab[BOT_MSGSMAX -1];
} // end: wins_stage_1
@ -4937,7 +4954,7 @@ static void bot_do (const char *str, int focus) {
* ( returns relative # of elements printed ) | */
static int bot_focus_str (const char *hdr, const char *str) {
#define maxRSVD ( Screen_rows - 1 )
const char *end, *beg;
char *beg, *end;
char tmp[BIGBUFSIZ];
int n, x;
@ -5050,9 +5067,25 @@ static struct {
static void *bot_item_hlp (struct pids_stack *p) {
static char buf[BIGBUFSIZ];
char tmp[SMLBUFSIZ], *b;
struct msg_node *m;
int i;
switch (Bot_what) {
case BOT_MSG_LOG:
*(b = &buf[0]) = '\0';
m = Msg_this->prev;
do {
if (m->msg[0]) {
b = scat(b, m->msg);
if (m != Msg_this && m->prev->msg[0]) {
// caller itself may have used fmtmk, so we'll old school it ...
snprintf(tmp, sizeof(tmp), "%c ", BOT_SEP_SMI);
b = scat(b, tmp);
}
}
m = m->prev;
} while (m != Msg_this->prev);
return buf;
case BOT_ITEM_NS:
*(b = &buf[0]) = '\0';
for (i = 0; i < MAXTBL(ns_tab); i++) {
@ -5528,6 +5561,9 @@ static void keys_global (int ch) {
// with string vectors, the 'separator' may serve a different purpose
bot_item_toggle(eu_CMDLINE_V, N_fmt(X_BOT_cmdlin_fmt), BOT_SEP_SPC);
break;
case kbd_CtrlL:
bot_item_toggle(BOT_MSG_LOG, N_txt(X_BOT_msglog_txt), BOT_SEP_SMI);
break;
case kbd_CtrlN:
// with string vectors, the 'separator' may serve a different purpose
bot_item_toggle(eu_ENVIRON_V, N_fmt(X_BOT_envirn_fmt), BOT_SEP_SPC);
@ -6412,7 +6448,7 @@ static void do_key (int ch) {
{ keys_global,
{ '?', 'B', 'd', 'E', 'e', 'f', 'g', 'H', 'h'
, 'I', 'k', 'r', 's', 'X', 'Y', 'Z', '0'
, kbd_CtrlE, kbd_CtrlG, kbd_CtrlI, kbd_CtrlK
, kbd_CtrlE, kbd_CtrlG, kbd_CtrlI, kbd_CtrlK, kbd_CtrlL
, kbd_CtrlN, kbd_CtrlP, kbd_CtrlR, kbd_CtrlU
, kbd_ENTER, kbd_SPACE, kbd_BTAB, '\0' } },
{ keys_summary,

View File

@ -180,6 +180,7 @@ char *strcasestr(const char *haystack, const char *needle);
#define kbd_CtrlG '\007'
#define kbd_CtrlI '\011'
#define kbd_CtrlK '\013'
#define kbd_CtrlL '\014'
#define kbd_CtrlN '\016'
#define kbd_CtrlO '\017'
#define kbd_CtrlP '\020'

View File

@ -596,6 +596,7 @@ static void build_norm_nlstab (void) {
Norm_nlstab[X_BOT_envirn_fmt] = _("environment for pid %d, %s");
Norm_nlstab[X_BOT_namesp_fmt] = _("namespaces for pid %d, %s");
Norm_nlstab[X_BOT_supgrp_fmt] = _("supplementary groups for pid %d, %s");
Norm_nlstab[X_BOT_msglog_txt] = _("message log, last 10 messages:");
}

View File

@ -85,8 +85,9 @@ enum norm_nls {
WORD_process_txt, WORD_threads_txt, WRITE_rcfile_fmt, WRONG_switch_fmt,
XTRA_badflds_fmt, XTRA_fixwide_fmt, XTRA_modebad_txt, XTRA_size2up_txt,
XTRA_vforest_fmt, XTRA_warncfg_txt, XTRA_warnold_txt, XTRA_winsize_txt,
X_BOT_cmdlin_fmt, X_BOT_ctlgrp_fmt, X_BOT_envirn_fmt, X_BOT_namesp_fmt,
X_BOT_supgrp_fmt, X_RESTRICTED_txt, X_SEMAPHORES_fmt, X_THREADINGS_fmt,
X_BOT_cmdlin_fmt, X_BOT_ctlgrp_fmt, X_BOT_envirn_fmt, X_BOT_msglog_txt,
X_BOT_namesp_fmt, X_BOT_supgrp_fmt, X_RESTRICTED_txt, X_SEMAPHORES_fmt,
X_THREADINGS_fmt,
YINSP_demo01_txt, YINSP_demo02_txt, YINSP_demo03_txt, YINSP_deqfmt_txt,
YINSP_deqtyp_txt, YINSP_dstory_txt,
YINSP_failed_fmt, YINSP_noent1_txt, YINSP_noent2_txt, YINSP_pidbad_fmt,