edit: Clean up escape code parser

This commit is contained in:
Jouni Malinen 2010-11-20 16:59:55 +02:00
parent 0bee81352f
commit 42034d6f60

View file

@ -464,6 +464,14 @@ enum edit_key_code {
EDIT_KEY_ALT_DOWN,
EDIT_KEY_ALT_RIGHT,
EDIT_KEY_ALT_LEFT,
EDIT_KEY_SHIFT_UP,
EDIT_KEY_SHIFT_DOWN,
EDIT_KEY_SHIFT_RIGHT,
EDIT_KEY_SHIFT_LEFT,
EDIT_KEY_ALT_SHIFT_UP,
EDIT_KEY_ALT_SHIFT_DOWN,
EDIT_KEY_ALT_SHIFT_RIGHT,
EDIT_KEY_ALT_SHIFT_LEFT,
EDIT_KEY_EOF
};
@ -475,37 +483,9 @@ static void show_esc_buf(const char *esc_buf, char c, int i)
}
static enum edit_key_code edit_read_key(int sock)
static enum edit_key_code esc_seq_to_key1_no(char last)
{
int c;
unsigned char buf[1];
int res;
static int esc = -1;
static char esc_buf[6];
res = read(sock, buf, 1);
if (res < 0)
perror("read");
if (res <= 0)
return EDIT_KEY_EOF;
c = buf[0];
if (esc >= 0) {
if (esc == 5) {
show_esc_buf(esc_buf, c, 0);
esc = -1;
} else {
esc_buf[esc++] = c;
esc_buf[esc] = '\0';
if (esc == 1)
return EDIT_KEY_NONE;
}
}
if (esc == 2 && esc_buf[0] == '[' && c >= 'A' && c <= 'Z') {
esc = -1;
switch (c) {
switch (last) {
case 'A':
return EDIT_KEY_UP;
case 'B':
@ -515,37 +495,31 @@ static enum edit_key_code edit_read_key(int sock)
case 'D':
return EDIT_KEY_LEFT;
default:
show_esc_buf(esc_buf, c, 1);
return EDIT_KEY_NONE;
}
}
if (esc > 1 && esc_buf[0] == '[') {
if ((c >= '0' && c <= '9') || c == ';')
return EDIT_KEY_NONE;
esc = -1;
if (esc_buf[1] == '1' && esc_buf[2] == ';' &&
esc_buf[3] == '5') {
switch (esc_buf[4]) {
static enum edit_key_code esc_seq_to_key1_shift(char last)
{
switch (last) {
case 'A':
return EDIT_KEY_CTRL_UP;
return EDIT_KEY_SHIFT_UP;
case 'B':
return EDIT_KEY_CTRL_DOWN;
return EDIT_KEY_SHIFT_DOWN;
case 'C':
return EDIT_KEY_CTRL_RIGHT;
return EDIT_KEY_SHIFT_RIGHT;
case 'D':
return EDIT_KEY_CTRL_LEFT;
return EDIT_KEY_SHIFT_LEFT;
default:
show_esc_buf(esc_buf, c, 2);
return EDIT_KEY_NONE;
}
}
if (esc_buf[1] == '1' && esc_buf[2] == ';' &&
esc_buf[3] == '3') {
switch (esc_buf[4]) {
static enum edit_key_code esc_seq_to_key1_alt(char last)
{
switch (last) {
case 'A':
return EDIT_KEY_ALT_UP;
case 'B':
@ -555,14 +529,68 @@ static enum edit_key_code edit_read_key(int sock)
case 'D':
return EDIT_KEY_ALT_LEFT;
default:
show_esc_buf(esc_buf, c, 7);
return EDIT_KEY_NONE;
}
}
switch (c) {
case '~':
switch (atoi(&esc_buf[1])) {
static enum edit_key_code esc_seq_to_key1_alt_shift(char last)
{
switch (last) {
case 'A':
return EDIT_KEY_ALT_SHIFT_UP;
case 'B':
return EDIT_KEY_ALT_SHIFT_DOWN;
case 'C':
return EDIT_KEY_ALT_SHIFT_RIGHT;
case 'D':
return EDIT_KEY_ALT_SHIFT_LEFT;
default:
return EDIT_KEY_NONE;
}
}
static enum edit_key_code esc_seq_to_key1_ctrl(char last)
{
switch (last) {
case 'A':
return EDIT_KEY_CTRL_UP;
case 'B':
return EDIT_KEY_CTRL_DOWN;
case 'C':
return EDIT_KEY_CTRL_RIGHT;
case 'D':
return EDIT_KEY_CTRL_LEFT;
default:
return EDIT_KEY_NONE;
}
}
static enum edit_key_code esc_seq_to_key1(int param1, int param2, char last)
{
/* ESC-[<param1>;<param2><last> */
if (param1 < 0 && param2 < 0)
return esc_seq_to_key1_no(last);
if (param1 == 1 && param2 == 2)
return esc_seq_to_key1_shift(last);
if (param1 == 1 && param2 == 3)
return esc_seq_to_key1_alt(last);
if (param1 == 1 && param2 == 4)
return esc_seq_to_key1_alt_shift(last);
if (param1 == 1 && param2 == 5)
return esc_seq_to_key1_ctrl(last);
if (param2 < 0) {
if (last != '~')
return EDIT_KEY_NONE;
switch (param1) {
case 2:
return EDIT_KEY_INSERT;
case 3:
@ -587,20 +615,21 @@ static enum edit_key_code edit_read_key(int sock)
return EDIT_KEY_F11;
case 24:
return EDIT_KEY_F12;
default:
show_esc_buf(esc_buf, c, 3);
return EDIT_KEY_NONE;
}
break;
default:
show_esc_buf(esc_buf, c, 4);
return EDIT_KEY_NONE;
}
}
if (esc > 1 && esc_buf[0] == 'O') {
esc = -1;
switch (esc_buf[1]) {
return EDIT_KEY_NONE;
}
static enum edit_key_code esc_seq_to_key2(int param1, int param2, char last)
{
/* ESC-O<param1>;<param2><last> */
if (param1 >= 0 || param2 >= 0)
return EDIT_KEY_NONE;
switch (last) {
case 'F':
return EDIT_KEY_END;
case 'H':
@ -614,14 +643,93 @@ static enum edit_key_code edit_read_key(int sock)
case 'S':
return EDIT_KEY_F4;
default:
show_esc_buf(esc_buf, c, 5);
return EDIT_KEY_NONE;
}
}
if (esc > 1) {
static enum edit_key_code esc_seq_to_key(char *seq)
{
char last, *pos;
int param1 = -1, param2 = -1;
enum edit_key_code ret = EDIT_KEY_NONE;
for (pos = seq; *pos; pos++)
last = *pos;
if (seq[1] >= '0' && seq[1] <= '9') {
param1 = atoi(&seq[1]);
pos = os_strchr(seq, ';');
if (pos)
param2 = atoi(pos + 1);
}
if (seq[0] == '[')
ret = esc_seq_to_key1(param1, param2, last);
else if (seq[0] == 'O')
ret = esc_seq_to_key2(param1, param2, last);
if (ret != EDIT_KEY_NONE)
return ret;
edit_clear_line();
printf("\rUnknown escape sequence '%s'\n", seq);
edit_redraw();
return EDIT_KEY_NONE;
}
static enum edit_key_code edit_read_key(int sock)
{
int c;
unsigned char buf[1];
int res;
static int esc = -1;
static char esc_buf[7];
res = read(sock, buf, 1);
if (res < 0)
perror("read");
if (res <= 0)
return EDIT_KEY_EOF;
c = buf[0];
if (esc >= 0) {
if (c == 27 /* ESC */) {
esc = 0;
return EDIT_KEY_NONE;
}
if (esc == 6) {
show_esc_buf(esc_buf, c, 0);
esc = -1;
} else {
esc_buf[esc++] = c;
esc_buf[esc] = '\0';
}
}
if (esc == 1) {
if (esc_buf[0] != '[' && esc_buf[0] != 'O') {
show_esc_buf(esc_buf, c, 1);
esc = -1;
return EDIT_KEY_NONE;
} else
return EDIT_KEY_NONE; /* Escape sequence continues */
}
if (esc > 1) {
if ((c >= '0' && c <= '9') || c == ';')
return EDIT_KEY_NONE; /* Escape sequence continues */
if (c == '~' || (c >= 'A' && c <= 'Z')) {
esc = -1;
return esc_seq_to_key(esc_buf);
}
show_esc_buf(esc_buf, c, 2);
esc = -1;
show_esc_buf(esc_buf, c, 6);
return EDIT_KEY_NONE;
}