patch 9.1.1122: too many strlen() calls in findfile.c
Problem: too many strlen() calls in findfile.c
Solution: refactor findfile.c and remove calls to strlen()
(John Marriott)
closes: #16595
Signed-off-by: John Marriott <basilisk@internode.on.net>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/findfile.c b/src/findfile.c
index b6ee092..ccb3ef8 100644
--- a/src/findfile.c
+++ b/src/findfile.c
@@ -66,8 +66,8 @@
// the fix part (no wildcards) and the part containing the wildcards
// of the search path
- char_u *ffs_fix_path;
- char_u *ffs_wc_path;
+ string_T ffs_fix_path;
+ string_T ffs_wc_path;
// files/dirs found in the above directory, matched by the first wildcard
// of wc_part
@@ -167,31 +167,31 @@
ff_visited_list_hdr_T *ffsc_dir_visited_list;
ff_visited_list_hdr_T *ffsc_visited_lists_list;
ff_visited_list_hdr_T *ffsc_dir_visited_lists_list;
- char_u *ffsc_file_to_search;
- char_u *ffsc_start_dir;
- char_u *ffsc_fix_path;
- char_u *ffsc_wc_path;
+ string_T ffsc_file_to_search;
+ string_T ffsc_start_dir;
+ string_T ffsc_fix_path;
+ string_T ffsc_wc_path;
int ffsc_level;
- char_u **ffsc_stopdirs_v;
+ string_T *ffsc_stopdirs_v;
int ffsc_find_what;
int ffsc_tagfile;
} ff_search_ctx_T;
// locally needed functions
-static int ff_check_visited(ff_visited_T **, char_u *, char_u *);
+static int ff_check_visited(ff_visited_T **, char_u *, size_t, char_u *, size_t);
static void vim_findfile_free_visited(void *search_ctx_arg);
static void vim_findfile_free_visited_list(ff_visited_list_hdr_T **list_headp);
static void ff_free_visited_list(ff_visited_T *vl);
-static ff_visited_list_hdr_T* ff_get_visited_list(char_u *, ff_visited_list_hdr_T **list_headp);
+static ff_visited_list_hdr_T* ff_get_visited_list(char_u *, size_t, ff_visited_list_hdr_T **list_headp);
static void ff_push(ff_search_ctx_T *search_ctx, ff_stack_T *stack_ptr);
static ff_stack_T *ff_pop(ff_search_ctx_T *search_ctx);
static void ff_clear(ff_search_ctx_T *search_ctx);
static void ff_free_stack_element(ff_stack_T *stack_ptr);
-static ff_stack_T *ff_create_stack_element(char_u *, char_u *, int, int);
-static int ff_path_in_stoplist(char_u *, int, char_u **);
+static ff_stack_T *ff_create_stack_element(char_u *, size_t, char_u *, size_t, int, int);
+static int ff_path_in_stoplist(char_u *, int, string_T *);
-static char_u *ff_expand_buffer = NULL; // used for expanding filenames
+static string_T ff_expand_buffer = {NULL, 0}; // used for expanding filenames
#if 0
/*
@@ -283,6 +283,7 @@
vim_findfile_init(
char_u *path,
char_u *filename,
+ size_t filenamelen,
char_u *stopdirs UNUSED,
int level,
int free_visited,
@@ -294,6 +295,7 @@
char_u *wc_part;
ff_stack_T *sptr;
ff_search_ctx_T *search_ctx;
+ int add_sep;
// If a search context is given by the caller, reuse it, else allocate a
// new one.
@@ -320,19 +322,20 @@
// filename. If no list for the current filename exists, creates a new
// one.
search_ctx->ffsc_visited_list = ff_get_visited_list(filename,
- &search_ctx->ffsc_visited_lists_list);
+ filenamelen, &search_ctx->ffsc_visited_lists_list);
if (search_ctx->ffsc_visited_list == NULL)
goto error_return;
search_ctx->ffsc_dir_visited_list = ff_get_visited_list(filename,
- &search_ctx->ffsc_dir_visited_lists_list);
+ filenamelen, &search_ctx->ffsc_dir_visited_lists_list);
if (search_ctx->ffsc_dir_visited_list == NULL)
goto error_return;
}
- if (ff_expand_buffer == NULL)
+ if (ff_expand_buffer.string == NULL)
{
- ff_expand_buffer = alloc(MAXPATHL);
- if (ff_expand_buffer == NULL)
+ ff_expand_buffer.length = 0;
+ ff_expand_buffer.string = alloc(MAXPATHL);
+ if (ff_expand_buffer.string == NULL)
goto error_return;
}
@@ -348,13 +351,23 @@
if (!vim_isAbsName(rel_fname) && len + 1 < MAXPATHL)
{
// Make the start dir an absolute path name.
- vim_strncpy(ff_expand_buffer, rel_fname, len);
- search_ctx->ffsc_start_dir = FullName_save(ff_expand_buffer, FALSE);
+ vim_strncpy(ff_expand_buffer.string, rel_fname, len);
+ ff_expand_buffer.length = len;
+
+ search_ctx->ffsc_start_dir.string = FullName_save(ff_expand_buffer.string, FALSE);
+ if (search_ctx->ffsc_start_dir.string == NULL)
+ goto error_return;
+ search_ctx->ffsc_start_dir.length = STRLEN(search_ctx->ffsc_start_dir.string);
}
else
- search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
- if (search_ctx->ffsc_start_dir == NULL)
- goto error_return;
+ {
+ search_ctx->ffsc_start_dir.length = len;
+ search_ctx->ffsc_start_dir.string = vim_strnsave(rel_fname,
+ search_ctx->ffsc_start_dir.length);
+ if (search_ctx->ffsc_start_dir.string == NULL)
+ goto error_return;
+ }
+
if (*++path != NUL)
++path;
}
@@ -369,17 +382,21 @@
drive[0] = path[0];
drive[1] = ':';
drive[2] = NUL;
- if (vim_FullName(drive, ff_expand_buffer, MAXPATHL, TRUE) == FAIL)
+ if (vim_FullName(drive, ff_expand_buffer.string, MAXPATHL, TRUE) == FAIL)
goto error_return;
path += 2;
}
else
#endif
- if (mch_dirname(ff_expand_buffer, MAXPATHL) == FAIL)
+ if (mch_dirname(ff_expand_buffer.string, MAXPATHL) == FAIL)
goto error_return;
- search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
- if (search_ctx->ffsc_start_dir == NULL)
+ ff_expand_buffer.length = STRLEN(ff_expand_buffer.string);
+
+ search_ctx->ffsc_start_dir.length = ff_expand_buffer.length;
+ search_ctx->ffsc_start_dir.string = vim_strnsave(ff_expand_buffer.string,
+ search_ctx->ffsc_start_dir.length);
+ if (search_ctx->ffsc_start_dir.string == NULL)
goto error_return;
#ifdef BACKSLASH_IN_FILENAME
@@ -387,8 +404,11 @@
// directory (but not for "//machine/dir"). Only use the drive name.
if ((*path == '/' || *path == '\\')
&& path[1] != path[0]
- && search_ctx->ffsc_start_dir[1] == ':')
- search_ctx->ffsc_start_dir[2] = NUL;
+ && search_ctx->ffsc_start_dir.string[1] == ':')
+ {
+ search_ctx->ffsc_start_dir.string[2] = NUL;
+ search_ctx->ffsc_start_dir.length = 2;
+ }
#endif
}
@@ -410,10 +430,12 @@
walker++;
dircount = 1;
- search_ctx->ffsc_stopdirs_v = ALLOC_ONE(char_u *);
+ search_ctx->ffsc_stopdirs_v = ALLOC_ONE(string_T);
if (search_ctx->ffsc_stopdirs_v != NULL)
{
+ string_T *tmp; // for convenience
+
do
{
char_u *helper;
@@ -422,7 +444,7 @@
helper = walker;
ptr = vim_realloc(search_ctx->ffsc_stopdirs_v,
- (dircount + 1) * sizeof(char_u *));
+ (dircount + 1) * sizeof(string_T));
if (ptr)
search_ctx->ffsc_stopdirs_v = ptr;
else
@@ -431,23 +453,36 @@
walker = vim_strchr(walker, ';');
len = walker ? (size_t)(walker - helper) : STRLEN(helper);
// "" means ascent till top of directory tree.
+
if (*helper != NUL && !vim_isAbsName(helper)
&& len + 1 < MAXPATHL)
{
// Make the stop dir an absolute path name.
- vim_strncpy(ff_expand_buffer, helper, len);
- search_ctx->ffsc_stopdirs_v[dircount-1] =
- FullName_save(ff_expand_buffer, FALSE);
+ vim_strncpy(ff_expand_buffer.string, helper, len);
+ ff_expand_buffer.length = len;
+
+ tmp = &search_ctx->ffsc_stopdirs_v[dircount - 1];
+ tmp->string = FullName_save(ff_expand_buffer.string, FALSE);
+ if (tmp->string != NULL)
+ tmp->length = STRLEN(tmp->string);
}
else
- search_ctx->ffsc_stopdirs_v[dircount-1] =
- vim_strnsave(helper, len);
+ {
+ tmp = &search_ctx->ffsc_stopdirs_v[dircount - 1];
+ tmp->length = len;
+ tmp->string = vim_strnsave(helper, tmp->length);
+ if (tmp->string == NULL)
+ tmp->length = 0;
+ }
if (walker)
walker++;
dircount++;
} while (walker != NULL);
- search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
+
+ tmp = &search_ctx->ffsc_stopdirs_v[dircount - 1];
+ tmp->string = NULL;
+ tmp->length = 0;
}
}
@@ -462,11 +497,14 @@
if (wc_part != NULL)
{
int llevel;
- int len;
char *errpt;
// save the fix part of the path
- search_ctx->ffsc_fix_path = vim_strnsave(path, wc_part - path);
+ search_ctx->ffsc_fix_path.length = (size_t)(wc_part - path);
+ search_ctx->ffsc_fix_path.string = vim_strnsave(path,
+ search_ctx->ffsc_fix_path.length);
+ if (search_ctx->ffsc_fix_path.string == NULL)
+ goto error_return;
/*
* copy wc_path and add restricts to the '**' wildcard.
@@ -477,27 +515,27 @@
* Due to this technique the path looks awful if you print it as a
* string.
*/
- len = 0;
+ ff_expand_buffer.length = 0;
while (*wc_part != NUL)
{
- if (len + 5 >= MAXPATHL)
+ if (ff_expand_buffer.length + 5 >= MAXPATHL)
{
emsg(_(e_path_too_long_for_completion));
break;
}
if (STRNCMP(wc_part, "**", 2) == 0)
{
- ff_expand_buffer[len++] = *wc_part++;
- ff_expand_buffer[len++] = *wc_part++;
+ ff_expand_buffer.string[ff_expand_buffer.length++] = *wc_part++;
+ ff_expand_buffer.string[ff_expand_buffer.length++] = *wc_part++;
llevel = strtol((char *)wc_part, &errpt, 10);
if ((char_u *)errpt != wc_part && llevel > 0 && llevel < 255)
- ff_expand_buffer[len++] = llevel;
+ ff_expand_buffer.string[ff_expand_buffer.length++] = llevel;
else if ((char_u *)errpt != wc_part && llevel == 0)
// restrict is 0 -> remove already added '**'
- len -= 2;
+ ff_expand_buffer.length -= 2;
else
- ff_expand_buffer[len++] = FF_MAX_STAR_STAR_EXPAND;
+ ff_expand_buffer.string[ff_expand_buffer.length++] = FF_MAX_STAR_STAR_EXPAND;
wc_part = (char_u *)errpt;
if (*wc_part != NUL && !vim_ispathsep(*wc_part))
{
@@ -506,107 +544,153 @@
}
}
else
- ff_expand_buffer[len++] = *wc_part++;
+ ff_expand_buffer.string[ff_expand_buffer.length++] = *wc_part++;
}
- ff_expand_buffer[len] = NUL;
- search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
+ ff_expand_buffer.string[ff_expand_buffer.length] = NUL;
- if (search_ctx->ffsc_wc_path == NULL)
+ search_ctx->ffsc_wc_path.length = ff_expand_buffer.length;
+ search_ctx->ffsc_wc_path.string = vim_strnsave(ff_expand_buffer.string,
+ search_ctx->ffsc_wc_path.length);
+ if (search_ctx->ffsc_wc_path.string == NULL)
goto error_return;
}
else
- search_ctx->ffsc_fix_path = vim_strsave(path);
+ {
+ search_ctx->ffsc_fix_path.length = STRLEN(path);
+ search_ctx->ffsc_fix_path.string = vim_strnsave(path,
+ search_ctx->ffsc_fix_path.length);
+ if (search_ctx->ffsc_fix_path.string == NULL)
+ goto error_return;
+ }
- if (search_ctx->ffsc_start_dir == NULL)
+ if (search_ctx->ffsc_start_dir.string == NULL)
{
// store the fix part as startdir.
// This is needed if the parameter path is fully qualified.
- search_ctx->ffsc_start_dir = vim_strsave(search_ctx->ffsc_fix_path);
- if (search_ctx->ffsc_start_dir == NULL)
+ search_ctx->ffsc_start_dir.length = search_ctx->ffsc_fix_path.length;
+ search_ctx->ffsc_start_dir.string = vim_strnsave(search_ctx->ffsc_fix_path.string,
+ search_ctx->ffsc_start_dir.length);
+ if (search_ctx->ffsc_start_dir.string == NULL)
goto error_return;
- search_ctx->ffsc_fix_path[0] = NUL;
+ search_ctx->ffsc_fix_path.string[0] = NUL;
+ search_ctx->ffsc_fix_path.length = 0;
}
// create an absolute path
- if (STRLEN(search_ctx->ffsc_start_dir)
- + STRLEN(search_ctx->ffsc_fix_path) + 3 >= MAXPATHL)
+ if (search_ctx->ffsc_start_dir.length
+ + search_ctx->ffsc_fix_path.length + 3 >= MAXPATHL)
{
emsg(_(e_path_too_long_for_completion));
goto error_return;
}
- STRCPY(ff_expand_buffer, search_ctx->ffsc_start_dir);
- add_pathsep(ff_expand_buffer);
- {
- int eb_len = (int)STRLEN(ff_expand_buffer);
- char_u *buf = alloc(eb_len
- + (int)STRLEN(search_ctx->ffsc_fix_path) + 1);
- STRCPY(buf, ff_expand_buffer);
- STRCPY(buf + eb_len, search_ctx->ffsc_fix_path);
+ add_sep = !after_pathsep(search_ctx->ffsc_start_dir.string,
+ search_ctx->ffsc_start_dir.string + search_ctx->ffsc_start_dir.length);
+ ff_expand_buffer.length = vim_snprintf(
+ (char *)ff_expand_buffer.string,
+ MAXPATHL,
+ "%s%s",
+ search_ctx->ffsc_start_dir.string,
+ add_sep ? PATHSEPSTR : "");
+
+ {
+ size_t bufsize = ff_expand_buffer.length + search_ctx->ffsc_fix_path.length + 1;
+ char_u *buf = alloc(bufsize);
+
+ if (buf == NULL)
+ goto error_return;
+
+ vim_snprintf(
+ (char *)buf,
+ bufsize,
+ "%s%s",
+ ff_expand_buffer.string,
+ search_ctx->ffsc_fix_path.string);
if (mch_isdir(buf))
{
- STRCAT(ff_expand_buffer, search_ctx->ffsc_fix_path);
- add_pathsep(ff_expand_buffer);
+ if (search_ctx->ffsc_fix_path.length > 0)
+ {
+ add_sep = !after_pathsep(search_ctx->ffsc_fix_path.string,
+ search_ctx->ffsc_fix_path.string + search_ctx->ffsc_fix_path.length);
+ ff_expand_buffer.length += vim_snprintf(
+ (char *)ff_expand_buffer.string + ff_expand_buffer.length,
+ MAXPATHL - ff_expand_buffer.length,
+ "%s%s",
+ search_ctx->ffsc_fix_path.string,
+ add_sep ? PATHSEPSTR : "");
+ }
}
else
{
- char_u *p = gettail(search_ctx->ffsc_fix_path);
- char_u *wc_path = NULL;
- char_u *temp = NULL;
- int len = 0;
+ char_u *p = gettail(search_ctx->ffsc_fix_path.string);
+ int len = (int)search_ctx->ffsc_fix_path.length;
- if (p > search_ctx->ffsc_fix_path)
+ if (p > search_ctx->ffsc_fix_path.string)
{
// do not add '..' to the path and start upwards searching
- len = (int)(p - search_ctx->ffsc_fix_path) - 1;
+ len = (int)(p - search_ctx->ffsc_fix_path.string) - 1;
if ((len >= 2
- && STRNCMP(search_ctx->ffsc_fix_path, "..", 2) == 0)
- && (len == 2
- || search_ctx->ffsc_fix_path[2] == PATHSEP))
+ && STRNCMP(search_ctx->ffsc_fix_path.string, "..", 2) == 0)
+ && (len == 2 || search_ctx->ffsc_fix_path.string[2] == PATHSEP))
{
vim_free(buf);
goto error_return;
}
- STRNCAT(ff_expand_buffer, search_ctx->ffsc_fix_path, len);
- add_pathsep(ff_expand_buffer);
- }
- else
- len = (int)STRLEN(search_ctx->ffsc_fix_path);
- if (search_ctx->ffsc_wc_path != NULL)
+ add_sep = !after_pathsep(search_ctx->ffsc_fix_path.string,
+ search_ctx->ffsc_fix_path.string + search_ctx->ffsc_fix_path.length);
+ ff_expand_buffer.length += vim_snprintf(
+ (char *)ff_expand_buffer.string + ff_expand_buffer.length,
+ MAXPATHL - ff_expand_buffer.length,
+ "%.*s%s",
+ len,
+ search_ctx->ffsc_fix_path.string,
+ add_sep ? PATHSEPSTR : "");
+ }
+
+ if (search_ctx->ffsc_wc_path.string != NULL)
{
- wc_path = vim_strsave(search_ctx->ffsc_wc_path);
- temp = alloc(STRLEN(search_ctx->ffsc_wc_path)
- + STRLEN(search_ctx->ffsc_fix_path + len)
- + 1);
- if (temp == NULL || wc_path == NULL)
+ size_t tempsize = (search_ctx->ffsc_fix_path.length - len)
+ + search_ctx->ffsc_wc_path.length
+ + 1;
+ char_u *temp = alloc(tempsize);
+
+ if (temp == NULL)
{
vim_free(buf);
vim_free(temp);
- vim_free(wc_path);
goto error_return;
}
- STRCPY(temp, search_ctx->ffsc_fix_path + len);
- STRCAT(temp, search_ctx->ffsc_wc_path);
- vim_free(search_ctx->ffsc_wc_path);
- vim_free(wc_path);
- search_ctx->ffsc_wc_path = temp;
+ search_ctx->ffsc_wc_path.length = vim_snprintf(
+ (char *)temp,
+ tempsize,
+ "%s%s",
+ search_ctx->ffsc_fix_path.string + len,
+ search_ctx->ffsc_wc_path.string);
+ vim_free(search_ctx->ffsc_wc_path.string);
+ search_ctx->ffsc_wc_path.string = temp;
}
}
vim_free(buf);
}
- sptr = ff_create_stack_element(ff_expand_buffer,
- search_ctx->ffsc_wc_path, level, 0);
+ sptr = ff_create_stack_element(ff_expand_buffer.string,
+ ff_expand_buffer.length,
+ search_ctx->ffsc_wc_path.string,
+ search_ctx->ffsc_wc_path.length,
+ level,
+ 0);
if (sptr == NULL)
goto error_return;
ff_push(search_ctx, sptr);
- search_ctx->ffsc_file_to_search = vim_strsave(filename);
- if (search_ctx->ffsc_file_to_search == NULL)
+ search_ctx->ffsc_file_to_search.length = filenamelen;
+ search_ctx->ffsc_file_to_search.string = vim_strnsave(filename,
+ search_ctx->ffsc_file_to_search.length);
+ if (search_ctx->ffsc_file_to_search.string == NULL)
goto error_return;
return search_ctx;
@@ -628,6 +712,7 @@
vim_findfile_stopdir(char_u *buf)
{
char_u *r_ptr = buf;
+ char_u *r_ptr_end = NULL; // points to NUL at end of string "r_ptr"
while (*r_ptr != NUL && *r_ptr != ';')
{
@@ -635,14 +720,18 @@
{
// Overwrite the escape char,
// use STRLEN(r_ptr) to move the trailing '\0'.
- STRMOVE(r_ptr, r_ptr + 1);
+ if (r_ptr_end == NULL)
+ r_ptr_end = r_ptr + STRLEN(r_ptr);
+ mch_memmove(r_ptr, r_ptr + 1,
+ (size_t)(r_ptr_end - (r_ptr + 1)) + 1); // +1 for NUL
r_ptr++;
+ --r_ptr_end;
}
r_ptr++;
}
if (*r_ptr == ';')
{
- *r_ptr = 0;
+ *r_ptr = NUL;
r_ptr++;
}
else if (*r_ptr == NUL)
@@ -679,14 +768,10 @@
char_u *
vim_findfile(void *search_ctx_arg)
{
- char_u *file_path;
- char_u *rest_of_wildcards;
+ string_T file_path;
+ string_T rest_of_wildcards;
char_u *path_end = NULL;
ff_stack_T *stackp;
- int len;
- int i;
- char_u *p;
- char_u *suf;
ff_search_ctx_T *search_ctx;
if (search_ctx_arg == NULL)
@@ -698,13 +783,13 @@
* filepath is used as buffer for various actions and as the storage to
* return a found filename.
*/
- if ((file_path = alloc(MAXPATHL)) == NULL)
+ if ((file_path.string = alloc(MAXPATHL)) == NULL)
return NULL;
// store the end of the start dir -- needed for upward search
- if (search_ctx->ffsc_start_dir != NULL)
- path_end = &search_ctx->ffsc_start_dir[
- STRLEN(search_ctx->ffsc_start_dir)];
+ if (search_ctx->ffsc_start_dir.string != NULL)
+ path_end = &search_ctx->ffsc_start_dir.string[
+ search_ctx->ffsc_start_dir.length];
// upward search loop
for (;;)
@@ -744,14 +829,17 @@
if (stackp->ffs_filearray == NULL
&& ff_check_visited(&search_ctx->ffsc_dir_visited_list
->ffvl_visited_list,
- stackp->ffs_fix_path, stackp->ffs_wc_path) == FAIL)
+ stackp->ffs_fix_path.string,
+ stackp->ffs_fix_path.length,
+ stackp->ffs_wc_path.string,
+ stackp->ffs_wc_path.length) == FAIL)
{
#ifdef FF_VERBOSE
if (p_verbose >= 5)
{
verbose_enter_scroll();
smsg("Already Searched: %s (%s)",
- stackp->ffs_fix_path, stackp->ffs_wc_path);
+ stackp->ffs_fix_path.string, stackp->ffs_wc_path.string);
// don't overwrite this either
msg_puts("\n");
verbose_leave_scroll();
@@ -765,7 +853,7 @@
{
verbose_enter_scroll();
smsg("Searching: %s (%s)",
- stackp->ffs_fix_path, stackp->ffs_wc_path);
+ stackp->ffs_fix_path.string, stackp->ffs_wc_path.string);
// don't overwrite this either
msg_puts("\n");
verbose_leave_scroll();
@@ -779,7 +867,8 @@
continue;
}
- file_path[0] = NUL;
+ file_path.string[0] = NUL;
+ file_path.length = 0;
/*
* If no filearray till now expand wildcards
@@ -793,17 +882,23 @@
// we use filepath to build the path expand_wildcards() should
// expand.
- dirptrs[0] = file_path;
+ dirptrs[0] = file_path.string;
dirptrs[1] = NULL;
// if we have a start dir copy it in
- if (!vim_isAbsName(stackp->ffs_fix_path)
- && search_ctx->ffsc_start_dir)
+ if (!vim_isAbsName(stackp->ffs_fix_path.string)
+ && search_ctx->ffsc_start_dir.string)
{
- if (STRLEN(search_ctx->ffsc_start_dir) + 1 < MAXPATHL)
+ if (search_ctx->ffsc_start_dir.length + 1 < MAXPATHL)
{
- STRCPY(file_path, search_ctx->ffsc_start_dir);
- add_pathsep(file_path);
+ int add_sep = !after_pathsep(search_ctx->ffsc_start_dir.string,
+ search_ctx->ffsc_start_dir.string + search_ctx->ffsc_start_dir.length);
+ file_path.length = vim_snprintf(
+ (char *)file_path.string,
+ MAXPATHL,
+ "%s%s",
+ search_ctx->ffsc_start_dir.string,
+ add_sep ? PATHSEPSTR : "");
}
else
{
@@ -813,11 +908,16 @@
}
// append the fix part of the search path
- if (STRLEN(file_path) + STRLEN(stackp->ffs_fix_path) + 1
- < MAXPATHL)
+ if (file_path.length + stackp->ffs_fix_path.length + 1 < MAXPATHL)
{
- STRCAT(file_path, stackp->ffs_fix_path);
- add_pathsep(file_path);
+ int add_sep = !after_pathsep(stackp->ffs_fix_path.string,
+ stackp->ffs_fix_path.string + stackp->ffs_fix_path.length);
+ file_path.length += vim_snprintf(
+ (char *)file_path.string + file_path.length,
+ MAXPATHL - file_path.length,
+ "%s%s",
+ stackp->ffs_fix_path.string,
+ add_sep ? PATHSEPSTR : "");
}
else
{
@@ -825,21 +925,23 @@
goto fail;
}
- rest_of_wildcards = stackp->ffs_wc_path;
- if (*rest_of_wildcards != NUL)
+ rest_of_wildcards.string = stackp->ffs_wc_path.string;
+ rest_of_wildcards.length = stackp->ffs_wc_path.length;
+ if (*rest_of_wildcards.string != NUL)
{
- len = (int)STRLEN(file_path);
- if (STRNCMP(rest_of_wildcards, "**", 2) == 0)
+ if (STRNCMP(rest_of_wildcards.string, "**", 2) == 0)
{
+ char_u *p;
+
// pointer to the restrict byte
// The restrict byte is not a character!
- p = rest_of_wildcards + 2;
+ p = rest_of_wildcards.string + 2;
if (*p > 0)
{
(*p)--;
- if (len + 1 < MAXPATHL)
- file_path[len++] = '*';
+ if (file_path.length + 1 < MAXPATHL)
+ file_path.string[file_path.length++] = '*';
else
{
ff_free_stack_element(stackp);
@@ -850,16 +952,23 @@
if (*p == 0)
{
// remove '**<numb> from wildcards
- STRMOVE(rest_of_wildcards, rest_of_wildcards + 3);
+ mch_memmove(rest_of_wildcards.string,
+ rest_of_wildcards.string + 3,
+ (size_t)(rest_of_wildcards.length - 3) + 1); // +1 for NUL
+ rest_of_wildcards.length -= 3;
+ stackp->ffs_wc_path.length = rest_of_wildcards.length;
}
else
- rest_of_wildcards += 3;
+ {
+ rest_of_wildcards.string += 3;
+ rest_of_wildcards.length -= 3;
+ }
if (stackp->ffs_star_star_empty == 0)
{
// if not done before, expand '**' to empty
stackp->ffs_star_star_empty = 1;
- dirptrs[1] = stackp->ffs_fix_path;
+ dirptrs[1] = stackp->ffs_fix_path.string;
}
}
@@ -870,19 +979,27 @@
* pushing every directory returned from expand_wildcards()
* on the stack again for further search.
*/
- while (*rest_of_wildcards
- && !vim_ispathsep(*rest_of_wildcards))
- if (len + 1 < MAXPATHL)
- file_path[len++] = *rest_of_wildcards++;
+ while (*rest_of_wildcards.string
+ && !vim_ispathsep(*rest_of_wildcards.string))
+ {
+ if (file_path.length + 1 < MAXPATHL)
+ {
+ file_path.string[file_path.length++] = *rest_of_wildcards.string++;
+ --rest_of_wildcards.length;
+ }
else
{
ff_free_stack_element(stackp);
goto fail;
}
+ }
- file_path[len] = NUL;
- if (vim_ispathsep(*rest_of_wildcards))
- rest_of_wildcards++;
+ file_path.string[file_path.length] = NUL;
+ if (vim_ispathsep(*rest_of_wildcards.string))
+ {
+ rest_of_wildcards.string++;
+ rest_of_wildcards.length--;
+ }
}
/*
@@ -894,7 +1011,7 @@
stackp->ffs_filearray = ALLOC_ONE(char_u *);
if (stackp->ffs_filearray != NULL
&& (stackp->ffs_filearray[0]
- = vim_strsave(dirptrs[0])) != NULL)
+ = vim_strnsave(dirptrs[0], file_path.length)) != NULL)
stackp->ffs_filearray_size = 1;
else
stackp->ffs_filearray_size = 0;
@@ -912,14 +1029,22 @@
stackp->ffs_stage = 0;
}
else
- rest_of_wildcards = &stackp->ffs_wc_path[
- STRLEN(stackp->ffs_wc_path)];
+ {
+ rest_of_wildcards.string = &stackp->ffs_wc_path.string[
+ stackp->ffs_wc_path.length];
+ rest_of_wildcards.length = 0;
+ }
if (stackp->ffs_stage == 0)
{
+ int i;
+
// this is the first time we work on this directory
- if (*rest_of_wildcards == NUL)
+ if (*rest_of_wildcards.string == NUL)
{
+ size_t len;
+ char_u *suf;
+
/*
* We don't have further wildcards to expand, so we have to
* check for the final file now.
@@ -933,13 +1058,19 @@
// prepare the filename to be checked for existence
// below
- if (STRLEN(stackp->ffs_filearray[i]) + 1
- + STRLEN(search_ctx->ffsc_file_to_search)
- < MAXPATHL)
+ len = STRLEN(stackp->ffs_filearray[i]);
+ if (len + 1 + search_ctx->ffsc_file_to_search.length
+ < MAXPATHL)
{
- STRCPY(file_path, stackp->ffs_filearray[i]);
- add_pathsep(file_path);
- STRCAT(file_path, search_ctx->ffsc_file_to_search);
+ int add_sep = !after_pathsep(stackp->ffs_filearray[i],
+ stackp->ffs_filearray[i] + len);
+ file_path.length = vim_snprintf(
+ (char *)file_path.string,
+ MAXPATHL,
+ "%s%s%s",
+ stackp->ffs_filearray[i],
+ add_sep ? PATHSEPSTR : "",
+ search_ctx->ffsc_file_to_search.string);
}
else
{
@@ -951,7 +1082,6 @@
* Try without extra suffix and then with suffixes
* from 'suffixesadd'.
*/
- len = (int)STRLEN(file_path);
if (search_ctx->ffsc_tagfile)
suf = (char_u *)"";
else
@@ -959,18 +1089,20 @@
for (;;)
{
// if file exists and we didn't already find it
- if ((path_with_url(file_path)
- || (mch_getperm(file_path) >= 0
+ if ((path_with_url(file_path.string)
+ || (mch_getperm(file_path.string) >= 0
&& (search_ctx->ffsc_find_what
== FINDFILE_BOTH
|| ((search_ctx->ffsc_find_what
== FINDFILE_DIR)
- == mch_isdir(file_path)))))
+ == mch_isdir(file_path.string)))))
#ifndef FF_VERBOSE
&& (ff_check_visited(
&search_ctx->ffsc_visited_list
->ffvl_visited_list,
- file_path, (char_u *)"") == OK)
+ file_path.string,
+ file_path.length,
+ (char_u *)"", 0) == OK)
#endif
)
{
@@ -978,13 +1110,14 @@
if (ff_check_visited(
&search_ctx->ffsc_visited_list
->ffvl_visited_list,
- file_path, (char_u *)"") == FAIL)
+ file_path.string,
+ file_path.length,
+ (char_u *)"", 0) == FAIL)
{
if (p_verbose >= 5)
{
verbose_enter_scroll();
- smsg("Already: %s",
- file_path);
+ smsg("Already: %s", file_path.string);
// don't overwrite this either
msg_puts("\n");
verbose_leave_scroll();
@@ -997,34 +1130,42 @@
stackp->ffs_filearray_cur = i + 1;
ff_push(search_ctx, stackp);
- if (!path_with_url(file_path))
- simplify_filename(file_path);
- if (mch_dirname(ff_expand_buffer, MAXPATHL)
+ if (!path_with_url(file_path.string))
+ file_path.length = simplify_filename(file_path.string);
+
+ if (mch_dirname(ff_expand_buffer.string, MAXPATHL)
== OK)
{
- p = shorten_fname(file_path,
- ff_expand_buffer);
+ char_u *p;
+
+ ff_expand_buffer.length = STRLEN(ff_expand_buffer.string);
+ p = shorten_fname(file_path.string,
+ ff_expand_buffer.string);
if (p != NULL)
- STRMOVE(file_path, p);
+ {
+ mch_memmove(file_path.string, p,
+ (size_t)((file_path.string + file_path.length) - p) + 1); // +1 for NUL
+ file_path.length -= (p - file_path.string);
+ }
}
#ifdef FF_VERBOSE
if (p_verbose >= 5)
{
verbose_enter_scroll();
- smsg("HIT: %s", file_path);
+ smsg("HIT: %s", file_path.string);
// don't overwrite this either
msg_puts("\n");
verbose_leave_scroll();
}
#endif
- return file_path;
+ return file_path.string;
}
// Not found or found already, try next suffix.
if (*suf == NUL)
break;
- copy_option_part(&suf, file_path + len,
- MAXPATHL - len, ",");
+ file_path.length += copy_option_part(&suf, file_path.string + file_path.length,
+ MAXPATHL - file_path.length, ",");
}
}
}
@@ -1043,7 +1184,9 @@
ff_push(search_ctx,
ff_create_stack_element(
stackp->ffs_filearray[i],
- rest_of_wildcards,
+ STRLEN(stackp->ffs_filearray[i]),
+ rest_of_wildcards.string,
+ rest_of_wildcards.length,
stackp->ffs_level - 1, 0));
}
}
@@ -1055,68 +1198,83 @@
* if wildcards contains '**' we have to descent till we reach the
* leaves of the directory tree.
*/
- if (STRNCMP(stackp->ffs_wc_path, "**", 2) == 0)
+ if (STRNCMP(stackp->ffs_wc_path.string, "**", 2) == 0)
{
+ int i;
+
for (i = stackp->ffs_filearray_cur;
i < stackp->ffs_filearray_size; ++i)
{
if (fnamecmp(stackp->ffs_filearray[i],
- stackp->ffs_fix_path) == 0)
+ stackp->ffs_fix_path.string) == 0)
continue; // don't repush same directory
if (!mch_isdir(stackp->ffs_filearray[i]))
continue; // not a directory
ff_push(search_ctx,
- ff_create_stack_element(stackp->ffs_filearray[i],
- stackp->ffs_wc_path, stackp->ffs_level - 1, 1));
+ ff_create_stack_element(
+ stackp->ffs_filearray[i],
+ STRLEN(stackp->ffs_filearray[i]),
+ stackp->ffs_wc_path.string,
+ stackp->ffs_wc_path.length,
+ stackp->ffs_level - 1, 1));
}
}
// we are done with the current directory
ff_free_stack_element(stackp);
-
}
// If we reached this, we didn't find anything downwards.
// Let's check if we should do an upward search.
- if (search_ctx->ffsc_start_dir
+ if (search_ctx->ffsc_start_dir.string
&& search_ctx->ffsc_stopdirs_v != NULL && !got_int)
{
ff_stack_T *sptr;
// path_end may point to the NUL or the previous path separator
- int plen = (path_end - search_ctx->ffsc_start_dir)
+ int plen = (path_end - search_ctx->ffsc_start_dir.string)
+ (*path_end != NUL);
// is the last starting directory in the stop list?
- if (ff_path_in_stoplist(search_ctx->ffsc_start_dir,
+ if (ff_path_in_stoplist(search_ctx->ffsc_start_dir.string,
plen, search_ctx->ffsc_stopdirs_v) == TRUE)
break;
// cut of last dir
- while (path_end > search_ctx->ffsc_start_dir
+ while (path_end > search_ctx->ffsc_start_dir.string
&& vim_ispathsep(*path_end))
path_end--;
- while (path_end > search_ctx->ffsc_start_dir
+ while (path_end > search_ctx->ffsc_start_dir.string
&& !vim_ispathsep(path_end[-1]))
path_end--;
- *path_end = 0;
+ *path_end = NUL;
+
+ // we may have shortened search_ctx->ffsc_start_dir, so update it's length
+ search_ctx->ffsc_start_dir.length = (size_t)(path_end - search_ctx->ffsc_start_dir.string);
path_end--;
- if (*search_ctx->ffsc_start_dir == 0)
+ if (*search_ctx->ffsc_start_dir.string == NUL)
break;
- if (STRLEN(search_ctx->ffsc_start_dir) + 1
- + STRLEN(search_ctx->ffsc_fix_path) < MAXPATHL)
+ if (search_ctx->ffsc_start_dir.length + 1
+ + search_ctx->ffsc_fix_path.length < MAXPATHL)
{
- STRCPY(file_path, search_ctx->ffsc_start_dir);
- add_pathsep(file_path);
- STRCAT(file_path, search_ctx->ffsc_fix_path);
+ int add_sep = !after_pathsep(search_ctx->ffsc_start_dir.string,
+ search_ctx->ffsc_start_dir.string + search_ctx->ffsc_start_dir.length);
+ file_path.length = vim_snprintf(
+ (char *)file_path.string,
+ MAXPATHL,
+ "%s%s%s",
+ search_ctx->ffsc_start_dir.string,
+ add_sep ? PATHSEPSTR : "",
+ search_ctx->ffsc_fix_path.string);
}
else
goto fail;
// create a new stack entry
- sptr = ff_create_stack_element(file_path,
- search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0);
+ sptr = ff_create_stack_element(file_path.string, file_path.length,
+ search_ctx->ffsc_wc_path.string, search_ctx->ffsc_wc_path.length,
+ search_ctx->ffsc_level, 0);
if (sptr == NULL)
break;
ff_push(search_ctx, sptr);
@@ -1126,7 +1284,7 @@
}
fail:
- vim_free(file_path);
+ vim_free(file_path.string);
return NULL;
}
@@ -1186,6 +1344,7 @@
static ff_visited_list_hdr_T*
ff_get_visited_list(
char_u *filename,
+ size_t filenamelen,
ff_visited_list_hdr_T **list_headp)
{
ff_visited_list_hdr_T *retptr = NULL;
@@ -1234,7 +1393,7 @@
return NULL;
retptr->ffvl_visited_list = NULL;
- retptr->ffvl_filename = vim_strsave(filename);
+ retptr->ffvl_filename = vim_strnsave(filename, filenamelen);
if (retptr->ffvl_filename == NULL)
{
vim_free(retptr);
@@ -1300,7 +1459,9 @@
ff_check_visited(
ff_visited_T **visited_list,
char_u *fname,
- char_u *wc_path)
+ size_t fnamelen,
+ char_u *wc_path,
+ size_t wc_pathlen)
{
ff_visited_T *vp;
#ifdef UNIX
@@ -1312,20 +1473,24 @@
// device/inode (unix) or the full path name (not Unix).
if (path_with_url(fname))
{
- vim_strncpy(ff_expand_buffer, fname, MAXPATHL - 1);
+ vim_strncpy(ff_expand_buffer.string, fname, fnamelen);
+ ff_expand_buffer.length = fnamelen;
#ifdef UNIX
url = TRUE;
#endif
}
else
{
- ff_expand_buffer[0] = NUL;
+ ff_expand_buffer.string[0] = NUL;
+ ff_expand_buffer.length = 0;
#ifdef UNIX
if (mch_stat((char *)fname, &st) < 0)
-#else
- if (vim_FullName(fname, ff_expand_buffer, MAXPATHL, TRUE) == FAIL)
-#endif
return FAIL;
+#else
+ if (vim_FullName(fname, ff_expand_buffer.string, MAXPATHL, TRUE) == FAIL)
+ return FAIL;
+ ff_expand_buffer.length = STRLEN(ff_expand_buffer.string);
+#endif
}
// check against list of already visited files
@@ -1337,7 +1502,7 @@
&& vp->ffv_ino == st.st_ino)
:
#endif
- fnamecmp(vp->ffv_fname, ff_expand_buffer) == 0
+ fnamecmp(vp->ffv_fname, ff_expand_buffer.string) == 0
)
{
// are the wildcard parts equal
@@ -1351,7 +1516,7 @@
* New file/dir. Add it to the list of visited files/dirs.
*/
vp = alloc(
- offsetof(ff_visited_T, ffv_fname) + STRLEN(ff_expand_buffer) + 1);
+ offsetof(ff_visited_T, ffv_fname) + ff_expand_buffer.length + 1);
if (vp == NULL)
return OK;
@@ -1359,20 +1524,20 @@
if (!url)
{
vp->ffv_dev_valid = TRUE;
- vp->ffv_ino = st.st_ino;
vp->ffv_dev = st.st_dev;
+ vp->ffv_ino = st.st_ino;
vp->ffv_fname[0] = NUL;
}
else
{
vp->ffv_dev_valid = FALSE;
#endif
- STRCPY(vp->ffv_fname, ff_expand_buffer);
+ STRCPY(vp->ffv_fname, ff_expand_buffer.string);
#ifdef UNIX
}
#endif
if (wc_path != NULL)
- vp->ffv_wc_path = vim_strsave(wc_path);
+ vp->ffv_wc_path = vim_strnsave(wc_path, wc_pathlen);
else
vp->ffv_wc_path = NULL;
@@ -1388,7 +1553,9 @@
static ff_stack_T *
ff_create_stack_element(
char_u *fix_part,
+ size_t fix_partlen,
char_u *wc_part,
+ size_t wc_partlen,
int level,
int star_star_empty)
{
@@ -1408,14 +1575,22 @@
// the following saves NULL pointer checks in vim_findfile
if (fix_part == NULL)
+ {
fix_part = (char_u *)"";
- new->ffs_fix_path = vim_strsave(fix_part);
+ fix_partlen = 0;
+ }
+ new->ffs_fix_path.string = vim_strnsave(fix_part, fix_partlen);
+ new->ffs_fix_path.length = fix_partlen;
if (wc_part == NULL)
- wc_part = (char_u *)"";
- new->ffs_wc_path = vim_strsave(wc_part);
+ {
+ wc_part = (char_u *)"";
+ wc_partlen = 0;
+ }
+ new->ffs_wc_path.string = vim_strnsave(wc_part, wc_partlen);
+ new->ffs_wc_path.length = wc_partlen;
- if (new->ffs_fix_path == NULL || new->ffs_wc_path == NULL)
+ if (new->ffs_fix_path.string == NULL || new->ffs_wc_path.string == NULL)
{
ff_free_stack_element(new);
new = NULL;
@@ -1461,9 +1636,9 @@
static void
ff_free_stack_element(ff_stack_T *stack_ptr)
{
- // vim_free handles possible NULL pointers
- vim_free(stack_ptr->ffs_fix_path);
- vim_free(stack_ptr->ffs_wc_path);
+ // VIM_CLEAR_STRING handles possible NULL pointers
+ VIM_CLEAR_STRING(stack_ptr->ffs_fix_path);
+ VIM_CLEAR_STRING(stack_ptr->ffs_wc_path);
if (stack_ptr->ffs_filearray != NULL)
FreeWild(stack_ptr->ffs_filearray_size, stack_ptr->ffs_filearray);
@@ -1483,29 +1658,23 @@
while ((sptr = ff_pop(search_ctx)) != NULL)
ff_free_stack_element(sptr);
- vim_free(search_ctx->ffsc_file_to_search);
- vim_free(search_ctx->ffsc_start_dir);
- vim_free(search_ctx->ffsc_fix_path);
- vim_free(search_ctx->ffsc_wc_path);
-
if (search_ctx->ffsc_stopdirs_v != NULL)
{
int i = 0;
- while (search_ctx->ffsc_stopdirs_v[i] != NULL)
+ while (search_ctx->ffsc_stopdirs_v[i].string != NULL)
{
- vim_free(search_ctx->ffsc_stopdirs_v[i]);
+ vim_free(search_ctx->ffsc_stopdirs_v[i].string);
i++;
}
- vim_free(search_ctx->ffsc_stopdirs_v);
+ VIM_CLEAR(search_ctx->ffsc_stopdirs_v);
}
- search_ctx->ffsc_stopdirs_v = NULL;
// reset everything
- search_ctx->ffsc_file_to_search = NULL;
- search_ctx->ffsc_start_dir = NULL;
- search_ctx->ffsc_fix_path = NULL;
- search_ctx->ffsc_wc_path = NULL;
+ VIM_CLEAR_STRING(search_ctx->ffsc_file_to_search);
+ VIM_CLEAR_STRING(search_ctx->ffsc_start_dir);
+ VIM_CLEAR_STRING(search_ctx->ffsc_fix_path);
+ VIM_CLEAR_STRING(search_ctx->ffsc_wc_path);
search_ctx->ffsc_level = 0;
}
@@ -1514,7 +1683,7 @@
* returns TRUE if yes else FALSE
*/
static int
-ff_path_in_stoplist(char_u *path, int path_len, char_u **stopdirs_v)
+ff_path_in_stoplist(char_u *path, int path_len, string_T *stopdirs_v)
{
int i = 0;
@@ -1526,13 +1695,13 @@
if (path_len == 0)
return TRUE;
- for (i = 0; stopdirs_v[i] != NULL; i++)
+ for (i = 0; stopdirs_v[i].string != NULL; i++)
// match for parent directory. So '/home' also matches
// '/home/rks'. Check for PATHSEP in stopdirs_v[i], else
// '/home/r' would also match '/home/rks'
- if (fnamencmp(stopdirs_v[i], path, path_len) == 0
- && ((int)STRLEN(stopdirs_v[i]) <= path_len
- || vim_ispathsep(stopdirs_v[i][path_len])))
+ if (fnamencmp(stopdirs_v[i].string, path, path_len) == 0
+ && ((int)stopdirs_v[i].length <= path_len
+ || vim_ispathsep(stopdirs_v[i].string[path_len])))
return TRUE;
return FALSE;
@@ -1583,7 +1752,7 @@
void
free_findfile(void)
{
- VIM_CLEAR(ff_expand_buffer);
+ VIM_CLEAR_STRING(ff_expand_buffer);
}
# endif
@@ -1628,9 +1797,7 @@
ff_search_ctx_T **search_ctx = (ff_search_ctx_T **)search_ctx_arg;
static char_u *dir;
static int did_findfile_init = FALSE;
- char_u save_char;
char_u *file_name = NULL;
- char_u *buf = NULL;
int rel_to_curdir;
# ifdef AMIGA
struct Process *proc = (struct Process *)FindTask(0L);
@@ -1639,9 +1806,12 @@
// Avoid a requester here for a volume that doesn't exist.
proc->pr_WindowPtr = (APTR)-1L;
# endif
+ static size_t file_to_findlen = 0;
if (first == TRUE)
{
+ char_u save_char;
+
if (len == 0)
return NULL;
@@ -1652,10 +1822,12 @@
ptr[len] = save_char;
vim_free(*file_to_find);
- *file_to_find = vim_strsave(NameBuff);
+ file_to_findlen = STRLEN(NameBuff);
+ *file_to_find = vim_strnsave(NameBuff, file_to_findlen);
if (*file_to_find == NULL) // out of memory
{
file_name = NULL;
+ file_to_findlen = 0;
goto theend;
}
if (options & FNAME_UNESC)
@@ -1663,7 +1835,11 @@
// Change all "\ " to " ".
for (ptr = *file_to_find; *ptr != NUL; ++ptr)
if (ptr[0] == '\\' && ptr[1] == ' ')
- mch_memmove(ptr, ptr + 1, STRLEN(ptr));
+ {
+ mch_memmove(ptr, ptr + 1,
+ (size_t)((*file_to_find + file_to_findlen) - (ptr + 1)) + 1);
+ --file_to_findlen;
+ }
}
}
@@ -1697,27 +1873,36 @@
{
int l;
int run;
+ size_t rel_fnamelen = 0;
+ char_u *suffix;
if (path_with_url(*file_to_find))
{
- file_name = vim_strsave(*file_to_find);
+ file_name = vim_strnsave(*file_to_find, file_to_findlen);
goto theend;
}
+ if (rel_fname != NULL)
+ rel_fnamelen = STRLEN(rel_fname);
+
// When FNAME_REL flag given first use the directory of the file.
// Otherwise or when this fails use the current directory.
for (run = 1; run <= 2; ++run)
{
- l = (int)STRLEN(*file_to_find);
+ l = (int)file_to_findlen;
if (run == 1
&& rel_to_curdir
&& (options & FNAME_REL)
&& rel_fname != NULL
- && STRLEN(rel_fname) + l < MAXPATHL)
+ && rel_fnamelen + l < MAXPATHL)
{
- STRCPY(NameBuff, rel_fname);
- STRCPY(gettail(NameBuff), *file_to_find);
- l = (int)STRLEN(NameBuff);
+ l = vim_snprintf(
+ (char *)NameBuff,
+ MAXPATHL,
+ "%.*s%s",
+ (int)(gettail(rel_fname) - rel_fname),
+ rel_fname,
+ *file_to_find);
}
else
{
@@ -1727,7 +1912,7 @@
// When the file doesn't exist, try adding parts of
// 'suffixesadd'.
- buf = suffixes;
+ suffix = suffixes;
for (;;)
{
if (mch_getperm(NameBuff) >= 0
@@ -1735,12 +1920,12 @@
|| ((find_what == FINDFILE_DIR)
== mch_isdir(NameBuff))))
{
- file_name = vim_strsave(NameBuff);
+ file_name = vim_strnsave(NameBuff, l);
goto theend;
}
- if (*buf == NUL)
+ if (*suffix == NUL)
break;
- copy_option_part(&buf, NameBuff + l, MAXPATHL - l, ",");
+ l += copy_option_part(&suffix, NameBuff + l, MAXPATHL - l, ",");
}
}
}
@@ -1772,6 +1957,7 @@
}
else
{
+ char_u *buf;
char_u *r_ptr;
if (dir == NULL || *dir == NUL)
@@ -1787,12 +1973,12 @@
break;
// copy next path
- buf[0] = 0;
+ buf[0] = NUL;
copy_option_part(&dir, buf, MAXPATHL, " ,");
// get the stopdir string
r_ptr = vim_findfile_stopdir(buf);
- *search_ctx = vim_findfile_init(buf, *file_to_find,
+ *search_ctx = vim_findfile_init(buf, *file_to_find, file_to_findlen,
r_ptr, 100, FALSE, find_what,
*search_ctx, FALSE, rel_fname);
if (*search_ctx != NULL)
@@ -1963,20 +2149,27 @@
if (file_lnum != NULL)
{
- char_u *p;
- char *line_english = " line ";
- char *line_transl = _(line_msg);
+ char_u *p;
+ char *match_text = " line "; // english
+ size_t match_textlen = 6;
// Get the number after the file name and a separator character.
// Also accept " line 999" with and without the same translation as
// used in last_set_msg().
p = ptr + len;
- if (STRNCMP(p, line_english, STRLEN(line_english)) == 0)
- p += STRLEN(line_english);
- else if (STRNCMP(p, line_transl, STRLEN(line_transl)) == 0)
- p += STRLEN(line_transl);
+ if (STRNCMP(p, match_text, match_textlen) == 0)
+ p += match_textlen;
else
- p = skipwhite(p);
+ {
+ // no match with english, try localized
+ match_text = _(line_msg);
+ match_textlen = STRLEN(match_text);
+
+ if (STRNCMP(p, match_text, match_textlen) == 0)
+ p += match_textlen;
+ else
+ p = skipwhite(p);
+ }
if (*p != NUL)
{
if (!SAFE_isdigit(*p))
@@ -2177,7 +2370,7 @@
is_unique(char_u *maybe_unique, garray_T *gap, int i)
{
int j;
- int candidate_len;
+ int candidate_len = (int)STRLEN(maybe_unique);
int other_path_len;
char_u **other_paths = (char_u **)gap->ga_data;
char_u *rival;
@@ -2187,7 +2380,6 @@
if (j == i)
continue; // don't compare it with itself
- candidate_len = (int)STRLEN(maybe_unique);
other_path_len = (int)STRLEN(other_paths[j]);
if (other_path_len < candidate_len)
continue; // it's different when it's shorter
@@ -2217,50 +2409,60 @@
garray_T *gap)
{
char_u *buf;
+ size_t buflen;
char_u *p;
- int len;
+ size_t curdirlen = 0;
if ((buf = alloc(MAXPATHL)) == NULL)
return;
while (*path_option != NUL)
{
- copy_option_part(&path_option, buf, MAXPATHL, " ,");
+ buflen = copy_option_part(&path_option, buf, MAXPATHL, " ,");
if (buf[0] == '.' && (buf[1] == NUL || vim_ispathsep(buf[1])))
{
+ size_t plen;
+
// Relative to current buffer:
// "/path/file" + "." -> "/path/"
// "/path/file" + "./subdir" -> "/path/subdir"
if (curbuf->b_ffname == NULL)
continue;
p = gettail(curbuf->b_ffname);
- len = (int)(p - curbuf->b_ffname);
- if (len + (int)STRLEN(buf) >= MAXPATHL)
+ plen = (size_t)(p - curbuf->b_ffname);
+ if (plen + buflen >= MAXPATHL)
continue;
if (buf[1] == NUL)
- buf[len] = NUL;
+ buf[plen] = NUL;
else
- STRMOVE(buf + len, buf + 2);
- mch_memmove(buf, curbuf->b_ffname, len);
- simplify_filename(buf);
+ mch_memmove(buf + plen, buf + 2, (buflen - 2) + 1); // +1 for NUL
+ mch_memmove(buf, curbuf->b_ffname, plen);
+ buflen = simplify_filename(buf);
}
else if (buf[0] == NUL)
+ {
// relative to current directory
STRCPY(buf, curdir);
+ if (curdirlen == 0)
+ curdirlen = STRLEN(curdir);
+ buflen = curdirlen;
+ }
else if (path_with_url(buf))
// URL can't be used here
continue;
else if (!mch_isFullName(buf))
{
// Expand relative path to their full path equivalent
- len = (int)STRLEN(curdir);
- if (len + (int)STRLEN(buf) + 3 > MAXPATHL)
+ if (curdirlen == 0)
+ curdirlen = STRLEN(curdir);
+ if (curdirlen + buflen + 3 > MAXPATHL)
continue;
- STRMOVE(buf + len + 1, buf);
+
+ mch_memmove(buf + curdirlen + 1, buf, buflen + 1); // +1 for NUL
STRCPY(buf, curdir);
- buf[len] = PATHSEP;
- simplify_filename(buf);
+ buf[curdirlen] = PATHSEP;
+ buflen = simplify_filename(buf);
}
if (ga_grow(gap, 1) == FAIL)
@@ -2269,12 +2471,11 @@
# if defined(MSWIN)
// Avoid the path ending in a backslash, it fails when a comma is
// appended.
- len = (int)STRLEN(buf);
- if (buf[len - 1] == '\\')
- buf[len - 1] = '/';
+ if (buf[buflen - 1] == '\\')
+ buf[buflen - 1] = '/';
# endif
- p = vim_strsave(buf);
+ p = vim_strnsave(buf, buflen);
if (p == NULL)
break;
((char_u **)gap->ga_data)[gap->ga_len++] = p;
@@ -2360,8 +2561,7 @@
if (file_pattern == NULL)
return;
file_pattern[0] = '*';
- file_pattern[1] = NUL;
- STRCAT(file_pattern, pattern);
+ STRCPY(file_pattern + 1, pattern);
pat = file_pat_to_reg_pat(file_pattern, NULL, NULL, FALSE);
vim_free(file_pattern);
if (pat == NULL)
@@ -2387,14 +2587,13 @@
char_u *path = fnames[i];
int is_in_curdir;
char_u *dir_end = gettail_dir(path);
- char_u *pathsep_p;
char_u *path_cutoff;
len = (int)STRLEN(path);
is_in_curdir = fnamencmp(curdir, path, dir_end - path) == 0
&& curdir[dir_end - path] == NUL;
if (is_in_curdir)
- in_curdir[i] = vim_strsave(path);
+ in_curdir[i] = vim_strnsave(path, len);
// Shorten the filename while maintaining its uniqueness
path_cutoff = get_path_cutoff(path, &path_ga);
@@ -2415,17 +2614,20 @@
{
// Here all files can be reached without path, so get shortest
// unique path. We start at the end of the path.
- pathsep_p = path + len - 1;
+ char_u *pathsep_p = path + len - 1;
while (find_previous_pathsep(path, &pathsep_p))
+ {
if (vim_regexec(®match, pathsep_p + 1, (colnr_T)0)
&& is_unique(pathsep_p + 1, gap, i)
&& path_cutoff != NULL && pathsep_p + 1 >= path_cutoff)
{
sort_again = TRUE;
- mch_memmove(path, pathsep_p + 1, STRLEN(pathsep_p));
+ mch_memmove(path, pathsep_p + 1,
+ (size_t)((path + len) - (pathsep_p + 1)) + 1); // +1 for NUL
break;
}
+ }
}
if (mch_isFullName(path))
@@ -2453,9 +2655,7 @@
# endif
)
{
- STRCPY(path, ".");
- add_pathsep(path);
- STRMOVE(path + STRLEN(path), short_name);
+ vim_snprintf((char *)path, MAXPATHL, ".%s%s", PATHSEPSTR, short_name);
}
}
ui_breakcheck();
@@ -2464,8 +2664,9 @@
// Shorten filenames in /in/current/directory/{filename}
for (i = 0; i < gap->ga_len && !got_int; i++)
{
- char_u *rel_path;
- char_u *path = in_curdir[i];
+ size_t rel_pathsize;
+ char_u *rel_path;
+ char_u *path = in_curdir[i];
if (path == NULL)
continue;
@@ -2481,12 +2682,12 @@
continue;
}
- rel_path = alloc(STRLEN(short_name) + STRLEN(PATHSEPSTR) + 2);
+ rel_pathsize = 1 + STRLEN_LITERAL(PATHSEPSTR) + STRLEN(short_name) + 1;
+ rel_path = alloc(rel_pathsize);
if (rel_path == NULL)
goto theend;
- STRCPY(rel_path, ".");
- add_pathsep(rel_path);
- STRCAT(rel_path, short_name);
+
+ vim_snprintf((char *)rel_path, rel_pathsize, ".%s%s", PATHSEPSTR, short_name);
vim_free(fnames[i]);
fnames[i] = rel_path;
@@ -2561,12 +2762,13 @@
* resulting file name is simplified in place and will either be the same
* length as that supplied, or shorter.
*/
- void
+ size_t
simplify_filename(char_u *filename)
{
#ifndef AMIGA // Amiga doesn't have "..", it uses "/"
int components = 0;
char_u *p, *tail, *start;
+ char_u *p_end; // point to NUL at end of string "p"
int stripping_disabled = FALSE;
int relative = TRUE;
@@ -2584,11 +2786,13 @@
while (vim_ispathsep(*p));
}
start = p; // remember start after "c:/" or "/" or "///"
+ p_end = p + STRLEN(p);
#ifdef UNIX
// Posix says that "//path" is unchanged but "///path" is "/path".
if (start > filename + 2)
{
- STRMOVE(filename + 1, p);
+ mch_memmove(filename + 1, p, (size_t)(p_end - p) + 1); // +1 for NUL
+ p_end -= (size_t)(p - (filename + 1));
start = p = filename + 1;
}
#endif
@@ -2614,8 +2818,11 @@
}
else
# endif
- if (vim_ispathsep(*p))
- STRMOVE(p, p + 1); // remove duplicate "/"
+ if (vim_ispathsep(*p))
+ {
+ mch_memmove(p, p + 1, (size_t)(p_end - (p + 1)) + 1); // remove duplicate "/"
+ --p_end;
+ }
else if (p[0] == '.' && (vim_ispathsep(p[1]) || p[1] == NUL))
{
if (p == start && relative)
@@ -2632,7 +2839,9 @@
MB_PTR_ADV(tail);
else if (p > start)
--p; // strip preceding path separator
- STRMOVE(p, tail);
+
+ mch_memmove(p, tail, (size_t)(p_end - tail) + 1);
+ p_end -= (size_t)(tail - p);
}
}
else if (p[0] == '.' && p[1] == '.' &&
@@ -2748,19 +2957,25 @@
{
if (p > start && tail[-1] == '.')
--p;
- STRMOVE(p, tail); // strip previous component
+
+ mch_memmove(p, tail, (size_t)(p_end - tail) + 1); // strip previous component
+ p_end -= (size_t)(tail - p);
}
--components;
}
}
else if (p == start && !relative) // leading "/.." or "/../"
- STRMOVE(p, tail); // strip ".." or "../"
+ {
+ mch_memmove(p, tail, (size_t)(p_end - tail) + 1); // strip ".." or "../"
+ p_end -= (size_t)(tail - p);
+ }
else
{
if (p == start + 2 && p[-2] == '.') // leading "./../"
{
- STRMOVE(p - 2, p); // strip leading "./"
+ mch_memmove(p - 2, p, (size_t)(p_end - p) + 1); // strip leading "./"
+ p_end -= 2;
tail -= 2;
}
p = tail; // skip to char after ".." or "../"
@@ -2773,6 +2988,8 @@
}
} while (*p != NUL);
#endif // !AMIGA
+
+ return (size_t)(p_end - filename);
}
#if defined(FEAT_EVAL) || defined(PROTO)