1implement Src; 2 3include "sys.m"; 4 sys: Sys; 5include "draw.m"; 6include "dis.m"; 7 dis: Dis; 8 9Src: module 10{ 11 init: fn(nil: ref Draw->Context, argv: list of string); 12}; 13 14init(nil: ref Draw->Context, argv: list of string) 15{ 16 sys = load Sys Sys->PATH; 17 dis = load Dis Dis->PATH; 18 19 if(dis != nil){ 20 dis->init(); 21 for(argv = tl argv; argv != nil; argv = tl argv){ 22 s := src(hd argv); 23 if(s == nil) 24 s = "?"; 25 sys->print("%s: %s\n", hd argv, s); 26 } 27 } 28} 29 30src(progname: string): string 31{ 32 disfile := 0; 33 if (len progname >= 4 && progname[len progname-4:] == ".dis") 34 disfile = 1; 35 pathlist: list of string; 36 if (absolute(progname)) 37 pathlist = list of {""}; 38 else 39 pathlist = list of {"/dis", "."}; 40 41 err := ""; 42 do { 43 path: string; 44 if (hd pathlist != "") 45 path = hd pathlist + "/" + progname; 46 else 47 path = progname; 48 49 npath := path; 50 if (!disfile) 51 npath += ".dis"; 52 src := dis->src(npath); 53 if(src != nil) 54 return src; 55 err = sys->sprint("%r"); 56 if (nonexistent(err)) { 57 # try and find it as a shell script 58 if (!disfile) { 59 (ok, info) := sys->stat(path); 60 if (ok == 0 && (info.mode & Sys->DMDIR) == 0 61 && (info.mode & 8r111) != 0) 62 return path; 63 else 64 err = sys->sprint("%r"); 65 } 66 } 67 pathlist = tl pathlist; 68 } while (pathlist != nil && nonexistent(err)); 69 return nil; 70} 71 72absolute(p: string): int 73{ 74 if (len p < 2) 75 return 0; 76 if (p[0] == '/' || p[0] == '#') 77 return 1; 78 if (len p < 3 || p[0] != '.') 79 return 0; 80 if (p[1] == '/') 81 return 1; 82 if (p[1] == '.' && p[2] == '/') 83 return 1; 84 return 0; 85} 86 87nonexistent(e: string): int 88{ 89 errs := array[] of {"does not exist", "directory entry not found"}; 90 for (i := 0; i < len errs; i++){ 91 j := len errs[i]; 92 if (j <= len e && e[len e-j:] == errs[i]) 93 return 1; 94 } 95 return 0; 96} 97