diff options
Diffstat (limited to 'appl/cmd/emuinit.b')
| -rw-r--r-- | appl/cmd/emuinit.b | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/appl/cmd/emuinit.b b/appl/cmd/emuinit.b new file mode 100644 index 00000000..56b11521 --- /dev/null +++ b/appl/cmd/emuinit.b @@ -0,0 +1,110 @@ +implement Emuinit; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "arg.m"; + arg: Arg; + +Emuinit: module +{ + init: fn(); +}; + +init() +{ + sys = load Sys Sys->PATH; + sys->bind("#e", "/env", sys->MREPL|sys->MCREATE); # if #e not configured, that's fine + args := getenv("emuargs"); + arg = load Arg Arg->PATH; + if (arg == nil) + sys->fprint(sys->fildes(2), "emuinit: cannot load %s: %r\n", Arg->PATH); + else{ + arg->init(args); + while((c := arg->opt()) != 0) + case c { + 'g' or 'c' or 'C' or 'm' or 'p' or 'f' or 'r' or 'd' => + arg->arg(); + } + args = arg->argv(); + } + mod: Command; + (mod, args) = loadmod(args); + mod->init(nil, args); +} + +loadmod(args: list of string): (Command, list of string) +{ + path := Command->PATH; + if(args != nil) + path = hd args; + else + args = "-l" :: nil; # add startup option + + # try loading the module directly. + mod: Command; + if (path != nil && path[0] == '/') + mod = load Command path; + else { + mod = load Command "/dis/"+path; + if (mod == nil) + mod = load Command "/"+path; + } + if(mod != nil) + return (mod, args); + + # if we can't load the module directly, try getting the shell to run it. + err := sys->sprint("%r"); + mod = load Command Command->PATH; + if(mod == nil){ + sys->fprint(sys->fildes(2), "emuinit: unable to load %s: %s\n", path, err); + raise "fail:error"; + } + return (mod, "sh" :: "-c" :: "$*" :: args); +} + +getenv(v: string): list of string +{ + fd := sys->open("#e/"+v, Sys->OREAD); + if (fd == nil) + return nil; + (ok, d) := sys->fstat(fd); + if(ok == -1) + return nil; + buf := array[int d.length] of byte; + n := sys->read(fd, buf, len buf); + if (n <= 0) + return nil; + return unquoted(string buf[0:n]); +} + +unquoted(s: string): list of string +{ + args: list of string; + word: string; + inquote := 0; + for(j := len s; j > 0;){ + c := s[j-1]; + if(c == ' ' || c == '\t' || c == '\n'){ + j--; + continue; + } + for(i := j-1; i >= 0 && ((c = s[i]) != ' ' && c != '\t' && c != '\n' || inquote); i--){ # collect word + if(c == '\''){ + word = s[i+1:j] + word; + j = i; + if(!inquote || i == 0 || s[i-1] != '\'') + inquote = !inquote; + else + i--; + } + } + args = (s[i+1:j]+word) :: args; + word = nil; + j = i; + } + # if quotes were unbalanced, balance them and try again. + if(inquote) + return unquoted(s + "'"); + return args; +} |
