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)
if (ign->ign_path.length > 0) {
git_attr_file *file = git_vector_last(&ign->ign_path);
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, '/');
}
return GIT_SUCCESS;
......
......@@ -398,42 +398,38 @@ int git_path_isfile(const char *path)
static int _check_dir_contents(
git_buf *dir,
const char *sub,
int append_on_success,
int (*predicate)(const char *))
{
int error = GIT_SUCCESS;
size_t dir_size = dir->size;
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)
return error;
/* save excursion */
git_buf_joinpath(dir, dir->ptr, sub);
error = (*predicate)(dir->ptr);
/* restore excursion */
if (!append_on_success || error != GIT_SUCCESS)
git_buf_truncate(dir, dir_size);
/* restore path */
git_buf_truncate(dir, dir_size);
return error;
}
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)
......
......@@ -143,20 +143,18 @@ extern int git_path_contains(git_buf *dir, const char *item);
*
* @param parent Directory path that might contain subdir
* @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.
*/
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.
*
* @param dir Directory path that might contain file
* @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.
*/
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.
......
......@@ -81,14 +81,14 @@ void git_repository_free(git_repository *repo)
static int quickcheck_repository_dir(git_buf *repository_path)
{
/* 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;
/* 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;
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_SUCCESS;
......@@ -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`
* folder inside of it.
*/
git_path_contains_dir(&path_buf, GIT_DIR, 1); /* append on success */
/* ignore error, since it just means `path/.git` doesn't exist */
if (git_path_contains_dir(&path_buf, GIT_DIR) == GIT_SUCCESS)
git_buf_joinpath(&path_buf, path_buf.ptr, GIT_DIR);
if (quickcheck_repository_dir(&path_buf) < GIT_SUCCESS) {
error = git__throw(GIT_ENOTAREPO,
......
......@@ -25,24 +25,6 @@ static int resize_vector(git_vector *v)
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)
{
assert(v);
......@@ -205,19 +187,10 @@ int git_vector_remove(git_vector *v, unsigned int idx)
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)
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;
if (v->length > 0)
v->length--;
}
void git_vector_uniq(git_vector *v)
......
......@@ -22,7 +22,6 @@ typedef struct git_vector {
#define GIT_VECTOR_INIT {0}
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_clear(git_vector *v);
......@@ -54,7 +53,7 @@ int git_vector_insert(git_vector *v, void *element);
int git_vector_insert_sorted(git_vector *v, void *element,
int (*on_dup)(void **old, void *new));
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);
#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