From d65a16f6c45c9b2a16f3abc45f727dc6507c853d Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 26 Feb 2007 14:55:55 -0500 Subject: sha1_file.c: cleanup hdr usage Let's have hdr be a simple char pointer/array when possible, and let's reduce its storage to 32 bytes. Especially for sha1_loose_object_info() where 128 bytes is way excessive and wastes extra CPU cycles inflating. The object type is already restricted to 10 bytes in parse_sha1_header() and the size, even if it is 64 bits, will fit in 20 decimal numbers. So 32 bytes is plenty. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano diff --git a/sha1_file.c b/sha1_file.c index 9a1dee0..57a9b53 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1461,7 +1461,7 @@ static int sha1_loose_object_info(const unsigned char *sha1, char *type, unsigne unsigned long mapsize, size; void *map; z_stream stream; - char hdr[128]; + char hdr[32]; map = map_sha1_file(sha1, &mapsize); if (!map) @@ -1628,12 +1628,12 @@ void *read_object_with_reference(const unsigned char *sha1, static void write_sha1_file_prepare(void *buf, unsigned long len, const char *type, unsigned char *sha1, - unsigned char *hdr, int *hdrlen) + char *hdr, int *hdrlen) { SHA_CTX c; /* Generate the header */ - *hdrlen = sprintf((char *)hdr, "%s %lu", type, len)+1; + *hdrlen = sprintf(hdr, "%s %lu", type, len)+1; /* Sha1.. */ SHA1_Init(&c); @@ -1740,7 +1740,7 @@ static int write_binary_header(unsigned char *hdr, enum object_type type, unsign static void setup_object_header(z_stream *stream, const char *type, unsigned long len) { - int obj_type, hdr; + int obj_type, hdrlen; if (use_legacy_headers) { while (deflate(stream, 0) == Z_OK) @@ -1757,16 +1757,16 @@ static void setup_object_header(z_stream *stream, const char *type, unsigned lon obj_type = OBJ_TAG; else die("trying to generate bogus object of type '%s'", type); - hdr = write_binary_header(stream->next_out, obj_type, len); - stream->total_out = hdr; - stream->next_out += hdr; - stream->avail_out -= hdr; + hdrlen = write_binary_header(stream->next_out, obj_type, len); + stream->total_out = hdrlen; + stream->next_out += hdrlen; + stream->avail_out -= hdrlen; } int hash_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1) { - unsigned char hdr[50]; + char hdr[32]; int hdrlen; write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen); return 0; @@ -1780,7 +1780,7 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha unsigned char sha1[20]; char *filename; static char tmpfile[PATH_MAX]; - unsigned char hdr[50]; + char hdr[32]; int fd, hdrlen; /* Normally if we have it in the pack then we do not bother writing @@ -1827,7 +1827,7 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha stream.avail_out = size; /* First header.. */ - stream.next_in = hdr; + stream.next_in = (unsigned char *)hdr; stream.avail_in = hdrlen; setup_object_header(&stream, type, len); @@ -1859,7 +1859,7 @@ static void *repack_object(const unsigned char *sha1, unsigned long *objsize) unsigned char *unpacked; unsigned long len; char type[20]; - char hdr[50]; + char hdr[32]; int hdrlen; void *buf; -- cgit v0.10.2-6-g49f6 From 2b87c45ba6f8950ffc44cb6a3c861ad2e5f176a8 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 26 Feb 2007 14:55:56 -0500 Subject: sha1_file.c: cleanup "offset" usage First there are too many offsets there and it is getting confusing. So 'offset' is now 'curpos' to distinguish from other offsets like 'obj_offset'. Then structures like x = foo(x, &y) are now done as y = foo(&x). It looks more natural that the result y be returned directly and x be passed as reference to be updated in place. This has the effect of reducing some line length and removing a few, needing a bit less stack space, and it even reduces the compiled code size. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano diff --git a/sha1_file.c b/sha1_file.c index 57a9b53..8147a4f 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1043,12 +1043,11 @@ void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned l static unsigned long get_delta_base(struct packed_git *p, struct pack_window **w_curs, - unsigned long offset, + unsigned long *curpos, enum object_type kind, - unsigned long delta_obj_offset, - unsigned long *base_obj_offset) + unsigned long delta_obj_offset) { - unsigned char *base_info = use_pack(p, w_curs, offset, NULL); + unsigned char *base_info = use_pack(p, w_curs, *curpos, NULL); unsigned long base_offset; /* use_pack() assured us we have [base_info, base_info + 20) @@ -1071,18 +1070,17 @@ static unsigned long get_delta_base(struct packed_git *p, base_offset = delta_obj_offset - base_offset; if (base_offset >= delta_obj_offset) die("delta base offset out of bound"); - offset += used; + *curpos += used; } else if (kind == OBJ_REF_DELTA) { /* The base entry _must_ be in the same pack */ base_offset = find_pack_entry_one(base_info, p); if (!base_offset) die("failed to find delta-pack base object %s", sha1_to_hex(base_info)); - offset += 20; + *curpos += 20; } else die("I am totally screwed"); - *base_obj_offset = base_offset; - return offset; + return base_offset; } /* forward declaration for a mutually recursive function */ @@ -1091,7 +1089,7 @@ static int packed_object_info(struct packed_git *p, unsigned long offset, static int packed_delta_info(struct packed_git *p, struct pack_window **w_curs, - unsigned long offset, + unsigned long curpos, enum object_type kind, unsigned long obj_offset, char *type, @@ -1099,8 +1097,7 @@ static int packed_delta_info(struct packed_git *p, { unsigned long base_offset; - offset = get_delta_base(p, w_curs, offset, kind, - obj_offset, &base_offset); + base_offset = get_delta_base(p, w_curs, &curpos, kind, obj_offset); /* We choose to only get the type of the base object and * ignore potentially corrupt pack file that expects the delta @@ -1113,7 +1110,6 @@ static int packed_delta_info(struct packed_git *p, if (sizep) { const unsigned char *data; unsigned char delta_head[20], *in; - unsigned long result_size; z_stream stream; int st; @@ -1123,10 +1119,10 @@ static int packed_delta_info(struct packed_git *p, inflateInit(&stream); do { - in = use_pack(p, w_curs, offset, &stream.avail_in); + in = use_pack(p, w_curs, curpos, &stream.avail_in); stream.next_in = in; st = inflate(&stream, Z_FINISH); - offset += stream.next_in - in; + curpos += stream.next_in - in; } while ((st == Z_OK || st == Z_BUF_ERROR) && stream.total_out < sizeof(delta_head)); inflateEnd(&stream); @@ -1143,21 +1139,20 @@ static int packed_delta_info(struct packed_git *p, get_delta_hdr_size(&data, delta_head+sizeof(delta_head)); /* Read the result size */ - result_size = get_delta_hdr_size(&data, delta_head+sizeof(delta_head)); - *sizep = result_size; + *sizep = get_delta_hdr_size(&data, delta_head+sizeof(delta_head)); } return 0; } -static unsigned long unpack_object_header(struct packed_git *p, - struct pack_window **w_curs, - unsigned long offset, - enum object_type *type, - unsigned long *sizep) +static int unpack_object_header(struct packed_git *p, + struct pack_window **w_curs, + unsigned long *curpos, + unsigned long *sizep) { unsigned char *base; unsigned int left; unsigned long used; + enum object_type type; /* use_pack() assures us we have [base, base + 20) available * as a range that we can look at at. (Its actually the hash @@ -1165,16 +1160,17 @@ static unsigned long unpack_object_header(struct packed_git *p, * the maximum deflated object size is 2^137, which is just * insane, so we know won't exceed what we have been given. */ - base = use_pack(p, w_curs, offset, &left); - used = unpack_object_header_gently(base, left, type, sizep); + base = use_pack(p, w_curs, *curpos, &left); + used = unpack_object_header_gently(base, left, &type, sizep); if (!used) die("object offset outside of pack file"); + *curpos += used; - return offset + used; + return type; } void packed_object_info_detail(struct packed_git *p, - unsigned long offset, + unsigned long obj_offset, char *type, unsigned long *size, unsigned long *store_size, @@ -1182,13 +1178,13 @@ void packed_object_info_detail(struct packed_git *p, unsigned char *base_sha1) { struct pack_window *w_curs = NULL; - unsigned long obj_offset, val; + unsigned long curpos, dummy; unsigned char *next_sha1; enum object_type kind; *delta_chain_length = 0; - obj_offset = offset; - offset = unpack_object_header(p, &w_curs, offset, &kind, size); + curpos = obj_offset; + kind = unpack_object_header(p, &w_curs, &curpos, size); for (;;) { switch (kind) { @@ -1204,61 +1200,58 @@ void packed_object_info_detail(struct packed_git *p, unuse_pack(&w_curs); return; case OBJ_OFS_DELTA: - get_delta_base(p, &w_curs, offset, kind, - obj_offset, &offset); + obj_offset = get_delta_base(p, &w_curs, &curpos, kind, obj_offset); if (*delta_chain_length == 0) { - /* TODO: find base_sha1 as pointed by offset */ + /* TODO: find base_sha1 as pointed by curpos */ } break; case OBJ_REF_DELTA: - next_sha1 = use_pack(p, &w_curs, offset, NULL); + next_sha1 = use_pack(p, &w_curs, curpos, NULL); if (*delta_chain_length == 0) hashcpy(base_sha1, next_sha1); - offset = find_pack_entry_one(next_sha1, p); + obj_offset = find_pack_entry_one(next_sha1, p); break; } - obj_offset = offset; - offset = unpack_object_header(p, &w_curs, offset, &kind, &val); (*delta_chain_length)++; + curpos = obj_offset; + kind = unpack_object_header(p, &w_curs, &curpos, &dummy); } } -static int packed_object_info(struct packed_git *p, unsigned long offset, +static int packed_object_info(struct packed_git *p, unsigned long obj_offset, char *type, unsigned long *sizep) { struct pack_window *w_curs = NULL; - unsigned long size, obj_offset = offset; + unsigned long size, curpos = obj_offset; enum object_type kind; - int r; - offset = unpack_object_header(p, &w_curs, offset, &kind, &size); + kind = unpack_object_header(p, &w_curs, &curpos, &size); switch (kind) { case OBJ_OFS_DELTA: case OBJ_REF_DELTA: - r = packed_delta_info(p, &w_curs, offset, kind, - obj_offset, type, sizep); - unuse_pack(&w_curs); - return r; + packed_delta_info(p, &w_curs, curpos, kind, + obj_offset, type, sizep); + break; case OBJ_COMMIT: case OBJ_TREE: case OBJ_BLOB: case OBJ_TAG: strcpy(type, type_names[kind]); - unuse_pack(&w_curs); + if (sizep) + *sizep = size; break; default: die("pack %s contains unknown object type %d", p->pack_name, kind); } - if (sizep) - *sizep = size; + unuse_pack(&w_curs); return 0; } static void *unpack_compressed_entry(struct packed_git *p, struct pack_window **w_curs, - unsigned long offset, + unsigned long curpos, unsigned long size) { int st; @@ -1273,10 +1266,10 @@ static void *unpack_compressed_entry(struct packed_git *p, inflateInit(&stream); do { - in = use_pack(p, w_curs, offset, &stream.avail_in); + in = use_pack(p, w_curs, curpos, &stream.avail_in); stream.next_in = in; st = inflate(&stream, Z_FINISH); - offset += stream.next_in - in; + curpos += stream.next_in - in; } while (st == Z_OK || st == Z_BUF_ERROR); inflateEnd(&stream); if ((st != Z_STREAM_END) || stream.total_out != size) { @@ -1289,7 +1282,7 @@ static void *unpack_compressed_entry(struct packed_git *p, static void *unpack_delta_entry(struct packed_git *p, struct pack_window **w_curs, - unsigned long offset, + unsigned long curpos, unsigned long delta_size, enum object_type kind, unsigned long obj_offset, @@ -1299,14 +1292,13 @@ static void *unpack_delta_entry(struct packed_git *p, void *delta_data, *result, *base; unsigned long result_size, base_size, base_offset; - offset = get_delta_base(p, w_curs, offset, kind, - obj_offset, &base_offset); + base_offset = get_delta_base(p, w_curs, &curpos, kind, obj_offset); base = unpack_entry(p, base_offset, type, &base_size); if (!base) die("failed to read delta base object at %lu from %s", base_offset, p->pack_name); - delta_data = unpack_compressed_entry(p, w_curs, offset, delta_size); + delta_data = unpack_compressed_entry(p, w_curs, curpos, delta_size); result = patch_delta(base, base_size, delta_data, delta_size, &result_size); @@ -1318,19 +1310,19 @@ static void *unpack_delta_entry(struct packed_git *p, return result; } -void *unpack_entry(struct packed_git *p, unsigned long offset, - char *type, unsigned long *sizep) +void *unpack_entry(struct packed_git *p, unsigned long obj_offset, + char *type, unsigned long *sizep) { struct pack_window *w_curs = NULL; - unsigned long size, obj_offset = offset; + unsigned long size, curpos = obj_offset; enum object_type kind; void *retval; - offset = unpack_object_header(p, &w_curs, offset, &kind, &size); + kind = unpack_object_header(p, &w_curs, &curpos, &size); switch (kind) { case OBJ_OFS_DELTA: case OBJ_REF_DELTA: - retval = unpack_delta_entry(p, &w_curs, offset, size, + retval = unpack_delta_entry(p, &w_curs, curpos, size, kind, obj_offset, type, sizep); break; case OBJ_COMMIT: @@ -1339,7 +1331,7 @@ void *unpack_entry(struct packed_git *p, unsigned long offset, case OBJ_TAG: strcpy(type, type_names[kind]); *sizep = size; - retval = unpack_compressed_entry(p, &w_curs, offset, size); + retval = unpack_compressed_entry(p, &w_curs, curpos, size); break; default: die("unknown object type %i in %s", kind, p->pack_name); -- cgit v0.10.2-6-g49f6 From 9ba630318f6fbc2f129e5a6872d70d2914cacb39 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 26 Feb 2007 14:55:57 -0500 Subject: sha1_file.c: don't ignore an error condition in sha1_loose_object_info() Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano diff --git a/sha1_file.c b/sha1_file.c index 8147a4f..8b7b68c 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1461,7 +1461,7 @@ static int sha1_loose_object_info(const unsigned char *sha1, char *type, unsigne if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0) status = error("unable to unpack %s header", sha1_to_hex(sha1)); - if (parse_sha1_header(hdr, type, &size) < 0) + else if (parse_sha1_header(hdr, type, &size) < 0) status = error("unable to parse %s header", sha1_to_hex(sha1)); else { status = 0; -- cgit v0.10.2-6-g49f6 From df8436622fb553f468180b61032fe34bd6712752 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 26 Feb 2007 14:55:58 -0500 Subject: formalize typename(), and add its reverse type_from_string() Sometime typename() is used, sometimes type_names[] is accessed directly. Let's enforce typename() all the time which allows for validating the type. Also let's add a function to go from a name to a type and use it instead of manual memcpy() when appropriate. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c index ac0b9f6..14fff2b 100644 --- a/builtin-for-each-ref.c +++ b/builtin-for-each-ref.c @@ -196,7 +196,7 @@ static void grab_common_values(struct atom_value *val, int deref, struct object if (deref) name++; if (!strcmp(name, "objecttype")) - v->s = type_names[obj->type]; + v->s = typename(obj->type); else if (!strcmp(name, "objectsize")) { char *s = xmalloc(40); sprintf(s, "%lu", sz); diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 426ffdd..1c04618 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -1065,18 +1065,7 @@ static void check_object(struct object_entry *entry) if (sha1_object_info(entry->sha1, type, &entry->size)) die("unable to get type of object %s", sha1_to_hex(entry->sha1)); - - if (!strcmp(type, commit_type)) { - entry->type = OBJ_COMMIT; - } else if (!strcmp(type, tree_type)) { - entry->type = OBJ_TREE; - } else if (!strcmp(type, blob_type)) { - entry->type = OBJ_BLOB; - } else if (!strcmp(type, tag_type)) { - entry->type = OBJ_TAG; - } else - die("unable to pack object %s of type %s", - sha1_to_hex(entry->sha1), type); + entry->type = type_from_string(type); } static unsigned int check_delta_limit(struct object_entry *me, unsigned int n) diff --git a/fast-import.c b/fast-import.c index 5d040fd..aa9eac3 100644 --- a/fast-import.c +++ b/fast-import.c @@ -891,7 +891,7 @@ static int store_object( SHA_CTX c; z_stream s; - hdrlen = sprintf((char*)hdr,"%s %lu", type_names[type], + hdrlen = sprintf((char*)hdr,"%s %lu", typename(type), (unsigned long)datlen) + 1; SHA1_Init(&c); SHA1_Update(&c, hdr, hdrlen); @@ -1626,7 +1626,7 @@ static void file_change_m(struct branch *b) } else if (oe) { if (oe->type != OBJ_BLOB) die("Not a blob (actually a %s): %s", - command_buf.buf, type_names[oe->type]); + command_buf.buf, typename(oe->type)); } else { if (sha1_object_info(sha1, type, NULL)) die("Blob not found: %s", command_buf.buf); @@ -1711,7 +1711,7 @@ static void cmd_from(struct branch *b) char *buf; buf = read_object_with_reference(b->sha1, - type_names[OBJ_COMMIT], &size, b->sha1); + commit_type, &size, b->sha1); if (!buf || size < 46) die("Not a valid commit: %s", from); if (memcmp("tree ", buf, 5) @@ -1895,7 +1895,7 @@ static void cmd_new_tag(void) char *buf; buf = read_object_with_reference(sha1, - type_names[OBJ_COMMIT], &size, sha1); + commit_type, &size, sha1); if (!buf || size < 46) die("Not a valid commit: %s", from); free(buf); @@ -1916,7 +1916,7 @@ static void cmd_new_tag(void) size_dbuf(&new_data, 67+strlen(t->name)+strlen(tagger)+msglen); sp = new_data.buffer; sp += sprintf(sp, "object %s\n", sha1_to_hex(sha1)); - sp += sprintf(sp, "type %s\n", type_names[OBJ_COMMIT]); + sp += sprintf(sp, "type %s\n", commit_type); sp += sprintf(sp, "tag %s\n", t->name); sp += sprintf(sp, "tagger %s\n", tagger); *sp++ = '\n'; diff --git a/index-pack.c b/index-pack.c index fa9a0e7..4b52785 100644 --- a/index-pack.c +++ b/index-pack.c @@ -604,13 +604,8 @@ static void fix_unresolved_deltas(int nr_unresolved) data = read_sha1_file(d->base.sha1, type, &size); if (!data) continue; - if (!strcmp(type, blob_type)) obj_type = OBJ_BLOB; - else if (!strcmp(type, tree_type)) obj_type = OBJ_TREE; - else if (!strcmp(type, commit_type)) obj_type = OBJ_COMMIT; - else if (!strcmp(type, tag_type)) obj_type = OBJ_TAG; - else die("base object %s is of type '%s'", - sha1_to_hex(d->base.sha1), type); + obj_type = type_from_string(type); find_delta_children(&d->base, &first, &last); for (j = first; j <= last; j++) { struct object_entry *child = objects + deltas[j].obj_no; diff --git a/object.c b/object.c index de244e2..37cedc0 100644 --- a/object.c +++ b/object.c @@ -18,11 +18,31 @@ struct object *get_indexed_object(unsigned int idx) return obj_hash[idx]; } -const char *type_names[] = { - "none", "commit", "tree", "blob", "tag", - "bad type 5", "bad type 6", "delta", "bad", +static const char *object_type_strings[] = { + NULL, /* OBJ_NONE = 0 */ + "commit", /* OBJ_COMMIT = 1 */ + "tree", /* OBJ_TREE = 2 */ + "blob", /* OBJ_BLOB = 3 */ + "tag", /* OBJ_TAG = 4 */ }; +const char *typename(unsigned int type) +{ + if (type >= ARRAY_SIZE(object_type_strings)) + return NULL; + return object_type_strings[type]; +} + +int type_from_string(const char *str) +{ + int i; + + for (i = 1; i < ARRAY_SIZE(object_type_strings); i++) + if (!strcmp(str, object_type_strings[i])) + return i; + die("invalid object type \"%s\"", str); +} + static unsigned int hash_obj(struct object *obj, unsigned int n) { unsigned int hash = *(unsigned int *)obj->sha1; diff --git a/object.h b/object.h index caee733..ade4dae 100644 --- a/object.h +++ b/object.h @@ -36,16 +36,12 @@ struct object { }; extern int track_object_refs; -extern const char *type_names[9]; + +extern const char *typename(unsigned int type); +extern int type_from_string(const char *str); extern unsigned int get_max_object_index(void); extern struct object *get_indexed_object(unsigned int); - -static inline const char *typename(unsigned int type) -{ - return type_names[type > OBJ_BAD ? OBJ_BAD : type]; -} - extern struct object_refs *lookup_object_refs(struct object *); /** Internal only **/ diff --git a/sha1_file.c b/sha1_file.c index 8b7b68c..423ff0a 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -952,7 +952,7 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon /* And generate the fake traditional header */ stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu", - type_names[type], size); + typename(type), size); return 0; } @@ -1195,7 +1195,7 @@ void packed_object_info_detail(struct packed_git *p, case OBJ_TREE: case OBJ_BLOB: case OBJ_TAG: - strcpy(type, type_names[kind]); + strcpy(type, typename(kind)); *store_size = 0; /* notyet */ unuse_pack(&w_curs); return; @@ -1237,7 +1237,7 @@ static int packed_object_info(struct packed_git *p, unsigned long obj_offset, case OBJ_TREE: case OBJ_BLOB: case OBJ_TAG: - strcpy(type, type_names[kind]); + strcpy(type, typename(kind)); if (sizep) *sizep = size; break; @@ -1329,7 +1329,7 @@ void *unpack_entry(struct packed_git *p, unsigned long obj_offset, case OBJ_TREE: case OBJ_BLOB: case OBJ_TAG: - strcpy(type, type_names[kind]); + strcpy(type, typename(kind)); *sizep = size; retval = unpack_compressed_entry(p, &w_curs, curpos, size); break; @@ -1739,16 +1739,7 @@ static void setup_object_header(z_stream *stream, const char *type, unsigned lon /* nothing */; return; } - if (!strcmp(type, blob_type)) - obj_type = OBJ_BLOB; - else if (!strcmp(type, tree_type)) - obj_type = OBJ_TREE; - else if (!strcmp(type, commit_type)) - obj_type = OBJ_COMMIT; - else if (!strcmp(type, tag_type)) - obj_type = OBJ_TAG; - else - die("trying to generate bogus object of type '%s'", type); + obj_type = type_from_string(type); hdrlen = write_binary_header(stream->next_out, obj_type, len); stream->total_out = hdrlen; stream->next_out += hdrlen; -- cgit v0.10.2-6-g49f6 From 21666f1aae4e890d8f50924f9e80763b27e6a45d Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 26 Feb 2007 14:55:59 -0500 Subject: convert object type handling from a string to a number We currently have two parallel notation for dealing with object types in the code: a string and a numerical value. One of them is obviously redundent, and the most used one requires more stack space and a bunch of strcmp() all over the place. This is an initial step for the removal of the version using a char array found in object reading code paths. The patch is unfortunately large but there is no sane way to split it in smaller parts without breaking the system. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano diff --git a/archive-tar.c b/archive-tar.c index 7d52a06..d9c30d3 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -262,7 +262,7 @@ static int write_tar_entry(const unsigned char *sha1, static struct strbuf path; int filenamelen = strlen(filename); void *buffer; - char type[20]; + enum object_type type; unsigned long size; if (!path.alloc) { @@ -283,7 +283,7 @@ static int write_tar_entry(const unsigned char *sha1, buffer = NULL; size = 0; } else { - buffer = read_sha1_file(sha1, type, &size); + buffer = read_sha1_file(sha1, &type, &size); if (!buffer) die("cannot read %s", sha1_to_hex(sha1)); } diff --git a/archive-zip.c b/archive-zip.c index f31b8ed..7c49848 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -167,7 +167,7 @@ static int write_zip_entry(const unsigned char *sha1, int pathlen; unsigned char *out; char *path; - char type[20]; + enum object_type type; void *buffer = NULL; void *deflated = NULL; @@ -195,7 +195,7 @@ static int write_zip_entry(const unsigned char *sha1, if (S_ISREG(mode) && zlib_compression_level != 0) method = 8; result = 0; - buffer = read_sha1_file(sha1, type, &size); + buffer = read_sha1_file(sha1, &type, &size); if (!buffer) die("cannot read %s", sha1_to_hex(sha1)); crc = crc32(crc, buffer, size); diff --git a/blob.c b/blob.c index 9776bea..0a9ea41 100644 --- a/blob.c +++ b/blob.c @@ -30,18 +30,18 @@ int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size) int parse_blob(struct blob *item) { - char type[20]; + enum object_type type; void *buffer; unsigned long size; int ret; if (item->object.parsed) return 0; - buffer = read_sha1_file(item->object.sha1, type, &size); + buffer = read_sha1_file(item->object.sha1, &type, &size); if (!buffer) return error("Could not read %s", sha1_to_hex(item->object.sha1)); - if (strcmp(type, blob_type)) + if (type != OBJ_BLOB) return error("Object %s not a blob", sha1_to_hex(item->object.sha1)); ret = parse_blob_buffer(item, buffer, size); diff --git a/builtin-apply.c b/builtin-apply.c index b84d747..38f6475 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -1912,11 +1912,11 @@ static int apply_binary(struct buffer_desc *desc, struct patch *patch) if (has_sha1_file(sha1)) { /* We already have the postimage */ - char type[10]; + enum object_type type; unsigned long size; free(desc->buffer); - desc->buffer = read_sha1_file(sha1, type, &size); + desc->buffer = read_sha1_file(sha1, &type, &size); if (!desc->buffer) return error("the necessary postimage %s for " "'%s' cannot be read", @@ -1972,8 +1972,8 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry * buf = NULL; if (cached) { if (ce) { - char type[20]; - buf = read_sha1_file(ce->sha1, type, &size); + enum object_type type; + buf = read_sha1_file(ce->sha1, &type, &size); if (!buf) return error("read of %s failed", patch->old_name); diff --git a/builtin-blame.c b/builtin-blame.c index 530b97f..9f7dd4e 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -87,9 +87,9 @@ struct origin { static char *fill_origin_blob(struct origin *o, mmfile_t *file) { if (!o->file.ptr) { - char type[10]; + enum object_type type; num_read_blob++; - file->ptr = read_sha1_file(o->blob_sha1, type, + file->ptr = read_sha1_file(o->blob_sha1, &type, (unsigned long *)(&(file->size))); o->file = *file; } @@ -263,7 +263,6 @@ static struct origin *get_origin(struct scoreboard *sb, static int fill_blob_sha1(struct origin *origin) { unsigned mode; - char type[10]; if (!is_null_sha1(origin->blob_sha1)) return 0; @@ -271,8 +270,7 @@ static int fill_blob_sha1(struct origin *origin) origin->path, origin->blob_sha1, &mode)) goto error_out; - if (sha1_object_info(origin->blob_sha1, type, NULL) || - strcmp(type, blob_type)) + if (sha1_object_info(origin->blob_sha1, NULL) != OBJ_BLOB) goto error_out; return 0; error_out: @@ -1322,10 +1320,10 @@ static void get_commit_info(struct commit *commit, * we now need to populate them for output. */ if (!commit->buffer) { - char type[20]; + enum object_type type; unsigned long size; commit->buffer = - read_sha1_file(commit->object.sha1, type, &size); + read_sha1_file(commit->object.sha1, &type, &size); } ret->author = author_buf; get_ac_line(commit->buffer, "\nauthor ", @@ -2006,7 +2004,7 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con buf[fin_size] = 0; origin->file.ptr = buf; origin->file.size = fin_size; - pretend_sha1_file(buf, fin_size, blob_type, origin->blob_sha1); + pretend_sha1_file(buf, fin_size, OBJ_BLOB, origin->blob_sha1); commit->util = origin; /* @@ -2068,7 +2066,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) int show_stats = 0; const char *revs_file = NULL; const char *final_commit_name = NULL; - char type[10]; + enum object_type type; const char *bottomtop = NULL; const char *contents_from = NULL; @@ -2302,7 +2300,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) if (fill_blob_sha1(o)) die("no such path %s in %s", path, final_commit_name); - sb.final_buf = read_sha1_file(o->blob_sha1, type, + sb.final_buf = read_sha1_file(o->blob_sha1, &type, &sb.final_buf_size); } num_read_blob++; diff --git a/builtin-cat-file.c b/builtin-cat-file.c index 6c16bfa..d61d3d5 100644 --- a/builtin-cat-file.c +++ b/builtin-cat-file.c @@ -79,7 +79,7 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long int cmd_cat_file(int argc, const char **argv, const char *prefix) { unsigned char sha1[20]; - char type[20]; + enum object_type type; void *buf; unsigned long size; int opt; @@ -100,14 +100,16 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix) buf = NULL; switch (opt) { case 't': - if (!sha1_object_info(sha1, type, NULL)) { - printf("%s\n", type); + type = sha1_object_info(sha1, NULL); + if (type > 0) { + printf("%s\n", typename(type)); return 0; } break; case 's': - if (!sha1_object_info(sha1, type, &size)) { + type = sha1_object_info(sha1, &size); + if (type > 0) { printf("%lu\n", size); return 0; } @@ -117,17 +119,18 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix) return !has_sha1_file(sha1); case 'p': - if (sha1_object_info(sha1, type, NULL)) + type = sha1_object_info(sha1, NULL); + if (type < 0) die("Not a valid object name %s", argv[2]); /* custom pretty-print here */ - if (!strcmp(type, tree_type)) + if (type == OBJ_TREE) return cmd_ls_tree(2, argv + 1, NULL); - buf = read_sha1_file(sha1, type, &size); + buf = read_sha1_file(sha1, &type, &size); if (!buf) die("Cannot read object %s", argv[2]); - if (!strcmp(type, tag_type)) { + if (type == OBJ_TAG) { pprint_tag(sha1, buf, size); return 0; } diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c index 2a818a0..04f61d5 100644 --- a/builtin-commit-tree.c +++ b/builtin-commit-tree.c @@ -47,11 +47,10 @@ static void add_buffer(char **bufp, unsigned int *sizep, const char *fmt, ...) static void check_valid(unsigned char *sha1, const char *expect) { - char type[20]; - - if (sha1_object_info(sha1, type, NULL)) + enum object_type type = sha1_object_info(sha1, NULL); + if (type < 0) die("%s is not a valid object", sha1_to_hex(sha1)); - if (expect && strcmp(type, expect)) + if (expect && type != type_from_string(expect)) die("%s is not a valid '%s' object", sha1_to_hex(sha1), expect); } diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c index 14fff2b..b11ca92 100644 --- a/builtin-for-each-ref.c +++ b/builtin-for-each-ref.c @@ -173,8 +173,8 @@ static void verify_format(const char *format) */ static void *get_obj(const unsigned char *sha1, struct object **obj, unsigned long *sz, int *eaten) { - char type[20]; - void *buf = read_sha1_file(sha1, type, sz); + enum object_type type; + void *buf = read_sha1_file(sha1, &type, sz); if (buf) *obj = parse_object_buffer(sha1, type, *sz, buf, eaten); diff --git a/builtin-grep.c b/builtin-grep.c index f35f2d0..96b7022 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -84,11 +84,11 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1, const char { unsigned long size; char *data; - char type[20]; + enum object_type type; char *to_free = NULL; int hit; - data = read_sha1_file(sha1, type, &size); + data = read_sha1_file(sha1, &type, &size); if (!data) { error("'%s': unable to read %s", name, sha1_to_hex(sha1)); return 0; @@ -380,10 +380,10 @@ static int grep_tree(struct grep_opt *opt, const char **paths, else if (S_ISREG(entry.mode)) hit |= grep_sha1(opt, entry.sha1, path_buf, tn_len); else if (S_ISDIR(entry.mode)) { - char type[20]; + enum object_type type; struct tree_desc sub; void *data; - data = read_sha1_file(entry.sha1, type, &sub.size); + data = read_sha1_file(entry.sha1, &type, &sub.size); if (!data) die("unable to read tree (%s)", sha1_to_hex(entry.sha1)); diff --git a/builtin-log.c b/builtin-log.c index f43790c..1c9f7d0 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -89,8 +89,8 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix) static int show_object(const unsigned char *sha1, int suppress_header) { unsigned long size; - char type[20]; - char *buf = read_sha1_file(sha1, type, &size); + enum object_type type; + char *buf = read_sha1_file(sha1, &type, &size); int offset = 0; if (!buf) diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 1c04618..8cf24f4 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -230,8 +230,8 @@ static unsigned char *find_packed_object_name(struct packed_git *p, static void *delta_against(void *buf, unsigned long size, struct object_entry *entry) { unsigned long othersize, delta_size; - char type[10]; - void *otherbuf = read_sha1_file(entry->delta->sha1, type, &othersize); + enum object_type type; + void *otherbuf = read_sha1_file(entry->delta->sha1, &type, &othersize); void *delta_buf; if (!otherbuf) @@ -375,7 +375,7 @@ static unsigned long write_object(struct sha1file *f, struct object_entry *entry) { unsigned long size; - char type[10]; + enum object_type type; void *buf; unsigned char header[10]; unsigned hdrlen, datalen; @@ -416,7 +416,7 @@ static unsigned long write_object(struct sha1file *f, } if (!to_reuse) { - buf = read_sha1_file(entry->sha1, type, &size); + buf = read_sha1_file(entry->sha1, &type, &size); if (!buf) die("unable to read %s", sha1_to_hex(entry->sha1)); if (size != entry->size) @@ -765,7 +765,7 @@ static struct pbase_tree_cache *pbase_tree_get(const unsigned char *sha1) struct pbase_tree_cache *ent, *nent; void *data; unsigned long size; - char type[20]; + enum object_type type; int neigh; int my_ix = pbase_tree_cache_ix(sha1); int available_ix = -1; @@ -792,10 +792,10 @@ static struct pbase_tree_cache *pbase_tree_get(const unsigned char *sha1) /* Did not find one. Either we got a bogus request or * we need to read and perhaps cache. */ - data = read_sha1_file(sha1, type, &size); + data = read_sha1_file(sha1, &type, &size); if (!data) return NULL; - if (strcmp(type, tree_type)) { + if (type != OBJ_TREE) { free(data); return NULL; } @@ -854,19 +854,19 @@ static void add_pbase_object(struct tree_desc *tree, while (tree_entry(tree,&entry)) { unsigned long size; - char type[20]; + enum object_type type; if (entry.pathlen != cmplen || memcmp(entry.path, name, cmplen) || !has_sha1_file(entry.sha1) || - sha1_object_info(entry.sha1, type, &size)) + (type = sha1_object_info(entry.sha1, &size)) < 0) continue; if (name[cmplen] != '/') { unsigned hash = name_hash(fullname); add_object_entry(entry.sha1, hash, 1); return; } - if (!strcmp(type, tree_type)) { + if (type == OBJ_TREE) { struct tree_desc sub; struct pbase_tree_cache *tree; const char *down = name+cmplen+1; @@ -978,8 +978,6 @@ static void add_preferred_base(unsigned char *sha1) static void check_object(struct object_entry *entry) { - char type[20]; - if (entry->in_pack && !entry->preferred_base) { struct packed_git *p = entry->in_pack; struct pack_window *w_curs = NULL; @@ -1062,10 +1060,10 @@ static void check_object(struct object_entry *entry) /* Otherwise we would do the usual */ } - if (sha1_object_info(entry->sha1, type, &entry->size)) + entry->type = sha1_object_info(entry->sha1, &entry->size); + if (entry->type < 0) die("unable to get type of object %s", sha1_to_hex(entry->sha1)); - entry->type = type_from_string(type); } static unsigned int check_delta_limit(struct object_entry *me, unsigned int n) @@ -1195,7 +1193,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, struct object_entry *trg_entry = trg->entry; struct object_entry *src_entry = src->entry; unsigned long trg_size, src_size, delta_size, sizediff, max_size, sz; - char type[10]; + enum object_type type; void *delta_buf; /* Don't bother doing diffs between different types */ @@ -1246,13 +1244,13 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, /* Load data if not already done */ if (!trg->data) { - trg->data = read_sha1_file(trg_entry->sha1, type, &sz); + trg->data = read_sha1_file(trg_entry->sha1, &type, &sz); if (sz != trg_size) die("object %s inconsistent object length (%lu vs %lu)", sha1_to_hex(trg_entry->sha1), sz, trg_size); } if (!src->data) { - src->data = read_sha1_file(src_entry->sha1, type, &sz); + src->data = read_sha1_file(src_entry->sha1, &type, &sz); if (sz != src_size) die("object %s inconsistent object length (%lu vs %lu)", sha1_to_hex(src_entry->sha1), sz, src_size); diff --git a/builtin-prune.c b/builtin-prune.c index 6f0ba0d..09864b7 100644 --- a/builtin-prune.c +++ b/builtin-prune.c @@ -10,15 +10,10 @@ static int show_only; static int prune_object(char *path, const char *filename, const unsigned char *sha1) { - char buf[20]; - const char *type; - if (show_only) { - if (sha1_object_info(sha1, buf, NULL)) - type = "unknown"; - else - type = buf; - printf("%s %s\n", sha1_to_hex(sha1), type); + enum object_type type = sha1_object_info(sha1, NULL); + printf("%s %s\n", sha1_to_hex(sha1), + (type > 0) ? typename(type) : "unknown"); return 0; } unlink(mkpath("%s/%s", path, filename)); diff --git a/builtin-reflog.c b/builtin-reflog.c index cefb40d..186aabc 100644 --- a/builtin-reflog.c +++ b/builtin-reflog.c @@ -55,8 +55,8 @@ static int tree_is_complete(const unsigned char *sha1) desc.buf = tree->buffer; desc.size = tree->size; if (!desc.buf) { - char type[20]; - void *data = read_sha1_file(sha1, type, &desc.size); + enum object_type type; + void *data = read_sha1_file(sha1, &type, &desc.size); if (!data) { tree->object.flags |= INCOMPLETE; return 0; diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c index 8f8e898..3956c56 100644 --- a/builtin-unpack-objects.c +++ b/builtin-unpack-objects.c @@ -119,18 +119,18 @@ struct obj_info { static struct obj_info *obj_list; -static void added_object(unsigned nr, const char *type, void *data, - unsigned long size); +static void added_object(unsigned nr, enum object_type type, + void *data, unsigned long size); -static void write_object(unsigned nr, void *buf, unsigned long size, - const char *type) +static void write_object(unsigned nr, enum object_type type, + void *buf, unsigned long size) { - if (write_sha1_file(buf, size, type, obj_list[nr].sha1) < 0) + if (write_sha1_file(buf, size, typename(type), obj_list[nr].sha1) < 0) die("failed to write object"); added_object(nr, type, buf, size); } -static void resolve_delta(unsigned nr, const char *type, +static void resolve_delta(unsigned nr, enum object_type type, void *base, unsigned long base_size, void *delta, unsigned long delta_size) { @@ -143,12 +143,12 @@ static void resolve_delta(unsigned nr, const char *type, if (!result) die("failed to apply delta"); free(delta); - write_object(nr, result, result_size, type); + write_object(nr, type, result, result_size); free(result); } -static void added_object(unsigned nr, const char *type, void *data, - unsigned long size) +static void added_object(unsigned nr, enum object_type type, + void *data, unsigned long size) { struct delta_info **p = &delta_list; struct delta_info *info; @@ -167,33 +167,24 @@ static void added_object(unsigned nr, const char *type, void *data, } } -static void unpack_non_delta_entry(enum object_type kind, unsigned long size, +static void unpack_non_delta_entry(enum object_type type, unsigned long size, unsigned nr) { void *buf = get_data(size); - const char *type; - - switch (kind) { - case OBJ_COMMIT: type = commit_type; break; - case OBJ_TREE: type = tree_type; break; - case OBJ_BLOB: type = blob_type; break; - case OBJ_TAG: type = tag_type; break; - default: die("bad type %d", kind); - } + if (!dry_run && buf) - write_object(nr, buf, size, type); + write_object(nr, type, buf, size); free(buf); } -static void unpack_delta_entry(enum object_type kind, unsigned long delta_size, +static void unpack_delta_entry(enum object_type type, unsigned long delta_size, unsigned nr) { void *delta_data, *base; unsigned long base_size; - char type[20]; unsigned char base_sha1[20]; - if (kind == OBJ_REF_DELTA) { + if (type == OBJ_REF_DELTA) { hashcpy(base_sha1, fill(20)); use(20); delta_data = get_data(delta_size); @@ -255,7 +246,7 @@ static void unpack_delta_entry(enum object_type kind, unsigned long delta_size, } } - base = read_sha1_file(base_sha1, type, &base_size); + base = read_sha1_file(base_sha1, &type, &base_size); if (!base) { error("failed to read delta-pack base object %s", sha1_to_hex(base_sha1)); diff --git a/cache.h b/cache.h index 8bbc142..0117b7e 100644 --- a/cache.h +++ b/cache.h @@ -262,13 +262,25 @@ int adjust_shared_perm(const char *path); int safe_create_leading_directories(char *path); char *enter_repo(char *path, int strict); +enum object_type { + OBJ_NONE = 0, + OBJ_COMMIT = 1, + OBJ_TREE = 2, + OBJ_BLOB = 3, + OBJ_TAG = 4, + /* 5 for future expansion */ + OBJ_OFS_DELTA = 6, + OBJ_REF_DELTA = 7, + OBJ_BAD, +}; + /* Read and unpack a sha1 file into memory, write memory to a sha1 file */ -extern int sha1_object_info(const unsigned char *, char *, unsigned long *); -extern void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size); -extern void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size); +extern int sha1_object_info(const unsigned char *, unsigned long *); +extern void * unpack_sha1_file(void *map, unsigned long mapsize, enum object_type *type, unsigned long *size); +extern void * read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size); extern int hash_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1); extern int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *return_sha1); -extern int pretend_sha1_file(void *, unsigned long, const char *, unsigned char *); +extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *); extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type); @@ -285,18 +297,6 @@ extern int legacy_loose_object(unsigned char *); extern int has_pack_file(const unsigned char *sha1); extern int has_pack_index(const unsigned char *sha1); -enum object_type { - OBJ_NONE = 0, - OBJ_COMMIT = 1, - OBJ_TREE = 2, - OBJ_BLOB = 3, - OBJ_TAG = 4, - /* 5 for future expansion */ - OBJ_OFS_DELTA = 6, - OBJ_REF_DELTA = 7, - OBJ_BAD, -}; - extern signed char hexval_table[256]; static inline unsigned int hexval(unsigned int c) { @@ -422,9 +422,9 @@ extern struct packed_git *add_packed_git(char *, int, int); extern int num_packed_objects(const struct packed_git *p); extern int nth_packed_object_sha1(const struct packed_git *, int, unsigned char*); extern unsigned long find_pack_entry_one(const unsigned char *, struct packed_git *); -extern void *unpack_entry(struct packed_git *, unsigned long, char *, unsigned long *); +extern void *unpack_entry(struct packed_git *, unsigned long, enum object_type *, unsigned long *); extern unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep); -extern void packed_object_info_detail(struct packed_git *, unsigned long, char *, unsigned long *, unsigned long *, unsigned int *, unsigned char *); +extern const char *packed_object_info_detail(struct packed_git *, unsigned long, unsigned long *, unsigned long *, unsigned int *, unsigned char *); /* Dumb servers support */ extern int update_server_info(int); diff --git a/combine-diff.c b/combine-diff.c index 044633d..9daa0cb 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -92,14 +92,14 @@ struct sline { static char *grab_blob(const unsigned char *sha1, unsigned long *size) { char *blob; - char type[20]; + enum object_type type; if (is_null_sha1(sha1)) { /* deleted blob */ *size = 0; return xcalloc(1, 1); } - blob = read_sha1_file(sha1, type, size); - if (strcmp(type, blob_type)) + blob = read_sha1_file(sha1, &type, size); + if (type != OBJ_BLOB) die("object '%s' is not a blob!", sha1_to_hex(sha1)); return blob; } diff --git a/commit.c b/commit.c index 8d279b0..da515a4 100644 --- a/commit.c +++ b/commit.c @@ -342,18 +342,18 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size) int parse_commit(struct commit *item) { - char type[20]; + enum object_type type; void *buffer; unsigned long size; int ret; if (item->object.parsed) return 0; - buffer = read_sha1_file(item->object.sha1, type, &size); + buffer = read_sha1_file(item->object.sha1, &type, &size); if (!buffer) return error("Could not read %s", sha1_to_hex(item->object.sha1)); - if (strcmp(type, commit_type)) { + if (type != OBJ_COMMIT) { free(buffer); return error("Object %s not a commit", sha1_to_hex(item->object.sha1)); diff --git a/convert-objects.c b/convert-objects.c index a630132..b5f41ae 100644 --- a/convert-objects.c +++ b/convert-objects.c @@ -284,27 +284,27 @@ static void convert_commit(void *buffer, unsigned long size, unsigned char *resu static struct entry * convert_entry(unsigned char *sha1) { struct entry *entry = lookup_entry(sha1); - char type[20]; + enum object_type type; void *buffer, *data; unsigned long size; if (entry->converted) return entry; - data = read_sha1_file(sha1, type, &size); + data = read_sha1_file(sha1, &type, &size); if (!data) die("unable to read object %s", sha1_to_hex(sha1)); buffer = xmalloc(size); memcpy(buffer, data, size); - if (!strcmp(type, blob_type)) { + if (type == OBJ_BLOB) { write_sha1_file(buffer, size, blob_type, entry->new_sha1); - } else if (!strcmp(type, tree_type)) + } else if (type == OBJ_TREE) convert_tree(buffer, size, entry->new_sha1); - else if (!strcmp(type, commit_type)) + else if (type == OBJ_COMMIT) convert_commit(buffer, size, entry->new_sha1); else - die("unknown object type '%s' in %s", type, sha1_to_hex(sha1)); + die("unknown object type %d in %s", type, sha1_to_hex(sha1)); entry->converted = 1; free(buffer); free(data); diff --git a/diff.c b/diff.c index d1eae72..f033eb0 100644 --- a/diff.c +++ b/diff.c @@ -1430,7 +1430,7 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) } } else { - char type[20]; + enum object_type type; struct sha1_size_cache *e; if (size_only) { @@ -1439,11 +1439,12 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) s->size = e->size; return 0; } - if (!sha1_object_info(s->sha1, type, &s->size)) + type = sha1_object_info(s->sha1, &s->size); + if (type < 0) locate_size_cache(s->sha1, 0, s->size); } else { - s->data = read_sha1_file(s->sha1, type, &s->size); + s->data = read_sha1_file(s->sha1, &type, &s->size); s->should_free = 1; } } diff --git a/entry.c b/entry.c index 472a9ef..21b5f2e 100644 --- a/entry.c +++ b/entry.c @@ -68,10 +68,10 @@ static int write_entry(struct cache_entry *ce, char *path, struct checkout *stat void *new; unsigned long size; long wrote; - char type[20]; + enum object_type type; - new = read_sha1_file(ce->sha1, type, &size); - if (!new || strcmp(type, blob_type)) { + new = read_sha1_file(ce->sha1, &type, &size); + if (!new || type != OBJ_BLOB) { if (new) free(new); return error("git-checkout-index: unable to read sha1 file of %s (%s)", diff --git a/fast-import.c b/fast-import.c index aa9eac3..65e99c2 100644 --- a/fast-import.c +++ b/fast-import.c @@ -1008,11 +1008,11 @@ static void *gfi_unpack_entry( struct object_entry *oe, unsigned long *sizep) { - static char type[20]; + enum object_type type; struct packed_git *p = all_packs[oe->pack_id]; if (p == pack_data) p->pack_size = pack_size + 20; - return unpack_entry(p, oe->offset, type, sizep); + return unpack_entry(p, oe->offset, &type, sizep); } static const char *get_mode(const char *str, uint16_t *modep) @@ -1049,9 +1049,9 @@ static void load_tree(struct tree_entry *root) t->delta_depth = 0; buf = gfi_unpack_entry(myoe, &size); } else { - char type[20]; - buf = read_sha1_file(sha1, type, &size); - if (!buf || strcmp(type, tree_type)) + enum object_type type; + buf = read_sha1_file(sha1, &type, &size); + if (!buf || type != OBJ_TREE) die("Can't load tree %s", sha1_to_hex(sha1)); } @@ -1573,7 +1573,6 @@ static void file_change_m(struct branch *b) struct object_entry *oe = oe; unsigned char sha1[20]; uint16_t mode, inline_data = 0; - char type[20]; p = get_mode(p, &mode); if (!p) @@ -1628,11 +1627,12 @@ static void file_change_m(struct branch *b) die("Not a blob (actually a %s): %s", command_buf.buf, typename(oe->type)); } else { - if (sha1_object_info(sha1, type, NULL)) + enum object_type type = sha1_object_info(sha1, NULL); + if (type < 0) die("Blob not found: %s", command_buf.buf); - if (strcmp(blob_type, type)) + if (type != OBJ_BLOB) die("Not a blob (actually a %s): %s", - command_buf.buf, type); + typename(type), command_buf.buf); } tree_content_set(&b->branch_tree, p, sha1, S_IFREG | mode); diff --git a/http-push.c b/http-push.c index 9ad6fd0..0fd73db 100644 --- a/http-push.c +++ b/http-push.c @@ -479,7 +479,7 @@ static void start_put(struct transfer_request *request) char *hex = sha1_to_hex(request->obj->sha1); struct active_request_slot *slot; char *posn; - char type[20]; + enum object_type type; char hdr[50]; void *unpacked; unsigned long len; @@ -487,8 +487,8 @@ static void start_put(struct transfer_request *request) ssize_t size; z_stream stream; - unpacked = read_sha1_file(request->obj->sha1, type, &len); - hdrlen = sprintf(hdr, "%s %lu", type, len) + 1; + unpacked = read_sha1_file(request->obj->sha1, &type, &len); + hdrlen = sprintf(hdr, "%s %lu", typename(type), len) + 1; /* Set it up */ memset(&stream, 0, sizeof(stream)); diff --git a/index-pack.c b/index-pack.c index 4b52785..c56458e 100644 --- a/index-pack.c +++ b/index-pack.c @@ -595,25 +595,23 @@ static void fix_unresolved_deltas(int nr_unresolved) struct delta_entry *d = sorted_by_pos[i]; void *data; unsigned long size; - char type[10]; - enum object_type obj_type; + enum object_type type; int j, first, last; if (objects[d->obj_no].real_type != OBJ_REF_DELTA) continue; - data = read_sha1_file(d->base.sha1, type, &size); + data = read_sha1_file(d->base.sha1, &type, &size); if (!data) continue; - obj_type = type_from_string(type); find_delta_children(&d->base, &first, &last); for (j = first; j <= last; j++) { struct object_entry *child = objects + deltas[j].obj_no; if (child->real_type == OBJ_REF_DELTA) - resolve_delta(child, data, size, obj_type); + resolve_delta(child, data, size, type); } - append_obj_to_pack(data, size, obj_type); + append_obj_to_pack(data, size, type); free(data); if (verbose) percent = display_progress(nr_resolved_deltas, diff --git a/merge-file.c b/merge-file.c index 69dc1eb..748d15c 100644 --- a/merge-file.c +++ b/merge-file.c @@ -7,12 +7,12 @@ static int fill_mmfile_blob(mmfile_t *f, struct blob *obj) { void *buf; unsigned long size; - char type[20]; + enum object_type type; - buf = read_sha1_file(obj->object.sha1, type, &size); + buf = read_sha1_file(obj->object.sha1, &type, &size); if (!buf) return -1; - if (strcmp(type, blob_type)) + if (type != OBJ_BLOB) return -1; f->ptr = buf; f->size = size; @@ -86,12 +86,12 @@ void *merge_file(struct blob *base, struct blob *our, struct blob *their, unsign * modified in the other branch! */ if (!our || !their) { - char type[20]; + enum object_type type; if (base) return NULL; if (!our) our = their; - return read_sha1_file(our->object.sha1, type, size); + return read_sha1_file(our->object.sha1, &type, size); } if (fill_mmfile_blob(&f1, our) < 0) diff --git a/merge-recursive.c b/merge-recursive.c index 397a7ad..87cd870 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -560,14 +560,14 @@ static void update_file_flags(const unsigned char *sha, update_wd = 0; if (update_wd) { - char type[20]; + enum object_type type; void *buf; unsigned long size; - buf = read_sha1_file(sha, type, &size); + buf = read_sha1_file(sha, &type, &size); if (!buf) die("cannot read object %s '%s'", sha1_to_hex(sha), path); - if (strcmp(type, blob_type) != 0) + if (type != OBJ_BLOB) die("blob expected for %s '%s'", sha1_to_hex(sha), path); if (S_ISREG(mode)) { @@ -620,7 +620,7 @@ struct merge_file_info static void fill_mm(const unsigned char *sha1, mmfile_t *mm) { unsigned long size; - char type[20]; + enum object_type type; if (!hashcmp(sha1, null_sha1)) { mm->ptr = xstrdup(""); @@ -628,8 +628,8 @@ static void fill_mm(const unsigned char *sha1, mmfile_t *mm) return; } - mm->ptr = read_sha1_file(sha1, type, &size); - if (!mm->ptr || strcmp(type, blob_type)) + mm->ptr = read_sha1_file(sha1, &type, &size); + if (!mm->ptr || type != OBJ_BLOB) die("unable to read blob object %s", sha1_to_hex(sha1)); mm->size = size; } @@ -1213,7 +1213,7 @@ static int merge(struct commit *h1, tree->object.parsed = 1; tree->object.type = OBJ_TREE; - pretend_sha1_file(NULL, 0, tree_type, tree->object.sha1); + pretend_sha1_file(NULL, 0, OBJ_TREE, tree->object.sha1); merged_common_ancestors = make_virtual_commit(tree, "ancestor"); } diff --git a/merge-tree.c b/merge-tree.c index 692ede0..b2867ba 100644 --- a/merge-tree.c +++ b/merge-tree.c @@ -57,11 +57,11 @@ extern void *merge_file(struct blob *, struct blob *, struct blob *, unsigned lo static void *result(struct merge_list *entry, unsigned long *size) { - char type[20]; + enum object_type type; struct blob *base, *our, *their; if (!entry->stage) - return read_sha1_file(entry->blob->object.sha1, type, size); + return read_sha1_file(entry->blob->object.sha1, &type, size); base = NULL; if (entry->stage == 1) { base = entry->blob; @@ -80,10 +80,10 @@ static void *result(struct merge_list *entry, unsigned long *size) static void *origin(struct merge_list *entry, unsigned long *size) { - char type[20]; + enum object_type type; while (entry) { if (entry->stage == 2) - return read_sha1_file(entry->blob->object.sha1, type, size); + return read_sha1_file(entry->blob->object.sha1, &type, size); entry = entry->link; } return NULL; diff --git a/mktag.c b/mktag.c index 3448a5d..9310111 100644 --- a/mktag.c +++ b/mktag.c @@ -27,13 +27,13 @@ static int verify_object(unsigned char *sha1, const char *expected_type) { int ret = -1; - char type[100]; + enum object_type type; unsigned long size; - void *buffer = read_sha1_file(sha1, type, &size); + void *buffer = read_sha1_file(sha1, &type, &size); if (buffer) { - if (!strcmp(type, expected_type)) - ret = check_sha1_signature(sha1, buffer, size, type); + if (type == type_from_string(expected_type)) + ret = check_sha1_signature(sha1, buffer, size, expected_type); free(buffer); } return ret; diff --git a/mktree.c b/mktree.c index 56205d1..d86dde8 100644 --- a/mktree.c +++ b/mktree.c @@ -95,7 +95,7 @@ int main(int ac, char **av) int len; char *ptr, *ntr; unsigned mode; - char type[20]; + enum object_type type; char *path; read_line(&sb, stdin, line_termination); @@ -115,11 +115,12 @@ int main(int ac, char **av) ntr[41] != '\t' || get_sha1_hex(ntr + 1, sha1)) die("input format error: %s", sb.buf); - if (sha1_object_info(sha1, type, NULL)) + type = sha1_object_info(sha1, NULL); + if (type < 0) die("object %s unavailable", sha1_to_hex(sha1)); *ntr++ = 0; /* now at the beginning of SHA1 */ - if (strcmp(ptr, type)) - die("object type %s mismatch (%s)", ptr, type); + if (type != type_from_string(ptr)) + die("object type %s mismatch (%s)", ptr, typename(type)); ntr += 41; /* at the beginning of name */ if (line_termination && ntr[0] == '"') path = unquote_c_style(ntr, NULL); diff --git a/object.c b/object.c index 37cedc0..0e67af3 100644 --- a/object.c +++ b/object.c @@ -158,23 +158,23 @@ struct object *lookup_unknown_object(const unsigned char *sha1) return obj; } -struct object *parse_object_buffer(const unsigned char *sha1, const char *type, unsigned long size, void *buffer, int *eaten_p) +struct object *parse_object_buffer(const unsigned char *sha1, enum object_type type, unsigned long size, void *buffer, int *eaten_p) { struct object *obj; int eaten = 0; - if (!strcmp(type, blob_type)) { + if (type == OBJ_BLOB) { struct blob *blob = lookup_blob(sha1); parse_blob_buffer(blob, buffer, size); obj = &blob->object; - } else if (!strcmp(type, tree_type)) { + } else if (type == OBJ_TREE) { struct tree *tree = lookup_tree(sha1); obj = &tree->object; if (!tree->object.parsed) { parse_tree_buffer(tree, buffer, size); eaten = 1; } - } else if (!strcmp(type, commit_type)) { + } else if (type == OBJ_COMMIT) { struct commit *commit = lookup_commit(sha1); parse_commit_buffer(commit, buffer, size); if (!commit->buffer) { @@ -182,7 +182,7 @@ struct object *parse_object_buffer(const unsigned char *sha1, const char *type, eaten = 1; } obj = &commit->object; - } else if (!strcmp(type, tag_type)) { + } else if (type == OBJ_TAG) { struct tag *tag = lookup_tag(sha1); parse_tag_buffer(tag, buffer, size); obj = &tag->object; @@ -196,13 +196,13 @@ struct object *parse_object_buffer(const unsigned char *sha1, const char *type, struct object *parse_object(const unsigned char *sha1) { unsigned long size; - char type[20]; + enum object_type type; int eaten; - void *buffer = read_sha1_file(sha1, type, &size); + void *buffer = read_sha1_file(sha1, &type, &size); if (buffer) { struct object *obj; - if (check_sha1_signature(sha1, buffer, size, type) < 0) + if (check_sha1_signature(sha1, buffer, size, typename(type)) < 0) printf("sha1 mismatch %s\n", sha1_to_hex(sha1)); obj = parse_object_buffer(sha1, type, size, buffer, &eaten); diff --git a/object.h b/object.h index ade4dae..749a6f5 100644 --- a/object.h +++ b/object.h @@ -59,7 +59,7 @@ struct object *parse_object(const unsigned char *sha1); * parsing it. eaten_p indicates if the object has a borrowed copy * of buffer and the caller should not free() it. */ -struct object *parse_object_buffer(const unsigned char *sha1, const char *type, unsigned long size, void *buffer, int *eaten_p); +struct object *parse_object_buffer(const unsigned char *sha1, enum object_type type, unsigned long size, void *buffer, int *eaten_p); /** Returns the object, with potentially excess memory allocated. **/ struct object *lookup_unknown_object(const unsigned char *sha1); diff --git a/pack-check.c b/pack-check.c index 08a9fd8..f248ac8 100644 --- a/pack-check.c +++ b/pack-check.c @@ -43,7 +43,7 @@ static int verify_packfile(struct packed_git *p, for (i = err = 0; i < nr_objects; i++) { unsigned char sha1[20]; void *data; - char type[20]; + enum object_type type; unsigned long size, offset; if (nth_packed_object_sha1(p, i, sha1)) @@ -51,13 +51,13 @@ static int verify_packfile(struct packed_git *p, offset = find_pack_entry_one(sha1, p); if (!offset) die("internal error pack-check find-pack-entry-one"); - data = unpack_entry(p, offset, type, &size); + data = unpack_entry(p, offset, &type, &size); if (!data) { err = error("cannot unpack %s from %s", sha1_to_hex(sha1), p->pack_name); continue; } - if (check_sha1_signature(sha1, data, size, type)) { + if (check_sha1_signature(sha1, data, size, typename(type))) { err = error("packed %s from %s is corrupt", sha1_to_hex(sha1), p->pack_name); free(data); @@ -82,7 +82,7 @@ static void show_pack_info(struct packed_git *p) for (i = 0; i < nr_objects; i++) { unsigned char sha1[20], base_sha1[20]; - char type[20]; + const char *type; unsigned long size; unsigned long store_size; unsigned long offset; @@ -94,9 +94,9 @@ static void show_pack_info(struct packed_git *p) if (!offset) die("internal error pack-check find-pack-entry-one"); - packed_object_info_detail(p, offset, type, &size, &store_size, - &delta_chain_length, - base_sha1); + type = packed_object_info_detail(p, offset, &size, &store_size, + &delta_chain_length, + base_sha1); printf("%s ", sha1_to_hex(sha1)); if (!delta_chain_length) printf("%-6s %lu %lu\n", type, size, offset); diff --git a/read-cache.c b/read-cache.c index 605b352..d637464 100644 --- a/read-cache.c +++ b/read-cache.c @@ -72,7 +72,7 @@ static int ce_compare_link(struct cache_entry *ce, unsigned long expected_size) char *target; void *buffer; unsigned long size; - char type[10]; + enum object_type type; int len; target = xmalloc(expected_size); @@ -81,7 +81,7 @@ static int ce_compare_link(struct cache_entry *ce, unsigned long expected_size) free(target); return -1; } - buffer = read_sha1_file(ce->sha1, type, &size); + buffer = read_sha1_file(ce->sha1, &type, &size); if (!buffer) { free(target); return -1; diff --git a/sha1_file.c b/sha1_file.c index 423ff0a..3831614 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -983,26 +983,27 @@ static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size * too permissive for what we want to check. So do an anal * object header parse by hand. */ -static int parse_sha1_header(char *hdr, char *type, unsigned long *sizep) +static int parse_sha1_header(const char *hdr, unsigned long *sizep) { + char type[10]; int i; unsigned long size; /* * The type can be at most ten bytes (including the * terminating '\0' that we add), and is followed by - * a space. + * a space. */ - i = 10; + i = 0; for (;;) { char c = *hdr++; if (c == ' ') break; - if (!--i) + type[i++] = c; + if (i >= sizeof(type)) return -1; - *type++ = c; } - *type = 0; + type[i] = 0; /* * The length must follow immediately, and be in canonical @@ -1025,17 +1026,17 @@ static int parse_sha1_header(char *hdr, char *type, unsigned long *sizep) /* * The length must be followed by a zero byte */ - return *hdr ? -1 : 0; + return *hdr ? -1 : type_from_string(type); } -void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size) +void * unpack_sha1_file(void *map, unsigned long mapsize, enum object_type *type, unsigned long *size) { int ret; z_stream stream; char hdr[8192]; ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)); - if (ret < Z_OK || parse_sha1_header(hdr, type, size) < 0) + if (ret < Z_OK || (*type = parse_sha1_header(hdr, size)) < 0) return NULL; return unpack_sha1_rest(&stream, hdr, *size); @@ -1044,7 +1045,7 @@ void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned l static unsigned long get_delta_base(struct packed_git *p, struct pack_window **w_curs, unsigned long *curpos, - enum object_type kind, + enum object_type type, unsigned long delta_obj_offset) { unsigned char *base_info = use_pack(p, w_curs, *curpos, NULL); @@ -1056,7 +1057,7 @@ static unsigned long get_delta_base(struct packed_git *p, * that is assured. An OFS_DELTA longer than the hash size * is stupid, as then a REF_DELTA would be smaller to store. */ - if (kind == OBJ_OFS_DELTA) { + if (type == OBJ_OFS_DELTA) { unsigned used = 0; unsigned char c = base_info[used++]; base_offset = c & 127; @@ -1071,7 +1072,7 @@ static unsigned long get_delta_base(struct packed_git *p, if (base_offset >= delta_obj_offset) die("delta base offset out of bound"); *curpos += used; - } else if (kind == OBJ_REF_DELTA) { + } else if (type == OBJ_REF_DELTA) { /* The base entry _must_ be in the same pack */ base_offset = find_pack_entry_one(base_info, p); if (!base_offset) @@ -1085,28 +1086,25 @@ static unsigned long get_delta_base(struct packed_git *p, /* forward declaration for a mutually recursive function */ static int packed_object_info(struct packed_git *p, unsigned long offset, - char *type, unsigned long *sizep); + unsigned long *sizep); static int packed_delta_info(struct packed_git *p, struct pack_window **w_curs, unsigned long curpos, - enum object_type kind, + enum object_type type, unsigned long obj_offset, - char *type, unsigned long *sizep) { unsigned long base_offset; - base_offset = get_delta_base(p, w_curs, &curpos, kind, obj_offset); + base_offset = get_delta_base(p, w_curs, &curpos, type, obj_offset); + type = packed_object_info(p, base_offset, NULL); /* We choose to only get the type of the base object and * ignore potentially corrupt pack file that expects the delta * based on a base with a wrong size. This saves tons of * inflate() calls. */ - if (packed_object_info(p, base_offset, type, NULL)) - die("cannot get info for delta-pack base"); - if (sizep) { const unsigned char *data; unsigned char delta_head[20], *in; @@ -1141,7 +1139,8 @@ static int packed_delta_info(struct packed_git *p, /* Read the result size */ *sizep = get_delta_hdr_size(&data, delta_head+sizeof(delta_head)); } - return 0; + + return type; } static int unpack_object_header(struct packed_git *p, @@ -1169,38 +1168,36 @@ static int unpack_object_header(struct packed_git *p, return type; } -void packed_object_info_detail(struct packed_git *p, - unsigned long obj_offset, - char *type, - unsigned long *size, - unsigned long *store_size, - unsigned int *delta_chain_length, - unsigned char *base_sha1) +const char *packed_object_info_detail(struct packed_git *p, + unsigned long obj_offset, + unsigned long *size, + unsigned long *store_size, + unsigned int *delta_chain_length, + unsigned char *base_sha1) { struct pack_window *w_curs = NULL; unsigned long curpos, dummy; unsigned char *next_sha1; - enum object_type kind; + enum object_type type; *delta_chain_length = 0; curpos = obj_offset; - kind = unpack_object_header(p, &w_curs, &curpos, size); + type = unpack_object_header(p, &w_curs, &curpos, size); for (;;) { - switch (kind) { + switch (type) { default: die("pack %s contains unknown object type %d", - p->pack_name, kind); + p->pack_name, type); case OBJ_COMMIT: case OBJ_TREE: case OBJ_BLOB: case OBJ_TAG: - strcpy(type, typename(kind)); *store_size = 0; /* notyet */ unuse_pack(&w_curs); - return; + return typename(type); case OBJ_OFS_DELTA: - obj_offset = get_delta_base(p, &w_curs, &curpos, kind, obj_offset); + obj_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset); if (*delta_chain_length == 0) { /* TODO: find base_sha1 as pointed by curpos */ } @@ -1214,39 +1211,38 @@ void packed_object_info_detail(struct packed_git *p, } (*delta_chain_length)++; curpos = obj_offset; - kind = unpack_object_header(p, &w_curs, &curpos, &dummy); + type = unpack_object_header(p, &w_curs, &curpos, &dummy); } } static int packed_object_info(struct packed_git *p, unsigned long obj_offset, - char *type, unsigned long *sizep) + unsigned long *sizep) { struct pack_window *w_curs = NULL; unsigned long size, curpos = obj_offset; - enum object_type kind; + enum object_type type; - kind = unpack_object_header(p, &w_curs, &curpos, &size); + type = unpack_object_header(p, &w_curs, &curpos, &size); - switch (kind) { + switch (type) { case OBJ_OFS_DELTA: case OBJ_REF_DELTA: - packed_delta_info(p, &w_curs, curpos, kind, - obj_offset, type, sizep); + type = packed_delta_info(p, &w_curs, curpos, + type, obj_offset, sizep); break; case OBJ_COMMIT: case OBJ_TREE: case OBJ_BLOB: case OBJ_TAG: - strcpy(type, typename(kind)); if (sizep) *sizep = size; break; default: die("pack %s contains unknown object type %d", - p->pack_name, kind); + p->pack_name, type); } unuse_pack(&w_curs); - return 0; + return type; } static void *unpack_compressed_entry(struct packed_git *p, @@ -1284,15 +1280,14 @@ static void *unpack_delta_entry(struct packed_git *p, struct pack_window **w_curs, unsigned long curpos, unsigned long delta_size, - enum object_type kind, unsigned long obj_offset, - char *type, + enum object_type *type, unsigned long *sizep) { void *delta_data, *result, *base; - unsigned long result_size, base_size, base_offset; + unsigned long base_size, base_offset; - base_offset = get_delta_base(p, w_curs, &curpos, kind, obj_offset); + base_offset = get_delta_base(p, w_curs, &curpos, *type, obj_offset); base = unpack_entry(p, base_offset, type, &base_size); if (!base) die("failed to read delta base object at %lu from %s", @@ -1301,43 +1296,39 @@ static void *unpack_delta_entry(struct packed_git *p, delta_data = unpack_compressed_entry(p, w_curs, curpos, delta_size); result = patch_delta(base, base_size, delta_data, delta_size, - &result_size); + sizep); if (!result) die("failed to apply delta"); free(delta_data); free(base); - *sizep = result_size; return result; } void *unpack_entry(struct packed_git *p, unsigned long obj_offset, - char *type, unsigned long *sizep) + enum object_type *type, unsigned long *sizep) { struct pack_window *w_curs = NULL; - unsigned long size, curpos = obj_offset; - enum object_type kind; - void *retval; + unsigned long curpos = obj_offset; + void *data; - kind = unpack_object_header(p, &w_curs, &curpos, &size); - switch (kind) { + *type = unpack_object_header(p, &w_curs, &curpos, sizep); + switch (*type) { case OBJ_OFS_DELTA: case OBJ_REF_DELTA: - retval = unpack_delta_entry(p, &w_curs, curpos, size, - kind, obj_offset, type, sizep); + data = unpack_delta_entry(p, &w_curs, curpos, *sizep, + obj_offset, type, sizep); break; case OBJ_COMMIT: case OBJ_TREE: case OBJ_BLOB: case OBJ_TAG: - strcpy(type, typename(kind)); - *sizep = size; - retval = unpack_compressed_entry(p, &w_curs, curpos, size); + data = unpack_compressed_entry(p, &w_curs, curpos, *sizep); break; default: - die("unknown object type %i in %s", kind, p->pack_name); + die("unknown object type %i in %s", *type, p->pack_name); } unuse_pack(&w_curs); - return retval; + return data; } int num_packed_objects(const struct packed_git *p) @@ -1444,10 +1435,10 @@ struct packed_git *find_sha1_pack(const unsigned char *sha1, return p; } return NULL; - + } -static int sha1_loose_object_info(const unsigned char *sha1, char *type, unsigned long *sizep) +static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *sizep) { int status; unsigned long mapsize, size; @@ -1461,31 +1452,29 @@ static int sha1_loose_object_info(const unsigned char *sha1, char *type, unsigne if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0) status = error("unable to unpack %s header", sha1_to_hex(sha1)); - else if (parse_sha1_header(hdr, type, &size) < 0) + else if ((status = parse_sha1_header(hdr, &size)) < 0) status = error("unable to parse %s header", sha1_to_hex(sha1)); - else { - status = 0; - if (sizep) - *sizep = size; - } + else if (sizep) + *sizep = size; inflateEnd(&stream); munmap(map, mapsize); return status; } -int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep) +int sha1_object_info(const unsigned char *sha1, unsigned long *sizep) { struct pack_entry e; if (!find_pack_entry(sha1, &e, NULL)) { reprepare_packed_git(); if (!find_pack_entry(sha1, &e, NULL)) - return sha1_loose_object_info(sha1, type, sizep); + return sha1_loose_object_info(sha1, sizep); } - return packed_object_info(e.p, e.offset, type, sizep); + return packed_object_info(e.p, e.offset, sizep); } -static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned long *size) +static void *read_packed_sha1(const unsigned char *sha1, + enum object_type *type, unsigned long *size) { struct pack_entry e; @@ -1503,7 +1492,7 @@ static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned lo */ static struct cached_object { unsigned char sha1[20]; - const char *type; + enum object_type type; void *buf; unsigned long size; } *cached_objects; @@ -1521,11 +1510,12 @@ static struct cached_object *find_cached_object(const unsigned char *sha1) return NULL; } -int pretend_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1) +int pretend_sha1_file(void *buf, unsigned long len, enum object_type type, + unsigned char *sha1) { struct cached_object *co; - hash_sha1_file(buf, len, type, sha1); + hash_sha1_file(buf, len, typename(type), sha1); if (has_sha1_file(sha1) || find_cached_object(sha1)) return 0; if (cached_object_alloc <= cached_object_nr) { @@ -1536,14 +1526,15 @@ int pretend_sha1_file(void *buf, unsigned long len, const char *type, unsigned c } co = &cached_objects[cached_object_nr++]; co->size = len; - co->type = strdup(type); + co->type = type; co->buf = xmalloc(len); memcpy(co->buf, buf, len); hashcpy(co->sha1, sha1); return 0; } -void *read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size) +void *read_sha1_file(const unsigned char *sha1, enum object_type *type, + unsigned long *size) { unsigned long mapsize; void *map, *buf; @@ -1554,7 +1545,7 @@ void *read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size) buf = xmalloc(co->size + 1); memcpy(buf, co->buf, co->size); ((char*)buf)[co->size] = 0; - strcpy(type, co->type); + *type = co->type; *size = co->size; return buf; } @@ -1573,33 +1564,34 @@ void *read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size) } void *read_object_with_reference(const unsigned char *sha1, - const char *required_type, + const char *required_type_name, unsigned long *size, unsigned char *actual_sha1_return) { - char type[20]; + enum object_type type, required_type; void *buffer; unsigned long isize; unsigned char actual_sha1[20]; + required_type = type_from_string(required_type_name); hashcpy(actual_sha1, sha1); while (1) { int ref_length = -1; const char *ref_type = NULL; - buffer = read_sha1_file(actual_sha1, type, &isize); + buffer = read_sha1_file(actual_sha1, &type, &isize); if (!buffer) return NULL; - if (!strcmp(type, required_type)) { + if (type == required_type) { *size = isize; if (actual_sha1_return) hashcpy(actual_sha1_return, actual_sha1); return buffer; } /* Handle references */ - else if (!strcmp(type, commit_type)) + else if (type == OBJ_COMMIT) ref_type = "tree "; - else if (!strcmp(type, tag_type)) + else if (type == OBJ_TAG) ref_type = "object "; else { free(buffer); @@ -1841,17 +1833,17 @@ static void *repack_object(const unsigned char *sha1, unsigned long *objsize) z_stream stream; unsigned char *unpacked; unsigned long len; - char type[20]; + enum object_type type; char hdr[32]; int hdrlen; void *buf; /* need to unpack and recompress it by itself */ - unpacked = read_packed_sha1(sha1, type, &len); + unpacked = read_packed_sha1(sha1, &type, &len); if (!unpacked) error("cannot read sha1_file for %s", sha1_to_hex(sha1)); - hdrlen = sprintf(hdr, "%s %lu", type, len) + 1; + hdrlen = sprintf(hdr, "%s %lu", typename(type), len) + 1; /* Set it up */ memset(&stream, 0, sizeof(stream)); diff --git a/tag.c b/tag.c index 864ac1b..30ffc17 100644 --- a/tag.c +++ b/tag.c @@ -85,18 +85,18 @@ int parse_tag_buffer(struct tag *item, void *data, unsigned long size) int parse_tag(struct tag *item) { - char type[20]; + enum object_type type; void *data; unsigned long size; int ret; if (item->object.parsed) return 0; - data = read_sha1_file(item->object.sha1, type, &size); + data = read_sha1_file(item->object.sha1, &type, &size); if (!data) return error("Could not read %s", sha1_to_hex(item->object.sha1)); - if (strcmp(type, tag_type)) { + if (type != OBJ_TAG) { free(data); return error("Object %s not a tag", sha1_to_hex(item->object.sha1)); diff --git a/tree-diff.c b/tree-diff.c index 37d235e..c827582 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -139,13 +139,13 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode); if (opt->recursive && S_ISDIR(mode)) { - char type[20]; + enum object_type type; char *newbase = malloc_base(base, path, strlen(path)); struct tree_desc inner; void *tree; - tree = read_sha1_file(sha1, type, &inner.size); - if (!tree || strcmp(type, tree_type)) + tree = read_sha1_file(sha1, &type, &inner.size); + if (!tree || type != OBJ_TREE) die("corrupt tree sha %s", sha1_to_hex(sha1)); inner.buf = tree; diff --git a/tree.c b/tree.c index b6f02fe..46923ee 100644 --- a/tree.c +++ b/tree.c @@ -190,17 +190,17 @@ int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size) int parse_tree(struct tree *item) { - char type[20]; + enum object_type type; void *buffer; unsigned long size; if (item->object.parsed) return 0; - buffer = read_sha1_file(item->object.sha1, type, &size); + buffer = read_sha1_file(item->object.sha1, &type, &size); if (!buffer) return error("Could not read %s", sha1_to_hex(item->object.sha1)); - if (strcmp(type, tree_type)) { + if (type != OBJ_TREE) { free(buffer); return error("Object %s not a tree", sha1_to_hex(item->object.sha1)); diff --git a/unpack-file.c b/unpack-file.c index d24acc2..25c56b3 100644 --- a/unpack-file.c +++ b/unpack-file.c @@ -5,12 +5,12 @@ static char *create_temp_file(unsigned char *sha1) { static char path[50]; void *buf; - char type[100]; + enum object_type type; unsigned long size; int fd; - buf = read_sha1_file(sha1, type, &size); - if (!buf || strcmp(type, blob_type)) + buf = read_sha1_file(sha1, &type, &size); + if (!buf || type != OBJ_BLOB) die("unable to read blob object %s", sha1_to_hex(sha1)); strcpy(path, ".merge_file_XXXXXX"); -- cgit v0.10.2-6-g49f6 From 0ab179504a17907c395a4009f7c23d2f71bba1d3 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 26 Feb 2007 14:56:00 -0500 Subject: get rid of lookup_object_type() This function is called only once in the whole source tree. Let's move its code inline instead, which is also in the spirit of removing as much object type char arrays as possible (not that this patch does anything for that but at least it is now a local matter). Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano diff --git a/object.c b/object.c index 0e67af3..5b46889 100644 --- a/object.c +++ b/object.c @@ -120,24 +120,6 @@ void created_object(const unsigned char *sha1, struct object *obj) nr_objs++; } -struct object *lookup_object_type(const unsigned char *sha1, const char *type) -{ - if (!type) { - return lookup_unknown_object(sha1); - } else if (!strcmp(type, blob_type)) { - return &lookup_blob(sha1)->object; - } else if (!strcmp(type, tree_type)) { - return &lookup_tree(sha1)->object; - } else if (!strcmp(type, commit_type)) { - return &lookup_commit(sha1)->object; - } else if (!strcmp(type, tag_type)) { - return &lookup_tag(sha1)->object; - } else { - error("Unknown type %s", type); - return NULL; - } -} - union any_object { struct object object; struct commit commit; diff --git a/object.h b/object.h index 749a6f5..bdbf0fa 100644 --- a/object.h +++ b/object.h @@ -47,9 +47,6 @@ extern struct object_refs *lookup_object_refs(struct object *); /** Internal only **/ struct object *lookup_object(const unsigned char *sha1); -/** Returns the object, having looked it up as being the given type. **/ -struct object *lookup_object_type(const unsigned char *sha1, const char *type); - void created_object(const unsigned char *sha1, struct object *obj); /** Returns the object, having parsed it to find out what it is. **/ diff --git a/tag.c b/tag.c index 30ffc17..56a49f4 100644 --- a/tag.c +++ b/tag.c @@ -1,5 +1,8 @@ #include "cache.h" #include "tag.h" +#include "commit.h" +#include "tree.h" +#include "blob.h" const char *tag_type = "tag"; @@ -37,7 +40,7 @@ struct tag *lookup_tag(const unsigned char *sha1) int parse_tag_buffer(struct tag *item, void *data, unsigned long size) { int typelen, taglen; - unsigned char object[20]; + unsigned char sha1[20]; const char *type_line, *tag_line, *sig_line; char type[20]; @@ -47,7 +50,7 @@ int parse_tag_buffer(struct tag *item, void *data, unsigned long size) if (size < 64) return -1; - if (memcmp("object ", data, 7) || get_sha1_hex((char *) data + 7, object)) + if (memcmp("object ", data, 7) || get_sha1_hex((char *) data + 7, sha1)) return -1; type_line = (char *) data + 48; @@ -73,7 +76,19 @@ int parse_tag_buffer(struct tag *item, void *data, unsigned long size) memcpy(item->tag, tag_line + 4, taglen); item->tag[taglen] = '\0'; - item->tagged = lookup_object_type(object, type); + if (!strcmp(type, blob_type)) { + item->tagged = &lookup_blob(sha1)->object; + } else if (!strcmp(type, tree_type)) { + item->tagged = &lookup_tree(sha1)->object; + } else if (!strcmp(type, commit_type)) { + item->tagged = &lookup_commit(sha1)->object; + } else if (!strcmp(type, tag_type)) { + item->tagged = &lookup_tag(sha1)->object; + } else { + error("Unknown type %s", type); + item->tagged = NULL; + } + if (item->tagged && track_object_refs) { struct object_refs *refs = alloc_object_refs(1); refs->ref[0] = item->tagged; -- cgit v0.10.2-6-g49f6 From fef742c4ed2be2b3b72f510314b7b2f3a7a7d0a7 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Tue, 27 Feb 2007 20:38:31 -0500 Subject: make sure enum object_type is signed This allows for keeping the common idiom which consists of using negative values to signal error conditions by ensuring that the enum will be a signed type. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano diff --git a/cache.h b/cache.h index 0117b7e..ec72c0c 100644 --- a/cache.h +++ b/cache.h @@ -263,6 +263,7 @@ int safe_create_leading_directories(char *path); char *enter_repo(char *path, int strict); enum object_type { + OBJ_BAD = -1, OBJ_NONE = 0, OBJ_COMMIT = 1, OBJ_TREE = 2, @@ -271,7 +272,7 @@ enum object_type { /* 5 for future expansion */ OBJ_OFS_DELTA = 6, OBJ_REF_DELTA = 7, - OBJ_BAD, + OBJ_MAX, }; /* Read and unpack a sha1 file into memory, write memory to a sha1 file */ -- cgit v0.10.2-6-g49f6 From 66035a6b3d629b546daef3784f5351d58f4f17b1 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 27 Feb 2007 10:00:33 -0500 Subject: Cleanup check_valid in commit-tree. This routine should be using the object_type enum rather than a string comparsion, as the expected type is always supplied and is known at compile time. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c index 04f61d5..4a8d8d8 100644 --- a/builtin-commit-tree.c +++ b/builtin-commit-tree.c @@ -45,14 +45,14 @@ static void add_buffer(char **bufp, unsigned int *sizep, const char *fmt, ...) memcpy(buf + size, one_line, len); } -static void check_valid(unsigned char *sha1, const char *expect) +static void check_valid(unsigned char *sha1, enum object_type expect) { enum object_type type = sha1_object_info(sha1, NULL); if (type < 0) die("%s is not a valid object", sha1_to_hex(sha1)); - if (expect && type != type_from_string(expect)) + if (type != expect) die("%s is not a valid '%s' object", sha1_to_hex(sha1), - expect); + typename(expect)); } /* @@ -100,7 +100,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix) if (get_sha1(argv[1], tree_sha1)) die("Not a valid object name %s", argv[1]); - check_valid(tree_sha1, tree_type); + check_valid(tree_sha1, OBJ_TREE); for (i = 2; i < argc; i += 2) { const char *a, *b; a = argv[i]; b = argv[i+1]; @@ -111,7 +111,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix) die("Too many parents (%d max)", MAXPARENT); if (get_sha1(b, parent_sha1[parents])) die("Not a valid object name %s", b); - check_valid(parent_sha1[parents], commit_type); + check_valid(parent_sha1[parents], OBJ_COMMIT); if (new_parent(parents)) parents++; } -- cgit v0.10.2-6-g49f6