diff options
author | Chris Luke <chrisy@flirble.org> | 2016-04-25 13:49:15 -0400 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2016-04-27 13:32:48 +0000 |
commit | 6b90fe323107b218019739ce8bb4429f83f218be (patch) | |
tree | 4b54094d43dc3ecc5b216b26c4a7394664813817 | |
parent | 572d81213a216fd8e86f17e0b8a6bb72479c893f (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.c | 72 |
1 files changed, 48 insertions, 24 deletions
diff --git a/vlib/vlib/unix/cli.c b/vlib/vlib/unix/cli.c index 60199561..c6b8cd2b 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; |