shithub: fsgen

ref: 17039fc93f8eb42fe58797dee5082f486616a6a6
dir: /code.c/

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

typedef struct Vqid Vqid;
struct Vqid {
	char *name;
	VFile *vfile;
	Vqid *children;
	Vqid *next;
};

Vqid *vqids = nil;

static void
printvars(VFile *file)
{
	char **a;
	char *s;
	char buf[64];
	int n;
	
	for (a = file->parts; *a; a++) {
		s = *a;
		if (!s)
			break;
		if (!s[0])
			continue;
		n = strlen(s) - 1;
		if (!(s[0] == '{' && s[n] == '}'))
			continue;
		strcpy(buf, s);
		buf[n] = 0;
		print(", char *%s", buf+1);
	}
}

char *invalid = "/{}";

static void
pathtostring(char *buf, int max, char *path)
{
	char *s;
	strncpy(buf, path, max);
	buf[max-1] = 0;
	for (s = buf; *s; s++)
		if (strchr(invalid, *s))
			*s = '_';
}

void
printgenfunc(VFile *file, char *nm)
{
	char buf[64];
	pathtostring(buf, sizeof(buf), file->path);
	print("static void\nfs%s_%s(Req *r", nm, buf);
	printvars(file);
	print(")\n");
}

void
printls(VFile *file)
{
	char buf[64];
	pathtostring(buf, sizeof(buf), file->path);
	print("static void\nfsls_%s(...)\n", buf);
}

void
printpre()
{
	print("#line 0 \"preamble.inc\"\n"
#include "preamble.cinc"
	);
}

static int
countvq(Vqid *v)
{
	int n = 0;
	for (; v; v = v->next)
		n++;
	return n;
}

int fhyid;

static void
rprintfilehierarchy(Vqid *vq, int nest)
{
	Vqid *v;
	int n, i;
	char buf[32];
	if (!vq) return;
	
	i = 0;
	for (v = vq; v; v = v->next) {
		n = countvq(v->children);
		if (!n)
			continue;
		pathtostring(buf, sizeof(buf), v->name);
		print("	%*sfilehierarchy[%d] = mallocz(%d, 1);\n", nest*4, "", fhyid, n + 1);
		fhyid++;
		print("	%*sfilehierarchy[%d][%d] = Q%s;\n", nest*4, "", fhyid, i++, buf);
		rprintfilehierarchy(v->children, nest+1);
	}
}

extern char* file;

void
printfs()
{
	char buf[64];
	char *s;
	int n;
	
	strcpy(buf, file);
	s = strrchr(buf, '.');
	if (strcmp(s, ".fs") == 0)
		*s = 0;
	for (s = buf; *s; s++)
		if (*s == '.')
			*s = '_';
	s = strrchr(buf, '/');
	if (s)
		s++;
	else
		s = buf;
	
	print("\n#line 0 \"fshandler.inc\"\n"
#include "fshandler.cinc"
	);
	
	print("\n#line 0 \"fsgen/code.c\"");
	print("\n"
	"Srv fs = {\n"
	"	.read = fsread,\n"
	"	.stat = fsstat,\n"
	"	.walk1 = fswalk,\n"
	"};\n\n");
	
	print("int **filehierarchy = nil;\n\n"
	"static void\n"
	"buildfilehierarchy()\n"
	"{\n");
	
	n = getnfiles();
	print("	filehierarchy = mallocz(%d, 1);\n", n+1);
	fhyid = 0;
	rprintfilehierarchy(vqids, 0);
	
	print("}\n\n");
	
	print(
	"Srv*\n"
	"getfs_%s()\n", s);
	
	print("#line 0 \"fsfunc.inc\"\n"
#include "fsfunc.cinc"
	);
}

static Vqid*
findchild(Vqid *parent, char *child)
{
	Vqid *v;
	
	for (v = parent->children; v; v = v->next) {
		if (strcmp(v->name, child) == 0)
			return v;
	}
	return nil;
}

void
genqids(VFile *f, void*)
{
	Vqid *v, *nv;
	char **s;
	
	if (!vqids) {
		/* root element */
		vqids = mallocz(sizeof(Vqid), 1);
		vqids->name = "root";
	}
	
	v = vqids;
	for (s = f->parts; *s; s++) {
		if (**s == 0) {
			/* if root element */
			continue;
		}
		nv = findchild(v, *s);
		if (nv) {
			v = nv;
			continue;
		}
		nv = mallocz(sizeof(Vqid), 1);
		nv->name = strdup(*s);
		nv->vfile = f;
		nv->next = v->children;
		v->children = nv;
		v = nv;
	}
}

static void
rprintqids(Vqid *vq, int nest)
{
	Vqid *v;
	char buf[32];
	if (!vq) return;
	
	for (v = vq; v; v = v->next) {
		pathtostring(buf, sizeof(buf), v->name);
		print("%*sQ%s,\n", nest*4, "", buf);
		rprintqids(v->children, nest+1);
	}
}

static void
rprintfilenames(Vqid *vq)
{
	Vqid *v;
	char buf[32];
	if (!vq) return;
	
	for (v = vq; v; v = v->next) {
		pathtostring(buf, sizeof(buf), v->name);
		print("	[Q%s] {\n", buf);
		print("		.name = \"%s\",\n", v->name);
		print("	},\n");
		rprintfilenames(v->children);
	}
}

void
printqids()
{
	print("#line 0 \"fsgen/code.c\"\n");
	print("enum {\n");
	rprintqids(vqids, 1);
	print("	Qmax,\n");
	print("};\n\n");
	print("Dir filedata[] = {\n");
	rprintfilenames(vqids);
	print("};\n\n");
}