1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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++;
}
}
}
}
|