Skip to content

Commit

Permalink
expose a helper function peel_to_type().
Browse files Browse the repository at this point in the history
This helper function is the core of "$object^{type}" parser.
Now it is made available to callers outside sha1_name.c
  • Loading branch information
Junio C Hamano committed Feb 18, 2008
1 parent 525ab63 commit 8177631
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 19 deletions.
3 changes: 3 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,9 @@ extern void *read_object_with_reference(const unsigned char *sha1,
unsigned long *size,
unsigned char *sha1_ret);

extern struct object *peel_to_type(const char *name, int namelen,
struct object *o, enum object_type);

enum date_mode {
DATE_NORMAL = 0,
DATE_RELATIVE,
Expand Down
57 changes: 38 additions & 19 deletions sha1_name.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,37 @@ static int get_nth_ancestor(const char *name, int len,
return 0;
}

struct object *peel_to_type(const char *name, int namelen,
struct object *o, enum object_type expected_type)
{
if (name && !namelen)
namelen = strlen(name);
if (!o) {
unsigned char sha1[20];
if (get_sha1_1(name, namelen, sha1))
return NULL;
o = parse_object(sha1);
}
while (1) {
if (!o || (!o->parsed && !parse_object(o->sha1)))
return NULL;
if (o->type == expected_type)
return o;
if (o->type == OBJ_TAG)
o = ((struct tag*) o)->tagged;
else if (o->type == OBJ_COMMIT)
o = &(((struct commit *) o)->tree->object);
else {
if (name)
error("%.*s: expected %s type, but the object "
"dereferences to %s type",
namelen, name, typename(expected_type),
typename(o->type));
return NULL;
}
}
}

static int peel_onion(const char *name, int len, unsigned char *sha1)
{
unsigned char outer[20];
Expand Down Expand Up @@ -474,29 +505,17 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
hashcpy(sha1, o->sha1);
}
else {
/* At this point, the syntax look correct, so
/*
* At this point, the syntax look correct, so
* if we do not get the needed object, we should
* barf.
*/

while (1) {
if (!o || (!o->parsed && !parse_object(o->sha1)))
return -1;
if (o->type == expected_type) {
hashcpy(sha1, o->sha1);
return 0;
}
if (o->type == OBJ_TAG)
o = ((struct tag*) o)->tagged;
else if (o->type == OBJ_COMMIT)
o = &(((struct commit *) o)->tree->object);
else
return error("%.*s: expected %s type, but the object dereferences to %s type",
len, name, typename(expected_type),
typename(o->type));
if (!o->parsed)
parse_object(o->sha1);
o = peel_to_type(name, len, o, expected_type);
if (o) {
hashcpy(sha1, o->sha1);
return 0;
}
return -1;
}
return 0;
}
Expand Down

0 comments on commit 8177631

Please sign in to comment.