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));
+}
--
⑨