Mercurial > flash_v2
changeset 1032:f5fa0e095f5e
Add RedBoot command history
| author | msalter |
|---|---|
| date | Tue, 20 May 2003 18:43:51 +0000 |
| parents | 6b4a1f23fbbb |
| children | 8f7a10771d67 |
| files | packages/redboot/current/ChangeLog packages/redboot/current/cdl/redboot.cdl packages/redboot/current/doc/redboot.sgml packages/redboot/current/src/io.c |
| diffstat | 4 files changed, 162 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/redboot/current/ChangeLog +++ b/packages/redboot/current/ChangeLog @@ -1,3 +1,9 @@ +2003-05-20 Mark Salter <msalter@redhat.com> + + * cdl/redboot.cdl (CYGBLD_REDBOOT_CMD_LINE_HISTORY): New option. + * src/io.c: Support history command and history expansion. + * doc/redboot.sgml: Document command history support. + 2003-05-14 Mark Salter <msalter@redhat.com> * src/flash.c (flash_get_config): Add CONFIG_NETPORT case.
--- a/packages/redboot/current/cdl/redboot.cdl +++ b/packages/redboot/current/cdl/redboot.cdl @@ -128,6 +128,17 @@ cdl_package CYGPKG_REDBOOT { enable rudimentary editting of the lines themselves." } + cdl_option CYGBLD_REDBOOT_CMD_LINE_HISTORY { + display "Enable history command and expansion" + requires { CYGNUM_REDBOOT_CMD_LINE_EDITING > 0 } + flavor bool + default_value 1 + description " + Enabling this option will allow RedBoot to provide a history command + to list previous commands. Also enables history expansion via '!' + character similar to bash shell." + } + cdl_option CYGBLD_BUILD_REDBOOT_WITH_ZLIB { display "Include support gzip/zlib decompression" active_if CYGPKG_COMPRESS_ZLIB
--- a/packages/redboot/current/doc/redboot.sgml +++ b/packages/redboot/current/doc/redboot.sgml @@ -223,6 +223,39 @@ value for the start-up script; it must a </itemizedlist></para> </sect1> +<sect1 id="RedBoot-Command-History"> +<title>RedBoot Command History</title> +<para> +<indexterm><primary>RedBoot</primary><secondary>command history</secondary></indexterm> +<indexterm><primary>command history</primary></indexterm> +<indexterm><primary>commands</primary><secondary>history</secondary></indexterm> +RedBoot provides support for listing and repeating previously entered commands. A +list of previously entered commands may be obtained by typing <command>history</command> +at the command line: +<screen> +RedBoot> <userinput>history</userinput> + 0 fis list + 1 fconfig -l + 2 load -m ymodem + 3 history +</screen> +</para><para> +The following history expansions may be used to execute commands in the history list: +<itemizedlist> +<listitem><para> +!! repeats last command. +</para></listitem> +<listitem><para> +!<userinput>n</userinput> repeats command <userinput>n</userinput>. +</para></listitem> +<listitem><para> +!<userinput>string</userinput> repeats most recent command starting with +<userinput>string</userinput>. +</para></listitem> +</itemizedlist> +</para> +</sect1> + <sect1 id="startup-mode"> <title>RedBoot Startup Mode</title> <para>
--- a/packages/redboot/current/src/io.c +++ b/packages/redboot/current/src/io.c @@ -8,7 +8,7 @@ //####ECOSGPLCOPYRIGHTBEGIN#### // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc. // Copyright (C) 2002 Gary Thomas // // eCos is free software; you can redistribute it and/or modify it under @@ -296,6 +296,17 @@ getc_script(char *cp) } #endif +#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0 +#define _CL_NUM_LINES CYGNUM_REDBOOT_CMD_LINE_EDITING // Number of lines to keep +static char _cl_lines[_CL_NUM_LINES][CYGPKG_REDBOOT_MAX_CMD_LINE]; +static int _cl_index = -1; // Last known command line +static int _cl_max_index = -1; // Last command in buffers + +#ifdef CYGBLD_REDBOOT_CMD_LINE_HISTORY +static void expand_history(char *); +#endif +#endif + // // Read a line of input from the user // Return: @@ -304,6 +315,15 @@ getc_script(char *cp) // _GETS_TIMEOUT: No input before timeout // _GETS_CTRLC: ^C typed // +// if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0 +// Command line history support +// ^P - Select previous line from history +// ^N - Select next line from history +// ^A - Move insertion [cursor] to start of line +// ^E - Move cursor to end of line +// ^B - Move cursor back [previous character] +// ^F - Move cursor forward [next character] +// int _rb_gets_preloaded(char *buf, int buflen, int timeout) { @@ -314,19 +334,6 @@ int static char last_ch = '\0'; int _timeout; #if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0 -// -// Command line history support -// ^P - Select previous line from history -// ^N - Select next line from history -// ^A - Move insertion [cursor] to start of line -// ^E - Move cursor to end of line -// ^B - Move cursor back [previous character] -// ^F - Move cursor forward [next character] -// -#define _CL_NUM_LINES CYGNUM_REDBOOT_CMD_LINE_EDITING // Number of lines to keep - static char _cl_lines[_CL_NUM_LINES][CYGPKG_REDBOOT_MAX_CMD_LINE]; - static int _cl_index = -1; // Last known command line - static int _cl_max_index = -1; // Last command in buffers int _index = _cl_index; // Last saved line char *xp; #endif @@ -490,11 +497,16 @@ int } last_ch = c; #if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0 - if (cmd_history && (buf != eol)) { - // Save current line - only when enabled - if (++_cl_index == _CL_NUM_LINES) _cl_index = 0; - if (_cl_index > _cl_max_index) _cl_max_index = _cl_index; - strcpy(_cl_lines[_cl_index], buf); + if (cmd_history) { + // History handling - only when enabled +#ifdef CYGBLD_REDBOOT_CMD_LINE_HISTORY + expand_history(buf); +#endif + if (*buf != '\0') { + if (++_cl_index == _CL_NUM_LINES) _cl_index = 0; + if (_cl_index > _cl_max_index) _cl_max_index = _cl_index; + strcpy(_cl_lines[_cl_index], buf); + } } #endif return _GETS_OK; @@ -649,3 +661,84 @@ verify_action_with_timeout(int timeout, va_start(ap, fmt); return _verify_action(timeout, fmt, ap); } + + +#ifdef CYGBLD_REDBOOT_CMD_LINE_HISTORY +// parse for history index number. Return number or -1 if not +// an index number. +static int +parse_history_index(char *s) +{ + int val = 0; + + while ('0' <= *s && *s <= '9') + val = (val * 10) + (*s++ - '0'); + + if (*s) + return -1; + + return val; +} + +// Check input line to see if it needs history expansion. If so, +// try to find matching command and replace buffer as appropriate. +static void +expand_history(char *buf) +{ + int ncmds = _cl_max_index + 1; + int i, index, len; + + if (buf[0] != '!' || buf[1] == '\0') + return; + + if (ncmds > 0) { + if (!strcmp(buf, "!!")) { + strcpy(buf, _cl_lines[_cl_index]); + return; + } + if ((index = parse_history_index(buf + 1)) >= 0) { + if (index <= _cl_max_index) { + strcpy(buf, _cl_lines[index]); + return; + } + } + len = strlen(buf + 1); + for (i = 0, index = _cl_index; i < ncmds; i++) { + if (!strncmp(_cl_lines[index], buf+1, len)) { + strcpy(buf, _cl_lines[index]); + return; + } + if (--index < 0) + index = _cl_max_index; + } + } + + diag_printf("%s: event not found\n", buf); + *buf = '\0'; +} + +static void +do_history(int argc, char *argv[]) +{ + int ncmds = _cl_max_index + 1; + int i, index; + + if (_cl_index == _cl_max_index) { + // history has not wrapped around + for (i = 0; i < ncmds; i++) + diag_printf("%3d %s\n", i, _cl_lines[i]); + } else { + for (i = 0, index = _cl_index + 1; i < ncmds; i++) { + diag_printf("%3d %s\n", i, _cl_lines[index++]); + if (index > _cl_max_index) + index = 0; + } + } +} + +RedBoot_cmd("history", + "Display command history", + "", + do_history + ); +#endif // CYGBLD_REDBOOT_CMD_LINE_HISTORY
