shithub: fsgen

ref: 7c4e47bececffe6e1a62adb2fc93ff2422a9c274
dir: /main.c/

View raw version
#include <u.h>
#include <libc.h>
#include <bio.h>
#include "dat.h"
#include "fns.h"

void
usage(void)
{
	fprint(2, "usage: %s file\n", argv0);
	exits("usage");
}

char *file = nil;

typedef enum {
	OUTSIDE,
	COPY,
	HASFILE,
} State;

State state = OUTSIDE;

VFile *currentfile = nil;

static void
process(Biobuf *bin)
{
	char *s;
	int line = 0;
	
	while (s = Brdstr(bin, '\n', 1)) {
		line++;
		switch (state) {
		case OUTSIDE:
			if (s[0] == 0)
				break;
			if (s[0] == '/') {
				print("has path: %s\n", s);
				currentfile = addfile(s);
				if (!currentfile)
					goto Err;
				state = HASFILE;
				break;
			}
			if (strcmp("%{", s) == 0) {
				state = COPY;
				break;
			}
			goto Err;
		case COPY:
			if (strcmp("r}", s) == 0) {
				print("}\n");
				state = HASFILE;
				break;
			}
			if (strcmp("w}", s) == 0) {
				print("}\n");
				state = HASFILE;
				break;
			}
			if (strcmp("ls}", s) == 0) {
				print("}\n");
				state = HASFILE;
				break;
			}
			if (strcmp("%}", s) == 0) {
				state = OUTSIDE;
				break;
			}
			print("%s\n", s);
			break;
		case HASFILE:
			if (s[0] == 0)
				break;
			if (strcmp("r{", s) == 0) {
				if (currentfile->hasread) {
					werrstr("file already has a read function");
					goto Err;
				}
				currentfile->hasread++;
				printread(currentfile);
				print("#line %d \"%s\"\n", line, file);
				print("{\n");
				state = COPY;
				break;
			}
			if (strcmp("w{", s) == 0) {
				if (currentfile->haswrite) {
					werrstr("file already has a write function");
					goto Err;
				}
				currentfile->haswrite++;
				printwrite(currentfile);
				print("#line %d \"%s\"\n", line, file);
				print("{\n");
				state = COPY;
				break;
			}
			if (strcmp("ls{", s) == 0) {
				if (currentfile->isdir) {
					werrstr("file already has a ls function");
					goto Err;
				}
				currentfile->isdir++;
				printls(currentfile);
				print("#line %d \"%s\"\n", line, file);
				print("{\n");
				state = COPY;
				break;
			}
			goto Err;
		}
		free(s);
	}
	return;
Err:
	fprint(2, "parse error at %s:%d: %r\n", file, line);
}

static void
p(VFile *f, void*)
{
	char **a;
	fprint(2, "file: %V\n", f);
	
	if (!f->parts)
		return;
	
	for (a = f->parts; *a; a++)
		fprint(2, "  /%s\n", *a);
}

void
main(int argc, char **argv)
{
	Biobuf *bin;
	
	ARGBEGIN{
	case 'h':
		usage();
	}ARGEND;
	
	if (argc != 1)
		usage();
	
	file = argv[0];
	bin = Bopen(file, OREAD);
	if (!bin)
		sysfatal("open: %r");
	
	vfileinit();
	printpre();
	
	process(bin);
	
	foreachfile(p, nil);
	
	printfs();
}