mirror of
https://github.com/neovim/neovim.git
synced 2024-09-17 20:58:20 -04:00
vim-patch:9.1.0426: too many strlen() calls in search.c
Problem: too many strlen() calls in search.c
Solution: refactor code and remove more strlen() calls,
use explicit variable to remember strlen
(John Marriott)
closes: vim/vim#14796
8c85a2a49a
Co-authored-by: John Marriott <basilisk@internode.on.net>
This commit is contained in:
parent
879d17ea8d
commit
b86381f425
@ -294,7 +294,7 @@ static int last_maptick = -1; // last seen maptick
|
||||
/// @param histype may be one of the HIST_ values.
|
||||
/// @param in_map consider maptick when inside a mapping
|
||||
/// @param sep separator character used (search hist)
|
||||
void add_to_history(int histype, const char *new_entry, int in_map, int sep)
|
||||
void add_to_history(int histype, const char *new_entry, size_t new_entrylen, bool in_map, int sep)
|
||||
{
|
||||
histentry_T *hisptr;
|
||||
|
||||
@ -334,11 +334,10 @@ void add_to_history(int histype, const char *new_entry, int in_map, int sep)
|
||||
hist_free_entry(hisptr);
|
||||
|
||||
// Store the separator after the NUL of the string.
|
||||
size_t len = strlen(new_entry);
|
||||
hisptr->hisstr = xstrnsave(new_entry, len + 2);
|
||||
hisptr->hisstr = xstrnsave(new_entry, new_entrylen + 2);
|
||||
hisptr->timestamp = os_time();
|
||||
hisptr->additional_elements = NULL;
|
||||
hisptr->hisstr[len + 1] = (char)sep;
|
||||
hisptr->hisstr[new_entrylen + 1] = (char)sep;
|
||||
|
||||
hisptr->hisnum = ++hisnum[histype];
|
||||
if (histype == HIST_SEARCH && in_map) {
|
||||
@ -536,7 +535,7 @@ void f_histadd(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
}
|
||||
|
||||
init_history();
|
||||
add_to_history(histype, str, false, NUL);
|
||||
add_to_history(histype, str, strlen(str), false, NUL);
|
||||
rettv->vval.v_number = true;
|
||||
}
|
||||
|
||||
|
@ -7076,12 +7076,13 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
|
||||
.sa_tm = &tm,
|
||||
};
|
||||
|
||||
const size_t patlen = strlen(pat);
|
||||
int subpatnum;
|
||||
|
||||
// Repeat until {skip} returns false.
|
||||
while (true) {
|
||||
subpatnum
|
||||
= searchit(curwin, curbuf, &pos, NULL, dir, (char *)pat, 1, options, RE_SEARCH, &sia);
|
||||
subpatnum = searchit(curwin, curbuf, &pos, NULL, dir, (char *)pat, patlen, 1,
|
||||
options, RE_SEARCH, &sia);
|
||||
// finding the first match again means there is no match where {skip}
|
||||
// evaluates to zero.
|
||||
if (firstpos.lnum != 0 && equalpos(pos, firstpos)) {
|
||||
@ -7636,16 +7637,20 @@ int do_searchpair(const char *spat, const char *mpat, const char *epat, int dir,
|
||||
|
||||
// Make two search patterns: start/end (pat2, for in nested pairs) and
|
||||
// start/middle/end (pat3, for the top pair).
|
||||
const size_t pat2_len = strlen(spat) + strlen(epat) + 17;
|
||||
char *pat2 = xmalloc(pat2_len);
|
||||
const size_t pat3_len = strlen(spat) + strlen(mpat) + strlen(epat) + 25;
|
||||
char *pat3 = xmalloc(pat3_len);
|
||||
snprintf(pat2, pat2_len, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
|
||||
const size_t spatlen = strlen(spat);
|
||||
const size_t epatlen = strlen(epat);
|
||||
const size_t pat2size = spatlen + epatlen + 17;
|
||||
char *pat2 = xmalloc(pat2size);
|
||||
const size_t pat3size = spatlen + strlen(mpat) + epatlen + 25;
|
||||
char *pat3 = xmalloc(pat3size);
|
||||
int pat2len = snprintf(pat2, pat2size, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
|
||||
int pat3len;
|
||||
if (*mpat == NUL) {
|
||||
STRCPY(pat3, pat2);
|
||||
pat3len = pat2len;
|
||||
} else {
|
||||
snprintf(pat3, pat3_len,
|
||||
"\\m\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat, mpat);
|
||||
pat3len = snprintf(pat3, pat3size,
|
||||
"\\m\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat, mpat);
|
||||
}
|
||||
if (flags & SP_START) {
|
||||
options |= SEARCH_START;
|
||||
@ -7662,13 +7667,15 @@ int do_searchpair(const char *spat, const char *mpat, const char *epat, int dir,
|
||||
pos_T foundpos;
|
||||
clearpos(&foundpos);
|
||||
char *pat = pat3;
|
||||
assert(pat3len >= 0);
|
||||
size_t patlen = (size_t)pat3len;
|
||||
while (true) {
|
||||
searchit_arg_T sia = {
|
||||
.sa_stop_lnum = lnum_stop,
|
||||
.sa_tm = &tm,
|
||||
};
|
||||
|
||||
int n = searchit(curwin, curbuf, &pos, NULL, dir, pat, 1,
|
||||
int n = searchit(curwin, curbuf, &pos, NULL, dir, pat, patlen, 1,
|
||||
options, RE_SEARCH, &sia);
|
||||
if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) {
|
||||
// didn't find it or found the first match again: FAIL
|
||||
|
@ -3099,8 +3099,9 @@ void sub_set_replacement(SubReplacementString sub)
|
||||
/// @param[in] save Save pattern to options, history
|
||||
///
|
||||
/// @returns true if :substitute can be replaced with a join command
|
||||
static bool sub_joining_lines(exarg_T *eap, char *pat, const char *sub, const char *cmd, bool save)
|
||||
FUNC_ATTR_NONNULL_ARG(1, 3, 4)
|
||||
static bool sub_joining_lines(exarg_T *eap, char *pat, size_t patlen, const char *sub,
|
||||
const char *cmd, bool save)
|
||||
FUNC_ATTR_NONNULL_ARG(1, 4, 5)
|
||||
{
|
||||
// TODO(vim): find a generic solution to make line-joining operations more
|
||||
// efficient, avoid allocating a string that grows in size.
|
||||
@ -3138,10 +3139,10 @@ static bool sub_joining_lines(exarg_T *eap, char *pat, const char *sub, const ch
|
||||
|
||||
if (save) {
|
||||
if ((cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0) {
|
||||
save_re_pat(RE_SUBST, pat, magic_isset());
|
||||
save_re_pat(RE_SUBST, pat, patlen, magic_isset());
|
||||
}
|
||||
// put pattern in history
|
||||
add_to_history(HIST_SEARCH, pat, true, NUL);
|
||||
add_to_history(HIST_SEARCH, pat, patlen, true, NUL);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -3332,6 +3333,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
||||
};
|
||||
char *pat = NULL;
|
||||
char *sub = NULL; // init for GCC
|
||||
size_t patlen = 0;
|
||||
int delimiter;
|
||||
bool has_second_delim = false;
|
||||
int sublen;
|
||||
@ -3383,12 +3385,14 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
||||
which_pat = RE_SEARCH; // use last '/' pattern
|
||||
}
|
||||
pat = ""; // empty search pattern
|
||||
patlen = 0;
|
||||
delimiter = (uint8_t)(*cmd++); // remember delimiter character
|
||||
has_second_delim = true;
|
||||
} else { // find the end of the regexp
|
||||
which_pat = RE_LAST; // use last used regexp
|
||||
delimiter = (uint8_t)(*cmd++); // remember delimiter character
|
||||
pat = cmd; // remember start of search pat
|
||||
patlen = strlen(pat);
|
||||
cmd = skip_regexp_ex(cmd, delimiter, magic_isset(), &eap->arg, NULL, NULL);
|
||||
if (cmd[0] == delimiter) { // end delimiter found
|
||||
*cmd++ = NUL; // replace it with a NUL
|
||||
@ -3415,6 +3419,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
||||
return 0;
|
||||
}
|
||||
pat = NULL; // search_regcomp() will use previous pattern
|
||||
patlen = 0;
|
||||
sub = xstrdup(old_sub.sub);
|
||||
|
||||
// Vi compatibility quirk: repeating with ":s" keeps the cursor in the
|
||||
@ -3422,7 +3427,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
||||
endcolumn = (curwin->w_curswant == MAXCOL);
|
||||
}
|
||||
|
||||
if (sub != NULL && sub_joining_lines(eap, pat, sub, cmd, cmdpreview_ns <= 0)) {
|
||||
if (sub != NULL && sub_joining_lines(eap, pat, patlen, sub, cmd, cmdpreview_ns <= 0)) {
|
||||
xfree(sub);
|
||||
return 0;
|
||||
}
|
||||
@ -3477,7 +3482,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (search_regcomp(pat, NULL, RE_SUBST, which_pat,
|
||||
if (search_regcomp(pat, patlen, NULL, RE_SUBST, which_pat,
|
||||
(cmdpreview_ns > 0 ? 0 : SEARCH_HIS), ®match) == FAIL) {
|
||||
if (subflags.do_error) {
|
||||
emsg(_(e_invcmd));
|
||||
@ -4390,6 +4395,7 @@ void ex_global(exarg_T *eap)
|
||||
|
||||
char delim; // delimiter, normally '/'
|
||||
char *pat;
|
||||
size_t patlen;
|
||||
regmmatch_T regmatch;
|
||||
|
||||
// When nesting the command works on one line. This allows for
|
||||
@ -4425,6 +4431,7 @@ void ex_global(exarg_T *eap)
|
||||
}
|
||||
cmd++;
|
||||
pat = "";
|
||||
patlen = 0;
|
||||
} else if (*cmd == NUL) {
|
||||
emsg(_("E148: Regular expression missing from global"));
|
||||
return;
|
||||
@ -4434,6 +4441,7 @@ void ex_global(exarg_T *eap)
|
||||
delim = *cmd; // get the delimiter
|
||||
cmd++; // skip delimiter if there is one
|
||||
pat = cmd; // remember start of pattern
|
||||
patlen = strlen(pat);
|
||||
cmd = skip_regexp_ex(cmd, delim, magic_isset(), &eap->arg, NULL, NULL);
|
||||
if (cmd[0] == delim) { // end delimiter found
|
||||
*cmd++ = NUL; // replace it with a NUL
|
||||
@ -4441,7 +4449,7 @@ void ex_global(exarg_T *eap)
|
||||
}
|
||||
|
||||
char *used_pat;
|
||||
if (search_regcomp(pat, &used_pat, RE_BOTH, which_pat,
|
||||
if (search_regcomp(pat, patlen, &used_pat, RE_BOTH, which_pat,
|
||||
SEARCH_HIS, ®match) == FAIL) {
|
||||
emsg(_(e_invcmd));
|
||||
return;
|
||||
|
@ -3506,7 +3506,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, bool
|
||||
}
|
||||
searchcmdlen = 0;
|
||||
flags = silent ? 0 : SEARCH_HIS | SEARCH_MSG;
|
||||
if (!do_search(NULL, c, c, cmd, 1, flags, NULL)) {
|
||||
if (!do_search(NULL, c, c, cmd, strlen(cmd), 1, flags, NULL)) {
|
||||
curwin->w_cursor = pos;
|
||||
cmd = NULL;
|
||||
goto error;
|
||||
@ -3543,7 +3543,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, bool
|
||||
pos.coladd = 0;
|
||||
if (searchit(curwin, curbuf, &pos, NULL,
|
||||
*cmd == '?' ? BACKWARD : FORWARD,
|
||||
"", 1, SEARCH_MSG, i, NULL) != FAIL) {
|
||||
"", 0, 1, SEARCH_MSG, i, NULL) != FAIL) {
|
||||
lnum = pos.lnum;
|
||||
} else {
|
||||
cmd = NULL;
|
||||
|
@ -470,7 +470,7 @@ static void may_do_incsearch_highlighting(int firstc, int count, incsearch_state
|
||||
.sa_tm = &tm,
|
||||
};
|
||||
found = do_search(NULL, firstc == ':' ? '/' : firstc, search_delim,
|
||||
ccline.cmdbuff + skiplen, count,
|
||||
ccline.cmdbuff + skiplen, (size_t)patlen, count,
|
||||
search_flags, &sia);
|
||||
ccline.cmdbuff[skiplen + patlen] = next_char;
|
||||
emsg_off--;
|
||||
@ -884,11 +884,12 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
|
||||
&& ccline.cmdlen
|
||||
&& s->firstc != NUL
|
||||
&& (s->some_key_typed || s->histype == HIST_SEARCH)) {
|
||||
add_to_history(s->histype, ccline.cmdbuff, true,
|
||||
size_t cmdbufflen = strlen(ccline.cmdbuff);
|
||||
add_to_history(s->histype, ccline.cmdbuff, cmdbufflen, true,
|
||||
s->histype == HIST_SEARCH ? s->firstc : NUL);
|
||||
if (s->firstc == ':') {
|
||||
xfree(new_last_cmdline);
|
||||
new_last_cmdline = xstrdup(ccline.cmdbuff);
|
||||
new_last_cmdline = xstrnsave(ccline.cmdbuff, cmdbufflen);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1451,7 +1452,7 @@ static int may_do_command_line_next_incsearch(int firstc, int count, incsearch_s
|
||||
pat[patlen] = NUL;
|
||||
int found = searchit(curwin, curbuf, &t, NULL,
|
||||
next_match ? FORWARD : BACKWARD,
|
||||
pat, count, search_flags,
|
||||
pat, (size_t)patlen, count, search_flags,
|
||||
RE_SEARCH, NULL);
|
||||
emsg_off--;
|
||||
pat[patlen] = save;
|
||||
|
@ -253,6 +253,7 @@ static int ctrl_x_mode = CTRL_X_NORMAL;
|
||||
|
||||
static int compl_matches = 0; ///< number of completion matches
|
||||
static char *compl_pattern = NULL;
|
||||
static size_t compl_patternlen = 0;
|
||||
static Direction compl_direction = FORWARD;
|
||||
static Direction compl_shows_dir = FORWARD;
|
||||
static int compl_pending = 0; ///< > 1 for postponed CTRL-N
|
||||
@ -1583,6 +1584,7 @@ static char *find_line_end(char *ptr)
|
||||
static void ins_compl_free(void)
|
||||
{
|
||||
XFREE_CLEAR(compl_pattern);
|
||||
compl_patternlen = 0;
|
||||
XFREE_CLEAR(compl_leader);
|
||||
|
||||
if (compl_first_match == NULL) {
|
||||
@ -1617,6 +1619,7 @@ void ins_compl_clear(void)
|
||||
compl_started = false;
|
||||
compl_matches = 0;
|
||||
XFREE_CLEAR(compl_pattern);
|
||||
compl_patternlen = 0;
|
||||
XFREE_CLEAR(compl_leader);
|
||||
edit_submode_extra = NULL;
|
||||
kv_destroy(compl_orig_extmarks);
|
||||
@ -2991,7 +2994,7 @@ done:
|
||||
static void get_next_include_file_completion(int compl_type)
|
||||
{
|
||||
find_pattern_in_path(compl_pattern, compl_direction,
|
||||
strlen(compl_pattern), false, false,
|
||||
compl_patternlen, false, false,
|
||||
((compl_type == CTRL_X_PATH_DEFINES
|
||||
&& !(compl_cont_status & CONT_SOL))
|
||||
? FIND_DEFINE : FIND_ANY),
|
||||
@ -3074,8 +3077,7 @@ static void get_next_cmdline_completion(void)
|
||||
char **matches;
|
||||
int num_matches;
|
||||
if (expand_cmdline(&compl_xp, compl_pattern,
|
||||
(int)strlen(compl_pattern),
|
||||
&num_matches, &matches) == EXPAND_OK) {
|
||||
(int)compl_patternlen, &num_matches, &matches) == EXPAND_OK) {
|
||||
ins_compl_add_matches(num_matches, matches, false);
|
||||
}
|
||||
}
|
||||
@ -3217,8 +3219,8 @@ static int get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_
|
||||
compl_direction, compl_pattern);
|
||||
} else {
|
||||
found_new_match = searchit(NULL, st->ins_buf, st->cur_match_pos,
|
||||
NULL, compl_direction, compl_pattern, 1,
|
||||
SEARCH_KEEP + SEARCH_NFMSG, RE_LAST, NULL);
|
||||
NULL, compl_direction, compl_pattern, compl_patternlen,
|
||||
1, SEARCH_KEEP + SEARCH_NFMSG, RE_LAST, NULL);
|
||||
}
|
||||
msg_silent--;
|
||||
if (!compl_started || st->set_match_pos) {
|
||||
@ -3902,7 +3904,8 @@ static bool ins_compl_use_match(int c)
|
||||
|
||||
/// Get the pattern, column and length for normal completion (CTRL-N CTRL-P
|
||||
/// completion)
|
||||
/// Sets the global variables: compl_col, compl_length and compl_pattern.
|
||||
/// Sets the global variables: compl_col, compl_length, compl_pattern and
|
||||
/// compl_patternlen.
|
||||
/// Uses the global variables: compl_cont_status and ctrl_x_mode
|
||||
static int get_normal_compl_info(char *line, int startcol, colnr_T curs_col)
|
||||
{
|
||||
@ -3919,21 +3922,23 @@ static int get_normal_compl_info(char *line, int startcol, colnr_T curs_col)
|
||||
}
|
||||
} else if (compl_status_adding()) {
|
||||
char *prefix = "\\<";
|
||||
size_t prefixlen = STRLEN_LITERAL("\\<");
|
||||
|
||||
// we need up to 2 extra chars for the prefix
|
||||
compl_pattern = xmalloc(quote_meta(NULL, line + compl_col, compl_length) + 2);
|
||||
compl_pattern = xmalloc(quote_meta(NULL, line + compl_col,
|
||||
compl_length) + prefixlen);
|
||||
if (!vim_iswordp(line + compl_col)
|
||||
|| (compl_col > 0
|
||||
&& (vim_iswordp(mb_prevptr(line, line + compl_col))))) {
|
||||
prefix = "";
|
||||
prefixlen = 0;
|
||||
}
|
||||
STRCPY(compl_pattern, prefix);
|
||||
quote_meta(compl_pattern + strlen(prefix),
|
||||
line + compl_col, compl_length);
|
||||
quote_meta(compl_pattern + prefixlen, line + compl_col, compl_length);
|
||||
} else if (--startcol < 0
|
||||
|| !vim_iswordp(mb_prevptr(line, line + startcol + 1))) {
|
||||
// Match any word of at least two chars
|
||||
compl_pattern = xstrdup("\\<\\k\\k");
|
||||
compl_pattern = xstrnsave(S_LEN("\\<\\k\\k"));
|
||||
compl_col += curs_col;
|
||||
compl_length = 0;
|
||||
} else {
|
||||
@ -3965,6 +3970,8 @@ static int get_normal_compl_info(char *line, int startcol, colnr_T curs_col)
|
||||
}
|
||||
}
|
||||
|
||||
compl_patternlen = strlen(compl_pattern);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -3984,6 +3991,8 @@ static int get_wholeline_compl_info(char *line, colnr_T curs_col)
|
||||
compl_pattern = xstrnsave(line + compl_col, (size_t)compl_length);
|
||||
}
|
||||
|
||||
compl_patternlen = strlen(compl_pattern);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -4009,6 +4018,7 @@ static int get_filename_compl_info(char *line, int startcol, colnr_T curs_col)
|
||||
compl_col += startcol;
|
||||
compl_length = (int)curs_col - startcol;
|
||||
compl_pattern = addstar(line + compl_col, (size_t)compl_length, EXPAND_FILES);
|
||||
compl_patternlen = strlen(compl_pattern);
|
||||
|
||||
return OK;
|
||||
}
|
||||
@ -4018,7 +4028,8 @@ static int get_filename_compl_info(char *line, int startcol, colnr_T curs_col)
|
||||
static int get_cmdline_compl_info(char *line, colnr_T curs_col)
|
||||
{
|
||||
compl_pattern = xstrnsave(line, (size_t)curs_col);
|
||||
set_cmd_context(&compl_xp, compl_pattern, (int)strlen(compl_pattern), curs_col, false);
|
||||
compl_patternlen = (size_t)curs_col;
|
||||
set_cmd_context(&compl_xp, compl_pattern, (int)compl_patternlen, curs_col, false);
|
||||
if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL
|
||||
|| compl_xp.xp_context == EXPAND_NOTHING) {
|
||||
// No completion possible, use an empty pattern to get a
|
||||
@ -4104,6 +4115,7 @@ static int get_userdefined_compl_info(colnr_T curs_col)
|
||||
char *line = ml_get(curwin->w_cursor.lnum);
|
||||
compl_length = curs_col - compl_col;
|
||||
compl_pattern = xstrnsave(line + compl_col, (size_t)compl_length);
|
||||
compl_patternlen = (size_t)compl_length;
|
||||
|
||||
return OK;
|
||||
}
|
||||
@ -4129,6 +4141,7 @@ static int get_spell_compl_info(int startcol, colnr_T curs_col)
|
||||
// Need to obtain "line" again, it may have become invalid.
|
||||
char *line = ml_get(curwin->w_cursor.lnum);
|
||||
compl_pattern = xstrnsave(line + compl_col, (size_t)compl_length);
|
||||
compl_patternlen = (size_t)compl_length;
|
||||
|
||||
return OK;
|
||||
}
|
||||
@ -4324,6 +4337,7 @@ static int ins_compl_start(void)
|
||||
if (ins_compl_add(compl_orig_text, -1, NULL, NULL, false, NULL, 0,
|
||||
flags, false) != OK) {
|
||||
XFREE_CLEAR(compl_pattern);
|
||||
compl_patternlen = 0;
|
||||
XFREE_CLEAR(compl_orig_text);
|
||||
kv_destroy(compl_orig_extmarks);
|
||||
return FAIL;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -2902,7 +2902,7 @@ static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char qf_viscol, char
|
||||
// Move the cursor to the first line in the buffer
|
||||
pos_T save_cursor = curwin->w_cursor;
|
||||
curwin->w_cursor.lnum = 0;
|
||||
if (!do_search(NULL, '/', '/', qf_pattern, 1, SEARCH_KEEP, NULL)) {
|
||||
if (!do_search(NULL, '/', '/', qf_pattern, strlen(qf_pattern), 1, SEARCH_KEEP, NULL)) {
|
||||
curwin->w_cursor = save_cursor;
|
||||
}
|
||||
}
|
||||
|
@ -99,9 +99,9 @@ static const char e_search_hit_bottom_without_match_for_str[]
|
||||
|
||||
static SearchPattern spats[2] = {
|
||||
// Last used search pattern
|
||||
[0] = { NULL, true, false, 0, { '/', false, false, 0 }, NULL },
|
||||
[0] = { NULL, 0, true, false, 0, { '/', false, false, 0 }, NULL },
|
||||
// Last used substitute pattern
|
||||
[1] = { NULL, true, false, 0, { '/', false, false, 0 }, NULL }
|
||||
[1] = { NULL, 0, true, false, 0, { '/', false, false, 0 }, NULL }
|
||||
};
|
||||
|
||||
static int last_idx = 0; // index in spats[] for RE_LAST
|
||||
@ -113,13 +113,15 @@ static char lastc_bytes[MB_MAXBYTES + 1];
|
||||
static int lastc_bytelen = 1; // >1 for multi-byte char
|
||||
|
||||
// copy of spats[], for keeping the search patterns while executing autocmds
|
||||
static SearchPattern saved_spats[2];
|
||||
static SearchPattern saved_spats[ARRAY_SIZE(spats)];
|
||||
static char *saved_mr_pattern = NULL;
|
||||
static size_t saved_mr_patternlen = 0;
|
||||
static int saved_spats_last_idx = 0;
|
||||
static bool saved_spats_no_hlsearch = false;
|
||||
|
||||
// allocated copy of pattern used by search_regcomp()
|
||||
static char *mr_pattern = NULL;
|
||||
static size_t mr_patternlen = 0;
|
||||
|
||||
// Type used by find_pattern_in_path() to remember which included files have
|
||||
// been searched already.
|
||||
@ -144,8 +146,8 @@ typedef struct {
|
||||
/// @param regmatch return: pattern and ignore-case flag
|
||||
///
|
||||
/// @return FAIL if failed, OK otherwise.
|
||||
int search_regcomp(char *pat, char **used_pat, int pat_save, int pat_use, int options,
|
||||
regmmatch_T *regmatch)
|
||||
int search_regcomp(char *pat, size_t patlen, char **used_pat, int pat_save, int pat_use,
|
||||
int options, regmmatch_T *regmatch)
|
||||
{
|
||||
rc_did_emsg = false;
|
||||
int magic = magic_isset();
|
||||
@ -168,10 +170,11 @@ int search_regcomp(char *pat, char **used_pat, int pat_save, int pat_use, int op
|
||||
return FAIL;
|
||||
}
|
||||
pat = spats[i].pat;
|
||||
patlen = spats[i].patlen;
|
||||
magic = spats[i].magic;
|
||||
no_smartcase = spats[i].no_scs;
|
||||
} else if (options & SEARCH_HIS) { // put new pattern in history
|
||||
add_to_history(HIST_SEARCH, pat, true, NUL);
|
||||
add_to_history(HIST_SEARCH, pat, patlen, true, NUL);
|
||||
}
|
||||
|
||||
if (used_pat) {
|
||||
@ -182,19 +185,20 @@ int search_regcomp(char *pat, char **used_pat, int pat_save, int pat_use, int op
|
||||
if (curwin->w_p_rl && *curwin->w_p_rlc == 's') {
|
||||
mr_pattern = reverse_text(pat);
|
||||
} else {
|
||||
mr_pattern = xstrdup(pat);
|
||||
mr_pattern = xstrnsave(pat, patlen);
|
||||
}
|
||||
mr_patternlen = patlen;
|
||||
|
||||
// Save the currently used pattern in the appropriate place,
|
||||
// unless the pattern should not be remembered.
|
||||
if (!(options & SEARCH_KEEP) && (cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0) {
|
||||
// search or global command
|
||||
if (pat_save == RE_SEARCH || pat_save == RE_BOTH) {
|
||||
save_re_pat(RE_SEARCH, pat, magic);
|
||||
save_re_pat(RE_SEARCH, pat, patlen, magic);
|
||||
}
|
||||
// substitute or global command
|
||||
if (pat_save == RE_SUBST || pat_save == RE_BOTH) {
|
||||
save_re_pat(RE_SUBST, pat, magic);
|
||||
save_re_pat(RE_SUBST, pat, patlen, magic);
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,14 +217,15 @@ char *get_search_pat(void)
|
||||
return mr_pattern;
|
||||
}
|
||||
|
||||
void save_re_pat(int idx, char *pat, int magic)
|
||||
void save_re_pat(int idx, char *pat, size_t patlen, int magic)
|
||||
{
|
||||
if (spats[idx].pat == pat) {
|
||||
return;
|
||||
}
|
||||
|
||||
free_spat(&spats[idx]);
|
||||
spats[idx].pat = xstrdup(pat);
|
||||
spats[idx].pat = xstrnsave(pat, patlen);
|
||||
spats[idx].patlen = patlen;
|
||||
spats[idx].magic = magic;
|
||||
spats[idx].no_scs = no_smartcase;
|
||||
spats[idx].timestamp = os_time();
|
||||
@ -243,18 +248,19 @@ void save_search_patterns(void)
|
||||
return;
|
||||
}
|
||||
|
||||
saved_spats[0] = spats[0];
|
||||
if (spats[0].pat != NULL) {
|
||||
saved_spats[0].pat = xstrdup(spats[0].pat);
|
||||
}
|
||||
saved_spats[1] = spats[1];
|
||||
if (spats[1].pat != NULL) {
|
||||
saved_spats[1].pat = xstrdup(spats[1].pat);
|
||||
for (size_t i = 0; i < ARRAY_SIZE(spats); i++) {
|
||||
saved_spats[i] = spats[i];
|
||||
if (spats[i].pat != NULL) {
|
||||
saved_spats[i].pat = xstrnsave(spats[i].pat, spats[i].patlen);
|
||||
saved_spats[i].patlen = spats[i].patlen;
|
||||
}
|
||||
}
|
||||
if (mr_pattern == NULL) {
|
||||
saved_mr_pattern = NULL;
|
||||
saved_mr_patternlen = 0;
|
||||
} else {
|
||||
saved_mr_pattern = xstrdup(mr_pattern);
|
||||
saved_mr_pattern = xstrnsave(mr_pattern, mr_patternlen);
|
||||
saved_mr_patternlen = mr_patternlen;
|
||||
}
|
||||
saved_spats_last_idx = last_idx;
|
||||
saved_spats_no_hlsearch = no_hlsearch;
|
||||
@ -266,13 +272,14 @@ void restore_search_patterns(void)
|
||||
return;
|
||||
}
|
||||
|
||||
free_spat(&spats[0]);
|
||||
spats[0] = saved_spats[0];
|
||||
for (size_t i = 0; i < ARRAY_SIZE(spats); i++) {
|
||||
free_spat(&spats[i]);
|
||||
spats[i] = saved_spats[i];
|
||||
}
|
||||
set_vv_searchforward();
|
||||
free_spat(&spats[1]);
|
||||
spats[1] = saved_spats[1];
|
||||
xfree(mr_pattern);
|
||||
mr_pattern = saved_mr_pattern;
|
||||
mr_patternlen = saved_mr_patternlen;
|
||||
last_idx = saved_spats_last_idx;
|
||||
set_no_hlsearch(saved_spats_no_hlsearch);
|
||||
}
|
||||
@ -286,12 +293,13 @@ static inline void free_spat(SearchPattern *const spat)
|
||||
#if defined(EXITFREE)
|
||||
void free_search_patterns(void)
|
||||
{
|
||||
free_spat(&spats[0]);
|
||||
free_spat(&spats[1]);
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(spats); i++) {
|
||||
free_spat(&spats[i]);
|
||||
}
|
||||
CLEAR_FIELD(spats);
|
||||
|
||||
XFREE_CLEAR(mr_pattern);
|
||||
mr_patternlen = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -320,7 +328,8 @@ void save_last_search_pattern(void)
|
||||
|
||||
saved_last_search_spat = spats[RE_SEARCH];
|
||||
if (spats[RE_SEARCH].pat != NULL) {
|
||||
saved_last_search_spat.pat = xstrdup(spats[RE_SEARCH].pat);
|
||||
saved_last_search_spat.pat = xstrnsave(spats[RE_SEARCH].pat, spats[RE_SEARCH].patlen);
|
||||
saved_last_search_spat.patlen = spats[RE_SEARCH].patlen;
|
||||
}
|
||||
saved_last_idx = last_idx;
|
||||
saved_no_hlsearch = no_hlsearch;
|
||||
@ -341,6 +350,7 @@ void restore_last_search_pattern(void)
|
||||
xfree(spats[RE_SEARCH].pat);
|
||||
spats[RE_SEARCH] = saved_last_search_spat;
|
||||
saved_last_search_spat.pat = NULL;
|
||||
saved_last_search_spat.patlen = 0;
|
||||
set_vv_searchforward();
|
||||
last_idx = saved_last_idx;
|
||||
set_no_hlsearch(saved_no_hlsearch);
|
||||
@ -487,8 +497,10 @@ void set_last_search_pat(const char *s, int idx, int magic, bool setlast)
|
||||
// An empty string means that nothing should be matched.
|
||||
if (*s == NUL) {
|
||||
spats[idx].pat = NULL;
|
||||
spats[idx].patlen = 0;
|
||||
} else {
|
||||
spats[idx].pat = xstrdup(s);
|
||||
spats[idx].patlen = strlen(s);
|
||||
spats[idx].pat = xstrnsave(s, spats[idx].patlen);
|
||||
}
|
||||
spats[idx].timestamp = os_time();
|
||||
spats[idx].additional_data = NULL;
|
||||
@ -507,8 +519,10 @@ void set_last_search_pat(const char *s, int idx, int magic, bool setlast)
|
||||
saved_spats[idx] = spats[0];
|
||||
if (spats[idx].pat == NULL) {
|
||||
saved_spats[idx].pat = NULL;
|
||||
saved_spats[idx].patlen = 0;
|
||||
} else {
|
||||
saved_spats[idx].pat = xstrdup(spats[idx].pat);
|
||||
saved_spats[idx].pat = xstrnsave(spats[idx].pat, spats[idx].patlen);
|
||||
saved_spats[idx].patlen = spats[idx].patlen;
|
||||
}
|
||||
saved_spats_last_idx = last_idx;
|
||||
}
|
||||
@ -528,7 +542,7 @@ void last_pat_prog(regmmatch_T *regmatch)
|
||||
return;
|
||||
}
|
||||
emsg_off++; // So it doesn't beep if bad expr
|
||||
search_regcomp("", NULL, 0, last_idx, SEARCH_KEEP, regmatch);
|
||||
search_regcomp("", 0, NULL, 0, last_idx, SEARCH_KEEP, regmatch);
|
||||
emsg_off--;
|
||||
}
|
||||
|
||||
@ -556,7 +570,7 @@ void last_pat_prog(regmmatch_T *regmatch)
|
||||
/// the index of the first matching
|
||||
/// subpattern plus one; one if there was none.
|
||||
int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, char *pat,
|
||||
int count, int options, int pat_use, searchit_arg_T *extra_arg)
|
||||
size_t patlen, int count, int options, int pat_use, searchit_arg_T *extra_arg)
|
||||
{
|
||||
int found;
|
||||
linenr_T lnum; // no init to shut up Apollo cc
|
||||
@ -584,7 +598,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|
||||
timed_out = &extra_arg->sa_timed_out;
|
||||
}
|
||||
|
||||
if (search_regcomp(pat, NULL, RE_SEARCH, pat_use,
|
||||
if (search_regcomp(pat, patlen, NULL, RE_SEARCH, pat_use,
|
||||
(options & (SEARCH_HIS + SEARCH_KEEP)), ®match) == FAIL) {
|
||||
if ((options & SEARCH_MSG) && !rc_did_emsg) {
|
||||
semsg(_("E383: Invalid search string: %s"), mr_pattern);
|
||||
@ -592,6 +606,8 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
const bool search_from_match_end = vim_strchr(p_cpo, CPO_SEARCH) != NULL;
|
||||
|
||||
// find the string
|
||||
do { // loop for count
|
||||
// When not accepting a match at the start position set "extra_col" to a
|
||||
@ -699,7 +715,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|
||||
// If vi-compatible searching, continue at the end
|
||||
// of the match, otherwise continue one position
|
||||
// forward.
|
||||
if (vim_strchr(p_cpo, CPO_SEARCH) != NULL) {
|
||||
if (search_from_match_end) {
|
||||
if (nmatched > 1) {
|
||||
// end is in next line, thus no match in
|
||||
// this line
|
||||
@ -791,7 +807,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|
||||
// If vi-compatible searching, continue at the end
|
||||
// of the match, otherwise continue one position
|
||||
// forward.
|
||||
if (vim_strchr(p_cpo, CPO_SEARCH) != NULL) {
|
||||
if (search_from_match_end) {
|
||||
if (nmatched > 1) {
|
||||
break;
|
||||
}
|
||||
@ -1031,11 +1047,12 @@ static int first_submatch(regmmatch_T *rp)
|
||||
/// @param sia optional arguments or NULL
|
||||
///
|
||||
/// @return 0 for failure, 1 for found, 2 for found and line offset added.
|
||||
int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, int options,
|
||||
searchit_arg_T *sia)
|
||||
int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, size_t patlen, int count,
|
||||
int options, searchit_arg_T *sia)
|
||||
{
|
||||
pos_T pos; // position of the last match
|
||||
char *searchstr;
|
||||
size_t searchstrlen;
|
||||
int retval; // Return value
|
||||
char *p;
|
||||
int64_t c;
|
||||
@ -1043,9 +1060,11 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
||||
char *strcopy = NULL;
|
||||
char *ps;
|
||||
char *msgbuf = NULL;
|
||||
size_t len;
|
||||
size_t msgbuflen = 0;
|
||||
bool has_offset = false;
|
||||
|
||||
searchcmdlen = 0;
|
||||
|
||||
// A line offset is not remembered, this is vi compatible.
|
||||
if (spats[0].off.line && vim_strchr(p_cpo, CPO_LINEOFF) != NULL) {
|
||||
spats[0].off.line = false;
|
||||
@ -1096,19 +1115,23 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
||||
bool show_top_bot_msg = false;
|
||||
|
||||
searchstr = pat;
|
||||
searchstrlen = patlen;
|
||||
|
||||
dircp = NULL;
|
||||
// use previous pattern
|
||||
if (pat == NULL || *pat == NUL || *pat == search_delim) {
|
||||
if (spats[RE_SEARCH].pat == NULL) { // no previous pattern
|
||||
searchstr = spats[RE_SUBST].pat;
|
||||
if (searchstr == NULL) {
|
||||
if (spats[RE_SUBST].pat == NULL) {
|
||||
emsg(_(e_noprevre));
|
||||
retval = 0;
|
||||
goto end_do_search;
|
||||
}
|
||||
searchstr = spats[RE_SUBST].pat;
|
||||
searchstrlen = spats[RE_SUBST].patlen;
|
||||
} else {
|
||||
// make search_regcomp() use spats[RE_SEARCH].pat
|
||||
searchstr = "";
|
||||
searchstrlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1118,12 +1141,16 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
||||
ps = strcopy;
|
||||
p = skip_regexp_ex(pat, search_delim, magic_isset(), &strcopy, NULL, NULL);
|
||||
if (strcopy != ps) {
|
||||
size_t len = strlen(strcopy);
|
||||
// made a copy of "pat" to change "\?" to "?"
|
||||
searchcmdlen += (int)(strlen(pat) - strlen(strcopy));
|
||||
searchcmdlen += (int)(patlen - len);
|
||||
pat = strcopy;
|
||||
patlen = len;
|
||||
searchstr = strcopy;
|
||||
searchstrlen = len;
|
||||
}
|
||||
if (*p == search_delim) {
|
||||
searchstrlen = (size_t)(p - pat);
|
||||
dircp = p; // remember where we put the NUL
|
||||
*p++ = NUL;
|
||||
}
|
||||
@ -1161,12 +1188,13 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
||||
// compute length of search command for get_address()
|
||||
searchcmdlen += (int)(p - pat);
|
||||
|
||||
patlen -= (size_t)(p - pat);
|
||||
pat = p; // put pat after search command
|
||||
}
|
||||
|
||||
bool show_search_stats = false;
|
||||
if ((options & SEARCH_ECHO) && messaging() && !msg_silent
|
||||
&& (!cmd_silent || !shortmess(SHM_SEARCHCOUNT))) {
|
||||
char *trunc;
|
||||
char off_buf[40];
|
||||
size_t off_len = 0;
|
||||
|
||||
@ -1176,56 +1204,59 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
||||
// Get the offset, so we know how long it is.
|
||||
if (!cmd_silent
|
||||
&& (spats[0].off.line || spats[0].off.end || spats[0].off.off)) {
|
||||
p = off_buf;
|
||||
*p++ = (char)dirc;
|
||||
off_buf[off_len++] = (char)dirc;
|
||||
if (spats[0].off.end) {
|
||||
*p++ = 'e';
|
||||
off_buf[off_len++] = 'e';
|
||||
} else if (!spats[0].off.line) {
|
||||
*p++ = 's';
|
||||
off_buf[off_len++] = 's';
|
||||
}
|
||||
if (spats[0].off.off > 0 || spats[0].off.line) {
|
||||
*p++ = '+';
|
||||
off_buf[off_len++] = '+';
|
||||
}
|
||||
*p = NUL;
|
||||
off_buf[off_len] = NUL;
|
||||
if (spats[0].off.off != 0 || spats[0].off.line) {
|
||||
snprintf(p, sizeof(off_buf) - 1 - (size_t)(p - off_buf),
|
||||
"%" PRId64, spats[0].off.off);
|
||||
off_len += (size_t)snprintf(off_buf + off_len, sizeof(off_buf) - off_len,
|
||||
"%" PRId64, spats[0].off.off);
|
||||
}
|
||||
off_len = strlen(off_buf);
|
||||
}
|
||||
|
||||
size_t plen;
|
||||
if (*searchstr == NUL) {
|
||||
p = spats[0].pat;
|
||||
plen = spats[0].patlen;
|
||||
} else {
|
||||
p = searchstr;
|
||||
plen = searchstrlen;
|
||||
}
|
||||
|
||||
size_t msgbufsize;
|
||||
if (!shortmess(SHM_SEARCHCOUNT) || cmd_silent) {
|
||||
// Reserve enough space for the search pattern + offset +
|
||||
// search stat. Use all the space available, so that the
|
||||
// search state is right aligned. If there is not enough space
|
||||
// msg_strtrunc() will shorten in the middle.
|
||||
if (ui_has(kUIMessages)) {
|
||||
len = 0; // adjusted below
|
||||
msgbufsize = 0; // adjusted below
|
||||
} else if (msg_scrolled != 0 && !cmd_silent) {
|
||||
// Use all the columns.
|
||||
len = (size_t)((Rows - msg_row) * Columns - 1);
|
||||
msgbufsize = (size_t)((Rows - msg_row) * Columns - 1);
|
||||
} else {
|
||||
// Use up to 'showcmd' column.
|
||||
len = (size_t)((Rows - msg_row - 1) * Columns + sc_col - 1);
|
||||
msgbufsize = (size_t)((Rows - msg_row - 1) * Columns + sc_col - 1);
|
||||
}
|
||||
if (len < strlen(p) + off_len + SEARCH_STAT_BUF_LEN + 3) {
|
||||
len = strlen(p) + off_len + SEARCH_STAT_BUF_LEN + 3;
|
||||
if (msgbufsize < plen + off_len + SEARCH_STAT_BUF_LEN + 3) {
|
||||
msgbufsize = plen + off_len + SEARCH_STAT_BUF_LEN + 3;
|
||||
}
|
||||
} else {
|
||||
// Reserve enough space for the search pattern + offset.
|
||||
len = strlen(p) + off_len + 3;
|
||||
msgbufsize = plen + off_len + 3;
|
||||
}
|
||||
|
||||
xfree(msgbuf);
|
||||
msgbuf = xmalloc(len);
|
||||
memset(msgbuf, ' ', len);
|
||||
msgbuf[len - 1] = NUL;
|
||||
msgbuf = xmalloc(msgbufsize);
|
||||
memset(msgbuf, ' ', msgbufsize);
|
||||
msgbuflen = msgbufsize - 1;
|
||||
msgbuf[msgbuflen] = NUL;
|
||||
|
||||
// do not fill the msgbuf buffer, if cmd_silent is set, leave it
|
||||
// empty for the search_stat feature.
|
||||
@ -1234,18 +1265,19 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
||||
if (utf_iscomposing(utf_ptr2char(p))) {
|
||||
// Use a space to draw the composing char on.
|
||||
msgbuf[1] = ' ';
|
||||
memmove(msgbuf + 2, p, strlen(p));
|
||||
memmove(msgbuf + 2, p, plen);
|
||||
} else {
|
||||
memmove(msgbuf + 1, p, strlen(p));
|
||||
memmove(msgbuf + 1, p, plen);
|
||||
}
|
||||
if (off_len > 0) {
|
||||
memmove(msgbuf + strlen(p) + 1, off_buf, off_len);
|
||||
memmove(msgbuf + plen + 1, off_buf, off_len);
|
||||
}
|
||||
|
||||
trunc = msg_strtrunc(msgbuf, true);
|
||||
char *trunc = msg_strtrunc(msgbuf, true);
|
||||
if (trunc != NULL) {
|
||||
xfree(msgbuf);
|
||||
msgbuf = trunc;
|
||||
msgbuflen = strlen(msgbuf);
|
||||
}
|
||||
|
||||
// The search pattern could be shown on the right in rightleft
|
||||
@ -1260,7 +1292,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
||||
while (*r == ' ') {
|
||||
r++;
|
||||
}
|
||||
size_t pat_len = (size_t)(msgbuf + strlen(msgbuf) - r);
|
||||
size_t pat_len = (size_t)(msgbuf + msgbuflen - r);
|
||||
memmove(msgbuf, r, pat_len);
|
||||
// overwrite old text
|
||||
if ((size_t)(r - msgbuf) >= pat_len) {
|
||||
@ -1277,6 +1309,10 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
||||
ui_flush();
|
||||
msg_nowait = true; // don't wait for this message
|
||||
}
|
||||
|
||||
if (!shortmess(SHM_SEARCHCOUNT)) {
|
||||
show_search_stats = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If there is a character offset, subtract it from the current
|
||||
@ -1309,7 +1345,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
||||
}
|
||||
|
||||
c = searchit(curwin, curbuf, &pos, NULL, dirc == '/' ? FORWARD : BACKWARD,
|
||||
searchstr, count,
|
||||
searchstr, searchstrlen, count,
|
||||
(spats[0].off.end * SEARCH_END
|
||||
+ (options
|
||||
& (SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS + SEARCH_MSG
|
||||
@ -1379,14 +1415,9 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
||||
}
|
||||
|
||||
// Show [1/15] if 'S' is not in 'shortmess'.
|
||||
if ((options & SEARCH_ECHO)
|
||||
&& messaging()
|
||||
&& !msg_silent
|
||||
&& c != FAIL
|
||||
&& !shortmess(SHM_SEARCHCOUNT)
|
||||
&& msgbuf != NULL) {
|
||||
if (show_search_stats) {
|
||||
cmdline_search_stat(dirc, &pos, &curwin->w_cursor,
|
||||
show_top_bot_msg, msgbuf,
|
||||
show_top_bot_msg, msgbuf, msgbuflen,
|
||||
(count != 1 || has_offset
|
||||
|| (!(fdo_flags & FDO_SEARCH)
|
||||
&& hasFolding(curwin, curwin->w_cursor.lnum, NULL,
|
||||
@ -1413,6 +1444,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
||||
goto end_do_search;
|
||||
}
|
||||
pat++;
|
||||
patlen--;
|
||||
}
|
||||
|
||||
if (options & SEARCH_MARK) {
|
||||
@ -2418,7 +2450,8 @@ int current_search(int count, bool forward)
|
||||
}
|
||||
|
||||
// Is the pattern is zero-width?, this time, don't care about the direction
|
||||
int zero_width = is_zero_width(spats[last_idx].pat, true, &curwin->w_cursor, FORWARD);
|
||||
int zero_width = is_zero_width(spats[last_idx].pat, spats[last_idx].patlen,
|
||||
true, &curwin->w_cursor, FORWARD);
|
||||
if (zero_width == -1) {
|
||||
return FAIL; // pattern not found
|
||||
}
|
||||
@ -2451,7 +2484,7 @@ int current_search(int count, bool forward)
|
||||
|
||||
result = searchit(curwin, curbuf, &pos, &end_pos,
|
||||
(dir ? FORWARD : BACKWARD),
|
||||
spats[last_idx].pat, i ? count : 1,
|
||||
spats[last_idx].pat, spats[last_idx].patlen, i ? count : 1,
|
||||
SEARCH_KEEP | flags, RE_SEARCH, NULL);
|
||||
|
||||
p_ws = old_p_ws;
|
||||
@ -2525,7 +2558,8 @@ int current_search(int count, bool forward)
|
||||
/// else from position "cur".
|
||||
/// "direction" is FORWARD or BACKWARD.
|
||||
/// Returns true, false or -1 for failure.
|
||||
static int is_zero_width(char *pattern, bool move, pos_T *cur, Direction direction)
|
||||
static int is_zero_width(char *pattern, size_t patternlen, bool move, pos_T *cur,
|
||||
Direction direction)
|
||||
{
|
||||
regmmatch_T regmatch;
|
||||
int result = -1;
|
||||
@ -2535,9 +2569,10 @@ static int is_zero_width(char *pattern, bool move, pos_T *cur, Direction directi
|
||||
|
||||
if (pattern == NULL) {
|
||||
pattern = spats[last_idx].pat;
|
||||
patternlen = spats[last_idx].patlen;
|
||||
}
|
||||
|
||||
if (search_regcomp(pattern, NULL, RE_SEARCH, RE_SEARCH,
|
||||
if (search_regcomp(pattern, patternlen, NULL, RE_SEARCH, RE_SEARCH,
|
||||
SEARCH_KEEP, ®match) == FAIL) {
|
||||
return -1;
|
||||
}
|
||||
@ -2552,7 +2587,7 @@ static int is_zero_width(char *pattern, bool move, pos_T *cur, Direction directi
|
||||
// accept a match at the cursor position
|
||||
flag = SEARCH_START;
|
||||
}
|
||||
if (searchit(curwin, curbuf, &pos, NULL, direction, pattern, 1,
|
||||
if (searchit(curwin, curbuf, &pos, NULL, direction, pattern, patternlen, 1,
|
||||
SEARCH_KEEP + flag, RE_SEARCH, NULL) != FAIL) {
|
||||
int nmatched = 0;
|
||||
// Zero-width pattern should match somewhere, then we can check if
|
||||
@ -2591,7 +2626,8 @@ bool linewhite(linenr_T lnum)
|
||||
/// Add the search count "[3/19]" to "msgbuf".
|
||||
/// See update_search_stat() for other arguments.
|
||||
static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool show_top_bot_msg,
|
||||
char *msgbuf, bool recompute, int maxcount, int timeout)
|
||||
char *msgbuf, size_t msgbuflen, bool recompute, int maxcount,
|
||||
int timeout)
|
||||
{
|
||||
searchstat_T stat;
|
||||
|
||||
@ -2602,36 +2638,36 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh
|
||||
}
|
||||
|
||||
char t[SEARCH_STAT_BUF_LEN];
|
||||
size_t len;
|
||||
|
||||
if (curwin->w_p_rl && *curwin->w_p_rlc == 's') {
|
||||
if (stat.incomplete == 1) {
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
|
||||
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
|
||||
} else if (stat.cnt > maxcount && stat.cur > maxcount) {
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
|
||||
maxcount, maxcount);
|
||||
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
|
||||
maxcount, maxcount);
|
||||
} else if (stat.cnt > maxcount) {
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/%d]",
|
||||
maxcount, stat.cur);
|
||||
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/%d]",
|
||||
maxcount, stat.cur);
|
||||
} else {
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
|
||||
stat.cnt, stat.cur);
|
||||
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
|
||||
stat.cnt, stat.cur);
|
||||
}
|
||||
} else {
|
||||
if (stat.incomplete == 1) {
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
|
||||
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
|
||||
} else if (stat.cnt > maxcount && stat.cur > maxcount) {
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
|
||||
maxcount, maxcount);
|
||||
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
|
||||
maxcount, maxcount);
|
||||
} else if (stat.cnt > maxcount) {
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/>%d]",
|
||||
stat.cur, maxcount);
|
||||
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/>%d]",
|
||||
stat.cur, maxcount);
|
||||
} else {
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
|
||||
stat.cur, stat.cnt);
|
||||
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
|
||||
stat.cur, stat.cnt);
|
||||
}
|
||||
}
|
||||
|
||||
size_t len = strlen(t);
|
||||
if (show_top_bot_msg && len + 2 < SEARCH_STAT_BUF_LEN) {
|
||||
memmove(t + 2, t, len);
|
||||
t[0] = 'W';
|
||||
@ -2639,11 +2675,10 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh
|
||||
len += 2;
|
||||
}
|
||||
|
||||
size_t msgbuf_len = strlen(msgbuf);
|
||||
if (len > msgbuf_len) {
|
||||
len = msgbuf_len;
|
||||
if (len > msgbuflen) {
|
||||
len = msgbuflen;
|
||||
}
|
||||
memmove(msgbuf + msgbuf_len - len, t, len);
|
||||
memmove(msgbuf + msgbuflen - len, t, len);
|
||||
|
||||
if (dirc == '?' && stat.cur == maxcount + 1) {
|
||||
stat.cur = -1;
|
||||
@ -2726,7 +2761,7 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst
|
||||
start = profile_setlimit(timeout);
|
||||
}
|
||||
while (!got_int && searchit(curwin, curbuf, &lastpos, &endpos,
|
||||
FORWARD, NULL, 1, SEARCH_KEEP, RE_LAST,
|
||||
FORWARD, NULL, 0, 1, SEARCH_KEEP, RE_LAST,
|
||||
NULL) != FAIL) {
|
||||
done_search = true;
|
||||
// Stop after passing the time limit.
|
||||
@ -2860,7 +2895,8 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
goto the_end;
|
||||
}
|
||||
xfree(spats[last_idx].pat);
|
||||
spats[last_idx].pat = xstrdup(pattern);
|
||||
spats[last_idx].patlen = strlen(pattern);
|
||||
spats[last_idx].pat = xstrnsave(pattern, spats[last_idx].patlen);
|
||||
}
|
||||
if (spats[last_idx].pat == NULL || *spats[last_idx].pat == NUL) {
|
||||
goto the_end; // the previous pattern was never defined
|
||||
@ -3602,10 +3638,10 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool
|
||||
// when CONT_SOL is set compare "ptr" with the beginning of the
|
||||
// line is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo
|
||||
&& !compl_status_sol()) {
|
||||
size_t patlen = len + 5;
|
||||
char *pat = xmalloc(patlen);
|
||||
size_t patsize = len + 5;
|
||||
char *pat = xmalloc(patsize);
|
||||
assert(len <= INT_MAX);
|
||||
snprintf(pat, patlen, whole ? "\\<%.*s\\>" : "%.*s", (int)len, ptr);
|
||||
snprintf(pat, patsize, whole ? "\\<%.*s\\>" : "%.*s", (int)len, ptr);
|
||||
// ignore case according to p_ic, p_scs and pat
|
||||
regmatch.rm_ic = ignorecase(pat);
|
||||
regmatch.regprog = vim_regcomp(pat, magic_isset() ? RE_MAGIC : 0);
|
||||
@ -3623,8 +3659,7 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool
|
||||
incl_regmatch.rm_ic = false; // don't ignore case in incl. pat.
|
||||
}
|
||||
if (type == FIND_DEFINE && (*curbuf->b_p_def != NUL || *p_def != NUL)) {
|
||||
def_regmatch.regprog = vim_regcomp(*curbuf->b_p_def == NUL
|
||||
? p_def : curbuf->b_p_def,
|
||||
def_regmatch.regprog = vim_regcomp(*curbuf->b_p_def == NUL ? p_def : curbuf->b_p_def,
|
||||
magic_isset() ? RE_MAGIC : 0);
|
||||
if (def_regmatch.regprog == NULL) {
|
||||
goto fpip_end;
|
||||
@ -4066,7 +4101,7 @@ exit_matched:
|
||||
&& action == ACTION_EXPAND
|
||||
&& !compl_status_sol()
|
||||
&& *startp != NUL
|
||||
&& *(p = startp + utfc_ptr2len(startp)) != NUL) {
|
||||
&& *(startp + utfc_ptr2len(startp)) != NUL) {
|
||||
goto search_line;
|
||||
}
|
||||
}
|
||||
@ -4165,8 +4200,9 @@ static void show_pat_in_path(char *line, int type, bool did_show, int action, FI
|
||||
if (got_int) { // 'q' typed at "--more--" message
|
||||
return;
|
||||
}
|
||||
size_t linelen = strlen(line);
|
||||
while (true) {
|
||||
char *p = line + strlen(line) - 1;
|
||||
char *p = line + linelen - 1;
|
||||
if (fp != NULL) {
|
||||
// We used fgets(), so get rid of newline at end
|
||||
if (p >= line && *p == '\n') {
|
||||
@ -4196,12 +4232,14 @@ static void show_pat_in_path(char *line, int type, bool did_show, int action, FI
|
||||
if (vim_fgets(line, LSIZE, fp)) { // end of file
|
||||
break;
|
||||
}
|
||||
linelen = strlen(line);
|
||||
(*lnum)++;
|
||||
} else {
|
||||
if (++*lnum > curbuf->b_ml.ml_line_count) {
|
||||
break;
|
||||
}
|
||||
line = ml_get(*lnum);
|
||||
linelen = (size_t)ml_get_len(*lnum);
|
||||
}
|
||||
msg_putchar('\n');
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ typedef struct {
|
||||
/// Structure containing last search pattern and its attributes.
|
||||
typedef struct {
|
||||
char *pat; ///< The pattern (in allocated memory) or NULL.
|
||||
size_t patlen; ///< The length of the patten (0 is pat is NULL).
|
||||
bool magic; ///< Magicness of the pattern.
|
||||
bool no_scs; ///< No smartcase for this pattern.
|
||||
Timestamp timestamp; ///< Time of the last change.
|
||||
|
@ -2665,16 +2665,16 @@ void ex_spellrepall(exarg_T *eap)
|
||||
const size_t repl_to_len = strlen(repl_to);
|
||||
const int addlen = (int)(repl_to_len - repl_from_len);
|
||||
|
||||
const size_t frompatlen = repl_from_len + 7;
|
||||
char *frompat = xmalloc(frompatlen);
|
||||
snprintf(frompat, frompatlen, "\\V\\<%s\\>", repl_from);
|
||||
const size_t frompatsize = repl_from_len + 7;
|
||||
char *frompat = xmalloc(frompatsize);
|
||||
size_t frompatlen = (size_t)snprintf(frompat, frompatsize, "\\V\\<%s\\>", repl_from);
|
||||
p_ws = false;
|
||||
|
||||
sub_nsubs = 0;
|
||||
sub_nlines = 0;
|
||||
curwin->w_cursor.lnum = 0;
|
||||
while (!got_int) {
|
||||
if (do_search(NULL, '/', '/', frompat, 1, SEARCH_KEEP, NULL) == 0
|
||||
if (do_search(NULL, '/', '/', frompat, frompatlen, 1, SEARCH_KEEP, NULL) == 0
|
||||
|| u_save_cursor() == FAIL) {
|
||||
break;
|
||||
}
|
||||
|
@ -2942,6 +2942,8 @@ static int jumpto_tag(const char *lbuf_arg, int forceit, bool keep_help)
|
||||
str = skip_regexp(pbuf + 1, pbuf[0], false) + 1;
|
||||
}
|
||||
if (str > pbuf_end - 1) { // search command with nothing following
|
||||
size_t pbuflen = (size_t)(pbuf_end - pbuf);
|
||||
|
||||
bool save_p_ws = p_ws;
|
||||
int save_p_ic = p_ic;
|
||||
int save_p_scs = p_scs;
|
||||
@ -2956,25 +2958,27 @@ static int jumpto_tag(const char *lbuf_arg, int forceit, bool keep_help)
|
||||
// start search before first line
|
||||
curwin->w_cursor.lnum = 0;
|
||||
}
|
||||
if (do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, 1, search_options, NULL)) {
|
||||
if (do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, pbuflen - 1, 1,
|
||||
search_options, NULL)) {
|
||||
retval = OK;
|
||||
} else {
|
||||
int found = 1;
|
||||
|
||||
// try again, ignore case now
|
||||
p_ic = true;
|
||||
if (!do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, 1, search_options, NULL)) {
|
||||
if (!do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, pbuflen - 1, 1,
|
||||
search_options, NULL)) {
|
||||
// Failed to find pattern, take a guess: "^func ("
|
||||
found = 2;
|
||||
test_for_static(&tagp);
|
||||
char cc = *tagp.tagname_end;
|
||||
*tagp.tagname_end = NUL;
|
||||
snprintf(pbuf, LSIZE, "^%s\\s\\*(", tagp.tagname);
|
||||
if (!do_search(NULL, '/', '/', pbuf, 1, search_options, NULL)) {
|
||||
pbuflen = (size_t)snprintf(pbuf, LSIZE, "^%s\\s\\*(", tagp.tagname);
|
||||
if (!do_search(NULL, '/', '/', pbuf, pbuflen, 1, search_options, NULL)) {
|
||||
// Guess again: "^char * \<func ("
|
||||
snprintf(pbuf, LSIZE, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
|
||||
tagp.tagname);
|
||||
if (!do_search(NULL, '/', '/', pbuf, 1, search_options, NULL)) {
|
||||
pbuflen = (size_t)snprintf(pbuf, LSIZE, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
|
||||
tagp.tagname);
|
||||
if (!do_search(NULL, '/', '/', pbuf, len, 1, search_options, NULL)) {
|
||||
found = 0;
|
||||
}
|
||||
}
|
||||
|
@ -35,9 +35,10 @@ itp('pat_has_uppercase', function()
|
||||
end)
|
||||
|
||||
describe('search_regcomp', function()
|
||||
local search_regcomp = function(pat, pat_save, pat_use, options)
|
||||
local search_regcomp = function(pat, patlen, pat_save, pat_use, options)
|
||||
local regmatch = ffi.new('regmmatch_T')
|
||||
local fail = search.search_regcomp(to_cstr(pat), nil, pat_save, pat_use, options, regmatch)
|
||||
local fail =
|
||||
search.search_regcomp(to_cstr(pat), patlen, nil, pat_save, pat_use, options, regmatch)
|
||||
return fail, regmatch
|
||||
end
|
||||
|
||||
@ -50,7 +51,7 @@ describe('search_regcomp', function()
|
||||
globals.curwin.w_onebuf_opt.wo_rl = 1
|
||||
globals.curwin.w_onebuf_opt.wo_rlc = to_cstr('s')
|
||||
globals.cmdmod.cmod_flags = globals.CMOD_KEEPPATTERNS
|
||||
local fail = search_regcomp('a\192', 0, 0, 0)
|
||||
local fail = search_regcomp('a\192', 2, 0, 0, 0)
|
||||
eq(1, fail)
|
||||
eq('\192a', get_search_pat())
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user