aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/buffer.c2
-rw-r--r--src/eval.c6
-rw-r--r--src/misc2.c2
-rw-r--r--src/path.c32
-rw-r--r--src/path.h14
-rw-r--r--src/spell.c2
-rw-r--r--test/unit/path.moon23
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'