Commit 0534641d by Russell Belfer

Fix iterators based on pull request feedback

This update addresses all of the feedback in pull request #570.

The biggest change was to create actual linked list stacks for
storing the tree and workdir iterator state.  This cleaned up
the code a ton.  Additionally, all of the static functions had
their 'git_' prefix removed, and a lot of other unnecessary
changes were removed from the original patch.
parent da337c80
...@@ -147,7 +147,7 @@ int git_ignore__pop_dir(git_ignores *ign) ...@@ -147,7 +147,7 @@ int git_ignore__pop_dir(git_ignores *ign)
if (ign->ign_path.length > 0) { if (ign->ign_path.length > 0) {
git_attr_file *file = git_vector_last(&ign->ign_path); git_attr_file *file = git_vector_last(&ign->ign_path);
if (git__suffixcmp(ign->dir.ptr, file->path) == 0) if (git__suffixcmp(ign->dir.ptr, file->path) == 0)
git_vector_pop(&ign->ign_path, NULL); git_vector_pop(&ign->ign_path);
git_buf_rtruncate_at_char(&ign->dir, '/'); git_buf_rtruncate_at_char(&ign->dir, '/');
} }
return GIT_SUCCESS; return GIT_SUCCESS;
......
...@@ -398,42 +398,38 @@ int git_path_isfile(const char *path) ...@@ -398,42 +398,38 @@ int git_path_isfile(const char *path)
static int _check_dir_contents( static int _check_dir_contents(
git_buf *dir, git_buf *dir,
const char *sub, const char *sub,
int append_on_success,
int (*predicate)(const char *)) int (*predicate)(const char *))
{ {
int error = GIT_SUCCESS; int error = GIT_SUCCESS;
size_t dir_size = dir->size; size_t dir_size = dir->size;
size_t sub_size = strlen(sub); size_t sub_size = strlen(sub);
/* leave base valid even if we could not make space for subdir */ /* separate allocation and join, so we can always leave git_buf valid */
if ((error = git_buf_try_grow(dir, dir_size + sub_size + 2)) < GIT_SUCCESS) if ((error = git_buf_try_grow(dir, dir_size + sub_size + 2)) < GIT_SUCCESS)
return error; return error;
/* save excursion */
git_buf_joinpath(dir, dir->ptr, sub); git_buf_joinpath(dir, dir->ptr, sub);
error = (*predicate)(dir->ptr); error = (*predicate)(dir->ptr);
/* restore excursion */ /* restore path */
if (!append_on_success || error != GIT_SUCCESS) git_buf_truncate(dir, dir_size);
git_buf_truncate(dir, dir_size);
return error; return error;
} }
int git_path_contains(git_buf *dir, const char *item) int git_path_contains(git_buf *dir, const char *item)
{ {
return _check_dir_contents(dir, item, 0, &git_path_exists); return _check_dir_contents(dir, item, &git_path_exists);
} }
int git_path_contains_dir(git_buf *base, const char *subdir, int append_if_exists) int git_path_contains_dir(git_buf *base, const char *subdir)
{ {
return _check_dir_contents(base, subdir, append_if_exists, &git_path_isdir); return _check_dir_contents(base, subdir, &git_path_isdir);
} }
int git_path_contains_file(git_buf *base, const char *file, int append_if_exists) int git_path_contains_file(git_buf *base, const char *file)
{ {
return _check_dir_contents(base, file, append_if_exists, &git_path_isfile); return _check_dir_contents(base, file, &git_path_isfile);
} }
int git_path_find_dir(git_buf *dir, const char *path, const char *base) int git_path_find_dir(git_buf *dir, const char *path, const char *base)
......
...@@ -143,20 +143,18 @@ extern int git_path_contains(git_buf *dir, const char *item); ...@@ -143,20 +143,18 @@ extern int git_path_contains(git_buf *dir, const char *item);
* *
* @param parent Directory path that might contain subdir * @param parent Directory path that might contain subdir
* @param subdir Subdirectory name to look for in parent * @param subdir Subdirectory name to look for in parent
* @param append_if_exists If true, then subdir will be appended to the parent path if it does exist
* @return GIT_SUCCESS if subdirectory exists, < 0 otherwise. * @return GIT_SUCCESS if subdirectory exists, < 0 otherwise.
*/ */
extern int git_path_contains_dir(git_buf *parent, const char *subdir, int append_if_exists); extern int git_path_contains_dir(git_buf *parent, const char *subdir);
/** /**
* Check if the given path contains the given file. * Check if the given path contains the given file.
* *
* @param dir Directory path that might contain file * @param dir Directory path that might contain file
* @param file File name to look for in parent * @param file File name to look for in parent
* @param append_if_exists If true, then file will be appended to the path if it does exist
* @return GIT_SUCCESS if file exists, < 0 otherwise. * @return GIT_SUCCESS if file exists, < 0 otherwise.
*/ */
extern int git_path_contains_file(git_buf *dir, const char *file, int append_if_exists); extern int git_path_contains_file(git_buf *dir, const char *file);
/** /**
* Clean up path, prepending base if it is not already rooted. * Clean up path, prepending base if it is not already rooted.
......
...@@ -81,14 +81,14 @@ void git_repository_free(git_repository *repo) ...@@ -81,14 +81,14 @@ void git_repository_free(git_repository *repo)
static int quickcheck_repository_dir(git_buf *repository_path) static int quickcheck_repository_dir(git_buf *repository_path)
{ {
/* Check OBJECTS_DIR first, since it will generate the longest path name */ /* Check OBJECTS_DIR first, since it will generate the longest path name */
if (git_path_contains_dir(repository_path, GIT_OBJECTS_DIR, 0) < 0) if (git_path_contains_dir(repository_path, GIT_OBJECTS_DIR) < 0)
return GIT_ERROR; return GIT_ERROR;
/* Ensure HEAD file exists */ /* Ensure HEAD file exists */
if (git_path_contains_file(repository_path, GIT_HEAD_FILE, 0) < 0) if (git_path_contains_file(repository_path, GIT_HEAD_FILE) < 0)
return GIT_ERROR; return GIT_ERROR;
if (git_path_contains_dir(repository_path, GIT_REFS_DIR, 0) < 0) if (git_path_contains_dir(repository_path, GIT_REFS_DIR) < 0)
return GIT_ERROR; return GIT_ERROR;
return GIT_SUCCESS; return GIT_SUCCESS;
...@@ -166,8 +166,8 @@ int git_repository_open(git_repository **repo_out, const char *path) ...@@ -166,8 +166,8 @@ int git_repository_open(git_repository **repo_out, const char *path)
* of the working dir, by testing if it contains a `.git` * of the working dir, by testing if it contains a `.git`
* folder inside of it. * folder inside of it.
*/ */
git_path_contains_dir(&path_buf, GIT_DIR, 1); /* append on success */ if (git_path_contains_dir(&path_buf, GIT_DIR) == GIT_SUCCESS)
/* ignore error, since it just means `path/.git` doesn't exist */ git_buf_joinpath(&path_buf, path_buf.ptr, GIT_DIR);
if (quickcheck_repository_dir(&path_buf) < GIT_SUCCESS) { if (quickcheck_repository_dir(&path_buf) < GIT_SUCCESS) {
error = git__throw(GIT_ENOTAREPO, error = git__throw(GIT_ENOTAREPO,
......
...@@ -25,24 +25,6 @@ static int resize_vector(git_vector *v) ...@@ -25,24 +25,6 @@ static int resize_vector(git_vector *v)
return GIT_SUCCESS; return GIT_SUCCESS;
} }
int git_vector_alloc(
git_vector **vptr, unsigned int initial_size, git_vector_cmp cmp)
{
int error;
git_vector *v = git__malloc(sizeof(git_vector));
if (!v) {
*vptr = NULL;
return GIT_ENOMEM;
}
if ((error = git_vector_init(v, initial_size, cmp)) < GIT_SUCCESS) {
git__free(v);
v = NULL;
}
*vptr = v;
return error;
}
void git_vector_free(git_vector *v) void git_vector_free(git_vector *v)
{ {
assert(v); assert(v);
...@@ -205,19 +187,10 @@ int git_vector_remove(git_vector *v, unsigned int idx) ...@@ -205,19 +187,10 @@ int git_vector_remove(git_vector *v, unsigned int idx)
return GIT_SUCCESS; return GIT_SUCCESS;
} }
int git_vector_pop(git_vector *v, void **element) void git_vector_pop(git_vector *v)
{ {
assert(v); if (v->length > 0)
v->length--;
if (v->length == 0)
return git__throw(GIT_ENOTFOUND, "Can't remove element from empty list");
if (element != NULL)
*element = v->contents[v->length - 1];
v->length--;
return GIT_SUCCESS;
} }
void git_vector_uniq(git_vector *v) void git_vector_uniq(git_vector *v)
......
...@@ -22,7 +22,6 @@ typedef struct git_vector { ...@@ -22,7 +22,6 @@ typedef struct git_vector {
#define GIT_VECTOR_INIT {0} #define GIT_VECTOR_INIT {0}
int git_vector_init(git_vector *v, unsigned int initial_size, git_vector_cmp cmp); int git_vector_init(git_vector *v, unsigned int initial_size, git_vector_cmp cmp);
int git_vector_alloc(git_vector **v, unsigned int initial_size, git_vector_cmp cmp);
void git_vector_free(git_vector *v); void git_vector_free(git_vector *v);
void git_vector_clear(git_vector *v); void git_vector_clear(git_vector *v);
...@@ -54,7 +53,7 @@ int git_vector_insert(git_vector *v, void *element); ...@@ -54,7 +53,7 @@ int git_vector_insert(git_vector *v, void *element);
int git_vector_insert_sorted(git_vector *v, void *element, int git_vector_insert_sorted(git_vector *v, void *element,
int (*on_dup)(void **old, void *new)); int (*on_dup)(void **old, void *new));
int git_vector_remove(git_vector *v, unsigned int idx); int git_vector_remove(git_vector *v, unsigned int idx);
int git_vector_pop(git_vector *v, void **element); void git_vector_pop(git_vector *v);
void git_vector_uniq(git_vector *v); void git_vector_uniq(git_vector *v);
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment