Re: [PATCH v4 2/4] compat/basename: make basename() conform to POSIX
From: Ramsay Jones <hidden>
Date: 2016-06-15 23:07:43
On 12/01/16 07:57, Johannes Schindelin wrote:
quoted hunk ↗ jump to hunk
According to POSIX, basename("/path/") should return "path", not "path/". Likewise, basename(NULL) and basename("") should both return "." to conform. Signed-off-by: Johannes Schindelin <redacted> --- compat/basename.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)diff --git a/compat/basename.c b/compat/basename.c index 9f00421..0f1b0b0 100644 --- a/compat/basename.c +++ b/compat/basename.c@@ -4,10 +4,24 @@ char *gitbasename (char *path) { const char *base; - skip_dos_drive_prefix(&path); + + if (path) + skip_dos_drive_prefix(&path); + + if (!path || !*path) + return "."; + for (base = path; *path; path++) { - if (is_dir_sep(*path)) - base = path + 1; + if (!is_dir_sep(*path)) + continue; + do { + path++; + } while (is_dir_sep(*path)); + if (*path) + base = path; + else + while (--path != base && is_dir_sep(*path)) + *path = '\0'; } return (char *)base; }
I don't suppose it makes much difference, but I find my version
slightly easier to read:
char *gitbasename (char *path)
{
char *p;
if (!path || !*path)
return ".";
/* skip drive designator, if any */
if (has_dos_drive_prefix(path))
path += 2;
if (!*path)
return ".";
/* trim trailing directory separators */
p = path + strlen(path) - 1;
while (is_dir_sep(*p)) {
if (p == path)
return path;
*p-- = '\0';
}
/* find begining of last path component */
while (p > path && !is_dir_sep(*p))
p--;
if (is_dir_sep(*p))
p++;
return p;
}
ATB,
Ramsay Jones