From 978a26968998216cf6c4e249d734c357a8f81c49 Mon Sep 17 00:00:00 2001 From: Nate Bargmann Date: Mon, 18 Feb 2013 20:42:42 -0600 Subject: [PATCH] rigctl_parse.c: Implement history recall Implement first cut at storing and recalling history. At this point history is retained for the current session only. History is stored as complete command lines even if values are entered at separate prompts. Readline allows editing and even deleting recalled history lines. --- tests/rigctl.c | 16 ++++++++++ tests/rigctl_parse.c | 75 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/tests/rigctl.c b/tests/rigctl.c index f53904d88..edf85e814 100644 --- a/tests/rigctl.c +++ b/tests/rigctl.c @@ -48,6 +48,19 @@ extern char *readline (); /* no readline */ #endif /* HAVE_LIBREADLINE */ +#ifdef HAVE_READLINE_HISTORY +# if defined(HAVE_READLINE_HISTORY_H) +# include +# elif defined(HAVE_HISTORY_H) +# include +# else /* !defined(HAVE_HISTORY_H) */ +extern void add_history (); +extern int write_history (); +extern int read_history (); +# endif /* defined(HAVE_READLINE_HISTORY_H) */ + /* no history */ +#endif /* HAVE_READLINE_HISTORY */ + #include #include "misc.h" @@ -351,6 +364,9 @@ int main (int argc, char *argv[]) if (interactive && prompt && have_rl) { rl_readline_name = "rigctl"; +#ifdef HAVE_READLINE_HISTORY + using_history(); +#endif } #endif /* HAVE_LIBREADLINE */ diff --git a/tests/rigctl_parse.c b/tests/rigctl_parse.c index 11bb989d7..c822f7272 100644 --- a/tests/rigctl_parse.c +++ b/tests/rigctl_parse.c @@ -48,6 +48,19 @@ extern char *readline (); /* no readline */ #endif /* HAVE_LIBREADLINE */ +#ifdef HAVE_READLINE_HISTORY +# if defined(HAVE_READLINE_HISTORY_H) +# include +# elif defined(HAVE_HISTORY_H) +# include +# else /* !defined(HAVE_HISTORY_H) */ +extern void add_history (); +extern int write_history (); +extern int read_history (); +# endif /* defined(HAVE_READLINE_HISTORY_H) */ + /* no history */ +#endif /* HAVE_READLINE_HISTORY */ + #include #include "misc.h" @@ -90,6 +103,11 @@ static char *input_line = (char *)NULL; static char *result = (char *)NULL; static char *parsed_input[sizeof(char) * 5]; static const int have_rl = 1; + +#ifdef HAVE_READLINE_HISTORY +static char *rp_hist_buf = (char *)NULL; +#endif + #else /* no readline */ static const int have_rl = 0; #endif @@ -605,6 +623,13 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc) if (interactive && prompt && have_rl) { int j, x; +#ifdef HAVE_READLINE_HISTORY + /* Minimum space for 32+1+32+1+128+1+128+1+128+1 = 453 chars, so + * allocate 512 chars cleared to zero for safety. + */ + rp_hist_buf = (char *)calloc(512, sizeof(char)); +#endif + rl_instream = fin; rl_outstream = fout; @@ -659,12 +684,19 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc) } /* At this point parsed_input contains the typed text of the command - * with surrounding space characters removed. + * with surrounding space characters removed. If Readline History is + * available, copy the command string into a history buffer. */ /* Single character command */ if ((strlen(parsed_input[0]) == 1) && (*parsed_input[0] != '\\')) { cmd = *parsed_input[0]; + +#ifdef HAVE_READLINE_HISTORY + /* Store what is typed, not validated, for history. */ + if (rp_hist_buf) + strncpy(rp_hist_buf, parsed_input[0], 1); +#endif } /* Test the command token, parsed_input[0] */ else if ((*parsed_input[0] == '\\') && (strlen(parsed_input[0]) > 1)) { @@ -677,6 +709,10 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc) if (strlen(parsed_input[0] + 1) >= MAXNAMSIZ) *(parsed_input[0] + MAXNAMSIZ) = '\0'; +#ifdef HAVE_READLINE_HISTORY + if (rp_hist_buf) + strncpy(rp_hist_buf, parsed_input[0], MAXNAMSIZ); +#endif /* The starting position of the source string is the first * character past the initial '\'. Using MAXNAMSIZ for the * length leaves enough space for the '\0' string terminator in the @@ -763,6 +799,12 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc) if (strlen(parsed_input[x]) >= MAXNAMSIZ) *(parsed_input[x] + (MAXNAMSIZ - 1)) = '\0'; +#ifdef HAVE_READLINE_HISTORY + if (rp_hist_buf) { + strncat(rp_hist_buf, " ", 1); + strncat(rp_hist_buf, parsed_input[x], MAXNAMSIZ); + } +#endif /* Sanity check, VFO names are alpha only. */ for (j = 0; j < MAXNAMSIZ && parsed_input[x][j] != '\0'; j++) { if (!(isalpha(parsed_input[x][j]))) { @@ -822,6 +864,12 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc) if (strlen(parsed_input[x]) > MAXARGSZ) parsed_input[x][MAXARGSZ] = '\0'; +#ifdef HAVE_READLINE_HISTORY + if (rp_hist_buf) { + strncat(rp_hist_buf, " ", 1); + strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); + } +#endif strcpy(arg1, parsed_input[x]); p1 = arg1; } @@ -864,6 +912,12 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc) if (strlen(parsed_input[x]) > MAXARGSZ) parsed_input[x][MAXARGSZ] = '\0'; +#ifdef HAVE_READLINE_HISTORY + if (rp_hist_buf) { + strncat(rp_hist_buf, " ", 1); + strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); + } +#endif strcpy(arg1, parsed_input[x]); p1 = arg1; } @@ -904,6 +958,12 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc) if (strlen(parsed_input[x]) > MAXARGSZ) parsed_input[x][MAXARGSZ] = '\0'; +#ifdef HAVE_READLINE_HISTORY + if (rp_hist_buf) { + strncat(rp_hist_buf, " ", 1); + strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); + } +#endif strcpy(arg2, parsed_input[x]); p2 = arg2; } @@ -944,9 +1004,22 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc) if (strlen(parsed_input[x]) > MAXARGSZ) parsed_input[x][MAXARGSZ] = '\0'; +#ifdef HAVE_READLINE_HISTORY + if (rp_hist_buf) { + strncat(rp_hist_buf, " ", 1); + strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); + } +#endif strcpy(arg3, parsed_input[x]); p3 = arg3; } +#ifdef HAVE_READLINE_HISTORY + if (rp_hist_buf) { + add_history(rp_hist_buf); + free(rp_hist_buf); + rp_hist_buf = (char *)NULL; + } +#endif } #endif /* HAVE_LIBREADLINE */