aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/normal.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/normal.c')
-rw-r--r--src/nvim/normal.c80
1 files changed, 46 insertions, 34 deletions
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 9646b83106..3b1f0bf73c 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -2349,13 +2349,15 @@ bool find_decl(char *ptr, size_t len, bool locally, bool thisblock, int flags_ar
bool incll;
int searchflags = flags_arg;
- size_t patlen = len + 7;
- char *pat = xmalloc(patlen);
+ size_t patsize = len + 7;
+ char *pat = xmalloc(patsize);
// Put "\V" before the pattern to avoid that the special meaning of "."
// and "~" causes trouble.
- assert(patlen <= INT_MAX);
- snprintf(pat, patlen, vim_iswordp(ptr) ? "\\V\\<%.*s\\>" : "\\V%.*s", (int)len, ptr);
+ assert(patsize <= INT_MAX);
+ size_t patlen = (size_t)snprintf(pat, patsize,
+ vim_iswordp(ptr) ? "\\V\\<%.*s\\>" : "\\V%.*s",
+ (int)len, ptr);
pos_T old_pos = curwin->w_cursor;
bool save_p_ws = p_ws;
bool save_p_scs = p_scs;
@@ -2382,7 +2384,7 @@ bool find_decl(char *ptr, size_t len, bool locally, bool thisblock, int flags_ar
clearpos(&found_pos);
while (true) {
t = searchit(curwin, curbuf, &curwin->w_cursor, NULL, FORWARD,
- pat, 1, searchflags, RE_LAST, NULL);
+ pat, patlen, 1, searchflags, RE_LAST, NULL);
if (curwin->w_cursor.lnum >= old_pos.lnum) {
t = false; // match after start is failure too
}
@@ -3296,21 +3298,22 @@ void do_nv_ident(int c1, int c2)
/// 'K' normal-mode command. Get the command to lookup the keyword under the
/// cursor.
static size_t nv_K_getcmd(cmdarg_T *cap, char *kp, bool kp_help, bool kp_ex, char **ptr_arg,
- size_t n, char *buf, size_t buf_size)
+ size_t n, char *buf, size_t bufsize, size_t *buflen)
{
if (kp_help) {
// in the help buffer
STRCPY(buf, "he! ");
+ *buflen = STRLEN_LITERAL("he! ");
return n;
}
if (kp_ex) {
+ *buflen = 0;
// 'keywordprg' is an ex command
if (cap->count0 != 0) { // Send the count to the ex command.
- snprintf(buf, buf_size, "%" PRId64, (int64_t)(cap->count0));
+ *buflen = (size_t)snprintf(buf, bufsize, "%" PRId64, (int64_t)(cap->count0));
}
- STRCAT(buf, kp);
- STRCAT(buf, " ");
+ *buflen += (size_t)snprintf(buf + *buflen, bufsize - *buflen, "%s ", kp);
return n;
}
@@ -3335,21 +3338,19 @@ static size_t nv_K_getcmd(cmdarg_T *cap, char *kp, bool kp_help, bool kp_ex, cha
bool isman = (strcmp(kp, "man") == 0);
bool isman_s = (strcmp(kp, "man -s") == 0);
if (cap->count0 != 0 && !(isman || isman_s)) {
- snprintf(buf, buf_size, ".,.+%" PRId64, (int64_t)(cap->count0 - 1));
+ *buflen = (size_t)snprintf(buf, bufsize, ".,.+%" PRId64, (int64_t)(cap->count0 - 1));
}
do_cmdline_cmd("tabnew");
- STRCAT(buf, "terminal ");
+ *buflen += (size_t)snprintf(buf + *buflen, bufsize - *buflen, "terminal ");
if (cap->count0 == 0 && isman_s) {
- STRCAT(buf, "man");
+ *buflen += (size_t)snprintf(buf + *buflen, bufsize - *buflen, "man ");
} else {
- STRCAT(buf, kp);
+ *buflen += (size_t)snprintf(buf + *buflen, bufsize - *buflen, "%s ", kp);
}
- STRCAT(buf, " ");
if (cap->count0 != 0 && (isman || isman_s)) {
- snprintf(buf + strlen(buf), buf_size - strlen(buf), "%" PRId64,
- (int64_t)cap->count0);
- STRCAT(buf, " ");
+ *buflen += (size_t)snprintf(buf + *buflen, bufsize - *buflen,
+ "%" PRId64 " ", (int64_t)cap->count0);
}
*ptr_arg = ptr;
@@ -3412,9 +3413,10 @@ static void nv_ident(cmdarg_T *cap)
return;
}
bool kp_ex = (*kp == ':'); // 'keywordprg' is an ex command
- size_t buf_size = n * 2 + 30 + strlen(kp);
- char *buf = xmalloc(buf_size);
+ size_t bufsize = n * 2 + 30 + strlen(kp);
+ char *buf = xmalloc(bufsize);
buf[0] = NUL;
+ size_t buflen = 0;
switch (cmdchar) {
case '*':
@@ -3428,12 +3430,13 @@ static void nv_ident(cmdarg_T *cap)
if (!g_cmd && vim_iswordp(ptr)) {
STRCPY(buf, "\\<");
+ buflen = STRLEN_LITERAL("\\<");
}
no_smartcase = true; // don't use 'smartcase' now
break;
case 'K':
- n = nv_K_getcmd(cap, kp, kp_help, kp_ex, &ptr, n, buf, buf_size);
+ n = nv_K_getcmd(cap, kp, kp_help, kp_ex, &ptr, n, buf, bufsize, &buflen);
if (n == 0) {
return;
}
@@ -3442,19 +3445,23 @@ static void nv_ident(cmdarg_T *cap)
case ']':
tag_cmd = true;
STRCPY(buf, "ts ");
+ buflen = STRLEN_LITERAL("ts ");
break;
default:
tag_cmd = true;
if (curbuf->b_help) {
STRCPY(buf, "he! ");
+ buflen = STRLEN_LITERAL("he! ");
} else {
if (g_cmd) {
STRCPY(buf, "tj ");
+ buflen = STRLEN_LITERAL("tj ");
} else if (cap->count0 == 0) {
STRCPY(buf, "ta ");
+ buflen = STRLEN_LITERAL("ta ");
} else {
- snprintf(buf, buf_size, ":%" PRId64 "ta ", (int64_t)cap->count0);
+ buflen = (size_t)snprintf(buf, bufsize, ":%" PRId64 "ta ", (int64_t)cap->count0);
}
}
}
@@ -3470,9 +3477,11 @@ static void nv_ident(cmdarg_T *cap)
p = vim_strsave_shellescape(ptr, true, true);
}
xfree(ptr);
- char *newbuf = xrealloc(buf, strlen(buf) + strlen(p) + 1);
+ size_t plen = strlen(p);
+ char *newbuf = xrealloc(buf, buflen + plen + 1);
buf = newbuf;
- STRCAT(buf, p);
+ STRCPY(buf + buflen, p);
+ buflen += plen;
xfree(p);
} else {
char *aux_ptr;
@@ -3491,12 +3500,13 @@ static void nv_ident(cmdarg_T *cap)
aux_ptr = "\\|\"\n*?[";
}
- p = buf + strlen(buf);
+ p = buf + buflen;
while (n-- > 0) {
// put a backslash before \ and some others
if (vim_strchr(aux_ptr, (uint8_t)(*ptr)) != NULL) {
*p++ = '\\';
}
+
// When current byte is a part of multibyte character, copy all
// bytes of that character.
const size_t len = (size_t)(utfc_ptr2len(ptr) - 1);
@@ -3506,20 +3516,21 @@ static void nv_ident(cmdarg_T *cap)
*p++ = *ptr++;
}
*p = NUL;
+ buflen = (size_t)(p - buf);
}
// Execute the command.
if (cmdchar == '*' || cmdchar == '#') {
- if (!g_cmd
- && vim_iswordp(mb_prevptr(get_cursor_line_ptr(), ptr))) {
- STRCAT(buf, "\\>");
+ if (!g_cmd && vim_iswordp(mb_prevptr(get_cursor_line_ptr(), ptr))) {
+ STRCPY(buf + buflen, "\\>");
+ buflen += STRLEN_LITERAL("\\>");
}
// put pattern in search history
init_history();
- add_to_history(HIST_SEARCH, buf, true, NUL);
+ add_to_history(HIST_SEARCH, buf, buflen, true, NUL);
- normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0, NULL);
+ normal_search(cap, cmdchar == '*' ? '/' : '?', buf, buflen, 0, NULL);
} else {
g_tag_at_cursor = true;
do_cmdline_cmd(buf);
@@ -3940,7 +3951,7 @@ static void nv_search(cmdarg_T *cap)
return;
}
- normal_search(cap, cap->cmdchar, cap->searchbuf,
+ normal_search(cap, cap->cmdchar, cap->searchbuf, strlen(cap->searchbuf),
(cap->arg || !equalpos(save_cursor, curwin->w_cursor))
? 0 : SEARCH_MARK, NULL);
}
@@ -3951,14 +3962,14 @@ static void nv_next(cmdarg_T *cap)
{
pos_T old = curwin->w_cursor;
int wrapped = false;
- int i = normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg, &wrapped);
+ int i = normal_search(cap, 0, NULL, 0, SEARCH_MARK | cap->arg, &wrapped);
if (i == 1 && !wrapped && equalpos(old, curwin->w_cursor)) {
// Avoid getting stuck on the current cursor position, which can happen when
// an offset is given and the cursor is on the last char in the buffer:
// Repeat with count + 1.
cap->count1 += 1;
- normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg, NULL);
+ normal_search(cap, 0, NULL, 0, SEARCH_MARK | cap->arg, NULL);
cap->count1 -= 1;
}
}
@@ -3969,7 +3980,7 @@ static void nv_next(cmdarg_T *cap)
/// @param opt extra flags for do_search()
///
/// @return 0 for failure, 1 for found, 2 for found and line offset added.
-static int normal_search(cmdarg_T *cap, int dir, char *pat, int opt, int *wrapped)
+static int normal_search(cmdarg_T *cap, int dir, char *pat, size_t patlen, int opt, int *wrapped)
{
searchit_arg_T sia;
@@ -3979,7 +3990,7 @@ static int normal_search(cmdarg_T *cap, int dir, char *pat, int opt, int *wrappe
curwin->w_set_curswant = true;
CLEAR_FIELD(sia);
- int i = do_search(cap->oap, dir, dir, pat, cap->count1,
+ int i = do_search(cap->oap, dir, dir, pat, patlen, cap->count1,
opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, &sia);
if (wrapped != NULL) {
*wrapped = sia.sa_wrapped;
@@ -3999,6 +4010,7 @@ static int normal_search(cmdarg_T *cap, int dir, char *pat, int opt, int *wrappe
// "/$" will put the cursor after the end of the line, may need to
// correct that here
check_cursor(curwin);
+
return i;
}