ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /appl/lib/fsfilter.b/
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++;
}
}
}
}