From c8f5ff8f65617e6e097dd779492bd7af47232d4f Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Thu, 20 Jan 2011 14:43:27 -0800 Subject: [PATCH] Fix initialization of in-memory trees In-memory tree objects were not being properly initialized, because the internal entries vector was created on the 'parse' method. Signed-off-by: Vicent Marti --- src/repository.c | 40 ++++++++++++++++++++++++++-------------- src/tree.c | 33 +++++++++++++++++++++++++++------ src/tree.h | 1 + 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/repository.c b/src/repository.c index 7e56a4b66..97a7e15e2 100644 --- a/src/repository.c +++ b/src/repository.c @@ -379,31 +379,48 @@ git_odb *git_repository_database(git_repository *repo) return repo->db; } -int git_repository_newobject(git_object **object_out, git_repository *repo, git_otype type) +static int create_object(git_object **object_out, git_otype type) { git_object *object = NULL; - assert(object_out && repo); + assert(object_out); *object_out = NULL; switch (type) { case GIT_OBJ_COMMIT: case GIT_OBJ_TAG: - case GIT_OBJ_TREE: case GIT_OBJ_BLOB: + object = git__malloc(git_object__size(type)); + if (object == NULL) + return GIT_ENOMEM; + memset(object, 0x0, git_object__size(type)); + break; + + case GIT_OBJ_TREE: + object = (git_object *)git_tree__new(); + if (object == NULL) + return GIT_ENOMEM; break; default: return GIT_EINVALIDTYPE; } - object = git__malloc(git_object__size(type)); + *object_out = object; + return GIT_SUCCESS; +} - if (object == NULL) - return GIT_ENOMEM; +int git_repository_newobject(git_object **object_out, git_repository *repo, git_otype type) +{ + git_object *object = NULL; + int error; + + assert(object_out && repo); + + if ((error = create_object(&object, type)) < GIT_SUCCESS) + return error; - memset(object, 0x0, git_object__size(type)); object->repo = repo; object->in_memory = 1; object->modified = 1; @@ -439,12 +456,8 @@ int git_repository_lookup(git_object **object_out, git_repository *repo, const g type = obj_file.type; - object = git__malloc(git_object__size(type)); - - if (object == NULL) - return GIT_ENOMEM; - - memset(object, 0x0, git_object__size(type)); + if ((error = create_object(&object, type)) < GIT_SUCCESS) + return error; /* Initialize parent object */ git_oid_cpy(&object->id, id); @@ -453,7 +466,6 @@ int git_repository_lookup(git_object **object_out, git_repository *repo, const g object->source.open = 1; switch (type) { - case GIT_OBJ_COMMIT: error = git_commit__parse((git_commit *)object); break; diff --git a/src/tree.c b/src/tree.c index 4655dc760..d160a79a4 100644 --- a/src/tree.c +++ b/src/tree.c @@ -30,6 +30,8 @@ #include "git2/repository.h" #include "git2/object.h" +#define DEFAULT_TREE_SIZE 16 + int entry_search_cmp(const void *key, const void *array_member) { const char *filename = (const char *)key; @@ -46,7 +48,7 @@ int entry_sort_cmp(const void *a, const void *b) return strcmp(entry_a->filename, entry_b->filename); } -static void free_tree_entries(git_tree *tree) +static void clear_entries(git_tree *tree) { unsigned int i; @@ -61,14 +63,35 @@ static void free_tree_entries(git_tree *tree) free(e); } - git_vector_free(&tree->entries); + git_vector_clear(&tree->entries); } +git_tree *git_tree__new(void) +{ + git_tree *tree; + + tree = git__malloc(sizeof(struct git_tree)); + if (tree == NULL) + return NULL; + + memset(tree, 0x0, sizeof(struct git_tree)); + + if (git_vector_init(&tree->entries, + DEFAULT_TREE_SIZE, + entry_sort_cmp, + entry_search_cmp) < GIT_SUCCESS) { + free(tree); + return NULL; + } + + return tree; +} void git_tree__free(git_tree *tree) { - free_tree_entries(tree); + clear_entries(tree); + git_vector_free(&tree->entries); free(tree); } @@ -243,9 +266,7 @@ static int tree_parse_buffer(git_tree *tree, char *buffer, char *buffer_end) expected_size = (tree->object.source.raw.len / avg_entry_size) + 1; - free_tree_entries(tree); - if (git_vector_init(&tree->entries, expected_size, entry_sort_cmp, entry_search_cmp) < GIT_SUCCESS) - return GIT_ENOMEM; + clear_entries(tree); while (buffer < buffer_end) { git_tree_entry *entry; diff --git a/src/tree.h b/src/tree.h index 5f532f887..78500c471 100644 --- a/src/tree.h +++ b/src/tree.h @@ -19,6 +19,7 @@ struct git_tree { }; void git_tree__free(git_tree *tree); +git_tree *git_tree__new(void); int git_tree__parse(git_tree *tree); int git_tree__writeback(git_tree *tree, git_odb_source *src);