expose a helper function peel_to_type().

This helper function is the core of "$object^{type}" parser.
Now it is made available to callers outside sha1_name.c
This commit is contained in:
Junio C Hamano 2007-12-24 00:51:01 -08:00
parent 525ab63950
commit 8177631547
2 changed files with 41 additions and 19 deletions

View File

@ -499,6 +499,9 @@ extern void *read_object_with_reference(const unsigned char *sha1,
unsigned long *size, unsigned long *size,
unsigned char *sha1_ret); unsigned char *sha1_ret);
extern struct object *peel_to_type(const char *name, int namelen,
struct object *o, enum object_type);
enum date_mode { enum date_mode {
DATE_NORMAL = 0, DATE_NORMAL = 0,
DATE_RELATIVE, DATE_RELATIVE,

View File

@ -423,6 +423,37 @@ static int get_nth_ancestor(const char *name, int len,
return 0; 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) static int peel_onion(const char *name, int len, unsigned char *sha1)
{ {
unsigned char outer[20]; unsigned char outer[20];
@ -474,29 +505,17 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
hashcpy(sha1, o->sha1); hashcpy(sha1, o->sha1);
} }
else { 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 * if we do not get the needed object, we should
* barf. * barf.
*/ */
o = peel_to_type(name, len, o, expected_type);
while (1) { if (o) {
if (!o || (!o->parsed && !parse_object(o->sha1))) hashcpy(sha1, o->sha1);
return -1; return 0;
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);
} }
return -1;
} }
return 0; return 0;
} }