diff options
-rw-r--r-- | src/buffer.c | 2 | ||||
-rw-r--r-- | src/eval.c | 6 | ||||
-rw-r--r-- | src/misc2.c | 2 | ||||
-rw-r--r-- | src/path.c | 32 | ||||
-rw-r--r-- | src/path.h | 14 | ||||
-rw-r--r-- | src/spell.c | 2 | ||||
-rw-r--r-- | test/unit/path.moon | 23 |
7 files changed, 56 insertions, 25 deletions
diff --git a/src/buffer.c b/src/buffer.c index e084e2e4e4..b417681987 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2713,7 +2713,7 @@ void maketitle(void) off += 2; #endif /* remove the file name */ - p = gettail_sep(buf + off); + p = path_tail_with_seperator(buf + off); if (p == buf + off) /* must be a help buffer */ vim_strncpy(buf + off, (char_u *)_("help"), diff --git a/src/eval.c b/src/eval.c index 60fc381f88..a2bfb19dd4 100644 --- a/src/eval.c +++ b/src/eval.c @@ -11657,7 +11657,7 @@ static int mkdir_recurse(char_u *dir, int prot) /* Get end of directory name in "dir". * We're done when it's "/" or "c:/". */ - p = gettail_sep(dir); + p = path_tail_with_seperator(dir); if (p <= get_past_head(dir)) return OK; @@ -11693,7 +11693,7 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv) else { if (*path_tail(dir) == NUL) /* remove trailing slashes */ - *gettail_sep(dir) = NUL; + *path_tail_with_seperator(dir) = NUL; if (argvars[1].v_type != VAR_UNKNOWN) { if (argvars[2].v_type != VAR_UNKNOWN) @@ -12544,7 +12544,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv) if (!has_trailing_pathsep) { q = p + STRLEN(p); if (after_pathsep(p, q)) - *gettail_sep(p) = NUL; + *path_tail_with_seperator(p) = NUL; } rettv->vval.v_string = p; diff --git a/src/misc2.c b/src/misc2.c index 9c87dd46d4..c43a7e4b90 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -1609,7 +1609,7 @@ int vim_chdirfile(char_u *fname) char_u dir[MAXPATHL]; vim_strncpy(dir, fname, MAXPATHL - 1); - *gettail_sep(dir) = NUL; + *path_tail_with_seperator(dir) = NUL; return os_chdir((char *)dir) == 0 ? OK : FAIL; } #endif diff --git a/src/path.c b/src/path.c index d4abdd03b4..c01b1b9fa2 100644 --- a/src/path.c +++ b/src/path.c @@ -78,21 +78,19 @@ char_u *path_tail(char_u *fname) return tail; } -/* - * Get pointer to tail of "fname", including path separators. Putting a NUL - * here leaves the directory name. Takes care of "c:/" and "//". - * Always returns a valid pointer. - */ -char_u *gettail_sep(char_u *fname) +char_u *path_tail_with_seperator(char_u *fname) { - char_u *p; - char_u *t; - - p = get_past_head(fname); /* don't remove the '/' from "c:/file" */ - t = path_tail(fname); - while (t > p && after_pathsep(fname, t)) - --t; - return t; + assert(fname != NULL); + char_u *past_head; + char_u *tail; + + // Don't remove the '/' from "c:/file". + past_head = get_past_head(fname); + tail = path_tail(fname); + while (tail > past_head && after_pathsep(fname, tail)) { + --tail; + } + return tail; } /* @@ -212,7 +210,7 @@ int dir_of_file_exists(char_u *fname) int c; int retval; - p = gettail_sep(fname); + p = path_tail_with_seperator(fname); if (p == fname) return TRUE; c = *p; @@ -1646,8 +1644,8 @@ int same_directory(char_u *f1, char_u *f2) return FALSE; (void)vim_FullName(f1, ffname, MAXPATHL, FALSE); - t1 = gettail_sep(ffname); - t2 = gettail_sep(f2); + t1 = path_tail_with_seperator(ffname); + t2 = path_tail_with_seperator(f2); return t1 - ffname == t2 - f2 && pathcmp((char *)ffname, (char *)f2, (int)(t1 - ffname)) == 0; } diff --git a/src/path.h b/src/path.h index 8ae475a22f..011736f215 100644 --- a/src/path.h +++ b/src/path.h @@ -19,7 +19,7 @@ typedef enum file_comparison { /// @return Enum of type FileComparison. @see FileComparison. FileComparison path_full_compare(char_u *s1, char_u *s2, int checkname); -/// Get the tail of a path:the file name. +/// Get the tail of a path: the file name. /// /// @param fname A file path. /// @return @@ -29,6 +29,17 @@ FileComparison path_full_compare(char_u *s1, char_u *s2, int checkname); /// - Never NULL. char_u *path_tail(char_u *fname); +/// Get pointer to tail of "fname", including path separators. +/// +/// Takes care of "c:/" and "//". That means `path_tail_with_seperator("dir///file.txt")` +/// will return a pointer to `"///file.txt"`. +/// @param fname A file path. +/// @return +/// - Pointer to the last path seperator of `fname`, if there is any. +/// - `fname` if it contains no path seperator. +/// - Never NULL. +char_u *path_tail_with_seperator(char_u *fname); + int vim_ispathsep(int c); int vim_ispathsep_nocolon(int c); int vim_ispathlistsep(int c); @@ -43,7 +54,6 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u ***file, int flags); void addfile(garray_T *gap, char_u *f, int flags); -char_u *gettail_sep(char_u *fname); char_u *getnextcomp(char_u *fname); char_u *get_past_head(char_u *path); char_u *concat_str(char_u *str1, char_u *str2); diff --git a/src/spell.c b/src/spell.c index fd33809b3a..1a09171491 100644 --- a/src/spell.c +++ b/src/spell.c @@ -8507,7 +8507,7 @@ spell_add_word ( * file. We may need to create the "spell" directory first. We * already checked the runtime directory is writable in * init_spellfile(). */ - if (!dir_of_file_exists(fname) && (p = gettail_sep(fname)) != fname) { + if (!dir_of_file_exists(fname) && (p = path_tail_with_seperator(fname)) != fname) { int c = *p; /* The directory doesn't exist. Try creating it and opening diff --git a/test/unit/path.moon b/test/unit/path.moon index 9004cc241c..efa3a2ce74 100644 --- a/test/unit/path.moon +++ b/test/unit/path.moon @@ -8,6 +8,7 @@ typedef enum file_comparison { } FileComparison; FileComparison path_full_compare(char_u *s1, char_u *s2, int checkname); char_u *path_tail(char_u *fname); +char_u *path_tail_with_seperator(char_u *fname); ]] -- import constants parsed by ffi @@ -62,3 +63,25 @@ describe 'path function', -> it 'returns an empty string if file ends in a slash', -> eq '', path_tail 'directory/' + + describe 'path_tail_with_seperator', -> + path_tail_with_seperator = (file) -> + res = path.path_tail_with_seperator (to_cstr file) + neq NULL, res + ffi.string res + + it 'returns the tail of a file together with its seperator', -> + eq '///file.txt', path_tail_with_seperator 'directory///file.txt' + + it 'returns an empty string when given an empty file name', -> + eq '', path_tail_with_seperator '' + + it 'returns only the seperator if there is a traling seperator', -> + eq '/', path_tail_with_seperator 'some/directory/' + + it 'cuts a leading seperator', -> + eq 'file.txt', path_tail_with_seperator '/file.txt' + eq '', path_tail_with_seperator '/' + + it 'returns the whole file name if there is no seperator', -> + eq 'file.txt', path_tail_with_seperator 'file.txt' |