1#include "../git-compat-util.h"
2#include "../strbuf.h"
3
4/* Adapted from libiberty's basename.c. */
5char *gitbasename (char *path)
6{
7 const char *base;
8
9 if (path)
10 skip_dos_drive_prefix(&path);
11
12 if (!path || !*path)
13 return ".";
14
15 for (base = path; *path; path++) {
16 if (!is_dir_sep(*path))
17 continue;
18 do {
19 path++;
20 } while (is_dir_sep(*path));
21 if (*path)
22 base = path;
23 else
24 while (--path != base && is_dir_sep(*path))
25 *path = '\0';
26 }
27 return (char *)base;
28}
29
30char *gitdirname(char *path)
31{
32 static struct strbuf buf = STRBUF_INIT;
33 char *p = path, *slash = NULL, c;
34 int dos_drive_prefix;
35
36 if (!p)
37 return ".";
38
39 if ((dos_drive_prefix = skip_dos_drive_prefix(&p)) && !*p)
40 goto dot;
41
42 /*
43 * POSIX.1-2001 says dirname("/") should return "/", and dirname("//")
44 * should return "//", but dirname("///") should return "/" again.
45 */
46 if (is_dir_sep(*p)) {
47 if (!p[1] || (is_dir_sep(p[1]) && !p[2]))
48 return path;
49 slash = ++p;
50 }
51 while ((c = *(p++)))
52 if (is_dir_sep(c)) {
53 char *tentative = p - 1;
54
55 /* POSIX.1-2001 says to ignore trailing slashes */
56 while (is_dir_sep(*p))
57 p++;
58 if (*p)
59 slash = tentative;
60 }
61
62 if (slash) {
63 *slash = '\0';
64 return path;
65 }
66
67dot:
68 strbuf_reset(&buf);
69 strbuf_addf(&buf, "%.*s.", dos_drive_prefix, path);
70 return buf.buf;
71}