summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Luke <chrisy@flirble.org>2016-04-25 13:49:15 -0400
committerDave Barach <openvpp@barachs.net>2016-04-27 13:32:48 +0000
commit6b90fe323107b218019739ce8bb4429f83f218be (patch)
tree4b54094d43dc3ecc5b216b26c4a7394664813817
parent572d81213a216fd8e86f17e0b8a6bb72479c893f (diff)
Add "history" CLI command
- Remove the '?' mechanism that previously only worked on telnet connections in favor of a more shell-like "history" command. The '?' approach had strange side-effects, like executing what was already in the command buffer. Change-Id: I043086b7f400c66c332a32dbd06ef580ecb18ee8 Signed-off-by: Chris Luke <chrisy@flirble.org>
-rw-r--r--vlib/vlib/unix/cli.c72
1 files changed, 48 insertions, 24 deletions
diff --git a/vlib/vlib/unix/cli.c b/vlib/vlib/unix/cli.c
index 601995619c8..c6b8cd2b449 100644
--- a/vlib/vlib/unix/cli.c
+++ b/vlib/vlib/unix/cli.c
@@ -114,7 +114,13 @@ typedef struct {
u8 ** command_history;
u8 * current_command;
i32 excursion;
+
+ /* Maximum number of history entries this session will store. */
u32 history_limit;
+
+ /* Current command line counter */
+ u32 command_number;
+
u8 * search_key;
int search_mode;
@@ -160,7 +166,6 @@ typedef enum {
UNIX_CLI_PARSE_ACTION_CLEAR,
UNIX_CLI_PARSE_ACTION_REVSEARCH,
UNIX_CLI_PARSE_ACTION_FWDSEARCH,
- UNIX_CLI_PARSE_ACTION_HISTORY,
UNIX_CLI_PARSE_ACTION_YANK,
UNIX_CLI_PARSE_ACTION_TELNETIAC,
@@ -237,9 +242,6 @@ static unix_cli_parse_actions_t unix_cli_parse_strings[] = {
_( CTL('S'), UNIX_CLI_PARSE_ACTION_FWDSEARCH ),
_( CTL('R'), UNIX_CLI_PARSE_ACTION_REVSEARCH ),
- /* TODO: replace with 'history' command? */
- _( "?", UNIX_CLI_PARSE_ACTION_HISTORY ),
-
/* Other protocol things */
_( "\xff", UNIX_CLI_PARSE_ACTION_TELNETIAC ), /* IAC */
_( "\0", UNIX_CLI_PARSE_ACTION_NOACTION ), /* NUL */
@@ -695,23 +697,6 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm,
case UNIX_CLI_PARSE_ACTION_NOACTION:
break;
- case UNIX_CLI_PARSE_ACTION_HISTORY:
- /* Erase the current command (if any)*/
- for (j = cf->cursor; j < (vec_len (cf->current_command)); j++)
- unix_vlib_cli_output_cooked (cf, uf, (u8 *) " ", 1);
- for (j = 0; j < (vec_len (cf->current_command)); j++)
- unix_vlib_cli_output_cooked (cf, uf, (u8 *) "\b \b", 3);
-
- unix_vlib_cli_output_cooked (cf, uf, (u8 *) "\nHistory:\n", 10);
-
- for (j = 0; j < vec_len (cf->command_history); j++)
- {
- unix_vlib_cli_output_cooked (cf, uf, cf->command_history[j],
- vec_len(cf->command_history[j]));
- unix_vlib_cli_output_cooked (cf, uf, (u8 *) "\n", 1);
- }
- goto crlf;
-
case UNIX_CLI_PARSE_ACTION_REVSEARCH:
case UNIX_CLI_PARSE_ACTION_FWDSEARCH:
if (cf->search_mode == 0)
@@ -1029,12 +1014,23 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm,
/* Don't add blank lines to the cmd history */
if (vec_len (cf->current_command) > 2)
{
+ /* Don't duplicate the previous command */
_vec_len (cf->current_command) -= 2;
- vec_add1 (cf->command_history, cf->current_command);
- cf->current_command = 0;
+ j = vec_len(cf->command_history);
+ if (j == 0 ||
+ (vec_len (cf->current_command) != vec_len (cf->command_history[j - 1]) ||
+ memcmp(cf->current_command, cf->command_history[j - 1],
+ vec_len (cf->current_command)) != 0))
+ {
+ vec_add1 (cf->command_history, cf->current_command);
+ cf->current_command = 0;
+ cf->command_number ++;
+ }
+ else
+ vec_reset_length (cf->current_command);
}
else
- vec_reset_length (cf->current_command);
+ vec_reset_length (cf->current_command);
cf->excursion = 0;
cf->search_mode = 0;
vec_reset_length (cf->search_key);
@@ -1786,6 +1782,34 @@ VLIB_CLI_COMMAND (cli_unix_show_errors, static) = {
};
static clib_error_t *
+unix_cli_show_history (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ unix_cli_main_t * cm = &unix_cli_main;
+ unix_cli_file_t * cf;
+ int i, j;
+
+ cf = pool_elt_at_index (cm->cli_file_pool, cm->current_input_file_index);
+
+ i = 1 + cf->command_number - vec_len(cf->command_history);
+
+ for (j = 0; j < vec_len (cf->command_history); j++)
+ {
+ vlib_cli_output (vm, "%d %v\n", i + j, cf->command_history[j]);
+ }
+
+ return 0;
+}
+
+VLIB_CLI_COMMAND (cli_unix_cli_show_history, static) = {
+ .path = "history",
+ .short_help = "Show current session command history",
+ .function = unix_cli_show_history,
+};
+
+
+static clib_error_t *
unix_cli_init (vlib_main_t * vm)
{
return 0;