/*
+ * (C) Copyright 2014-2016 Leo C. <erbl259-lmu@yahoo.de>
+ *
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2005
* JinHua Luo, GuangDong Linux Center, <luo.jinhua@gd-linux.com>
*
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0
*/
+#include "cli_readline.h"
#include "common.h"
-
#include <string.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <ctype.h>
#include "config.h"
#include "con-utils.h"
+#include "print-utils.h"
#include "command.h"
-#include "cli_readline.h"
-char console_buffer[CONFIG_SYS_CBSIZE + 1]; /* console I/O buffer */
-static const FLASH char erase_seq[] = "\b \b"; /* erase sequence */
-static const FLASH char tab_seq[] = " "; /* used to expand TABs */
-#ifndef CONFIG_CMDLINE_EDITING
-static char *delete_char (char *buffer, char *p, int *colp, int *np, int plen)
+/************************************************************************************************/
+/* TODO:
+ *
+ */
+
+#define ESC 0x1b
+
+#define KEY_TAB '\t' // TAB key
+#define KEY_CR '\r' // RETURN key
+#define KEY_BACKSPACE '\b' // Backspace key
+#define KEY_ESCAPE 0x1B // ESCAPE (pressed twice)
+
+#define KEY_DOWN 0x80 // Down arrow key
+#define KEY_UP 0x81 // Up arrow key
+#define KEY_LEFT 0x82 // Left arrow key
+#define KEY_RIGHT 0x83 // Right arrow key
+#define KEY_HOME 0x84 // Home key
+#define KEY_DC 0x85 // Delete character key
+#define KEY_IC 0x86 // Ins char/toggle ins mode key
+#define KEY_NPAGE 0x87 // Next-page key
+#define KEY_PPAGE 0x88 // Previous-page key
+#define KEY_END 0x89 // End key
+#define KEY_BTAB 0x8A // Back tab key
+#define KEY_F1 0x8B // Function key F1
+#define KEY_F(n) (KEY_F1+(n)-1) // Space for additional 12 function keys
+
+
+struct fkey_tbl_s {
+ const FLASH char *sequence; /* ESC Sequence */
+ int code; /* Keycode */
+};
+
+//typedef const FLASH struct fkey_tbl_s fkey_tbl_t;
+
+#define FKEY_TBL_ITEM(_seq, _code) { FSTR(#_seq), _code }
+
+
+
+static const FLASH struct fkey_tbl_s fkey_table[] = {
+
+FKEY_TBL_ITEM(B, KEY_DOWN), // Down arrow key
+FKEY_TBL_ITEM(A, KEY_UP), // Up arrow key
+FKEY_TBL_ITEM(D, KEY_LEFT), // Left arrow key
+FKEY_TBL_ITEM(C, KEY_RIGHT), // Right arrow key
+FKEY_TBL_ITEM(1~, KEY_HOME), // Home key
+FKEY_TBL_ITEM(3~, KEY_DC), // Delete character key
+FKEY_TBL_ITEM(2~, KEY_IC), // Ins char/toggle ins mode key
+FKEY_TBL_ITEM(6~, KEY_NPAGE), // Next-page key
+FKEY_TBL_ITEM(5~, KEY_PPAGE), // Previous-page key
+FKEY_TBL_ITEM(4~, KEY_END), // End key
+FKEY_TBL_ITEM(Z, KEY_BTAB), // Back tab key
+/* VT400: */
+FKEY_TBL_ITEM(11~, KEY_F(1)), // Function key F1
+FKEY_TBL_ITEM(12~, KEY_F(2)), // Function key F2
+FKEY_TBL_ITEM(13~, KEY_F(3)), // Function key F3
+FKEY_TBL_ITEM(14~, KEY_F(4)), // Function key F4
+FKEY_TBL_ITEM(15~, KEY_F(5)), // Function key F5
+/* Linux consoe */
+FKEY_TBL_ITEM([A, KEY_F(1)), // Function key F1
+FKEY_TBL_ITEM([B, KEY_F(2)), // Function key F2
+FKEY_TBL_ITEM([C, KEY_F(3)), // Function key F3
+FKEY_TBL_ITEM([D, KEY_F(4)), // Function key F4
+FKEY_TBL_ITEM([E, KEY_F(5)), // Function key F5
+
+FKEY_TBL_ITEM(17~, KEY_F(6)), // Function key F6
+FKEY_TBL_ITEM(18~, KEY_F(7)), // Function key F7
+FKEY_TBL_ITEM(19~, KEY_F(8)), // Function key F8
+FKEY_TBL_ITEM(20~, KEY_F(9)), // Function key F9
+FKEY_TBL_ITEM(21~, KEY_F(10)), // Function key F10
+FKEY_TBL_ITEM(23~, KEY_F(11)), // Function key F11
+FKEY_TBL_ITEM(24~, KEY_F(12)), // Function key F12
+{ NULL } /* Mark end of table */
+};
+
+
+
+typedef enum {
+ STATE_GROUND,
+ STATE_ESCAPE,
+ STATE_CSI_ENTRY,
+ STATE_SS3
+} vtparse_state_t;
+
+#define CHB_SIZE 15
+
+static
+int vt_parse (void)
{
- char *s;
+ static vtparse_state_t state = STATE_GROUND;
+ char buf[CHB_SIZE+1];
+ uint8_t param[2];
+ uint8_t i_buf;
+ uint8_t i_param;
+ int ch;
- if (*np == 0)
- return p;
- if (*(--p) == '\t') { /* will retype the whole line */
- while (*colp > plen) {
- my_puts_P(erase_seq);
- (*colp)--;
- }
- for (s = buffer; s < p; ++s) {
- if (*s == '\t') {
- my_puts_P(tab_seq + ((*colp) & 07));
- *colp += 8 - ((*colp) & 07);
- } else {
- ++(*colp);
- putchar(*s);
+ while (1) {
+ ch = my_getchar(1);
+// debug_getch(state, ch);
+
+ switch (state) {
+ case STATE_GROUND:
+ if (ch == ESC) {
+ state = STATE_ESCAPE;
+ continue;
+ }
+ if (ch == 0x7F) // BACKSPACE on VT200 sends DEL char
+ ch = KEY_BACKSPACE; // map it to '\b'
+ break;
+ case STATE_ESCAPE:
+ if (ch < 0)
+ continue;
+
+ if (ch == '[') {
+ state = STATE_CSI_ENTRY;
+ param[0] = param[1] = 0;
+ i_buf = 0;
+ i_param = 0;
+ continue;
}
+ if (ch == 'O') {
+ state = STATE_SS3;
+ continue;
+ }
+ state = STATE_GROUND;
+ break;
+ case STATE_SS3:
+ if (ch == 'F') /* weird */
+ ch = KEY_END;
+ state = STATE_GROUND;
+ break;
+ case STATE_CSI_ENTRY:
+ if (ch < 0)
+ continue;
+
+ buf[i_buf] = ch;
+ if (i_buf < CHB_SIZE)
+ i_buf++;
+ if (ch == ';') {
+ i_param++;
+ continue;
+ }
+ if (isdigit(ch)) {
+ if (i_param < 2)
+ param[i_param] = param[i_param] * 10 + ch - '0';
+ continue;
+ }
+ if (ch >= '@' && ch <= '~' && ch != '[') {
+ buf[i_buf] = '\0';
+ int_fast8_t i = 0;
+ while (fkey_table[i].sequence) {
+ if (! strcmp_P (buf, fkey_table[i].sequence)) {
+ ch = fkey_table[i].code;
+ break;
+ }
+ i++;
+ }
+ if (fkey_table[i].sequence == NULL) {
+ ch = '$'; /* KEY_ESCAPE; */
+ }
+ }
+ state = STATE_GROUND;
+ break;
}
- } else {
- my_puts_P(erase_seq);
- (*colp)--;
+ break; /* while */
}
- (*np)--;
- return p;
+ return ch;
}
-#endif /* CONFIG_CMDLINE_EDITING */
+
+/************************************************************************************************/
-#ifdef CONFIG_CMDLINE_EDITING
+char console_buffer[CONFIG_SYS_CBSIZE + 1]; /* console I/O buffer */
/*
* cmdline-editing related codes from vivi.
* Author: Janghoon Lyu <nandy@mizi.com>
*/
-#define putnstr(str, n) printf_P(PSTR("%.*s"), (int)n, str)
+static void putnstr(char *str, int n)
+{
+ /* printf_P(PSTR("%.*s"), (int)n, str) */
+ while (n-- && *str)
+ putchar(*str++);
+}
-#define CTL_CH(c) ((c) - 'a' + 1)
+
+#define CTL_CH(c) ((c) - 'a' + 1)
#define CTL_BACKSPACE ('\b')
-#define DEL ((char)255)
-#define DEL7 ((char)127)
-#define CREAD_HIST_CHAR ('!')
+#define DEL ((char)255)
+#define DEL7 ((char)127)
#define getcmd_putch(ch) putchar(ch)
-#define getcmd_getch() my_getchar(1)
+#define getcmd_getch() vt_parse()
#define getcmd_cbeep() getcmd_putch('\a')
-#define HIST_MAX 5
-#define HIST_SIZE CONFIG_SYS_CBSIZE
-static int hist_max;
-static int hist_add_idx;
-static int hist_cur = -1;
-static unsigned hist_num;
+struct hist_node_s {
+ struct hist_node_s *next;
+ char line[];
+};
+typedef struct hist_node_s hist_node;
-static char *hist_list[HIST_MAX];
-static char hist_lines[HIST_MAX][HIST_SIZE + 1]; /* Save room for NULL */
-#define add_idx_minus_one() ((hist_add_idx == 0) ? hist_max : hist_add_idx-1)
+static hist_node *hist_head;
+static hist_node *hist_cur;
-static void hist_init(void)
+static hist_node *hist_search_node(char *line)
{
- int i;
+ hist_node *p = hist_head;
- hist_max = 0;
- hist_add_idx = 0;
- hist_cur = -1;
- hist_num = 0;
+ while (p && strcmp(p->line, line))
+ p = p->next;
+ return p;
+}
+
+#if 0
+static hist_node *hist_insert(char *line)
+{
+ hist_node *p = (hist_node *) malloc(sizeof (hist_node) + strlen(line) + 1);
- for (i = 0; i < HIST_MAX; i++) {
- hist_list[i] = hist_lines[i];
- hist_list[i][0] = '\0';
+ if (p) {
+ strcpy(p->line, line);
+ p->next = hist_head;
+ hist_head = p;
}
+ return p;
}
+#endif
-static void cread_add_to_hist(char *line)
+static hist_node *hist_new(char *line)
{
- strcpy(hist_list[hist_add_idx], line);
+ hist_node *p = (hist_node *) malloc(sizeof (hist_node) + strlen(line) + 1);
- if (++hist_add_idx >= HIST_MAX)
- hist_add_idx = 0;
+ if (p) {
+ strcpy(p->line, line);
+ p->next = NULL;
+ }
+ return p;
+}
- if (hist_add_idx > hist_max)
- hist_max = hist_add_idx;
+static hist_node *hist_delete(void)
+{
+ hist_node *p = NULL;
+ hist_node *q = hist_head;
- hist_num++;
+ if (q) {
+ while(q->next) {
+ p = q;
+ q = q->next;
+ }
+ free(q);
+ if (p)
+ p->next = NULL;
+ }
+ return p;
}
-static char *hist_prev(void)
+static hist_node *hist_unlink(hist_node *pos)
{
- char *ret;
- int old_cur;
+ hist_node *p = NULL;
+ hist_node *q = hist_head;
- if (hist_cur < 0)
- return NULL;
+ while(q && q != pos) {
+ p = q;
+ q = q->next;
+ }
+ if (q) {
+ if (p)
+ p->next = q->next;
+ else
+ hist_head = q->next;
+ q->next = NULL;
+ }
+ return q;
+}
- old_cur = hist_cur;
- if (--hist_cur < 0)
- hist_cur = hist_max;
+static uint_fast8_t hist_count(void)
+{
+ hist_node *p = hist_head;
+ uint_fast8_t n = 0;
- if (hist_cur == hist_add_idx) {
- hist_cur = old_cur;
- ret = NULL;
- } else {
- ret = hist_list[hist_cur];
+ while (p) {
+ ++n;
+ p = p->next;
}
-
- return ret;
+ return n;
}
-static char *hist_next(void)
+static hist_node *cread_add_to_hist(char *line)
{
- char *ret;
+ hist_node * p;
- if (hist_cur < 0)
- return NULL;
+ p = hist_search_node(line);
+ if (p)
+ hist_unlink(p);
+ else
+ p = hist_new(line);
- if (hist_cur == hist_add_idx)
- return NULL;
+ if (p) {
+ p->next = hist_head;
+ hist_head = p;
+ }
- if (++hist_cur > hist_max)
- hist_cur = 0;
+ if (hist_count() > CONFIG_SYS_HIST_MAX)
+ hist_delete();
+ return p;
+}
- if (hist_cur == hist_add_idx)
- ret = "";
- else
- ret = hist_list[hist_cur];
+static char *hist_prev(void)
+{
+ hist_node *p = hist_cur;
+
+ if (p == NULL)
+ return NULL;
+
+ hist_cur = hist_cur->next;
- return ret;
+ return p->line;
}
-#ifndef CONFIG_CMDLINE_EDITING
-static void cread_print_hist_list(void)
+static char *hist_next(void)
{
- int i;
- unsigned n;
+ hist_node *p = NULL;
+ hist_node *q = hist_head;
- n = hist_num - hist_max;
+ if(q == hist_cur)
+ return NULL;
- i = hist_add_idx + 1;
- while (1) {
- if (i > hist_max)
- i = 0;
- if (i == hist_add_idx)
- break;
- printf_P(PSTR("%s\n"), hist_list[i]);
- n++;
- i++;
+ while(q->next != hist_cur) {
+ p = q;
+ q = q->next;
}
+ hist_cur = q;
+
+ return p ? p->line : "";
}
-#endif /* CONFIG_CMDLINE_EDITING */
-#define BEGINNING_OF_LINE() { \
- while (num) { \
- getcmd_putch(CTL_BACKSPACE); \
- num--; \
- } \
+
+#define BEGINNING_OF_LINE() { \
+ while (num) { \
+ getcmd_putch(CTL_BACKSPACE); \
+ num--; \
+ } \
}
-#define ERASE_TO_EOL() { \
- if (num < eol_num) { \
- printf_P(PSTR("%*S"), (int)(eol_num - num), PSTR("")); \
- do { \
- getcmd_putch(CTL_BACKSPACE); \
- } while (--eol_num > num); \
- } \
+#define ERASE_TO_EOL() { \
+ if (num < eol_num) { \
+ /* printf_P(PSTR("%*S"), (int)(eol_num - num), PSTR("")); */ \
+ print_blanks(eol_num - num); \
+ do { \
+ getcmd_putch(CTL_BACKSPACE); \
+ } while (--eol_num > num); \
+ } \
}
-#define REFRESH_TO_EOL() { \
- if (num < eol_num) { \
- wlen = eol_num - num; \
- putnstr(buf + num, wlen); \
- num = eol_num; \
- } \
+#define REFRESH_TO_EOL() { \
+ if (num < eol_num) { \
+ uint_fast8_t wlen = eol_num - num; \
+ putnstr(buf + num, wlen); \
+ num = eol_num; \
+ } \
}
-static void cread_add_char(char ichar, int insert, unsigned long *num,
- unsigned long *eol_num, char *buf, unsigned long len)
+static void cread_add_char(char ichar, bool insert, uint_fast8_t *num,
+ uint_fast8_t *eol_num, char *buf, uint_fast8_t len)
{
- unsigned long wlen;
+ uint_fast8_t wlen;
/* room ??? */
if (insert || *num == *eol_num) {
}
}
-static void cread_add_str(char *str, int strsize, int insert,
- unsigned long *num, unsigned long *eol_num,
- char *buf, unsigned long len)
+static void cread_add_str(char *str, uint_fast8_t strsize, bool insert,
+ uint_fast8_t *num, uint_fast8_t *eol_num,
+ char *buf, uint_fast8_t len)
{
while (strsize--) {
cread_add_char(*str, insert, num, eol_num, buf, len);
}
}
-static int cread_line(const FLASH char *const prompt, char *buf, unsigned int *len)
+static int cread_line(const FLASH char *const prompt, char *buf,
+ uint_fast8_t *len, bool enable_history)
{
- unsigned long num = 0;
- unsigned long eol_num = 0;
- unsigned long wlen;
- char ichar;
- int insert = 1;
- int esc_len = 0;
- char esc_save[8];
- int init_len = strlen(buf);
+ uint_fast8_t num = 0;
+ uint_fast8_t eol_num = 0;
+ bool insert = 1;
(void) prompt;
+ uint_fast8_t init_len = strlen(buf);
if (init_len)
cread_add_str(buf, init_len, 1, &num, &eol_num, buf, *len);
while (1) {
- ichar = getcmd_getch();
+ int ichar = getcmd_getch();
if ((ichar == '\n') || (ichar == '\r')) {
putchar('\n');
break;
}
- /*
- * handle standard linux xterm esc sequences for arrow key, etc.
- */
- if (esc_len != 0) {
- if (esc_len == 1) {
- if (ichar == '[') {
- esc_save[esc_len] = ichar;
- esc_len = 2;
- } else {
- cread_add_str(esc_save, esc_len,
- insert, &num, &eol_num,
- buf, *len);
- esc_len = 0;
- }
- continue;
- }
-
- switch (ichar) {
- case 'D': /* <- key */
- ichar = CTL_CH('b');
- esc_len = 0;
- break;
- case 'C': /* -> key */
- ichar = CTL_CH('f');
- esc_len = 0;
- break; /* pass off to ^F handler */
- case 'H': /* Home key */
- ichar = CTL_CH('a');
- esc_len = 0;
- break; /* pass off to ^A handler */
- case 'A': /* up arrow */
- ichar = CTL_CH('p');
- esc_len = 0;
- break; /* pass off to ^P handler */
- case 'B': /* down arrow */
- ichar = CTL_CH('n');
- esc_len = 0;
- break; /* pass off to ^N handler */
- default:
- esc_save[esc_len++] = ichar;
- cread_add_str(esc_save, esc_len, insert,
- &num, &eol_num, buf, *len);
- esc_len = 0;
- continue;
- }
- }
switch (ichar) {
- case 0x1b:
- if (esc_len == 0) {
- esc_save[esc_len] = ichar;
- esc_len = 1;
- } else {
- my_puts_P(PSTR("impossible condition #876\n"));
- esc_len = 0;
- }
- break;
+ case KEY_HOME:
case CTL_CH('a'):
BEGINNING_OF_LINE();
break;
- case CTL_CH('c'): /* ^C - break */
- *buf = '\0'; /* discard input */
+ case CTL_CH('c'): /* ^C - break */
+ *buf = '\0'; /* discard input */
return -1;
- case CTL_CH('f'):
+ case KEY_RIGHT:
+ case CTL_CH('f'): /* forward-char */
if (num < eol_num) {
getcmd_putch(buf[num]);
num++;
}
break;
- case CTL_CH('b'):
+ case KEY_LEFT:
+ case CTL_CH('b'): /* backward-char */
if (num) {
getcmd_putch(CTL_BACKSPACE);
num--;
}
break;
- case CTL_CH('d'):
+ case KEY_DC:
+ case CTL_CH('d'): /* delete-char */
if (num < eol_num) {
- wlen = eol_num - num - 1;
+ uint_fast8_t wlen = eol_num - num - 1;
if (wlen) {
memmove(&buf[num], &buf[num+1], wlen);
putnstr(buf + num, wlen);
eol_num--;
}
break;
- case CTL_CH('k'):
+ case CTL_CH('k'): /* kill-line */
ERASE_TO_EOL();
break;
+ case KEY_END:
case CTL_CH('e'):
REFRESH_TO_EOL();
break;
+ case KEY_IC:
case CTL_CH('o'):
insert = !insert;
break;
case CTL_CH('x'):
- case CTL_CH('u'):
+ case CTL_CH('u'): /* kill-whole-line */
BEGINNING_OF_LINE();
ERASE_TO_EOL();
break;
case DEL:
case DEL7:
- case 8:
+ case 8: /* backward-delete-char */
if (num) {
- wlen = eol_num - num;
+ uint_fast8_t wlen = eol_num - num;
num--;
memmove(&buf[num], &buf[num+1], wlen);
getcmd_putch(CTL_BACKSPACE);
eol_num--;
}
break;
- case CTL_CH('p'):
- case CTL_CH('n'):
- {
- char *hline;
-
- esc_len = 0;
-
- if (ichar == CTL_CH('p'))
- hline = hist_prev();
- else
- hline = hist_next();
-
- if (!hline) {
+ case KEY_UP:
+ case CTL_CH('p'): /* previous-history */
+ case KEY_DOWN:
+ case CTL_CH('n'): /* next-history */
+ if (enable_history) {
+ char *hline;
+
+ if (ichar == CTL_CH('p') || ichar == KEY_UP)
+ hline = hist_prev();
+ else
+ hline = hist_next();
+
+ if (hline) {
+ /* nuke the current line */
+ /* first, go home */
+ BEGINNING_OF_LINE();
+
+ /* erase to end of line */
+ ERASE_TO_EOL();
+
+ /* copy new line into place and display */
+ strcpy(buf, hline);
+ eol_num = strlen(buf);
+ REFRESH_TO_EOL();
+ } else {
+ getcmd_cbeep();
+ }
+ } else {
getcmd_cbeep();
- continue;
}
-
- /* nuke the current line */
- /* first, go home */
- BEGINNING_OF_LINE();
-
- /* erase to end of line */
- ERASE_TO_EOL();
-
- /* copy new line into place and display */
- strcpy(buf, hline);
- eol_num = strlen(buf);
- REFRESH_TO_EOL();
- continue;
- }
+ break;
+#if 0
+ case KEY_PPAGE: /* history-search-backward */
+ case KEY_NPAGE: /* history-search-forward */
+ if (enable_history) {
+ char *hline;
+
+ if (ichar == KEY_PPAGE)
+ hline = hist_search_backward();
+ else
+ hline = hist_search_forward();
+
+ if (hline) {
+ /* nuke the current line */
+ /* first, go home */
+ BEGINNING_OF_LINE();
+
+ /* erase to end of line */
+ ERASE_TO_EOL();
+
+ /* copy new line into place and display */
+ strcpy(buf, hline);
+ eol_num = strlen(buf);
+ REFRESH_TO_EOL();
+ } else {
+ getcmd_cbeep();
+ }
+ } else {
+ getcmd_cbeep();
+ }
+ break;
+#endif
#ifdef CONFIG_AUTO_COMPLETE
case '\t': {
int num2, col;
}
#endif
default:
- cread_add_char(ichar, insert, &num, &eol_num, buf,
- *len);
+ if (isprint(ichar))
+ cread_add_char(ichar, insert, &num, &eol_num, buf,
+ *len);
break;
}
}
*len = eol_num;
buf[eol_num] = '\0'; /* lose the newline */
- if (buf[0] && buf[0] != CREAD_HIST_CHAR)
- cread_add_to_hist(buf);
- hist_cur = hist_add_idx;
-
+ if (enable_history) {
+ if (buf[0])
+ hist_cur = cread_add_to_hist(buf);
+ }
return 0;
}
-#endif /* CONFIG_CMDLINE_EDITING */
-
/****************************************************************************/
-static int cli_readline_into_buffer(const FLASH char *const prompt, char *buffer)
+static int cli_readline_into_buffer(const FLASH char *const prompt,
+ char *buffer, bool enable_history)
{
char *p = buffer;
-#ifdef CONFIG_CMDLINE_EDITING
- unsigned int len = CONFIG_SYS_CBSIZE;
+ uint_fast8_t len = CONFIG_SYS_CBSIZE;
int rc;
- static int initted;
-
- if (!initted) {
- hist_init();
- initted = 1;
- }
if (prompt)
my_puts_P(prompt);
- rc = cread_line(prompt, p, &len);
+ rc = cread_line(prompt, p, &len, enable_history);
return rc < 0 ? rc : (int) len;
-
-#else /* CONFIG_CMDLINE_EDITING */
- char *p_buf = p;
- int n = 0; /* buffer index */
- int plen = 0; /* prompt length */
- int col; /* output column cnt */
- char c;
-
- /* print prompt */
- if (prompt) {
- plen = strlen_P(prompt);
- my_puts_P(prompt);
- }
- col = plen;
-
- for (;;) {
-
- c = my_getchar(1);
-
- /*
- * Special character handling
- */
- switch (c) {
- case '\r': /* Enter */
- case '\n':
- *p = '\0';
- my_puts_P(PSTR("\r\n"));
- return p - p_buf;
-
- case '\0': /* nul */
- continue;
-
- case 0x03: /* ^C - break */
- p_buf[0] = '\0'; /* discard input */
- return -1;
-
- case 0x15: /* ^U - erase line */
- while (col > plen) {
- my_puts_P(erase_seq);
- --col;
- }
- p = p_buf;
- n = 0;
- continue;
-
- case 0x17: /* ^W - erase word */
- p = delete_char(p_buf, p, &col, &n, plen);
- while ((n > 0) && (*p != ' '))
- p = delete_char(p_buf, p, &col, &n, plen);
- continue;
-
- case 0x08: /* ^H - backspace */
- case 0x7F: /* DEL - backspace */
- p = delete_char(p_buf, p, &col, &n, plen);
- continue;
-
- default:
- /*
- * Must be a normal character then
- */
- if (n < CONFIG_SYS_CBSIZE-2) {
- if (c == '\t') { /* expand TABs */
-#ifdef CONFIG_AUTO_COMPLETE
- /*
- * if auto completion triggered just
- * continue
- */
- *p = '\0';
- if (cmd_auto_complete(prompt,
- console_buffer,
- &n, &col)) {
- p = p_buf + n; /* reset */
- continue;
- }
-#endif
- my_puts_P(tab_seq + (col & 07));
- col += 8 - (col & 07);
- } else {
- char buf[2];
-
- /*
- * Echo input using puts() to force an
- * LCD flush if we are using an LCD
- */
- ++col;
- buf[0] = c;
- buf[1] = '\0';
- my_puts(buf);
- }
- *p++ = c;
- ++n;
- } else { /* Buffer full */
- putchar('\a');
- }
- }
- }
-#endif /* CONFIG_CMDLINE_EDITING */
}
-int cli_readline(const FLASH char *const prompt)
+int cli_readline(const FLASH char *const prompt, bool enable_history)
{
/*
* If console_buffer isn't 0-length the user will be prompted to modify
*/
console_buffer[0] = '\0';
- return cli_readline_into_buffer(prompt, console_buffer);
+ return cli_readline_into_buffer(prompt, console_buffer, enable_history);
}
-