diff options
Diffstat (limited to 'src/nvim/search.c')
-rw-r--r-- | src/nvim/search.c | 250 |
1 files changed, 144 insertions, 106 deletions
diff --git a/src/nvim/search.c b/src/nvim/search.c index df0a9171d2..746c253708 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -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'); } |