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