From f37a794ccd52c449890247c64fae17c1001b1bb5 Mon Sep 17 00:00:00 2001 From: Jefferson Delfes Date: Mon, 4 Nov 2013 15:33:59 -0400 Subject: rl_helper: add history command management We need a growable buffer which will store a list of command strings. So when we press up or down keys, our line buffer is replaced with old commands that we typed. This also fix a possible bug, when we pass a copy of line buffer to line processing callback. So we will not have problems if we change its value (eg strtok). --- rl_helper.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/rl_helper.c b/rl_helper.c index b066600..62a5cbe 100644 --- a/rl_helper.c +++ b/rl_helper.c @@ -60,6 +60,9 @@ size_t pos = 0; char seq[MAX_SEQ]; /* sequence buffer (escape codes) */ size_t seq_pos = 0; const char *prompt = "> "; +char **history = NULL; /* pointer to history buffer */ +int hs_len = 0; /* how much pointers we have in history buffer */ +int hs_cur = 0; /* current position of up/down keys navigation */ typedef struct { char sequence[MAX_SEQ]; @@ -223,8 +226,20 @@ bool rl_feed(int c) { break; case '\r': case '\n': - putchar('\n'); - line_cb(lnbuf); + if (strlen(lnbuf) > 0) { + char *dup = strdup(lnbuf); + /* alloc space in history buffer to new string pointer */ + hs_len++; + history = realloc(history, hs_len * sizeof(history[0])); + history[hs_len - 1] = strdup(lnbuf); + putchar('\n'); + line_cb(dup); /* send a copy, so we can change it */ + free(dup); + } else + /* don't parse empty lines */ + putchar('\n'); + + hs_cur = hs_len; rl_clear(); rl_reprint_prompt(); break; @@ -238,8 +253,27 @@ bool rl_feed(int c) { } break; case K_UP: + if (hs_cur > 0) { + /* we have more history commands up */ + hs_cur--; + strcpy(lnbuf, history[hs_cur]); + pos = strlen(history[hs_cur]); + rl_reprint_prompt(); + } + break; case K_DOWN: - /* history handle */ + if (hs_cur < hs_len - 1) { + /* we have more history commands down */ + hs_cur++; + strcpy(lnbuf, history[hs_cur]); + pos = strlen(history[hs_cur]); + rl_reprint_prompt(); + } else if (hs_cur == hs_len - 1) { + /* we don't have more commands down, let's clear the prompt */ + hs_cur++; + rl_clear(); + rl_reprint_prompt(); + } break; case K_RIGHT: if (pos < strlen(lnbuf)) { -- cgit v1.2.3