[git commit] vi: fix ":list" command
Denys Vlasenko
vda.linux at googlemail.com
Fri Feb 6 23:52:49 UTC 2026
commit: https://git.busybox.net/busybox/commit/?id=79d35b5a0eae5d0784f34a9dcb6774220aedb611
branch: https://git.busybox.net/busybox/log/?h=master
function old new delta
.rodata 107010 107007 -3
show_status_line 372 362 -10
colon 3989 3942 -47
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-60) Total: -60 bytes
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
editors/vi.c | 62 +++++++++++++++++++++++++++++-------------------------------
1 file changed, 30 insertions(+), 32 deletions(-)
diff --git a/editors/vi.c b/editors/vi.c
index 13f79ed10..3bea8f3e2 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -555,7 +555,6 @@ static int crashme = 0;
#endif
static void show_status_line(void); // put a message on the bottom line
-static void status_line_bold(const char *, ...);
static void show_help(void)
{
@@ -1336,11 +1335,10 @@ static void show_status_line(void)
go_bottom_and_clear_to_eol();
write1(status_buffer);
if (have_status_msg) {
- if (((int)strlen(status_buffer) - (have_status_msg - 1)) >
- (columns - 1) ) {
- have_status_msg = 0;
+ int n = (int)strlen(status_buffer) - (have_status_msg - 1);
+ // careful with int->unsigned promotion in comparison!
+ if (n >= 0 && n >= columns)
Hit_Return();
- }
have_status_msg = 0;
}
place_cursor(crow, ccol); // put cursor back in correct place
@@ -2849,7 +2847,8 @@ static void colon(char *buf)
}
not_implemented(p);
#else
- char cmd[MAX_INPUT_LEN], *args;
+ char cmd[sizeof("features!")]; // longest known command + NUL
+ char *args;
int cmdlen;
char *useforce;
char *q, *r;
@@ -2888,14 +2887,12 @@ static void colon(char *buf)
goto ret;
// get the COMMAND into cmd[]
- args = skip_non_whitespace(buf);
- safe_strncpy(cmd, buf, (args - buf) + 1);
-//NB: in "s/find/repl" and "!CMD" cases, we copy unnecessary data into buf[]
+ safe_strncpy(cmd, buf, sizeof(cmd));
useforce = last_char_is(cmd, '!');
if (useforce && useforce > cmd)
*useforce = '\0'; // "CMD!" -> "CMD" (unless single "!")
// find ARGuments
- args = skip_whitespace(args);
+ args = skip_whitespace(skip_non_whitespace(buf));
// assume the command will want a range, certain commands
// (read, substitute) need to adjust these assumptions
@@ -3032,36 +3029,41 @@ static void colon(char *buf)
rawmode();
Hit_Return();
} else if (strncmp(cmd, "list", cmdlen) == 0) { // literal print line
+ char *dst;
if (!GOT_ADDRESS) { // no addr given- use defaults
q = begin_line(dot); // assume .,. for the range
r = end_line(dot);
}
- go_bottom_and_clear_to_eol();
- puts("\r");
- for (; q <= r; q++) {
+ have_status_msg = 1;
+ dst = status_buffer;
+#define MAXPRINT (sizeof(ESC_BOLD_TEXT "^?" ESC_NORM_TEXT) + 1)
+ while (q <= r && dst < status_buffer + STATUS_BUFFER_LEN - MAXPRINT) {
char c;
int c_is_no_print;
- c = *q;
+ c = *q++;
+ if (c == '\n') {
+ *dst++ = '$';
+ break;
+ }
c_is_no_print = (c & 0x80) && !Isprint(c);
if (c_is_no_print) {
- c = '.';
- standout_start();
+//TODO: print fewer ESC if more than one ctrl char
+ dst = stpcpy(dst, ESC_BOLD_TEXT);
+ *dst++ = '.';
+ dst = stpcpy(dst, ESC_NORM_TEXT);
+ continue;
}
- if (c == '\n') {
- write1("$\r");
- } else if (c < ' ' || c == 127) {
- bb_putchar('^');
+ if (c < ' ' || c == 127) {
+ *dst++ = '^';
if (c == 127)
c = '?';
else
c += '@';
}
- bb_putchar(c);
- if (c_is_no_print)
- standout_end();
+ *dst++ = c;
}
- Hit_Return();
+ *dst = '\0';
} else if (strncmp(cmd, "quit", cmdlen) == 0 // quit
|| strncmp(cmd, "next", cmdlen) == 0 // edit next file
|| strncmp(cmd, "prev", cmdlen) == 0 // edit previous file
@@ -3156,7 +3158,6 @@ static void colon(char *buf)
# if ENABLE_FEATURE_VI_SETOPTS
char *argp, *argn, oldch;
# endif
- // only blank is regarded as args delimiter. What about tab '\t'?
if (!args[0] || strcmp(args, "all") == 0) {
// print out values of all options
# if ENABLE_FEATURE_VI_SETOPTS
@@ -3402,13 +3403,12 @@ static void colon(char *buf)
// are there other files to edit?
int n = cmdline_filecnt - optind - 1;
if (n > 0) {
- if (useforce) {
- // force end of argv list
- optind = cmdline_filecnt;
- } else {
+ if (!useforce) {
status_line_bold("%u more file(s) to edit", n);
goto ret;
}
+ // force end of argv list
+ optind = cmdline_filecnt;
}
editing = 0;
}
@@ -3431,9 +3431,7 @@ static void colon(char *buf)
not_implemented(cmd);
}
ret:
-# if ENABLE_FEATURE_VI_COLON_EXPAND
- free(exp);
-# endif
+ IF_FEATURE_VI_COLON_EXPAND(free(exp);)
dot = bound_dot(dot); // make sure "dot" is valid
return;
# if ENABLE_FEATURE_VI_SEARCH
More information about the busybox-cvs
mailing list