~ubuntu-branches/ubuntu/intrepid/git-core/intrepid-updates

« back to all changes in this revision

Viewing changes to tree-walk.c

  • Committer: Package Import Robot
  • Author(s): Gerrit Pape
  • Date: 2007-04-22 13:31:05 UTC
  • mfrom: (1.1.14)
  • Revision ID: package-import@ubuntu.com-20070422133105-tkmhz328g2p0epz1
Tags: 1:1.5.1.2-1
* new upstream point release.
* debian/changelog.upstream: upstream changes taken from mailing list
  announcement.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
#include "tree-walk.h"
3
3
#include "tree.h"
4
4
 
 
5
static const char *get_mode(const char *str, unsigned int *modep)
 
6
{
 
7
        unsigned char c;
 
8
        unsigned int mode = 0;
 
9
 
 
10
        while ((c = *str++) != ' ') {
 
11
                if (c < '0' || c > '7')
 
12
                        return NULL;
 
13
                mode = (mode << 3) + (c - '0');
 
14
        }
 
15
        *modep = mode;
 
16
        return str;
 
17
}
 
18
 
 
19
static void decode_tree_entry(struct tree_desc *desc, const void *buf, unsigned long size)
 
20
{
 
21
        const char *path;
 
22
        unsigned int mode, len;
 
23
 
 
24
        path = get_mode(buf, &mode);
 
25
        if (!path)
 
26
                die("corrupt tree file");
 
27
        len = strlen(path) + 1;
 
28
 
 
29
        /* Initialize the descriptor entry */
 
30
        desc->entry.path = path;
 
31
        desc->entry.mode = mode;
 
32
        desc->entry.sha1 = (const unsigned char *)(path + len);
 
33
}
 
34
 
 
35
void init_tree_desc(struct tree_desc *desc, const void *buffer, unsigned long size)
 
36
{
 
37
        desc->buffer = buffer;
 
38
        desc->size = size;
 
39
        if (size)
 
40
                decode_tree_entry(desc, buffer, size);
 
41
}
 
42
 
5
43
void *fill_tree_descriptor(struct tree_desc *desc, const unsigned char *sha1)
6
44
{
7
45
        unsigned long size = 0;
12
50
                if (!buf)
13
51
                        die("unable to read tree %s", sha1_to_hex(sha1));
14
52
        }
15
 
        desc->size = size;
16
 
        desc->buf = buf;
 
53
        init_tree_desc(desc, buf, size);
17
54
        return buf;
18
55
}
19
56
 
20
57
static int entry_compare(struct name_entry *a, struct name_entry *b)
21
58
{
22
59
        return base_name_compare(
23
 
                        a->path, a->pathlen, a->mode,
24
 
                        b->path, b->pathlen, b->mode);
 
60
                        a->path, tree_entry_len(a->path, a->sha1), a->mode,
 
61
                        b->path, tree_entry_len(b->path, b->sha1), b->mode);
25
62
}
26
63
 
27
64
static void entry_clear(struct name_entry *a)
31
68
 
32
69
static void entry_extract(struct tree_desc *t, struct name_entry *a)
33
70
{
34
 
        a->sha1 = tree_entry_extract(t, &a->path, &a->mode);
35
 
        a->pathlen = strlen(a->path);
 
71
        *a = t->entry;
36
72
}
37
73
 
38
74
void update_tree_entry(struct tree_desc *desc)
39
75
{
40
 
        const void *buf = desc->buf;
 
76
        const void *buf = desc->buffer;
 
77
        const unsigned char *end = desc->entry.sha1 + 20;
41
78
        unsigned long size = desc->size;
42
 
        int len = strlen(buf) + 1 + 20;
 
79
        unsigned long len = end - (const unsigned char *)buf;
43
80
 
44
81
        if (size < len)
45
82
                die("corrupt tree file");
46
 
        desc->buf = (char *) buf + len;
47
 
        desc->size = size - len;
48
 
}
49
 
 
50
 
static const char *get_mode(const char *str, unsigned int *modep)
51
 
{
52
 
        unsigned char c;
53
 
        unsigned int mode = 0;
54
 
 
55
 
        while ((c = *str++) != ' ') {
56
 
                if (c < '0' || c > '7')
57
 
                        return NULL;
58
 
                mode = (mode << 3) + (c - '0');
59
 
        }
60
 
        *modep = mode;
61
 
        return str;
62
 
}
63
 
 
64
 
const unsigned char *tree_entry_extract(struct tree_desc *desc, const char **pathp, unsigned int *modep)
65
 
{
66
 
        const void *tree = desc->buf;
67
 
        unsigned long size = desc->size;
68
 
        int len = strlen(tree)+1;
69
 
        const unsigned char *sha1 = (unsigned char *) tree + len;
70
 
        const char *path;
71
 
        unsigned int mode;
72
 
 
73
 
        path = get_mode(tree, &mode);
74
 
        if (!path || size < len + 20)
75
 
                die("corrupt tree file");
76
 
        *pathp = path;
77
 
        *modep = canon_mode(mode);
78
 
        return sha1;
 
83
        buf = end;
 
84
        size -= len;
 
85
        desc->buffer = buf;
 
86
        desc->size = size;
 
87
        if (size)
 
88
                decode_tree_entry(desc, buf, size);
79
89
}
80
90
 
81
91
int tree_entry(struct tree_desc *desc, struct name_entry *entry)
82
92
{
83
 
        const void *tree = desc->buf;
84
 
        const char *path;
85
 
        unsigned long len, size = desc->size;
86
 
 
87
 
        if (!size)
 
93
        if (!desc->size)
88
94
                return 0;
89
95
 
90
 
        path = get_mode(tree, &entry->mode);
91
 
        if (!path)
92
 
                die("corrupt tree file");
93
 
 
94
 
        entry->path = path;
95
 
        len = strlen(path);
96
 
        entry->pathlen = len;
97
 
 
98
 
        path += len + 1;
99
 
        entry->sha1 = (const unsigned char *) path;
100
 
 
101
 
        path += 20;
102
 
        len = path - (char *) tree;
103
 
        if (len > size)
104
 
                die("corrupt tree file");
105
 
 
106
 
        desc->buf = path;
107
 
        desc->size = size - len;
 
96
        *entry = desc->entry;
 
97
        update_tree_entry(desc);
108
98
        return 1;
109
99
}
110
100
 
113
103
        struct name_entry *entry = xmalloc(n*sizeof(*entry));
114
104
 
115
105
        for (;;) {
116
 
                struct name_entry entry[3];
117
106
                unsigned long mask = 0;
118
107
                int i, last;
119
108
 
170
159
 
171
160
                sha1 = tree_entry_extract(t, &entry, mode);
172
161
                update_tree_entry(t);
173
 
                entrylen = strlen(entry);
 
162
                entrylen = tree_entry_len(entry, sha1);
174
163
                if (entrylen > namelen)
175
164
                        continue;
176
165
                cmp = memcmp(name, entry, entrylen);
199
188
{
200
189
        int retval;
201
190
        void *tree;
 
191
        unsigned long size;
202
192
        struct tree_desc t;
 
193
        unsigned char root[20];
203
194
 
204
 
        tree = read_object_with_reference(tree_sha1, tree_type, &t.size, NULL);
 
195
        tree = read_object_with_reference(tree_sha1, tree_type, &size, root);
205
196
        if (!tree)
206
197
                return -1;
207
 
        t.buf = tree;
 
198
 
 
199
        if (name[0] == '\0') {
 
200
                hashcpy(sha1, root);
 
201
                return 0;
 
202
        }
 
203
 
 
204
        init_tree_desc(&t, tree, size);
208
205
        retval = find_tree_entry(&t, name, sha1, mode);
209
206
        free(tree);
210
207
        return retval;