diff options
Diffstat (limited to 'src/nvim/search.c')
-rw-r--r-- | src/nvim/search.c | 352 |
1 files changed, 169 insertions, 183 deletions
diff --git a/src/nvim/search.c b/src/nvim/search.c index b24b6ad27c..642219c1e0 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -1,6 +1,3 @@ -// This is an open source non-commercial project. Dear PVS-Studio, please check -// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - // search.c: code for normal mode searching commands #include <assert.h> @@ -11,7 +8,7 @@ #include <stdlib.h> #include <string.h> -#include "nvim/ascii.h" +#include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" #include "nvim/buffer_defs.h" @@ -27,13 +24,14 @@ #include "nvim/ex_getln.h" #include "nvim/fileio.h" #include "nvim/fold.h" +#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" -#include "nvim/highlight_defs.h" +#include "nvim/highlight.h" #include "nvim/indent_c.h" #include "nvim/insexpand.h" -#include "nvim/macros.h" +#include "nvim/macros_defs.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" @@ -43,23 +41,31 @@ #include "nvim/move.h" #include "nvim/normal.h" #include "nvim/option.h" +#include "nvim/option_vars.h" #include "nvim/os/fs.h" #include "nvim/os/input.h" #include "nvim/os/time.h" #include "nvim/path.h" +#include "nvim/plines.h" #include "nvim/profile.h" #include "nvim/regexp.h" -#include "nvim/screen.h" #include "nvim/search.h" +#include "nvim/state_defs.h" #include "nvim/strings.h" +#include "nvim/tag.h" #include "nvim/ui.h" -#include "nvim/vim.h" +#include "nvim/vim_defs.h" #include "nvim/window.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "search.c.generated.h" #endif +static const char e_search_hit_top_without_match_for_str[] + = N_("E384: Search hit TOP without match for: %s"); +static const char e_search_hit_bottom_without_match_for_str[] + = N_("E385: Search hit BOTTOM without match for: %s"); + // This file contains various searching-related routines. These fall into // three groups: // 1. string searches (for /, ?, n, and N) @@ -88,14 +94,14 @@ static struct spat spats[2] = { // Last used search pattern - [0] = { NULL, true, false, 0, { '/', false, false, 0L }, NULL }, + [0] = { NULL, true, false, 0, { '/', false, false, 0 }, NULL }, // Last used substitute pattern - [1] = { NULL, true, false, 0, { '/', false, false, 0L }, NULL } + [1] = { NULL, true, false, 0, { '/', false, false, 0 }, NULL } }; static int last_idx = 0; // index in spats[] for RE_LAST -static char_u lastc[2] = { NUL, NUL }; // last character searched for +static uint8_t lastc[2] = { NUL, NUL }; // last character searched for static Direction lastcdir = FORWARD; // last direction of character search static int last_t_cmd = true; // last search t_cmd static char lastc_bytes[MB_MAXBYTES + 1]; @@ -136,14 +142,12 @@ typedef struct SearchedFile { int search_regcomp(char *pat, char **used_pat, int pat_save, int pat_use, int options, regmmatch_T *regmatch) { - int magic; - int i; - rc_did_emsg = false; - magic = magic_isset(); + int magic = magic_isset(); // If no pattern given, use a previously defined pattern. if (pat == NULL || *pat == NUL) { + int i; if (pat_use == RE_LAST) { i = last_idx; } else { @@ -343,13 +347,13 @@ void restore_last_search_pattern(void) static void save_incsearch_state(void) { saved_search_match_endcol = search_match_endcol; - saved_search_match_lines = search_match_lines; + saved_search_match_lines = search_match_lines; } static void restore_incsearch_state(void) { search_match_endcol = saved_search_match_endcol; - search_match_lines = saved_search_match_lines; + search_match_lines = saved_search_match_lines; } char *last_search_pattern(void) @@ -439,7 +443,7 @@ int last_csearch_until(void) void set_last_csearch(int c, char *s, int len) { - *lastc = (char_u)c; + *lastc = (uint8_t)c; lastc_bytelen = len; if (len) { memcpy(lastc_bytes, s, (size_t)len); @@ -547,7 +551,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, - long count, int options, int pat_use, searchit_arg_T *extra_arg) + int count, int options, int pat_use, searchit_arg_T *extra_arg) { int found; linenr_T lnum; // no init to shut up Apollo cc @@ -557,12 +561,10 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, lpos_T endpos; lpos_T matchpos; int loop; - pos_T start_pos; - int at_first_line; int extra_col; int start_char_len; bool match_ok; - long nmatched; + int nmatched; int submatch = 0; bool first_match = true; const int called_emsg_before = called_emsg; @@ -596,7 +598,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, && pos->lnum <= buf->b_ml.ml_line_count && pos->col < MAXCOL - 2) { // Watch out for the "col" being MAXCOL - 2, used in a closed fold. - ptr = ml_get_buf(buf, pos->lnum, false); + ptr = ml_get_buf(buf, pos->lnum); if ((int)strlen(ptr) <= pos->col) { start_char_len = 1; } else { @@ -611,9 +613,9 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, extra_col = (options & SEARCH_START) ? start_char_len : 0; } - start_pos = *pos; // remember start pos for detecting no match + pos_T start_pos = *pos; // remember start pos for detecting no match found = 0; // default: not found - at_first_line = true; // default: start in first line + int at_first_line = true; // default: start in first line if (pos->lnum == 0) { // correct lnum for when starting in line 0 pos->lnum = 1; pos->col = 0; @@ -667,7 +669,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, if (lnum + matchpos.lnum > buf->b_ml.ml_line_count) { ptr = ""; } else { - ptr = ml_get_buf(buf, lnum + matchpos.lnum, false); + ptr = ml_get_buf(buf, lnum + matchpos.lnum); } // Forward search in the first line: match should be after @@ -683,9 +685,9 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, // otherwise "/$" will get stuck on end of line. while (matchpos.lnum == 0 && (((options & SEARCH_END) && first_match) - ? (nmatched == 1 - && (int)endpos.col - 1 - < (int)start_pos.col + extra_col) + ? (nmatched == 1 + && (int)endpos.col - 1 + < (int)start_pos.col + extra_col) : ((int)matchpos.col - (ptr[matchpos.col] == NUL) < (int)start_pos.col + extra_col))) { @@ -739,7 +741,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, } // Need to get the line pointer again, a multi-line search may // have made it invalid. - ptr = ml_get_buf(buf, lnum, false); + ptr = ml_get_buf(buf, lnum); } if (!match_ok) { continue; @@ -752,7 +754,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, // When putting the new cursor at the end, compare // relative to the end of the match. match_ok = false; - for (;;) { + while (true) { // Remember a position that is before the start // position, we use it if it's the last match in // the line. Always accept a position after @@ -821,7 +823,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, } // Need to get the line pointer again, a // multi-line search may have made it invalid. - ptr = ml_get_buf(buf, lnum + matchpos.lnum, false); + ptr = ml_get_buf(buf, lnum + matchpos.lnum); } // If there is only a match after the cursor, skip @@ -844,12 +846,12 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, if (endpos.col == 0) { if (pos->lnum > 1) { // just in case pos->lnum--; - pos->col = (colnr_T)strlen(ml_get_buf(buf, pos->lnum, false)); + pos->col = (colnr_T)strlen(ml_get_buf(buf, pos->lnum)); } } else { pos->col--; if (pos->lnum <= buf->b_ml.ml_line_count) { - ptr = ml_get_buf(buf, pos->lnum, false); + ptr = ml_get_buf(buf, pos->lnum); pos->col -= utf_head_off(ptr, ptr + pos->col); } } @@ -913,19 +915,22 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, || found || loop) { break; } - // + // If 'wrapscan' is set we continue at the other end of the file. - // If 'shortmess' does not contain 's', we give a message. + // If 'shortmess' does not contain 's', we give a message, but + // only, if we won't show the search stat later anyhow, + // (so SEARCH_COUNT must be absent). // This message is also remembered in keep_msg for when the screen // is redrawn. The keep_msg is cleared whenever another message is // written. - // if (dir == BACKWARD) { // start second loop at the other end lnum = buf->b_ml.ml_line_count; } else { lnum = 1; } - if (!shortmess(SHM_SEARCH) && (options & SEARCH_MSG)) { + if (!shortmess(SHM_SEARCH) + && shortmess(SHM_SEARCHCOUNT) + && (options & SEARCH_MSG)) { give_warning(_(dir == BACKWARD ? top_bot_msg : bot_top_msg), true); } if (extra_arg != NULL) { @@ -948,11 +953,9 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, if (p_ws) { semsg(_(e_patnotf2), mr_pattern); } else if (lnum == 0) { - semsg(_("E384: search hit TOP without match for: %s"), - mr_pattern); + semsg(_(e_search_hit_top_without_match_for_str), mr_pattern); } else { - semsg(_("E385: search hit BOTTOM without match for: %s"), - mr_pattern); + semsg(_(e_search_hit_bottom_without_match_for_str), mr_pattern); } } return FAIL; @@ -961,7 +964,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, // A pattern like "\n\zs" may go past the last line. if (pos->lnum > buf->b_ml.ml_line_count) { pos->lnum = buf->b_ml.ml_line_count; - pos->col = (int)strlen(ml_get_buf(buf, pos->lnum, false)); + pos->col = (int)strlen(ml_get_buf(buf, pos->lnum)); if (pos->col > 0) { pos->col--; } @@ -977,7 +980,7 @@ void set_search_direction(int cdir) static void set_vv_searchforward(void) { - set_vim_var_nr(VV_SEARCHFORWARD, (long)(spats[0].off.dir == '/')); + set_vim_var_nr(VV_SEARCHFORWARD, spats[0].off.dir == '/'); } // Return the number of the first subpat that matched. @@ -1023,15 +1026,14 @@ 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, long count, int options, +int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, int options, searchit_arg_T *sia) { pos_T pos; // position of the last match char *searchstr; - struct soffset old_off; int retval; // Return value char *p; - long c; + int64_t c; char *dircp; char *strcopy = NULL; char *ps; @@ -1047,13 +1049,13 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, long count, i // Save the values for when (options & SEARCH_KEEP) is used. // (there is no "if ()" around this because gcc wants them initialized) - old_off = spats[0].off; + struct soffset old_off = spats[0].off; pos = curwin->w_cursor; // start searching at the cursor position // Find out the direction of the search. if (dirc == 0) { - dirc = (char_u)spats[0].off.dir; + dirc = (uint8_t)spats[0].off.dir; } else { spats[0].off.dir = (char)dirc; set_vv_searchforward(); @@ -1085,7 +1087,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, long count, i } // Repeat the search when pattern followed by ';', e.g. "/foo/;?bar". - for (;;) { + while (true) { bool show_top_bot_msg = false; searchstr = pat; @@ -1169,7 +1171,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, long count, i // 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; // -V507 + p = off_buf; *p++ = (char)dirc; if (spats[0].off.end) { *p++ = 'e'; @@ -1262,7 +1264,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, long count, i memset(msgbuf + pat_len, ' ', (size_t)(r - msgbuf)); } } - msg_outtrans(msgbuf); + msg_outtrans(msgbuf, 0); msg_clr_eos(); msg_check(); @@ -1434,13 +1436,11 @@ end_do_search: int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char *pat) { linenr_T start = 0; - char *ptr; - char *p; if (buf->b_ml.ml_line_count == 0) { return FAIL; } - for (;;) { + while (true) { pos->lnum += dir; if (pos->lnum < 1) { if (p_ws) { @@ -1469,21 +1469,21 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char *pat) if (start == 0) { start = pos->lnum; } - ptr = ml_get_buf(buf, pos->lnum, false); - p = skipwhite(ptr); + char *ptr = ml_get_buf(buf, pos->lnum); + char *p = skipwhite(ptr); pos->col = (colnr_T)(p - ptr); // when adding lines the matching line may be empty but it is not // ignored because we are interested in the next line -- Acevedo if (compl_status_adding() && !compl_status_sol()) { - if (mb_strcmp_ic((bool)p_ic, (const char *)p, (const char *)pat) == 0) { + if (mb_strcmp_ic((bool)p_ic, p, pat) == 0) { return OK; } } else if (*p != NUL) { // Ignore empty lines. // Expanding lines or words. assert(ins_compl_len() >= 0); if ((p_ic ? mb_strnicmp(p, pat, (size_t)ins_compl_len()) - : strncmp(p, pat, (size_t)ins_compl_len())) == 0) { + : strncmp(p, pat, (size_t)ins_compl_len())) == 0) { return OK; } } @@ -1502,15 +1502,12 @@ int searchc(cmdarg_T *cap, int t_cmd) { int c = cap->nchar; // char to search for int dir = cap->arg; // true for searching forward - long count = cap->count1; // repeat count - int col; - char *p; - int len; + int count = cap->count1; // repeat count bool stop = true; if (c != NUL) { // normal search: remember args for repeat if (!KeyStuffed) { // don't remember when redoing - *lastc = (char_u)c; + *lastc = (uint8_t)c; set_csearch_direction(dir); set_csearch_until(t_cmd); lastc_bytelen = utf_char2bytes(c, lastc_bytes); @@ -1524,7 +1521,7 @@ int searchc(cmdarg_T *cap, int t_cmd) } } } else { // repeat previous search - if (*lastc == NUL && lastc_bytelen == 1) { + if (*lastc == NUL && lastc_bytelen <= 1) { return FAIL; } if (dir) { // repeat in opposite direction @@ -1550,12 +1547,12 @@ int searchc(cmdarg_T *cap, int t_cmd) cap->oap->inclusive = true; } - p = get_cursor_line_ptr(); - col = curwin->w_cursor.col; - len = (int)strlen(p); + char *p = get_cursor_line_ptr(); + int col = curwin->w_cursor.col; + int len = (int)strlen(p); while (count--) { - for (;;) { + while (true) { if (dir > 0) { col += utfc_ptr2len(p + col); if (col >= len) { @@ -1567,7 +1564,7 @@ int searchc(cmdarg_T *cap, int t_cmd) } col -= utf_head_off(p, p + col - 1) + 1; } - if (lastc_bytelen == 1) { + if (lastc_bytelen <= 1) { if (p[col] == c && stop) { break; } @@ -1632,7 +1629,7 @@ static bool find_rawstring_end(char *linep, pos_T *startpos, pos_T *endpos) for (p = linep + startpos->col + 1; *p && *p != '('; p++) {} size_t delim_len = (size_t)((p - linep) - startpos->col - 1); - char *delim_copy = xstrnsave(linep + startpos->col + 1, delim_len); + char *delim_copy = xmemdupz(linep + startpos->col + 1, delim_len); bool found = false; for (lnum = startpos->lnum; lnum <= endpos->lnum; lnum++) { char *line = ml_get(lnum); @@ -1821,7 +1818,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) if (linep[pos.col] == NUL && pos.col) { pos.col--; } - for (;;) { + while (true) { initc = utf_ptr2char(linep + pos.col); if (initc == NUL) { break; @@ -1841,11 +1838,11 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) return NULL; } } else if (!cpo_bsl) { - int col, bslcnt = 0; + int bslcnt = 0; // Set "match_escaped" if there are an odd number of // backslashes. - for (col = pos.col; check_prevcol(linep, col, '\\', &col);) { + for (int col = pos.col; check_prevcol(linep, col, '\\', &col);) { bslcnt++; } match_escaped = (bslcnt & 1); @@ -2207,10 +2204,10 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) // quotes when the start is also inside of quotes. if ((!inquote || start_in_quotes == kTrue) && (c == initc || c == findc)) { - int col, bslcnt = 0; + int bslcnt = 0; if (!cpo_bsl) { - for (col = pos.col; check_prevcol(linep, col, '\\', &col);) { + for (int col = pos.col; check_prevcol(linep, col, '\\', &col);) { bslcnt++; } } @@ -2244,10 +2241,10 @@ int check_linecomment(const char *line) const char *p = line; // scan from start // skip Lispish one-line comments if (curbuf->b_p_lisp) { - if (vim_strchr((char *)p, ';') != NULL) { // there may be comments + if (vim_strchr(p, ';') != NULL) { // there may be comments bool in_str = false; // inside of string - while ((p = strpbrk((char *)p, "\";")) != NULL) { + while ((p = strpbrk(p, "\";")) != NULL) { if (*p == '"') { if (in_str) { if (*(p - 1) != '\\') { // skip escaped quote @@ -2269,7 +2266,7 @@ int check_linecomment(const char *line) p = NULL; } } else { - while ((p = vim_strchr((char *)p, '/')) != NULL) { + while ((p = vim_strchr(p, '/')) != NULL) { // Accept a double /, unless it's preceded with * and followed by *, // because * / / * is an end and start of a C comment. Only // accept the position if it is not inside a string. @@ -2295,15 +2292,10 @@ int check_linecomment(const char *line) /// @param c char to show match for void showmatch(int c) { - pos_T *lpos, save_cursor; - pos_T mpos; + pos_T *lpos; colnr_T vcol; - long *so = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so; - long *siso = curwin->w_p_siso >= 0 ? &curwin->w_p_siso : &p_siso; - long save_so; - long save_siso; - int save_state; - colnr_T save_dollar_vcol; + OptInt *so = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so; + OptInt *siso = curwin->w_p_siso >= 0 ? &curwin->w_p_siso : &p_siso; char *p; // Only show match for chars in the 'matchpairs' option. @@ -2345,26 +2337,26 @@ void showmatch(int c) return; } - mpos = *lpos; // save the pos, update_screen() may change it - save_cursor = curwin->w_cursor; - save_so = *so; - save_siso = *siso; + pos_T mpos = *lpos; // save the pos, update_screen() may change it + pos_T save_cursor = curwin->w_cursor; + OptInt save_so = *so; + OptInt save_siso = *siso; // Handle "$" in 'cpo': If the ')' is typed on top of the "$", // stop displaying the "$". if (dollar_vcol >= 0 && dollar_vcol == curwin->w_virtcol) { dollar_vcol = -1; } curwin->w_virtcol++; // do display ')' just before "$" - update_screen(); // show the new char first - save_dollar_vcol = dollar_vcol; - save_state = State; + colnr_T save_dollar_vcol = dollar_vcol; + int save_state = State; State = MODE_SHOWMATCH; ui_cursor_shape(); // may show different cursor shape curwin->w_cursor = mpos; // move to matching char *so = 0; // don't use 'scrolloff' here *siso = 0; // don't use 'sidescrolloff' here - show_cursor_info(false); + show_cursor_info_later(false); + update_screen(); // show the new char setcursor(); ui_flush(); // Restore dollar_vcol(), because setcursor() may call curs_rows() @@ -2375,9 +2367,9 @@ void showmatch(int c) // brief pause, unless 'm' is present in 'cpo' and a character is // available. if (vim_strchr(p_cpo, CPO_SHOWMATCH) != NULL) { - os_delay((uint64_t)p_mat * 100L + 8, true); + os_delay((uint64_t)p_mat * 100 + 8, true); } else if (!char_avail()) { - os_delay((uint64_t)p_mat * 100L + 9, false); + os_delay((uint64_t)p_mat * 100 + 9, false); } curwin->w_cursor = save_cursor; // restore cursor position *so = save_so; @@ -2390,7 +2382,7 @@ void showmatch(int c) /// Used while an operator is pending, and in Visual mode. /// /// @param forward true for forward, false for backward -int current_search(long count, bool forward) +int current_search(int count, bool forward) { bool old_p_ws = p_ws; pos_T save_VIsual = VIsual; @@ -2475,7 +2467,7 @@ int current_search(long count, bool forward) } else { // try again from end of buffer // searching backwards, so set pos to last line and col pos.lnum = curwin->w_buffer->b_ml.ml_line_count; - pos.col = (colnr_T)strlen(ml_get(curwin->w_buffer->b_ml.ml_line_count)); + pos.col = (colnr_T)strlen(ml_get(curwin->w_buffer->b_ml.ml_line_count)); } } } @@ -2531,7 +2523,6 @@ int current_search(long count, bool forward) static int is_zero_width(char *pattern, int move, pos_T *cur, Direction direction) { regmmatch_T regmatch; - int nmatched = 0; int result = -1; pos_T pos; const int called_emsg_before = called_emsg; @@ -2558,13 +2549,14 @@ static int is_zero_width(char *pattern, int move, pos_T *cur, Direction directio } if (searchit(curwin, curbuf, &pos, NULL, direction, pattern, 1, SEARCH_KEEP + flag, RE_SEARCH, NULL) != FAIL) { + int nmatched = 0; // Zero-width pattern should match somewhere, then we can check if // start and end are in the same position. do { regmatch.startpos[0].col++; - nmatched = (int)vim_regexec_multi(®match, curwin, curbuf, - pos.lnum, regmatch.startpos[0].col, - NULL, NULL); + nmatched = vim_regexec_multi(®match, curwin, curbuf, + pos.lnum, regmatch.startpos[0].col, + NULL, NULL); if (nmatched != 0) { break; } @@ -2587,16 +2579,14 @@ static int is_zero_width(char *pattern, int move, pos_T *cur, Direction directio /// return true if line 'lnum' is empty or has white chars only. int linewhite(linenr_T lnum) { - char *p; - - p = skipwhite(ml_get(lnum)); + char *p = skipwhite(ml_get(lnum)); return *p == NUL; } /// 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, long timeout) + char *msgbuf, bool recompute, int maxcount, int timeout) { searchstat_T stat; @@ -2644,7 +2634,12 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh len += 2; } - memmove(msgbuf + strlen(msgbuf) - len, t, len); + size_t msgbuf_len = strlen(msgbuf); + if (len > msgbuf_len) { + len = msgbuf_len; + } + memmove(msgbuf + msgbuf_len - len, t, len); + if (dirc == '?' && stat.cur == maxcount + 1) { stat.cur = -1; } @@ -2663,7 +2658,7 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh // dirc == '/': find the next match // dirc == '?': find the previous match static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchstat_T *stat, - bool recompute, int maxcount, long timeout) + bool recompute, int maxcount, int timeout) { int save_ws = p_ws; bool wraparound = false; @@ -2677,7 +2672,6 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst static int chgtick = 0; static char *lastpat = NULL; static buf_T *lbuf = NULL; - proftime_T start; CLEAR_POINTER(stat); @@ -2713,15 +2707,18 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst lbuf = curbuf; } + // when searching backwards and having jumped to the first occurrence, + // cur must remain greater than 1 if (equalpos(lastpos, *cursor_pos) && !wraparound - && (dirc == 0 || dirc == '/' ? cur < cnt : cur > 0)) { + && (dirc == 0 || dirc == '/' ? cur < cnt : cur > 1)) { cur += dirc == 0 ? 0 : dirc == '/' ? 1 : -1; } else { + proftime_T start; bool done_search = false; pos_T endpos = { 0, 0, 0 }; p_ws = false; if (timeout > 0) { - start = profile_setlimit(timeout); + start = profile_setlimit(timeout); } while (!got_int && searchit(curwin, curbuf, &lastpos, &endpos, FORWARD, NULL, 1, SEARCH_KEEP, RE_LAST, @@ -2770,7 +2767,7 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) pos_T pos = curwin->w_cursor; char *pattern = NULL; int maxcount = SEARCH_STAT_DEF_MAX_COUNT; - long timeout = SEARCH_STAT_DEF_TIMEOUT; + int timeout = SEARCH_STAT_DEF_TIMEOUT; bool recompute = true; searchstat_T stat; @@ -2783,29 +2780,27 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) if (argvars[0].v_type != VAR_UNKNOWN) { dict_T *dict; dictitem_T *di; - listitem_T *li; bool error = false; - if (argvars[0].v_type != VAR_DICT || argvars[0].vval.v_dict == NULL) { - emsg(_(e_dictreq)); + if (tv_check_for_nonnull_dict_arg(argvars, 0) == FAIL) { return; } dict = argvars[0].vval.v_dict; - di = tv_dict_find(dict, (const char *)"timeout", -1); + di = tv_dict_find(dict, "timeout", -1); if (di != NULL) { - timeout = (long)tv_get_number_chk(&di->di_tv, &error); + timeout = (int)tv_get_number_chk(&di->di_tv, &error); if (error) { return; } } - di = tv_dict_find(dict, (const char *)"maxcount", -1); + di = tv_dict_find(dict, "maxcount", -1); if (di != NULL) { maxcount = (int)tv_get_number_chk(&di->di_tv, &error); if (error) { return; } } - di = tv_dict_find(dict, (const char *)"recompute", -1); + di = tv_dict_find(dict, "recompute", -1); if (di != NULL) { recompute = tv_get_number_chk(&di->di_tv, &error); if (error) { @@ -2819,7 +2814,7 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) return; } } - di = tv_dict_find(dict, (const char *)"pos", -1); + di = tv_dict_find(dict, "pos", -1); if (di != NULL) { if (di->di_tv.v_type != VAR_LIST) { semsg(_(e_invarg2), "pos"); @@ -2829,21 +2824,21 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) semsg(_(e_invarg2), "List format should be [lnum, col, off]"); return; } - li = tv_list_find(di->di_tv.vval.v_list, 0L); + listitem_T *li = tv_list_find(di->di_tv.vval.v_list, 0); if (li != NULL) { pos.lnum = (linenr_T)tv_get_number_chk(TV_LIST_ITEM_TV(li), &error); if (error) { return; } } - li = tv_list_find(di->di_tv.vval.v_list, 1L); + li = tv_list_find(di->di_tv.vval.v_list, 1); if (li != NULL) { pos.col = (colnr_T)tv_get_number_chk(TV_LIST_ITEM_TV(li), &error) - 1; if (error) { return; } } - li = tv_list_find(di->di_tv.vval.v_list, 2L); + li = tv_list_find(di->di_tv.vval.v_list, 2); if (li != NULL) { pos.coladd = (colnr_T)tv_get_number_chk(TV_LIST_ITEM_TV(li), &error); if (error) { @@ -3050,8 +3045,8 @@ static int fuzzy_match_recursive(const char *fuzpat, const char *str, uint32_t s // Loop through fuzpat and str looking for a match bool first_match = true; while (*fuzpat != NUL && *str != NUL) { - const int c1 = utf_ptr2char((char *)fuzpat); - const int c2 = utf_ptr2char((char *)str); + const int c1 = utf_ptr2char(fuzpat); + const int c2 = utf_ptr2char(str); // Found match if (mb_tolower(c1) == mb_tolower(c2)) { @@ -3060,6 +3055,10 @@ static int fuzzy_match_recursive(const char *fuzpat, const char *str, uint32_t s return 0; } + int recursiveScore = 0; + uint32_t recursiveMatches[MAX_FUZZY_MATCHES]; + CLEAR_FIELD(recursiveMatches); + // "Copy-on-Write" srcMatches into matches if (first_match && srcMatches != NULL) { memcpy(matches, srcMatches, (size_t)nextMatch * sizeof(srcMatches[0])); @@ -3067,9 +3066,7 @@ static int fuzzy_match_recursive(const char *fuzpat, const char *str, uint32_t s } // Recursive call that "skips" this match - uint32_t recursiveMatches[MAX_FUZZY_MATCHES]; - int recursiveScore = 0; - const char *const next_char = (char *)str + utfc_ptr2len((char *)str); + const char *const next_char = str + utfc_ptr2len(str); if (fuzzy_match_recursive(fuzpat, next_char, strIdx + 1, &recursiveScore, strBegin, strLen, matches, recursiveMatches, sizeof(recursiveMatches) / sizeof(recursiveMatches[0]), nextMatch, @@ -3120,8 +3117,7 @@ static int fuzzy_match_recursive(const char *fuzpat, const char *str, uint32_t s /// normalized and varies with pattern. /// Recursion is limited internally (default=10) to prevent degenerate cases /// (pat_arg="aaaaaa" str="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"). -/// Uses char_u for match indices. Therefore patterns are limited to -/// MAX_FUZZY_MATCHES characters. +/// Patterns are limited to MAX_FUZZY_MATCHES characters. /// /// @return true if "pat_arg" matches "str". Also returns the match score in /// "outScore" and the matching character positions in "matches". @@ -3211,10 +3207,10 @@ static int fuzzy_match_item_compare(const void *const s1, const void *const s2) static void fuzzy_match_in_list(list_T *const l, char *const str, const bool matchseq, const char *const key, Callback *const item_cb, const bool retmatchpos, list_T *const fmatchlist, - const long max_matches) + const int max_matches) FUNC_ATTR_NONNULL_ARG(2, 5, 7) { - long len = tv_list_len(l); + int len = tv_list_len(l); if (len == 0) { return; } @@ -3223,7 +3219,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat } fuzzyItem_T *const items = xcalloc((size_t)len, sizeof(fuzzyItem_T)); - long match_count = 0; + int match_count = 0; uint32_t matches[MAX_FUZZY_MATCHES]; // For all the string items in items, get the fuzzy matching score @@ -3242,7 +3238,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat // For a dict, either use the specified key to lookup the string or // use the specified callback function to get the string. if (key != NULL) { - itemstr = tv_dict_get_string(tv->vval.v_dict, (const char *)key, false); + itemstr = tv_dict_get_string(tv->vval.v_dict, key, false); } else { typval_T argv[2]; @@ -3272,7 +3268,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat if (retmatchpos) { items[match_count].lmatchpos = tv_list_alloc(kListLenMayKnow); int j = 0; - const char *p = (char *)str; + const char *p = str; while (*p != NUL) { if (!ascii_iswhite(utf_ptr2char(p)) || matchseq) { tv_list_append_number(items[match_count].lmatchpos, matches[j]); @@ -3307,7 +3303,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat } // Copy the matching strings with a valid score to the return list - for (long i = 0; i < match_count; i++) { + for (int i = 0; i < match_count; i++) { if (items[i].score == SCORE_NONE) { break; } @@ -3320,7 +3316,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat assert(li != NULL && TV_LIST_ITEM_TV(li)->vval.v_list != NULL); retlist = TV_LIST_ITEM_TV(li)->vval.v_list; - for (long i = 0; i < match_count; i++) { + for (int i = 0; i < match_count; i++) { if (items[i].score == SCORE_NONE) { break; } @@ -3331,7 +3327,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat li = tv_list_find(fmatchlist, -1); assert(li != NULL && TV_LIST_ITEM_TV(li)->vval.v_list != NULL); retlist = TV_LIST_ITEM_TV(li)->vval.v_list; - for (long i = 0; i < match_count; i++) { + for (int i = 0; i < match_count; i++) { if (items[i].score == SCORE_NONE) { break; } @@ -3361,10 +3357,9 @@ static void do_fuzzymatch(const typval_T *const argvars, typval_T *const rettv, Callback cb = CALLBACK_NONE; const char *key = NULL; bool matchseq = false; - long max_matches = 0; + int max_matches = 0; if (argvars[2].v_type != VAR_UNKNOWN) { - if (argvars[2].v_type != VAR_DICT || argvars[2].vval.v_dict == NULL) { - emsg(_(e_dictreq)); + if (tv_check_for_nonnull_dict_arg(argvars, 2) == FAIL) { return; } @@ -3389,7 +3384,7 @@ static void do_fuzzymatch(const typval_T *const argvars, typval_T *const rettv, semsg(_(e_invarg2), tv_get_string(&di->di_tv)); return; } - max_matches = (long)tv_get_number_chk(&di->di_tv, NULL); + max_matches = (int)tv_get_number_chk(&di->di_tv, NULL); } if (tv_dict_find(d, "matchseq", -1) != NULL) { @@ -3553,26 +3548,19 @@ static char *get_line_and_copy(linenr_T lnum, char *buf) /// @param start_lnum first line to start searching /// @param end_lnum last line for searching void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool skip_comments, - int type, long count, int action, linenr_T start_lnum, linenr_T end_lnum) + int type, int count, int action, linenr_T start_lnum, linenr_T end_lnum) { SearchedFile *files; // Stack of included files SearchedFile *bigger; // When we need more space int max_path_depth = 50; - long match_count = 1; + int match_count = 1; - char *pat; char *new_fname; char *curr_fname = curbuf->b_fname; char *prev_fname = NULL; - linenr_T lnum; - int depth; int depth_displayed; // For type==CHECK_PATH - int old_files; int already_searched; - char *file_line; - char *line; char *p; - char save_char; bool define_matched; regmatch_T regmatch; regmatch_T incl_regmatch; @@ -3590,14 +3578,14 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool incl_regmatch.regprog = NULL; def_regmatch.regprog = NULL; - file_line = xmalloc(LSIZE); + char *file_line = xmalloc(LSIZE); if (type != CHECK_PATH && type != FIND_DEFINE // 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; - pat = xmalloc(patlen); + char *pat = xmalloc(patlen); assert(len <= INT_MAX); snprintf(pat, patlen, whole ? "\\<%.*s\\>" : "%.*s", (int)len, ptr); // ignore case according to p_ic, p_scs and pat @@ -3626,23 +3614,23 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool def_regmatch.rm_ic = false; // don't ignore case in define pat. } files = xcalloc((size_t)max_path_depth, sizeof(SearchedFile)); - old_files = max_path_depth; - depth = depth_displayed = -1; + int old_files = max_path_depth; + int depth = depth_displayed = -1; - lnum = start_lnum; + linenr_T lnum = start_lnum; if (end_lnum > curbuf->b_ml.ml_line_count) { end_lnum = curbuf->b_ml.ml_line_count; } if (lnum > end_lnum) { // do at least one line lnum = end_lnum; } - line = get_line_and_copy(lnum, file_line); + char *line = get_line_and_copy(lnum, file_line); - for (;;) { + while (true) { if (incl_regmatch.regprog != NULL - && vim_regexec(&incl_regmatch, line, (colnr_T)0)) { + && vim_regexec(&incl_regmatch, line, 0)) { char *p_fname = (curr_fname == curbuf->b_fname) - ? curbuf->b_ffname : curr_fname; + ? curbuf->b_ffname : curr_fname; if (inc_opt != NULL && strstr(inc_opt, "\\zs") != NULL) { // Use text from '\zs' to '\ze' (or end) of 'include'. @@ -3650,11 +3638,11 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool (size_t)(incl_regmatch.endp[0] - incl_regmatch.startp[0]), FNAME_EXP|FNAME_INCL|FNAME_REL, - 1L, p_fname); + 1, p_fname); } else { // Use text after match with 'include'. new_fname = file_name_in_line(incl_regmatch.endp[0], 0, - FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname, + FNAME_EXP|FNAME_INCL|FNAME_REL, 1, p_fname, NULL); } already_searched = false; @@ -3715,7 +3703,7 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool if (new_fname != NULL) { // using "new_fname" is more reliable, e.g., when // 'includeexpr' is set. - msg_outtrans_attr(new_fname, HL_ATTR(HLF_D)); + msg_outtrans(new_fname, HL_ATTR(HLF_D)); } else { // Isolate the file name. // Include the surrounding "" or <> if present. @@ -3747,9 +3735,9 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool i++; } } - save_char = p[i]; + char save_char = p[i]; p[i] = NUL; - msg_outtrans_attr(p, HL_ATTR(HLF_D)); + msg_outtrans(p, HL_ATTR(HLF_D)); p[i] = save_char; } @@ -3797,14 +3785,14 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool files[depth].lnum = 0; files[depth].matched = false; if (action == ACTION_EXPAND) { - msg_hist_off = true; // reset in msg_trunc_attr() + msg_hist_off = true; // reset in msg_trunc() vim_snprintf(IObuff, IOSIZE, _("Scanning included file: %s"), new_fname); - msg_trunc_attr(IObuff, true, HL_ATTR(HLF_R)); + msg_trunc(IObuff, true, HL_ATTR(HLF_R)); } else if (p_verbose >= 5) { verbose_enter(); - smsg(_("Searching included file %s"), new_fname); + smsg(0, _("Searching included file %s"), new_fname); verbose_leave(); } } @@ -3815,7 +3803,7 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool search_line: define_matched = false; if (def_regmatch.regprog != NULL - && vim_regexec(&def_regmatch, line, (colnr_T)0)) { + && vim_regexec(&def_regmatch, line, 0)) { // Pattern must be first identifier after 'define', so skip // to that position before checking for match of pattern. Also // don't let it match beyond the end of this identifier. @@ -4000,7 +3988,7 @@ search_line: } else if (action == ACTION_SHOW) { show_pat_in_path(line, type, did_show, action, (depth == -1) ? NULL : files[depth].fp, - (depth == -1) ? &lnum : &files[depth].lnum, 1L); + (depth == -1) ? &lnum : &files[depth].lnum, 1); did_show = true; } else { // ":psearch" uses the preview window @@ -4030,7 +4018,7 @@ search_line: curwin->w_cursor.lnum = lnum; check_cursor(); } else { - if (!GETFILE_SUCCESS(getfile(0, (char *)files[depth].name, NULL, true, + if (!GETFILE_SUCCESS(getfile(0, files[depth].name, NULL, true, files[depth].lnum, false))) { break; // failed to jump to file } @@ -4107,7 +4095,7 @@ exit_matched: } already = NULL; } - // End of big for (;;) loop. + // End of big while (true) loop. // Close any files that are still open. for (i = 0; i <= depth; i++) { @@ -4122,9 +4110,9 @@ exit_matched: if (type == CHECK_PATH) { if (!did_show) { if (action != ACTION_SHOW_ALL) { - msg(_("All included files were found")); + msg(_("All included files were found"), 0); } else { - msg(_("No included files")); + msg(_("No included files"), 0); } } } else if (!found @@ -4149,11 +4137,9 @@ fpip_end: } static void show_pat_in_path(char *line, int type, bool did_show, int action, FILE *fp, - linenr_T *lnum, long count) + linenr_T *lnum, int count) FUNC_ATTR_NONNULL_ARG(1, 6) { - char *p; - if (did_show) { msg_putchar('\n'); // cursor below last one } else if (!msg_silent) { @@ -4162,8 +4148,8 @@ 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; } - for (;;) { - p = line + strlen(line) - 1; + while (true) { + char *p = line + strlen(line) - 1; if (fp != NULL) { // We used fgets(), so get rid of newline at end if (p >= line && *p == '\n') { @@ -4175,11 +4161,11 @@ static void show_pat_in_path(char *line, int type, bool did_show, int action, FI *(p + 1) = NUL; } if (action == ACTION_SHOW_ALL) { - snprintf(IObuff, IOSIZE, "%3ld: ", count); // Show match nr. - msg_puts((const char *)IObuff); + snprintf(IObuff, IOSIZE, "%3d: ", count); // Show match nr. + msg_puts(IObuff); snprintf(IObuff, IOSIZE, "%4" PRIdLINENR, *lnum); // Show line nr. // Highlight line numbers. - msg_puts_attr((const char *)IObuff, HL_ATTR(HLF_N)); + msg_puts_attr(IObuff, HL_ATTR(HLF_N)); msg_puts(" "); } msg_prt_line(line, false); |