summaryrefslogtreecommitdiff
path: root/src/path.c
diff options
context:
space:
mode:
authorRussell Belfer <arrbee@arrbee.com>2012-01-11 20:41:55 -0800
committerRussell Belfer <arrbee@arrbee.com>2012-01-11 20:41:55 -0800
commit0cfcff5daac50d5a4ba41d5125b108cdfceed832 (patch)
treef878699e76c530f5e7556020d11bcee97460d7a9 /src/path.c
parent15debaf5da2821e6f97038218b46d9fb3c755631 (diff)
downloadlibgit2-0cfcff5daac50d5a4ba41d5125b108cdfceed832.tar.gz
Convert git_path_walk_up to regular function
This gets rid of the crazy macro version of git_path_walk_up and makes it into a normal function that takes a callback parameter. This turned out not to be too messy.
Diffstat (limited to 'src/path.c')
-rw-r--r--src/path.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/path.c b/src/path.c
index f9663b7e5..4888123bf 100644
--- a/src/path.c
+++ b/src/path.c
@@ -305,3 +305,45 @@ int git_path_fromurl(git_buf *local_path_out, const char *file_url)
return error;
}
+
+int git_path_walk_up(
+ git_buf *path,
+ const char *ceiling,
+ int (*cb)(void *data, git_buf *),
+ void *data)
+{
+ int error = GIT_SUCCESS;
+ git_buf iter;
+ ssize_t stop = 0, scan;
+ char oldc = '\0';
+
+ assert(path && cb);
+
+ if (ceiling != NULL) {
+ if (git__prefixcmp(path->ptr, ceiling) == GIT_SUCCESS)
+ stop = (ssize_t)strlen(ceiling);
+ else
+ stop = path->size;
+ }
+ scan = path->size;
+
+ iter.ptr = path->ptr;
+ iter.size = path->size;
+
+ while (scan >= stop) {
+ if ((error = cb(data, &iter)) < GIT_SUCCESS)
+ break;
+ iter.ptr[scan] = oldc;
+ scan = git_buf_rfind_next(&iter, '/');
+ if (scan >= 0) {
+ scan++;
+ oldc = iter.ptr[scan];
+ iter.size = scan;
+ iter.ptr[scan] = '\0';
+ }
+ }
+
+ iter.ptr[scan] = oldc;
+
+ return error;
+}