duskos

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

commit e34038044db5085567c0fcc44eb8459f4e8ed2f7
parent ce95a0ef822e52e0cb01dae88d7f0d4c0b654e00
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Sat,  4 Feb 2023 15:12:18 -0500

sys/file: make Path :iter into an :iterator

Diffstat:
Mfs/doc/sys/file.txt | 20+++++++++++---------
Mfs/sys/file.fs | 56++++++++++++++++++++++----------------------------------
Mfs/xcomp/i386/pc/build.fs | 12+++++-------
3 files changed, 38 insertions(+), 50 deletions(-)

diff --git a/fs/doc/sys/file.txt b/fs/doc/sys/file.txt @@ -132,20 +132,22 @@ on to a Path reference a little longer, you should copy it elsewhere. doesn't start with "/", the search will start from this directory. Aborts if path is not found. +:iter ( self -- ) + Writes an iterator that iterates over all "self"'s children. During yields, + "i" is the FSID of the children and "j" is the fsid of the parent (self). A + Path structure conveniently wraps "i" and live at ":i". + + Recursion notes: :iter can recurse and it will behave as expected. However, + all recursive :iter calls must take place within the same filesystem. + +:i ( self -- path ) + Wraps "i" from :iter in a Path structure. + :open ( self -- file ) :info ( self -- file ) :child ( name self -- path-or-0 ) -:iter ( w self -- ) Convenience proxies to the corresponding methods in the Filesystem API. -:iterdirs ( w self -- ) - Calls :iter but filters the call to 'w' to directories only. On top of this, - an additional "info" argument is passed to 'w', making its signature - "id fs info -- " - -:iterfiles ( w self -- ) - Same as :iterdirs, but for files. - ## Global variables The File subsystem has 2 important global variables: diff --git a/fs/sys/file.fs b/fs/sys/file.fs @@ -24,7 +24,7 @@ struct[ Path create _curpath bootfs , 0 , - $100 const BUFSZ + $200 const BUFSZ create _paths BUFSZ SZ * allot 0 value _pathidx @@ -41,19 +41,15 @@ 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 ( w self -- ) dup fs >r swap >r ( self ) \ V1=fs V2=w - id dup >r 0 V1 Filesystem :iter ( childid ) \ V3=dirid - begin ?dup while - dup V1 V2 execute ( childid ) - V3 swap V1 Filesystem :iter repeat - 2rdrop rdrop ; - - : _dir? ( id fs -- info f ) 2dup Filesystem :info dup FSInfo dir? ; - alias noop _w ( id fs info -- ) - : _ ( id fs -- ) _dir? if _w else 2drop drop then ; - : :iterdirs ( w self -- ) swap ['] _w realias ['] _ swap :iter ; - : _ ( id fs -- ) _dir? not if _w else 2drop drop then ; - : :iterfiles ( w self -- ) swap ['] _w realias ['] _ swap :iter ; + + \ recursive iteration works fine, but *only* within the same FS at once. + 0 value _fs + 0 value :i + :iterator :iter ( self -- ) + dup fs to _fs id to j 0 to i begin + j i _fs Filesystem :iter ?dup while + to i _fs i :new to :i yield repeat unyield ; + : :remove ( self -- ) dup id swap fs Filesystem :remove ; : :root ( self -- path ) fs 0 :new ; @@ -91,28 +87,20 @@ struct[ Path : :appendfile ( src self -- ) :open dup File size over File :seek swap :open _copyfile ; - - \ dst is the *parent* of where the source element will be - create _dst SZ allot - create _src SZ allot - : _ ( id fs -- ) - _src to fs _src to id - _src :info dup FSInfo name stype nl> - dup FSInfo dir? if ( info ) - _dst id swap FSInfo name _dst fs Filesystem :?newdir ( id ) - to@! _dst id ( oldid ) - ['] _ _src :iter ( oldid ) to _dst id - else ( info ) - _dst id swap FSInfo name _dst fs Filesystem :?newfile ( id ) - _dst fs Filesystem :open ( dstfile ) _src :open ( srcfile ) - _copyfile then ; - \ For now, this method has to be called on a freshly created directory as \ "dst". We assume that no destination file or directory exist in dst. - : :copydir ( dst self -- ) swap _dst SZ move ['] _ swap :iter ; - - : _ ( id fs -- ) Filesystem :info FSInfo name stype nl> ; - : :listdir ( self -- ) ['] _ swap :iter ; + : :copydir ( dst self -- ) >r >r \ V1=self V2=dst + V1 :iter + :i :info dup FSInfo name stype nl> + dup FSInfo dir? if ( info ) + V2 id swap FSInfo name V2 fs Filesystem :?newdir ( id ) + V2 fs swap :new :i :copydir + else ( info ) + V2 id swap FSInfo name V2 fs Filesystem :?newfile ( id ) + V2 fs swap :new :i :copyfile then + next 2rdrop ; + + : :listdir ( self -- ) :iter :i :info FSInfo name stype nl> next ; ]struct Path _curpath structbind Path curpath diff --git a/fs/xcomp/i386/pc/build.fs b/fs/xcomp/i386/pc/build.fs @@ -30,14 +30,12 @@ org value kernel \ $00 to fatopts drvnum ( drv ) dup FAT newFAT12 FAT :mountvolume ; -0 value _dstfs -: _iterdir ( id fs info -- ) - FSInfo name dup S" doc" s= if 2drop else ( id fs name ) - 0 swap _dstfs Filesystem :newdir ( id fs dstid ) - _dstfs swap Path :new ( id fs dstpath ) - rot> swap Path :new ( dstpath srcpath ) Path :copydir ; : copyfs ( srcfs dstfs -- ) - to _dstfs 0 Path :new ['] _iterdir swap Path :iterdirs ; + 0 Path :new swap 0 Path :new Path :iter ( dst ) + Path :i Path :info dup FSInfo dir? + over FSInfo name S" doc" s= not and if ( dst info ) + FSInfo name over Path :newdir ( dst newdir ) + Path :i Path :copydir else drop then next ( dst ) drop ; $200 const SECSZ \ TODO: get from drive create _buf SECSZ allot0