|
@@ -0,0 +1,179 @@
|
|
|
|
|
+IMPLEMENTATION MODULE Keys ;
|
|
|
|
|
+
|
|
|
|
|
+FROM Posix IMPORT open, read, close ;
|
|
|
|
|
+FROM SYSTEM IMPORT ADR, BYTE ;
|
|
|
|
|
+FROM TermCfg IMPORT ParseValue ;
|
|
|
|
|
+
|
|
|
|
|
+CONST
|
|
|
|
|
+ MaxFile = 4095 ;
|
|
|
|
|
+ CR = 13 ;
|
|
|
|
|
+ LF = 10 ;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE Up (ch : CHAR) : CHAR ;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF (ch >= 'a') AND (ch <= 'z') THEN
|
|
|
|
|
+ RETURN CHR (ORD (ch) - 32)
|
|
|
|
|
+ END ;
|
|
|
|
|
+ RETURN ch
|
|
|
|
|
+END Up ;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE Eq (a, b : ARRAY OF CHAR) : BOOLEAN ;
|
|
|
|
|
+VAR i : CARDINAL ;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ i := 0 ;
|
|
|
|
|
+ LOOP
|
|
|
|
|
+ IF (i > HIGH (a)) OR (i > HIGH (b)) THEN
|
|
|
|
|
+ RETURN FALSE
|
|
|
|
|
+ END ;
|
|
|
|
|
+ IF Up (a [i]) # Up (b [i]) THEN
|
|
|
|
|
+ RETURN FALSE
|
|
|
|
|
+ END ;
|
|
|
|
|
+ IF b [i] = 0C THEN
|
|
|
|
|
+ RETURN TRUE
|
|
|
|
|
+ END ;
|
|
|
|
|
+ INC (i)
|
|
|
|
|
+ END
|
|
|
|
|
+END Eq ;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE One (val : ARRAY OF CHAR ; VAR ch : CHAR ; VAR good : BOOLEAN) ;
|
|
|
|
|
+(* exactly one decoded byte *)
|
|
|
|
|
+VAR tmp : ARRAY [0..63] OF CHAR ;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ ParseValue (val, tmp) ;
|
|
|
|
|
+ IF (tmp [0] # 0C) AND (tmp [1] = 0C) THEN
|
|
|
|
|
+ ch := tmp [0] ;
|
|
|
|
|
+ good := TRUE
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ good := FALSE
|
|
|
|
|
+ END
|
|
|
|
|
+END One ;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE Apply (VAR m : Map ; name, val : ARRAY OF CHAR ; VAR bad : BOOLEAN) ;
|
|
|
|
|
+VAR good : BOOLEAN ;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ good := TRUE ;
|
|
|
|
|
+ IF Eq (name, "QUIT") THEN One (val, m.quit, good)
|
|
|
|
|
+ ELSIF Eq (name, "CANCEL") THEN One (val, m.cancel, good)
|
|
|
|
|
+ ELSIF Eq (name, "PREFIX") THEN One (val, m.prefix, good)
|
|
|
|
|
+ ELSIF Eq (name, "LITERAL") THEN One (val, m.literal, good)
|
|
|
|
|
+ ELSIF Eq (name, "WORDLEFT") THEN One (val, m.wordLeft, good)
|
|
|
|
|
+ ELSIF Eq (name, "CHARLEFT") THEN One (val, m.charLeft, good)
|
|
|
|
|
+ ELSIF Eq (name, "CHARRIGHT") THEN One (val, m.charRight, good)
|
|
|
|
|
+ ELSIF Eq (name, "WORDRIGHT") THEN One (val, m.wordRight, good)
|
|
|
|
|
+ ELSIF Eq (name, "LINEUP") THEN One (val, m.lineUp, good)
|
|
|
|
|
+ ELSIF Eq (name, "LINEDOWN") THEN One (val, m.lineDown, good)
|
|
|
|
|
+ ELSIF Eq (name, "SCROLLUP") THEN One (val, m.scrollUp, good)
|
|
|
|
|
+ ELSIF Eq (name, "SCROLLDOWN") THEN One (val, m.scrollDown, good)
|
|
|
|
|
+ ELSIF Eq (name, "PAGEUP") THEN One (val, m.pageUp, good)
|
|
|
|
|
+ ELSIF Eq (name, "PAGEDOWN") THEN One (val, m.pageDown, good)
|
|
|
|
|
+ ELSIF Eq (name, "INSERTTOGGLE") THEN One (val, m.insertToggle, good)
|
|
|
|
|
+ ELSIF Eq (name, "DELETECHAR") THEN One (val, m.deleteChar, good)
|
|
|
|
|
+ ELSIF Eq (name, "DELETELEFT") THEN One (val, m.deleteLeft, good)
|
|
|
|
|
+ ELSIF Eq (name, "DELETEWORD") THEN One (val, m.deleteWord, good)
|
|
|
|
|
+ ELSIF Eq (name, "INSERTBREAK") THEN One (val, m.insertBreak, good)
|
|
|
|
|
+ ELSIF Eq (name, "DELETELINE") THEN One (val, m.deleteLine, good)
|
|
|
|
|
+ ELSIF Eq (name, "REPEAT") THEN One (val, m.repeatLast, good)
|
|
|
|
|
+ ELSIF Eq (name, "AUTOTAB") THEN One (val, m.autoTab, good)
|
|
|
|
|
+ ELSIF Eq (name, "NEWLINE") THEN One (val, m.newLine, good)
|
|
|
|
|
+ END ;
|
|
|
|
|
+ IF NOT good THEN
|
|
|
|
|
+ bad := TRUE
|
|
|
|
|
+ END
|
|
|
|
|
+END Apply ;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE Default (VAR m : Map) ;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ m.quit := CHR (17) ; (* ^Q *)
|
|
|
|
|
+ m.cancel := CHR (21) ; (* ^U *)
|
|
|
|
|
+ m.prefix := CHR (11) ; (* ^K *)
|
|
|
|
|
+ m.literal := CHR (16) ; (* ^P *)
|
|
|
|
|
+ m.wordLeft := CHR (1) ; (* ^A *)
|
|
|
|
|
+ m.charLeft := CHR (19) ; (* ^S *)
|
|
|
|
|
+ m.charRight := CHR (4) ; (* ^D *)
|
|
|
|
|
+ m.wordRight := CHR (6) ; (* ^F *)
|
|
|
|
|
+ m.lineUp := CHR (5) ; (* ^E *)
|
|
|
|
|
+ m.lineDown := CHR (24) ; (* ^X *)
|
|
|
|
|
+ m.scrollUp := CHR (23) ; (* ^W *)
|
|
|
|
|
+ m.scrollDown := CHR (26) ; (* ^Z *)
|
|
|
|
|
+ m.pageUp := CHR (18) ; (* ^R *)
|
|
|
|
|
+ m.pageDown := CHR (3) ; (* ^C *)
|
|
|
|
|
+ m.insertToggle := CHR (22) ; (* ^V *)
|
|
|
|
|
+ m.deleteChar := CHR (7) ; (* ^G *)
|
|
|
|
|
+ m.deleteLeft := CHR (8) ; (* ^H *)
|
|
|
|
|
+ m.deleteWord := CHR (20) ; (* ^T *)
|
|
|
|
|
+ m.insertBreak := CHR (14) ; (* ^N *)
|
|
|
|
|
+ m.deleteLine := CHR (25) ; (* ^Y *)
|
|
|
|
|
+ m.repeatLast := CHR (12) ; (* ^L *)
|
|
|
|
|
+ m.autoTab := CHR (9) ; (* ^I *)
|
|
|
|
|
+ m.newLine := CHR (13) (* ^M *)
|
|
|
|
|
+END Default ;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE Load (path : ARRAY OF CHAR ; VAR m : Map ; VAR ok : BOOLEAN) ;
|
|
|
|
|
+VAR fd : INTEGER ;
|
|
|
|
|
+ k : LONGINT ;
|
|
|
|
|
+ b : BYTE ;
|
|
|
|
|
+ buf : ARRAY [0..MaxFile] OF CHAR ;
|
|
|
|
|
+ n, i, ls, le, eq, j : CARDINAL ;
|
|
|
|
|
+ name : ARRAY [0..31] OF CHAR ;
|
|
|
|
|
+ val : ARRAY [0..63] OF CHAR ;
|
|
|
|
|
+ bad : BOOLEAN ;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ Default (m) ;
|
|
|
|
|
+ ok := FALSE ;
|
|
|
|
|
+ fd := open (ADR (path), 0, 0) ;
|
|
|
|
|
+ IF fd < 0 THEN
|
|
|
|
|
+ RETURN
|
|
|
|
|
+ END ;
|
|
|
|
|
+ n := 0 ;
|
|
|
|
|
+ LOOP
|
|
|
|
|
+ k := read (fd, ADR (b), 1) ;
|
|
|
|
|
+ IF k # 1 THEN EXIT END ;
|
|
|
|
|
+ IF b = 26 THEN EXIT END ;
|
|
|
|
|
+ IF n <= HIGH (buf) THEN
|
|
|
|
|
+ buf [n] := CHR (ORD (b)) ;
|
|
|
|
|
+ INC (n)
|
|
|
|
|
+ END
|
|
|
|
|
+ END ;
|
|
|
|
|
+ k := close (fd) ;
|
|
|
|
|
+ bad := FALSE ;
|
|
|
|
|
+ i := 0 ;
|
|
|
|
|
+ WHILE i < n DO
|
|
|
|
|
+ ls := i ;
|
|
|
|
|
+ WHILE (i < n) AND (buf [i] # CHR (CR)) AND (buf [i] # CHR (LF)) DO
|
|
|
|
|
+ INC (i)
|
|
|
|
|
+ END ;
|
|
|
|
|
+ le := i ;
|
|
|
|
|
+ WHILE (i < n) AND ((buf [i] = CHR (CR)) OR (buf [i] = CHR (LF))) DO
|
|
|
|
|
+ INC (i)
|
|
|
|
|
+ END ;
|
|
|
|
|
+ WHILE (ls < le) AND ((buf [ls] = ' ') OR (buf [ls] = CHR (9))) DO
|
|
|
|
|
+ INC (ls)
|
|
|
|
|
+ END ;
|
|
|
|
|
+ WHILE (le > ls) AND ((buf [le - 1] = ' ') OR (buf [le - 1] = CHR (9))) DO
|
|
|
|
|
+ DEC (le)
|
|
|
|
|
+ END ;
|
|
|
|
|
+ IF (ls < le) AND (buf [ls] # ';') THEN
|
|
|
|
|
+ eq := ls ;
|
|
|
|
|
+ WHILE (eq < le) AND (buf [eq] # '=') DO INC (eq) END ;
|
|
|
|
|
+ IF eq = le THEN
|
|
|
|
|
+ bad := TRUE
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ j := 0 ;
|
|
|
|
|
+ WHILE (ls < eq) AND (j <= HIGH (name)) DO
|
|
|
|
|
+ name [j] := buf [ls] ; INC (j) ; INC (ls)
|
|
|
|
|
+ END ;
|
|
|
|
|
+ name [j] := 0C ;
|
|
|
|
|
+ INC (eq) ;
|
|
|
|
|
+ j := 0 ;
|
|
|
|
|
+ WHILE (eq < le) AND (j <= HIGH (val)) DO
|
|
|
|
|
+ val [j] := buf [eq] ; INC (j) ; INC (eq)
|
|
|
|
|
+ END ;
|
|
|
|
|
+ val [j] := 0C ;
|
|
|
|
|
+ Apply (m, name, val, bad)
|
|
|
|
|
+ END
|
|
|
|
|
+ END
|
|
|
|
|
+ END ;
|
|
|
|
|
+ ok := NOT bad
|
|
|
|
|
+END Load ;
|
|
|
|
|
+
|
|
|
|
|
+END Keys.
|