Skip to content

Commit 53b6313

Browse files
author
Daniel Thompson
committed
kdb: Tidy up code to handle escape sequences
kdb_read_get_key() has extremely complex break/continue control flow managed by state variables and is very hard to review or modify. In particular the way the escape sequence handling interacts with the general control flow is hard to follow. Separate out the escape key handling, without changing the control flow. This makes the main body of the code easier to review. Signed-off-by: Daniel Thompson <[email protected]> Reviewed-by: Douglas Anderson <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent d07ce4e commit 53b6313

File tree

1 file changed

+67
-61
lines changed

1 file changed

+67
-61
lines changed

kernel/debug/kdb/kdb_io.c

Lines changed: 67 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,65 @@ static int kgdb_transition_check(char *buffer)
4949
return 0;
5050
}
5151

52+
/**
53+
* kdb_handle_escape() - validity check on an accumulated escape sequence.
54+
* @buf: Accumulated escape characters to be examined. Note that buf
55+
* is not a string, it is an array of characters and need not be
56+
* nil terminated.
57+
* @sz: Number of accumulated escape characters.
58+
*
59+
* Return: -1 if the escape sequence is unwanted, 0 if it is incomplete,
60+
* otherwise it returns a mapped key value to pass to the upper layers.
61+
*/
62+
static int kdb_handle_escape(char *buf, size_t sz)
63+
{
64+
char *lastkey = buf + sz - 1;
65+
66+
switch (sz) {
67+
case 1:
68+
if (*lastkey == '\e')
69+
return 0;
70+
break;
71+
72+
case 2: /* \e<something> */
73+
if (*lastkey == '[')
74+
return 0;
75+
break;
76+
77+
case 3:
78+
switch (*lastkey) {
79+
case 'A': /* \e[A, up arrow */
80+
return 16;
81+
case 'B': /* \e[B, down arrow */
82+
return 14;
83+
case 'C': /* \e[C, right arrow */
84+
return 6;
85+
case 'D': /* \e[D, left arrow */
86+
return 2;
87+
case '1': /* \e[<1,3,4>], may be home, del, end */
88+
case '3':
89+
case '4':
90+
return 0;
91+
}
92+
break;
93+
94+
case 4:
95+
if (*lastkey == '~') {
96+
switch (buf[2]) {
97+
case '1': /* \e[1~, home */
98+
return 1;
99+
case '3': /* \e[3~, del */
100+
return 4;
101+
case '4': /* \e[4~, end */
102+
return 5;
103+
}
104+
}
105+
break;
106+
}
107+
108+
return -1;
109+
}
110+
52111
static int kdb_read_get_key(char *buffer, size_t bufsize)
53112
{
54113
#define ESCAPE_UDELAY 1000
@@ -102,68 +161,15 @@ static int kdb_read_get_key(char *buffer, size_t bufsize)
102161
escape_delay = 2;
103162
continue;
104163
}
105-
if (ped - escape_data == 1) {
106-
/* \e */
107-
continue;
108-
} else if (ped - escape_data == 2) {
109-
/* \e<something> */
110-
if (key != '[')
111-
escape_delay = 2;
112-
continue;
113-
} else if (ped - escape_data == 3) {
114-
/* \e[<something> */
115-
int mapkey = 0;
116-
switch (key) {
117-
case 'A': /* \e[A, up arrow */
118-
mapkey = 16;
119-
break;
120-
case 'B': /* \e[B, down arrow */
121-
mapkey = 14;
122-
break;
123-
case 'C': /* \e[C, right arrow */
124-
mapkey = 6;
125-
break;
126-
case 'D': /* \e[D, left arrow */
127-
mapkey = 2;
128-
break;
129-
case '1': /* dropthrough */
130-
case '3': /* dropthrough */
131-
/* \e[<1,3,4>], may be home, del, end */
132-
case '4':
133-
mapkey = -1;
134-
break;
135-
}
136-
if (mapkey != -1) {
137-
if (mapkey > 0) {
138-
escape_data[0] = mapkey;
139-
escape_data[1] = '\0';
140-
}
141-
escape_delay = 2;
142-
}
143-
continue;
144-
} else if (ped - escape_data == 4) {
145-
/* \e[<1,3,4><something> */
146-
int mapkey = 0;
147-
if (key == '~') {
148-
switch (escape_data[2]) {
149-
case '1': /* \e[1~, home */
150-
mapkey = 1;
151-
break;
152-
case '3': /* \e[3~, del */
153-
mapkey = 4;
154-
break;
155-
case '4': /* \e[4~, end */
156-
mapkey = 5;
157-
break;
158-
}
159-
}
160-
if (mapkey > 0) {
161-
escape_data[0] = mapkey;
162-
escape_data[1] = '\0';
163-
}
164-
escape_delay = 2;
165-
continue;
164+
165+
key = kdb_handle_escape(escape_data, ped - escape_data);
166+
if (key > 0) {
167+
escape_data[0] = key;
168+
escape_data[1] = '\0';
166169
}
170+
if (key)
171+
escape_delay = 2;
172+
continue;
167173
}
168174
break; /* A key to process */
169175
}

0 commit comments

Comments
 (0)