diff --git a/eeshow/file.c b/eeshow/file.c index 428f211..d2718c6 100644 --- a/eeshow/file.c +++ b/eeshow/file.c @@ -132,18 +132,25 @@ static void *open_vcs(struct file *file) return file->vcs; if (verbose > 1) fprintf(stderr, "could not open %s\n", file->name); - return 0; + return NULL; } } -bool file_open(struct file *file, const char *name, const struct file *related) +static void file_init(struct file *file, const char *name, + const struct file *related) { file->name = stralloc(name); file->lineno = 0; file->related = related; file->file = NULL; file->vcs = NULL; +} + + +bool file_open(struct file *file, const char *name, const struct file *related) +{ + file_init(file, name, related); if (related && related->vcs) { file->vcs = open_vcs(file); @@ -181,6 +188,22 @@ fail: } +bool file_open_revision(struct file *file, const char *rev, const char *name, + const struct file *related) +{ + if (!rev) + return file_open(file, name, related); + + file_init(file, name, related); + file->vcs = vcs_git_open(rev, name, related ? related->vcs : NULL); + if (file->vcs) + return 1; + if (verbose > 1) + fprintf(stderr, "could not open %s at %s\n", name, rev); + return 0; +} + + bool file_read(struct file *file, bool (*parse)(const struct file *file, void *user, const char *line), void *user) diff --git a/eeshow/file.h b/eeshow/file.h index 6a0e9ae..10d012d 100644 --- a/eeshow/file.h +++ b/eeshow/file.h @@ -32,6 +32,8 @@ char *file_graft_relative(const char *base, const char *name); bool file_open(struct file *file, const char *name, const struct file *related); +bool file_open_revision(struct file *file, const char *rev, const char *name, + const struct file *related); bool file_read(struct file *file, bool (*parse)(const struct file *file, void *user, const char *line), void *user); diff --git a/eeshow/git-file.c b/eeshow/git-file.c index 1828d84..8972df4 100644 --- a/eeshow/git-file.c +++ b/eeshow/git-file.c @@ -282,12 +282,14 @@ static git_tree_entry *find_file(git_repository *repo, git_tree *tree, fprintf(stderr, "repo dir \"%s\"\n", repo_path); canon_path = canonical_path_into_repo(repo_path, path); + free(repo_path); if (git_tree_entry_bypath(&entry, tree, canon_path)) { const git_error *e = giterr_last(); fprintf(stderr, "%s: %s\n", path, e->message); - exit(1); + free(canon_path); + return NULL; } free(canon_path); @@ -345,15 +347,18 @@ static bool send_line(const char *s, unsigned len, } -static void access_file_data(struct vcs_git *vcs_git, const char *name) +static bool access_file_data(struct vcs_git *vcs_git, const char *name) { git_tree_entry *entry; entry = find_file(vcs_git->repo, vcs_git->tree, name); + if (!entry) + return 0; if (verbose) fprintf(stderr, "reading %s\n", name); vcs_git->data = get_data(vcs_git->repo, entry, &vcs_git->size); + return 1; } @@ -364,9 +369,7 @@ static bool related_same_repo(struct vcs_git *vcs_git) vcs_git->repo = related->repo; vcs_git->tree = related->tree; - access_file_data(vcs_git, vcs_git->name); - - return 1; + return access_file_data(vcs_git, vcs_git->name); } @@ -393,7 +396,10 @@ static bool related_only_repo(struct vcs_git *vcs_git) vcs_git->repo = related->repo; vcs_git->tree = related->tree; - access_file_data(vcs_git, tmp); + if (!access_file_data(vcs_git, tmp)) { + free(tmp); + return 0; + } free((char *) vcs_git->name); vcs_git->name = tmp; @@ -439,7 +445,7 @@ struct vcs_git *vcs_git_open(const char *revision, const char *name, vcs_git->repo = select_repo(name); if (!vcs_git->repo) { fprintf(stderr, "%s: not found\n", name); - exit(1); + goto fail; } if (verbose > 1) fprintf(stderr, "using repository %s\n", @@ -449,9 +455,14 @@ struct vcs_git *vcs_git_open(const char *revision, const char *name, revision = "HEAD"; vcs_git->tree = pick_revision(vcs_git->repo, revision); - access_file_data(vcs_git, name); + if (!access_file_data(vcs_git, name)) + goto fail; return vcs_git; + +fail: + vcs_git_close(vcs_git); + return 0; } diff --git a/eeshow/git-file.h b/eeshow/git-file.h index 220b9fc..7faba3a 100644 --- a/eeshow/git-file.h +++ b/eeshow/git-file.h @@ -29,6 +29,7 @@ struct vcs_git; struct file; + void vcs_git_init(void); struct vcs_git *vcs_git_open(const char *revision, const char *name,