xref: /inferno-os/appl/lib/fsfilter.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsythimplement Fsfilter;
2*37da2899SCharles.Forsyth
3*37da2899SCharles.Forsyth#
4*37da2899SCharles.Forsyth# Copyright © 2004 Vita Nuova Holdings Limited
5*37da2899SCharles.Forsyth#
6*37da2899SCharles.Forsyth
7*37da2899SCharles.Forsythinclude "sys.m";
8*37da2899SCharles.Forsythinclude "draw.m";
9*37da2899SCharles.Forsythinclude "sh.m";
10*37da2899SCharles.Forsythinclude "fslib.m";
11*37da2899SCharles.Forsyth	Fschan, Next, Quit, Skip, Down: import Fslib;
12*37da2899SCharles.Forsyth
13*37da2899SCharles.Forsythfilter[T](t: T, src, dst: Fschan)
14*37da2899SCharles.Forsyth	for{
15*37da2899SCharles.Forsyth	T =>
16*37da2899SCharles.Forsyth		query: fn(t: self T, d: ref Sys->Dir, name: string, depth: int): int;
17*37da2899SCharles.Forsyth	}
18*37da2899SCharles.Forsyth{
19*37da2899SCharles.Forsyth	names: list of string;
20*37da2899SCharles.Forsyth	name: string;
21*37da2899SCharles.Forsyth	indent := 0;
22*37da2899SCharles.Forsyth	myreply := chan of int;
23*37da2899SCharles.Forsythloop:
24*37da2899SCharles.Forsyth	for(;;){
25*37da2899SCharles.Forsyth		(d, reply) := <-src;
26*37da2899SCharles.Forsyth		if(d.dir != nil){
27*37da2899SCharles.Forsyth			p := name;
28*37da2899SCharles.Forsyth			if(indent > 0){
29*37da2899SCharles.Forsyth				if(p != nil && p[len p - 1] != '/')
30*37da2899SCharles.Forsyth					p[len p] = '/';
31*37da2899SCharles.Forsyth			}
32*37da2899SCharles.Forsyth			if(t.query(d.dir, p + d.dir.name, indent) == 0 && indent > 0){
33*37da2899SCharles.Forsyth				reply <-= Next;
34*37da2899SCharles.Forsyth				continue;
35*37da2899SCharles.Forsyth			}
36*37da2899SCharles.Forsyth		}
37*37da2899SCharles.Forsyth		dst <-= (d, myreply);
38*37da2899SCharles.Forsyth		case reply <-= <-myreply {
39*37da2899SCharles.Forsyth		Quit =>
40*37da2899SCharles.Forsyth			break loop;
41*37da2899SCharles.Forsyth		Next =>
42*37da2899SCharles.Forsyth			if(d.dir == nil && d.data == nil){
43*37da2899SCharles.Forsyth				if(--indent == 0)
44*37da2899SCharles.Forsyth					break loop;
45*37da2899SCharles.Forsyth				(name, names) = (hd names, tl names);
46*37da2899SCharles.Forsyth			}
47*37da2899SCharles.Forsyth		Skip =>
48*37da2899SCharles.Forsyth			if(--indent == 0)
49*37da2899SCharles.Forsyth				break loop;
50*37da2899SCharles.Forsyth			(name, names) = (hd names, tl names);
51*37da2899SCharles.Forsyth		Down =>
52*37da2899SCharles.Forsyth			if(d.dir != nil){
53*37da2899SCharles.Forsyth				names = name :: names;
54*37da2899SCharles.Forsyth				if(d.dir.mode & Sys->DMDIR){
55*37da2899SCharles.Forsyth					if(indent == 0)
56*37da2899SCharles.Forsyth						name = d.dir.name;
57*37da2899SCharles.Forsyth					else{
58*37da2899SCharles.Forsyth						if(name[len name - 1] != '/')
59*37da2899SCharles.Forsyth							name[len name] = '/';
60*37da2899SCharles.Forsyth						name += d.dir.name;
61*37da2899SCharles.Forsyth					}
62*37da2899SCharles.Forsyth				}
63*37da2899SCharles.Forsyth				indent++;
64*37da2899SCharles.Forsyth			}
65*37da2899SCharles.Forsyth		}
66*37da2899SCharles.Forsyth	}
67*37da2899SCharles.Forsyth}
68