summaryrefslogtreecommitdiff
path: root/appl/lib/fsfilter.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/lib/fsfilter.b')
-rw-r--r--appl/lib/fsfilter.b67
1 files changed, 67 insertions, 0 deletions
diff --git a/appl/lib/fsfilter.b b/appl/lib/fsfilter.b
new file mode 100644
index 00000000..ea4041e4
--- /dev/null
+++ b/appl/lib/fsfilter.b
@@ -0,0 +1,67 @@
+implement Fsfilter;
+
+#
+# Copyright © 2004 Vita Nuova Holdings Limited
+#
+
+include "sys.m";
+include "draw.m";
+include "sh.m";
+include "fslib.m";
+ Fschan, Next, Quit, Skip, Down: import Fslib;
+
+filter[T](t: T, src, dst: Fschan)
+ for{
+ T =>
+ query: fn(t: self T, d: ref Sys->Dir, name: string, depth: int): int;
+ }
+{
+ names: list of string;
+ name: string;
+ indent := 0;
+ myreply := chan of int;
+loop:
+ for(;;){
+ (d, reply) := <-src;
+ if(d.dir != nil){
+ p := name;
+ if(indent > 0){
+ if(p != nil && p[len p - 1] != '/')
+ p[len p] = '/';
+ }
+ if(t.query(d.dir, p + d.dir.name, indent) == 0 && indent > 0){
+ reply <-= Next;
+ continue;
+ }
+ }
+ dst <-= (d, myreply);
+ case reply <-= <-myreply {
+ Quit =>
+ break loop;
+ Next =>
+ if(d.dir == nil && d.data == nil){
+ if(--indent == 0)
+ break loop;
+ (name, names) = (hd names, tl names);
+ }
+ Skip =>
+ if(--indent == 0)
+ break loop;
+ (name, names) = (hd names, tl names);
+ Down =>
+ if(d.dir != nil){
+ names = name :: names;
+ if(d.dir.mode & Sys->DMDIR){
+ if(indent == 0)
+ name = d.dir.name;
+ else{
+ if(name[len name - 1] != '/')
+ name[len name] = '/';
+ name += d.dir.name;
+ }
+ }
+ indent++;
+ }
+ }
+ }
+}