1
0
mirror of git://projects.qi-hardware.com/eda-tools.git synced 2024-07-05 04:56:23 +03:00

eeshow/: make "related" work also for repositories (WIP)

For now, we only support the case where the file doesn't exists in any
other repo, which is a common situation with sub-sheets.
This commit is contained in:
Werner Almesberger 2016-08-02 19:13:28 -03:00
parent ade54c6029
commit a21bc66e55
4 changed files with 183 additions and 34 deletions

View File

@ -10,6 +10,7 @@
* (at your option) any later version.
*/
#include <stddef.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
@ -28,28 +29,42 @@ bool file_cat(const struct file *file, void *user, const char *line)
}
char *file_graft_relative(const char *base, const char *name)
{
const char *slash;
char *res;
unsigned len;
if (*name == '/')
return NULL;
slash = strrchr(base, '/');
if (!slash)
return NULL;
len = slash + 1 - base;
res = alloc_size(len + strlen(name) + 1);
memcpy(res, base, len);
strcpy(res + len, name);
return res;
}
static bool try_related(struct file *file)
{
const char *related;
const char *slash;
char *tmp;
unsigned len;
if (!file->related)
return 0;
tmp = file_graft_relative(file->related->name, file->name);
if (!tmp)
return NULL;
if (*file->name == '/')
return 0;
related = file->related->name;
slash = strrchr(related, '/');
if (!slash)
return 0;
len = slash + 1 - related;
tmp = alloc_size(len + strlen(file->name) + 1);
memcpy(tmp, related, len);
strcpy(tmp + len, file->name);
file->file = fopen(tmp, "r");
if (!file->file) {
free(tmp);
@ -90,15 +105,52 @@ static bool try_related(struct file *file)
* @@@ explicit revision should always win over related.
*/
static void *open_vcs(struct file *file)
{
char *colon;
colon = strchr(file->name, ':');
if (colon) {
char *tmp;
tmp = stralloc(file->name);
tmp[colon - file->name] = 0;
file->vcs = vcs_git_open(tmp, colon + 1,
file->related ? file->related->vcs : NULL);
if (file->vcs) {
free(tmp);
return file->vcs;
}
if (verbose > 1)
fprintf(stderr, "could not open %s:%s\n",
tmp, colon + 1);
return NULL;
} else {
file->vcs = vcs_git_open(NULL, file->name,
file->related ? file->related->vcs : NULL);
if (file->vcs)
return file->vcs;
if (verbose > 1)
fprintf(stderr, "could not open %s\n", file->name);
return 0;
}
}
void file_open(struct file *file, const char *name, const struct file *related)
{
char *colon, *tmp;
file->name = stralloc(name);
file->lineno = 0;
file->related = related;
file->file = NULL;
file->vcs = NULL;
if (related && related->vcs) {
file->vcs = open_vcs(file);
if (file->vcs)
return;
}
file->file = fopen(name, "r");
if (file->file) {
if (verbose)
@ -112,21 +164,17 @@ void file_open(struct file *file, const char *name, const struct file *related)
if (verbose)
perror(name);
colon = strchr(name, ':');
if (!colon) {
if (!strchr(name, ':')) {
if (!verbose)
perror(name);
exit(1);
}
tmp = stralloc(name);
tmp[colon - name] = 0;
file->vcs = vcs_git_open(tmp, colon + 1);
file->vcs = open_vcs(file);
if (!file->vcs) {
fprintf(stderr, "could not open %s:%s\n", tmp, colon + 1);
fprintf(stderr, "could not open %s\n", name);
exit(1);
}
free(tmp);
}

View File

@ -28,6 +28,8 @@ struct file {
bool file_cat(const struct file *file, void *user, const char *line);
char *file_graft_relative(const char *base, const char *name);
void file_open(struct file *file, const char *name,
const struct file *related);
void file_read(struct file *file,

View File

@ -27,6 +27,13 @@
struct vcs_git {
const char *name;
const char *revision;
const struct vcs_git *related;
git_repository *repo;
git_tree *tree;
const void *data;
unsigned size;
};
@ -305,6 +312,18 @@ static const void *get_data(git_repository *repo, git_tree_entry *entry,
exit(1);
}
if (verbose > 2) {
git_buf buf = { 0 } ;
if (git_object_short_id(&buf, obj)) {
const git_error *e = giterr_last();
fprintf(stderr, "%s\n", e->message);
exit(1);
}
fprintf(stderr, "object %s\n", buf.ptr);
git_buf_free(&buf);
}
blob = (git_blob *) obj;
*size = git_blob_rawsize(blob);
return git_blob_rawcontent(blob);
@ -326,12 +345,78 @@ static bool send_line(const char *s, unsigned len,
}
struct vcs_git *vcs_git_open(const char *revision, const char *name)
static bool related_same_repo(struct vcs_git *vcs_git)
{
/* @@@ use same revision */
fprintf(stderr, "related_same_repo is no yet implemented\n");
return 0;
}
static bool related_other_repo(struct vcs_git *vcs_git)
{
/* @@@ find revision <= date of revision in related */
fprintf(stderr, "related_other_repo is no yet implemented\n");
return 0;
}
static bool related_only_repo(struct vcs_git *vcs_git)
{
const struct vcs_git *related = vcs_git->related;
char *tmp;
git_tree_entry *entry;
if (verbose > 1)
fprintf(stderr, "trying graft \"%s\" \"%s\"\n",
related->name, vcs_git->name);
tmp = file_graft_relative(related->name, vcs_git->name);
if (!tmp)
return 0;
vcs_git->repo = related->repo;
vcs_git->tree = related->tree;
/* @@@ code below also exists in vcs_git_open */
entry = find_file(vcs_git->repo, vcs_git->tree, tmp);
if (verbose)
fprintf(stderr, "reading %s\n", tmp);
vcs_git->data = get_data(vcs_git->repo, entry, &vcs_git->size);
free((char *) vcs_git->name);
vcs_git->name = tmp;
return 1;
}
static bool try_related(struct vcs_git *vcs_git)
{
if (!vcs_git->related)
return 0;
if (vcs_git->revision)
return 0;
vcs_git->repo = select_repo(vcs_git->name);
if (vcs_git->repo) {
if (!strcmp(git_repository_path(vcs_git->related->repo),
git_repository_path(vcs_git->repo)))
return related_same_repo(vcs_git);
else
return related_other_repo(vcs_git);
}
return related_only_repo(vcs_git);
}
struct vcs_git *vcs_git_open(const char *revision, const char *name,
const struct vcs_git *related)
{
static bool initialized = 0;
struct vcs_git *vcs_git = alloc_type(struct vcs_git);
git_repository *repo;
git_tree *tree;
git_tree_entry *entry;
if (!initialized) {
@ -339,21 +424,30 @@ struct vcs_git *vcs_git_open(const char *revision, const char *name)
initialized = 1;
}
repo = select_repo(name);
if (!repo) {
fprintf(stderr, "%s:%s not found\n", revision, name);
vcs_git->name = stralloc(name);
vcs_git->revision = revision ? stralloc(revision) : NULL;
vcs_git->related = related;
if (try_related(vcs_git))
return vcs_git;
vcs_git->repo = select_repo(name);
if (!vcs_git->repo) {
fprintf(stderr, "%s: not found\n", name);
exit(1);
}
if (verbose > 1)
fprintf(stderr, "using repository %s\n",
git_repository_path(repo));
git_repository_path(vcs_git->repo));
tree = pick_revision(repo, revision);
entry = find_file(repo, tree, name);
if (!revision)
revision = "HEAD";
vcs_git->tree = pick_revision(vcs_git->repo, revision);
entry = find_file(vcs_git->repo, vcs_git->tree, name);
if (verbose)
fprintf(stderr, "reading %s:%s\n", revision, name);
vcs_git->data = get_data(repo, entry, &vcs_git->size);
vcs_git->data = get_data(vcs_git->repo, entry, &vcs_git->size);
return vcs_git;
}
@ -384,5 +478,9 @@ void vcs_git_read(void *ctx, struct file *file,
void vcs_git_close(void *ctx)
{
free(ctx);
struct vcs_git *vcs_git = ctx;
free((char *) vcs_git->name);
free((char *) vcs_git->revision);
free(vcs_git);
}

View File

@ -29,7 +29,8 @@
struct vcs_git;
struct file;
struct vcs_git *vcs_git_open(const char *revision, const char *name);
struct vcs_git *vcs_git_open(const char *revision, const char *name,
const struct vcs_git *related);
void vcs_git_read(void *ctx, struct file *file,
bool (*parse)(const struct file *file, void *user, const char *line),
void *user);