diff options
Diffstat (limited to 'lib/fileutil/walk.myr')
-rw-r--r-- | lib/fileutil/walk.myr | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/lib/fileutil/walk.myr b/lib/fileutil/walk.myr index 75ed5e2..dbdfb5f 100644 --- a/lib/fileutil/walk.myr +++ b/lib/fileutil/walk.myr @@ -1,18 +1,33 @@ use std +use "loopcheck" + pkg fileutil = type walkiter = struct dirstk : std.dir#[:] curdir : byte[:][:] - iterdir : bool + loopck : loopcheck ;; impl iterable walkiter -> byte[:] - const bywalk : (dir : std.dir# -> walkiter) + const bywalk : (dir : byte[:] -> walkiter) ;; -const bywalk = {d - -> [.dirstk = std.sldup([d][:]), .curdir = std.sldup([""][:])] +const bywalk = {p + match std.diropen(p) + | `std.Ok d: + -> [ + .dirstk = std.sldup([d][:]), + .curdir = std.sldup([std.sldup(p)][:]), + .loopck = mkloopcheck(p), + ] + | `std.Err e: + -> [ + .dirstk = [][:], + .curdir = [][:], + .loopck = mkloopcheck(p), + ] + ;; } impl iterable walkiter -> byte[:] = @@ -20,34 +35,38 @@ impl iterable walkiter -> byte[:] = var cur, p :nextfile + if itp.dirstk.len < 1 + freeloopcheck(itp.loopck) + -> false + ;; cur = itp.dirstk[itp.dirstk.len - 1] match std.dirread(cur) | `std.Some ".": goto nextfile | `std.Some "..": goto nextfile | `std.Some ent: p = std.pathcat(itp.curdir[itp.curdir.len - 1], ent) + if looped(itp.loopck, p) + std.slfree(p) + goto nextfile + ;; if std.fisdir(p) match std.diropen(p) - | `std.Ok d: std.slpush(&itp.dirstk, d) + | `std.Ok d: + std.slpush(&itp.dirstk, d) + std.slpush(&itp.curdir, p) | `std.Err e: /* ? */ + std.slfree(p) ;; - std.slpush(&itp.curdir, p) goto nextfile - else - valp# = p ;; + valp# = p -> true | `std.None: - /* don't close the directory given to us by the user */ - if itp.dirstk.len > 1 - std.dirclose(itp.dirstk[itp.dirstk.len - 1]) - std.slfree(itp.curdir[itp.curdir.len - 1]) - std.slpop(&itp.curdir) - std.slpop(&itp.dirstk) - goto nextfile - else - -> false - ;; + std.dirclose(cur) + std.slfree(itp.curdir[itp.curdir.len - 1]) + std.slpop(&itp.curdir) + std.slpop(&itp.dirstk) + goto nextfile ;; } |