mirror of
https://github.com/neovim/neovim.git
synced 2025-10-16 23:06:14 +00: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:
@@ -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');
|
||||
}
|
||||
|
Reference in New Issue
Block a user