duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit d167bdaa7aa3d2ff0398c5dd10b4cd4bb81f6225
parent f966805f2daffa8b6c7d5902a354125778090f1c
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Wed, 24 Aug 2022 14:00:41 -0400

Make Filesystem :iter take a callback word and remove :next

The previous system didn't allow recursion, which is needed in many cases.
Adding recursion support to a :iter/:next system would make it heavier than it
should. A callback word works fine. I hope...

Diffstat:
Mfs/fs/fat.fs | 4++--
Mfs/fs/fatlo.fs | 27+++++++++++----------------
Mfs/sys/file.fs | 14++++----------
Mfs/xcomp/bootlo.fs | 1-
Mposix/glue.fs | 4+---
Mposix/vm.c | 63++++++++++++++++++++++++++++-----------------------------------
6 files changed, 46 insertions(+), 67 deletions(-)

diff --git a/fs/fs/fat.fs b/fs/fs/fat.fs @@ -185,8 +185,8 @@ $e5 const DIRFREE r@ FATLO :getdirentry ( dirent ) DIRFREE swap c! r> writecursector ; : _patchFS ( fs -- ) - ['] fatinfo over 12 + ! ['] fatopen over 16 + ! ['] fatnewfile over 28 + ! - ['] fatnewdir over 32 + ! ['] fatremove over 36 + ! 1 swap to FATLO flags ; + ['] fatinfo over 12 + ! ['] fatopen over 16 + ! ['] fatnewfile over 24 + ! + ['] fatnewdir over 28 + ! ['] fatremove over 32 + ! 1 swap to FATLO flags ; : :mountvolume ( drv -- fs ) FATLO :mountvolume dup _patchFS ; bootfs 12 + @ ' abort = [if] bootfs _patchFS [then] diff --git a/fs/fs/fatlo.fs b/fs/fs/fatlo.fs @@ -241,20 +241,15 @@ extends File struct[ FATFile ]struct extends _FAT struct[ FATLO - 0 value _dirent - : :next ( self -- id-or-0 ) - _dirent not if abort" invalid iterator" then >r - DirEntry SZ to+ _dirent _dirent r@ _FAT :)buf = if - r@ _FAT :nextsector? not if - rootdirentry( to _dirent else \ parses as "lastentry" - r@ _FAT :buf( to _dirent then then - _dirent DirEntry :lastentry? if rdrop 0 to _dirent 0 else - _dirent DirEntry :iterable? if _dirent r> _FAT :getid else r> :next then - then ; - - : :iter ( dirid self -- id-or-0 ) >r - r@ _FAT :getdirentry r@ _FAT :readdir - r@ _FAT :buf( DirEntry SZ - to _dirent r> :next ; + : :iter ( w dirid self -- id-or-0 ) >r \ V1=self + V1 _FAT :getdirentry V1 _FAT :readdir >r ( ) \ V2=w + V1 _FAT :buf( begin ( a ) + dup DirEntry :lastentry? not while ( a ) + dup DirEntry :iterable? if dup V1 _FAT :getid V1 V2 execute then ( a ) + DirEntry SZ + dup V1 _FAT :)buf = if + drop V1 _FAT :nextsector? not if + rootdirentry( ( parses as "lastentry" ) else V1 _FAT :buf( then then + repeat ( a ) drop rdrop rdrop ; : :child ( dirid name self -- id-or-0 ) >r fnbuf! r@ _FAT :getdirentry r@ _FAT :readdir r@ _FAT :findindir @@ -273,8 +268,8 @@ extends _FAT struct[ FATLO : :mountvolume ( drv -- fs ) align4 here >r dup , ( drv R:fs ) 0 ( flags ) , - ['] :child , ['] abort , ['] :fatopen , ['] :iter , ['] :next , ['] abort , - ['] abort , ['] abort , + ['] :child , ['] abort , ['] :fatopen , ['] :iter , ['] abort , ['] abort , + ['] abort , 0 , 0 , 0 , 0 , ( drv ) \ At this point, "here" points to the FAT-header-to-be. Read the first sector \ directly in "here": we'll have the header right here! diff --git a/fs/sys/file.fs b/fs/sys/file.fs @@ -35,11 +35,8 @@ struct[ Path r@ id swap r@ fs Filesystem :newfile ( id ) r> fs swap :new ; : :newdir ( name self -- path ) >r r@ id swap r@ fs Filesystem :newdir ( id ) r> fs swap :new ; - : :iter ( self -- path ) >r - r@ id r@ fs Filesystem :iter ( id ) r> fs swap :new ; - : :next ( self -- path-or-0 ) >r - r@ fs Filesystem :next ( id ) - dup if r> fs swap :new else rdrop then ; + : :iter ( w self -- ) >r + r@ id r> fs Filesystem :iter ( id ) ; : :remove ( self -- ) dup id swap fs Filesystem :remove ; : :root ( self -- path ) fs 0 :new ; @@ -82,11 +79,8 @@ struct[ Path _src size _src :readbuf ?dup while ( a n ) _dst :self IO :write repeat _dst :close _src :close ; - : :listdir ( self -- ) >r - r@ :iter begin ( path-or-0 ) ?dup while - :info FSInfo name stype nl> - r@ :next repeat - rdrop ; + : _ ( id fs -- ) Filesystem :info FSInfo name stype nl> ; + : :listdir ( self -- ) ['] _ swap :iter ; ]struct Path _curpath structbind Path curpath diff --git a/fs/xcomp/bootlo.fs b/fs/xcomp/bootlo.fs @@ -258,7 +258,6 @@ struct[ Filesystem smethod :info smethod :open smethod :iter - smethod :next smethod :newfile smethod :newdir smethod :remove diff --git a/posix/glue.fs b/posix/glue.fs @@ -1,13 +1,11 @@ : _ doer ' , does> nip @ execute ; _ _:child _fchild _ _:open _fopen _ _:info _finfo -_ _:iter _fiter _ _:next _fnext create _POSIXFS 0 , 0 , ' _:child , ' _:info , ' _:open , - ' _:iter , - ' _:next , + ' _fiter , ' abort , ' abort , ' abort , diff --git a/posix/vm.c b/posix/vm.c @@ -872,43 +872,36 @@ static void FINFO() { // op: 64 memcpy(&vm.mem[dst+13], name, strlen(name)); } -static dword iterid = 0; -static DIR *dirp = NULL; - -static void FNEXT() { // op: 65 +// ( w id self -- ) +static void FITER() { // op: 65 + DIR *dirp; struct dirent *d; + dword self = ppop(); + dword fsid = ppop(); + dword w = ppop(); + int baselen; char path[MAXPATHSZ] = {0}; - dword res; - if (!dirp) { - printf("Calling next without an iter first!"); - vm.PC = gd(ABORT); - return; - } - do { - d = readdir(dirp); - } while (d && ((strcmp(d->d_name, ".") == 0) || (strcmp(d->d_name, "..") == 0))); - if (!d) { - ppush(0); - return; - } - strcpy(path, getpathfromid(iterid)); - strcat(path, "/"); - strcat(path, d->d_name); - res = findpath(path); - if (!res) { - while (fsids[++res][0]); - strcpy(fsids[res], path); - } - ppush(res); -} - -static void FITER() { // op: 66 - iterid = ppop(); - char *path = getpathfromid(iterid); - if (dirp) closedir(dirp); + strcpy(path, getpathfromid(fsid)); dirp = opendir(path); if (dirp) { - FNEXT(); + strcat(path, "/"); + baselen = strlen(path); + while(1) { + do { + d = readdir(dirp); + } while (d && ((strcmp(d->d_name, ".") == 0) || (strcmp(d->d_name, "..") == 0))); + if (!d) break; + strcpy(&path[baselen], d->d_name); + fsid = findpath(path); + if (!fsid) { + while (fsids[++fsid][0]); + strcpy(fsids[fsid], path); + } + ppush(fsid); + ppush(self); + callword(w); + } + closedir(dirp); } else { printf("Couldn't open dir %s\n", path); vm.PC = gd(ABORT); @@ -965,7 +958,7 @@ static void (*ops[OPCNT])() = { RSHIFT, LITN, EXECUTEWR, EXITWR, MOVE, MOVEWR, RTYPE, WNF, STACKCHK, MAYBEWORD, WORD, PARSE, REQ, FIND, APOS, COMPILING, SWR, STARTCOMP, STOPCOMP, RUNWORD, NULL, NULL, NULL, NULL, - FCHILD, FOPEN, FREADBUF, FCLOSE, FINFO, FNEXT, FITER, NULL, + FCHILD, FOPEN, FREADBUF, FCLOSE, FINFO, FITER, NULL, NULL, MOUNTDRV, DRVRD, DRVWR}; static char *opnames[OPCNT] = { @@ -981,7 +974,7 @@ static char *opnames[OPCNT] = { "rshift", "litn", "execute,", "exit,", "move", "move,", "rtype", "(wnf)", "stack?", "maybeword", "word", "parse", "[]=", "find", "'", "compiling", ",\"", "]", "[", "runword", NULL, NULL, NULL, NULL, - "_fchild", "_fopen", "_freadbuf", "_fclose", "_finfo", "_fnext", "_fiter", NULL, + "_fchild", "_fopen", "_freadbuf", "_fclose", "_finfo", "_fiter", NULL, NULL, "_mountdrv", "_drv@", "_drv!"}; static void oprun1() { // run next op