Merge branch 'np/types'
authorJunio C Hamano <junkio@cox.net>
Wed, 28 Feb 2007 19:58:27 +0000 (11:58 -0800)
committerJunio C Hamano <junkio@cox.net>
Wed, 28 Feb 2007 19:58:27 +0000 (11:58 -0800)
* np/types:
  Cleanup check_valid in commit-tree.
  make sure enum object_type is signed
  get rid of lookup_object_type()
  convert object type handling from a string to a number
  formalize typename(), and add its reverse type_from_string()
  sha1_file.c: don't ignore an error condition in sha1_loose_object_info()
  sha1_file.c: cleanup "offset" usage
  sha1_file.c: cleanup hdr usage

37 files changed:
archive-tar.c
archive-zip.c
blob.c
builtin-apply.c
builtin-blame.c
builtin-cat-file.c
builtin-commit-tree.c
builtin-for-each-ref.c
builtin-grep.c
builtin-log.c
builtin-pack-objects.c
builtin-prune.c
builtin-reflog.c
builtin-unpack-objects.c
cache.h
combine-diff.c
commit.c
convert-objects.c
diff.c
entry.c
fast-import.c
http-push.c
index-pack.c
merge-file.c
merge-recursive.c
merge-tree.c
mktag.c
mktree.c
object.c
object.h
pack-check.c
read-cache.c
sha1_file.c
tag.c
tree-diff.c
tree.c
unpack-file.c

index 7d52a06..d9c30d3 100644 (file)
@@ -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));
        }
index f31b8ed..7c49848 100644 (file)
@@ -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 (file)
--- 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);
index b84d747..38f6475 100644 (file)
@@ -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);
index 530b97f..9f7dd4e 100644 (file)
@@ -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++;
index 6c16bfa..d61d3d5 100644 (file)
@@ -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;
                }
index 2a818a0..4a8d8d8 100644 (file)
@@ -45,15 +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)
 {
-       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 (type != expect)
                die("%s is not a valid '%s' object", sha1_to_hex(sha1),
-                   expect);
+                   typename(expect));
 }
 
 /*
@@ -101,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];
@@ -112,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++;
        }
index ac0b9f6..b11ca92 100644 (file)
@@ -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);
@@ -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);
index f35f2d0..96b7022 100644 (file)
@@ -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));
index f43790c..1c9f7d0 100644 (file)
@@ -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)
index 426ffdd..8cf24f4 100644 (file)
@@ -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,21 +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));
-
-       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);
 }
 
 static unsigned int check_delta_limit(struct object_entry *me, unsigned int n)
@@ -1206,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 */
@@ -1257,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);
index 6f0ba0d..09864b7 100644 (file)
@@ -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));
index cefb40d..186aabc 100644 (file)
@@ -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;
index 8f8e898..3956c56 100644 (file)
@@ -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..ec72c0c 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -262,13 +262,26 @@ 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_BAD = -1,
+       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_MAX,
+};
+
 /* 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 +298,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 +423,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);
index 044633d..9daa0cb 100644 (file)
@@ -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;
 }
index 8d279b0..da515a4 100644 (file)
--- 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));
index a630132..b5f41ae 100644 (file)
@@ -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 5651152..e225de2 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1436,7 +1436,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) {
@@ -1445,11 +1445,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 (file)
--- 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)",
index 5d040fd..65e99c2 100644 (file)
@@ -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);
@@ -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)
@@ -1626,13 +1625,14 @@ 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))
+               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);
@@ -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';
index 9ad6fd0..0fd73db 100644 (file)
@@ -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));
index 48874a0..9f8f0ca 100644 (file)
@@ -601,30 +601,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;
-               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);
 
                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,
index 69dc1eb..748d15c 100644 (file)
@@ -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)
index 397a7ad..87cd870 100644 (file)
@@ -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");
        }
 
index 692ede0..b2867ba 100644 (file)
@@ -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 (file)
--- a/mktag.c
+++ b/mktag.c
 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;
index 56205d1..d86dde8 100644 (file)
--- 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);
index de244e2..5b46889 100644 (file)
--- 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;
@@ -100,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;
@@ -138,23 +140,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) {
@@ -162,7 +164,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;
@@ -176,13 +178,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);
index caee733..bdbf0fa 100644 (file)
--- a/object.h
+++ b/object.h
@@ -36,24 +36,17 @@ 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 **/
 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. **/
@@ -63,7 +56,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);
index 08a9fd8..f248ac8 100644 (file)
@@ -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);
index 605b352..d637464 100644 (file)
@@ -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;
index 9a1dee0..3831614 100644 (file)
@@ -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;
 }
 
@@ -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);
@@ -1043,12 +1044,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,
-                                   enum object_type kind,
-                                   unsigned long delta_obj_offset,
-                                   unsigned long *base_obj_offset)
+                                   unsigned long *curpos,
+                                   enum object_type type,
+                                   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)
@@ -1057,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,49 +1071,43 @@ 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;
-       } else if (kind == OBJ_REF_DELTA) {
+               *curpos += used;
+       } 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)
                        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 */
 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 offset,
-                            enum object_type kind,
+                            unsigned long curpos,
+                            enum object_type type,
                             unsigned long obj_offset,
-                            char *type,
                             unsigned long *sizep)
 {
        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, 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;
-               unsigned long result_size;
                z_stream stream;
                int st;
 
@@ -1123,10 +1117,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 +1137,21 @@ 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;
+
+       return type;
 }
 
-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,100 +1159,95 @@ 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,
-                              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 obj_offset, val;
+       unsigned long curpos, dummy;
        unsigned char *next_sha1;
-       enum object_type kind;
+       enum object_type type;
 
        *delta_chain_length = 0;
-       obj_offset = offset;
-       offset = unpack_object_header(p, &w_curs, offset, &kind, size);
+       curpos = obj_offset;
+       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, type_names[kind]);
                        *store_size = 0; /* notyet */
                        unuse_pack(&w_curs);
-                       return;
+                       return typename(type);
                case OBJ_OFS_DELTA:
-                       get_delta_base(p, &w_curs, offset, kind,
-                               obj_offset, &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 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;
+               type = unpack_object_header(p, &w_curs, &curpos, &dummy);
        }
 }
 
-static int packed_object_info(struct packed_git *p, unsigned long offset,
-                             char *type, unsigned long *sizep)
+static int packed_object_info(struct packed_git *p, unsigned long obj_offset,
+                             unsigned long *sizep)
 {
        struct pack_window *w_curs = NULL;
-       unsigned long size, obj_offset = offset;
-       enum object_type kind;
-       int r;
+       unsigned long size, curpos = obj_offset;
+       enum object_type type;
 
-       offset = unpack_object_header(p, &w_curs, offset, &kind, &size);
+       type = unpack_object_header(p, &w_curs, &curpos, &size);
 
-       switch (kind) {
+       switch (type) {
        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;
+               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, 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);
+                   p->pack_name, type);
        }
-       if (sizep)
-               *sizep = size;
-       return 0;
+       unuse_pack(&w_curs);
+       return type;
 }
 
 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 +1262,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,63 +1278,57 @@ 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,
-                               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;
 
-       offset = get_delta_base(p, w_curs, offset, kind,
-               obj_offset, &base_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",
                    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);
+                            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 offset,
-                         char *type, unsigned long *sizep)
+void *unpack_entry(struct packed_git *p, unsigned long obj_offset,
+                  enum object_type *type, unsigned long *sizep)
 {
        struct pack_window *w_curs = NULL;
-       unsigned long size, obj_offset = offset;
-       enum object_type kind;
-       void *retval;
+       unsigned long curpos = obj_offset;
+       void *data;
 
-       offset = unpack_object_header(p, &w_curs, offset, &kind, &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, offset, 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, type_names[kind]);
-               *sizep = size;
-               retval = unpack_compressed_entry(p, &w_curs, offset, 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)
@@ -1452,16 +1435,16 @@ 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;
        void *map;
        z_stream stream;
-       char hdr[128];
+       char hdr[32];
 
        map = map_sha1_file(sha1, &mapsize);
        if (!map)
@@ -1469,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));
-       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;
 
@@ -1511,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;
@@ -1529,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) {
@@ -1544,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;
@@ -1562,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;
        }
@@ -1581,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);
@@ -1628,12 +1612,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,33 +1724,24 @@ 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)
                        /* 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);
-       hdr = write_binary_header(stream->next_out, obj_type, len);
-       stream->total_out = hdr;
-       stream->next_out += hdr;
-       stream->avail_out -= hdr;
+       obj_type = type_from_string(type);
+       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 +1755,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 +1802,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);
 
@@ -1858,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];
-       char hdr[50];
+       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..56a49f4 100644 (file)
--- 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;
@@ -85,18 +100,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));
index 37d235e..c827582 100644 (file)
@@ -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 (file)
--- 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));
index d24acc2..25c56b3 100644 (file)
@@ -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");