diff options
| author | Russell Belfer <arrbee@arrbee.com> | 2012-02-21 14:46:24 -0800 |
|---|---|---|
| committer | Russell Belfer <arrbee@arrbee.com> | 2012-02-21 14:46:24 -0800 |
| commit | b6c93aef4276051f9c4536ecbed48f4cd093bd1b (patch) | |
| tree | a15962c672890c0c8cc021dafa7d29487f81c75a /src/path.c | |
| parent | 9c94a356cc61daa85e17c6342db9b3d62f788802 (diff) | |
| download | libgit2-b6c93aef4276051f9c4536ecbed48f4cd093bd1b.tar.gz | |
Uniform iterators for trees, index, and workdir
This create a new git_iterator type of object that provides a
uniform interface for iterating over the index, an arbitrary
tree, or the working directory of a repository.
As part of this, git ignore support was extended to support
push and pop of directory-based ignore files as the working
directory is being traversed (so the array of ignores does
not have to be recreated at each directory during traveral).
There are a number of other small utility functions in buffer,
path, vector, and fileops that are included in this patch
that made the iterator implementation cleaner.
Diffstat (limited to 'src/path.c')
| -rw-r--r-- | src/path.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/path.c b/src/path.c index 042332c45..6f46dc95e 100644 --- a/src/path.c +++ b/src/path.c @@ -421,6 +421,11 @@ static int _check_dir_contents( return error; } +int git_path_contains(git_buf *dir, const char *item) +{ + return _check_dir_contents(dir, item, 0, &git_path_exists); +} + int git_path_contains_dir(git_buf *base, const char *subdir, int append_if_exists) { return _check_dir_contents(base, subdir, append_if_exists, &git_path_isdir); @@ -522,3 +527,63 @@ int git_path_direach( closedir(dir); return GIT_SUCCESS; } + +int git_path_dirload( + const char *path, + size_t prefix_len, + size_t alloc_extra, + git_vector *contents) +{ + int error, need_slash; + DIR *dir; + struct dirent de_buf, *de; + size_t path_len; + + assert(path != NULL && contents != NULL); + path_len = strlen(path); + assert(path_len > 0 && path_len >= prefix_len); + + if ((dir = opendir(path)) == NULL) + return git__throw(GIT_EOSERR, "Failed to process `%s` tree structure." + " An error occured while opening the directory", path); + + path += prefix_len; + path_len -= prefix_len; + need_slash = (path_len > 0 && path[path_len-1] != '/') ? 1 : 0; + + while ((error = readdir_r(dir, &de_buf, &de)) == 0 && de != NULL) { + char *entry_path; + size_t entry_len; + + if (is_dot_or_dotdot(de->d_name)) + continue; + + entry_len = strlen(de->d_name); + + entry_path = git__malloc( + path_len + need_slash + entry_len + 1 + alloc_extra); + if (entry_path == NULL) + return GIT_ENOMEM; + + if (path_len) + memcpy(entry_path, path, path_len); + if (need_slash) + entry_path[path_len] = '/'; + memcpy(&entry_path[path_len + need_slash], de->d_name, entry_len); + entry_path[path_len + need_slash + entry_len] = '\0'; + + if ((error = git_vector_insert(contents, entry_path)) < GIT_SUCCESS) { + git__free(entry_path); + return error; + } + } + + closedir(dir); + + if (error != GIT_SUCCESS) + return git__throw( + GIT_EOSERR, "Failed to process directory entry in `%s`", path); + + return GIT_SUCCESS; +} + |
