|
|
@@ -0,0 +1,247 @@
|
|
|
+MODULE Tp3Cfg ;
|
|
|
+
|
|
|
+(* The terminal CONFIGURATOR - the TINST role, without the binary patch.
|
|
|
+
|
|
|
+ TINST installs terminal escape sequences by writing them into TURBO.COM.
|
|
|
+ This program writes a TEXT file, TP3.TRM, that the shell reads at startup
|
|
|
+ (TermCfg.Load). Nothing here touches tpshell: edit the file by hand, copy
|
|
|
+ it, version it, generate it - the shell will read whatever is there.
|
|
|
+
|
|
|
+ Usage:
|
|
|
+ tp3cfg list the terminals, pick one, write TP3.TRM
|
|
|
+ (The sequence table below is the place to add a terminal: one Build case,
|
|
|
+ one NumTerms increment. A CLI with --list/--show is a later convenience;
|
|
|
+ the file it writes is plain text and can be edited or copied by hand.)
|
|
|
+
|
|
|
+ The sequences are entered here as readable text and DECODED by TermCfg, so
|
|
|
+ the emitted file contains the same `\e...' spelling a person can edit. *)
|
|
|
+
|
|
|
+FROM Posix IMPORT read, write, open, close ;
|
|
|
+FROM SYSTEM IMPORT ADR ;
|
|
|
+FROM TermCfg IMPORT Cfg, Default, ParseValue ;
|
|
|
+
|
|
|
+CONST
|
|
|
+ STDOUT = 1 ;
|
|
|
+ NumTerms = 3 ;
|
|
|
+
|
|
|
+VAR
|
|
|
+ terms : ARRAY [0..NumTerms - 1] OF Cfg ;
|
|
|
+ nout : LONGINT ;
|
|
|
+ chbuf : CHAR ;
|
|
|
+ outFd : INTEGER ; (* STDOUT normally, the file while writing it *)
|
|
|
+
|
|
|
+PROCEDURE NL ;
|
|
|
+BEGIN
|
|
|
+ chbuf := CHR (10) ;
|
|
|
+ nout := write (outFd, ADR (chbuf), 1)
|
|
|
+END NL ;
|
|
|
+
|
|
|
+PROCEDURE Out (s : ARRAY OF CHAR) ;
|
|
|
+VAR i : CARDINAL ;
|
|
|
+BEGIN
|
|
|
+ i := 0 ;
|
|
|
+ WHILE (i <= HIGH (s)) AND (s [i] # 0C) DO
|
|
|
+ chbuf := s [i] ;
|
|
|
+ nout := write (outFd, ADR (chbuf), 1) ;
|
|
|
+ INC (i)
|
|
|
+ END
|
|
|
+END Out ;
|
|
|
+
|
|
|
+PROCEDURE OutCh (ch : CHAR) ;
|
|
|
+BEGIN
|
|
|
+ chbuf := ch ;
|
|
|
+ nout := write (outFd, ADR (chbuf), 1)
|
|
|
+END OutCh ;
|
|
|
+
|
|
|
+PROCEDURE Copy (VAR dst : ARRAY OF CHAR ; src : ARRAY OF CHAR) ;
|
|
|
+VAR i : CARDINAL ;
|
|
|
+BEGIN
|
|
|
+ i := 0 ;
|
|
|
+ WHILE (i <= HIGH (dst)) AND (i <= HIGH (src)) AND (src [i] # 0C) DO
|
|
|
+ dst [i] := src [i] ;
|
|
|
+ INC (i)
|
|
|
+ END ;
|
|
|
+ IF i <= HIGH (dst) THEN
|
|
|
+ dst [i] := 0C
|
|
|
+ END
|
|
|
+END Copy ;
|
|
|
+
|
|
|
+PROCEDURE Build (i : CARDINAL ; VAR c : Cfg) ;
|
|
|
+BEGIN
|
|
|
+ Default (c) ;
|
|
|
+ IF i = 0 THEN
|
|
|
+ Copy (c.name, "ANSI")
|
|
|
+ (* ANSI is the default in TermCfg *)
|
|
|
+ ELSIF i = 1 THEN
|
|
|
+ Copy (c.name, "VT100")
|
|
|
+ (* VT100 is ANSI-compatible for everything the shell emits *)
|
|
|
+ ELSE
|
|
|
+ Copy (c.name, "VT52") ;
|
|
|
+ ParseValue ("\eH\eJ", c.clear) ;
|
|
|
+ ParseValue ("\eH", c.home) ;
|
|
|
+ ParseValue ("\eY%R%C", c.moveTo) ;
|
|
|
+ ParseValue ("\eA", c.normal) ;
|
|
|
+ ParseValue ("\eB", c.marked) ;
|
|
|
+ ParseValue ("^G", c.beep)
|
|
|
+ END
|
|
|
+END Build ;
|
|
|
+
|
|
|
+PROCEDURE Init ;
|
|
|
+VAR i : CARDINAL ;
|
|
|
+BEGIN
|
|
|
+ i := 0 ;
|
|
|
+ WHILE i < NumTerms DO
|
|
|
+ Build (i, terms [i]) ;
|
|
|
+ INC (i)
|
|
|
+ END
|
|
|
+END Init ;
|
|
|
+
|
|
|
+PROCEDURE Find (name : ARRAY OF CHAR) : CARDINAL ;
|
|
|
+(* 0..NumTerms-1, or NumTerms when not found *)
|
|
|
+VAR i : CARDINAL ;
|
|
|
+BEGIN
|
|
|
+ i := 0 ;
|
|
|
+ WHILE i < NumTerms DO
|
|
|
+ IF NameEq (terms [i].name, name) THEN
|
|
|
+ RETURN i
|
|
|
+ END ;
|
|
|
+ INC (i)
|
|
|
+ END ;
|
|
|
+ RETURN NumTerms
|
|
|
+END Find ;
|
|
|
+
|
|
|
+PROCEDURE NameEq (a, b : ARRAY OF CHAR) : BOOLEAN ;
|
|
|
+VAR i : CARDINAL ; ca, cb : CHAR ;
|
|
|
+BEGIN
|
|
|
+ i := 0 ;
|
|
|
+ LOOP
|
|
|
+ IF (i > HIGH (a)) OR (i > HIGH (b)) THEN
|
|
|
+ RETURN FALSE
|
|
|
+ END ;
|
|
|
+ ca := a [i] ; cb := b [i] ;
|
|
|
+ IF (ca >= 'a') AND (ca <= 'z') THEN ca := CHR (ORD (ca) - 32) END ;
|
|
|
+ IF (cb >= 'a') AND (cb <= 'z') THEN cb := CHR (ORD (cb) - 32) END ;
|
|
|
+ IF ca # cb THEN
|
|
|
+ RETURN FALSE
|
|
|
+ END ;
|
|
|
+ IF ca = 0C THEN
|
|
|
+ RETURN TRUE
|
|
|
+ END ;
|
|
|
+ INC (i)
|
|
|
+ END
|
|
|
+END NameEq ;
|
|
|
+
|
|
|
+PROCEDURE EncCh (ch : CHAR) ;
|
|
|
+(* the inverse of TermCfg.Decode, so the file stays readable *)
|
|
|
+VAR o : CARDINAL ;
|
|
|
+BEGIN
|
|
|
+ o := ORD (ch) ;
|
|
|
+ IF o = 27 THEN
|
|
|
+ Out ("\e")
|
|
|
+ ELSIF o = 13 THEN
|
|
|
+ Out ("\r")
|
|
|
+ ELSIF o = 10 THEN
|
|
|
+ NL
|
|
|
+ ELSIF o = 9 THEN
|
|
|
+ Out ("\t")
|
|
|
+ ELSIF o = 92 THEN
|
|
|
+ Out ("\\")
|
|
|
+ ELSIF (o > 0) AND (o < 27) THEN
|
|
|
+ Out ("^") ;
|
|
|
+ OutCh (CHR (o + 64))
|
|
|
+ ELSE
|
|
|
+ OutCh (ch)
|
|
|
+ END
|
|
|
+END EncCh ;
|
|
|
+
|
|
|
+PROCEDURE Enc (label : ARRAY OF CHAR ; s : ARRAY OF CHAR) ;
|
|
|
+VAR i : CARDINAL ;
|
|
|
+BEGIN
|
|
|
+ Out (label) ;
|
|
|
+ Out ("=") ;
|
|
|
+ i := 0 ;
|
|
|
+ WHILE (i <= HIGH (s)) AND (s [i] # 0C) DO
|
|
|
+ EncCh (s [i]) ;
|
|
|
+ INC (i)
|
|
|
+ END ;
|
|
|
+ NL
|
|
|
+END Enc ;
|
|
|
+
|
|
|
+PROCEDURE WriteCfg (path : ARRAY OF CHAR ; c : Cfg) : BOOLEAN ;
|
|
|
+VAR fd : INTEGER ;
|
|
|
+BEGIN
|
|
|
+ fd := open (ADR (path), 0241H, 420) ; (* O_WRONLY|O_CREAT|O_TRUNC, 0644 *)
|
|
|
+ IF fd < 0 THEN
|
|
|
+ Out ("tp3cfg: cannot write ") ; Out (path) ; NL ;
|
|
|
+ RETURN FALSE
|
|
|
+ END ;
|
|
|
+ outFd := fd ;
|
|
|
+ Out ("; TP3 terminal configuration - written by tp3cfg") ; NL ;
|
|
|
+ Out ("; the shell reads it as TP3.TRM; edit freely") ; NL ;
|
|
|
+ Enc ("NAME", c.name) ;
|
|
|
+ Enc ("CLEAR", c.clear) ;
|
|
|
+ Enc ("HOME", c.home) ;
|
|
|
+ Enc ("GOTO", c.moveTo) ;
|
|
|
+ Enc ("NORMAL", c.normal) ;
|
|
|
+ Enc ("MARKED", c.marked) ;
|
|
|
+ Enc ("BEEP", c.beep) ;
|
|
|
+ outFd := STDOUT ;
|
|
|
+ nout := close (fd) ;
|
|
|
+ RETURN TRUE
|
|
|
+END WriteCfg ;
|
|
|
+
|
|
|
+PROCEDURE Show (i : CARDINAL) ;
|
|
|
+BEGIN
|
|
|
+ Out ("NAME=") ; Out (terms [i].name) ; NL ;
|
|
|
+ Enc ("CLEAR", terms [i].clear) ;
|
|
|
+ Enc ("HOME", terms [i].home) ;
|
|
|
+ Enc ("GOTO", terms [i].moveTo) ;
|
|
|
+ Enc ("NORMAL", terms [i].normal) ;
|
|
|
+ Enc ("MARKED", terms [i].marked) ;
|
|
|
+ Enc ("BEEP", terms [i].beep)
|
|
|
+END Show ;
|
|
|
+
|
|
|
+(* ------------------------------------------------------------------ main *)
|
|
|
+
|
|
|
+PROCEDURE Main ;
|
|
|
+VAR i : CARDINAL ;
|
|
|
+ pick : ARRAY [0..31] OF CHAR ;
|
|
|
+ line : ARRAY [0..127] OF CHAR ;
|
|
|
+ n : LONGINT ;
|
|
|
+ k : CARDINAL ;
|
|
|
+BEGIN
|
|
|
+ Init ;
|
|
|
+ Out ("Terminals:") ;
|
|
|
+ NL ;
|
|
|
+ i := 0 ;
|
|
|
+ WHILE i < NumTerms DO
|
|
|
+ Out (" ") ; Out (terms [i].name) ; NL ;
|
|
|
+ INC (i)
|
|
|
+ END ;
|
|
|
+ Out ("Write which one to TP3.TRM? ") ;
|
|
|
+ k := 0 ;
|
|
|
+ LOOP
|
|
|
+ n := read (0, ADR (chbuf), 1) ;
|
|
|
+ IF (n # 1) OR (chbuf = CHR (10)) OR (chbuf = CHR (13)) THEN
|
|
|
+ EXIT
|
|
|
+ END ;
|
|
|
+ IF k <= HIGH (line) THEN
|
|
|
+ line [k] := chbuf ;
|
|
|
+ INC (k)
|
|
|
+ END
|
|
|
+ END ;
|
|
|
+ line [k] := 0C ;
|
|
|
+ i := Find (line) ;
|
|
|
+ IF i = NumTerms THEN
|
|
|
+ Out ("unknown terminal") ; NL
|
|
|
+ ELSE
|
|
|
+ IF WriteCfg ("TP3.TRM", terms [i]) THEN
|
|
|
+ Out ("wrote TP3.TRM (") ; Out (terms [i].name) ; Out (")") ; NL
|
|
|
+ END
|
|
|
+ END
|
|
|
+END Main ;
|
|
|
+
|
|
|
+BEGIN
|
|
|
+ outFd := STDOUT ;
|
|
|
+ Main
|
|
|
+END Tp3Cfg.
|