aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-06-16 14:47:00 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2021-06-16 23:53:03 +0200
commit038d4007092f6d0d2dc107f31397c57e62751717 (patch)
treef77d354026e4aefb9f7362e43e8aca5a3d4fbf0d
parentac04eb3657f99f6952971d8ceb8a82d73b783de8 (diff)
downloadbusybox-w32-038d4007092f6d0d2dc107f31397c57e62751717.tar.gz
busybox-w32-038d4007092f6d0d2dc107f31397c57e62751717.tar.bz2
busybox-w32-038d4007092f6d0d2dc107f31397c57e62751717.zip
vi: reject change command when motion fails
If the motion command used to define the range of a change, yank or delete fails the whole command should be rejected. BusyBox vi already handled failed searches in these circumstances. Add some more cases: - non-existent mark: d'x - movement beyond end of file: c99999+ or 99999<< This is implemented using a global variable which is set when a command error is detected. Unlike the case of motion within a line it's insufficient to check that the motion command doesn't move the cursor: this fails to process 'LyL' correctly, for example, as the second 'L' doesn't move the cursor. function old new delta indicate_error 75 82 +7 find_range 686 692 +6 do_cmd 4851 4852 +1 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 14/0) Total: 14 bytes Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/vi.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/editors/vi.c b/editors/vi.c
index 231c62809..b06270dfd 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -378,6 +378,7 @@ struct globals {
378#if ENABLE_FEATURE_VI_SETOPTS 378#if ENABLE_FEATURE_VI_SETOPTS
379 int indentcol; // column of recently autoindent, 0 or -1 379 int indentcol; // column of recently autoindent, 0 or -1
380#endif 380#endif
381 smallint cmd_error;
381 382
382 // former statics 383 // former statics
383#if ENABLE_FEATURE_VI_YANKMARK 384#if ENABLE_FEATURE_VI_YANKMARK
@@ -502,6 +503,7 @@ struct globals {
502#define dotcnt (G.dotcnt ) 503#define dotcnt (G.dotcnt )
503#define last_search_pattern (G.last_search_pattern) 504#define last_search_pattern (G.last_search_pattern)
504#define indentcol (G.indentcol ) 505#define indentcol (G.indentcol )
506#define cmd_error (G.cmd_error )
505 507
506#define edit_file__cur_line (G.edit_file__cur_line) 508#define edit_file__cur_line (G.edit_file__cur_line)
507#define refresh__old_offset (G.refresh__old_offset) 509#define refresh__old_offset (G.refresh__old_offset)
@@ -1099,6 +1101,7 @@ static void indicate_error(void)
1099 if (crashme > 0) 1101 if (crashme > 0)
1100 return; 1102 return;
1101#endif 1103#endif
1104 cmd_error = TRUE;
1102 if (!err_method) { 1105 if (!err_method) {
1103 write1(ESC_BELL); 1106 write1(ESC_BELL);
1104 } else { 1107 } else {
@@ -3399,8 +3402,11 @@ static int find_range(char **start, char **stop, int cmd)
3399#endif 3402#endif
3400 // these cmds operate on whole lines 3403 // these cmds operate on whole lines
3401 buftype = WHOLE; 3404 buftype = WHOLE;
3402 if (--cmdcnt > 0) 3405 if (--cmdcnt > 0) {
3403 do_cmd('j'); 3406 do_cmd('j');
3407 if (cmd_error)
3408 buftype = -1;
3409 }
3404 } else if (strchr("^%$0bBeEfFtThnN/?|{}\b\177", c)) { 3410 } else if (strchr("^%$0bBeEfFtThnN/?|{}\b\177", c)) {
3405 // Most operate on char positions within a line. Of those that 3411 // Most operate on char positions within a line. Of those that
3406 // don't '%' needs no special treatment, search commands are 3412 // don't '%' needs no special treatment, search commands are
@@ -3430,6 +3436,8 @@ static int find_range(char **start, char **stop, int cmd)
3430 // these operate on whole lines 3436 // these operate on whole lines
3431 buftype = WHOLE; 3437 buftype = WHOLE;
3432 do_cmd(c); // execute movement cmd 3438 do_cmd(c); // execute movement cmd
3439 if (cmd_error)
3440 buftype = -1;
3433 } else if (c == ' ' || c == 'l') { 3441 } else if (c == ' ' || c == 'l') {
3434 // forward motion by character 3442 // forward motion by character
3435 int tmpcnt = (cmdcnt ?: 1); 3443 int tmpcnt = (cmdcnt ?: 1);
@@ -3515,6 +3523,7 @@ static void do_cmd(int c)
3515// p = q = save_dot = buf; // quiet the compiler 3523// p = q = save_dot = buf; // quiet the compiler
3516 memset(buf, '\0', sizeof(buf)); 3524 memset(buf, '\0', sizeof(buf));
3517 keep_index = FALSE; 3525 keep_index = FALSE;
3526 cmd_error = FALSE;
3518 3527
3519 show_status_line(); 3528 show_status_line();
3520 3529
@@ -3699,6 +3708,8 @@ static void do_cmd(int c)
3699 dot = q; 3708 dot = q;
3700 dot_begin(); // go to B-o-l 3709 dot_begin(); // go to B-o-l
3701 dot_skip_over_ws(); 3710 dot_skip_over_ws();
3711 } else {
3712 indicate_error();
3702 } 3713 }
3703 } else if (c1 == '\'') { // goto previous context 3714 } else if (c1 == '\'') { // goto previous context
3704 dot = swap_context(dot); // swap current and previous context 3715 dot = swap_context(dot); // swap current and previous context