Merge pull request #4441 from cacplate/pr-2842

This commit is contained in:
Felipe Oliveira Carvalho 2016-03-29 16:28:18 -03:00
commit a9e0d734d7
3 changed files with 107 additions and 131 deletions

View File

@ -91,7 +91,6 @@ set(CONV_SOURCES
message.c message.c
misc1.c misc1.c
ops.c ops.c
path.c
regexp.c regexp.c
screen.c screen.c
search.c search.c

View File

@ -166,7 +166,7 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
// Glue together the given directory from $PATH with name and save into // Glue together the given directory from $PATH with name and save into
// buf. // buf.
STRLCPY(buf, path, e - path + 1); STRLCPY(buf, path, e - path + 1);
append_path((char *) buf, (const char *) name, (int)buf_len); append_path((char *) buf, (const char *) name, buf_len);
if (is_executable(buf)) { if (is_executable(buf)) {
// Check if the caller asked for a copy of the path. // Check if the caller asked for a copy of the path.

View File

@ -268,16 +268,13 @@ char_u *shorten_dir(char_u *str)
*/ */
bool dir_of_file_exists(char_u *fname) bool dir_of_file_exists(char_u *fname)
{ {
char_u *p; char_u *p = path_tail_with_sep(fname);
int c; if (p == fname) {
bool retval;
p = path_tail_with_sep(fname);
if (p == fname)
return true; return true;
c = *p; }
char_u c = *p;
*p = NUL; *p = NUL;
retval = os_isdir(fname); bool retval = os_isdir(fname);
*p = c; *p = c;
return retval; return retval;
} }
@ -539,15 +536,10 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
size_t wildoff, int flags, bool didstar) size_t wildoff, int flags, bool didstar)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
char_u *buf;
char_u *p, *s, *e;
int start_len = gap->ga_len; int start_len = gap->ga_len;
char_u *pat; size_t len;
int starts_with_dot;
int matches;
int len;
bool starstar = false; bool starstar = false;
static int stardepth = 0; /* depth for "**" expansion */ static int stardepth = 0; // depth for "**" expansion
/* Expanding "**" may take a long time, check for CTRL-C. */ /* Expanding "**" may take a long time, check for CTRL-C. */
if (stardepth > 0) { if (stardepth > 0) {
@ -558,16 +550,14 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
// Make room for file name. When doing encoding conversion the actual // Make room for file name. When doing encoding conversion the actual
// length may be quite a bit longer, thus use the maximum possible length. // length may be quite a bit longer, thus use the maximum possible length.
buf = xmalloc(MAXPATHL); char_u *buf = xmalloc(MAXPATHL);
/* // Find the first part in the path name that contains a wildcard.
* Find the first part in the path name that contains a wildcard. // When EW_ICASE is set every letter is considered to be a wildcard.
* When EW_ICASE is set every letter is considered to be a wildcard. // Copy it into "buf", including the preceding characters.
* Copy it into "buf", including the preceding characters. char_u *p = buf;
*/ char_u *s = buf;
p = buf; char_u *e = NULL;
s = buf;
e = NULL;
const char_u *path_end = path; const char_u *path_end = path;
while (*path_end != NUL) { while (*path_end != NUL) {
/* May ignore a wildcard that has a backslash before it; it will /* May ignore a wildcard that has a backslash before it; it will
@ -588,7 +578,7 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
e = p; e = p;
} }
if (has_mbyte) { if (has_mbyte) {
len = (*mb_ptr2len)(path_end); len = (size_t)(*mb_ptr2len)(path_end);
STRNCPY(p, path_end, len); STRNCPY(p, path_end, len);
p += len; p += len;
path_end += len; path_end += len;
@ -613,9 +603,9 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
if (p[0] == '*' && p[1] == '*') if (p[0] == '*' && p[1] == '*')
starstar = true; starstar = true;
/* convert the file pattern to a regexp pattern */ // convert the file pattern to a regexp pattern
starts_with_dot = (*s == '.'); int starts_with_dot = (*s == '.');
pat = file_pat_to_reg_pat(s, e, NULL, FALSE); char_u *pat = file_pat_to_reg_pat(s, e, NULL, false);
if (pat == NULL) { if (pat == NULL) {
xfree(buf); xfree(buf);
return 0; return 0;
@ -646,9 +636,9 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
if (!didstar && stardepth < 100 && starstar && e - s == 2 if (!didstar && stardepth < 100 && starstar && e - s == 2
&& *path_end == '/') { && *path_end == '/') {
STRCPY(s, path_end + 1); STRCPY(s, path_end + 1);
++stardepth; stardepth++;
(void)do_path_expand(gap, buf, (int)(s - buf), flags, true); (void)do_path_expand(gap, buf, (size_t)(s - buf), flags, true);
--stardepth; stardepth--;
} }
*s = NUL; *s = NUL;
@ -703,10 +693,11 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
xfree(buf); xfree(buf);
vim_regfree(regmatch.regprog); vim_regfree(regmatch.regprog);
matches = gap->ga_len - start_len; size_t matches = (size_t)(gap->ga_len - start_len);
if (matches > 0) if (matches > 0) {
qsort(((char_u **)gap->ga_data) + start_len, matches, qsort(((char_u **)gap->ga_data) + start_len, matches,
sizeof(char_u *), pstrcmp); sizeof(char_u *), pstrcmp);
}
return matches; return matches;
} }
@ -736,27 +727,24 @@ static int find_previous_pathsep(char_u *path, char_u **psep)
*/ */
static bool is_unique(char_u *maybe_unique, garray_T *gap, int i) static bool is_unique(char_u *maybe_unique, garray_T *gap, int i)
{ {
int candidate_len; char_u **other_paths = (char_u **)gap->ga_data;
int other_path_len;
char_u **other_paths = (char_u **)gap->ga_data;
char_u *rival;
for (int j = 0; j < gap->ga_len; j++) { for (int j = 0; j < gap->ga_len; j++) {
if (j == i) if (j == i) {
continue; /* don't compare it with itself */ continue; // don't compare it with itself
}
candidate_len = (int)STRLEN(maybe_unique); size_t candidate_len = STRLEN(maybe_unique);
other_path_len = (int)STRLEN(other_paths[j]); size_t other_path_len = STRLEN(other_paths[j]);
if (other_path_len < candidate_len) if (other_path_len < candidate_len) {
continue; /* it's different when it's shorter */ continue; // it's different when it's shorter
}
rival = other_paths[j] + other_path_len - candidate_len; char_u *rival = other_paths[j] + other_path_len - candidate_len;
if (fnamecmp(maybe_unique, rival) == 0 if (fnamecmp(maybe_unique, rival) == 0
&& (rival == other_paths[j] || vim_ispathsep(*(rival - 1)))) && (rival == other_paths[j] || vim_ispathsep(*(rival - 1)))) {
return false; /* match */ return false; // match
}
} }
return true; // no match found
return true; /* no match found */
} }
/* /*
@ -770,12 +758,8 @@ static bool is_unique(char_u *maybe_unique, garray_T *gap, int i)
*/ */
static void expand_path_option(char_u *curdir, garray_T *gap) static void expand_path_option(char_u *curdir, garray_T *gap)
{ {
char_u *path_option = *curbuf->b_p_path == NUL char_u *path_option = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path;
? p_path : curbuf->b_p_path; char_u *buf = xmalloc(MAXPATHL);
char_u *buf;
int len;
buf = xmalloc(MAXPATHL);
while (*path_option != NUL) { while (*path_option != NUL) {
copy_option_part(&path_option, buf, MAXPATHL, " ,"); copy_option_part(&path_option, buf, MAXPATHL, " ,");
@ -787,26 +771,27 @@ static void expand_path_option(char_u *curdir, garray_T *gap)
if (curbuf->b_ffname == NULL) if (curbuf->b_ffname == NULL)
continue; continue;
char_u *p = path_tail(curbuf->b_ffname); char_u *p = path_tail(curbuf->b_ffname);
len = (int)(p - curbuf->b_ffname); size_t len = (size_t)(p - curbuf->b_ffname);
if (len + (int)STRLEN(buf) >= MAXPATHL) if (len + STRLEN(buf) >= MAXPATHL) {
continue; continue;
if (buf[1] == NUL) }
if (buf[1] == NUL) {
buf[len] = NUL; buf[len] = NUL;
else } else {
STRMOVE(buf + len, buf + 2); STRMOVE(buf + len, buf + 2);
}
memmove(buf, curbuf->b_ffname, len); memmove(buf, curbuf->b_ffname, len);
simplify_filename(buf); simplify_filename(buf);
} else if (buf[0] == NUL) } else if (buf[0] == NUL) {
/* relative to current directory */ STRCPY(buf, curdir); // relative to current directory
STRCPY(buf, curdir); } else if (path_with_url((char *)buf)) {
else if (path_with_url((char *)buf)) continue; // URL can't be used here
/* URL can't be used here */ } else if (!path_is_absolute_path(buf)) {
continue; // Expand relative path to their full path equivalent
else if (!path_is_absolute_path(buf)) { size_t len = STRLEN(curdir);
/* Expand relative path to their full path equivalent */ if (len + STRLEN(buf) + 3 > MAXPATHL) {
len = (int)STRLEN(curdir);
if (len + (int)STRLEN(buf) + 3 > MAXPATHL)
continue; continue;
}
STRMOVE(buf + len + 1, buf); STRMOVE(buf + len + 1, buf);
STRCPY(buf, curdir); STRCPY(buf, curdir);
buf[len] = PATHSEP; buf[len] = PATHSEP;
@ -860,31 +845,25 @@ static char_u *get_path_cutoff(char_u *fname, garray_T *gap)
*/ */
static void uniquefy_paths(garray_T *gap, char_u *pattern) static void uniquefy_paths(garray_T *gap, char_u *pattern)
{ {
int len; char_u **fnames = (char_u **)gap->ga_data;
char_u **fnames = (char_u **)gap->ga_data;
bool sort_again = false; bool sort_again = false;
char_u *pat;
char_u *file_pattern;
char_u *curdir;
regmatch_T regmatch; regmatch_T regmatch;
garray_T path_ga; garray_T path_ga;
char_u **in_curdir = NULL; char_u **in_curdir = NULL;
char_u *short_name; char_u *short_name;
ga_remove_duplicate_strings(gap); ga_remove_duplicate_strings(gap);
ga_init(&path_ga, (int)sizeof(char_u *), 1); ga_init(&path_ga, (int)sizeof(char_u *), 1);
/* // We need to prepend a '*' at the beginning of file_pattern so that the
* We need to prepend a '*' at the beginning of file_pattern so that the // regex matches anywhere in the path. FIXME: is this valid for all
* regex matches anywhere in the path. FIXME: is this valid for all // possible patterns?
* possible patterns? size_t len = STRLEN(pattern);
*/ char_u *file_pattern = xmalloc(len + 2);
len = (int)STRLEN(pattern);
file_pattern = xmalloc(len + 2);
file_pattern[0] = '*'; file_pattern[0] = '*';
file_pattern[1] = NUL; file_pattern[1] = NUL;
STRCAT(file_pattern, pattern); STRCAT(file_pattern, pattern);
pat = file_pat_to_reg_pat(file_pattern, NULL, NULL, TRUE); char_u *pat = file_pat_to_reg_pat(file_pattern, NULL, NULL, true);
xfree(file_pattern); xfree(file_pattern);
if (pat == NULL) if (pat == NULL)
return; return;
@ -895,11 +874,11 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
if (regmatch.regprog == NULL) if (regmatch.regprog == NULL)
return; return;
curdir = xmalloc(MAXPATHL); char_u *curdir = xmalloc(MAXPATHL);
os_dirname(curdir, MAXPATHL); os_dirname(curdir, MAXPATHL);
expand_path_option(curdir, &path_ga); expand_path_option(curdir, &path_ga);
in_curdir = xcalloc(gap->ga_len, sizeof(char_u *)); in_curdir = xcalloc((size_t)gap->ga_len, sizeof(char_u *));
for (int i = 0; i < gap->ga_len && !got_int; i++) { for (int i = 0; i < gap->ga_len && !got_int; i++) {
char_u *path = fnames[i]; char_u *path = fnames[i];
@ -908,7 +887,7 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
char_u *pathsep_p; char_u *pathsep_p;
char_u *path_cutoff; char_u *path_cutoff;
len = (int)STRLEN(path); len = STRLEN(path);
is_in_curdir = fnamencmp(curdir, path, dir_end - path) == 0 is_in_curdir = fnamencmp(curdir, path, dir_end - path) == 0
&& curdir[dir_end - path] == NUL; && curdir[dir_end - path] == NUL;
if (is_in_curdir) if (is_in_curdir)
@ -1113,9 +1092,8 @@ static bool has_special_wildchar(char_u *p)
int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file, int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
char_u ***file, int flags) char_u ***file, int flags)
{ {
int i;
garray_T ga; garray_T ga;
char_u *p; char_u *p;
static bool recursive = false; static bool recursive = false;
int add_pat; int add_pat;
bool did_expand_in_path = false; bool did_expand_in_path = false;
@ -1140,11 +1118,11 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
* avoids starting the shell for each argument separately. * avoids starting the shell for each argument separately.
* For `=expr` do use the internal function. * For `=expr` do use the internal function.
*/ */
for (i = 0; i < num_pat; i++) { for (int i = 0; i < num_pat; i++) {
if (has_special_wildchar(pat[i]) if (has_special_wildchar(pat[i])
&& !(vim_backtick(pat[i]) && pat[i][1] == '=') && !(vim_backtick(pat[i]) && pat[i][1] == '=')) {
)
return mch_expand_wildcards(num_pat, pat, num_file, file, flags); return mch_expand_wildcards(num_pat, pat, num_file, file, flags);
}
} }
#endif #endif
@ -1155,7 +1133,7 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
*/ */
ga_init(&ga, (int)sizeof(char_u *), 30); ga_init(&ga, (int)sizeof(char_u *), 30);
for (i = 0; i < num_pat; ++i) { for (int i = 0; i < num_pat; ++i) {
add_pat = -1; add_pat = -1;
p = pat[i]; p = pat[i];
@ -1212,7 +1190,9 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
recursive = true; recursive = true;
did_expand_in_path = true; did_expand_in_path = true;
} else { } else {
add_pat = path_expand(&ga, p, flags); size_t tmp_add_pat = path_expand(&ga, p, flags);
assert(tmp_add_pat <= INT_MAX);
add_pat = (int)tmp_add_pat;
} }
} }
} }
@ -1261,14 +1241,12 @@ static int expand_backtick(
int flags /* EW_* flags */ int flags /* EW_* flags */
) )
{ {
char_u *p; char_u *p;
char_u *cmd; char_u *buffer;
char_u *buffer;
int cnt = 0; int cnt = 0;
int i;
/* Create the command: lop off the backticks. */ // Create the command: lop off the backticks.
cmd = vim_strnsave(pat + 1, (int)STRLEN(pat) - 2); char_u *cmd = vim_strnsave(pat + 1, STRLEN(pat) - 2);
if (*cmd == '=') /* `={expr}`: Expand expression */ if (*cmd == '=') /* `={expr}`: Expand expression */
buffer = eval_to_string(cmd + 1, &p, TRUE); buffer = eval_to_string(cmd + 1, &p, TRUE);
@ -1288,7 +1266,7 @@ static int expand_backtick(
++p; ++p;
/* add an entry if it is not empty */ /* add an entry if it is not empty */
if (p > cmd) { if (p > cmd) {
i = *p; char_u i = *p;
*p = NUL; *p = NUL;
addfile(gap, cmd, flags); addfile(gap, cmd, flags);
*p = i; *p = i;
@ -1541,9 +1519,8 @@ find_file_name_in_path (
char_u *rel_fname /* file we are searching relative to */ char_u *rel_fname /* file we are searching relative to */
) )
{ {
char_u *file_name; char_u *file_name;
int c; char_u *tofree = NULL;
char_u *tofree = NULL;
if ((options & FNAME_INCL) && *curbuf->b_p_inex != NUL) { if ((options & FNAME_INCL) && *curbuf->b_p_inex != NUL) {
tofree = eval_includeexpr(ptr, len); tofree = eval_includeexpr(ptr, len);
@ -1554,8 +1531,8 @@ find_file_name_in_path (
} }
if (options & FNAME_EXP) { if (options & FNAME_EXP) {
file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS, file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS, true,
TRUE, rel_fname); rel_fname);
/* /*
* If the file could not be found in a normal way, try applying * If the file could not be found in a normal way, try applying
@ -1572,7 +1549,7 @@ find_file_name_in_path (
} }
} }
if (file_name == NULL && (options & FNAME_MESS)) { if (file_name == NULL && (options & FNAME_MESS)) {
c = ptr[len]; char_u c = ptr[len];
ptr[len] = NUL; ptr[len] = NUL;
EMSG2(_("E447: Can't find file \"%s\" in path"), ptr); EMSG2(_("E447: Can't find file \"%s\" in path"), ptr);
ptr[len] = c; ptr[len] = c;
@ -1631,7 +1608,7 @@ bool vim_isAbsName(char_u *name)
/// @param force is a flag to force expanding even if the path is absolute /// @param force is a flag to force expanding even if the path is absolute
/// ///
/// @return FAIL for failure, OK otherwise /// @return FAIL for failure, OK otherwise
int vim_FullName(const char *fname, char *buf, int len, bool force) int vim_FullName(const char *fname, char *buf, size_t len, bool force)
FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_NONNULL_ARG(2)
{ {
int retval = OK; int retval = OK;
@ -2017,14 +1994,12 @@ int expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u ***file,
*/ */
int match_suffix(char_u *fname) int match_suffix(char_u *fname)
{ {
int fnamelen, setsuflen; #define MAXSUFLEN 30 // maximum length of a file suffix
char_u *setsuf;
#define MAXSUFLEN 30 /* maximum length of a file suffix */
char_u suf_buf[MAXSUFLEN]; char_u suf_buf[MAXSUFLEN];
fnamelen = (int)STRLEN(fname); size_t fnamelen = STRLEN(fname);
setsuflen = 0; size_t setsuflen = 0;
for (setsuf = p_su; *setsuf; ) { for (char_u *setsuf = p_su; *setsuf; ) {
setsuflen = copy_option_part(&setsuf, suf_buf, MAXSUFLEN, ".,"); setsuflen = copy_option_part(&setsuf, suf_buf, MAXSUFLEN, ".,");
if (setsuflen == 0) { if (setsuflen == 0) {
char_u *tail = path_tail(fname); char_u *tail = path_tail(fname);
@ -2035,10 +2010,10 @@ int match_suffix(char_u *fname)
break; break;
} }
} else { } else {
if (fnamelen >= setsuflen if (fnamelen >= setsuflen &&
&& fnamencmp(suf_buf, fname + fnamelen - setsuflen, fnamencmp(suf_buf, fname + fnamelen - setsuflen, setsuflen) == 0) {
(size_t)setsuflen) == 0)
break; break;
}
setsuflen = 0; setsuflen = 0;
} }
} }
@ -2049,7 +2024,7 @@ int match_suffix(char_u *fname)
/// ///
/// @param directory Directory name, relative to current directory. /// @param directory Directory name, relative to current directory.
/// @return `FAIL` for failure, `OK` for success. /// @return `FAIL` for failure, `OK` for success.
int path_full_dir_name(char *directory, char *buffer, int len) int path_full_dir_name(char *directory, char *buffer, size_t len)
{ {
int SUCCESS = 0; int SUCCESS = 0;
int retval = OK; int retval = OK;
@ -2091,10 +2066,10 @@ int path_full_dir_name(char *directory, char *buffer, int len)
// Append to_append to path with a slash in between. // Append to_append to path with a slash in between.
// Append to_append to path with a slash in between. // Append to_append to path with a slash in between.
int append_path(char *path, const char *to_append, int max_len) int append_path(char *path, const char *to_append, size_t max_len)
{ {
int current_length = STRLEN(path); size_t current_length = strlen(path);
int to_append_length = STRLEN(to_append); size_t to_append_length = strlen(to_append);
// Do not append empty strings. // Do not append empty strings.
if (to_append_length == 0) { if (to_append_length == 0) {
@ -2129,12 +2104,14 @@ int append_path(char *path, const char *to_append, int max_len)
/// Expand a given file to its absolute path. /// Expand a given file to its absolute path.
/// ///
/// @param fname The filename which should be expanded. /// @param fname filename which should be expanded.
/// @param buf Buffer to store the absolute path of `fname`. /// @param buf buffer to store the absolute path of "fname".
/// @param len Length of `buf`. /// @param len length of "buf".
/// @param force Also expand when `fname` is already absolute. /// @param force also expand when "fname" is already absolute.
/// @return `FAIL` for failure, `OK` for success. ///
static int path_get_absolute_path(const char_u *fname, char_u *buf, int len, int force) /// @return FAIL for failure, OK for success.
static int path_get_absolute_path(const char_u *fname, char_u *buf,
size_t len, int force)
{ {
char_u *p; char_u *p;
*buf = NUL; *buf = NUL;