diff options
| -rw-r--r-- | src/nvim/buffer.c | 2 | ||||
| -rw-r--r-- | src/nvim/eval.c | 2 | ||||
| -rw-r--r-- | src/nvim/ex_cmds.c | 2 | ||||
| -rw-r--r-- | src/nvim/main.c | 4 | ||||
| -rw-r--r-- | src/nvim/os_unix.c | 56 | ||||
| -rw-r--r-- | src/nvim/path.c | 57 | 
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.  | 
