aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/path.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/path.c')
-rw-r--r--src/nvim/path.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 1c787e3a1d..31318f6bea 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -51,9 +51,10 @@
/// expanded.
/// @param s2 Second file name.
/// @param checkname When both files don't exist, only compare their names.
+/// @param expandenv Whether to expand environment variables in file names.
/// @return Enum of type FileComparison. @see FileComparison.
FileComparison path_full_compare(char_u *const s1, char_u *const s2,
- const bool checkname)
+ const bool checkname, const bool expandenv)
{
assert(s1 && s2);
char_u exp1[MAXPATHL];
@@ -61,7 +62,11 @@ FileComparison path_full_compare(char_u *const s1, char_u *const s2,
char_u full2[MAXPATHL];
FileID file_id_1, file_id_2;
- expand_env(s1, exp1, MAXPATHL);
+ if (expandenv) {
+ expand_env(s1, exp1, MAXPATHL);
+ } else {
+ xstrlcpy((char *)exp1, (const char *)s1, MAXPATHL - 1);
+ }
bool id_ok_1 = os_fileid((char *)exp1, &file_id_1);
bool id_ok_2 = os_fileid((char *)s2, &file_id_2);
if (!id_ok_1 && !id_ok_2) {
@@ -333,9 +338,9 @@ int path_fnamencmp(const char *const fname1, const char *const fname2,
&& (p_fic ? (c1 != c2 && CH_FOLD(c1) != CH_FOLD(c2)) : c1 != c2)) {
break;
}
- len -= (size_t)MB_PTR2LEN((const char_u *)p1);
- p1 += MB_PTR2LEN((const char_u *)p1);
- p2 += MB_PTR2LEN((const char_u *)p2);
+ len -= (size_t)utfc_ptr2len((const char_u *)p1);
+ p1 += utfc_ptr2len((const char_u *)p1);
+ p2 += utfc_ptr2len((const char_u *)p2);
}
return c1 - c2;
#else
@@ -1115,10 +1120,22 @@ static bool has_env_var(char_u *p)
static bool has_special_wildchar(char_u *p)
{
for (; *p; MB_PTR_ADV(p)) {
- // Allow for escaping
- if (*p == '\\' && p[1] != NUL) {
+ // Disallow line break characters.
+ if (*p == '\r' || *p == '\n') {
+ break;
+ }
+ // Allow for escaping.
+ if (*p == '\\' && p[1] != NUL && p[1] != '\r' && p[1] != '\n') {
p++;
} else if (vim_strchr((char_u *)SPECIAL_WILDCHAR, *p) != NULL) {
+ // A { must be followed by a matching }.
+ if (*p == '{' && vim_strchr(p, '}') == NULL) {
+ continue;
+ }
+ // A quote and backtick must be followed by another one.
+ if ((*p == '`' || *p == '\'') && vim_strchr(p, *p) == NULL) {
+ continue;
+ }
return true;
}
}
@@ -1161,7 +1178,7 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
*/
if (recursive)
#ifdef SPECIAL_WILDCHAR
- return mch_expand_wildcards(num_pat, pat, num_file, file, flags);
+ return os_expand_wildcards(num_pat, pat, num_file, file, flags);
#else
return FAIL;
#endif
@@ -1176,7 +1193,7 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
for (int i = 0; i < num_pat; i++) {
if (has_special_wildchar(pat[i])
&& !(vim_backtick(pat[i]) && pat[i][1] == '=')) {
- return mch_expand_wildcards(num_pat, pat, num_file, file, flags);
+ return os_expand_wildcards(num_pat, pat, num_file, file, flags);
}
}
#endif
@@ -1203,7 +1220,7 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
}
} else {
// First expand environment variables, "~/" and "~user/".
- if (has_env_var(p) || *p == '~') {
+ if ((has_env_var(p) && !(flags & EW_NOTENV)) || *p == '~') {
p = expand_env_save_opt(p, true);
if (p == NULL)
p = pat[i];
@@ -1216,8 +1233,8 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
else if (has_env_var(p) || *p == '~') {
xfree(p);
ga_clear_strings(&ga);
- i = mch_expand_wildcards(num_pat, pat, num_file, file,
- flags | EW_KEEPDOLLAR);
+ i = os_expand_wildcards(num_pat, pat, num_file, file,
+ flags | EW_KEEPDOLLAR);
recursive = false;
return i;
}
@@ -1905,16 +1922,16 @@ int pathcmp(const char *p, const char *q, int maxlen)
: c1 - c2; // no match
}
- i += MB_PTR2LEN((char_u *)p + i);
- j += MB_PTR2LEN((char_u *)q + j);
+ i += utfc_ptr2len((char_u *)p + i);
+ j += utfc_ptr2len((char_u *)q + j);
}
if (s == NULL) { // "i" or "j" ran into "maxlen"
return 0;
}
c1 = PTR2CHAR((char_u *)s + i);
- c2 = PTR2CHAR((char_u *)s + i + MB_PTR2LEN((char_u *)s + i));
- /* ignore a trailing slash, but not "//" or ":/" */
+ c2 = PTR2CHAR((char_u *)s + i + utfc_ptr2len((char_u *)s + i));
+ // ignore a trailing slash, but not "//" or ":/"
if (c2 == NUL
&& i > 0
&& !after_pathsep((char *)s, (char *)s + i)
@@ -1923,10 +1940,12 @@ int pathcmp(const char *p, const char *q, int maxlen)
#else
&& c1 == '/'
#endif
- )
- return 0; /* match with trailing slash */
- if (s == q)
- return -1; /* no match */
+ ) {
+ return 0; // match with trailing slash
+ }
+ if (s == q) {
+ return -1; // no match
+ }
return 1;
}