Skip to content

Commit

Permalink
Add option to have peristent history
Browse files Browse the repository at this point in the history
Signed-off-by: Yan Burman <[email protected]>
  • Loading branch information
yanburman committed Mar 7, 2019
1 parent 417b901 commit a55d39e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 4 deletions.
1 change: 1 addition & 0 deletions examples/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ int main(int argc, char *argv[])
.history_size = 10,
.app_name = "example_cli",
.prompt = "my_cli",
.hist_file = "/tmp/icli_history",
.cmd_hook = cli_cmd_hook,
.out_hook = cli_out_hook,
.err_hook = cli_err_hook};
Expand Down
47 changes: 43 additions & 4 deletions icli.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <assert.h>
#include <sys/queue.h>
#include <termios.h>
#include <errno.h>

#include <editline/readline.h>

Expand Down Expand Up @@ -71,7 +72,7 @@ struct icli {
struct icli_command *curr_cmd;
char *curr_prompt;
const char *prompt;

const char *hist_file;
int rows;
int cols;
int curr_row;
Expand Down Expand Up @@ -936,6 +937,7 @@ int icli_register_command(struct icli_command_params *params, struct icli_comman
int icli_init(struct icli_params *params)
{
memset(&icli, 0, sizeof(icli));
int ret = 0;

icli.root_cmd = calloc(1, sizeof(struct icli_command));
if (!icli.root_cmd) {
Expand All @@ -951,20 +953,48 @@ int icli_init(struct icli_params *params)
icli.user_data = params->user_data;

icli.prompt = strdup(params->prompt);
if (!icli.prompt) {
icli_api_printf("Unable to allocate memory for prompt\n");
ret = -1;
goto err;
}

if (params->hist_file) {
icli.hist_file = strdup(params->hist_file);
if (!icli.hist_file) {
icli_api_printf("Unable to allocate memory for hist_file\n");
ret = -1;
goto err;
}
}

icli.cmd_hook = params->cmd_hook;
icli.out_hook = params->out_hook;
icli.err_hook = params->err_hook;

/* Allow conditional parsing of the ~/.inputrc file. */
rl_readline_name = strdup(params->app_name);
if (!rl_readline_name) {
icli_api_printf("Unable to allocate memory for rl_readline_name\n");
ret = -1;
goto err;
}

/* Tell the completer that we want a crack first. */
rl_attempted_completion_function = icli_completion;

using_history();
stifle_history(params->history_size);

if (icli.hist_file) {
ret = read_history(icli.hist_file);
if (ret && ret != ENOENT) {
icli_api_printf("Unable to read history from %s (%d)\n", icli.hist_file, ret);
ret = -1;
goto err;
}
}

rl_get_screen_size(&icli.rows, &icli.cols);

icli_build_prompt(icli.curr_cmd);
Expand All @@ -977,7 +1007,7 @@ int icli_init(struct icli_params *params)
.argc = 1,
.argv = execute_args}};
struct icli_command *commands[array_len(cmd_params)] = {};
int ret = icli_register_commands(cmd_params, commands, array_len(cmd_params));
ret = icli_register_commands(cmd_params, commands, array_len(cmd_params));
if (ret) {
goto err;
}
Expand All @@ -1001,8 +1031,6 @@ void icli_cleanup(void)
{
icli_clean_command(icli.root_cmd);

rl_callback_handler_remove();

HISTORY_STATE *hist_state = history_get_history_state();
HIST_ENTRY **mylist = history_list();

Expand All @@ -1012,13 +1040,24 @@ void icli_cleanup(void)
free(mylist);
free(hist_state);

if (icli.hist_file) {
int ret = write_history(icli.hist_file);
if (ret)
icli_api_printf("Unable to save history to %s (%d)\n", icli.hist_file, ret);
}

clear_history();

rl_callback_handler_remove();

free(rl_readline_name);
rl_readline_name = "";

free((void *)icli.prompt);
free((void *)icli.curr_prompt);
free((void *)icli.hist_file);

memset(&icli, 0, sizeof(icli));
}

void icli_run(void)
Expand Down
1 change: 1 addition & 0 deletions icli.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ struct icli_params {
int history_size; /**< how many commands to keep in history */
const char *app_name; /**< name of application for interfacing ~/.inputrc */
const char *prompt; /**< prompt string (will be post-fixed by "> " */
const char *hist_file; /**< history file to load/store history. can be NULL for not saving history */
icli_cmd_hook_t cmd_hook; /**< hook to be called before command is executed */
icli_output_hook_t out_hook; /**< hook to be called when there is output */
icli_output_hook_t err_hook; /**< hook to be called when there is error print */
Expand Down

0 comments on commit a55d39e

Please sign in to comment.