summaryrefslogtreecommitdiff
path: root/appl
diff options
context:
space:
mode:
Diffstat (limited to 'appl')
-rw-r--r--appl/cmd/sh92.b1303
-rw-r--r--appl/cmd/sh9cmd.b2
-rw-r--r--appl/lib/sh9util.b1
3 files changed, 898 insertions, 408 deletions
diff --git a/appl/cmd/sh92.b b/appl/cmd/sh92.b
index 0c1ece7..55ce38a 100644
--- a/appl/cmd/sh92.b
+++ b/appl/cmd/sh92.b
@@ -5,22 +5,30 @@ include "draw.m";
include "sh9util.m";
include "sh9parser.m";
include "sh9cmd.m";
+include "bufio.m";
+include "env.m";
+include "hash.m";
+include "workdir.m";
Sh92: module
{
- init: fn(ctxt: ref Draw->Context, argv: list of string);
- zstmt_assign: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode;
- zstmt_cmd_call: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode;
- zempty: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode;
- zsqstr_to_expr: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode;
- zvar_sub_expr: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode;
- zexpr_expr_combiner: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode;
+ init: fn(ctxt: ref Draw->Context, argv: list of string);
+ zstmt_assign: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode;
+ zstmt_cmd_call: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode;
+ zempty: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode;
+ zsqstr_to_expr: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode;
+ zvar_sub_expr: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode;
+ zexpr_expr_combiner: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode;
+ zsimple_cond: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode;
};
sys: Sys;
sh9u: Sh9Util;
sh9p: Sh9Parser;
sh9cmd: Sh9Cmd;
+bufio: Bufio;
+env: Env;
+hash: Hash;
GrammarNode: import sh9p;
ModProc: import sh9p;
@@ -39,6 +47,11 @@ Async, Seq: import sh9u;
Command: import sh9u;
Pipeline: import sh9u;
+Iobuf: import bufio;
+
+HashTable: import hash;
+HashVal: import hash;
+
stdin: ref sys->FD;
stderr: ref sys->FD;
waitfd: ref sys->FD;
@@ -78,449 +91,925 @@ S_DONE: con "DONE";
waitfor(pid: int)
{
- if (pid <= 0)
- return;
- buf := array[sys->WAITLEN] of byte;
- status := "";
- for (;;) {
- n := sys->read(waitfd, buf, len buf);
- if (n < 0) {
- sys->fprint(stderr, "sh9: read wait: %r\n");
- return;
- }
- status = string buf[0:n];
- if (status[len status-1] != ':')
- sys->fprint(stderr, "%s\n", status);
- who := int status;
- if (who != 0) {
- if (who == pid) {
- return;
- }
- }
- }
+ if (pid <= 0)
+ return;
+ buf := array[sys->WAITLEN] of byte;
+ status := "";
+ for (;;) {
+ n := sys->read(waitfd, buf, len buf);
+ if (n < 0) {
+ sys->fprint(stderr, "sh9: read wait: %r\n");
+ return;
+ }
+ status = string buf[0:n];
+ if (status[len status-1] != ':')
+ sys->fprint(stderr, "%s\n", status);
+ who := int status;
+ if (who != 0) {
+ if (who == pid) {
+ return;
+ }
+ }
+ }
}
runpipeline(ctx: ref Draw->Context, pipeline: ref Pipeline)
{
- if (pipeline.term == Async)
- sys->pctl(sys->NEWPGRP, nil);
- pid := startpipeline(ctx, pipeline);
- if (pid < 0)
- return;
- if (pipeline.term == Seq)
- waitfor(pid);
+ if (pipeline.term == Async)
+ sys->pctl(sys->NEWPGRP, nil);
+ pid := startpipeline(ctx, pipeline);
+ if (pid < 0)
+ return;
+ if (pipeline.term == Seq)
+ waitfor(pid);
}
startpipeline(ctx: ref Draw->Context, pipeline: ref Pipeline): int
{
- pid := 0;
- cmds := pipeline.cmds;
- first := 1;
- inpipe, outpipe: ref Sys->FD;
- while (cmds != nil) {
- last := tl cmds == nil;
- cmd := hd cmds;
-
- infd: ref Sys->FD;
- if (!first)
- infd = inpipe;
- else if (cmd.inf != nil) {
- infd = sys->open(cmd.inf, Sys->OREAD);
- if (infd == nil) {
- sys->fprint(stderr, "sh9: can't open %s: %r\n", cmd.inf);
- return -1;
- }
- }
-
- outfd: ref Sys->FD;
- if (!last) {
- fds := array[2] of ref Sys->FD;
- if (sys->pipe(fds) < 0) {
- sys->fprint(stderr, "sh9: can't make pipe: %r\n");
- return -1;
- }
- outpipe = fds[0];
- outfd = fds[1];
- fds = nil;
- } else if (cmd.outf != nil) {
- if (cmd.append){
- outfd = sys->open(cmd.outf, Sys->OWRITE);
- if (outfd != nil)
- sys->seek(outfd, big 0, Sys->SEEKEND);
- }
- if (outfd == nil)
- outfd = sys->create(cmd.outf, Sys->OWRITE, 8r666);
- if (outfd == nil) {
- sys->fprint(stderr, "sh9: can't open %s: %r\n", cmd.outf);
- return -1;
- }
- }
-
- rpid := chan of int;
- ta:=cmd.args;
-
- la:= len cmd.args;
- #sys->print("mkprog args[%d]: ", la);
- for (z:=0; z<la; z++) {
- #sys->print("%s ", hd ta);
- ta = tl ta;
- }
- #sys->print("\n");
- spawn mkprog(ctx, cmd.args, infd, outfd, rpid);
- pid = <-rpid;
- infd = nil;
- outfd = nil;
-
- inpipe = outpipe;
- outpipe = nil;
-
- first = 0;
- cmds = tl cmds;
- }
- return pid;
+ pid := 0;
+ cmds := pipeline.cmds;
+ first := 1;
+ inpipe, outpipe: ref Sys->FD;
+ while (cmds != nil) {
+ last := tl cmds == nil;
+ cmd := hd cmds;
+
+ infd: ref Sys->FD;
+ if (!first)
+ infd = inpipe;
+ else if (cmd.inf != nil) {
+ infd = sys->open(cmd.inf, Sys->OREAD);
+ if (infd == nil) {
+ sys->fprint(stderr, "sh9: can't open %s: %r\n", cmd.inf);
+ return -1;
+ }
+ }
+
+ outfd: ref Sys->FD;
+ if (!last) {
+ fds := array[2] of ref Sys->FD;
+ if (sys->pipe(fds) < 0) {
+ sys->fprint(stderr, "sh9: can't make pipe: %r\n");
+ return -1;
+ }
+ outpipe = fds[0];
+ outfd = fds[1];
+ fds = nil;
+ } else if (cmd.outf != nil) {
+ if (cmd.append){
+ outfd = sys->open(cmd.outf, Sys->OWRITE);
+ if (outfd != nil)
+ sys->seek(outfd, big 0, Sys->SEEKEND);
+ }
+ if (outfd == nil)
+ outfd = sys->create(cmd.outf, Sys->OWRITE, 8r666);
+ if (outfd == nil) {
+ sys->fprint(stderr, "sh9: can't open %s: %r\n", cmd.outf);
+ return -1;
+ }
+ } else if (cmd.outfd != nil) {
+ outfd = cmd.outfd;
+ }
+
+ rpid := chan of int;
+ ta:=cmd.args;
+
+ la:= len cmd.args;
+ #sys->print("mkprog args[%d]: ", la);
+ for (z:=0; z<la; z++) {
+ #sys->print("%s ", hd ta);
+ ta = tl ta;
+ }
+ #sys->print("\n");
+ spawn mkprog(ctx, cmd.args, infd, outfd, rpid);
+ pid = <-rpid;
+ infd = nil;
+ outfd = nil;
+
+ inpipe = outpipe;
+ outpipe = nil;
+
+ first = 0;
+ cmds = tl cmds;
+ }
+ return pid;
}
mkprog(ctxt: ref Draw->Context, arg: list of string, infd, outfd: ref Sys->FD, waitpid: chan of int)
{
- fds := list of {0, 1, 2};
- if(infd != nil)
- fds = infd.fd :: fds;
- if(outfd != nil)
- fds = outfd.fd :: fds;
- pid := sys->pctl(sys->NEWFD, fds);
- console := sys->fildes(2);
-
- if(infd != nil){
- sys->dup(infd.fd, 0);
- infd = nil;
- }
- if(outfd != nil){
- sys->dup(outfd.fd, 1);
- outfd = nil;
- }
-
- waitpid <-= pid;
-
- if(pid < 0 || arg == nil)
- return;
-
- {
- exec(ctxt, arg, console);
- }exception{
- "fail:*" =>
- #sys->fprint(console, "%s:%s\n", hd arg, e.name[5:]);
- exit;
- "write on closed pipe" =>
- #sys->fprint(console, "%s: %s\n", hd arg, e.name);
- exit;
- }
+ fds := list of {0, 1, 2};
+ if(infd != nil)
+ fds = infd.fd :: fds;
+ if(outfd != nil)
+ fds = outfd.fd :: fds;
+ pid := sys->pctl(sys->NEWFD, fds);
+ console := sys->fildes(2);
+
+ if(infd != nil){
+ sys->dup(infd.fd, 0);
+ infd = nil;
+ }
+ if(outfd != nil){
+ sys->dup(outfd.fd, 1);
+ outfd = nil;
+ }
+
+ waitpid <-= pid;
+
+ if(pid < 0 || arg == nil) {
+ sys->print("no args\n");
+ return;
+ }
+
+ sys->print("exec: ");
+ al:= len arg;
+ a:=arg;
+ for (i:=0; i<al; i++) {
+ ar:= hd a;
+ sys->print("\"%s\" ", ar);
+ a = tl a;
+ }
+ sys->print("\n");
+ {
+ exec(ctxt, arg, console);
+ }exception{
+ "fail:*" =>
+ #sys->fprint(console, "%s:%s\n", hd arg, e.name[5:]);
+ exit;
+ "write on closed pipe" =>
+ #sys->fprint(console, "%s: %s\n", hd arg, e.name);
+ exit;
+ }
}
exec(ctxt: ref Draw->Context, args: list of string, console: ref Sys->FD)
{
- if (args == nil)
- return;
- cmd := hd args;
- file := cmd;
-
- if (len file<4 || file[len file-4:]!=".dis")
- file += ".dis";
-
- cm : Sh9Cmd;
- cm = load Sh9Cmd file;
- if (cm == nil) {
- err := sys->sprint("%r");
- if (err != "permission denied" && err != "access permission denied" && file[0]!='/' && file[0:2]!="./") {
- cm = load Sh9Cmd "/dis/"+file;
- if (cm == nil) {
- err = sys->sprint("%r");
- }
- }
- if (cm == nil) {
- sys->fprint(console, "%s: %s\n", cmd, err);
- return;
- }
- }
-
- cm->init(ctxt, args);
+ if (args == nil)
+ return;
+ cmd := hd args;
+ file := cmd;
+
+ if (len file<4 || file[len file-4:]!=".dis")
+ file += ".dis";
+
+ cm : Sh9Cmd;
+ cm = load Sh9Cmd file;
+ if (cm == nil) {
+ err := sys->sprint("%r");
+ if (err != "permission denied" && err != "access permission denied" && file[0]!='/' && file[0:2]!="./") {
+ cm = load Sh9Cmd "/dis/"+file;
+ if (cm == nil) {
+ err = sys->sprint("%r");
+ }
+ }
+ if (cm == nil) {
+ sys->fprint(console, "%s: %s\n", cmd, err);
+ return;
+ }
+ }
+
+ cm->init(ctxt, args);
}
check_keywords(t: ref TokNode): ref TokNode {
- case (t.tok) {
- "if" => t.typ = S_IF;
- "then" => t.typ = S_THEN;
- "fi" => t.typ = S_FI;
- "elif" => t.typ = S_ELIF;
- "else" => t.typ = S_ELSE;
- "while" => t.typ = S_WHILE;
- "do" => t.typ = S_DO;
- "done" => t.typ = S_DONE;
- }
- return t;
+ case (t.tok) {
+ "if" => t.typ = S_IF;
+ "then" => t.typ = S_THEN;
+ "fi" => t.typ = S_FI;
+ "elif" => t.typ = S_ELIF;
+ "else" => t.typ = S_ELSE;
+ "while" => t.typ = S_WHILE;
+ "do" => t.typ = S_DO;
+ "done" => t.typ = S_DONE;
+ }
+ return t;
}
tokenize(line: string, line_n: int): array of ref TokNode {
- toks : list of ref TokNode;
- last_tok:= ref TokNode;
- last_tok.start = -1;
- last_tok.line = -1;
- last_tok.tok = "";
- last_tok.typ = S_UNKNOWN;
- k:=0;
-
- for (i := 0; i < len line; i++) {
- if (last_tok.typ == S_DQSTR) {
- case (line[i:i+1]) {
- "\"" => {
- l := len last_tok.tok;
- if ((last_tok.tok[l-1:] != "\\") || ((last_tok.tok[l-1:] == "\\") && (last_tok.tok[l-2:l-1] == "\\"))) {
- # end of str
- last_tok.tok = last_tok.tok + line[i:i+1];
- last_tok = check_keywords(last_tok);
- (last_tok, toks) = set_last_tok(last_tok, toks);
- } else {
- # escaped dqte, just continue
- last_tok.tok = last_tok.tok + line[i:i+1];
- }
- };
- * => {
- last_tok.tok = last_tok.tok + line[i:i+1];
- }
- }
- } else if (last_tok.typ == S_SQSTR) {
- case (line[i:i+1]) {
- "'" => {
- l := len last_tok.tok;
- if ((last_tok.tok[l-1:] != "\\") || ((last_tok.tok[l-1:] == "\\") && (last_tok.tok[l-2:l-1] == "\\"))) {
- # end of str
- last_tok.tok = last_tok.tok + line[i:i+1];
- last_tok = check_keywords(last_tok);
- (last_tok, toks) = set_last_tok(last_tok, toks);
- } else {
- # escaped sqte, just continue
- last_tok.tok = last_tok.tok + line[i:i+1];
- }
- };
- * => {
- last_tok.tok = last_tok.tok + line[i:i+1];
- }
- }
- } else {
- case (line[i:i+1]) {
- " " or "\t" => {
- last_tok = check_keywords(last_tok);
- (last_tok, toks) = set_last_tok(last_tok, toks);
- };
- "=" => {
- last_tok = check_keywords(last_tok);
- (last_tok, toks) = set_last_tok(last_tok, toks);
- toks = mk_tok(i, line_n, "=", S_EQ) :: toks;
- };
- ";" => {
- last_tok = check_keywords(last_tok);
- (last_tok, toks) = set_last_tok(last_tok, toks);
- toks = mk_tok(i, line_n, ";", S_SEMIC) :: toks;
- };
- ":" => {
- last_tok = check_keywords(last_tok);
- (last_tok, toks) = set_last_tok(last_tok, toks);
- toks = mk_tok(i, line_n, ":", S_COLON) :: toks;
- };
- "(" => {
- last_tok = check_keywords(last_tok);
- (last_tok, toks) = set_last_tok(last_tok, toks);
- toks = mk_tok(i, line_n, "(", S_LPAR) :: toks;
- };
- ")" => {
- last_tok = check_keywords(last_tok);
- (last_tok, toks) = set_last_tok(last_tok, toks);
- toks = mk_tok(i, line_n, ")", S_RPAR) :: toks;
- };
- "{" => {
- last_tok = check_keywords(last_tok);
- (last_tok, toks) = set_last_tok(last_tok, toks);
- toks = mk_tok(i, line_n, "{", S_LCURLY) :: toks;
- };
- "}" => {
- last_tok = check_keywords(last_tok);
- (last_tok, toks) = set_last_tok(last_tok, toks);
- toks = mk_tok(i, line_n, "}", S_RCURLY) :: toks;
- };
- "$" => {
- last_tok = check_keywords(last_tok);
- (last_tok, toks) = set_last_tok(last_tok, toks);
- toks = mk_tok(i, line_n, "$", S_DOLL) :: toks;
- };
- "\"" => {
- last_tok = check_keywords(last_tok);
- (last_tok, toks) = set_last_tok(last_tok, toks);
- last_tok.start = i;
- last_tok.line = line_n;
- last_tok.typ = S_DQSTR;
- last_tok.tok = last_tok.tok + line[i:i+1];
- };
- "'" => {
- last_tok = check_keywords(last_tok);
- (last_tok, toks) = set_last_tok(last_tok, toks);
- last_tok.start = i;
- last_tok.line = line_n;
- last_tok.typ = S_SQSTR;
- last_tok.tok = last_tok.tok + line[i:i+1];
- };
- * => {
- if (last_tok.start == -1) {
- last_tok.start = i;
- last_tok.line = line_n;
- last_tok.typ = S_ID;
- }
- last_tok.tok = last_tok.tok + line[i:i+1];
- };
- }
- }
- }
- last_tok = check_keywords(last_tok);
- (last_tok, toks) = set_last_tok(last_tok, toks);
- toks = mk_tok(i, line_n, "", S_EOL) :: toks;
- toks = reverse_list(toks);
- return to_array(toks);
+ toks : list of ref TokNode;
+ last_tok:= ref TokNode;
+ last_tok.start = -1;
+ last_tok.line = -1;
+ last_tok.tok = nil;
+ last_tok.typ = S_UNKNOWN;
+
+ for (i := 0; i < len line; i++) {
+ if (last_tok.typ == S_DQSTR) {
+ case (line[i:i+1]) {
+ "\"" => {
+ l := len last_tok.tok;
+ if ((last_tok.tok[l-1:] != "\\") || ((last_tok.tok[l-1:] == "\\") && (last_tok.tok[l-2:l-1] == "\\"))) {
+ # end of str
+ last_tok.tok = last_tok.tok + line[i:i+1];
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ } else {
+ # escaped dqte, just continue
+ last_tok.tok = last_tok.tok + line[i:i+1];
+ }
+ };
+ * => {
+ last_tok.tok = last_tok.tok + line[i:i+1];
+ }
+ }
+ } else if (last_tok.typ == S_SQSTR) {
+ case (line[i:i+1]) {
+ "'" => {
+ l := len last_tok.tok;
+ if ((last_tok.tok[l-1:] != "\\") || ((last_tok.tok[l-1:] == "\\") && (last_tok.tok[l-2:l-1] == "\\"))) {
+ # end of str
+ last_tok.tok = last_tok.tok + line[i:i+1];
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ } else {
+ # escaped sqte, just continue
+ last_tok.tok = last_tok.tok + line[i:i+1];
+ }
+ };
+ * => {
+ last_tok.tok = last_tok.tok + line[i:i+1];
+ }
+ }
+ } else {
+ case (line[i:i+1]) {
+ " " or "\t" => {
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ };
+ "\r" => {
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ };
+ "\n" => {
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ toks = mk_tok(i, line_n, nil, S_EOL) :: toks;
+ };
+ "=" => {
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ toks = mk_tok(i, line_n, "=", S_EQ) :: toks;
+ };
+ ";" => {
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ toks = mk_tok(i, line_n, ";", S_SEMIC) :: toks;
+ };
+ ":" => {
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ toks = mk_tok(i, line_n, ":", S_COLON) :: toks;
+ };
+ "(" => {
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ toks = mk_tok(i, line_n, "(", S_LPAR) :: toks;
+ };
+ ")" => {
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ toks = mk_tok(i, line_n, ")", S_RPAR) :: toks;
+ };
+ "{" => {
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ toks = mk_tok(i, line_n, "{", S_LCURLY) :: toks;
+ };
+ "}" => {
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ toks = mk_tok(i, line_n, "}", S_RCURLY) :: toks;
+ };
+ "$" => {
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ toks = mk_tok(i, line_n, "$", S_DOLL) :: toks;
+ };
+ "\"" => {
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ last_tok.start = i;
+ last_tok.line = line_n;
+ last_tok.typ = S_DQSTR;
+ last_tok.tok = last_tok.tok + line[i:i+1];
+ };
+ "'" => {
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ last_tok.start = i;
+ last_tok.line = line_n;
+ last_tok.typ = S_SQSTR;
+ last_tok.tok = last_tok.tok + line[i:i+1];
+ };
+ * => {
+ if (last_tok.start == -1) {
+ last_tok.start = i;
+ last_tok.line = line_n;
+ last_tok.typ = S_ID;
+ }
+ last_tok.tok = last_tok.tok + line[i:i+1];
+ };
+ }
+ }
+ }
+ last_tok = check_keywords(last_tok);
+ (last_tok, toks) = set_last_tok(last_tok, toks);
+ toks = mk_tok(i, line_n, nil, S_EOL) :: toks;
+ toks = reverse_list(toks);
+ return to_array(toks);
}
zstmt_assign(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode {
- sys->print("ASSIGN STMT\n");
- m:= c.get_current_module();
- v:= ref ModVar;
- v.name= toks[0].tok;
- v.val= toks[2].tok;
- m.set_var(v);
- return array[0] of ref TokNode;
+ sys->print("ASSIGN STMT\n");
+ m:= c.get_current_module();
+ v:= ref ModVar;
+ v.name= toks[0].tok;
+ v.val= toks[2].tok;
+ m.set_var(v);
+ return array[0] of ref TokNode;
}
unquote(s: string): string {
- if (s == nil) {
- return nil;
- }
- ls := len s;
- if (len s > 2) {
- if ((s[:1] == "\"") && (s[ls-1:] == "\"")) {
- return s[1:ls-1];
- } else if ((s[:1] == "\'") && (s[ls-1:] == "\'")) {
- return s[1:ls-1];
- }
- }
- return s;
+ if (s == nil) {
+ return nil;
+ }
+ ls := len s;
+ if (len s > 2) {
+ if ((s[:1] == "\"") && (s[ls-1:] == "\"")) {
+ return s[1:ls-1];
+ } else if ((s[:1] == "\'") && (s[ls-1:] == "\'")) {
+ return s[1:ls-1];
+ }
+ }
+ return s;
}
-zstmt_cmd_call(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode {
- sys->print("CMD CALL\n");
- args:= tokenize(toks[1].tok, 0);
- pl:= ref Pipeline;
- cmd:= ref Command;
- cmd.args = unquote(toks[0].tok) :: cmd.args;
- # sys->print("args: ");
- # sys->print("%s ", toks[0].tok);
- la:= len args;
- for (i:=0; i<la; i++) {
- cmd.args = unquote(args[i].tok) :: cmd.args;
- #sys->print("%s ", args[i].tok);
- }
- cmd.args = reverse_list(cmd.args);
- pl.cmds = cmd :: pl.cmds;
- pl.term = Seq;
- #sys->print("Call runpipeline\n");
- ret := runpipeline(c.ctxt, pl);
+zstmt_cmd_eol_call(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode {
+ sys->print("CMD EOL CALL\n");
+ pl:= ref Pipeline;
+ cmd:= ref Command;
+ cmd.args = unquote(toks[0].tok) :: cmd.args;
+ pl.cmds = cmd :: pl.cmds;
+ pl.term = Seq;
+ ret := runpipeline(c.ctxt, pl);
+ # TODO: check/store ret
+
+ return array[0] of ref TokNode;
+}
- return array[0] of ref TokNode;
+zstmt_cmd_call(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode {
+ sys->print("CMD CALL\n");
+ print_toks(toks);
+ sys->print("tokenize \"%s\"\n", toks[1].tok);
+ args:= tokenize(toks[1].tok, 0);
+ print_toks(args);
+ pl:= ref Pipeline;
+ cmd:= ref Command;
+ cmd.args = unquote(toks[0].tok) :: cmd.args;
+ sys->print("args: ");
+ sys->print("\"%s\" ", toks[0].tok);
+ la:= len args;
+ for (i:=0; i<la; i++) {
+ if (args[i].typ == S_EOL) {
+ continue;
+ }
+ cmd.args = unquote(args[i].tok) :: cmd.args;
+ sys->print("\"%s\" ", args[i].tok);
+ }
+ cmd.args = reverse_list(cmd.args);
+ pl.cmds = cmd :: pl.cmds;
+ pl.term = Seq;
+ #sys->print("Call runpipeline\n");
+ ret := runpipeline(c.ctxt, pl);
+ # TODO: check/store ret
+
+ return array[0] of ref TokNode;
}
-zempty(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode {
- return array[0] of ref TokNode;
+zempty(nil: ref ParserCtx, nil: array of ref TokNode): array of ref TokNode {
+ return array[0] of ref TokNode;
}
-zsqstr_to_expr(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode {
- tn:= mk_tok(toks[0].start, toks[0].line, toks[0].tok, S_EXPR);
- return array[1] of {tn};
+zsqstr_to_expr(nil: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode {
+ tn:= mk_tok(toks[0].start, toks[0].line, toks[0].tok, S_EXPR);
+ return array[1] of {tn};
}
zvar_sub_expr(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode {
- sys->print("VAR SUB\n");
- varname:=toks[1].tok;
- if (varname == "{") {
- varname = toks[2].tok;
- }
- v:= c.find_var_in_current_module(varname);
- if (v == nil) {
- sys->print("Var %s is nil\nAll vars:\n", varname);
- c.print_all_vars();
- }
- sys->print("VAR %s SUB: %s\n", v.name, v.val);
- tn:= mk_tok(toks[0].start, toks[0].line, v.val, S_EXPR);
- return array[1] of {tn};
-}
-
-zexpr_expr_combiner(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode {
- comb_tok:= toks[0].tok + " " + toks[1].tok;
- tn:= mk_tok(toks[0].start, toks[0].line, comb_tok, S_EXPR);
- return array[1] of {tn};
+ sys->print("VAR SUB\n");
+ varname:=toks[1].tok;
+ if (varname == "{") {
+ varname = toks[2].tok;
+ }
+ v:= c.find_var_in_current_module(varname);
+ if (v == nil) {
+ sys->print("Var %s is nil\nAll vars:\n", varname);
+ c.print_all_vars();
+ }
+ sys->print("VAR %s SUB: %s\n", v.name, v.val);
+ tn:= mk_tok(toks[0].start, toks[0].line, v.val, S_EXPR);
+ return array[1] of {tn};
+}
+
+zcmd_sub_call_expr(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode {
+ sys->print("CMD SUB\n");
+ cmdname := toks[2].tok;
+ args:= tokenize(toks[1].tok, 0);
+ pl:= ref Pipeline;
+ cmd:= ref Command;
+ cmd.args = cmdname :: cmd.args;
+ # sys->print("args: ");
+ # sys->print("%s ", toks[0].tok);
+ la:= len args;
+ for (i:=0; i<la; i++) {
+ cmd.args = unquote(args[i].tok) :: cmd.args;
+ #sys->print("%s ", args[i].tok);
+ }
+ cmd.args = reverse_list(cmd.args);
+
+ fds := array[2] of ref Sys->FD;
+ if(sys->pipe(fds) < 0){
+ sys->fprint(stderr, "sh92: can't make pipe: %r\n");
+ return array[0] of ref TokNode;
+ }
+ outpipe := fds[0];
+ outfd := fds[1];
+ fds = nil;
+
+ cmd.outfd = outfd;
+ pl.cmds = cmd :: pl.cmds;
+ pl.term = Seq;
+ #sys->print("Call runpipeline\n");
+
+ ret := runpipeline(c.ctxt, pl);
+
+ output := "";
+ buf := array[1024] of byte;
+ for (;;) {
+ n := sys->read(outpipe, buf, len buf);
+ if (n < 0) {
+ break;
+ }
+ chunk := string buf[0:n];
+ output = output + chunk;
+ }
+ tn:= mk_tok(toks[0].start, toks[0].line, output, S_EXPR);
+ return array[1] of {tn};
+}
+
+zexpr_expr_combiner(nil: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode {
+ comb_tok:= toks[0].tok + " " + toks[1].tok;
+ tn:= mk_tok(toks[0].start, toks[0].line, comb_tok, S_EXPR);
+ return array[1] of {tn};
+}
+
+zid_id_combiner(nil: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode {
+ t0:= mk_tok(toks[0].start, toks[0].line, toks[0].tok, S_ID);
+ t1:= mk_tok(toks[0].start, toks[0].line, toks[1].tok, S_EXPR);
+ return array[] of {t0, t1};
+}
+
+zexpr_id_combiner(nil: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode {
+ t0:= mk_tok(toks[0].start, toks[0].line, toks[0].tok, S_EXPR);
+ t1:= mk_tok(toks[0].start, toks[0].line, toks[1].tok, S_EXPR);
+ return array[] of {t0, t1};
+}
+
+zsimple_cond(nil: ref ParserCtx, nil: array of ref TokNode): array of ref TokNode {
+ return array[0] of ref TokNode;
}
mk_grammar(ctx: ref ParserCtx): array of ref GrammarNode
{
- semic_eol_g : GrammarNode = (array [] of {S_SEMIC, S_EOL}, S_SEMIC, zempty, ctx);
- assign_g_semic : GrammarNode = (array [] of {S_ID, S_EQ, S_EXPR, S_SEMIC}, S_NONE, zstmt_assign, ctx);
- sqstr_expr_g: GrammarNode = (array [] of {S_SQSTR}, nil, zsqstr_to_expr, ctx);
- str_expr_g: GrammarNode = (array [] of {S_STR}, S_EXPR, zempty, ctx);
- expr_combinator_g: GrammarNode = (array [] of {S_EXPR, S_EXPR}, nil, zexpr_expr_combiner, ctx);
- cmd_call_semic_g: GrammarNode = (array [] of {S_ID, S_EXPR, S_SEMIC}, nil, zstmt_cmd_call, ctx);
-
- var_sub_g: GrammarNode = (array [] of {S_DOLL, S_ID}, nil, zvar_sub_expr, ctx);
- var_sub_curl_g: GrammarNode = (array [] of {S_DOLL, S_LCURLY, S_ID, S_RCURLY}, nil, zvar_sub_expr, ctx);
- dqstr_expr_g: GrammarNode = (array [] of {S_DQTE, S_EXPR, S_DQTE}, nil, zempty, ctx);
-
- # simple_cond_g: GrammarNode = (array [] of {S_IF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_FI})
- # ifel_cond_g: GrammarNode = (array [] of {S_IF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_ELSE, S_STMT, S_FI})
- # elifelifel_cond_g: GrammarNode = (array [] of {S_ELIF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_ELIF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_ELSE, S_STMT, S_FI})
- # elifeliffi_cond_g: GrammarNode = (array [] of {S_ELIF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_ELIF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_FI})
-
- #grammar:= array[0] of ref GrammarNode;
- grammar: array of ref GrammarNode;
- grammar = array [] of {
- ref semic_eol_g,
- ref assign_g_semic,
- ref assign_g_eol,
- ref sqstr_expr_g,
- ref str_expr_g,
- ref cmd_call_semic_g,
- ref cmd_call_eol_g,
- ref expr_combinator_g,
- ref var_sub_g,
- ref var_sub_curl_g,
- };
- return grammar;
+ semic_eol_g : GrammarNode = (array [] of {S_SEMIC, S_EOL}, S_SEMIC, zempty, ctx);
+ assign_g_semic : GrammarNode = (array [] of {S_ID, S_EQ, S_EXPR, S_SEMIC}, S_NONE, zstmt_assign, ctx);
+ sqstr_expr_g: GrammarNode = (array [] of {S_SQSTR}, nil, zsqstr_to_expr, ctx);
+ str_expr_g: GrammarNode = (array [] of {S_STR}, S_EXPR, zempty, ctx);
+ expr_combinator_g: GrammarNode = (array [] of {S_EXPR, S_EXPR}, nil, zexpr_expr_combiner, ctx);
+ id_id_combinator_g: GrammarNode = (array [] of {S_ID, S_ID}, nil, zid_id_combiner, ctx);
+ expr_id_combinator_g: GrammarNode = (array [] of {S_EXPR, S_ID}, nil, zexpr_id_combiner, ctx);
+ cmd_call_semic_g: GrammarNode = (array [] of {S_ID, S_EXPR, S_SEMIC}, nil, zstmt_cmd_call, ctx);
+ cmd_call_eol_g: GrammarNode = (array [] of {S_ID, S_EOL}, nil, zstmt_cmd_eol_call, ctx);
+ cmd_expr_call_eol_g: GrammarNode = (array [] of {S_ID, S_EXPR, S_EOL}, nil, zstmt_cmd_call, ctx);
+
+ var_sub_g: GrammarNode = (array [] of {S_DOLL, S_ID}, nil, zvar_sub_expr, ctx);
+ var_sub_curl_g: GrammarNode = (array [] of {S_DOLL, S_LCURLY, S_ID, S_RCURLY}, nil, zvar_sub_expr, ctx);
+ cmd_sub_call_g: GrammarNode = (array [] of {S_DOLL, S_LPAR, S_ID, S_EXPR, S_RPAR}, nil, zcmd_sub_call_expr, ctx);
+ dqstr_expr_g: GrammarNode = (array [] of {S_DQTE, S_EXPR, S_DQTE}, nil, zempty, ctx);
+
+ simple_cond_g: GrammarNode = (array [] of {S_IF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_FI}, nil, zsimple_cond, ctx);
+ # ifel_cond_g: GrammarNode = (array [] of {S_IF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_ELSE, S_STMT, S_FI})
+ # elifelifel_cond_g: GrammarNode = (array [] of {S_ELIF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_ELIF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_ELSE, S_STMT, S_FI})
+ # elifeliffi_cond_g: GrammarNode = (array [] of {S_ELIF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_ELIF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_FI})
+
+ #grammar:= array[0] of ref GrammarNode;
+ grammar: array of ref GrammarNode;
+ grammar = array [] of {
+ ref semic_eol_g,
+ ref assign_g_semic,
+ ref sqstr_expr_g,
+ ref str_expr_g,
+ ref cmd_call_semic_g,
+ ref cmd_call_eol_g,
+ ref cmd_expr_call_eol_g,
+ ref expr_combinator_g,
+ ref id_id_combinator_g,
+ ref expr_id_combinator_g,
+ ref var_sub_g,
+ ref var_sub_curl_g,
+ ref simple_cond_g,
+ };
+ return grammar;
+}
+
+getusername(): string
+{
+ fd := sys->open("/dev/user", sys->OREAD);
+ if(fd == nil)
+ return "/";
+ buf := array[128] of byte;
+ n := sys->read(fd, buf, len buf);
+ if(n < 0)
+ return "?";
+ return string buf[0:n];
+}
+
+getcwd(): string
+{
+ gwd := load Workdir Workdir->PATH;
+ if (gwd == nil) {
+ sys->fprint(stderr, "pwd: cannot load %s: %r\n", Workdir->PATH);
+ raise "fail:bad module";
+ }
+
+ wd := gwd->init();
+ if(wd == nil) {
+ sys->fprint(stderr, "pwd: %r\n");
+ raise "fail:error";
+ }
+ return wd;
+}
+
+sysname(): string
+{
+ fd := sys->open("#c/sysname", sys->OREAD);
+ if(fd == nil)
+ return "anon";
+ buf := array[128] of byte;
+ n := sys->read(fd, buf, len buf);
+ if(n < 0)
+ return "anon";
+ return string buf[0:n];
+}
+
+gethome(): string
+{
+ fd := sys->open("/dev/user", sys->OREAD);
+ if(fd == nil)
+ return "/";
+ buf := array[128] of byte;
+ n := sys->read(fd, buf, len buf);
+ if(n < 0)
+ return "/";
+ return "/usr/" + string buf[0:n];
+}
+
+script(nil: ref Draw->Context, src: string, grammar: array of ref GrammarNode)
+{
+ bufio = load Bufio Bufio->PATH;
+ if(bufio == nil){
+ sys->fprint(stderr, "sh9: load bufio: %r\n");
+ return;
+ }
+
+ f := bufio->open(src, Bufio->OREAD);
+ if(f == nil){
+ sys->fprint(stderr, "sh9: open %s: %r\n", src);
+ return;
+ }
+ for(;;){
+ s := f.gets('\n');
+ if(s == nil)
+ break;
+ toks := tokenize(s, 0);
+ if(toks != nil) {
+ parse_toks(toks, grammar, 0);
+ }
+ }
+}
+
+escript(ctxt: ref Draw->Context, file: string, grammar: array of ref GrammarNode)
+{
+ fd := sys->open(file, Sys->OREAD);
+ if (fd != nil)
+ script(ctxt, file, grammar);
+}
+
+# PROFILE: con "/lib/profile";
+PROFILE: con "/lib/infernoinit";
+
+startup(ctxt: ref Draw->Context, grammar: array of ref GrammarNode)
+{
+ if (env == nil)
+ return;
+ # if (env->getenv("home") != nil)
+ # return;
+ home := gethome();
+ env->setenv("home", home);
+ escript(ctxt, PROFILE, grammar);
+ escript(ctxt, home + PROFILE, grammar);
+}
+
+clean_n_chars_seek(sys: Sys, n: int, seek: int) {
+ for (i:=0; i<(n-seek); i++) {
+ sys->print("\b");
+ }
+ for (i=0; i<n; i++) {
+ sys->print(" ");
+ }
+ for (i=0; i<n; i++) {
+ sys->print("\b");
+ }
+}
+
+clean_n_chars(sys: Sys, n: int) {
+ clean_n_chars_seek(sys, n, 0);
+}
+
+argv_to_str(argv: list of string): string {
+ out := "";
+ lt := len argv;
+ for (i := 0; i < lt; i ++) {
+ tok := hd argv;
+ argv = tl argv;
+ out = out + " " + tok;
+ }
+ return out;
+}
+
+prompt(): string {
+ prompt := "SH92/" + getusername() + "@" + sysname() + ":" + getcwd() + "; ";
+ return prompt;
+}
+
+usage()
+{
+ sys->fprint(stderr, "Usage: sh92 [-n] [-c cmd] [file]\n");
+ sys->fprint(stderr, "\t-n : start with FORKNS;\n");
+ sys->fprint(stderr, "\t-c : run cmd on start;\n");
+ sys->fprint(stderr, "\t[file] : run script file on start and exit, optional.\n");
}
init(ctxt: ref Draw->Context, argv: list of string) {
- sys = load Sys Sys->PATH;
- sh9u = load Sh9Util Sh9Util->PATH;
- sh9p = load Sh9Parser Sh9Parser->PATH;
- sh9p->init();
- sh9cmd = load Sh9Cmd Sh9Cmd->PATH;
-
- stderr = sys->fildes(2);
-
- waitfd = sys->open("#p/"+string sys->pctl(0, nil)+"/wait", sys->OREAD);
- if(waitfd == nil){
- sys->fprint(stderr, "sh9: open wait: %r\n");
- return;
- }
-
- sys->pctl(sys->FORKENV, nil);
- sys->pctl(sys->FORKNS, nil);
-
- pctx:= ref ParserCtx;
- pctx.add_module("shell");
- pctx.ctxt = ctxt;
-
- toks1 := tokenize("AB = 'smth \"test\" '; echo ${AB}; echo $AB", 0);
- grammar:= mk_grammar(pctx);
- parse_toks(toks1, grammar, 0);
+ sys = load Sys Sys->PATH;
+ sh9u = load Sh9Util Sh9Util->PATH;
+ sh9p = load Sh9Parser Sh9Parser->PATH;
+ sh9p->init();
+ sh9cmd = load Sh9Cmd Sh9Cmd->PATH;
+ env = load Env Env->PATH;
+ bufio = load Bufio Bufio->PATH;
+ hash = load Hash Hash->PATH;
+
+ #n: int;
+ #arg: list of string;
+ buf := array[1024] of byte;
+
+ pctx:= ref ParserCtx;
+ pctx.add_module("");
+ pctx.ctxt = ctxt;
+ grammar:= mk_grammar(pctx);
+
+ stderr = sys->fildes(2);
+
+ waitfd = sys->open("#p/"+string sys->pctl(0, nil)+"/wait", sys->OREAD);
+ if(waitfd == nil){
+ sys->fprint(stderr, "sh9: open wait: %r\n");
+ return;
+ }
+
+ eflag := nflag := lflag := 0;
+ cmd: string;
+ if(argv != nil) {
+ argv = tl argv;
+ }
+ for(; argv != nil && len hd argv && (hd argv)[0]=='-'; argv = tl argv) {
+ case hd argv {
+ "-e" =>
+ eflag = 1;
+ "-n" =>
+ nflag = 1;
+ "-l" =>
+ lflag = 1;
+ "-c" =>
+ argv = tl argv;
+ if(len argv != 1){
+ usage();
+ return;
+ }
+ cmd = hd argv;
+ * =>
+ usage();
+ return;
+ }
+ }
+
+ if (lflag)
+ startup(ctxt, grammar);
+
+ if(eflag == 0)
+ sys->pctl(sys->FORKENV, nil);
+ if(nflag == 0)
+ sys->pctl(sys->FORKNS, nil);
+ if(cmd != nil){
+ toks := tokenize(cmd, 0);
+ if(toks != nil) {
+ parse_toks(toks, grammar, 0);
+ }
+ return;
+ }
+ if(argv != nil){
+ script(ctxt, hd argv, grammar);
+ return;
+ }
+
+ cctlfd := sys->open("/dev/consctl", sys->OWRITE);
+ if(cctlfd == nil)
+ return;
+ sys->write(cctlfd, array of byte "rawon", 5);
+
+ dfd := sys->open("/dev/cons", sys->OREAD);
+ if(dfd == nil)
+ return;
+
+ offset : int = 0;
+ temp : int;
+ #last_cmdline := array[1024] of int;
+ #last_cmdline_length : int = 0;
+
+ cmd1 := 0;
+ ST_NORMAL : con 0;
+ ST_WAITCMD1 : con 1;
+ ST_WAITCMD2 : con 2;
+ state := ST_NORMAL;
+ history_len := 1;
+ history_entry_cur := 0;
+# history.entries = nil;
+# history.entries = ("", "") :: nil;
+ history := hash->new(1024);
+ history.insert("0", (0,0.0,""));
+ seek := 0;
+
+ bio := bufio->fopen(dfd, sys->OREAD);
+
+ sys->print("%s", prompt());
+ for(;;) {
+ temp = bio.getb();
+ # check if escape
+ case state {
+ ST_NORMAL =>
+ # check if escape
+ if (temp == 27) {
+ state = ST_WAITCMD1; # is escape
+ } else if (temp == '\t') {
+ # tab complete rq
+ sys->print("tab");
+ } else if (temp == '\b') {
+ if (seek == 0) {
+ if (offset != 0) {
+ sys->print("\b");
+ sys->print(" ");
+ sys->print("\b");
+ offset --;
+ }
+ } else {
+ cur_buf := array[1024] of byte;
+ cur_buf[0:] = buf[0:offset];
+ correction := 0;
+ for (i:=0;i<offset;i++) {
+ if ((offset-i-1) == seek) {
+ correction = 1;
+ } else {
+ buf[i-correction] = cur_buf[i];
+ }
+ }
+ clean_n_chars_seek(sys, offset, seek);
+ offset --;
+ for (i=0;i<offset;i++) {
+ sys->print("%c", int(buf[i]));
+ }
+ for (i=0; i<seek; i++) {
+ sys->print("\b");
+ }
+ }
+ } else {
+ buf[offset] = byte(temp);
+ offset ++;
+ if ((offset >= len buf) || (buf[offset-1] == byte('\n'))) {
+ history_entry_cur = 0;
+ seek = 0;
+ sys->print("\n");
+ sys->print("run: \"%s\"\n", string buf[0: offset]);
+ toks := tokenize(string buf[0: offset], 0);
+ print_toks(toks);
+ if(toks != nil) {
+ parse_toks(toks, grammar, 0);
+ #runit(ctxt, parseit(arg));
+ history.insert(sys->sprint("%d", history_len), (0,0.0,string buf[0:offset-1]));
+ history_len++;
+ }
+ offset = 0;
+ sys->print("%s", prompt());
+ } else {
+ sys->print("%c",temp);
+ }
+ }
+ ST_WAITCMD1 =>
+ if (temp == '[') {
+ state = ST_WAITCMD2;
+ cmd1 = temp;
+ }
+ ST_WAITCMD2 =>
+ state = ST_NORMAL;
+ case cmd1 {
+ '[' =>
+ case temp {
+ 65 => { #up press
+ seek = 0;
+ clean_n_chars(sys, offset);
+
+ offset = 0;
+ he := history_len;
+ if (history_entry_cur < history_len) {
+ history_entry_cur ++;
+ he -= history_entry_cur;
+ }
+ cmdline := history.find(sys->sprint("%d", he));
+ if (cmdline != nil) {
+ sys->print("%s", cmdline.s);
+ offset = len cmdline.s;
+ for (i:=0; i<len cmdline.s; i++) {
+ buf[i] = byte(cmdline.s[i]);
+ }
+ }
+ }
+ 66 => { # down key
+ seek = 0;
+ if (history_entry_cur > 0) {
+ history_entry_cur --;
+ clean_n_chars(sys, offset);
+
+ offset = 0;
+ he := history_len;
+ he -= history_entry_cur;
+ cmdline := history.find(sys->sprint("%d", he));
+ if (cmdline != nil) {
+ sys->print("%s", cmdline.s);
+ offset = len cmdline.s;
+ for (i:=0; i<len cmdline.s; i++) {
+ buf[i] = byte(cmdline.s[i]);
+ }
+ }
+ }
+ }
+ 68 => { # left key
+ if (seek > offset) {
+ seek = offset;
+ } else {
+ seek ++;
+ sys->print("\b");
+ }
+ }
+ 67 => { # right key
+ clean_n_chars_seek(sys, offset, seek);
+ for (i:=0; i<offset; i++) {
+ sys->print("%c", int(buf[i]));
+ }
+ if (seek > 0) {
+ seek --;
+ }
+ for (i=0; i<seek; i++) {
+ sys->print("\b");
+ }
+ }
+ 70 => { # end key
+ clean_n_chars_seek(sys, offset, seek);
+ seek = 0;
+ for (i:=0; i<offset; i++) {
+ sys->print("%c", int(buf[i]));
+ }
+ }
+ 72 => { # home key
+ seek = offset;
+ for (i:=0; i<seek; i++) {
+ sys->print("\b");
+ }
+ }
+ * => {
+ sys->print("no action bind for %d\n", temp);
+ }
+
+ }
+ }
+ }
+ }
}
diff --git a/appl/cmd/sh9cmd.b b/appl/cmd/sh9cmd.b
index 9eea237..a735d03 100644
--- a/appl/cmd/sh9cmd.b
+++ b/appl/cmd/sh9cmd.b
@@ -4,6 +4,6 @@ include "sys.m";
include "draw.m";
include "sh9cmd.m";
-init(ctxt: ref Draw->Context, argv: list of string)
+init(nil: ref Draw->Context, nil: list of string)
{
}
diff --git a/appl/lib/sh9util.b b/appl/lib/sh9util.b
index 7452a13..7d4df29 100644
--- a/appl/lib/sh9util.b
+++ b/appl/lib/sh9util.b
@@ -1,6 +1,7 @@
implement Sh9Util;
include "sh9util.m";
+include "sys.m";
reverse_list[T](toks: list of T): list of T
{