Only use a single parser for tree objects
authorDaniel Barkalow <barkalow@iabervon.org>
Thu, 26 Jan 2006 06:13:36 +0000 (01:13 -0500)
committerJunio C Hamano <junkio@cox.net>
Thu, 26 Jan 2006 09:08:29 +0000 (01:08 -0800)
This makes read_tree_recursive and read_tree take a struct tree
instead of a buffer. It also move the declaration of read_tree into
tree.h (where struct tree is defined), and updates ls-tree and
diff-index (the only places that presently use read_tree*()) to use
the new versions.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
cache.h
diff-index.c
ls-tree.c
tree.c
tree.h

diff --git a/cache.h b/cache.h
index b493b65b74d31aa146ac3af80c5cd24967bce816..1e8e27f7b33fb9adca642eab77e14f452bd2e4cb 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -209,9 +209,6 @@ extern char *write_sha1_file_prepare(void *buf,
 
 extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type);
 
-/* Read a tree into the cache */
-extern int read_tree(void *buffer, unsigned long size, int stage, const char **paths);
-
 extern int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
                              size_t bufsize, size_t *bufposn);
 extern int write_sha1_to_fd(int fd, const unsigned char *sha1);
index 87e10619830ba71654240d424f15cb6db8ac1d65..bbd873ba13306ed87f89ea5a4315bfe7ce794c7e 100644 (file)
@@ -1,4 +1,5 @@
 #include "cache.h"
+#include "tree.h"
 #include "diff.h"
 
 static int cached_only = 0;
@@ -174,8 +175,7 @@ int main(int argc, const char **argv)
        unsigned char sha1[20];
        const char *prefix = setup_git_directory();
        const char **pathspec = NULL;
-       void *tree;
-       unsigned long size;
+       struct tree *tree;
        int ret;
        int allow_options = 1;
        int i;
@@ -233,10 +233,10 @@ int main(int argc, const char **argv)
 
        mark_merge_entries();
 
-       tree = read_object_with_reference(sha1, "tree", &size, NULL);
+       tree = parse_tree_indirect(sha1);
        if (!tree)
                die("bad tree object %s", tree_name);
-       if (read_tree(tree, size, 1, pathspec))
+       if (read_tree(tree, 1, pathspec))
                die("unable to read tree object %s", tree_name);
 
        ret = diff_cache(active_cache, active_nr, pathspec);
index d585b6fc13f4b980fa237067157de96e8e7ef601..d005643ee08e03be2309c02e72522c6a81e8a1c6 100644 (file)
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -84,8 +84,7 @@ static int show_tree(unsigned char *sha1, const char *base, int baselen,
 int main(int argc, const char **argv)
 {
        unsigned char sha1[20];
-       char *buf;
-       unsigned long size;
+       struct tree *tree;
 
        prefix = setup_git_directory();
        if (prefix && *prefix)
@@ -131,10 +130,10 @@ int main(int argc, const char **argv)
                usage(ls_tree_usage);
 
        pathspec = get_pathspec(prefix, argv + 2);
-       buf = read_object_with_reference(sha1, "tree", &size, NULL);
-       if (!buf)
+       tree = parse_tree_indirect(sha1);
+       if (!tree)
                die("not a tree object");
-       read_tree_recursive(buf, size, "", 0, 0, pathspec, show_tree);
+       read_tree_recursive(tree, "", 0, 0, pathspec, show_tree);
 
        return 0;
 }
diff --git a/tree.c b/tree.c
index dc1c41e938b6475df3611294c17ff923be72a72d..87e0d743f85605b8a77eda57f28ad1b25489905a 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -74,27 +74,24 @@ static int match_tree_entry(const char *base, int baselen, const char *path, uns
        return 0;
 }
 
-int read_tree_recursive(void *buffer, unsigned long size,
+int read_tree_recursive(struct tree *tree,
                        const char *base, int baselen,
                        int stage, const char **match,
                        read_tree_fn_t fn)
 {
-       while (size) {
-               int len = strlen(buffer)+1;
-               unsigned char *sha1 = buffer + len;
-               char *path = strchr(buffer, ' ')+1;
-               unsigned int mode;
-
-               if (size < len + 20 || sscanf(buffer, "%o", &mode) != 1)
-                       return -1;
-
-               buffer = sha1 + 20;
-               size -= len + 20;
-
-               if (!match_tree_entry(base, baselen, path, mode, match))
+       struct tree_entry_list *list;
+       if (parse_tree(tree))
+               return -1;
+       list = tree->entries;
+       while (list) {
+               struct tree_entry_list *current = list;
+               list = list->next;
+               if (!match_tree_entry(base, baselen, current->name,
+                                     current->mode, match))
                        continue;
 
-               switch (fn(sha1, base, baselen, path, mode, stage)) {
+               switch (fn(current->item.any->sha1, base, baselen,
+                          current->name, current->mode, stage)) {
                case 0:
                        continue;
                case READ_TREE_RECURSIVE:
@@ -102,28 +99,19 @@ int read_tree_recursive(void *buffer, unsigned long size,
                default:
                        return -1;
                }
-               if (S_ISDIR(mode)) {
+               if (current->directory) {
                        int retval;
-                       int pathlen = strlen(path);
+                       int pathlen = strlen(current->name);
                        char *newbase;
-                       void *eltbuf;
-                       char elttype[20];
-                       unsigned long eltsize;
 
-                       eltbuf = read_sha1_file(sha1, elttype, &eltsize);
-                       if (!eltbuf || strcmp(elttype, "tree")) {
-                               if (eltbuf) free(eltbuf);
-                               return -1;
-                       }
                        newbase = xmalloc(baselen + 1 + pathlen);
                        memcpy(newbase, base, baselen);
-                       memcpy(newbase + baselen, path, pathlen);
+                       memcpy(newbase + baselen, current->name, pathlen);
                        newbase[baselen + pathlen] = '/';
-                       retval = read_tree_recursive(eltbuf, eltsize,
+                       retval = read_tree_recursive(current->item.tree,
                                                     newbase,
                                                     baselen + pathlen + 1,
                                                     stage, match, fn);
-                       free(eltbuf);
                        free(newbase);
                        if (retval)
                                return -1;
@@ -133,9 +121,9 @@ int read_tree_recursive(void *buffer, unsigned long size,
        return 0;
 }
 
-int read_tree(void *buffer, unsigned long size, int stage, const char **match)
+int read_tree(struct tree *tree, int stage, const char **match)
 {
-       return read_tree_recursive(buffer, size, "", 0, stage, match, read_one_entry);
+       return read_tree_recursive(tree, "", 0, stage, match, read_one_entry);
 }
 
 struct tree *lookup_tree(const unsigned char *sha1)
diff --git a/tree.h b/tree.h
index 57a5bf71f2f5f6eb8f4f75709670d36ee6976683..330ab64bbd40bd9202a7474cbda0818b98640cde 100644 (file)
--- a/tree.h
+++ b/tree.h
@@ -37,10 +37,11 @@ struct tree *parse_tree_indirect(const unsigned char *sha1);
 #define READ_TREE_RECURSIVE 1
 typedef int (*read_tree_fn_t)(unsigned char *, const char *, int, const char *, unsigned int, int);
 
-extern int read_tree_recursive(void *buffer, unsigned long size,
-                       const char *base, int baselen,
-                       int stage, const char **match,
-                       read_tree_fn_t fn);
+extern int read_tree_recursive(struct tree *tree,
+                              const char *base, int baselen,
+                              int stage, const char **match,
+                              read_tree_fn_t fn);
 
+extern int read_tree(struct tree *tree, int stage, const char **paths);
 
 #endif /* TREE_H */