| #include "../git-compat-util.h" | |
| #include "../strbuf.h" | |
| /* Adapted from libiberty's basename.c. */ | |
| char *gitbasename (char *path) | |
| { | |
| const char *base; | |
| if (path) | |
| skip_dos_drive_prefix(&path); | |
| if (!path || !*path) | |
| /* | |
| * basename(3P) is mis-specified because it returns a | |
| * non-constant pointer even though it is specified to return a | |
| * pointer to internal memory at times. The cast is a result of | |
| * that. | |
| */ | |
| return (char *) "."; | |
| for (base = path; *path; path++) { | |
| 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) | |
| /* | |
| * dirname(3P) is mis-specified because it returns a | |
| * non-constant pointer even though it is specified to return a | |
| * pointer to internal memory at times. The cast is a result of | |
| * that. | |
| */ | |
| return (char *) "."; | |
| 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; | |
| } |