summaryrefslogtreecommitdiff
path: root/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'tree.c')
-rw-r--r--tree.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/tree.c b/tree.c
index 468f99e494..d9777bf810 100644
--- a/tree.c
+++ b/tree.c
@@ -88,24 +88,14 @@ struct tree *lookup_tree(unsigned char *sha1)
return (struct tree *) obj;
}
-int parse_tree(struct tree *item)
+int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
{
- char type[20];
- void *buffer, *bufptr;
- unsigned long size;
+ void *bufptr = buffer;
struct tree_entry_list **list_p;
+
if (item->object.parsed)
return 0;
item->object.parsed = 1;
- buffer = bufptr = read_sha1_file(item->object.sha1, type, &size);
- if (!buffer)
- return error("Could not read %s",
- sha1_to_hex(item->object.sha1));
- if (strcmp(type, tree_type)) {
- free(buffer);
- return error("Object %s not a tree",
- sha1_to_hex(item->object.sha1));
- }
list_p = &item->entries;
while (size) {
struct object *obj;
@@ -115,10 +105,8 @@ int parse_tree(struct tree *item)
char *path = strchr(bufptr, ' ');
unsigned int mode;
if (size < len + 20 || !path ||
- sscanf(bufptr, "%o", &mode) != 1) {
- free(buffer);
+ sscanf(bufptr, "%o", &mode) != 1)
return -1;
- }
entry = xmalloc(sizeof(struct tree_entry_list));
entry->name = strdup(path + 1);
@@ -144,6 +132,28 @@ int parse_tree(struct tree *item)
*list_p = entry;
list_p = &entry->next;
}
- free(buffer);
return 0;
}
+
+int parse_tree(struct tree *item)
+{
+ char type[20];
+ void *buffer;
+ unsigned long size;
+ int ret;
+
+ if (item->object.parsed)
+ return 0;
+ buffer = read_sha1_file(item->object.sha1, type, &size);
+ if (!buffer)
+ return error("Could not read %s",
+ sha1_to_hex(item->object.sha1));
+ if (strcmp(type, tree_type)) {
+ free(buffer);
+ return error("Object %s not a tree",
+ sha1_to_hex(item->object.sha1));
+ }
+ ret = parse_tree_buffer(item, buffer, size);
+ free(buffer);
+ return ret;
+}