X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/4912667be3154f62d3206a47b6e748b0b6281ae3..f1e16f884308e8ef720a4ecbcdcc97af97dce4bd:/avr/cli_readline.c diff --git a/avr/cli_readline.c b/avr/cli_readline.c index be753d5..0ed8f67 100644 --- a/avr/cli_readline.c +++ b/avr/cli_readline.c @@ -15,7 +15,6 @@ #include "common.h" #include #include -#include #include #include @@ -23,6 +22,13 @@ #include "con-utils.h" #include "print-utils.h" #include "command.h" +#include "debug.h" + + +#define DEBUG_READLINE 0 /* set to 1 to debug */ + +#define debug_readline(fmt, args...) \ + debug_cond(DEBUG_READLINE, fmt, ##args) @@ -85,13 +91,16 @@ 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 consoe */ +/* 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 @@ -125,7 +134,7 @@ int vt_parse (void) static vtparse_state_t state = STATE_GROUND; char buf[CHB_SIZE+1]; uint8_t param[2]; - uint8_t i_buf; + uint8_t i_buf = 0; uint8_t i_param; int ch; @@ -161,8 +170,10 @@ int vt_parse (void) state = STATE_GROUND; break; case STATE_SS3: - if (ch == 'F') /* weird */ + if (ch == 'F') ch = KEY_END; + if (ch == 'H') + ch = KEY_HOME; state = STATE_GROUND; break; case STATE_CSI_ENTRY: @@ -212,188 +223,190 @@ int vt_parse (void) */ -struct hist_node_s { - struct hist_node_s *next; - char line[]; -}; -typedef struct hist_node_s hist_node; - +char histbuf[CONFIG_SYS_HISTSIZE+1]; +#define HISTBUFE (histbuf+CONFIG_SYS_HISTSIZE) -static hist_node *hist_head; -static hist_node *hist_cur; +static char *hist_head; +static char *hist_cur; static void hist_reset(void) { + if (hist_head == NULL) + hist_head = HISTBUFE; hist_cur = hist_head; } -static hist_node *hist_search_node(char *line) +static char *hist_entry_next(char *p) { - hist_node *p = hist_head; + if (*p) + while (*p++); - while (p && strcmp(p->line, line)) - p = p->next; return p; } -#if 0 -static hist_node *hist_insert(char *line) +static char *hist_entry_prev(char *p) { - hist_node *p = (hist_node *) malloc(sizeof (hist_node) + strlen(line) + 1); + if (p == hist_head) + return NULL; + + --p; + while (p != hist_head && *(p-1) != 0) + --p; - if (p) { - strcpy(p->line, line); - p->next = hist_head; - hist_head = p; - } return p; } -#endif -static hist_node *hist_new(char *line) +static char *hist_search_entry(char *line) { - hist_node *p = (hist_node *) malloc(sizeof (hist_node) + strlen(line) + 1); + char *p = hist_head; - if (p) { - strcpy(p->line, line); - p->next = NULL; - } - return p; + while (*p && strcmp(p, line)) + p = hist_entry_next(p); + return *p ? p : NULL; } -static hist_node *hist_delete(void) +static char *hist_delete(size_t amount) { - hist_node *p = NULL; - hist_node *q = hist_head; + char *p; - if (q) { - while(q->next) { - p = q; - q = q->next; - } - free(q); - if (p) - p->next = NULL; + p = HISTBUFE - amount; + if (p < hist_head) + p = hist_head; + + while (p > hist_head && *(p-1)) + --p; + + if (p == hist_head) + hist_head = HISTBUFE; + else { + size_t shift = HISTBUFE - p; + size_t len = p - hist_head; + hist_head = memmove(hist_head + shift, hist_head, len); } - return p; + return hist_head; } -static hist_node *hist_unlink(hist_node *pos) +static char *hist_delete_entry(char *entry) { - hist_node *p = NULL; - hist_node *q = hist_head; + size_t shift = strlen(entry) + 1; + size_t len = entry - hist_head; - 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; + hist_head = memmove(hist_head + shift, hist_head, len); + + return hist_head; } -static uint_fast8_t hist_count(void) + +static char *hist_add_entry(char *line) { - hist_node *p = hist_head; + char *p = hist_head; + + if (p == NULL) + p = HISTBUFE; + + char *q = p - strlen(line) - 1; + if (q < histbuf) + q = histbuf; + + strlcpy(q, line, p - q); + + hist_head = q; + + return hist_head; +} + +static uint_fast8_t hist_get_count(void) +{ + char *p = hist_head; uint_fast8_t n = 0; - while (p) { + while (*p) { ++n; - p = p->next; + while (*p++); } return n; } -static hist_node *cread_add_to_hist(char *line) +static int hist_get_size(void) { - hist_node * p; + return HISTBUFE - hist_head; +} - p = hist_search_node(line); - if (p) - hist_unlink(p); - else - p = hist_new(line); +static char *cread_add_to_hist(char *line) +{ + char *p; - if (p) { - p->next = hist_head; - hist_head = p; + p = hist_search_entry(line); + if (p) + hist_delete_entry(p); + else { + size_t free = hist_head - histbuf; + if (free < strlen(line) + 1) + hist_delete(strlen(line) + 1 - free); } + hist_add_entry(line); - if (hist_count() > CONFIG_SYS_HIST_MAX) - hist_delete(); return p; } static char *hist_prev(void) { - hist_node *p = hist_cur; + char *p = hist_cur; - if (p == NULL) + if (*p == '\0') return NULL; - hist_cur = p->next; + hist_cur = hist_entry_next(p); - return p->line; + return p; } static char *hist_next(void) { - hist_node *p = NULL; - hist_node *q = hist_head; + char *p = hist_cur; - if(q == hist_cur) + if(p == hist_head) return NULL; - while(q->next != hist_cur) { - p = q; - q = q->next; - } - hist_cur = q; + p = hist_entry_prev(p); + hist_cur = p; - return p ? p->line : ""; + return p == hist_head ? "" : hist_entry_prev(p); } static char *hist_search_backward(char* buf, uint8_t num) { - hist_node *p = hist_cur; + char *p = hist_cur; - if (p == NULL) + if (*p == '\0') return NULL; - while (p->next && strncmp(p->line, buf, num)) - p = p->next; + while (*p && strncmp(p, buf, num)) + p = hist_entry_next(p); - if(!strncmp(p->line, buf, num)) { - hist_cur = p->next; - return p->line; + if(!strncmp(p, buf, num)) { + hist_cur = hist_entry_next(p); + return p; } + return NULL; } static char *hist_search_forward (char* buf, uint8_t num) { - hist_node *p = NULL; - hist_node *match = NULL; - hist_node *q = hist_head; + char *p = hist_cur; - if(q == hist_cur) - return NULL; + if(p != hist_head && (p = hist_entry_prev(p)) != NULL) { + do { + p = hist_entry_prev(p); + } while (p && strncmp(p, buf, num) != 0); - while(q->next != hist_cur) { - p = q; - q = q->next; - if (p && !strncmp(p->line, buf, num)) - match = p; + //if(!strncmp(p, buf, num)) { + if(p) { + hist_cur = hist_entry_next(p); + return p; + } } - if(match) { - hist_cur = match->next; - return match->line; - } return NULL; } @@ -654,8 +667,20 @@ static int cread_line(const FLASH char *const prompt, char *buf, --eol_num; /* remove trailing blanks */ buf[eol_num] = '\0'; /* lose the newline */ - if (enable_history && buf[0]) + uint_fast8_t i = 0; + while (buf[i] == ' ') + ++i; /* remove leading blanks */ + if (i) { + eol_num -= i; + memmove(buf, buf+i, eol_num+1); + } + + debug_readline("### hist_head: %p, hist_cur: %p\n", hist_head, hist_cur); + if (enable_history && buf[0]) { cread_add_to_hist(buf); + debug_readline("### hist_head: %p, hist_cur: %p, hist_size: %3d, hist_count: %2d\n", + hist_head, hist_cur, hist_get_size(), hist_get_count()); + } return eol_num; }