Merge branch 'as/read-tree-prefix-doc-fix'
[git] / compat / basename.c
1 #include "../git-compat-util.h"
2 #include "../strbuf.h"
3
4 /* Adapted from libiberty's basename.c.  */
5 char *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
30 char *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
67 dot:
68         strbuf_reset(&buf);
69         strbuf_addf(&buf, "%.*s.", dos_drive_prefix, path);
70         return buf.buf;
71 }