diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2022-12-30 14:49:46 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2023-01-19 14:41:55 -0500 |
commit | 683552c4c9a3dfee4ce603157bb2cf18d64fbcfc (patch) | |
tree | 475130eeb136007eea7c59cb7190dc05287e2c56 /src/bfstd.c | |
parent | 944cd72f40a84d318453c320a84d443273956859 (diff) | |
download | bfs-683552c4c9a3dfee4ce603157bb2cf18d64fbcfc.tar.xz |
bfstd: New wrappers for dirname()/basename()
Diffstat (limited to 'src/bfstd.c')
-rw-r--r-- | src/bfstd.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/src/bfstd.c b/src/bfstd.c index 1561796..3a37250 100644 --- a/src/bfstd.c +++ b/src/bfstd.c @@ -45,17 +45,52 @@ bool is_nonexistence_error(int error) { return error == ENOENT || errno == ENOTDIR; } -const char *xbasename(const char *path) { - const char *i; +char *xdirname(const char *path) { + size_t i = xbaseoff(path); // Skip trailing slashes - for (i = path + strlen(path); i > path && i[-1] == '/'; --i); + while (i > 0 && path[i - 1] == '/') { + --i; + } + + if (i > 0) { + return strndup(path, i); + } else if (path[i] == '/') { + return strdup("/"); + } else { + return strdup("."); + } +} + +char *xbasename(const char *path) { + size_t i = xbaseoff(path); + size_t len = strcspn(path + i, "/"); + if (len > 0) { + return strndup(path + i, len); + } else if (path[i] == '/') { + return strdup("/"); + } else { + return strdup("."); + } +} + +size_t xbaseoff(const char *path) { + size_t i = strlen(path); + + // Skip trailing slashes + while (i > 0 && path[i - 1] == '/') { + --i; + } // Find the beginning of the name - for (; i > path && i[-1] != '/'; --i); + while (i > 0 && path[i - 1] != '/') { + --i; + } // Skip leading slashes - for (; i[0] == '/' && i[1]; ++i); + while (path[i] == '/' && path[i + 1]) { + ++i; + } return i; } |