aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/file_search.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-29 22:39:54 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-29 22:39:54 +0000
commit21cb7d04c387e4198ca8098a884c78b56ffcf4c2 (patch)
tree84fe5690df1551f0bb2bdfe1a13aacd29ebc1de7 /src/nvim/file_search.c
parentd9c904f85a23a496df4eb6be42aa43f007b22d50 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-colorcolchar.tar.gz
rneovim-colorcolchar.tar.bz2
rneovim-colorcolchar.zip
Merge remote-tracking branch 'upstream/master' into colorcolcharcolorcolchar
Diffstat (limited to 'src/nvim/file_search.c')
-rw-r--r--src/nvim/file_search.c185
1 files changed, 93 insertions, 92 deletions
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index e236f23895..460cd48fc5 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_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
-
// File searching functions for 'path', 'tags' and 'cdpath' options.
//
// External visible functions:
@@ -47,31 +44,30 @@
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
+#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "nvim/ascii.h"
+#include "nvim/ascii_defs.h"
#include "nvim/autocmd.h"
-#include "nvim/buffer_defs.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
-#include "nvim/eval/typval_defs.h"
#include "nvim/file_search.h"
#include "nvim/gettext.h"
#include "nvim/globals.h"
-#include "nvim/macros.h"
+#include "nvim/macros_defs.h"
#include "nvim/mbyte.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/option.h"
-#include "nvim/os/fs_defs.h"
+#include "nvim/option_vars.h"
+#include "nvim/os/fs.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
#include "nvim/path.h"
#include "nvim/strings.h"
-#include "nvim/types.h"
-#include "nvim/vim.h"
+#include "nvim/vim_defs.h"
#include "nvim/window.h"
static char *ff_expand_buffer = NULL; // used for expanding filenames
@@ -117,7 +113,7 @@ typedef struct ff_visited {
FileID file_id;
// The memory for this struct is allocated according to the length of
// ffv_fname.
- char ffv_fname[1]; // actually longer
+ char ffv_fname[];
} ff_visited_T;
// We might have to manage several visited lists during a search.
@@ -182,7 +178,8 @@ typedef struct ff_search_ctx_T {
# include "file_search.c.generated.h"
#endif
-static char e_pathtoolong[] = N_("E854: path too long for completion");
+static const char e_path_too_long_for_completion[]
+ = N_("E854: Path too long for completion");
/// Initialization routine for vim_findfile().
///
@@ -293,7 +290,7 @@ void *vim_findfile_init(char *path, char *filename, char *stopdirs, int level, i
xstrlcpy(ff_expand_buffer, rel_fname, len + 1);
search_ctx->ffsc_start_dir = FullName_save(ff_expand_buffer, false);
} else {
- search_ctx->ffsc_start_dir = xstrnsave(rel_fname, len);
+ search_ctx->ffsc_start_dir = xmemdupz(rel_fname, len);
}
if (*++path != NUL) {
path++;
@@ -395,7 +392,7 @@ void *vim_findfile_init(char *path, char *filename, char *stopdirs, int level, i
len = 0;
while (*wc_part != NUL) {
if (len + 5 >= MAXPATHL) {
- emsg(_(e_pathtoolong));
+ emsg(_(e_path_too_long_for_completion));
break;
}
if (strncmp(wc_part, "**", 2) == 0) {
@@ -438,7 +435,7 @@ void *vim_findfile_init(char *path, char *filename, char *stopdirs, int level, i
// create an absolute path
if (strlen(search_ctx->ffsc_start_dir)
+ strlen(search_ctx->ffsc_fix_path) + 3 >= MAXPATHL) {
- emsg(_(e_pathtoolong));
+ emsg(_(e_path_too_long_for_completion));
goto error_return;
}
STRCPY(ff_expand_buffer, search_ctx->ffsc_start_dir);
@@ -576,9 +573,9 @@ char *vim_findfile(void *search_ctx_arg)
}
// upward search loop
- for (;;) {
+ while (true) {
// downward search loop
- for (;;) {
+ while (true) {
// check if user wants to stop the search
os_breakcheck();
if (got_int) {
@@ -614,7 +611,7 @@ char *vim_findfile(void *search_ctx_arg)
#ifdef FF_VERBOSE
if (p_verbose >= 5) {
verbose_enter_scroll();
- smsg("Already Searched: %s (%s)",
+ smsg(0, "Already Searched: %s (%s)",
stackp->ffs_fix_path, stackp->ffs_wc_path);
msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
@@ -625,7 +622,7 @@ char *vim_findfile(void *search_ctx_arg)
#ifdef FF_VERBOSE
} else if (p_verbose >= 5) {
verbose_enter_scroll();
- smsg("Searching: %s (%s)",
+ smsg(0, "Searching: %s (%s)",
stackp->ffs_fix_path, stackp->ffs_wc_path);
msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
@@ -780,7 +777,7 @@ char *vim_findfile(void *search_ctx_arg)
} else {
suf = curbuf->b_p_sua;
}
- for (;;) {
+ while (true) {
// if file exists and we didn't already find it
if ((path_with_url(file_path)
|| (os_path_exists(file_path)
@@ -794,10 +791,10 @@ char *vim_findfile(void *search_ctx_arg)
) {
#ifdef FF_VERBOSE
if (ff_check_visited(&search_ctx->ffsc_visited_list->ffvl_visited_list,
- file_path, (char_u *)"") == FAIL) {
+ file_path, "") == FAIL) {
if (p_verbose >= 5) {
verbose_enter_scroll();
- smsg("Already: %s", file_path);
+ smsg(0, "Already: %s", file_path);
msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
@@ -822,7 +819,7 @@ char *vim_findfile(void *search_ctx_arg)
#ifdef FF_VERBOSE
if (p_verbose >= 5) {
verbose_enter_scroll();
- smsg("HIT: %s", file_path);
+ smsg(0, "HIT: %s", file_path);
msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
@@ -985,7 +982,7 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char *filename,
#ifdef FF_VERBOSE
if (p_verbose >= 5) {
verbose_enter_scroll();
- smsg("ff_get_visited_list: FOUND list for %s", filename);
+ smsg(0, "ff_get_visited_list: FOUND list for %s", filename);
msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
@@ -999,7 +996,7 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char *filename,
#ifdef FF_VERBOSE
if (p_verbose >= 5) {
verbose_enter_scroll();
- smsg("ff_get_visited_list: new list for %s", filename);
+ smsg(0, "ff_get_visited_list: new list for %s", filename);
msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
@@ -1026,8 +1023,6 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char *filename,
static bool ff_wc_equal(char *s1, char *s2)
{
int i, j;
- int c1 = NUL;
- int c2 = NUL;
int prev1 = NUL;
int prev2 = NUL;
@@ -1040,8 +1035,8 @@ static bool ff_wc_equal(char *s1, char *s2)
}
for (i = 0, j = 0; s1[i] != NUL && s2[j] != NUL;) {
- c1 = utf_ptr2char(s1 + i);
- c2 = utf_ptr2char(s2 + j);
+ int c1 = utf_ptr2char(s1 + i);
+ int c2 = utf_ptr2char(s2 + j);
if ((p_fic ? mb_tolower(c1) != mb_tolower(c2) : c1 != c2)
&& (prev1 != '*' || prev2 != '*')) {
@@ -1092,7 +1087,7 @@ static int ff_check_visited(ff_visited_T **visited_list, char *fname, char *wc_p
}
// New file/dir. Add it to the list of visited files/dirs.
- vp = xmalloc(sizeof(ff_visited_T) + strlen(ff_expand_buffer));
+ vp = xmalloc(offsetof(ff_visited_T, ffv_fname) + strlen(ff_expand_buffer) + 1);
if (!url) {
vp->file_id_valid = true;
@@ -1119,28 +1114,28 @@ static int ff_check_visited(ff_visited_T **visited_list, char *fname, char *wc_p
static ff_stack_T *ff_create_stack_element(char *fix_part, char *wc_part, int level,
int star_star_empty)
{
- ff_stack_T *new = xmalloc(sizeof(ff_stack_T));
+ ff_stack_T *stack = xmalloc(sizeof(ff_stack_T));
- new->ffs_prev = NULL;
- new->ffs_filearray = NULL;
- new->ffs_filearray_size = 0;
- new->ffs_filearray_cur = 0;
- new->ffs_stage = 0;
- new->ffs_level = level;
- new->ffs_star_star_empty = star_star_empty;
+ stack->ffs_prev = NULL;
+ stack->ffs_filearray = NULL;
+ stack->ffs_filearray_size = 0;
+ stack->ffs_filearray_cur = 0;
+ stack->ffs_stage = 0;
+ stack->ffs_level = level;
+ stack->ffs_star_star_empty = star_star_empty;
// the following saves NULL pointer checks in vim_findfile
if (fix_part == NULL) {
fix_part = "";
}
- new->ffs_fix_path = xstrdup(fix_part);
+ stack->ffs_fix_path = xstrdup(fix_part);
if (wc_part == NULL) {
wc_part = "";
}
- new->ffs_wc_path = xstrdup(wc_part);
+ stack->ffs_wc_path = xstrdup(wc_part);
- return new;
+ return stack;
}
/// Push a dir on the directory stack.
@@ -1283,28 +1278,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.
@@ -1318,12 +1311,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
@@ -1333,9 +1330,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;
@@ -1343,7 +1344,7 @@ char *find_file_in_path_option(char *ptr, size_t len, int options, int first, ch
char *buf = NULL;
int rel_to_curdir;
- if (rel_fname != NULL && path_with_url((const char *)rel_fname)) {
+ if (rel_fname != NULL && path_with_url(rel_fname)) {
// Do not attempt to search "relative" to a URL. #6009
rel_fname = NULL;
}
@@ -1359,11 +1360,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));
}
@@ -1371,51 +1372,51 @@ 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;
}
// When the file doesn't exist, try adding parts of 'suffixesadd'.
buf = suffixes;
- for (;;) {
+ while (true) {
if ((os_path_exists(NameBuff)
&& (find_what == FINDFILE_BOTH
|| ((find_what == FINDFILE_DIR)
@@ -1437,14 +1438,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 (;;) {
+ while (true) {
if (did_findfile_init) {
- file_name = vim_findfile(fdip_search_ctx);
+ file_name = vim_findfile(*search_ctx);
if (file_name != NULL) {
break;
}
@@ -1455,8 +1456,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;
}
@@ -1468,10 +1469,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);
@@ -1481,19 +1482,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);
}
}
}
@@ -1547,7 +1544,7 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, CdCause cause, bool pre
} else {
tv_dict_add_str(dict, S_LEN("cwd"), new_dir);
}
- tv_dict_add_str(dict, S_LEN("scope"), buf); // -V614
+ tv_dict_add_str(dict, S_LEN("scope"), buf);
tv_dict_add_bool(dict, S_LEN("changed_window"), cause == kCdCauseWindow);
tv_dict_set_keys_readonly(dict);
@@ -1608,8 +1605,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;
}