xref: /inferno-os/appl/cmd/test.b (revision 6e425a9de8c003b5a733621a6b6730ec3cc902b8)
137da2899SCharles.Forsythimplement Test;
237da2899SCharles.Forsyth
337da2899SCharles.Forsyth#
4*6e425a9dSCharles.Forsyth#	venerable
5*6e425a9dSCharles.Forsyth#		test expression
637da2899SCharles.Forsyth#
737da2899SCharles.Forsyth
837da2899SCharles.Forsythinclude "sys.m";
937da2899SCharles.Forsyth	sys: Sys;
1037da2899SCharles.Forsyth	stderr: ref Sys->FD;
1137da2899SCharles.Forsyth
1237da2899SCharles.Forsythinclude "draw.m";
1337da2899SCharles.Forsyth
14*6e425a9dSCharles.Forsythinclude "daytime.m";
15*6e425a9dSCharles.Forsyth	daytime: Daytime;
16*6e425a9dSCharles.Forsyth
1737da2899SCharles.ForsythTest: module
1837da2899SCharles.Forsyth{
1937da2899SCharles.Forsyth	init:	fn(ctxt: ref Draw->Context, argv: list of string);
2037da2899SCharles.Forsyth};
2137da2899SCharles.Forsyth
22*6e425a9dSCharles.Forsythgargs: list of string;
2337da2899SCharles.Forsyth
24*6e425a9dSCharles.Forsythinit(nil: ref Draw->Context, args: list of string)
2537da2899SCharles.Forsyth{
26*6e425a9dSCharles.Forsyth	if(args == nil)
2737da2899SCharles.Forsyth		return;
28*6e425a9dSCharles.Forsyth	gargs = tl args;
2937da2899SCharles.Forsyth
3037da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
3137da2899SCharles.Forsyth	stderr = sys->fildes(2);
3237da2899SCharles.Forsyth
33*6e425a9dSCharles.Forsyth	if(gargs == nil)
34*6e425a9dSCharles.Forsyth		raise "fail:usage";
35*6e425a9dSCharles.Forsyth	if(!e())
36*6e425a9dSCharles.Forsyth		raise "fail:false";
3737da2899SCharles.Forsyth}
3837da2899SCharles.Forsyth
39*6e425a9dSCharles.Forsythnextarg(mt: int): string
4037da2899SCharles.Forsyth{
41*6e425a9dSCharles.Forsyth	if(gargs == nil){
42*6e425a9dSCharles.Forsyth		if(mt)
4337da2899SCharles.Forsyth			return nil;
4437da2899SCharles.Forsyth		synbad("argument expected");
4537da2899SCharles.Forsyth	}
46*6e425a9dSCharles.Forsyth	s := hd gargs;
47*6e425a9dSCharles.Forsyth	gargs = tl gargs;
48*6e425a9dSCharles.Forsyth	return s;
4937da2899SCharles.Forsyth}
5037da2899SCharles.Forsyth
51*6e425a9dSCharles.Forsythnextintarg(): (int, int)
5237da2899SCharles.Forsyth{
53*6e425a9dSCharles.Forsyth	if(gargs != nil && isint(hd gargs))
54*6e425a9dSCharles.Forsyth		return (1, int nextarg(0));
5537da2899SCharles.Forsyth	return (0, 0);
5637da2899SCharles.Forsyth}
5737da2899SCharles.Forsyth
58*6e425a9dSCharles.Forsythisnextarg(s: string): int
59*6e425a9dSCharles.Forsyth{
60*6e425a9dSCharles.Forsyth	if(gargs != nil && hd gargs == s){
61*6e425a9dSCharles.Forsyth		gargs = tl gargs;
62*6e425a9dSCharles.Forsyth		return 1;
63*6e425a9dSCharles.Forsyth	}
64*6e425a9dSCharles.Forsyth	return 0;
65*6e425a9dSCharles.Forsyth}
66*6e425a9dSCharles.Forsyth
6737da2899SCharles.Forsythe(): int
6837da2899SCharles.Forsyth{
6937da2899SCharles.Forsyth	p1 := e1();
70*6e425a9dSCharles.Forsyth	if(isnextarg("-o"))
7137da2899SCharles.Forsyth		return p1 || e();
7237da2899SCharles.Forsyth	return p1;
7337da2899SCharles.Forsyth}
7437da2899SCharles.Forsyth
7537da2899SCharles.Forsythe1(): int
7637da2899SCharles.Forsyth{
7737da2899SCharles.Forsyth	p1 := e2();
78*6e425a9dSCharles.Forsyth	if(isnextarg("-a"))
7937da2899SCharles.Forsyth		return p1 && e1();
8037da2899SCharles.Forsyth	return p1;
8137da2899SCharles.Forsyth}
8237da2899SCharles.Forsyth
8337da2899SCharles.Forsythe2(): int
8437da2899SCharles.Forsyth{
85*6e425a9dSCharles.Forsyth	if(isnextarg("!"))
8637da2899SCharles.Forsyth		return !e2();
8737da2899SCharles.Forsyth	return e3();
8837da2899SCharles.Forsyth}
8937da2899SCharles.Forsyth
9037da2899SCharles.Forsythe3(): int
9137da2899SCharles.Forsyth{
92*6e425a9dSCharles.Forsyth	a := nextarg(0);
93*6e425a9dSCharles.Forsyth	case a {
94*6e425a9dSCharles.Forsyth	"(" =>
9537da2899SCharles.Forsyth		p1 := e();
96*6e425a9dSCharles.Forsyth		if(nextarg(0) != ")")
9737da2899SCharles.Forsyth			synbad(") expected");
9837da2899SCharles.Forsyth		return p1;
99*6e425a9dSCharles.Forsyth	"-A" =>
100*6e425a9dSCharles.Forsyth		return hasmode(nextarg(0), Sys->DMAPPEND);
101*6e425a9dSCharles.Forsyth	"-L" =>
102*6e425a9dSCharles.Forsyth		return hasmode(nextarg(0), Sys->DMEXCL);
103*6e425a9dSCharles.Forsyth	"-T" =>
104*6e425a9dSCharles.Forsyth		return hasmode(nextarg(0), Sys->DMTMP);
105*6e425a9dSCharles.Forsyth	"-f" =>
106*6e425a9dSCharles.Forsyth		f := nextarg(0);
107*6e425a9dSCharles.Forsyth		return exists(f) && !hasmode(f, Sys->DMDIR);
108*6e425a9dSCharles.Forsyth	"-d" =>
109*6e425a9dSCharles.Forsyth		return hasmode(nextarg(0), Sys->DMDIR);
110*6e425a9dSCharles.Forsyth	"-r" =>
111*6e425a9dSCharles.Forsyth		return sys->open(nextarg(0), Sys->OREAD) != nil;
112*6e425a9dSCharles.Forsyth	"-w" =>
113*6e425a9dSCharles.Forsyth		return sys->open(nextarg(0), Sys->OWRITE) != nil;
114*6e425a9dSCharles.Forsyth	"-x" =>
115*6e425a9dSCharles.Forsyth		fd := sys->open(nextarg(0), Sys->OREAD);
116*6e425a9dSCharles.Forsyth		if(fd == nil)
11737da2899SCharles.Forsyth			return 0;
118*6e425a9dSCharles.Forsyth		(ok, d) := sys->fstat(fd);
119*6e425a9dSCharles.Forsyth		if(ok < 0)
12037da2899SCharles.Forsyth			return 0;
121*6e425a9dSCharles.Forsyth		return (d.mode & 8r111) != 0;
122*6e425a9dSCharles.Forsyth	"-e" =>
123*6e425a9dSCharles.Forsyth		return exists(nextarg(0));
124*6e425a9dSCharles.Forsyth	"-s" =>
125*6e425a9dSCharles.Forsyth		(ok, d) := sys->stat(nextarg(0));
126*6e425a9dSCharles.Forsyth		if(ok < 0)
12737da2899SCharles.Forsyth			return 0;
128*6e425a9dSCharles.Forsyth		return d.length > big 0;
129*6e425a9dSCharles.Forsyth	"-t" =>
130*6e425a9dSCharles.Forsyth		(ok, fd) := nextintarg();
13137da2899SCharles.Forsyth		if(!ok)
132*6e425a9dSCharles.Forsyth			return iscons(1);
133*6e425a9dSCharles.Forsyth		return iscons(fd);
134*6e425a9dSCharles.Forsyth	"-n" =>
135*6e425a9dSCharles.Forsyth		return nextarg(0) != "";
136*6e425a9dSCharles.Forsyth	"-z" =>
137*6e425a9dSCharles.Forsyth		return nextarg(0) == "";
138*6e425a9dSCharles.Forsyth	* =>
139*6e425a9dSCharles.Forsyth		p2 := nextarg(1);
14037da2899SCharles.Forsyth		if(p2 == nil)
14137da2899SCharles.Forsyth			return a != nil;
142*6e425a9dSCharles.Forsyth		case p2 {
143*6e425a9dSCharles.Forsyth		"=" =>
144*6e425a9dSCharles.Forsyth			return nextarg(0) == a;
145*6e425a9dSCharles.Forsyth		"!=" =>
146*6e425a9dSCharles.Forsyth			return nextarg(0) != a;
147*6e425a9dSCharles.Forsyth		"-older" =>
148*6e425a9dSCharles.Forsyth			return isolder(nextarg(0), a);
149*6e425a9dSCharles.Forsyth		"-ot" =>
150*6e425a9dSCharles.Forsyth			return isolderthan(a, nextarg(0));
151*6e425a9dSCharles.Forsyth		"-nt" =>
152*6e425a9dSCharles.Forsyth			return isnewerthan(a, nextarg(0));
153*6e425a9dSCharles.Forsyth		}
15437da2899SCharles.Forsyth
15537da2899SCharles.Forsyth		if(!isint(a))
15637da2899SCharles.Forsyth			return a != nil;
15737da2899SCharles.Forsyth
158*6e425a9dSCharles.Forsyth		int1 := int a;
159*6e425a9dSCharles.Forsyth		(ok, int2) := nextintarg();
16037da2899SCharles.Forsyth		if(ok){
161*6e425a9dSCharles.Forsyth			case p2 {
162*6e425a9dSCharles.Forsyth			"-eq" =>
16337da2899SCharles.Forsyth				return int1 == int2;
164*6e425a9dSCharles.Forsyth			"-ne" =>
16537da2899SCharles.Forsyth				return int1 != int2;
166*6e425a9dSCharles.Forsyth			"-gt" =>
16737da2899SCharles.Forsyth				return int1 > int2;
168*6e425a9dSCharles.Forsyth			"-lt" =>
16937da2899SCharles.Forsyth				return int1 < int2;
170*6e425a9dSCharles.Forsyth			"-ge" =>
17137da2899SCharles.Forsyth				return int1 >= int2;
172*6e425a9dSCharles.Forsyth			"-le" =>
17337da2899SCharles.Forsyth				return int1 <= int2;
17437da2899SCharles.Forsyth			}
175*6e425a9dSCharles.Forsyth		}
17637da2899SCharles.Forsyth
17737da2899SCharles.Forsyth		synbad("unknown operator " + p2);
178*6e425a9dSCharles.Forsyth		return 0;
179*6e425a9dSCharles.Forsyth	}
18037da2899SCharles.Forsyth}
18137da2899SCharles.Forsyth
18237da2899SCharles.Forsythsynbad(s: string)
18337da2899SCharles.Forsyth{
18437da2899SCharles.Forsyth	sys->fprint(stderr, "test: bad syntax: %s\n", s);
185*6e425a9dSCharles.Forsyth	raise "fail:bad syntax";
18637da2899SCharles.Forsyth}
18737da2899SCharles.Forsyth
18837da2899SCharles.Forsythisint(s: string): int
18937da2899SCharles.Forsyth{
19037da2899SCharles.Forsyth	if(s == nil)
19137da2899SCharles.Forsyth		return 0;
19237da2899SCharles.Forsyth	for(i := 0; i < len s; i++)
19337da2899SCharles.Forsyth		if(s[i] < '0' || s[i] > '9')
19437da2899SCharles.Forsyth			return 0;
19537da2899SCharles.Forsyth	return 1;
19637da2899SCharles.Forsyth}
19737da2899SCharles.Forsyth
198*6e425a9dSCharles.Forsythexists(f: string): int
19937da2899SCharles.Forsyth{
200*6e425a9dSCharles.Forsyth	return sys->stat(f).t0 >= 0;
20137da2899SCharles.Forsyth}
20237da2899SCharles.Forsyth
203*6e425a9dSCharles.Forsythhasmode(f: string, m: int): int
20437da2899SCharles.Forsyth{
205*6e425a9dSCharles.Forsyth	(ok, d) := sys->stat(f);
20637da2899SCharles.Forsyth	if(ok < 0)
20737da2899SCharles.Forsyth		return 0;
208*6e425a9dSCharles.Forsyth	return (d.mode & m) != 0;
209*6e425a9dSCharles.Forsyth}
210*6e425a9dSCharles.Forsyth
211*6e425a9dSCharles.Forsythiscons(fno: int): int
212*6e425a9dSCharles.Forsyth{
213*6e425a9dSCharles.Forsyth	fd := sys->fildes(fno);
214*6e425a9dSCharles.Forsyth	if(fd == nil)
215*6e425a9dSCharles.Forsyth		return 0;
216*6e425a9dSCharles.Forsyth	s := sys->fd2path(fd);
217*6e425a9dSCharles.Forsyth	n := len "/dev/cons";
218*6e425a9dSCharles.Forsyth	return s == "#c/cons" || len s >= n && s[len s-n:] == "/dev/cons";
219*6e425a9dSCharles.Forsyth}
220*6e425a9dSCharles.Forsyth
221*6e425a9dSCharles.Forsythisolder(t: string, f: string): int
222*6e425a9dSCharles.Forsyth{
223*6e425a9dSCharles.Forsyth	(ok, dir) := sys->stat(f);
22437da2899SCharles.Forsyth	if(ok < 0)
22537da2899SCharles.Forsyth		return 0;
22637da2899SCharles.Forsyth
227*6e425a9dSCharles.Forsyth	n := 0;
228*6e425a9dSCharles.Forsyth	for(i := 0; i < len t;){
229*6e425a9dSCharles.Forsyth		for(j := i; j < len t; j++)
230*6e425a9dSCharles.Forsyth			if(!(t[j] >= '0' && t[j] <= '9'))
231*6e425a9dSCharles.Forsyth				break;
232*6e425a9dSCharles.Forsyth		if(i == j)
233*6e425a9dSCharles.Forsyth			synbad("bad time syntax, "+t);
234*6e425a9dSCharles.Forsyth		m := int t[i:j];
235*6e425a9dSCharles.Forsyth		i = j;
236*6e425a9dSCharles.Forsyth		if(i == len t){
237*6e425a9dSCharles.Forsyth			n = m;
238*6e425a9dSCharles.Forsyth			break;
239*6e425a9dSCharles.Forsyth		}
240*6e425a9dSCharles.Forsyth		case t[i++] {
241*6e425a9dSCharles.Forsyth		'y' =>	n += m*12*30*24*3600;
242*6e425a9dSCharles.Forsyth		'M' =>	n += m*30*24*3600;
243*6e425a9dSCharles.Forsyth		'd' =>	n += m*24*3600;
244*6e425a9dSCharles.Forsyth		'h' =>	n += m*3600;
245*6e425a9dSCharles.Forsyth		'm' =>	n += m*60;
246*6e425a9dSCharles.Forsyth		's' =>		n += m;
247*6e425a9dSCharles.Forsyth		* =>		synbad("bad time syntax, "+t);
248*6e425a9dSCharles.Forsyth		}
249*6e425a9dSCharles.Forsyth	}
250*6e425a9dSCharles.Forsyth
251*6e425a9dSCharles.Forsyth	return dir.mtime+n < now();
252*6e425a9dSCharles.Forsyth}
253*6e425a9dSCharles.Forsyth
254*6e425a9dSCharles.Forsythisolderthan(a: string, b: string): int
255*6e425a9dSCharles.Forsyth{
256*6e425a9dSCharles.Forsyth	(aok, ad) := sys->stat(a);
257*6e425a9dSCharles.Forsyth	if(aok < 0)
258*6e425a9dSCharles.Forsyth		return 0;
259*6e425a9dSCharles.Forsyth	(bok, bd) := sys->stat(b);
260*6e425a9dSCharles.Forsyth	if(bok < 0)
261*6e425a9dSCharles.Forsyth		return 0;
262*6e425a9dSCharles.Forsyth	return ad.mtime < bd.mtime;
263*6e425a9dSCharles.Forsyth}
264*6e425a9dSCharles.Forsyth
265*6e425a9dSCharles.Forsythisnewerthan(a: string, b: string): int
266*6e425a9dSCharles.Forsyth{
267*6e425a9dSCharles.Forsyth	(aok, ad) := sys->stat(a);
268*6e425a9dSCharles.Forsyth	if(aok < 0)
269*6e425a9dSCharles.Forsyth		return 0;
270*6e425a9dSCharles.Forsyth	(bok, bd) := sys->stat(b);
271*6e425a9dSCharles.Forsyth	if(bok < 0)
272*6e425a9dSCharles.Forsyth		return 0;
273*6e425a9dSCharles.Forsyth	return ad.mtime > bd.mtime;
274*6e425a9dSCharles.Forsyth}
275*6e425a9dSCharles.Forsyth
276*6e425a9dSCharles.Forsythnow(): int
277*6e425a9dSCharles.Forsyth{
278*6e425a9dSCharles.Forsyth	if(daytime == nil){
279*6e425a9dSCharles.Forsyth		daytime = load Daytime Daytime->PATH;
280*6e425a9dSCharles.Forsyth		if(daytime == nil)
281*6e425a9dSCharles.Forsyth			synbad(sys->sprint("can't load %s: %r", Daytime->PATH));
282*6e425a9dSCharles.Forsyth	}
283*6e425a9dSCharles.Forsyth	return daytime->now();
28437da2899SCharles.Forsyth}
285