summaryrefslogtreecommitdiff
path: root/avr
diff options
context:
space:
mode:
authorLeo C2015-06-11 17:30:49 +0200
committerLeo C2015-06-11 17:30:49 +0200
commit8506d791786eea8ee55db5418a8f646bb2dd3a6d (patch)
treea7a1c470de53669dd0406561dc2dc6aac89c8657 /avr
parent8591c65b4c987852c76ebdea35498295969068e1 (diff)
downloadz180-stamp-8506d791786eea8ee55db5418a8f646bb2dd3a6d.zip
VT100/ANSI parser
Diffstat (limited to 'avr')
-rw-r--r--avr/cli_readline.c270
1 files changed, 184 insertions, 86 deletions
diff --git a/avr/cli_readline.c b/avr/cli_readline.c
index 08d2c4b..8795a97 100644
--- a/avr/cli_readline.c
+++ b/avr/cli_readline.c
@@ -13,6 +13,7 @@
#include <string.h>
#include <stdio.h>
+#include <ctype.h>
#include "config.h"
#include "con-utils.h"
@@ -20,12 +21,180 @@
#include "command.h"
#include "cli_readline.h"
+
+
+/************************************************************************************************/
+/* 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
+} vtparse_state_t;
+
+#define CHB_SIZE 15
+
+static
+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_param;
+ int ch;
+
+
+ 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;
+ }
+ 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;
+ }
+ break; /* while */
+ }
+
+ return ch;
+}
+
+/************************************************************************************************/
+
+
+
+
+
char console_buffer[CONFIG_SYS_CBSIZE + 1]; /* console I/O buffer */
+#ifndef CONFIG_CMDLINE_EDITING
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)
{
char *s;
@@ -80,7 +249,7 @@ static void putnstr(char *str, int n)
#define CREAD_HIST_CHAR ('!')
#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
@@ -167,26 +336,6 @@ static char *hist_next(void)
return ret;
}
-#ifndef CONFIG_CMDLINE_EDITING
-static void cread_print_hist_list(void)
-{
- int i;
- unsigned n;
-
- n = hist_num - hist_max;
-
- 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++;
- }
-}
-#endif /* CONFIG_CMDLINE_EDITING */
#define BEGINNING_OF_LINE() { \
while (num) { \
@@ -261,10 +410,8 @@ static int cread_line(const FLASH char *const prompt, char *buf, unsigned int *l
unsigned int num = 0;
unsigned int eol_num = 0;
unsigned int wlen;
- char ichar;
+ int ichar;
int insert = 1;
- int esc_len = 0;
- char esc_save[8];
int init_len = strlen(buf);
(void) prompt;
@@ -280,82 +427,31 @@ static int cread_line(const FLASH char *const prompt, char *buf, unsigned int *l
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 */
return -1;
+ case KEY_RIGHT:
case CTL_CH('f'):
if (num < eol_num) {
getcmd_putch(buf[num]);
num++;
}
break;
+ case KEY_LEFT:
case CTL_CH('b'):
if (num) {
getcmd_putch(CTL_BACKSPACE);
num--;
}
break;
+ case KEY_DC:
case CTL_CH('d'):
if (num < eol_num) {
wlen = eol_num - num - 1;
@@ -377,6 +473,7 @@ static int cread_line(const FLASH char *const prompt, char *buf, unsigned int *l
case CTL_CH('e'):
REFRESH_TO_EOL();
break;
+ case KEY_IC:
case CTL_CH('o'):
insert = !insert;
break;
@@ -401,14 +498,14 @@ static int cread_line(const FLASH char *const prompt, char *buf, unsigned int *l
eol_num--;
}
break;
+ case KEY_UP:
case CTL_CH('p'):
+ case KEY_DOWN:
case CTL_CH('n'):
{
char *hline;
- esc_len = 0;
-
- if (ichar == CTL_CH('p'))
+ if (ichar == CTL_CH('p') || ichar == KEY_UP)
hline = hist_prev();
else
hline = hist_next();
@@ -453,15 +550,16 @@ 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;
buf[eol_num] = '\0'; /* lose the newline */
- if (buf[0] && buf[0] != CREAD_HIST_CHAR)
+ if (buf[0] /* && buf[0] != CREAD_HIST_CHAR */)
cread_add_to_hist(buf);
hist_cur = hist_add_idx;