diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2024-05-24 19:18:11 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2024-05-24 19:18:11 +0000 |
commit | ff7ed8f586589d620a806c3758fac4a47a8e7e15 (patch) | |
tree | 729bbcb92231538fa61dab6c3d890b025484b7f5 /src/nvim/path.c | |
parent | 376914f419eb08fdf4c1a63a77e1f035898a0f10 (diff) | |
parent | 28c04948a1c887a1cc0cb64de79fa32631700466 (diff) | |
download | rneovim-ff7ed8f586589d620a806c3758fac4a47a8e7e15.tar.gz rneovim-ff7ed8f586589d620a806c3758fac4a47a8e7e15.tar.bz2 rneovim-ff7ed8f586589d620a806c3758fac4a47a8e7e15.zip |
Merge remote-tracking branch 'upstream/master' into mix_20240309
Diffstat (limited to 'src/nvim/path.c')
-rw-r--r-- | src/nvim/path.c | 80 |
1 files changed, 46 insertions, 34 deletions
diff --git a/src/nvim/path.c b/src/nvim/path.c index 4de18c7530..d782d1a989 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -62,8 +62,8 @@ enum { /// @return Enum of type FileComparison. @see FileComparison. FileComparison path_full_compare(char *const s1, char *const s2, const bool checkname, const bool expandenv) + FUNC_ATTR_NONNULL_ALL { - assert(s1 && s2); char exp1[MAXPATHL]; char full1[MAXPATHL]; char full2[MAXPATHL]; @@ -134,9 +134,8 @@ char *path_tail(const char *fname) /// - `fname` if it contains no path separator. /// - Never NULL. char *path_tail_with_sep(char *fname) + FUNC_ATTR_NONNULL_ALL { - assert(fname != NULL); - // Don't remove the '/' from "c:/file". char *past_head = get_past_head(fname); char *tail = path_tail(fname); @@ -181,8 +180,8 @@ const char *invocation_path_tail(const char *invocation, size_t *len) /// @return Pointer to first found path separator + 1. /// An empty string, if `fname` doesn't contain a path separator, const char *path_next_component(const char *fname) + FUNC_ATTR_NONNULL_ALL { - assert(fname != NULL); while (*fname != NUL && !vim_ispathsep(*fname)) { MB_PTR_ADV(fname); } @@ -212,6 +211,7 @@ int path_head_length(void) /// - True if path begins with a path head /// - False otherwise bool is_path_head(const char *path) + FUNC_ATTR_NONNULL_ALL { #ifdef MSWIN return isalpha((uint8_t)path[0]) && path[1] == ':'; @@ -224,6 +224,7 @@ bool is_path_head(const char *path) /// Unix: after "/"; Win: after "c:\" /// If there is no head, path is returned. char *get_past_head(const char *path) + FUNC_ATTR_NONNULL_ALL { const char *retval = path; @@ -281,6 +282,7 @@ bool vim_ispathlistsep(int c) /// Must be 1 or more. /// It's done in-place. void shorten_dir_len(char *str, int trim_len) + FUNC_ATTR_NONNULL_ALL { char *tail = path_tail(str); char *d = str; @@ -317,6 +319,7 @@ void shorten_dir_len(char *str, int trim_len) /// Shorten the path of a file from "~/foo/../.bar/fname" to "~/f/../.b/fname" /// It's done in-place. void shorten_dir(char *str) + FUNC_ATTR_NONNULL_ALL { shorten_dir_len(str, 1); } @@ -325,6 +328,7 @@ void shorten_dir(char *str) /// Also returns true if there is no directory name. /// "fname" must be writable!. bool dir_of_file_exists(char *fname) + FUNC_ATTR_NONNULL_ALL { char *p = path_tail_with_sep(fname); if (p == fname) { @@ -795,6 +799,7 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in // Moves "*psep" back to the previous path separator in "path". // Returns FAIL is "*psep" ends up at the beginning of "path". static int find_previous_pathsep(char *path, char **psep) + FUNC_ATTR_NONNULL_ALL { // skip the current separator if (*psep > path && vim_ispathsep(**psep)) { @@ -815,6 +820,7 @@ static int find_previous_pathsep(char *path, char **psep) /// Returns true if "maybe_unique" is unique wrt other_paths in "gap". /// "maybe_unique" is the end portion of "((char **)gap->ga_data)[i]". static bool is_unique(char *maybe_unique, garray_T *gap, int i) + FUNC_ATTR_NONNULL_ALL { char **other_paths = gap->ga_data; @@ -844,6 +850,7 @@ static bool is_unique(char *maybe_unique, garray_T *gap, int i) // TODO(vim): handle upward search (;) and path limiter (**N) notations by // expanding each into their equivalent path(s). static void expand_path_option(char *curdir, garray_T *gap) + FUNC_ATTR_NONNULL_ALL { char *path_option = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; char *buf = xmalloc(MAXPATHL); @@ -899,6 +906,7 @@ static void expand_path_option(char *curdir, garray_T *gap) // fname: /foo/bar/baz/quux.txt // returns: ^this static char *get_path_cutoff(char *fname, garray_T *gap) + FUNC_ATTR_NONNULL_ALL { int maxlen = 0; char **path_part = gap->ga_data; @@ -935,6 +943,7 @@ static char *get_path_cutoff(char *fname, garray_T *gap) /// that they are unique with respect to each other while conserving the part /// that matches the pattern. Beware, this is at least O(n^2) wrt "gap->ga_len". static void uniquefy_paths(garray_T *gap, char *pattern) + FUNC_ATTR_NONNULL_ALL { char **fnames = gap->ga_data; bool sort_again = false; @@ -999,7 +1008,7 @@ static void uniquefy_paths(garray_T *gap, char *pattern) memmove(path, path_cutoff, strlen(path_cutoff) + 1); } else { // Here all files can be reached without path, so get shortest - // unique path. We start at the end of the path. */ + // unique path. We start at the end of the path. char *pathsep_p = path + len - 1; while (find_previous_pathsep(path, &pathsep_p)) { if (vim_regexec(®match, pathsep_p + 1, 0) @@ -1115,6 +1124,7 @@ const char *gettail_dir(const char *const fname) /// /// @param flags EW_* flags static int expand_in_path(garray_T *const gap, char *const pattern, const int flags) + FUNC_ATTR_NONNULL_ALL { garray_T path_ga; @@ -1147,6 +1157,7 @@ static int expand_in_path(garray_T *const gap, char *const pattern, const int fl /// Return true if "p" contains what looks like an environment variable. /// Allowing for escaping. static bool has_env_var(char *p) + FUNC_ATTR_NONNULL_ALL { for (; *p; MB_PTR_ADV(p)) { if (*p == '\\' && p[1] != NUL) { @@ -1163,6 +1174,7 @@ static bool has_env_var(char *p) // Return true if "p" contains a special wildcard character, one that Vim // cannot expand, requires using a shell. static bool has_special_wildchar(char *p, int flags) + FUNC_ATTR_NONNULL_ALL { for (; *p; MB_PTR_ADV(p)) { // Disallow line break characters. @@ -1356,6 +1368,7 @@ void FreeWild(int count, char **files) /// @return true if we can expand this backtick thing here. static bool vim_backtick(char *p) + FUNC_ATTR_NONNULL_ALL { return *p == '`' && *(p + 1) != NUL && *(p + strlen(p) - 1) == '`'; } @@ -1366,6 +1379,7 @@ static bool vim_backtick(char *p) /// /// @param flags EW_* flags static int expand_backtick(garray_T *gap, char *pat, int flags) + FUNC_ATTR_NONNULL_ALL { char *p; char *buffer; @@ -1419,6 +1433,7 @@ static int expand_backtick(garray_T *gap, char *pat, int flags) /// When 'shellslash' set do it the other way around. /// When the path looks like a URL leave it unmodified. void slash_adjust(char *p) + FUNC_ATTR_NONNULL_ALL { if (path_with_url(p)) { return; @@ -1451,6 +1466,7 @@ void slash_adjust(char *p) /// /// @param f filename void addfile(garray_T *gap, char *f, int flags) + FUNC_ATTR_NONNULL_ALL { bool isdir; FileInfo file_info; @@ -1500,6 +1516,7 @@ void addfile(garray_T *gap, char *f, int flags) // resulting file name is simplified in place and will either be the same // length as that supplied, or shorter. void simplify_filename(char *filename) + FUNC_ATTR_NONNULL_ALL { int components = 0; bool stripping_disabled = false; @@ -1757,6 +1774,7 @@ bool path_has_drive_letter(const char *p) // Also check for ":\\", which MS Internet Explorer accepts, return // URL_BACKSLASH. int path_is_url(const char *p) + FUNC_ATTR_NONNULL_ALL { // In the spec ':' is enough to recognize a scheme // https://url.spec.whatwg.org/#scheme-state @@ -1773,6 +1791,7 @@ int path_is_url(const char *p) /// @param fname is the filename to test /// @return URL_SLASH for "name://", URL_BACKSLASH for "name:\\", zero otherwise. int path_with_url(const char *fname) + FUNC_ATTR_NONNULL_ALL { const char *p; @@ -1802,6 +1821,7 @@ int path_with_url(const char *fname) } bool path_with_extension(const char *path, const char *extension) + FUNC_ATTR_NONNULL_ALL { const char *last_dot = strrchr(path, '.'); if (!last_dot) { @@ -1812,6 +1832,7 @@ bool path_with_extension(const char *path, const char *extension) /// Return true if "name" is a full (absolute) path name or URL. bool vim_isAbsName(const char *name) + FUNC_ATTR_NONNULL_ALL { return path_with_url(name) != 0 || path_is_absolute(name); } @@ -1951,6 +1972,7 @@ void path_fix_case(char *name) /// Takes care of multi-byte characters. /// "b" must point to the start of the file name int after_pathsep(const char *b, const char *p) + FUNC_ATTR_NONNULL_ALL { return p > b && vim_ispathsep(p[-1]) && utf_head_off(b, p - 1) == 0; @@ -2240,6 +2262,7 @@ int expand_wildcards(int num_pat, char **pat, int *num_files, char ***files, int /// @return true if "fname" matches with an entry in 'suffixes'. bool match_suffix(char *fname) + FUNC_ATTR_NONNULL_ALL { #define MAXSUFLEN 30 // maximum length of a file suffix char suf_buf[MAXSUFLEN]; @@ -2272,14 +2295,22 @@ bool match_suffix(char *fname) /// @param directory Directory name, relative to current directory. /// @return `FAIL` for failure, `OK` for success. int path_full_dir_name(char *directory, char *buffer, size_t len) + FUNC_ATTR_NONNULL_ALL { - int SUCCESS = 0; - int retval = OK; - if (strlen(directory) == 0) { return os_dirname(buffer, len); } + if (os_realpath(directory, buffer, len) != NULL) { + return OK; + } + + // Path does not exist (yet). For a full path fail, will use the path as-is. + if (path_is_absolute(directory)) { + return FAIL; + } + // For a relative path use the current directory and append the file name. + char old_dir[MAXPATHL]; // Get current directory name. @@ -2287,38 +2318,17 @@ int path_full_dir_name(char *directory, char *buffer, size_t len) return FAIL; } - // We have to get back to the current dir at the end, check if that works. - if (os_chdir(old_dir) != SUCCESS) { + xstrlcpy(buffer, old_dir, len); + if (append_path(buffer, directory, len) == FAIL) { return FAIL; } - if (os_chdir(directory) != SUCCESS) { - // Path does not exist (yet). For a full path fail, - // will use the path as-is. For a relative path use - // the current directory and append the file name. - if (path_is_absolute(directory)) { - // Do not return immediately since we may be in the wrong directory. - retval = FAIL; - } else { - xstrlcpy(buffer, old_dir, len); - append_path(buffer, directory, len); - } - } else if (os_dirname(buffer, len) == FAIL) { - // Do not return immediately since we are in the wrong directory. - retval = FAIL; - } - - if (os_chdir(old_dir) != SUCCESS) { - // That shouldn't happen, since we've tested if it works. - retval = FAIL; - emsg(_(e_prev_dir)); - } - - return retval; + return OK; } // Append to_append to path with a slash in between. int append_path(char *path, const char *to_append, size_t max_len) + FUNC_ATTR_NONNULL_ALL { size_t current_length = strlen(path); size_t to_append_length = strlen(to_append); @@ -2358,6 +2368,7 @@ int append_path(char *path, const char *to_append, size_t max_len) /// /// @return FAIL for failure, OK for success. static int path_to_absolute(const char *fname, char *buf, size_t len, int force) + FUNC_ATTR_NONNULL_ALL { const char *p; *buf = NUL; @@ -2395,6 +2406,7 @@ static int path_to_absolute(const char *fname, char *buf, size_t len, int force) /// /// @return `true` if "fname" is absolute. bool path_is_absolute(const char *fname) + FUNC_ATTR_NONNULL_ALL { #ifdef MSWIN if (*fname == NUL) { @@ -2443,7 +2455,7 @@ void path_guess_exepath(const char *argv0, char *buf, size_t bufsize) if (dir_len + 1 > sizeof(NameBuff)) { continue; } - xstrlcpy(NameBuff, dir, dir_len + 1); + xmemcpyz(NameBuff, dir, dir_len); xstrlcat(NameBuff, PATHSEPSTR, sizeof(NameBuff)); xstrlcat(NameBuff, argv0, sizeof(NameBuff)); if (os_can_exe(NameBuff, NULL, false)) { |