aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-10-14 10:09:56 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-10-14 10:09:56 +0000
commit5373fbcd1140a9fb4b2e259c04cdd79d4b80bc3b (patch)
tree11dd19b912f6ed606f7a50184c20ff38bac3474f
parent5e38cd910acacccb98387b0404bb2130280d0772 (diff)
downloadbusybox-w32-5373fbcd1140a9fb4b2e259c04cdd79d4b80bc3b.tar.gz
busybox-w32-5373fbcd1140a9fb4b2e259c04cdd79d4b80bc3b.tar.bz2
busybox-w32-5373fbcd1140a9fb4b2e259c04cdd79d4b80bc3b.zip
vi: add comments to Rob's algorithm of reading and matching ESC sequences
(nice work btw!)
-rw-r--r--editors/vi.c56
1 files changed, 33 insertions, 23 deletions
diff --git a/editors/vi.c b/editors/vi.c
index 3c3d759e5..e1cd7a482 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -2243,60 +2243,70 @@ static char readit(void) // read (maybe cursor) key from stdin
2243 2243
2244 fflush(stdout); 2244 fflush(stdout);
2245 2245
2246 // If no data, block waiting for input.
2247 n = chars_to_parse; 2246 n = chars_to_parse;
2248 while (!n) { 2247 if (n == 0) {
2248 // If no data, block waiting for input.
2249 n = safe_read(0, readbuffer, 1); 2249 n = safe_read(0, readbuffer, 1);
2250 if (n <= 0) { 2250 if (n <= 0) {
2251 error:
2251 place_cursor(rows - 1, 0, FALSE); // go to bottom of screen 2252 place_cursor(rows - 1, 0, FALSE); // go to bottom of screen
2252 clear_to_eol(); // erase to end of line 2253 clear_to_eol(); // erase to end of line
2253 cookmode(); // terminal to "cooked" 2254 cookmode(); // terminal to "cooked"
2254 bb_error_msg_and_die("can't read user input"); 2255 bb_error_msg_and_die("can't read user input");
2255 } 2256 }
2256 // Returning NUL from this routine would be bad.
2257 if (*readbuffer) break;
2258 } 2257 }
2259 2258
2260 // Grab character to return from buffer 2259 // Grab character to return from buffer
2261 c = *readbuffer; 2260 c = readbuffer[0];
2261 // Returning NUL from this routine would be bad.
2262 if (c == '\0')
2263 c = ' ';
2262 n--; 2264 n--;
2263 if (n) memmove(readbuffer, readbuffer+1, n); 2265 if (n) memmove(readbuffer, readbuffer + 1, n);
2264 2266
2265 // If it's an escape sequence, loop through known matches. 2267 // If it's an escape sequence, loop through known matches.
2266 if (c == 27) { 2268 if (c == 27) {
2267 const struct esc_cmds *eindex; 2269 const struct esc_cmds *eindex;
2268 2270
2269 for (eindex = esccmds; eindex < esccmds+ARRAY_SIZE(esccmds); eindex++) { 2271 for (eindex = esccmds; eindex < esccmds + ARRAY_SIZE(esccmds); eindex++) {
2270 int i=0, cnt = strnlen(eindex->seq, 4); 2272 // n - position in seq to read
2273 int i = 0; // position in seq to compare
2274 int cnt = strnlen(eindex->seq, 4);
2271 2275
2272 // Loop through chars in this sequence. 2276 // Loop through chars in this sequence.
2273 for (;;) { 2277 for (;;) {
2274 2278 // We've matched this escape sequence up to [i-1]
2275 // If we've matched this escape sequence so far but need more
2276 // chars, read another as long as it wouldn't block. (Note that
2277 // escape sequences come in as a unit, so if we would block
2278 // it's not really an escape sequence.)
2279 if (n <= i) { 2279 if (n <= i) {
2280 // Need more chars, read another one if it wouldn't block.
2281 // (Note that escape sequences come in as a unit,
2282 // so if we would block it's not really an escape sequence.)
2280 struct pollfd pfd; 2283 struct pollfd pfd;
2281 pfd.fd = 0; 2284 pfd.fd = 0;
2282 pfd.events = POLLIN; 2285 pfd.events = POLLIN;
2283 if (0 < safe_poll(&pfd, 1, 300) 2286 // TODO: what is a good timeout here? why?
2284 && 0 < safe_read(0, readbuffer + n, 1)) 2287 if (safe_poll(&pfd, 1, /*timeout:*/ 0)) {
2285 n++; 2288 if (safe_read(0, readbuffer + n, 1) <= 0)
2286 2289 goto error;
2287 // Since the array is sorted from shortest to longest, if 2290 n++;
2288 // we needed more data we can't match anything later, so 2291 } else {
2289 // break out of both loops. 2292 // No more data!
2290 else goto loop_out; 2293 // Array is sorted from shortest to longest,
2294 // we can't match anything later in array,
2295 // break out of both loops.
2296 goto loop_out;
2297 }
2291 } 2298 }
2292 if (readbuffer[i] != eindex->seq[i]) break; 2299 if (readbuffer[i] != eindex->seq[i])
2293 if (++i == cnt) { 2300 break; // try next seq
2301 if (++i == cnt) { // entire seq matched
2294 c = eindex->val; 2302 c = eindex->val;
2295 n = 0; 2303 n = 0;
2296 goto loop_out; 2304 goto loop_out;
2297 } 2305 }
2298 } 2306 }
2299 } 2307 }
2308 // We did not find matching sequence, it was a bare ESC.
2309 // We possibly read and stored more input in readbuffer by now.
2300 } 2310 }
2301loop_out: 2311loop_out:
2302 2312