summaryrefslogtreecommitdiff
path: root/lib/fileutil
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2016-06-02 09:31:26 -0400
committerOri Bernstein <ori@eigenstate.org>2016-06-02 09:31:26 -0400
commitd5eaba0e687c26c7eb1a7954eda6e82508e0775a (patch)
treef127f81df24738cea9ac0634e72fb9ca9fd84380 /lib/fileutil
parentf79cf73913ebc6394f5333440bf6d9312c07719a (diff)
downloadmc-d5eaba0e687c26c7eb1a7954eda6e82508e0775a.tar.gz
Add a file walking library.
Diffstat (limited to 'lib/fileutil')
-rw-r--r--lib/fileutil/bld.sub5
-rw-r--r--lib/fileutil/walk.myr61
2 files changed, 66 insertions, 0 deletions
diff --git a/lib/fileutil/bld.sub b/lib/fileutil/bld.sub
new file mode 100644
index 0000000..b03b7a8
--- /dev/null
+++ b/lib/fileutil/bld.sub
@@ -0,0 +1,5 @@
+lib fileutil =
+ walk.myr
+ lib ../std:std
+;;
+
diff --git a/lib/fileutil/walk.myr b/lib/fileutil/walk.myr
new file mode 100644
index 0000000..6af3d1d
--- /dev/null
+++ b/lib/fileutil/walk.myr
@@ -0,0 +1,61 @@
+use std
+
+pkg fileutil =
+ type walkiter = struct
+ dirstk : std.dir#[:]
+ curdir : byte[:][:]
+ iterdir : bool
+ ;;
+
+ impl iterable walkiter -> byte[:]
+ const bywalk : (dir : std.dir# -> walkiter)
+;;
+
+const bywalk = {d
+ -> [.dirstk = std.sldup([d][:]), .curdir = std.sldup([""][:])]
+}
+
+impl iterable walkiter -> byte[:] =
+ __iternext__ = {itp, valp
+ var cur, p
+
+:nextfile
+ 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 std.fisdir(p)
+ match std.diropen(p)
+ | `std.Ok d: std.slpush(&itp.dirstk, d)
+ | `std.Fail e: /* ? */
+ ;;
+ std.slpush(&itp.curdir, p)
+ goto nextfile
+ else
+ 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
+ ;;
+ ;;
+ }
+
+ __iterfin__ = {itp, valp
+ std.slfree(valp#)
+ }
+;;
+
+generic last = {sl : @a[:]
+ -> sl[sl.len - 1]
+}