summaryrefslogtreecommitdiffstats
path: root/src/bfstd.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2022-12-30 14:49:46 -0500
committerTavian Barnes <tavianator@tavianator.com>2023-01-19 14:41:55 -0500
commit683552c4c9a3dfee4ce603157bb2cf18d64fbcfc (patch)
tree475130eeb136007eea7c59cb7190dc05287e2c56 /src/bfstd.c
parent944cd72f40a84d318453c320a84d443273956859 (diff)
downloadbfs-683552c4c9a3dfee4ce603157bb2cf18d64fbcfc.tar.xz
bfstd: New wrappers for dirname()/basename()
Diffstat (limited to 'src/bfstd.c')
-rw-r--r--src/bfstd.c45
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;
}