diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval/funcs.c | 9 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 34 | ||||
-rw-r--r-- | src/nvim/file_search.c | 100 | ||||
-rw-r--r-- | src/nvim/path.c | 16 |
4 files changed, 94 insertions, 65 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index b064379210..28901d6e55 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -2146,6 +2146,9 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) } if (*fname != NUL && !error) { + char *file_to_find = NULL; + char *search_ctx = NULL; + do { if (rettv->v_type == VAR_STRING || rettv->v_type == VAR_LIST) { xfree(fresult); @@ -2156,13 +2159,17 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) find_what, curbuf->b_ffname, (find_what == FINDFILE_DIR ? "" - : curbuf->b_p_sua)); + : curbuf->b_p_sua), + &file_to_find, &search_ctx); first = false; if (fresult != NULL && rettv->v_type == VAR_LIST) { tv_list_append_string(rettv->vval.v_list, fresult, -1); } } while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL); + + xfree(file_to_find); + vim_findfile_cleanup(search_ctx); } if (rettv->v_type == VAR_STRING) { diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 8e55672615..246aa0aace 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -4976,8 +4976,13 @@ void ex_splitview(exarg_T *eap) } if (eap->cmdidx == CMD_sfind || eap->cmdidx == CMD_tabfind) { + char *file_to_find = NULL; + char *search_ctx = NULL; fname = find_file_in_path(eap->arg, strlen(eap->arg), - FNAME_MESS, true, curbuf->b_ffname); + FNAME_MESS, true, curbuf->b_ffname, + &file_to_find, &search_ctx); + xfree(file_to_find); + vim_findfile_cleanup(search_ctx); if (fname == NULL) { goto theend; } @@ -5169,17 +5174,23 @@ static void ex_resize(exarg_T *eap) /// ":find [+command] <file>" command. static void ex_find(exarg_T *eap) { + char *file_to_find = NULL; + char *search_ctx = NULL; char *fname = find_file_in_path(eap->arg, strlen(eap->arg), - FNAME_MESS, true, curbuf->b_ffname); + FNAME_MESS, true, curbuf->b_ffname, + &file_to_find, &search_ctx); if (eap->addr_count > 0) { - // Repeat finding the file "count" times. This matters when it - // appears several times in the path. + // Repeat finding the file "count" times. This matters when it appears + // several times in the path. linenr_T count = eap->line2; while (fname != NULL && --count > 0) { xfree(fname); - fname = find_file_in_path(NULL, 0, FNAME_MESS, false, curbuf->b_ffname); + fname = find_file_in_path(NULL, 0, FNAME_MESS, false, curbuf->b_ffname, + &file_to_find, &search_ctx); } } + xfree(file_to_find); + vim_findfile_cleanup(search_ctx); if (fname == NULL) { return; @@ -5211,18 +5222,17 @@ void do_exedit(exarg_T *eap, win_T *old_curwin) if (*eap->arg == NUL) { // Special case: ":global/pat/visual\NLvi-commands" if (global_busy) { - int rd = RedrawingDisabled; - int nwr = no_wait_return; - int ms = msg_scroll; - if (eap->nextcmd != NULL) { stuffReadbuff(eap->nextcmd); eap->nextcmd = NULL; } + const int save_rd = RedrawingDisabled; RedrawingDisabled = 0; + const int save_nwr = no_wait_return; no_wait_return = 0; need_wait_return = false; + const int save_ms = msg_scroll; msg_scroll = 0; redraw_all_later(UPD_NOT_VALID); pending_exmode_active = true; @@ -5230,9 +5240,9 @@ void do_exedit(exarg_T *eap, win_T *old_curwin) normal_enter(false, true); pending_exmode_active = false; - RedrawingDisabled = rd; - no_wait_return = nwr; - msg_scroll = ms; + RedrawingDisabled = save_rd; + no_wait_return = save_nwr; + msg_scroll = save_ms; } return; } diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 6782c0211b..4f6c3b1918 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -1281,28 +1281,26 @@ static int ff_path_in_stoplist(char *path, int path_len, char **stopdirs_v) /// @param len length of file name /// @param first use count'th matching file name /// @param rel_fname file name searching relative to +/// @param[in,out] file_to_find modified copy of file name +/// @param[in,out] search_ctx state of the search /// /// @return an allocated string for the file name. NULL for error. -char *find_file_in_path(char *ptr, size_t len, int options, int first, char *rel_fname) +char *find_file_in_path(char *ptr, size_t len, int options, int first, char *rel_fname, + char **file_to_find, char **search_ctx) { return find_file_in_path_option(ptr, len, options, first, (*curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path), - FINDFILE_BOTH, rel_fname, curbuf->b_p_sua); + FINDFILE_BOTH, rel_fname, curbuf->b_p_sua, + file_to_find, search_ctx); } -static char *ff_file_to_find = NULL; -static void *fdip_search_ctx = NULL; - #if defined(EXITFREE) void free_findfile(void) { - xfree(ff_file_to_find); - vim_findfile_cleanup(fdip_search_ctx); - xfree(ff_expand_buffer); + XFREE_CLEAR(ff_expand_buffer); } - #endif /// Find the directory name "ptr[len]" in the path. @@ -1316,12 +1314,16 @@ void free_findfile(void) /// @param ptr file name /// @param len length of file name /// @param rel_fname file name searching relative to +/// @param[in,out] file_to_find modified copy of file name +/// @param[in,out] search_ctx state of the search /// /// @return an allocated string for the file name. NULL for error. -char *find_directory_in_path(char *ptr, size_t len, int options, char *rel_fname) +char *find_directory_in_path(char *ptr, size_t len, int options, char *rel_fname, + char **file_to_find, char **search_ctx) { return find_file_in_path_option(ptr, len, options, true, p_cdpath, - FINDFILE_DIR, rel_fname, ""); + FINDFILE_DIR, rel_fname, "", + file_to_find, search_ctx); } /// @param ptr file name @@ -1331,9 +1333,13 @@ char *find_directory_in_path(char *ptr, size_t len, int options, char *rel_fname /// @param find_what FINDFILE_FILE, _DIR or _BOTH /// @param rel_fname file name we are looking relative to. /// @param suffixes list of suffixes, 'suffixesadd' option +/// @param[in,out] file_to_find modified copy of file name +/// @param[in,out] search_ctx_arg state of the search char *find_file_in_path_option(char *ptr, size_t len, int options, int first, char *path_option, - int find_what, char *rel_fname, char *suffixes) + int find_what, char *rel_fname, char *suffixes, char **file_to_find, + char **search_ctx_arg) { + ff_search_ctx_T **search_ctx = (ff_search_ctx_T **)search_ctx_arg; static char *dir; static int did_findfile_init = false; char save_char; @@ -1357,11 +1363,11 @@ char *find_file_in_path_option(char *ptr, size_t len, int options, int first, ch expand_env_esc(ptr, NameBuff, MAXPATHL, false, true, NULL); ptr[len] = save_char; - xfree(ff_file_to_find); - ff_file_to_find = xstrdup(NameBuff); + xfree(*file_to_find); + *file_to_find = xstrdup(NameBuff); if (options & FNAME_UNESC) { // Change all "\ " to " ". - for (ptr = ff_file_to_find; *ptr != NUL; ptr++) { + for (ptr = *file_to_find; *ptr != NUL; ptr++) { if (ptr[0] == '\\' && ptr[1] == ' ') { memmove(ptr, ptr + 1, strlen(ptr)); } @@ -1369,45 +1375,45 @@ char *find_file_in_path_option(char *ptr, size_t len, int options, int first, ch } } - rel_to_curdir = (ff_file_to_find[0] == '.' - && (ff_file_to_find[1] == NUL - || vim_ispathsep(ff_file_to_find[1]) - || (ff_file_to_find[1] == '.' - && (ff_file_to_find[2] == NUL - || vim_ispathsep(ff_file_to_find[2]))))); - if (vim_isAbsName(ff_file_to_find) + rel_to_curdir = ((*file_to_find)[0] == '.' + && ((*file_to_find)[1] == NUL + || vim_ispathsep((*file_to_find)[1]) + || ((*file_to_find)[1] == '.' + && ((*file_to_find)[2] == NUL + || vim_ispathsep((*file_to_find)[2]))))); + if (vim_isAbsName(*file_to_find) // "..", "../path", "." and "./path": don't use the path_option || rel_to_curdir #if defined(MSWIN) // handle "\tmp" as absolute path - || vim_ispathsep(ff_file_to_find[0]) + || vim_ispathsep((*file_to_find)[0]) // handle "c:name" as absolute path - || (ff_file_to_find[0] != NUL && ff_file_to_find[1] == ':') + || ((*file_to_find)[0] != NUL && (*file_to_find)[1] == ':') #endif ) { // Absolute path, no need to use "path_option". // If this is not a first call, return NULL. We already returned a // filename on the first call. if (first == true) { - if (path_with_url(ff_file_to_find)) { - file_name = xstrdup(ff_file_to_find); + if (path_with_url(*file_to_find)) { + file_name = xstrdup(*file_to_find); goto theend; } // When FNAME_REL flag given first use the directory of the file. // Otherwise or when this fails use the current directory. for (int run = 1; run <= 2; run++) { - size_t l = strlen(ff_file_to_find); + size_t l = strlen(*file_to_find); if (run == 1 && rel_to_curdir && (options & FNAME_REL) && rel_fname != NULL && strlen(rel_fname) + l < MAXPATHL) { STRCPY(NameBuff, rel_fname); - STRCPY(path_tail(NameBuff), ff_file_to_find); + STRCPY(path_tail(NameBuff), *file_to_find); l = strlen(NameBuff); } else { - STRCPY(NameBuff, ff_file_to_find); + STRCPY(NameBuff, *file_to_find); run = 2; } @@ -1435,14 +1441,14 @@ char *find_file_in_path_option(char *ptr, size_t len, int options, int first, ch // Otherwise continue to find the next match. if (first == true) { // vim_findfile_free_visited can handle a possible NULL pointer - vim_findfile_free_visited(fdip_search_ctx); + vim_findfile_free_visited(*search_ctx); dir = path_option; did_findfile_init = false; } for (;;) { if (did_findfile_init) { - file_name = vim_findfile(fdip_search_ctx); + file_name = vim_findfile(*search_ctx); if (file_name != NULL) { break; } @@ -1453,8 +1459,8 @@ char *find_file_in_path_option(char *ptr, size_t len, int options, int first, ch if (dir == NULL || *dir == NUL) { // We searched all paths of the option, now we can free the search context. - vim_findfile_cleanup(fdip_search_ctx); - fdip_search_ctx = NULL; + vim_findfile_cleanup(*search_ctx); + *search_ctx = NULL; break; } @@ -1466,10 +1472,10 @@ char *find_file_in_path_option(char *ptr, size_t len, int options, int first, ch // get the stopdir string r_ptr = vim_findfile_stopdir(buf); - fdip_search_ctx = vim_findfile_init(buf, ff_file_to_find, - r_ptr, 100, false, find_what, - fdip_search_ctx, false, rel_fname); - if (fdip_search_ctx != NULL) { + *search_ctx = vim_findfile_init(buf, *file_to_find, + r_ptr, 100, false, find_what, + *search_ctx, false, rel_fname); + if (*search_ctx != NULL) { did_findfile_init = true; } xfree(buf); @@ -1479,19 +1485,15 @@ char *find_file_in_path_option(char *ptr, size_t len, int options, int first, ch if (file_name == NULL && (options & FNAME_MESS)) { if (first == true) { if (find_what == FINDFILE_DIR) { - semsg(_("E344: Can't find directory \"%s\" in cdpath"), - ff_file_to_find); + semsg(_("E344: Can't find directory \"%s\" in cdpath"), *file_to_find); } else { - semsg(_("E345: Can't find file \"%s\" in path"), - ff_file_to_find); + semsg(_("E345: Can't find file \"%s\" in path"), *file_to_find); } } else { if (find_what == FINDFILE_DIR) { - semsg(_("E346: No more directory \"%s\" found in cdpath"), - ff_file_to_find); + semsg(_("E346: No more directory \"%s\" found in cdpath"), *file_to_find); } else { - semsg(_("E347: No more file \"%s\" found in path"), - ff_file_to_find); + semsg(_("E347: No more file \"%s\" found in path"), *file_to_find); } } } @@ -1606,8 +1608,12 @@ int vim_chdirfile(char *fname, CdCause cause) /// Change directory to "new_dir". Search 'cdpath' for relative directory names. int vim_chdir(char *new_dir) { - char *dir_name = find_directory_in_path(new_dir, strlen(new_dir), - FNAME_MESS, curbuf->b_ffname); + char *file_to_find = NULL; + char *search_ctx = NULL; + char *dir_name = find_directory_in_path(new_dir, strlen(new_dir), FNAME_MESS, + curbuf->b_ffname, &file_to_find, &search_ctx); + xfree(file_to_find); + vim_findfile_cleanup(search_ctx); if (dir_name == NULL) { return -1; } diff --git a/src/nvim/path.c b/src/nvim/path.c index 8bd3303166..137a8da2bc 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -1690,8 +1690,11 @@ char *find_file_name_in_path(char *ptr, size_t len, int options, long count, cha } if (options & FNAME_EXP) { - file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS, true, - rel_fname); + char *file_to_find = NULL; + char *search_ctx = NULL; + + file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS, + true, rel_fname, &file_to_find, &search_ctx); // If the file could not be found in a normal way, try applying // 'includeexpr' (unless done already). @@ -1702,7 +1705,7 @@ char *find_file_name_in_path(char *ptr, size_t len, int options, long count, cha ptr = tofree; len = strlen(ptr); file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS, - true, rel_fname); + true, rel_fname, &file_to_find, &search_ctx); } } if (file_name == NULL && (options & FNAME_MESS)) { @@ -1716,9 +1719,12 @@ char *find_file_name_in_path(char *ptr, size_t len, int options, long count, cha // appears several times in the path. while (file_name != NULL && --count > 0) { xfree(file_name); - file_name = - find_file_in_path(ptr, len, options, false, rel_fname); + file_name = find_file_in_path(ptr, len, options, false, rel_fname, + &file_to_find, &search_ctx); } + + xfree(file_to_find); + vim_findfile_cleanup(search_ctx); } else { file_name = xstrnsave(ptr, len); } |