Skip to content

Commit 175785e

Browse files
iabervonLinus Torvalds
authored andcommitted
[PATCH] Implementations of parsing functions
This implements the parsing functions. Signed-Off-By: Daniel Barkalow <barkalow@iabervon.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
1 parent 6eb8ae0 commit 175785e

File tree

4 files changed

+272
-0
lines changed

4 files changed

+272
-0
lines changed

blob.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "blob.h"
2+
#include "cache.h"
3+
#include <stdlib.h>
4+
5+
const char *blob_type = "blob";
6+
7+
struct blob *lookup_blob(unsigned char *sha1)
8+
{
9+
struct object *obj = lookup_object(sha1);
10+
if (!obj) {
11+
struct blob *ret = malloc(sizeof(struct blob));
12+
memset(ret, 0, sizeof(struct blob));
13+
created_object(sha1, &ret->object);
14+
ret->object.type = blob_type;
15+
ret->object.parsed = 1;
16+
return ret;
17+
}
18+
if (obj->parsed && obj->type != blob_type) {
19+
error("Object %s is a %s, not a blob",
20+
sha1_to_hex(sha1), obj->type);
21+
return NULL;
22+
}
23+
return (struct blob *) obj;
24+
}

commit.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#include "commit.h"
2+
#include "cache.h"
3+
#include <string.h>
4+
5+
const char *commit_type = "commit";
6+
7+
struct commit *lookup_commit(unsigned char *sha1)
8+
{
9+
struct object *obj = lookup_object(sha1);
10+
if (!obj) {
11+
struct commit *ret = malloc(sizeof(struct commit));
12+
memset(ret, 0, sizeof(struct commit));
13+
created_object(sha1, &ret->object);
14+
return ret;
15+
}
16+
if (obj->parsed && obj->type != commit_type) {
17+
error("Object %s is a %s, not a commit",
18+
sha1_to_hex(sha1), obj->type);
19+
return NULL;
20+
}
21+
return (struct commit *) obj;
22+
}
23+
24+
static unsigned long parse_commit_date(const char *buf)
25+
{
26+
unsigned long date;
27+
28+
if (memcmp(buf, "author", 6))
29+
return 0;
30+
while (*buf++ != '\n')
31+
/* nada */;
32+
if (memcmp(buf, "committer", 9))
33+
return 0;
34+
while (*buf++ != '>')
35+
/* nada */;
36+
date = strtoul(buf, NULL, 10);
37+
if (date == ULONG_MAX)
38+
date = 0;
39+
return date;
40+
}
41+
42+
int parse_commit(struct commit *item)
43+
{
44+
char type[20];
45+
void * buffer, *bufptr;
46+
unsigned long size;
47+
unsigned char parent[20];
48+
if (item->object.parsed)
49+
return 0;
50+
item->object.parsed = 1;
51+
buffer = bufptr = read_sha1_file(item->object.sha1, type, &size);
52+
if (!buffer)
53+
return error("Could not read %s",
54+
sha1_to_hex(item->object.sha1));
55+
if (strcmp(type, commit_type))
56+
return error("Object %s not a commit",
57+
sha1_to_hex(item->object.sha1));
58+
item->object.type = commit_type;
59+
get_sha1_hex(bufptr + 5, parent);
60+
item->tree = lookup_tree(parent);
61+
add_ref(&item->object, &item->tree->object);
62+
bufptr += 46; /* "tree " + "hex sha1" + "\n" */
63+
while (!memcmp(bufptr, "parent ", 7) &&
64+
!get_sha1_hex(bufptr + 7, parent)) {
65+
struct commit_list *new_parent =
66+
malloc(sizeof(struct commit_list));
67+
new_parent->next = item->parents;
68+
new_parent->item = lookup_commit(parent);
69+
add_ref(&item->object, &new_parent->item->object);
70+
item->parents = new_parent;
71+
bufptr += 48;
72+
}
73+
item->date = parse_commit_date(bufptr);
74+
free(buffer);
75+
return 0;
76+
}
77+
78+
void free_commit_list(struct commit_list *list)
79+
{
80+
while (list) {
81+
struct commit_list *temp = list;
82+
list = temp->next;
83+
free(temp);
84+
}
85+
}

object.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#include "object.h"
2+
#include "cache.h"
3+
#include <stdlib.h>
4+
#include <string.h>
5+
6+
struct object **objs;
7+
int nr_objs;
8+
static int obj_allocs;
9+
10+
static int find_object(unsigned char *sha1)
11+
{
12+
int first = 0, last = nr_objs;
13+
14+
while (first < last) {
15+
int next = (first + last) / 2;
16+
struct object *obj = objs[next];
17+
int cmp;
18+
19+
cmp = memcmp(sha1, obj->sha1, 20);
20+
if (!cmp)
21+
return next;
22+
if (cmp < 0) {
23+
last = next;
24+
continue;
25+
}
26+
first = next+1;
27+
}
28+
return -first-1;
29+
}
30+
31+
struct object *lookup_object(unsigned char *sha1)
32+
{
33+
int pos = find_object(sha1);
34+
if (pos >= 0)
35+
return objs[pos];
36+
return NULL;
37+
}
38+
39+
void created_object(unsigned char *sha1, struct object *obj)
40+
{
41+
int pos = find_object(sha1);
42+
43+
obj->parsed = 0;
44+
memcpy(obj->sha1, sha1, 20);
45+
obj->type = NULL;
46+
obj->refs = NULL;
47+
obj->used = 0;
48+
49+
if (pos >= 0)
50+
die("Inserting %s twice\n", sha1_to_hex(sha1));
51+
pos = -pos-1;
52+
53+
if (obj_allocs == nr_objs) {
54+
obj_allocs = alloc_nr(obj_allocs);
55+
objs = realloc(objs, obj_allocs * sizeof(struct object *));
56+
}
57+
58+
/* Insert it into the right place */
59+
memmove(objs + pos + 1, objs + pos, (nr_objs - pos) *
60+
sizeof(struct object *));
61+
62+
objs[pos] = obj;
63+
nr_objs++;
64+
}
65+
66+
void add_ref(struct object *refer, struct object *target)
67+
{
68+
struct object_list **pp = &refer->refs;
69+
struct object_list *p;
70+
71+
while ((p = *pp) != NULL) {
72+
if (p->item == target)
73+
return;
74+
pp = &p->next;
75+
}
76+
77+
target->used = 1;
78+
p = malloc(sizeof(*p));
79+
p->item = target;
80+
p->next = NULL;
81+
*pp = p;
82+
}
83+
84+
void mark_reachable(struct object *obj, unsigned int mask)
85+
{
86+
struct object_list *p = obj->refs;
87+
88+
/* If we've been here already, don't bother */
89+
if (obj->flags & mask)
90+
return;
91+
obj->flags |= mask;
92+
while (p) {
93+
mark_reachable(p->item, mask);
94+
p = p->next;
95+
}
96+
}

tree.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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+
}

0 commit comments

Comments
 (0)