Browse Source
dirname() emulation has been added, as Msys2 lacks it. * js/dirname-basename: mingw: avoid linking to the C library's isalpha() t0060: loosen overly strict expectations t0060: verify that basename() and dirname() work as expected compat/basename.c: provide a dirname() compatibility function compat/basename: make basename() conform to POSIX Refactor skipping DOS drive prefixesmaint
Junio C Hamano
9 years ago
7 changed files with 225 additions and 24 deletions
@ -1,15 +1,71 @@
@@ -1,15 +1,71 @@
|
||||
#include "../git-compat-util.h" |
||||
#include "../strbuf.h" |
||||
|
||||
/* Adapted from libiberty's basename.c. */ |
||||
char *gitbasename (char *path) |
||||
{ |
||||
const char *base; |
||||
/* Skip over the disk name in MSDOS pathnames. */ |
||||
if (has_dos_drive_prefix(path)) |
||||
path += 2; |
||||
|
||||
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; |
||||
} |
||||
|
||||
char *gitdirname(char *path) |
||||
{ |
||||
static struct strbuf buf = STRBUF_INIT; |
||||
char *p = path, *slash = NULL, c; |
||||
int dos_drive_prefix; |
||||
|
||||
if (!p) |
||||
return "."; |
||||
|
||||
if ((dos_drive_prefix = skip_dos_drive_prefix(&p)) && !*p) |
||||
goto dot; |
||||
|
||||
/* |
||||
* POSIX.1-2001 says dirname("/") should return "/", and dirname("//") |
||||
* should return "//", but dirname("///") should return "/" again. |
||||
*/ |
||||
if (is_dir_sep(*p)) { |
||||
if (!p[1] || (is_dir_sep(p[1]) && !p[2])) |
||||
return path; |
||||
slash = ++p; |
||||
} |
||||
while ((c = *(p++))) |
||||
if (is_dir_sep(c)) { |
||||
char *tentative = p - 1; |
||||
|
||||
/* POSIX.1-2001 says to ignore trailing slashes */ |
||||
while (is_dir_sep(*p)) |
||||
p++; |
||||
if (*p) |
||||
slash = tentative; |
||||
} |
||||
|
||||
if (slash) { |
||||
*slash = '\0'; |
||||
return path; |
||||
} |
||||
|
||||
dot: |
||||
strbuf_reset(&buf); |
||||
strbuf_addf(&buf, "%.*s.", dos_drive_prefix, path); |
||||
return buf.buf; |
||||
} |
||||
|
Loading…
Reference in new issue