shithub: fsgen

Download patch

ref: d7de4a7c8e5532dd8ac6f63616836c03ef9bd4d5
parent: f41811c5b13705495acee0eda08a8bb5955c1e00
author: sirjofri <sirjofri@sirjofri.de>
date: Tue Dec 16 06:10:12 EST 2025

adds prepass

--- a/main.c
+++ b/main.c
@@ -24,10 +24,114 @@
 VFile *currentfile = nil;
 
 static void
+prepass(Biobuf *bin)
+{
+	char *s;
+	int line = 0;
+	state = OUTSIDE;
+	
+	while (s = Brdstr(bin, '\n', 1)) {
+		line++;
+Retry:
+		switch (state) {
+		case OUTSIDE:
+			if (s[0] == 0)
+				break;
+			if (s[0] == '/') {
+				currentfile = addfile(s);
+				if (!currentfile)
+					goto Err;
+				state = HASFILE;
+				break;
+			}
+			if (strcmp("%{", s) == 0) {
+				state = COPY;
+				break;
+			}
+			werrstr("prepass: invalid input in OUTSIDE: %s", s);
+			goto Err;
+		case COPY:
+			if (strcmp("r}", s) == 0) {
+				state = HASFILE;
+				break;
+			}
+			if (strcmp("w}", s) == 0) {
+				state = HASFILE;
+				break;
+			}
+			if (strcmp("ls}", s) == 0) {
+				state = HASFILE;
+				break;
+			}
+			if (strcmp("s}", s) == 0) {
+				state = HASFILE;
+				break;
+			}
+			if (strcmp("%}", s) == 0) {
+				state = OUTSIDE;
+				break;
+			}
+			break;
+		case HASFILE:
+			if (s[0] == 0)
+				break;
+			if (s[0] == '/') {
+				state = OUTSIDE;
+				goto Retry;
+			}
+			if (strcmp("r{", s) == 0) {
+				if (currentfile->hasread) {
+					werrstr("%s already has a read function", currentfile->path);
+					goto Err;
+				}
+				currentfile->hasread++;
+				state = COPY;
+				break;
+			}
+			if (strcmp("w{", s) == 0) {
+				if (currentfile->haswrite) {
+					werrstr("%s already has a write function", currentfile->path);
+					goto Err;
+				}
+				currentfile->haswrite++;
+				state = COPY;
+				break;
+			}
+			if (strcmp("ls{", s) == 0) {
+				if (currentfile->isdir) {
+					werrstr("%s already has a ls function", currentfile->path);
+					goto Err;
+				}
+				currentfile->isdir++;
+				state = COPY;
+				break;
+			}
+			if (strcmp("s{", s) == 0) {
+				if (currentfile->hasstat) {
+					werrstr("%s already has a stat function", currentfile->path);
+					goto Err;
+				}
+				currentfile->hasstat++;
+				state = COPY;
+				break;
+			}
+			werrstr("invalid input in HASFILE: %s", s);
+			goto Err;
+		}
+		free(s);
+	}
+	return;
+Err:
+	fprint(2, "prepass %s:%d: %r\n", file, line);
+	free(s);
+}
+
+static void
 process(Biobuf *bin)
 {
 	char *s;
 	int line = 0;
+	state = OUTSIDE;
 	
 	while (s = Brdstr(bin, '\n', 1)) {
 		line++;
@@ -86,11 +190,6 @@
 				goto Retry;
 			}
 			if (strcmp("r{", s) == 0) {
-				if (currentfile->hasread) {
-					werrstr("file already has a read function");
-					goto Err;
-				}
-				currentfile->hasread++;
 				printgenfunc(currentfile, "read");
 				print("#line %d \"%s\"\n", line, file);
 				print("{\n");
@@ -98,11 +197,6 @@
 				break;
 			}
 			if (strcmp("w{", s) == 0) {
-				if (currentfile->haswrite) {
-					werrstr("file already has a write function");
-					goto Err;
-				}
-				currentfile->haswrite++;
 				printgenfunc(currentfile, "write");
 				print("#line %d \"%s\"\n", line, file);
 				print("{\n");
@@ -110,11 +204,6 @@
 				break;
 			}
 			if (strcmp("ls{", s) == 0) {
-				if (currentfile->isdir) {
-					werrstr("file already has a ls function");
-					goto Err;
-				}
-				currentfile->isdir++;
 				printgenfunc(currentfile, "ls");
 				print("#line %d \"%s\"\n", line, file);
 				print("{\n");
@@ -122,11 +211,6 @@
 				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");
@@ -140,7 +224,8 @@
 	}
 	return;
 Err:
-	fprint(2, "parse error at %s:%d: %r\n", file, line);
+	fprint(2, "process %s:%d: %r\n", file, line);
+	free(s);
 }
 
 void
@@ -162,12 +247,14 @@
 		sysfatal("open: %r");
 	
 	vfileinit();
+	prepass(bin);
 	printpre();
 	
+	printauxvars();
+	
+	Bseek(bin, 0, 0);
 	process(bin);
 	Bterm(bin);
-	
-	printauxvars();
 	
 	foreachfile(genqids, nil);
 	printqids();
--- a/preamble.inc
+++ b/preamble.inc
@@ -15,9 +15,6 @@
 	Dir dir;
 };
 
-typedef struct FileAux FileAux;
-#pragma incomplete FileAux
-
 int SHIFT = 3;
 int qidtype = -1;
 
--- a/vars.c
+++ b/vars.c
@@ -67,6 +67,7 @@
 	foreachfile(collectvars, nil);
 	
 	print(
+	"typedef struct FileAux FileAux;\n"
 	"struct FileAux {\n"
 	);
 	
--