From 8177631547e4d10ae071def07eff83e056092bfa Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 24 Dec 2007 00:51:01 -0800 Subject: [PATCH] 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 --- cache.h | 3 +++ sha1_name.c | 57 +++++++++++++++++++++++++++++++++++------------------ 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/cache.h b/cache.h index e1000bccb..4bfb1ba49 100644 --- a/cache.h +++ b/cache.h @@ -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, diff --git a/sha1_name.c b/sha1_name.c index ed3c867d6..739f1b2d4 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -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]; @@ -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; } -- 2.30.2