X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/4bc81323e51ac138e733c14eeb6f283ae706e904..7af9364ebd7ad6c143f31e9abe745c6d75f8322b:/avr/cli_readline.c diff --git a/avr/cli_readline.c b/avr/cli_readline.c index 17d5494..2fdc56e 100644 --- a/avr/cli_readline.c +++ b/avr/cli_readline.c @@ -1,4 +1,6 @@ /* + * (C) Copyright 2014-2016 Leo C. + * * (C) Copyright 2000 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * @@ -6,210 +8,443 @@ * (C) Copyright 2005 * JinHua Luo, GuangDong Linux Center, * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0 */ +#include "cli_readline.h" #include "common.h" - -#include #include #include +#include +#include +#include #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 */ +#define CTL_CH(c) ((c) - 'a' + 1) +#define CTL_BACKSPACE ('\b') +#define DEL ((char)255) +#define DEL7 ((char)127) + + +/************************************************************************************************/ +/* TODO: + * + */ -#ifndef CONFIG_CMDLINE_EDITING -static char *delete_char (char *buffer, char *p, int *colp, int *np, int plen) +#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 +/* */ +FKEY_TBL_ITEM(H, KEY_HOME), // Home key +FKEY_TBL_ITEM(F, KEY_END), // End 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 console */ +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') + ch = KEY_END; + if (ch == 'H') + ch = KEY_HOME; + 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 +/************************************************************************************************/ /* * cmdline-editing related codes from vivi. * Author: Janghoon Lyu */ -#define putnstr(str, n) printf_P(PSTR("%.*s"), (int)n, str) -#define CTL_CH(c) ((c) - 'a' + 1) -#define CTL_BACKSPACE ('\b') -#define DEL ((char)255) -#define DEL7 ((char)127) -#define CREAD_HIST_CHAR ('!') +struct hist_node_s { + struct hist_node_s *next; + char line[]; +}; +typedef struct hist_node_s hist_node; -#define getcmd_putch(ch) putchar(ch) -#define getcmd_getch() my_getchar() -#define getcmd_cbeep() getcmd_putch('\a') -#define HIST_MAX 5 -#define HIST_SIZE CONFIG_SYS_CBSIZE +static hist_node *hist_head; +static hist_node *hist_cur; -static int hist_max; -static int hist_add_idx; -static int hist_cur = -1; -static unsigned hist_num; +static void hist_reset(void) +{ + hist_cur = hist_head; +} -static char *hist_list[HIST_MAX]; -static char hist_lines[HIST_MAX][HIST_SIZE + 1]; /* Save room for NULL */ +static hist_node *hist_search_node(char *line) +{ + hist_node *p = hist_head; -#define add_idx_minus_one() ((hist_add_idx == 0) ? hist_max : hist_add_idx-1) + while (p && strcmp(p->line, line)) + p = p->next; + return p; +} -static void hist_init(void) +#if 0 +static hist_node *hist_insert(char *line) { - int i; + hist_node *p = (hist_node *) malloc(sizeof (hist_node) + strlen(line) + 1); - hist_max = 0; - hist_add_idx = 0; - hist_cur = -1; - hist_num = 0; + if (p) { + strcpy(p->line, line); + p->next = hist_head; + hist_head = p; + } + return p; +} +#endif - for (i = 0; i < HIST_MAX; i++) { - hist_list[i] = hist_lines[i]; - hist_list[i][0] = '\0'; +static hist_node *hist_new(char *line) +{ + hist_node *p = (hist_node *) malloc(sizeof (hist_node) + strlen(line) + 1); + + if (p) { + strcpy(p->line, line); + p->next = NULL; } + return p; } -static void cread_add_to_hist(char *line) +static hist_node *hist_delete(void) { - strcpy(hist_list[hist_add_idx], line); + hist_node *p = NULL; + hist_node *q = hist_head; - if (++hist_add_idx >= HIST_MAX) - hist_add_idx = 0; + if (q) { + while(q->next) { + p = q; + q = q->next; + } + free(q); + if (p) + p->next = NULL; + } + return p; +} - if (hist_add_idx > hist_max) - hist_max = hist_add_idx; +static hist_node *hist_unlink(hist_node *pos) +{ + hist_node *p = NULL; + hist_node *q = hist_head; - hist_num++; + 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; } -static char *hist_prev(void) +static uint_fast8_t hist_count(void) { - char *ret; - int old_cur; + hist_node *p = hist_head; + uint_fast8_t n = 0; - if (hist_cur < 0) - return NULL; + while (p) { + ++n; + p = p->next; + } + return n; +} - old_cur = hist_cur; - if (--hist_cur < 0) - hist_cur = hist_max; +static hist_node *cread_add_to_hist(char *line) +{ + hist_node * p; - if (hist_cur == hist_add_idx) { - hist_cur = old_cur; - ret = NULL; - } else { - ret = hist_list[hist_cur]; + p = hist_search_node(line); + if (p) + hist_unlink(p); + else + p = hist_new(line); + + if (p) { + p->next = hist_head; + hist_head = p; } - return ret; + if (hist_count() > CONFIG_SYS_HIST_MAX) + hist_delete(); + return p; } -static char *hist_next(void) +static char *hist_prev(void) { - char *ret; + hist_node *p = hist_cur; - if (hist_cur < 0) + if (p == NULL) return NULL; + hist_cur = p->next; + + return p->line; +} - if (hist_cur == hist_add_idx) +static char *hist_next(void) +{ + hist_node *p = NULL; + hist_node *q = hist_head; + + if(q == hist_cur) return NULL; - if (++hist_cur > hist_max) - hist_cur = 0; + while(q->next != hist_cur) { + p = q; + q = q->next; + } + hist_cur = q; - if (hist_cur == hist_add_idx) - ret = ""; - else - ret = hist_list[hist_cur]; + return p ? p->line : ""; +} + +static char *hist_search_backward(char* buf, uint8_t num) +{ + hist_node *p = hist_cur; + + if (p == NULL) + return NULL; + + while (p->next && strncmp(p->line, buf, num)) + p = p->next; - return ret; + if(!strncmp(p->line, buf, num)) { + hist_cur = p->next; + return p->line; + } + return NULL; } -#ifndef CONFIG_CMDLINE_EDITING -static void cread_print_hist_list(void) +static char *hist_search_forward (char* buf, uint8_t num) { - int i; - unsigned n; + hist_node *p = NULL; + hist_node *match = 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; + if (p && !strncmp(p->line, buf, num)) + match = p; + } + + if(match) { + hist_cur = match->next; + return match->line; } + return NULL; } -#endif /* CONFIG_CMDLINE_EDITING */ -#define BEGINNING_OF_LINE() { \ - while (num) { \ - getcmd_putch(CTL_BACKSPACE); \ - num--; \ - } \ +static void putnstr(char *str, int n) +{ + /* printf_P(PSTR("%.*s"), (int)n, str) */ + while (n-- && *str) + putchar(*str++); } -#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); \ - } \ +static void getcmd_putch(int ch) { putchar(ch);} +static int getcmd_getch(void) { return vt_parse();} +static void getcmd_cbeep(void) { getcmd_putch('\a');} + +static void beginning_of_line(uint8_t *num) +{ + while (*num) { + getcmd_putch(CTL_BACKSPACE); + (*num)--; + } } -#define REFRESH_TO_EOL() { \ - if (num < eol_num) { \ - wlen = eol_num - num; \ - putnstr(buf + num, wlen); \ - num = eol_num; \ - } \ +static void erase_to_eol(uint_fast8_t *num, uint_fast8_t *eol_num) +{ + 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); + } +} + +static void refresh_to_eol(char *buf, uint_fast8_t *num, uint_fast8_t *eol_num) +{ + 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) { @@ -232,126 +467,72 @@ static void cread_add_char(char ichar, int insert, unsigned long *num, getcmd_putch(CTL_BACKSPACE); } else { /* echo the character */ - wlen = 1; buf[*num] = ichar; - putnstr(buf + *num, wlen); + putnstr(buf + *num, 1); (*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, 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); - str++; - } + char c; + + while ((c = *str++) != '\0') + cread_add_char(c, 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; - if (init_len) - cread_add_str(buf, init_len, 1, &num, &eol_num, buf, *len); + if (buf[0]) + cread_add_str(buf, 1, &num, &eol_num, buf, len); + + hist_reset(); 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(); + beginning_of_line(&num); break; - case CTL_CH('c'): /* ^C - break */ - *buf = '\0'; /* discard input */ + case CTL_CH('c'): /* ^C - break */ + putchar('\n'); + *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); @@ -364,66 +545,89 @@ static int cread_line(const FLASH char *const prompt, char *buf, unsigned int *l eol_num--; } break; - case CTL_CH('k'): - ERASE_TO_EOL(); + case CTL_CH('k'): /* kill-line */ + erase_to_eol(&num, &eol_num); break; + case KEY_END: case CTL_CH('e'): - REFRESH_TO_EOL(); + refresh_to_eol(buf, &num, &eol_num); break; + case KEY_IC: case CTL_CH('o'): insert = !insert; break; case CTL_CH('x'): - case CTL_CH('u'): - BEGINNING_OF_LINE(); - ERASE_TO_EOL(); + case CTL_CH('u'): /* kill-whole-line */ + beginning_of_line(&num); + erase_to_eol(&num, &eol_num); break; case DEL: case DEL7: - case 8: + case 8: /* backward-delete-char */ if (num) { - wlen = eol_num - num; - num--; + uint_fast8_t wlen = eol_num - --num; + buf[eol_num] = ' '; memmove(&buf[num], &buf[num+1], wlen); getcmd_putch(CTL_BACKSPACE); putnstr(buf + num, wlen); - getcmd_putch(' '); do { getcmd_putch(CTL_BACKSPACE); - } while (wlen--); + } while (--wlen); eol_num--; } break; - case CTL_CH('p'): - case CTL_CH('n'): - { - char *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) { + /* first, go home */ + beginning_of_line(&num); + /* overwrite current line */ + cread_add_str(hline, 0, &num, &eol_num, buf, len); + /* erase to end of line */ + erase_to_eol(&num, &eol_num); - esc_len = 0; - - if (ichar == CTL_CH('p')) - hline = hist_prev(); - else - hline = hist_next(); - - if (!hline) { + } 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; + 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(buf, num); + else + hline = hist_search_forward(buf, num); + + if (hline) { + uint_fast8_t num2 = num; + /* overwrite current line from cursor position */ + cread_add_str(hline+num, 0, &num2, &eol_num, buf, len); + /* erase to end of line */ + erase_to_eol(&num2, &eol_num); + /* cursor back */ + while (num2-- > num) + getcmd_putch(CTL_BACKSPACE); + } else { + getcmd_cbeep(); + } + } else { + getcmd_cbeep(); + } + break; #ifdef CONFIG_AUTO_COMPLETE case '\t': { int num2, col; @@ -446,143 +650,23 @@ static int cread_line(const FLASH char *const prompt, char *buf, unsigned int *l } #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; + while (eol_num && buf[eol_num-1] == ' ') + --eol_num; /* remove trailing blanks */ buf[eol_num] = '\0'; /* lose the newline */ - if (buf[0] && buf[0] != CREAD_HIST_CHAR) + if (enable_history && buf[0]) cread_add_to_hist(buf); - hist_cur = hist_add_idx; - - return 0; + return eol_num; } -#endif /* CONFIG_CMDLINE_EDITING */ - /****************************************************************************/ -static int cli_readline_into_buffer(const FLASH char *const prompt, char *buffer) -{ - char *p = buffer; -#ifdef CONFIG_CMDLINE_EDITING - unsigned int 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); - 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(); - - /* - * 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 @@ -590,6 +674,8 @@ int cli_readline(const FLASH char *const prompt) */ console_buffer[0] = '\0'; - return cli_readline_into_buffer(prompt, console_buffer); -} + if (prompt) + my_puts_P(prompt); + return cread_line(prompt, console_buffer, CONFIG_SYS_CBSIZE, enable_history); +}