Commit 521698b1 authored by Daniel Barkalow's avatar Daniel Barkalow Committed by Junio C Hamano

Only use a single parser for tree objects

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: default avatarDaniel Barkalow <[email protected]>
Signed-off-by: default avatarJunio C Hamano <[email protected]>
parent 731043fd
......@@ -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);
......
#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);
......
......@@ -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;
}
......@@ -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)
......
......@@ -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 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment