diff --git a/top/top.c b/top/top.c index 56d785be..3ec422f4 100644 --- a/top/top.c +++ b/top/top.c @@ -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, diff --git a/top/top.h b/top/top.h index ef0ce188..78ecdac0 100644 --- a/top/top.h +++ b/top/top.h @@ -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' diff --git a/top/top_nls.c b/top/top_nls.c index 668836aa..e539c5c0 100644 --- a/top/top_nls.c +++ b/top/top_nls.c @@ -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:"); } diff --git a/top/top_nls.h b/top/top_nls.h index 73e6c716..6a116ccb 100644 --- a/top/top_nls.h +++ b/top/top_nls.h @@ -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,