shithub: fsgen

Download patch

ref: 17039fc93f8eb42fe58797dee5082f486616a6a6
parent: e49f718071886411a94f42ebf007f08eca4cfa9d
author: sirjofri <sirjofri@sirjofri.de>
date: Mon Dec 15 11:20:19 EST 2025

begin qid handling, fix parser

--- a/code.c
+++ b/code.c
@@ -3,20 +3,34 @@
 #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++) {
-		if (!(*a)[0])
+		s = *a;
+		if (!s)
+			break;
+		if (!s[0])
 			continue;
-		n = strlen(*a) - 1;
-		if (!((*a)[0] == '{' && (*a)[n] == '}'))
+		n = strlen(s) - 1;
+		if (!(s[0] == '{' && s[n] == '}'))
 			continue;
-		strcpy(buf, *a);
+		strcpy(buf, s);
 		buf[n] = 0;
 		print(", char *%s", buf+1);
 	}
@@ -36,26 +50,16 @@
 }
 
 void
-printread(VFile *file)
+printgenfunc(VFile *file, char *nm)
 {
 	char buf[64];
 	pathtostring(buf, sizeof(buf), file->path);
-	print("static void\nfsread_%s(Req *r", buf);
+	print("static void\nfs%s_%s(Req *r", nm, buf);
 	printvars(file);
 	print(")\n");
 }
 
 void
-printwrite(VFile *file)
-{
-	char buf[64];
-	pathtostring(buf, sizeof(buf), file->path);
-	print("static void\nfswrite_%s(Req *r", buf);
-	printvars(file);
-	print(")\n");
-}
-
-void
 printls(VFile *file)
 {
 	char buf[64];
@@ -71,6 +75,38 @@
 	);
 }
 
+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
@@ -78,6 +114,7 @@
 {
 	char buf[64];
 	char *s;
+	int n;
 	
 	strcpy(buf, file);
 	s = strrchr(buf, '.');
@@ -100,8 +137,23 @@
 	print("\n"
 	"Srv fs = {\n"
 	"	.read = fsread,\n"
+	"	.stat = fsstat,\n"
 	"	.walk1 = fswalk,\n"
-	"};\n\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);
 	
@@ -110,16 +162,6 @@
 	);
 }
 
-typedef struct Vqid Vqid;
-struct Vqid {
-	char *name;
-	VFile *vfile;
-	Vqid *children;
-	Vqid *next;
-};
-
-Vqid *vqids = nil;
-
 static Vqid*
 findchild(Vqid *parent, char *child)
 {
@@ -157,6 +199,7 @@
 		}
 		nv = mallocz(sizeof(Vqid), 1);
 		nv->name = strdup(*s);
+		nv->vfile = f;
 		nv->next = v->children;
 		v->children = nv;
 		v = nv;
@@ -177,10 +220,31 @@
 	}
 }
 
+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");
 }
--- a/dat.h
+++ b/dat.h
@@ -6,6 +6,7 @@
 	int isdir;
 	int hasread;
 	int haswrite;
+	int hasstat;
 	char **parts;
 	VFile *next;
 };
--- a/files.c
+++ b/files.c
@@ -12,14 +12,25 @@
 	char *s;
 	int numparts = 1, n;
 	
+	if (path[1] == 0) {
+		args = mallocz(2, 1);
+		args[0] = mallocz(1, 1);
+		args[0][0] = 0;
+		args[1] = nil;
+		return args;
+	}
+	
 	for (s = path; *s; s++) {
 		if (*s == '/')
 			numparts++;
 	}
+	
 	/* root dir, each directory part, ending nil */
 	args = mallocz(numparts+1, 1);
+	args[numparts] = nil;
 	s = strdup(path);
 	n = getfields(s, args, numparts, 0, "/");
+	
 	assert(s == args[0]);
 	if (n == numparts)
 		return args;
@@ -33,6 +44,10 @@
 addfile(char *path)
 {
 	VFile *old;
+	old = getfile(path);
+	if (old)
+		return old;
+	
 	if (!files) {
 		files = mallocz(sizeof(VFile), 1);
 	} else {
@@ -47,6 +62,18 @@
 	return files;
 }
 
+VFile*
+getfile(char *path)
+{
+	VFile *v;
+	
+	for (v = files; v; v = v->next)
+		if (strcmp(v->path, path) == 0)
+			return v;
+	werrstr("file not found: %s", path);
+	return nil;
+}
+
 void
 foreachfile(void (*f)(VFile*,void*), void *aux)
 {
@@ -54,6 +81,18 @@
 	
 	for (vf = files; vf; vf = vf->next)
 		f(vf, aux);
+}
+
+int
+getnfiles()
+{
+	int n = 0;
+	VFile *v;
+	
+	for (v = files; v; v = v->next)
+		n++;
+	
+	return n;
 }
 
 static int
--- a/fns.h
+++ b/fns.h
@@ -1,12 +1,12 @@
 void vfileinit(void);
 VFile *addfile(char *path);
+VFile *getfile(char *path);
+int getnfiles(void);
 void foreachfile(void (*f)(VFile*,void*), void*);
 
 void genqids(VFile*,void*);
 void printqids(void);
 
-void printread(VFile*);
-void printwrite(VFile*);
-void printls(VFile*);
+void printgenfunc(VFile*, char*);
 void printfs(void);
 void printpre(void);
--- a/fsfunc.inc
+++ b/fsfunc.inc
@@ -1,3 +1,4 @@
 {
+	fs.write = fswrite;
 	return &fs;
 }
--- a/fshandler.inc
+++ b/fshandler.inc
@@ -9,3 +9,26 @@
 {
 	respond(r, nil);
 }
+
+static void
+fsstat(Req *r)
+{
+	uvlong q;
+	
+	q = breakqid(r->fid->qid.path);
+	
+	for (int i = 1; i < Qmax; i++) {
+		if (q == i) {
+			r->d = filedata[i];
+			respond(r, nil);
+			return;
+		}
+	}
+	respond(r, "file not found");
+}
+
+static char*
+fswalk(Fid *fid, char *name, Qid *qid)
+{
+	return nil;
+}
--- a/main.c
+++ b/main.c
@@ -31,12 +31,12 @@
 	
 	while (s = Brdstr(bin, '\n', 1)) {
 		line++;
+Retry:
 		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;
@@ -47,6 +47,7 @@
 				state = COPY;
 				break;
 			}
+			werrstr("invalid input in OUTSIDE: %s", s);
 			goto Err;
 		case COPY:
 			if (strcmp("r}", s) == 0) {
@@ -64,7 +65,13 @@
 				state = HASFILE;
 				break;
 			}
+			if (strcmp("s}", s) == 0) {
+				print("}\n\n");
+				state = HASFILE;
+				break;
+			}
 			if (strcmp("%}", s) == 0) {
+				print("\n");
 				state = OUTSIDE;
 				break;
 			}
@@ -73,6 +80,10 @@
 		case HASFILE:
 			if (s[0] == 0)
 				break;
+			if (s[0] == '/') {
+				state = OUTSIDE;
+				goto Retry;
+			}
 			if (strcmp("r{", s) == 0) {
 				if (currentfile->hasread) {
 					werrstr("file already has a read function");
@@ -79,7 +90,7 @@
 					goto Err;
 				}
 				currentfile->hasread++;
-				printread(currentfile);
+				printgenfunc(currentfile, "read");
 				print("#line %d \"%s\"\n", line, file);
 				print("{\n");
 				state = COPY;
@@ -91,7 +102,7 @@
 					goto Err;
 				}
 				currentfile->haswrite++;
-				printwrite(currentfile);
+				printgenfunc(currentfile, "write");
 				print("#line %d \"%s\"\n", line, file);
 				print("{\n");
 				state = COPY;
@@ -103,12 +114,25 @@
 					goto Err;
 				}
 				currentfile->isdir++;
-				printls(currentfile);
+				printgenfunc(currentfile, "ls");
 				print("#line %d \"%s\"\n", line, file);
 				print("{\n");
 				state = COPY;
 				break;
 			}
+			if (strcmp("s{", s) == 0) {
+				if (currentfile->hasstat) {
+					werrstr("file already has a stat function");
+					goto Err;
+				}
+				currentfile->hasstat++;
+				printgenfunc(currentfile, "stat");
+				print("#line %d \"%s\"\n", line, file);
+				print("{\n");
+				state = COPY;
+				break;
+			}
+			werrstr("invalid input in HASFILE: %s", s);
 			goto Err;
 		}
 		free(s);
@@ -118,19 +142,6 @@
 	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)
 {
@@ -157,7 +168,8 @@
 	
 	foreachfile(genqids, nil);
 	printqids();
-	foreachfile(p, nil);
 	
 	printfs();
+	
+	exits(nil);
 }
--- a/mkfile
+++ b/mkfile
@@ -14,4 +14,4 @@
 code.$O: fsfunc.cinc fshandler.cinc preamble.cinc
 
 %.cinc: %.inc
-	sed 's/^/"/;s/$/\\n"/;' $stem.inc > $target
+	sed 's/\\/\\\\/g;s/"/\\"/g;s/^/"/;s/$/\\n"/;' $stem.inc > $target
--- a/preamble.inc
+++ b/preamble.inc
@@ -3,3 +3,29 @@
 #include <thread.h>
 #include <fcall.h>
 #include <9p.h>
+
+typedef struct Fchildren Fchildren;
+struct Fchildren {
+	int *children;
+};
+
+int SHIFT = 3;
+int qidtype = -1;
+
+static uvlong
+makeqid(uvlong id)
+{
+	return (id << SHIFT) | qidtype;
+}
+
+static uvlong
+getqidid(uvlong qid)
+{
+	return (qid >> SHIFT);
+}
+
+static uvlong
+breakqid(uvlong qid)
+{
+	return (qid & (0x1<<(SHIFT+1) - 1));
+}
--