aboutsummaryrefslogtreecommitdiff
path: root/appl/cmd/src.b
diff options
context:
space:
mode:
authorbhgv <bhgv.empire@gmail.com>2018-03-01 16:54:45 +0200
committerbhgv <bhgv.empire@gmail.com>2018-03-01 16:54:45 +0200
commitb786f20bbab5a59046aa78a2c6c2a11536497202 (patch)
tree0851ecdec889eb9b7ba3751cc04d4f0b474e4a9e /appl/cmd/src.b
inferno-os tree was separated from the inferno-os-android (separated from the Android driver)
Diffstat (limited to 'appl/cmd/src.b')
-rw-r--r--appl/cmd/src.b96
1 files changed, 96 insertions, 0 deletions
diff --git a/appl/cmd/src.b b/appl/cmd/src.b
new file mode 100644
index 0000000..2b44b75
--- /dev/null
+++ b/appl/cmd/src.b
@@ -0,0 +1,96 @@
+implement Src;
+
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "dis.m";
+ dis: Dis;
+
+Src: module
+{
+ init: fn(nil: ref Draw->Context, argv: list of string);
+};
+
+init(nil: ref Draw->Context, argv: list of string)
+{
+ sys = load Sys Sys->PATH;
+ dis = load Dis Dis->PATH;
+
+ if(dis != nil){
+ dis->init();
+ for(argv = tl argv; argv != nil; argv = tl argv){
+ s := src(hd argv);
+ if(s == nil)
+ s = "?";
+ sys->print("%s: %s\n", hd argv, s);
+ }
+ }
+}
+
+src(progname: string): string
+{
+ disfile := 0;
+ if (len progname >= 4 && progname[len progname-4:] == ".dis")
+ disfile = 1;
+ pathlist: list of string;
+ if (absolute(progname))
+ pathlist = list of {""};
+ else
+ pathlist = list of {"/dis", "."};
+
+ err := "";
+ do {
+ path: string;
+ if (hd pathlist != "")
+ path = hd pathlist + "/" + progname;
+ else
+ path = progname;
+
+ npath := path;
+ if (!disfile)
+ npath += ".dis";
+ src := dis->src(npath);
+ if(src != nil)
+ return src;
+ err = sys->sprint("%r");
+ if (nonexistent(err)) {
+ # try and find it as a shell script
+ if (!disfile) {
+ (ok, info) := sys->stat(path);
+ if (ok == 0 && (info.mode & Sys->DMDIR) == 0
+ && (info.mode & 8r111) != 0)
+ return path;
+ else
+ err = sys->sprint("%r");
+ }
+ }
+ pathlist = tl pathlist;
+ } while (pathlist != nil && nonexistent(err));
+ return nil;
+}
+
+absolute(p: string): int
+{
+ if (len p < 2)
+ return 0;
+ if (p[0] == '/' || p[0] == '#')
+ return 1;
+ if (len p < 3 || p[0] != '.')
+ return 0;
+ if (p[1] == '/')
+ return 1;
+ if (p[1] == '.' && p[2] == '/')
+ return 1;
+ return 0;
+}
+
+nonexistent(e: string): int
+{
+ errs := array[] of {"does not exist", "directory entry not found"};
+ for (i := 0; i < len errs; i++){
+ j := len errs[i];
+ if (j <= len e && e[len e-j:] == errs[i])
+ return 1;
+ }
+ return 0;
+}