mirror of
git://projects.qi-hardware.com/eda-tools.git
synced 2024-12-23 12:14:35 +02:00
eeshow/: split file_read into open/read/close
This is to allow for a better implementation of "related" in the future.
This commit is contained in:
parent
4b6eb3f641
commit
05af03a0fd
@ -21,41 +21,27 @@
|
||||
#include "file.h"
|
||||
|
||||
|
||||
bool file_cat(void *user, const char *line)
|
||||
bool file_cat(const struct file *file, void *user, const char *line)
|
||||
{
|
||||
printf("%s\n", line);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void read_from_file(FILE *file,
|
||||
bool (*parse)(void *user, const char *line), void *user)
|
||||
void file_open(struct file *file, const char *name,
|
||||
const struct file *related)
|
||||
{
|
||||
char buf[1000];
|
||||
char *nl;
|
||||
|
||||
while (fgets(buf, sizeof(buf), file)) {
|
||||
nl = strchr(buf, '\n');
|
||||
if (nl)
|
||||
*nl = 0;
|
||||
if (!parse(user, buf))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void file_read(const char *name, bool (*parse)(void *user, const char *line),
|
||||
void *user)
|
||||
{
|
||||
FILE *file;
|
||||
char *colon, *tmp;
|
||||
|
||||
file = fopen(name, "r");
|
||||
if (file) {
|
||||
file->name = stralloc(name);
|
||||
file->lineno = 0;
|
||||
file->related = related;
|
||||
file->vcs = NULL;
|
||||
|
||||
file->file = fopen(name, "r");
|
||||
if (file->file) {
|
||||
if (verbose)
|
||||
fprintf(stderr, "reading %s\n", name);
|
||||
read_from_file(file, parse, user);
|
||||
fclose(file);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -71,6 +57,42 @@ void file_read(const char *name, bool (*parse)(void *user, const char *line),
|
||||
|
||||
tmp = stralloc(name);
|
||||
tmp[colon - name] = 0;
|
||||
vcs_git_read(tmp, colon + 1, parse, user);
|
||||
file->vcs = vcs_git_open(tmp, colon + 1);
|
||||
if (!file->vcs) {
|
||||
fprintf(stderr, "could not open %s:%s\n", tmp, colon + 1);
|
||||
exit(1);
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
|
||||
void file_read(struct file *file,
|
||||
bool (*parse)(const struct file *file, void *user, const char *line),
|
||||
void *user)
|
||||
{
|
||||
char buf[1000];
|
||||
char *nl;
|
||||
|
||||
if (file->vcs) {
|
||||
vcs_read(file->vcs, file, parse, user);
|
||||
return;
|
||||
}
|
||||
while (fgets(buf, sizeof(buf), file->file)) {
|
||||
nl = strchr(buf, '\n');
|
||||
if (nl)
|
||||
*nl = 0;
|
||||
file->lineno++;
|
||||
if (!parse(file, user, buf))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void file_close(struct file *file)
|
||||
{
|
||||
if (file->file)
|
||||
fclose(file->file);
|
||||
if (file->vcs)
|
||||
vcs_close(file->vcs);
|
||||
free((char *) file->name);
|
||||
}
|
||||
|
@ -14,9 +14,25 @@
|
||||
#define FILE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
bool file_cat(void *user, const char *line);
|
||||
void file_read(const char *name, bool (*parse)(void *user, const char *line),
|
||||
|
||||
struct file {
|
||||
FILE *file; /* NULL if using a version control system */
|
||||
void *vcs; /* VCS descriptor or NULL */
|
||||
const char *name; /* name/designator given to file_open */
|
||||
unsigned lineno;
|
||||
const struct file *related; /* NULL if not related to anything */
|
||||
};
|
||||
|
||||
|
||||
bool file_cat(const struct file *file, void *user, const char *line);
|
||||
|
||||
void file_open(struct file *file, const char *name,
|
||||
const struct file *related);
|
||||
void file_read(struct file *file,
|
||||
bool (*parse)(const struct file *file, void *user, const char *line),
|
||||
void *user);
|
||||
void file_close(struct file *file);
|
||||
|
||||
#endif /* !FILE_H */
|
||||
|
@ -22,9 +22,16 @@
|
||||
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "file.h"
|
||||
#include "git-file.h"
|
||||
|
||||
|
||||
struct vcs_git {
|
||||
const void *data;
|
||||
unsigned size;
|
||||
};
|
||||
|
||||
|
||||
static git_repository *select_repo(const char *path)
|
||||
{
|
||||
git_repository *repo = NULL;
|
||||
@ -305,48 +312,27 @@ static const void *get_data(git_repository *repo, git_tree_entry *entry,
|
||||
|
||||
|
||||
static bool send_line(const char *s, unsigned len,
|
||||
bool (*parse)(void *user, const char *line), void *user)
|
||||
bool (*parse)(const struct file *file, void *user, const char *line),
|
||||
void *user, const struct file *file)
|
||||
{
|
||||
char *tmp = alloc_size(len + 1);
|
||||
bool res;
|
||||
|
||||
memcpy(tmp, s, len);
|
||||
tmp[len] = 0;
|
||||
res = parse(user, tmp);
|
||||
res = parse(file, user, tmp);
|
||||
free(tmp);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static void send_data(const char *data, unsigned size,
|
||||
bool (*parse)(void *user, const char *line), void *user)
|
||||
{
|
||||
const char *end = data + size;
|
||||
const char *p = data;
|
||||
const char *nl;
|
||||
|
||||
while (p != end) {
|
||||
nl = memchr(p, '\n', end - p);
|
||||
if (!nl) {
|
||||
send_line(p, end - p, parse, user);
|
||||
return;
|
||||
}
|
||||
if (!send_line(p, nl - p, parse, user))
|
||||
return;
|
||||
p = nl + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void vcs_git_read(const char *revision, const char *name,
|
||||
bool (*parse)(void *user, const char *line), void *user)
|
||||
struct vcs_git *vcs_git_open(const char *revision, const char *name)
|
||||
{
|
||||
static bool initialized = 0;
|
||||
struct vcs_git *vcs_git = alloc_type(struct vcs_git);
|
||||
git_repository *repo;
|
||||
git_tree *tree;
|
||||
git_tree_entry *entry;
|
||||
const void *data;
|
||||
unsigned size;
|
||||
|
||||
if (!initialized) {
|
||||
git_libgit2_init();
|
||||
@ -366,6 +352,37 @@ void vcs_git_read(const char *revision, const char *name,
|
||||
entry = find_file(repo, tree, name);
|
||||
if (verbose)
|
||||
fprintf(stderr, "reading %s:%s\n", revision, name);
|
||||
data = get_data(repo, entry, &size);
|
||||
send_data(data, size, parse, user);
|
||||
|
||||
vcs_git->data = get_data(repo, entry, &vcs_git->size);
|
||||
|
||||
return vcs_git;
|
||||
}
|
||||
|
||||
|
||||
void vcs_git_read(void *ctx, struct file *file,
|
||||
bool (*parse)(const struct file *file, void *user, const char *line),
|
||||
void *user)
|
||||
{
|
||||
const struct vcs_git *vcs_git = ctx;
|
||||
const char *end = vcs_git->data + vcs_git->size;
|
||||
const char *p = vcs_git->data;
|
||||
const char *nl;
|
||||
|
||||
while (p != end) {
|
||||
nl = memchr(p, '\n', end - p);
|
||||
file->lineno++;
|
||||
if (!nl) {
|
||||
send_line(p, end - p, parse, user, file);
|
||||
return;
|
||||
}
|
||||
if (!send_line(p, nl - p, parse, user, file))
|
||||
return;
|
||||
p = nl + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void vcs_git_close(void *ctx)
|
||||
{
|
||||
free(ctx);
|
||||
}
|
||||
|
@ -16,7 +16,23 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
void vcs_git_read(const char *revision, const char *name,
|
||||
bool (*parse)(void *user, const char *line), void *user);
|
||||
/*
|
||||
* future-proofing: if someone wants to add back-ends for other version control
|
||||
* systems, the identifiers will already be there.
|
||||
*/
|
||||
|
||||
#define vcs_open vcs_git_open
|
||||
#define vcs_read vcs_git_read
|
||||
#define vcs_close vcs_git_close
|
||||
|
||||
|
||||
struct vcs_git;
|
||||
struct file;
|
||||
|
||||
struct vcs_git *vcs_git_open(const char *revision, const char *name);
|
||||
void vcs_git_read(void *ctx, struct file *file,
|
||||
bool (*parse)(const struct file *file, void *user, const char *line),
|
||||
void *user);
|
||||
void vcs_git_close(void *ctx);
|
||||
|
||||
#endif /* !GIT_FILE_H */
|
||||
|
@ -130,7 +130,8 @@ static bool parse_arc(struct lib_obj *obj, const char *line)
|
||||
/* ----- Library parser ---------------------------------------------------- */
|
||||
|
||||
|
||||
static bool lib_parse_line(void *user, const char *line)
|
||||
static bool lib_parse_line(const struct file *file,
|
||||
void *user, const char *line)
|
||||
{
|
||||
struct lib *lib = user;
|
||||
int n = 0;
|
||||
@ -253,11 +254,15 @@ static bool lib_parse_line(void *user, const char *line)
|
||||
}
|
||||
|
||||
|
||||
void lib_parse(struct lib *lib, const char *file)
|
||||
void lib_parse(struct lib *lib, const char *name)
|
||||
{
|
||||
struct file file;
|
||||
|
||||
lib->state = lib_skip;
|
||||
lib->lineno = 0;
|
||||
file_read(file, lib_parse_line, lib);
|
||||
file_open(&file, name, NULL);
|
||||
file_read(&file, lib_parse_line, lib);
|
||||
file_close(&file);
|
||||
}
|
||||
|
||||
|
||||
|
@ -118,7 +118,7 @@ const struct comp *lib_find(const struct lib *lib, const char *name);
|
||||
bool lib_field_visible(const struct comp *comp, int n);
|
||||
void lib_render(const struct comp *comp, unsigned unit, const int m[6]);
|
||||
|
||||
void lib_parse(struct lib *lib, const char *file);
|
||||
void lib_parse(struct lib *lib, const char *name);
|
||||
void lib_init(struct lib *lib);
|
||||
|
||||
#endif /* !LIB_H */
|
||||
|
@ -109,9 +109,13 @@ int main(int argc, char *const *argv)
|
||||
}
|
||||
|
||||
if (cat) {
|
||||
struct file file;
|
||||
|
||||
if (argc != optind)
|
||||
usage(*argv);
|
||||
file_read(cat, file_cat, NULL);
|
||||
file_open(&file, cat, NULL);
|
||||
file_read(&file, file_cat, NULL);
|
||||
file_close(&file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -293,7 +293,7 @@ static struct sheet *new_sheet(struct sch_ctx *ctx)
|
||||
}
|
||||
|
||||
|
||||
static bool parse_line(void *user, const char *line);
|
||||
static bool parse_line(const struct file *file, void *user, const char *line);
|
||||
|
||||
|
||||
static void recurse_sheet(struct sch_ctx *ctx)
|
||||
@ -301,6 +301,7 @@ static void recurse_sheet(struct sch_ctx *ctx)
|
||||
struct sch_obj **saved_next_obj = ctx->next_obj;
|
||||
const char *parent = ctx->file->name;
|
||||
char *tmp = NULL;
|
||||
struct file file;
|
||||
struct sch_file dsc = {
|
||||
.name = ctx->obj.u.sheet.file,
|
||||
.lineno = 0,
|
||||
@ -326,14 +327,16 @@ static void recurse_sheet(struct sch_ctx *ctx)
|
||||
new_sheet(ctx);
|
||||
ctx->file = &dsc;
|
||||
ctx->state = sch_descr;
|
||||
file_read(dsc.name, parse_line, ctx);
|
||||
file_open(&file, dsc.name, NULL);
|
||||
file_read(&file, parse_line, ctx);
|
||||
file_close(&file);
|
||||
ctx->file = dsc.parent;
|
||||
ctx->next_obj = saved_next_obj;
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
|
||||
static bool parse_line(void *user, const char *line)
|
||||
static bool parse_line(const struct file *file, void *user, const char *line)
|
||||
{
|
||||
struct sch_ctx *ctx = user;
|
||||
struct sch_obj *obj = &ctx->obj;
|
||||
@ -538,17 +541,20 @@ static bool parse_line(void *user, const char *line)
|
||||
}
|
||||
|
||||
|
||||
void sch_parse(struct sch_ctx *ctx, const char *file, const struct lib *lib)
|
||||
void sch_parse(struct sch_ctx *ctx, const char *name, const struct lib *lib)
|
||||
{
|
||||
struct file file;
|
||||
struct sch_file dsc = {
|
||||
.name = file,
|
||||
.name = name,
|
||||
.lineno = 0,
|
||||
.parent = NULL,
|
||||
};
|
||||
|
||||
ctx->file = &dsc;
|
||||
ctx->lib = lib;
|
||||
file_read(file, parse_line, ctx);
|
||||
file_open(&file, name, NULL);
|
||||
file_read(&file, parse_line, ctx);
|
||||
file_close(&file);
|
||||
}
|
||||
|
||||
|
||||
|
@ -117,7 +117,7 @@ struct sch_ctx {
|
||||
void decode_alignment(struct text *txt, char hor, char vert);
|
||||
|
||||
void sch_render(const struct sheet *sheet);
|
||||
void sch_parse(struct sch_ctx *ctx, const char *file, const struct lib *lib);
|
||||
void sch_parse(struct sch_ctx *ctx, const char *name, const struct lib *lib);
|
||||
void sch_init(struct sch_ctx *ctx, bool recurse);
|
||||
|
||||
#endif /* !SCH_H */
|
||||
|
Loading…
Reference in New Issue
Block a user