📄 io.c
字号:
if (res == false) {
do_idle(true);
return _GETS_TIMEOUT; // Input timed out
}
} else {
mon_read_char(&c);
}
*eol = '\0';
switch (c) {
#define CTRL(c) ((c)&0x1F)
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
case CTRL('P'):
// Fetch the previous line into the buffer
if (_index >= 0) {
// Erase the previous line [crude]
while (ip != buf) {
mon_write_char('\b');
mon_write_char(' ');
mon_write_char('\b');
ip--;
}
strcpy(buf, _cl_lines[_index]);
while (*ip) {
mon_write_char(*ip++);
}
eol = ip;
// Move to previous line
_index--;
if (_index < 0) {
_index = _cl_max_index;
}
} else {
mon_write_char(0x07); // Audible bell on most devices
}
break;
case CTRL('N'):
// Fetch the next line into the buffer
if (_index >= 0) {
if (++_index > _cl_max_index) _index = 0;
// Erase the previous line [crude]
while (ip != buf) {
mon_write_char('\b');
mon_write_char(' ');
mon_write_char('\b');
ip--;
}
strcpy(buf, _cl_lines[_index]);
while (*ip) {
mon_write_char(*ip++);
}
eol = ip;
} else {
mon_write_char(0x07); // Audible bell on most devices
}
break;
case CTRL('B'):
// Move insertion point backwards
if (ip != buf) {
mon_write_char('\b');
ip--;
}
break;
case CTRL('F'):
// Move insertion point forwards
if (ip != eol) {
mon_write_char(*ip++);
}
break;
case CTRL('E'):
// Move insertion point to end of line
while (ip != eol) {
mon_write_char(*ip++);
}
break;
case CTRL('A'):
// Move insertion point to beginning of line
if (ip != buf) {
xp = ip;
while (xp-- != buf) {
mon_write_char('\b');
}
}
ip = buf;
break;
case CTRL('K'):
// Kill to the end of line
if (ip != eol) {
xp = ip;
while (xp++ != eol) {
mon_write_char(' ');
}
while (--xp != ip) {
mon_write_char('\b');
}
eol = ip;
}
break;
case CTRL('D'):
// Erase the character under the cursor
if (ip != eol) {
xp = ip;
eol--;
while (xp != eol) {
*xp = *(xp+1);
mon_write_char(*xp++);
}
mon_write_char(' '); // Erases last character
mon_write_char('\b');
while (xp-- != ip) {
mon_write_char('\b');
}
}
break;
#endif // CYGNUM_REDBOOT_CMD_LINE_EDITING
case CTRL('C'): // ^C
// Abort current input
diag_printf("^C\n");
*buf = '\0'; // Nothing useful in buffer
return _GETS_CTRLC;
case '\n':
case '\r':
// If previous character was the "other" end-of-line, ignore this one
if (((c == '\n') && (last_ch == '\r')) ||
((c == '\r') && (last_ch == '\n'))) {
c = '\0';
break;
}
// End of line
if (console_echo) {
mon_write_char('\r');
mon_write_char('\n');
}
last_ch = c;
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
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
if (ip != buf) {
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
if (ip != eol) {
ip--;
mon_write_char('\b');
xp = ip;
while (xp != (eol-1)) {
*xp = *(xp+1);
mon_write_char(*xp++);
}
mon_write_char(' '); // Erases last character
mon_write_char('\b');
while (xp-- != ip) {
mon_write_char('\b');
}
} else {
if (console_echo) {
mon_write_char('\b');
mon_write_char(' ');
mon_write_char('\b');
}
ip--;
}
eol--;
#else
if (console_echo) {
mon_write_char('\b');
mon_write_char(' ');
mon_write_char('\b');
}
ip--;
eol--;
#endif
}
break;
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
case '+': // fall through
case '$':
if (ip == buf || last_ch != '\\')
{
// Give up and try GDB protocol
ungetDebugChar(c); // Push back character so stubs will see it
return _GETS_GDB;
}
if (last_ch == '\\') {
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
if (ip == eol) {
// Just save \$ as $
eol = --ip;
} else {
mon_write_char('\b');
*--ip = c;
mon_write_char(c);
break;
}
#else
ip--; // Save \$ as $
#endif
}
// else fall through
#endif
default:
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
// If the insertion point is not at the end of line, make space for it
if (ip != eol) {
xp = eol;
*++eol = '\0';
while (xp != ip) {
*xp = *(xp-1);
xp--;
}
}
#endif
if (console_echo) {
mon_write_char(c);
}
if (ip == eol) {
// Advance both pointers
*ip++ = c;
eol = ip;
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
} else {
// Just insert the character
*ip++ = c;
xp = ip;
while (xp != eol) {
mon_write_char(*xp++);
}
while (xp-- != ip) {
mon_write_char('\b');
}
#endif
}
}
last_ch = c;
if (ip == buf + buflen - 1) { // Buffer full
*ip = '\0';
return buflen;
}
}
}
int
_rb_gets(char *buf, int buflen, int timeout)
{
*buf = '\0'; // Empty buffer
return _rb_gets_preloaded(buf, buflen, timeout);
}
static bool
_verify_action(int timeout, char *fmt, va_list ap)
{
char ans[8];
int ret;
#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
// Don't ask if we're executing a script
if (script && *script)
return 1;
#endif
diag_vprintf(fmt, ap);
diag_printf(" - continue (y/n)? ");
if ((ret = _rb_gets(ans, sizeof(ans), timeout)) > 0) {
return ((ans[0] == 'y') || (ans[0] == 'Y'));
} else {
if (ret == _GETS_TIMEOUT) {
diag_printf(" ** Timed out!\n");
}
return 0; // Timed out or ^C
}
}
bool
verify_action(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
return _verify_action(0, fmt, ap);
}
bool
verify_action_with_timeout(int timeout, char *fmt, ...)
{
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -