This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
RedBoot command history
- From: Mark Salter <msalter at redhat dot com>
- To: ecos-patches at sources dot redhat dot com
- Date: Tue, 20 May 2003 14:44:44 -0400 (EDT)
- Subject: RedBoot command history
Index: redboot/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/ChangeLog,v
retrieving revision 1.110
diff -u -p -5 -r1.110 ChangeLog
--- redboot/current/ChangeLog 14 May 2003 20:12:54 -0000 1.110
+++ redboot/current/ChangeLog 20 May 2003 18:40:58 -0000
@@ -1,5 +1,11 @@
+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.
2003-05-13 Nick Garnett <nickg@balti.calivar.com>
Index: redboot/current/cdl/redboot.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/cdl/redboot.cdl,v
retrieving revision 1.48
diff -u -p -5 -r1.48 redboot.cdl
--- redboot/current/cdl/redboot.cdl 6 May 2003 21:00:21 -0000 1.48
+++ redboot/current/cdl/redboot.cdl 20 May 2003 18:40:59 -0000
@@ -126,10 +126,21 @@ cdl_package CYGPKG_REDBOOT {
If this option is non-zero, RedBoot will remember the last N command
lines. These lines may be reused. Enabling this history will also
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
no_define
default_value 1
Index: redboot/current/doc/redboot.sgml
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/doc/redboot.sgml,v
retrieving revision 1.6
diff -u -p -5 -r1.6 redboot.sgml
--- redboot/current/doc/redboot.sgml 24 Feb 2003 17:21:26 -0000 1.6
+++ redboot/current/doc/redboot.sgml 20 May 2003 18:40:59 -0000
@@ -221,10 +221,43 @@ for this item unchanged. Currently it is
value for the start-up script; it must always be retyped.</para>
</listitem>
</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>
<indexterm><primary>RedBoot</primary><secondary>mode</secondary></indexterm>
<indexterm><primary>RedBoot</primary><secondary>startup mode</secondary></indexterm>
Index: redboot/current/src/io.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/src/io.c,v
retrieving revision 1.29
diff -u -p -5 -r1.29 io.c
--- redboot/current/src/io.c 5 Nov 2002 04:27:05 -0000 1.29
+++ redboot/current/src/io.c 20 May 2003 18:40:59 -0000
@@ -6,11 +6,11 @@
//
//==========================================================================
//####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
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
@@ -294,41 +294,48 @@ getc_script(char *cp)
}
return false;
}
#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:
// _GETS_OK: 'n' valid characters received
// _GETS_GDB: '$' (GDB lead-in)
// _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)
{
char *ip = buf; // Insertion point
char *eol = buf; // End of line
char c;
bool res = false;
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
// Display current buffer data
@@ -488,15 +495,20 @@ _rb_gets_preloaded(char *buf, int buflen
mon_write_char('\r');
mon_write_char('\n');
}
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;
case '\b':
case 0x7F: // DEL
@@ -647,5 +659,86 @@ verify_action_with_timeout(int timeout,
va_list ap;
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