DEFINITION MODULE TermCfg ; (* Terminal escape sequences, loaded from a TEXT file. This is the whole point of the module: the shell never patches its own binary (TINST's approach); it reads a configuration at startup. FILE FORMAT - plain text, one KEY=value per line: ; a comment NAME=ANSI CLEAR=\e[2J\e[H HOME=\e[H GOTO=\e[%r;%cH NORMAL=\e[0m MARKED=\e[1;7m BEEP=^G `;' at the start of a line starts a comment. Blanks around the key and value are ignored. The key is case-insensitive. Values are DECODED, so the file stays readable and editable: \e or \E ESC (27) \r CR (13) \n LF (10) \t TAB (9) \\ a backslash ^X control-X (X uppercased, minus 64), e.g. ^G = BEL (7) GOTO may contain %r and %c; the shell substitutes the decimal row and column there (1-based, as TP3's GotoXY is). %% is a literal percent. A missing file, or a line with no '=', sets ok to FALSE and leaves the defaults (and anything read before the bad line) in place - never a silently half-written screen. *) CONST MaxSeq = 63 ; MaxName = 31 ; TYPE Cfg = RECORD name : ARRAY [0..MaxName] OF CHAR ; clear : ARRAY [0..MaxSeq] OF CHAR ; home : ARRAY [0..MaxSeq] OF CHAR ; moveTo : ARRAY [0..MaxSeq] OF CHAR ; (* GOTO: %r, %c *) normal : ARRAY [0..MaxSeq] OF CHAR ; marked : ARRAY [0..MaxSeq] OF CHAR ; beep : ARRAY [0..MaxSeq] OF CHAR ; END ; PROCEDURE ParseValue (src : ARRAY OF CHAR ; VAR dst : ARRAY OF CHAR) ; (* decode one value's escapes into dst: the same rules as a file's value, so a caller building a Cfg in memory spells it exactly as the file would. *) PROCEDURE Default (VAR c : Cfg) ; (* the ANSI set - what the shell used before there was a config file *) PROCEDURE Load (path : ARRAY OF CHAR ; VAR c : Cfg ; VAR ok : BOOLEAN) ; (* Default(c), then every KEY=value in path. ok is FALSE if the file could not be opened or a line is malformed. *) END TermCfg.