Git fork
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 /*
14 * basename(3P) is mis-specified because it returns a
15 * non-constant pointer even though it is specified to return a
16 * pointer to internal memory at times. The cast is a result of
17 * that.
18 */
19 return (char *) ".";
20
21 for (base = path; *path; path++) {
22 if (!is_dir_sep(*path))
23 continue;
24 do {
25 path++;
26 } while (is_dir_sep(*path));
27 if (*path)
28 base = path;
29 else
30 while (--path != base && is_dir_sep(*path))
31 *path = '\0';
32 }
33 return (char *)base;
34}
35
36char *gitdirname(char *path)
37{
38 static struct strbuf buf = STRBUF_INIT;
39 char *p = path, *slash = NULL, c;
40 int dos_drive_prefix;
41
42 if (!p)
43 /*
44 * dirname(3P) is mis-specified because it returns a
45 * non-constant pointer even though it is specified to return a
46 * pointer to internal memory at times. The cast is a result of
47 * that.
48 */
49 return (char *) ".";
50
51 if ((dos_drive_prefix = skip_dos_drive_prefix(&p)) && !*p)
52 goto dot;
53
54 /*
55 * POSIX.1-2001 says dirname("/") should return "/", and dirname("//")
56 * should return "//", but dirname("///") should return "/" again.
57 */
58 if (is_dir_sep(*p)) {
59 if (!p[1] || (is_dir_sep(p[1]) && !p[2]))
60 return path;
61 slash = ++p;
62 }
63 while ((c = *(p++)))
64 if (is_dir_sep(c)) {
65 char *tentative = p - 1;
66
67 /* POSIX.1-2001 says to ignore trailing slashes */
68 while (is_dir_sep(*p))
69 p++;
70 if (*p)
71 slash = tentative;
72 }
73
74 if (slash) {
75 *slash = '\0';
76 return path;
77 }
78
79dot:
80 strbuf_reset(&buf);
81 strbuf_addf(&buf, "%.*s.", dos_drive_prefix, path);
82 return buf.buf;
83}