]>
Commit | Line | Data |
---|---|---|
175785e5 DB |
1 | #include "tree.h" |
2 | #include "blob.h" | |
3 | #include "cache.h" | |
4 | #include <stdlib.h> | |
5 | ||
6 | const char *tree_type = "tree"; | |
7 | ||
8 | struct tree *lookup_tree(unsigned char *sha1) | |
9 | { | |
10 | struct object *obj = lookup_object(sha1); | |
11 | if (!obj) { | |
12 | struct tree *ret = malloc(sizeof(struct tree)); | |
13 | memset(ret, 0, sizeof(struct tree)); | |
14 | created_object(sha1, &ret->object); | |
15 | return ret; | |
16 | } | |
17 | if (obj->parsed && obj->type != tree_type) { | |
18 | error("Object %s is a %s, not a tree", | |
19 | sha1_to_hex(sha1), obj->type); | |
20 | return NULL; | |
21 | } | |
22 | return (struct tree *) obj; | |
23 | } | |
24 | ||
25 | int parse_tree(struct tree *item) | |
26 | { | |
27 | char type[20]; | |
28 | void *buffer, *bufptr; | |
29 | unsigned long size; | |
30 | if (item->object.parsed) | |
31 | return 0; | |
32 | item->object.parsed = 1; | |
33 | item->object.type = tree_type; | |
34 | buffer = bufptr = read_sha1_file(item->object.sha1, type, &size); | |
35 | if (!buffer) | |
36 | return error("Could not read %s", | |
37 | sha1_to_hex(item->object.sha1)); | |
38 | if (strcmp(type, tree_type)) | |
39 | return error("Object %s not a tree", | |
40 | sha1_to_hex(item->object.sha1)); | |
41 | while (size) { | |
42 | struct object *obj; | |
43 | int len = 1+strlen(bufptr); | |
44 | unsigned char *file_sha1 = bufptr + len; | |
45 | char *path = strchr(bufptr, ' '); | |
46 | unsigned int mode; | |
47 | if (size < len + 20 || !path || | |
48 | sscanf(bufptr, "%o", &mode) != 1) | |
49 | return -1; | |
50 | ||
51 | /* Warn about trees that don't do the recursive thing.. */ | |
52 | if (strchr(path, '/')) { | |
53 | item->has_full_path = 1; | |
54 | } | |
55 | ||
56 | bufptr += len + 20; | |
57 | size -= len + 20; | |
58 | ||
59 | if (S_ISDIR(mode)) { | |
60 | obj = &lookup_tree(file_sha1)->object; | |
61 | } else { | |
62 | obj = &lookup_blob(file_sha1)->object; | |
63 | } | |
64 | add_ref(&item->object, obj); | |
65 | } | |
66 | return 0; | |
67 | } |