ðøbSyntax10.Scn.Fnt­üÿÿÐûÐûInfoElemsAllocTSyntax10.Scn.Fntk÷ÿÿÿzÀÔStampElemsAlloc5 Nov 4“ÿ"Title": System "Author": JG/NW; MH 13.9.93 / 6.5.94; MAD 3.7.94; RLI "Abstract": System provides miscellaneous Commands for File handling, Viewer management, etc. as well as the Standard Trap-Handler mechanism. The basic Trap Handling mechanism is now located in Module Unix "Keywords": System, Trap-Handling, Files "Version": 1.2 "From": 1993 (?) "Until":  "Changes": 14 May 97 RLI Added improved Trap-Viewer (using full reference information) 12 Sep 97 RLI Directory taken from Windows 16 Sep 97 RLI Interface adapted to Windows (ChangeDir, StartupDir, etc.) 06 Oct 97 RLI Bug fixed in Trap Stack dump (relative address of topmost procedure was wrong) 09 Dec 98 RLI Glibc adaption 28 Mar 99 RLI DeleteFiles taken from Windows "Hints": Syntax10i.Scn.Fntvÿÿÿp°­VersionElemsAllocBeg#Syntax10.Scn.FntLinuxLibc6 LinuxLibc5LinuxLibc6LinuxLibc6 LinuxLibc5$Syntax10i.Scn.FntLibc5p°­VersionElemsAllocEndu¢X.ÿÿÿÿ€8ÀÔFoldElemsNewsÿÿÿÿ€8ÀÔ*¤ÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt:: BEGIN IF i >= j THEN RETURN i ELSE RETURN j END END Max; ÿÿÿÿ€8ÀÔJÙýÿÿ€8ÀÔ#Syntax10.Scn.Fnt VAR V: Viewers.Viewer; X, Y: INTEGER; M: TextFrames.Frame; buf: Texts.Buffer; menu: Texts.Text; BEGIN Oberon.AllocateSystemViewer(at, X, Y); IF Files.Old("System.Menu.Text") = NIL THEN M := TextFrames.NewMenu(name, StandardMenu) ELSE M := TextFrames.NewMenu(name, ""); NEW(menu); Texts.Open(menu, "System.Menu.Text"); NEW(buf); Texts.OpenBuf(buf); Texts.Save(menu, 0, menu.len, buf); Texts.Append(M.text, buf) END; V := MenuViewers.New(M, TextFrames.NewText(text, 0), TextFrames.menuH, X, Y) END SysOpen; ÿÿÿÿ€8ÀÔ Syntax10b.Scn.Fntcÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt{{ BEGIN OpenArgs(Sx); IF Sx.class = Texts.Name THEN SysOpen(TextFrames.Text(Sx.s), Sx.s, Oberon.Par.vwr.X) END END Open; ÿÿÿÿ€8ÀÔDTüÿÿ€8ÀÔ#Syntax10.Scn.FntŠŠ VAR r: Texts.Reader; pos, oldpos, last: LONGINT; ch: CHAR; BEGIN WITH F: TextFrames.Frame DO TextFrames.Handle(F, M); IF M IS TextFrames.UpdateMsg THEN WITH M : TextFrames.UpdateMsg DO IF (M.id = TextFrames.insert) & (M.end = Oberon.Log.len) THEN last := TextFrames.Pos(F, MAX(INTEGER), F.Y); IF last < Oberon.Log.len - 1 THEN Oberon.RemoveMarks(F.X, F.Y, F.W, F.H); TextFrames.RemoveSelection(F); TextFrames.RemoveCaret(F); REPEAT oldpos := pos; IF last + 2 < M.beg THEN pos := M.beg; TextFrames.Show(F, pos) ELSE Texts.OpenReader(r, Oberon.Log, F.org); REPEAT Texts.Read(r, ch) UNTIL r.eot OR (ch = 0DX); pos := Texts.Pos(r); TextFrames.Show(F, pos) END; last := TextFrames.Pos(F, MAX(INTEGER), F.Y) UNTIL (last >= Oberon.Log.len - 1) OR (oldpos = pos) END END END END END END LogHandler; ÿÿÿÿ€8ÀÔ  ™ýÿÿ€8ÀÔ#Syntax10.Scn.FntEE VAR logV: Viewers.Viewer; X, Y: INTEGER; F, M: TextFrames.Frame; T: Texts.Text; buf: Texts.Buffer; BEGIN Oberon.AllocateSystemViewer(0, X, Y); F := TextFrames.NewText(Oberon.Log, Max(0, Oberon.Log.len - 200)); F.handle := LogHandler; IF Files.Old("Log.Menu.Text") = NIL THEN M := TextFrames.NewMenu("System.Log", LogMenu) ELSE M := TextFrames.NewMenu("System.Log", ""); NEW(T); Texts.Open(T, "Log.Menu.Text"); NEW(buf); Texts.OpenBuf(buf); Texts.Save(T, 0, T.len, buf); Texts.Append(M.text, buf) END; logV := MenuViewers.New(M, F, TextFrames.menuH, X, Y) END OpenLog; ÿÿÿÿ€8ÀÔ Øþÿÿ€8ÀÔ#Syntax10.Scn.Fnt VAR par: Oberon.ParList; V: Viewers.Viewer; M: Viewers.ViewerMsg; BEGIN par := Oberon.Par; V := NIL; IF par.frame = par.vwr.dsc THEN V := par.vwr ELSIF Oberon.Pointer.on THEN V := Oberon.MarkedViewer() END; IF V # NIL THEN Viewers.Close(V) END END Close; ÿÿÿÿ€8ÀÔ  {ÿÿÿ€8ÀÔ#Syntax10.Scn.Fntcc VAR V: Viewers.Viewer; BEGIN V := Oberon.MarkedViewer(); Viewers.CloseTrack(V.X) END CloseTrack; ÿÿÿÿ€8ÀÔ ÿÿÿ€8ÀÔ#Syntax10.Scn.FntÈÈ VAR V: Viewers.Viewer; M: Viewers.ViewerMsg; BEGIN Viewers.Recall(V); IF (V # NIL) & (V.state = 0) THEN Viewers.Open(V, V.X, V.Y + V.H); M.id := Viewers.restore; V.handle(V, M) END END Recall; ÿÿÿÿ€8ÀÔ óþÿÿ€8ÀÔ#Syntax10.Scn.Fntëë VAR V, V1: Viewers.Viewer; M: Oberon.CopyMsg; N: Viewers.ViewerMsg; BEGIN V := Oberon.Par.vwr; V.handle(V, M); V1 := M.F(Viewers.Viewer); Viewers.Open(V1, V.X, V.Y + V.H DIV 2); N.id := Viewers.restore; V1.handle(V1, N) END Copy; ÿÿÿÿ€8ÀÔ ïýÿÿ€8ÀÔ#Syntax10.Scn.Fntïï VAR V, V1: Viewers.Viewer; M: Oberon.CopyMsg; N: Viewers.ViewerMsg; DW, DH: INTEGER; BEGIN V := Oberon.Par.vwr; DW := Oberon.DisplayWidth(V.X); DH := Oberon.DisplayHeight(V.X); IF V.H < DH - Viewers.minH THEN Oberon.OpenTrack(V.X, V.W) ELSIF V.W < DW THEN Oberon.OpenTrack(Oberon.UserTrack(V.X), DW) END; IF (V.H < DH - Viewers.minH) OR (V.W < DW) THEN V.handle(V, M); V1 := M.F(Viewers.Viewer); Viewers.Open(V1, V.X, DH); N.id := Viewers.restore; V1.handle(V1, N) END END Grow; ÿÿÿÿ€8ÀÔ  wÿÿÿ€8ÀÔ#Syntax10.Scn.Fntgg BEGIN OpenArgs(Sx); IF Sx.class = Texts.Name THEN Oberon.SetFont(Fonts.This(Sx.s)) END END SetFont; ÿÿÿÿ€8ÀÔ  tÿÿÿ€8ÀÔ#Syntax10.Scn.Fntjj BEGIN OpenArgs(Sx); IF Sx.class = Texts.Int THEN Oberon.SetColor(SHORT(SHORT(Sx.i))) END END SetColor; ÿÿÿÿ€8ÀÔ  rÿÿÿ€8ÀÔ#Syntax10.Scn.Fntll BEGIN OpenArgs(Sx); IF Sx.class = Texts.Int THEN Oberon.SetOffset(SHORT(SHORT(Sx.i))) END END SetOffset; ÿÿÿÿ€8ÀÔ .ÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt°° VAR t, d: LONGINT; BEGIN Texts.WriteString(W, "System.Time"); Oberon.GetClock(t, d); Texts.WriteDate(W, t, d); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END Time; ÿÿÿÿ€8ÀÔ ¡ýÿÿ€8ÀÔ#Syntax10.Scn.Fnt== VAR avail: LONGINT; BEGIN Texts.WriteString(W, "System.Watch"); Texts.WriteLn(W); avail := Kernel.Available(); Texts.WriteString(W, " heap size: "); Texts.WriteInt(W, Kernel.heapSize, 0); Texts.WriteLn(W); Texts.WriteString(W, " bytes allocated: "); Texts.WriteInt(W, Kernel.heapSize - avail, 0); Texts.WriteLn(W); Texts.WriteString(W, " available: "); Texts.WriteInt(W, avail, 0); Texts.WriteLn(W); Texts.WriteString(W, " largest available: "); Texts.WriteInt(W, Kernel.LargestAvailable(), 0); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END Watch; ÿÿÿÿ€8ÀÔ  ¸ÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt&& BEGIN Oberon.Collect(0) END Collect; ÿÿÿÿ€8ÀÔ,«þÿÿ€8ÀÔ#Syntax10.Scn.Fnt33 VAR m: Kernel.Module; BEGIN m := Kernel.modules; WHILE m # NIL DO Texts.WriteString(W, m.name); Texts.WriteString(W, " codesize = "); Texts.WriteInt(W, LEN(m.code^), 0); Texts.WriteString(W, " refcnt = "); Texts.WriteInt(W, m.refcnt, 0); Texts.WriteLn(W); m := m.next END END ShowMods; ÿÿÿÿ€8ÀÔ,bþÿÿ€8ÀÔ#Syntax10.Scn.Fnt|| BEGIN Texts.WriteString(W, S.s); Texts.WriteString(W, " unloading"); Texts.Append(Oberon.Log, W.buf); IF S.nextCh # "*" THEN Modules.Free(S.s, FALSE) ELSE Modules.Free(S.s, TRUE); Texts.Scan(S); Texts.WriteString(W, " all") END; IF Modules.res # 0 THEN Texts.WriteString(W, " failed"); Modules.res := 0 END; Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END FreeMod; ÿÿÿÿ€8ÀÔ œûÿÿ€8ÀÔ#Syntax10.Scn.FntBB VAR par: Oberon.ParList; T: Texts.Text; S: Texts.Scanner; V: Viewers.Viewer; beg, end, time: LONGINT; F: TextFrames.Frame; line: INTEGER; BEGIN Texts.WriteString(W, "System.Free"); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); par := Oberon.Par; IF par.vwr.dsc = par.frame THEN F := par.frame.next(TextFrames.Frame); IF F.hasSel THEN end := F.selend.pos; Texts.OpenScanner(S, F.text, F.selbeg.pos); beg := Texts.Pos(S); Texts.Scan(S); WHILE (S.class = Texts.Name) & (beg < end) DO FreeMod(S); line := S.line; REPEAT beg := Texts.Pos(S); Texts.Scan(S) UNTIL (S.line # line) OR S.eot END; ShowMods(W); Texts.Delete(F.text, 0, F.text.len); Texts.Append(F.text, W.buf) ELSE RETURN END ELSE Texts.OpenScanner(S, par.text, par.pos); Texts.Scan(S); WHILE S.class = Texts.Name DO FreeMod(S); Texts.Scan(S) END; IF (S.class = Texts.Char) & (S.c = "^") THEN Oberon.GetSelection(T, beg, end, time); IF time >= 0 THEN Texts.OpenScanner(S, T, beg); Texts.Scan(S); IF S.class = Texts.Name THEN FreeMod(S) END END END END END Free; ÿÿÿÿ€8ÀÔ  ^þÿÿ€8ÀÔ#Syntax10.Scn.Fnt€€ CONST Menu = "System.Close System.Copy System.Grow System.Free"; VAR T: Texts.Text; V: Viewers.Viewer; X, Y: INTEGER; BEGIN T := TextFrames.Text(""); Oberon.AllocateSystemViewer(Oberon.Par.vwr.X, X, Y); V := MenuViewers.New(TextFrames.NewMenu("System.ShowModules", Menu), TextFrames.NewText(T, 0), TextFrames.menuH, X, Y); ShowMods(W); Texts.Append(T, W.buf) END ShowModules; ÿÿÿÿ€8ÀÔ eüÿÿ€8ÀÔ¥Syntax10.Scn.Fnt3Syntax10i.Scn.Fnt!÷5K3ã÷ VAR M: Kernel.Module; i: LONGINT; T: Texts.Text; (*V: Viewers.Viewer; X, Y: INTEGER;*) BEGIN OpenArgs(Sx); IF Sx.class = Texts.Name THEN i := 0; WHILE Sx.s[i] >= "0" DO INC(i) END; Sx.s[i] := 0X; M := Modules.ThisMod(Sx.s); IF M # NIL THEN T := TextFrames.Text(""); SysOpen(T, "System.ShowCommands", Oberon.Mouse.X); (* Oberon.AllocateSystemViewer(Oberon.Par.vwr.X, X, Y); V := MenuViewers.New( TextFrames.NewMenu("System.Commands", StandardMenu), TextFrames.NewText(T, 0), TextFrames.menuH, X, Y); *) i := 0; WHILE i < LEN(M.cmds^) DO Texts.WriteString(W, M.name); Texts.Write(W, "."); Texts.WriteString(W, M.cmds[i].name); Texts.WriteLn(W); INC(i) END ; Texts.Append(T, W.buf) END END END ShowCommands; ÿÿÿÿ€8ÀÔ  nþÿÿ€8ÀÔ#Syntax10.Scn.Fntpp VAR i: INTEGER; ch: CHAR; user: ARRAY 8 OF CHAR; password: ARRAY 16 OF CHAR; BEGIN i := 0; Input.Read(ch); WHILE (ch # "/") & (i < 7) DO user[i] := ch; INC(i); Input.Read(ch) END; user[i] := 0X; i := 0; Input.Read(ch); WHILE (ch > " ") & (i < 15) DO password[i] := ch; INC(i); Input.Read(ch) END; password[i] := 0X; Oberon.SetUser(user, password) END SetUser; ÿÿÿÿ€8ÀÔ  Dýÿÿ€8ÀÔ#Syntax10.Scn.Fntšš VAR par: Oberon.ParList; T: Texts.Text; S: Texts.Scanner; res: INTEGER; beg, end, time: LONGINT; BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); IF (S.class = Texts.Char) & (S.c = "^") OR (S.line # 0) THEN Oberon.GetSelection(T, beg, end, time); IF time >= 0 THEN Texts.OpenScanner(S, T, beg); Texts.Scan(S) END END; IF (S.class = Texts.Name) & (S.line = 0) THEN Texts.WriteString(W, "System.ChangeDirectory "); Texts.WriteString(W, S.s); Directories.Change(S.s); res := Directories.res; IF res # 0 THEN Texts.WriteString(W, " -- failed") END ; Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END END ChangeDir; ÿÿÿÿ€8ÀÔ  —þÿÿ€8ÀÔ#Syntax10.Scn.FntGG BEGIN OpenArgs(Sx); IF Sx.class IN {Texts.Name, Texts.String} THEN Texts.WriteString(W, "System.CreateDir "); Texts.WriteString(W, Sx.s); Directories.Create(Sx.s); IF Directories.res # Directories.noErr THEN Texts.WriteString(W, " failed") END ; Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END END CreateDir; ÿÿÿÿ€8ÀÔ  —þÿÿ€8ÀÔ#Syntax10.Scn.FntGG BEGIN OpenArgs(Sx); IF Sx.class IN {Texts.Name, Texts.String} THEN Texts.WriteString(W, "System.DeleteDir "); Texts.WriteString(W, Sx.s); Directories.Delete(Sx.s); IF Directories.res # Directories.noErr THEN Texts.WriteString(W, " failed") END ; Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END END DeleteDir; ÿÿÿÿ€8ÀÔBÞûÿÿ€8ÀÔ#Syntax10.Scn.Fnt CONST N = 2048; VAR f, g: Files.File; Rf, Rg: Files.Rider; buf: ARRAY N OF CHAR; n, remaining: LONGINT; BEGIN Texts.Scan(S); IF (S.class = Texts.Char) & (S.c = "=") THEN Texts.Scan(S); IF (S.class = Texts.Char) & (S.c = ">") THEN Texts.Scan(S); IF S.class = Texts.Name THEN Texts.WriteString(W, name); Texts.WriteString(W, " => "); Texts.WriteString(W, S.s); Texts.WriteString(W, " copying"); Texts.Append(Oberon.Log, W.buf); f := Files.Old(name); IF f # NIL THEN g := Files.New(S.s); IF g # NIL THEN Files.Set(Rf, f, 0); Files.Set(Rg, g, 0); remaining := Files.Length(f); WHILE remaining > 0 DO IF remaining > N THEN n := N ELSE n := remaining END; Files.ReadBytes(Rf, buf, n); Files.WriteBytes(Rg, buf, n); DEC(remaining, n) END; Files.Register(g) ELSE Texts.WriteString(W, " failed") END ELSE Texts.WriteString(W, " failed") END; Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END END END END CopyFile; ÿÿÿÿ€8ÀÔ  Çþÿÿ€8ÀÔ#Syntax10.Scn.Fnt BEGIN OpenArgs(Sx); Texts.WriteString(W, "System.CopyFiles"); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); IF InSelection & (Sx.class = Texts.Name) THEN CopyFile(Sx.s, Sx) ELSE WHILE Sx.class = Texts.Name DO CopyFile(Sx.s, Sx); Texts.Scan(Sx) END END END CopyFiles; ÿÿÿÿ€8ÀÔD¾ýÿÿ€8ÀÔ#Syntax10.Scn.Fnt   VAR res: INTEGER; BEGIN Texts.Scan(S); IF (S.class = Texts.Char) & (S.c = "=") THEN Texts.Scan(S); IF (S.class = Texts.Char) & (S.c = ">") THEN Texts.Scan(S); IF S.class = Texts.Name THEN Texts.WriteString(W, name); Texts.WriteString(W, " => "); Texts.WriteString(W, S.s); Texts.WriteString(W, " renaming"); Texts.Append(Oberon.Log, W.buf); Files.Rename(name, S.s, res); IF res > 1 THEN Texts.WriteString(W, " failed") END; Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END END END END RenameFile; ÿÿÿÿ€8ÀÔ  ¿þÿÿ€8ÀÔ#Syntax10.Scn.Fnt BEGIN OpenArgs(Sx); Texts.WriteString(W, "System.RenameFiles"); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); IF InSelection & (Sx.class = Texts.Name) THEN RenameFile(Sx.s, Sx) ELSE WHILE Sx.class = Texts.Name DO RenameFile(Sx.s, Sx); Texts.Scan(Sx) END END END RenameFiles; ÿÿÿÿ€8ÀÔ2Îþÿÿ€8ÀÔ#Syntax10.Scn.Fnt VAR res: INTEGER; BEGIN Texts.WriteString(W, name); Texts.WriteString(W, " deleting"); Texts.Append(Oberon.Log, W.buf); Files.Delete(name, res); IF res # 0 THEN Texts.WriteString(W, " failed") END; Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END DeleteFile; ÿÿÿÿ€8ÀÔ  Éþÿÿ€8ÀÔ#Syntax10.Scn.Fnt BEGIN OpenArgs(Sx); Texts.WriteString(W, "System.DeleteFiles"); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); WHILE (Sx.class IN {Texts.Name, Texts.String}) & (~InSelection OR (Texts.Pos(Sx) <= SelEnd + 1)) DO DeleteFile(Sx.s); Texts.Scan(Sx) END END DeleteFiles; ÿÿÿÿ€8ÀÔ  _þÿÿ€8ÀÔ#Syntax10.Scn.Fnt VAR M: Oberon.InputMsg; VM: Viewers.ViewerMsg; res: LONGINT; BEGIN M.id := Oberon.neutralize; Viewers.Broadcast(M); VM.id := Viewers.suspend; Viewers.Broadcast(VM); Display.ReplConst(Display.black, 0, 0, Display.Width, Display.Height, Display.replace); res := Unix.Kill(Unix.Getpid(), 19); Display.SetMode(0, {}); VM.id := Viewers.restore; Viewers.Broadcast(VM) END Suspend; ÿÿÿÿ€8ÀÔ  õÿÿ€8ÀÔmSyntax10.Scn.Fnt9Syntax10i.Scn.FntK$04.!y VAR par: Oberon.ParList; t: Texts.Text; R: Texts.Reader; V: Viewers.Viewer; i, bufsize, beg, end, time, stdin, stdout, stderr, fd, res: LONGINT; boldFnt, italicFnt: Fonts.Font; cmd: ARRAY 4096 OF CHAR; buf: ARRAY 32000 OF CHAR; X, Y: INTEGER; ch: CHAR; BEGIN par := Oberon.Par; Oberon.AllocateSystemViewer(par.vwr.X, X, Y); Texts.OpenReader(R, par.text, par.pos); i := 0; cmd := ""; Texts.Read(R, ch); WHILE ch = " " DO Texts.Read(R, ch) END ; WHILE (ch >= " ") & (ch # "^") DO cmd[i] := ch; INC(i); Texts.Read(R, ch) END ; IF (i = 0) OR (ch = "^") THEN Oberon.GetSelection(t, beg, end, time); IF time >= 0 THEN Texts.OpenReader(R, t, beg); Texts.Read(R, ch); WHILE Texts.Pos(R) <= end DO IF ch = 0DX THEN ch := " " END ; cmd[i] := ch; INC(i); Texts.Read(R, ch) END END END ; cmd[i] := 0X; stdin := Unix.Dup(Unix.stdin); stdout := Unix.Dup(Unix.stdout); stderr := Unix.Dup(Unix.stderr); res := Unix.Close(Unix.stdin); res := Unix.Close(Unix.stdout); res := Unix.Close(Unix.stderr); fd := Unix.Open(S.ADR("/dev/null"), {1}, {0..31}); (* {1} = rdwr *) fd := Unix.Open(S.ADR("/tmp/.tmp.System.Execute"), {1, 6, 9}, {0..31}); (* {1, 6, 9} = rdwr, creat, trunc *) res := Unix.Unlink(S.ADR("/tmp/.tmp.System.Execute")); fd := Unix.Dup(fd); system(cmd); boldFnt := Fonts.This("Oberon10b.Scn.Fnt"); italicFnt := Fonts.This("Oberon10i.Scn.Fnt"); res := Unix.Lseek(Unix.stdout, 0, 0); bufsize := Unix.Read(Unix.stdout, S.ADR(buf), LEN(buf)); IF bufsize > 0 THEN t := TextFrames.Text(""); V := MenuViewers.New( TextFrames.NewMenu("System.Execute", StandardMenu), TextFrames.NewText(t, 0), TextFrames.menuH, X, Y); REPEAT i := 0; WHILE i < bufsize DO ch := buf[i]; IF ch = 0AX THEN ch := 0DX END ; (* LF -> CR *) IF (i < bufsize - 2) & (buf[i + 1] = 08X) THEN (* -almost- correct (consider buf limit...) *) Texts.SetFont(W, boldFnt); IF ch # "_" THEN Texts.SetFont(W, boldFnt); Texts.Write(W, ch) ELSE Texts.SetFont(W, boldFnt); Texts.Write(W, buf[i + 2]) END ; Texts.SetFont(W, Fonts.Default); REPEAT INC(i, 2) UNTIL (i + 1 >= bufsize) OR (buf[i + 1] # 08X) ELSE Texts.Write(W, ch) END ; INC(i) END ; bufsize := Unix.Read(Unix.stdout, S.ADR(buf), LEN(buf)) UNTIL bufsize = 0; Texts.Append(t, W.buf); res := Unix.Ftruncate(Unix.stdout, 0); res := Unix.Lseek(Unix.stdout, 0, 0) END ; res := Unix.Close(Unix.stdin); res := Unix.Close(Unix.stdout); res := Unix.Close(Unix.stderr); fd := Unix.Dup(stdin); fd := Unix.Dup(stdout); fd := Unix.Dup(stderr); res := Unix.Close(stdin); res := Unix.Close(stdout); res := Unix.Close(stderr) END Execute; ÿÿÿÿ€8ÀÔL–þÿÿ€8ÀÔCSyntax10.Scn.Fnt—Syntax10i.Scn.Fnt%l( BEGIN IF (name[i] = 0X) & (pat[j] = 0X) THEN RETURN TRUE ELSIF pat[j] # "*" THEN RETURN (name[i] = pat[j]) & matches(name, pat, i + 1, j + 1) ELSE (* pat[j] = "*", name[i] may be 0X *) RETURN matches(name, pat, i, j + 1) OR ((name[i] # 0X) & matches(name, pat, i + 1, j)) END END matches; ÿÿÿÿ€8ÀÔMVþÿÿ€8ÀÔQSyntax10.Scn.FntSyntax10i.Scn.Fnt"¢%oZ (* as matches, but ignores case *) BEGIN IF (name[i] = 0X) & (pat[j] = 0X) THEN RETURN TRUE ELSIF pat[j] # "*" THEN RETURN (CAP(name[i]) = CAP(pat[j])) & matches2(name, pat, i + 1, j + 1) ELSE (* pat[j] = "*", name[i] may be 0X *) RETURN matches2(name, pat, i, j + 1) OR ((name[i] # 0X) & matches2(name, pat, i + 1, j)) END END matches2; ÿÿÿÿ€8ÀÔ"@ÿÿÿ€8ÀÔ#Syntax10.Scn.Fntžž VAR i: INTEGER; BEGIN i := 0; WHILE (s1[i] # 0X) & (s2[i] # 0X) & (CAP(s1[i]) = CAP(s2[i])) DO INC(i) END ; RETURN (s1[i] = 0X) & (s2[i] = 0X) END Match; ÿÿÿÿ€8ÀÔm¥úÿÿ€8ÀÔ#Syntax10.Scn.Fnt99 CONST blue = 3; VAR path: ARRAY 256 OF CHAR; time, date, size: LONGINT; i: INTEGER; f: Files.File; cur: Directories.Directory; oldFont: Fonts.Font; BEGIN IF ((name[0] = "&") & matches2(name, pattern, 0, 0)) OR matches(name, pattern, 0, 0) THEN COPY(d.path, path); i := 0; WHILE path[i] # 0X DO INC(i) END ; IF (i > 2) & (path[i - 1] # Directories.delimiter) THEN path[i] := Directories.delimiter; path[i + 1] := 0X END ; Strings.Append(name, path); cur := Directories.Current(); IF isDir THEN Texts.SetColor(W, blue) ELSE Texts.SetColor(W, Display.white) END ; IF (allPaths IN options) OR ~Match(cur.path, d.path) THEN Texts.WriteString(W, path) ELSE Texts.WriteString(W, name) END ; IF isDir THEN Texts.Write(W, Directories.delimiter); Texts.Write(W, "*") END ; Texts.SetColor(W, Display.white); IF {dateOpt, sizeOpt} * options # {} THEN f := Files.Old(path); IF f # NIL THEN Files.GetDate(f, time, date); size := Files.Length(f); IF dateOpt IN options THEN Texts.Write(W, 9X); Texts.WriteDate(W, time, date) END ; IF sizeOpt IN options THEN Texts.Write(W, 9X); oldFont := W.fnt; Texts.SetFont(W, Fonts.This("Courier10.Scn.Fnt")); Texts.WriteInt(W, size, 8); Texts.SetFont(W, oldFont) END END END ; Texts.WriteLn(W); Texts.Append(T, W.buf) END END ShowFile; ÿÿÿÿ€8ÀÔH§þÿÿ€8ÀÔ#Syntax10.Scn.Fnt77 VAR d, cur, startup: Directories.Directory; BEGIN d := Directories.This(path); cur := Directories.Current(); startup := Directories.Startup(); IF (d # NIL) & (d.path # cur.path) THEN Directories.Enumerate(d, ShowFile); IF Match(d.path, startup.path) THEN startupDone := TRUE END END END ScanDirectory; ÿÿÿÿ€8ÀÔ  ÿÿÿÿ€8ÀÔh D[ÿÿÿÿ€8ÀÔ  ÿÿÿ€8ÀÔ#Syntax10.Scn.FntÁÁ VAR d: Directories.Directory; BEGIN d := Directories.Startup(); Directories.Change(d.path); Texts.WriteString(W, d.path); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END StartupDir; ÿÿÿÿ€8ÀÔ  =ÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt¡¡ VAR d: Directories.Directory; BEGIN d := Directories.Current(); Texts.WriteString(W, d.path); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END ShowDir; ÿÿÿÿ€8ÀÔ  ¼þÿÿ€8ÀÔ#Syntax10.Scn.Fnt"" VAR d: Directories.Directory; BEGIN Directories.Change(".."); IF Directories.res # Directories.noErr THEN Texts.WriteString(W, ".. -- failed") ELSE d := Directories.Current(); Texts.WriteString(W, d.path) END ; Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END ParentDir; ÿÿÿÿ€8ÀÔ ¾ÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt BEGIN Kernel.Exit(0) END Quit; ÿÿÿÿ€8ÀÔ] þÿÿ€8ÀÔ#Syntax10.Scn.FntØØ VAR T: Texts.Text; i: INTEGER; r: Ref.Rider; BEGIN OpenArgs(Sx); T := TextFrames.Text(""); SysOpen(T, "System.State", Oberon.Par.vwr.X); IF Sx.class = Texts.Name THEN i := 0; WHILE Sx.s[i] > "." DO INC(i) END ; Sx.s[i] := 0X; Ref.OpenVars(Sx.s, r); IF r.mod = "" THEN Texts.WriteString(W, " not loaded") ELSE Texts.WriteString(W, "MODULE "); Texts.WriteString(W, Sx.s); RefElems.WriteRider(W, r, 1) END ; Texts.Append(T, W.buf) END END State; ÿÿÿÿ€8ÀÔ üÿÿÿÀÔ°­MarkElemsAllocœ,ÿÿÿÿ€8ÀÔ½?t6(Q)æ'‰nOÿÿÿp°­#Syntax10.Scn.FntLinuxLibc6 LinuxLibc5LinuxLibc6LinuxLibc6 LinuxLibc5#Syntax10.Scn.Fnt--addr := Kernel.siglongjmp(Kernel.trapEnv, 1);+p°­3ÿÿÿÿ€8ÀÔ  œÿÿÿ€8ÀÔ#Syntax10.Scn.FntBB BEGIN Texts.Delete(Oberon.Log, 0, Oberon.Log.len) END ClearLog; ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔCD;8?;®ÿÿÿÿ€8ÀÔ®ýÿÿ€8ÀÔ#Syntax10.Scn.Fnt00 VAR logV, toolV: Viewers.Viewer; t, d: LONGINT; X, Y: INTEGER; mod: Modules.Module; BEGIN Oberon.GetClock(t, d); Texts.WriteString(W, "GNU/LINUX Oberon"); Texts.SetFont(W, Fonts.This("Oberon8.Scn.Fnt")); Texts.SetOffset(W, 32); Texts.WriteString(W, "TM "); Texts.SetFont(W, Fonts.Default); Texts.SetOffset(W, 0); Texts.WriteString(W, Version); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); mod := Modules.ThisMod("Configuration"); IF mod = NIL THEN OpenLog; SysOpen(TextFrames.Text("System.Tool"), "System.Tool", 0) END END OpenViewers; ÿÿÿÿ€8ÀÔ’ÿÿÿ€8ÀÔ#Syntax10.Scn.FntLL Texts.OpenWriter(W); Oberon.Log := TextFrames.Text(""); Init; OpenViewersÿÿÿÿ€8ÀÔ w$MODULE System;  (* Libc6 *) IMPORT S := SYSTEM, Unix, Kernel, Modules, Files, Input, Display, Viewers, MenuViewers, Oberon, Fonts, Texts, TextFrames, X11, Ref, RefElems, Directories, Strings, Threads; CONST Version = "V4.0-1.7.02 Linz RLI"; StandardMenu = "^Trap.Menu.Text"; LogMenu = "System.Close System.Grow Edit.Locate Edit.Store System.ClearLog "; dateOpt = 1; sizeOpt = 2; allPaths = 3; (* Directory Options *) delimiter = Directories.delimiter; VAR T: Texts.Text; Sx: Texts.Scanner; InSelection: BOOLEAN; SelEnd: LONGINT; W: Texts.Writer; pattern: ARRAY 32 OF CHAR; (* for Directory command *) DetailedDirListing: BOOLEAN; system: PROCEDURE (cmd: ARRAY OF CHAR); options: SET; (*options in System.Directory*) startupDone: BOOLEAN; (* state in System.Directory *) PROCEDURE OpenArgs (VAR S: Texts.Scanner);  VAR beg, time: LONGINT; T: Texts.Text; BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); InSelection := FALSE; IF (S.class = Texts.Char) & (S.c = "^") THEN InSelection := TRUE; Oberon.GetSelection(T, beg, SelEnd, time); IF time >= 0 THEN Texts.OpenScanner(S, T, beg); Texts.Scan(S) ELSE S.class := Texts.Inval END END END OpenArgs;  PROCEDURE Max (i, j: LONGINT): LONGINT;  PROCEDURE SysOpen (text: Texts.Text; name: ARRAY OF CHAR; at: INTEGER);  PROCEDURE Open*;  PROCEDURE LogHandler (F: Display.Frame; VAR M: Display.FrameMsg);  PROCEDURE OpenLog*;  PROCEDURE Close*;  PROCEDURE CloseTrack*;  PROCEDURE Recall*;  PROCEDURE Copy*;  PROCEDURE Grow*;  PROCEDURE SetFont*;  PROCEDURE SetColor*;  PROCEDURE SetOffset*;  PROCEDURE Time*;  PROCEDURE Watch*;  PROCEDURE Collect*;  PROCEDURE ShowMods (VAR W: Texts.Writer);  PROCEDURE FreeMod (VAR S: Texts.Scanner);  PROCEDURE Free*;  PROCEDURE ShowModules*;  PROCEDURE ShowCommands*;  PROCEDURE SetUser*;  PROCEDURE ChangeDir*;  PROCEDURE CreateDir*;  PROCEDURE DeleteDir*;  PROCEDURE CopyFile (name: ARRAY OF CHAR; VAR S: Texts.Scanner);  PROCEDURE CopyFiles*;  PROCEDURE RenameFile (name: ARRAY OF CHAR; VAR S: Texts.Scanner);  PROCEDURE RenameFiles*;  PROCEDURE DeleteFile (VAR name: ARRAY OF CHAR);  PROCEDURE DeleteFiles*;  PROCEDURE Suspend*;  PROCEDURE Execute*;  PROCEDURE matches (VAR name, pat: ARRAY OF CHAR; i, j: INTEGER): BOOLEAN;  PROCEDURE matches2 (VAR name, pat: ARRAY OF CHAR; i, j: INTEGER): BOOLEAN;  PROCEDURE Match (VAR (*in*) s1, s2: ARRAY OF CHAR): BOOLEAN;  PROCEDURE ShowFile (d: Directories.Directory; name: ARRAY OF CHAR; isDir: BOOLEAN; VAR continue: BOOLEAN);  PROCEDURE ScanDirectory (path: ARRAY OF CHAR; VAR continue: BOOLEAN);  PROCEDURE Directory*;  VAR r: Texts.Reader; t: Texts.Text; v: Viewers.Viewer; beg, end, time: LONGINT; x, y, i, j, pos: INTEGER; c, ch: CHAR; path: ARRAY 128 OF CHAR; dir, startup: Directories.Directory; copy: Texts.CopyMsg; parc: TextFrames.Parc; BEGIN Texts.OpenReader(r, Oberon.Par.text, Oberon.Par.pos); Texts.Read(r, ch); WHILE ((ch = " ") OR (ch = 09X)) & ~r.eot DO Texts.Read(r, ch) END ; IF ch = "^" THEN Oberon.GetSelection(t, beg, end, time); IF time >= 0 THEN Texts.OpenReader(r, t, beg); Texts.Read(r, ch); WHILE ((ch = " ") OR (ch = 09X)) & ~r.eot DO Texts.Read(r, ch) END END END ; i := 0; j := 0; pos := 0; IF (ch = "'") OR (ch = '"') THEN c := ch; Texts.Read(r, ch); WHILE (ch # c) & (ch >= " ") & ~r.eot DO path[i] := ch; pattern[j] := ch; INC(j); IF ch = delimiter THEN pos := i; j := 0 END ; INC(i); Texts.Read(r, ch) END ; Texts.Read(r, ch) ELSIF (ch > " ") & (ch # "\") & (ch # "^") THEN WHILE (ch > " ") & (ch # "\") DO path[i] := ch; pattern[j] := ch; INC(j); IF ch = delimiter THEN pos := i; j := 0 END ; INC(i); Texts.Read(r, ch) END END ; pattern[j] := 0X; IF pos = 0 THEN (* no path *) path[0] := 0X ELSIF (pos = 0) OR (pos = 2) & (path[1] = ":") THEN (* keep trailing \ *) path[pos + 1] := 0X ELSE (* cut last \ *) path[pos] := 0X END ; options := {}; WHILE ((ch = " ") OR (ch = 09X)) & ~r.eot DO Texts.Read(r, ch) END ; IF ch = "\" THEN LOOP Texts.Read(r, ch); IF CAP(ch) = "D" THEN INCL(options, dateOpt) ELSIF CAP(ch) = "S" THEN INCL(options, sizeOpt) ELSIF CAP(ch) = "A" THEN INCL(options, allPaths) ELSE EXIT END END END ; IF pattern = "" THEN RETURN END ; T := TextFrames.Text(""); Oberon.AllocateSystemViewer(Oberon.Par.vwr.X, x, y); v := MenuViewers.New(TextFrames.NewMenu("System.Directory", "^System.Menu.Text"), TextFrames.NewText(T, 0), TextFrames.menuH, x, y); TextFrames.defParc.handle(TextFrames.defParc, copy); parc := copy.e(TextFrames.Parc); parc.nofTabs := 1; parc.tab[0] := 1584000; Texts.WriteElem(W, parc); startup := Directories.Startup(); IF path = "" THEN dir := Directories.Current() ELSE dir := Directories.This(path) END ; Directories.Enumerate(dir, ShowFile); startupDone := Match(dir.path, startup.path); IF allPaths IN options THEN Directories.EnumeratePaths(ScanDirectory); IF ~startupDone THEN Directories.Enumerate(startup, ShowFile) END END END Directory;  PROCEDURE StartupDir*;  PROCEDURE ShowDir*;  PROCEDURE ParentDir*;  PROCEDURE Quit*;  (* ------------------------ trap handling and memory dump -------------------------------- *) PROCEDURE State*;  PROCEDURE Trap (exInfo: Unix.ExceptionInfo): LONGINT;  VAR V: Viewers.Viewer; X, Y: INTEGER; ch: CHAR; excode, pc, bp, sp, ref, refend, n, addr: LONGINT; offs: LONGINT; trapno: LONGINT; name: ARRAY 32 OF CHAR; mod: Modules.Module; r, r2: Ref.Rider; retAdr: LONGINT; t: Threads.Thread; PROCEDURE Str (str: ARRAY OF CHAR); BEGIN (* Console.Str(str); *) Texts.WriteString(W, str) END Str; PROCEDURE Int (i: LONGINT); BEGIN (* Console.Int(i); *) Texts.WriteInt(W, i, 0) END Int; PROCEDURE Hex (i: LONGINT); BEGIN (* Console.Hex(i); Console.Ch("H"); *) Texts.WriteHex(W, i); Texts.Write(W, "H") END Hex; PROCEDURE Ln; BEGIN (* Console.Ln; *) Texts.WriteLn(W) END Ln; BEGIN IF Kernel.TrapHandlingLevel < 2 THEN INC(Kernel.TrapHandlingLevel); (* IF T # NIL THEN Texts.Append(T, W.buf); T := NIL END; *) pc := exInfo.cont.Eip; bp := exInfo.cont.Ebp; sp := exInfo.cont.Esp; trapno := exInfo.cont.Eax; IF pc = 0 THEN (* assume call of procedure variable with value NIL *) S.GET(sp, pc) (* get return address on top of stack *) END; Str("Trap "); CASE exInfo.sig OF | 2: Str(" (INTERRUPT)"); | 4: (* Illegal Instruction => Oberon traps *) Int(trapno); CASE trapno OF | 0: Str(" (ASSERT failed)"); | 1: Str(" (Heap overflow)"); | 15: Str(" (invalid case in WITH statement)"); | 16: Str(" (invalid case in CASE statement)"); | 17: Str(" (function procedure with no return value)"); | 18: Str(" (type guard check)"); | 19: Str(" (implicit type guard check in record assignment)"); | 20: Str(" (integer overflow)"); | 21: Str(" (range overflow)"); | 22: Str(" (dimension trap)") ELSE IF trapno >= 30 THEN Str(" (programmed HALT)") ELSE Str(" (unknown trap)") END END; | 8: Str(" (ARITHMETIC EXCEPTION)"); | 11: Str(" (SEGMENTATION VIOLATION)") ELSE Str(" (SIGNAL "); Int(exInfo.sig); Str(") ") END; (* New TRAP handler RLI, 14 May 1997 *) Str(" PC = "); Hex(pc); Ref.OpenProc(pc, r); mod := r.m; IF mod # NIL THEN Str(" ("); Hex(pc - S.ADR(mod.code[0])); Str(") ") END; Ln; T := TextFrames.Text(""); Oberon.AllocateSystemViewer(0, X, Y); V := MenuViewers.New(TextFrames.NewMenu("System.Trap", StandardMenu), TextFrames.NewText(T, 0), TextFrames.menuH, X, Y); IF V.state > 0 THEN Texts.Append(T, W.buf); (* stack dump *) Ref.OpenStack(exInfo, r); n := 0; retAdr := pc; WHILE (r.mode # Ref.End) & (n < 64) DO Ln; Str(r.mod); Str("."); Str(r.name); Str(" (Rel. PC: "); Hex(retAdr - S.ADR(r.m.code^)); Str(", FP: "); Hex(r.fp); Str(", abs. PC: "); Hex(r.pc); Str(")"); r.Zoom(r2); RefElems.WriteRider(W, r2, 1); Texts.Append(T, W.buf); S.GET(r.fp + 4, retAdr); r.Next; INC(n) END END ELSE Str("-- recursive trap"); Ln; Unix.Exit(0); IF T # NIL THEN Texts.Append(T, W.buf); T := NIL END END; Kernel.TrapHandlingLevel := 0; T := NIL; t := Threads.ActiveThread(); IF t = Threads.OberonThread() THEN addr := Kernel.longjmp(Kernel.trapEnv, 1);  ELSE Threads.Kill(t) END; RETURN 0 END Trap;  PROCEDURE ClearLog*;  PROCEDURE Init;  TYPE EnvVar = POINTER TO ARRAY 1024 OF CHAR; VAR getenv: PROCEDURE (var: ARRAY OF CHAR): EnvVar; var: EnvVar; old: Unix.TrapHandler; dummy: LONGINT; BEGIN Kernel.dlsym(Kernel.libc, "system", S.VAL(LONGINT, system)); Kernel.dlsym(Kernel.libc, "getenv", S.VAL(LONGINT, getenv)); Unix.InstallTrapHandler(Trap, old); (* ASSERT(old = NIL) *) (* -- old Kernel.InstallSignal(2, Trap); (* keyboard interrupt *) Kernel.InstallSignal(4, Trap); (* illegal instruction *) Kernel.InstallSignal(8, Trap); (* arithmetic error *) Kernel.InstallSignal(11, Trap); (* segmentation violation *) Kernel.InstallSignal(13, Trap); (* unconnected pipe *) *) var := getenv("USER"); IF var # NIL THEN COPY(var^, Oberon.User) ELSE Oberon.User := "" END; NEW(Oberon.Par); dummy := X11.SetErrorHandler(X11.MyErrorHandler) END Init;  PROCEDURE OpenViewers;  BEGIN END System.