Commit c8f5ff8f by Vicent Marti

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 <tanoku@gmail.com>
parent e16c2f6a
...@@ -379,31 +379,48 @@ git_odb *git_repository_database(git_repository *repo) ...@@ -379,31 +379,48 @@ git_odb *git_repository_database(git_repository *repo)
return repo->db; 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; git_object *object = NULL;
assert(object_out && repo); assert(object_out);
*object_out = NULL; *object_out = NULL;
switch (type) { switch (type) {
case GIT_OBJ_COMMIT: case GIT_OBJ_COMMIT:
case GIT_OBJ_TAG: case GIT_OBJ_TAG:
case GIT_OBJ_TREE:
case GIT_OBJ_BLOB: 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; break;
default: default:
return GIT_EINVALIDTYPE; return GIT_EINVALIDTYPE;
} }
object = git__malloc(git_object__size(type)); *object_out = object;
return GIT_SUCCESS;
}
if (object == NULL) int git_repository_newobject(git_object **object_out, git_repository *repo, git_otype type)
return GIT_ENOMEM; {
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->repo = repo;
object->in_memory = 1; object->in_memory = 1;
object->modified = 1; object->modified = 1;
...@@ -439,12 +456,8 @@ int git_repository_lookup(git_object **object_out, git_repository *repo, const g ...@@ -439,12 +456,8 @@ int git_repository_lookup(git_object **object_out, git_repository *repo, const g
type = obj_file.type; type = obj_file.type;
object = git__malloc(git_object__size(type)); if ((error = create_object(&object, type)) < GIT_SUCCESS)
return error;
if (object == NULL)
return GIT_ENOMEM;
memset(object, 0x0, git_object__size(type));
/* Initialize parent object */ /* Initialize parent object */
git_oid_cpy(&object->id, id); git_oid_cpy(&object->id, id);
...@@ -453,7 +466,6 @@ int git_repository_lookup(git_object **object_out, git_repository *repo, const g ...@@ -453,7 +466,6 @@ int git_repository_lookup(git_object **object_out, git_repository *repo, const g
object->source.open = 1; object->source.open = 1;
switch (type) { switch (type) {
case GIT_OBJ_COMMIT: case GIT_OBJ_COMMIT:
error = git_commit__parse((git_commit *)object); error = git_commit__parse((git_commit *)object);
break; break;
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include "git2/repository.h" #include "git2/repository.h"
#include "git2/object.h" #include "git2/object.h"
#define DEFAULT_TREE_SIZE 16
int entry_search_cmp(const void *key, const void *array_member) int entry_search_cmp(const void *key, const void *array_member)
{ {
const char *filename = (const char *)key; const char *filename = (const char *)key;
...@@ -46,7 +48,7 @@ int entry_sort_cmp(const void *a, const void *b) ...@@ -46,7 +48,7 @@ int entry_sort_cmp(const void *a, const void *b)
return strcmp(entry_a->filename, entry_b->filename); 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; unsigned int i;
...@@ -61,14 +63,35 @@ static void free_tree_entries(git_tree *tree) ...@@ -61,14 +63,35 @@ static void free_tree_entries(git_tree *tree)
free(e); 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) void git_tree__free(git_tree *tree)
{ {
free_tree_entries(tree); clear_entries(tree);
git_vector_free(&tree->entries);
free(tree); free(tree);
} }
...@@ -243,9 +266,7 @@ static int tree_parse_buffer(git_tree *tree, char *buffer, char *buffer_end) ...@@ -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; expected_size = (tree->object.source.raw.len / avg_entry_size) + 1;
free_tree_entries(tree); clear_entries(tree);
if (git_vector_init(&tree->entries, expected_size, entry_sort_cmp, entry_search_cmp) < GIT_SUCCESS)
return GIT_ENOMEM;
while (buffer < buffer_end) { while (buffer < buffer_end) {
git_tree_entry *entry; git_tree_entry *entry;
......
...@@ -19,6 +19,7 @@ struct git_tree { ...@@ -19,6 +19,7 @@ struct git_tree {
}; };
void git_tree__free(git_tree *tree); void git_tree__free(git_tree *tree);
git_tree *git_tree__new(void);
int git_tree__parse(git_tree *tree); int git_tree__parse(git_tree *tree);
int git_tree__writeback(git_tree *tree, git_odb_source *src); int git_tree__writeback(git_tree *tree, git_odb_source *src);
......
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