X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/c647afca0ab5d67de1c18b52b4e50262fcb73425..f6edf92baa4ed307ca517574f38dd0b8752cbc52:/avr/cli_readline.c diff --git a/avr/cli_readline.c b/avr/cli_readline.c index 5545015..81230e0 100644 --- a/avr/cli_readline.c +++ b/avr/cli_readline.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2014 Leo C. + * (C) Copyright 2014-2016 Leo C. * * (C) Copyright 2000 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -11,6 +11,7 @@ * SPDX-License-Identifier: GPL-2.0 */ +#include "cli_readline.h" #include "common.h" #include #include @@ -22,7 +23,6 @@ #include "con-utils.h" #include "print-utils.h" #include "command.h" -#include "cli_readline.h" @@ -67,14 +67,14 @@ struct fkey_tbl_s { 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(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(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(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: */ @@ -94,9 +94,9 @@ 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 +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 */ }; @@ -105,7 +105,8 @@ FKEY_TBL_ITEM(24~, KEY_F(12)), // Function key F12 typedef enum { STATE_GROUND, STATE_ESCAPE, - STATE_CSI_ENTRY + STATE_CSI_ENTRY, + STATE_SS3 } vtparse_state_t; #define CHB_SIZE 15 @@ -145,6 +146,15 @@ int vt_parse (void) 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: @@ -213,79 +223,146 @@ static void putnstr(char *str, int n) #define getcmd_getch() vt_parse() #define getcmd_cbeep() getcmd_putch('\a') -#define HIST_MAX 20 -static int_fast8_t hist_max; -static int_fast8_t hist_add_idx; -static int_fast8_t hist_cur = -1; +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 hist_node *hist_head; +static hist_node *hist_cur; -static void cread_add_to_hist(char *line) +static hist_node *hist_search_node(char *line) { - if (hist_max) { - int_fast8_t last = hist_add_idx; - if (--last < 0) - last = hist_max; + hist_node *p = hist_head; - if (!strcmp(line, hist_list[last])) - return; + 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); + + if (p) { + strcpy(p->line, line); + p->next = hist_head; + hist_head = p; } + return p; +} +#endif + +static hist_node *hist_new(char *line) +{ + hist_node *p = (hist_node *) malloc(sizeof (hist_node) + strlen(line) + 1); - char *p = strdup(line); if (p) { - free(hist_list[hist_add_idx]); - hist_list[hist_add_idx] = p; + strcpy(p->line, line); + p->next = NULL; + } + return p; +} - if (++hist_add_idx >= HIST_MAX) - hist_add_idx = 0; +static hist_node *hist_delete(void) +{ + hist_node *p = NULL; + hist_node *q = hist_head; - if (hist_add_idx > hist_max) - hist_max = hist_add_idx; + 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_fast8_t 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 n; +} + +static hist_node *cread_add_to_hist(char *line) +{ + hist_node * p; + + 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; - if (hist_cur == hist_add_idx) - return NULL; + hist_cur = hist_cur->next; - if (++hist_cur > hist_max) - hist_cur = 0; + return p->line; +} - if (hist_cur == hist_add_idx) - ret = ""; - else - ret = hist_list[hist_cur]; +static char *hist_next(void) +{ + hist_node *p = NULL; + hist_node *q = hist_head; + + if(q == hist_cur) + return NULL; + + while(q->next != hist_cur) { + p = q; + q = q->next; + } + hist_cur = q; - return ret; + return p ? p->line : ""; } @@ -308,7 +385,7 @@ static char *hist_next(void) #define REFRESH_TO_EOL() { \ if (num < eol_num) { \ - wlen = eol_num - num; \ + uint_fast8_t wlen = eol_num - num; \ putnstr(buf + num, wlen); \ num = eol_num; \ } \ @@ -347,7 +424,7 @@ static void cread_add_char(char ichar, bool insert, uint_fast8_t *num, } } -static void cread_add_str(char *str, int strsize, bool insert, +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) { @@ -357,22 +434,21 @@ static void cread_add_str(char *str, int strsize, bool insert, } } -static int cread_line(const FLASH char *const prompt, char *buf, uint_fast8_t *len) +static int cread_line(const FLASH char *const prompt, char *buf, + uint_fast8_t *len, bool enable_history) { uint_fast8_t num = 0; uint_fast8_t eol_num = 0; - uint_fast8_t wlen; - int ichar; bool insert = 1; - int init_len = strlen(buf); (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'); @@ -406,7 +482,7 @@ static int cread_line(const FLASH char *const prompt, char *buf, uint_fast8_t *l 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); @@ -439,7 +515,7 @@ static int cread_line(const FLASH char *const prompt, char *buf, uint_fast8_t *l case DEL7: 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); @@ -455,32 +531,64 @@ static int cread_line(const FLASH char *const prompt, char *buf, uint_fast8_t *l case CTL_CH('p'): /* previous-history */ case KEY_DOWN: case CTL_CH('n'): /* next-history */ - { - char *hline; - - if (ichar == CTL_CH('p') || ichar == KEY_UP) - hline = hist_prev(); - else - hline = hist_next(); - - if (!hline) { + 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; @@ -512,16 +620,17 @@ static int cread_line(const FLASH char *const prompt, char *buf, uint_fast8_t *l *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; } /****************************************************************************/ -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; uint_fast8_t len = CONFIG_SYS_CBSIZE; @@ -530,11 +639,11 @@ static int cli_readline_into_buffer(const FLASH char *const prompt, char *buffer 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; } -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 @@ -542,5 +651,5 @@ int cli_readline(const FLASH char *const prompt) */ console_buffer[0] = '\0'; - return cli_readline_into_buffer(prompt, console_buffer); + return cli_readline_into_buffer(prompt, console_buffer, enable_history); }