📄 io.c
字号:
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
while (*eol) {
mon_write_char(*eol++);
}
ip = eol;
while (true) {
#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
if (getc_script(&c))
do_idle(false);
else
#endif
if ((timeout > 0) && (eol == buf)) {
#define MIN_TIMEOUT 50
_timeout = timeout > MIN_TIMEOUT ? MIN_TIMEOUT : timeout;
mon_set_read_char_timeout(_timeout);
while (timeout > 0) {
res = mon_read_char_with_timeout(&c);
if (res) {
// Got a character
do_idle(false);
break;
}
timeout -= _timeout;
}
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 = eol;
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 && (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);
}
#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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -