aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/buffer.c2
-rw-r--r--src/nvim/eval.c2
-rw-r--r--src/nvim/ex_cmds.c2
-rw-r--r--src/nvim/main.c4
-rw-r--r--src/nvim/os_unix.c56
-rw-r--r--src/nvim/path.c57
6 files changed, 60 insertions, 63 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index dd20d61f75..11cb7bdeac 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -2253,7 +2253,7 @@ setfname (
}
sfname = vim_strsave(sfname);
#ifdef USE_FNAME_CASE
- fname_case(sfname, 0); /* set correct case for short file name */
+ path_fix_case(sfname); /* set correct case for short file name */
#endif
free(buf->b_ffname);
free(buf->b_sfname);
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index deeca10310..9d8421ef04 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -9895,9 +9895,7 @@ static void f_has(typval_T *argvars, typval_T *rettv)
#if defined(WIN64) || defined(_WIN64)
"win64",
#endif
-#ifndef CASE_INSENSITIVE_FILENAME
"fname_case",
-#endif
#ifdef HAVE_ACL
"acl",
#endif
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 81c7ecab5f..e687eab3c4 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -2563,7 +2563,7 @@ do_ecmd (
sfname = ffname;
#ifdef USE_FNAME_CASE
if (sfname != NULL)
- fname_case(sfname, 0); /* set correct case for sfname */
+ path_fix_case(sfname); // set correct case for sfname
#endif
if ((flags & ECMD_ADDBUF) && (ffname == NULL || *ffname == NUL))
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 55935564b8..a03fd2e8a9 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -1290,8 +1290,8 @@ scripterror:
}
#ifdef USE_FNAME_CASE
- /* Make the case of the file name match the actual file. */
- fname_case(p, 0);
+ // Make the case of the file name match the actual file.
+ path_fix_case(p);
#endif
alist_add(&global_alist, p,
diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c
index 82a43499b4..70cafc62ca 100644
--- a/src/nvim/os_unix.c
+++ b/src/nvim/os_unix.c
@@ -69,62 +69,6 @@ static int selinux_enabled = -1;
# include "os_unix.c.generated.h"
#endif
-#if defined(USE_FNAME_CASE)
-/*
- * Set the case of the file name, if it already exists. This will cause the
- * file name to remain exactly the same.
- * Only required for file systems where case is ignored and preserved.
- */
-void fname_case(
-char_u *name,
-int len /* buffer size, only used when name gets longer */
-)
-{
- char_u *slash, *tail;
- DIR *dirp;
- struct dirent *dp;
-
- FileInfo file_info;
- if (os_fileinfo_link((char *)name, &file_info)) {
- /* Open the directory where the file is located. */
- slash = vim_strrchr(name, '/');
- if (slash == NULL) {
- dirp = opendir(".");
- tail = name;
- } else {
- *slash = NUL;
- dirp = opendir((char *)name);
- *slash = '/';
- tail = slash + 1;
- }
-
- if (dirp != NULL) {
- while ((dp = readdir(dirp)) != NULL) {
- /* Only accept names that differ in case and are the same byte
- * length. TODO: accept different length name. */
- if (STRICMP(tail, dp->d_name) == 0
- && STRLEN(tail) == STRLEN(dp->d_name)) {
- char_u newname[MAXPATHL + 1];
-
- /* Verify the inode is equal. */
- STRLCPY(newname, name, MAXPATHL + 1);
- STRLCPY(newname + (tail - name), dp->d_name,
- MAXPATHL - (tail - name) + 1);
- FileInfo file_info_new;
- if (os_fileinfo_link((char *)newname, &file_info_new)
- && os_fileinfo_id_equal(&file_info, &file_info_new)) {
- STRCPY(tail, dp->d_name);
- break;
- }
- }
- }
-
- closedir(dirp);
- }
- }
-}
-#endif
-
#if defined(HAVE_ACL)
# ifdef HAVE_SYS_ACL_H
# include <sys/acl.h>
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 25ed2e3fd8..e83b4e44ed 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -1617,13 +1617,68 @@ char_u *fix_fname(char_u *fname)
fname = vim_strsave(fname);
# ifdef USE_FNAME_CASE
- fname_case(fname, 0); // set correct case for file name
+ path_fix_case(fname); // set correct case for file name
# endif
return fname;
#endif
}
+/// Set the case of the file name, if it already exists. This will cause the
+/// file name to remain exactly the same.
+/// Only required for file systems where case is ignored and preserved.
+// TODO(SplinterOfChaos): Could also be used when mounting case-insensitive
+// file systems.
+void path_fix_case(char_u *name)
+ FUNC_ATTR_NONNULL_ALL
+{
+ FileInfo file_info;
+ if (!os_fileinfo_link((char *)name, &file_info)) {
+ return;
+ }
+
+ // Open the directory where the file is located.
+ char_u *slash = vim_strrchr(name, '/');
+ char_u *tail;
+ Directory dir;
+ bool ok;
+ if (slash == NULL) {
+ ok = os_scandir(&dir, ".");
+ tail = name;
+ } else {
+ *slash = NUL;
+ ok = os_scandir(&dir, (char *) name);
+ *slash = '/';
+ tail = slash + 1;
+ }
+
+ if (!ok) {
+ return;
+ }
+
+ char_u *entry;
+ while ((entry = (char_u *) os_scandir_next(&dir))) {
+ // Only accept names that differ in case and are the same byte
+ // length. TODO: accept different length name.
+ if (STRICMP(tail, entry) == 0 && STRLEN(tail) == STRLEN(entry)) {
+ char_u newname[MAXPATHL + 1];
+
+ // Verify the inode is equal.
+ STRLCPY(newname, name, MAXPATHL + 1);
+ STRLCPY(newname + (tail - name), entry,
+ MAXPATHL - (tail - name) + 1);
+ FileInfo file_info_new;
+ if (os_fileinfo_link((char *)newname, &file_info_new)
+ && os_fileinfo_id_equal(&file_info, &file_info_new)) {
+ STRCPY(tail, entry);
+ break;
+ }
+ }
+ }
+
+ os_closedir(&dir);
+}
+
/*
* Return TRUE if "p" points to just after a path separator.
* Takes care of multi-byte characters.