1implement Fs; 2include "sys.m"; 3 sys: Sys; 4include "draw.m"; 5include "sh.m"; 6include "readdir.m"; 7include "fslib.m"; 8 fslib: Fslib; 9 Report, Value, type2s: import fslib; 10 Fschan, Fsdata, Entrychan, Entry, 11 Quit: import Fslib; 12 13# fs distribution: 14 15# {filter -d {not {match -r '\.(dis|sbl)$'}} {filter {path /module/fslib.m /module/bundle.m /module/unbundle.m /appl/cmd/fs.b /appl/cmd/fs /appl/lib/fslib.b} /}} 16 17Fs: module { 18 init: fn(nil: ref Draw->Context, argv: list of string); 19}; 20 21badmod(path: string) 22{ 23 sys->fprint(stderr(), "fs: cannot load %s: %r\n", path); 24 raise "fail:bad module"; 25} 26 27init(ctxt: ref Draw->Context, argv: list of string) 28{ 29 sys = load Sys Sys->PATH; 30 fslib = load Fslib Fslib->PATH; 31 if(fslib == nil) 32 badmod(Fslib->PATH); 33 fslib->init(); 34 argv = tl argv; 35 36 if(argv == nil) 37 usage(); 38 report := Report.new(); 39 s := hd argv; 40 if(tl argv == nil && s != nil && s[0] == '{' && s[len s - 1] == '}') 41 s = "void " + hd argv; 42 else { 43 s = "void {" + hd argv; 44 for(argv = tl argv; argv != nil; argv = tl argv){ 45 a := hd argv; 46 if(a == nil || a[0] != '{') # } 47 s += sys->sprint(" %q", a); 48 else 49 s += " " + hd argv; 50 } 51 s += "}"; 52 } 53 m := load Fsmodule "/dis/fs/eval.dis"; 54 if(m == nil) 55 badmod("/dis/fs/eval.dis"); 56 if(!fslib->typecompat("as", m->types())){ 57 sys->fprint(stderr(), "fs: eval module implements incompatible type (usage: %s)\n", 58 fslib->cmdusage("eval", m->types())); 59 raise "fail:bad eval module"; 60 } 61 m->init(); 62 v := m->run(ctxt, report, nil, ref Value.S(s) :: nil); 63 fail: string; 64 if(v == nil) 65 fail = "error"; 66 else{ 67 sync := v.v().i; 68 sync <-= 1; 69 } 70 report.enable(); 71 while((e := <-report.reportc) != nil) 72 sys->fprint(stderr(), "fs: %s\n", e); 73 if(fail != nil) 74 raise "fail:" +fail; 75} 76 77usage() 78{ 79 fd := stderr(); 80 sys->fprint(fd, "usage: fs expression\n"); 81 sys->fprint(fd, "verbs are:\n"); 82 if((readdir := load Readdir Readdir->PATH) == nil){ 83 sys->fprint(fd, "fs: cannot load %s: %r\n", Readdir->PATH); 84 }else{ 85 (a, nil) := readdir->init("/dis/fs", Readdir->NAME|Readdir->COMPACT); 86 for(i := 0; i < len a; i++){ 87 f := a[i].name; 88 if(len f < 4 || f[len f - 4:] != ".dis") 89 continue; 90 m := load Fsmodule "/dis/fs/" + f; 91 if(m == nil) 92 sys->fprint(fd, "\t(%s: cannot load: %r)\n", f[0:len f - 4]); 93 else 94 sys->fprint(fd, "\t%s\n", fslib->cmdusage(f[0:len f - 4], m->types())); 95 } 96 } 97 sys->fprint(fd, "automatic conversions:\n"); 98 sys->fprint(fd, "\tstring -> fs {walk string}\n"); 99 sys->fprint(fd, "\tfs -> entries {entries fs}\n"); 100 sys->fprint(fd, "\tstring -> gate {match string}\n"); 101 sys->fprint(fd, "\tentries -> void {print entries}\n"); 102 sys->fprint(fd, "\tcommand -> string {run command}\n"); 103 raise "fail:usage"; 104} 105 106stderr(): ref Sys->FD 107{ 108 return sys->fildes(2); 109} 110