Keys.mod 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. IMPLEMENTATION MODULE Keys ;
  2. FROM Posix IMPORT open, read, close ;
  3. FROM SYSTEM IMPORT ADR, BYTE ;
  4. FROM TermCfg IMPORT ParseValue ;
  5. CONST
  6. MaxFile = 4095 ;
  7. CR = 13 ;
  8. LF = 10 ;
  9. PROCEDURE Up (ch : CHAR) : CHAR ;
  10. BEGIN
  11. IF (ch >= 'a') AND (ch <= 'z') THEN
  12. RETURN CHR (ORD (ch) - 32)
  13. END ;
  14. RETURN ch
  15. END Up ;
  16. PROCEDURE Eq (a, b : ARRAY OF CHAR) : BOOLEAN ;
  17. VAR i : CARDINAL ;
  18. BEGIN
  19. i := 0 ;
  20. LOOP
  21. IF (i > HIGH (a)) OR (i > HIGH (b)) THEN
  22. RETURN FALSE
  23. END ;
  24. IF Up (a [i]) # Up (b [i]) THEN
  25. RETURN FALSE
  26. END ;
  27. IF b [i] = 0C THEN
  28. RETURN TRUE
  29. END ;
  30. INC (i)
  31. END
  32. END Eq ;
  33. PROCEDURE One (val : ARRAY OF CHAR ; VAR ch : CHAR ; VAR good : BOOLEAN) ;
  34. (* exactly one decoded byte *)
  35. VAR tmp : ARRAY [0..63] OF CHAR ;
  36. BEGIN
  37. ParseValue (val, tmp) ;
  38. IF (tmp [0] # 0C) AND (tmp [1] = 0C) THEN
  39. ch := tmp [0] ;
  40. good := TRUE
  41. ELSE
  42. good := FALSE
  43. END
  44. END One ;
  45. PROCEDURE Apply (VAR m : Map ; name, val : ARRAY OF CHAR ; VAR bad : BOOLEAN) ;
  46. VAR good : BOOLEAN ;
  47. BEGIN
  48. good := TRUE ;
  49. IF Eq (name, "QUIT") THEN One (val, m.quit, good)
  50. ELSIF Eq (name, "CANCEL") THEN One (val, m.cancel, good)
  51. ELSIF Eq (name, "PREFIX") THEN One (val, m.prefix, good)
  52. ELSIF Eq (name, "LITERAL") THEN One (val, m.literal, good)
  53. ELSIF Eq (name, "WORDLEFT") THEN One (val, m.wordLeft, good)
  54. ELSIF Eq (name, "CHARLEFT") THEN One (val, m.charLeft, good)
  55. ELSIF Eq (name, "CHARRIGHT") THEN One (val, m.charRight, good)
  56. ELSIF Eq (name, "WORDRIGHT") THEN One (val, m.wordRight, good)
  57. ELSIF Eq (name, "LINEUP") THEN One (val, m.lineUp, good)
  58. ELSIF Eq (name, "LINEDOWN") THEN One (val, m.lineDown, good)
  59. ELSIF Eq (name, "SCROLLUP") THEN One (val, m.scrollUp, good)
  60. ELSIF Eq (name, "SCROLLDOWN") THEN One (val, m.scrollDown, good)
  61. ELSIF Eq (name, "PAGEUP") THEN One (val, m.pageUp, good)
  62. ELSIF Eq (name, "PAGEDOWN") THEN One (val, m.pageDown, good)
  63. ELSIF Eq (name, "INSERTTOGGLE") THEN One (val, m.insertToggle, good)
  64. ELSIF Eq (name, "DELETECHAR") THEN One (val, m.deleteChar, good)
  65. ELSIF Eq (name, "DELETELEFT") THEN One (val, m.deleteLeft, good)
  66. ELSIF Eq (name, "DELETEWORD") THEN One (val, m.deleteWord, good)
  67. ELSIF Eq (name, "INSERTBREAK") THEN One (val, m.insertBreak, good)
  68. ELSIF Eq (name, "DELETELINE") THEN One (val, m.deleteLine, good)
  69. ELSIF Eq (name, "REPEAT") THEN One (val, m.repeatLast, good)
  70. ELSIF Eq (name, "AUTOTAB") THEN One (val, m.autoTab, good)
  71. ELSIF Eq (name, "NEWLINE") THEN One (val, m.newLine, good)
  72. END ;
  73. IF NOT good THEN
  74. bad := TRUE
  75. END
  76. END Apply ;
  77. PROCEDURE Default (VAR m : Map) ;
  78. BEGIN
  79. m.quit := CHR (17) ; (* ^Q *)
  80. m.cancel := CHR (21) ; (* ^U *)
  81. m.prefix := CHR (11) ; (* ^K *)
  82. m.literal := CHR (16) ; (* ^P *)
  83. m.wordLeft := CHR (1) ; (* ^A *)
  84. m.charLeft := CHR (19) ; (* ^S *)
  85. m.charRight := CHR (4) ; (* ^D *)
  86. m.wordRight := CHR (6) ; (* ^F *)
  87. m.lineUp := CHR (5) ; (* ^E *)
  88. m.lineDown := CHR (24) ; (* ^X *)
  89. m.scrollUp := CHR (23) ; (* ^W *)
  90. m.scrollDown := CHR (26) ; (* ^Z *)
  91. m.pageUp := CHR (18) ; (* ^R *)
  92. m.pageDown := CHR (3) ; (* ^C *)
  93. m.insertToggle := CHR (22) ; (* ^V *)
  94. m.deleteChar := CHR (7) ; (* ^G *)
  95. m.deleteLeft := CHR (8) ; (* ^H *)
  96. m.deleteWord := CHR (20) ; (* ^T *)
  97. m.insertBreak := CHR (14) ; (* ^N *)
  98. m.deleteLine := CHR (25) ; (* ^Y *)
  99. m.repeatLast := CHR (12) ; (* ^L *)
  100. m.autoTab := CHR (9) ; (* ^I *)
  101. m.newLine := CHR (13) (* ^M *)
  102. END Default ;
  103. PROCEDURE Load (path : ARRAY OF CHAR ; VAR m : Map ; VAR ok : BOOLEAN) ;
  104. VAR fd : INTEGER ;
  105. k : LONGINT ;
  106. b : BYTE ;
  107. buf : ARRAY [0..MaxFile] OF CHAR ;
  108. n, i, ls, le, eq, j : CARDINAL ;
  109. name : ARRAY [0..31] OF CHAR ;
  110. val : ARRAY [0..63] OF CHAR ;
  111. bad : BOOLEAN ;
  112. BEGIN
  113. Default (m) ;
  114. ok := FALSE ;
  115. fd := open (ADR (path), 0, 0) ;
  116. IF fd < 0 THEN
  117. RETURN
  118. END ;
  119. n := 0 ;
  120. LOOP
  121. k := read (fd, ADR (b), 1) ;
  122. IF k # 1 THEN EXIT END ;
  123. IF b = 26 THEN EXIT END ;
  124. IF n <= HIGH (buf) THEN
  125. buf [n] := CHR (ORD (b)) ;
  126. INC (n)
  127. END
  128. END ;
  129. k := close (fd) ;
  130. bad := FALSE ;
  131. i := 0 ;
  132. WHILE i < n DO
  133. ls := i ;
  134. WHILE (i < n) AND (buf [i] # CHR (CR)) AND (buf [i] # CHR (LF)) DO
  135. INC (i)
  136. END ;
  137. le := i ;
  138. WHILE (i < n) AND ((buf [i] = CHR (CR)) OR (buf [i] = CHR (LF))) DO
  139. INC (i)
  140. END ;
  141. WHILE (ls < le) AND ((buf [ls] = ' ') OR (buf [ls] = CHR (9))) DO
  142. INC (ls)
  143. END ;
  144. WHILE (le > ls) AND ((buf [le - 1] = ' ') OR (buf [le - 1] = CHR (9))) DO
  145. DEC (le)
  146. END ;
  147. IF (ls < le) AND (buf [ls] # ';') THEN
  148. eq := ls ;
  149. WHILE (eq < le) AND (buf [eq] # '=') DO INC (eq) END ;
  150. IF eq = le THEN
  151. bad := TRUE
  152. ELSE
  153. j := 0 ;
  154. WHILE (ls < eq) AND (j <= HIGH (name)) DO
  155. name [j] := buf [ls] ; INC (j) ; INC (ls)
  156. END ;
  157. name [j] := 0C ;
  158. INC (eq) ;
  159. j := 0 ;
  160. WHILE (eq < le) AND (j <= HIGH (val)) DO
  161. val [j] := buf [eq] ; INC (j) ; INC (eq)
  162. END ;
  163. val [j] := 0C ;
  164. Apply (m, name, val, bad)
  165. END
  166. END
  167. END ;
  168. ok := NOT bad
  169. END Load ;
  170. END Keys.