Browse Source

work in progress : step 39

Eric Streit 2 days ago
commit
ccc0f62770
100 changed files with 3118 additions and 0 deletions
  1. 9 0
      Done/step1/Makefile
  2. BIN
      Done/step1/editor
  3. 9 0
      Done/step1/editor.mod
  4. BIN
      Done/step1/kilo
  5. 3 0
      Done/step1/kilo.c
  6. 9 0
      Done/step10/Makefile
  7. BIN
      Done/step10/editor
  8. 65 0
      Done/step10/editor.mod
  9. BIN
      Done/step10/kilo
  10. 32 0
      Done/step10/kilo.c
  11. 9 0
      Done/step11/Makefile
  12. BIN
      Done/step11/editor
  13. 66 0
      Done/step11/editor.mod
  14. BIN
      Done/step11/kilo
  15. 32 0
      Done/step11/kilo.c
  16. 9 0
      Done/step12/Makefile
  17. BIN
      Done/step12/editor
  18. 67 0
      Done/step12/editor.mod
  19. BIN
      Done/step12/kilo
  20. 32 0
      Done/step12/kilo.c
  21. 9 0
      Done/step13/Makefile
  22. BIN
      Done/step13/editor
  23. 68 0
      Done/step13/editor.mod
  24. BIN
      Done/step13/kilo
  25. 33 0
      Done/step13/kilo.c
  26. 9 0
      Done/step14/Makefile
  27. BIN
      Done/step14/editor
  28. 72 0
      Done/step14/editor.mod
  29. BIN
      Done/step14/kilo
  30. 33 0
      Done/step14/kilo.c
  31. 9 0
      Done/step15/Makefile
  32. BIN
      Done/step15/editor
  33. 77 0
      Done/step15/editor.mod
  34. BIN
      Done/step15/kilo
  35. 34 0
      Done/step15/kilo.c
  36. 9 0
      Done/step16/Makefile
  37. BIN
      Done/step16/editor
  38. 88 0
      Done/step16/editor.mod
  39. BIN
      Done/step16/kilo
  40. 38 0
      Done/step16/kilo.c
  41. 9 0
      Done/step17/Makefile
  42. BIN
      Done/step17/editor
  43. 93 0
      Done/step17/editor.mod
  44. BIN
      Done/step17/kilo
  45. 43 0
      Done/step17/kilo.c
  46. 12 0
      Done/step18/Makefile
  47. 17 0
      Done/step18/cmakeraw.txt
  48. 16 0
      Done/step18/cmakeraw.txt~
  49. 17 0
      Done/step18/doc.txt
  50. 37 0
      Done/step18/doc1.txt
  51. 32 0
      Done/step18/doc1.txt~
  52. BIN
      Done/step18/doc2
  53. 58 0
      Done/step18/doc2.c
  54. 58 0
      Done/step18/doc2.txt
  55. 58 0
      Done/step18/doc2.txt~
  56. BIN
      Done/step18/doc3
  57. 51 0
      Done/step18/doc3.c
  58. BIN
      Done/step18/editor
  59. 103 0
      Done/step18/editor.mod
  60. BIN
      Done/step18/editor1
  61. 111 0
      Done/step18/editor1.mod
  62. BIN
      Done/step18/kilo
  63. 52 0
      Done/step18/kilo.c
  64. 9 0
      Done/step19/Makefile
  65. 110 0
      Done/step19/editor.mod
  66. 55 0
      Done/step19/kilo.c
  67. 9 0
      Done/step2/Makefile
  68. BIN
      Done/step2/editor
  69. 19 0
      Done/step2/editor.mod
  70. BIN
      Done/step2/kilo
  71. 6 0
      Done/step2/kilo.c
  72. 9 0
      Done/step20/Makefile
  73. BIN
      Done/step20/editor
  74. 122 0
      Done/step20/editor.mod
  75. BIN
      Done/step20/kilo
  76. 65 0
      Done/step20/kilo.c
  77. 9 0
      Done/step21/Makefile
  78. BIN
      Done/step21/editor
  79. 139 0
      Done/step21/editor.mod
  80. BIN
      Done/step21/kilo
  81. 72 0
      Done/step21/kilo.c
  82. 9 0
      Done/step22/Makefile
  83. BIN
      Done/step22/editor
  84. 156 0
      Done/step22/editor.mod
  85. BIN
      Done/step22/kilo
  86. 73 0
      Done/step22/kilo.c
  87. 9 0
      Done/step23/Makefile
  88. BIN
      Done/step23/editor
  89. 157 0
      Done/step23/editor.mod
  90. BIN
      Done/step23/kilo
  91. 75 0
      Done/step23/kilo.c
  92. 9 0
      Done/step24/Makefile
  93. BIN
      Done/step24/editor
  94. 157 0
      Done/step24/editor.mod
  95. BIN
      Done/step24/kilo
  96. 75 0
      Done/step24/kilo.c
  97. 9 0
      Done/step25/Makefile
  98. BIN
      Done/step25/editor
  99. 177 0
      Done/step25/editor.mod
  100. BIN
      Done/step25/kilo

+ 9 - 0
Done/step1/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step1/editor


+ 9 - 0
Done/step1/editor.mod

@@ -0,0 +1,9 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Chapter 2 *)
+
+BEGIN
+    
+END editor.

BIN
Done/step1/kilo


+ 3 - 0
Done/step1/kilo.c

@@ -0,0 +1,3 @@
+int main() {
+  return 0;
+}

+ 9 - 0
Done/step10/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step10/editor


+ 65 - 0
Done/step10/editor.mod

@@ -0,0 +1,65 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 10 *)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc;
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios);
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw);
+    END enableRawMode;
+
+BEGIN
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    result := termios.tcgetattr(FIO.StdIn, thetermios);
+    result := termios.tcgetattr(FIO.StdIn, raw);
+
+    enableRawMode;
+    p := SYSTEM.ADR(c);
+    WHILE (FIO.ReadNBytes(FIO.StdIn,1,p) = 1) AND (c <> "q") DO
+        IF CharClass.IsControl(c) THEN
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteLn;
+        ELSE
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteString(" ('");
+            STextIO.WriteChar(c);
+            STextIO.WriteString(" ')");
+            STextIO.WriteLn;
+        END;
+    END;
+END editor.

BIN
Done/step10/kilo


+ 32 - 0
Done/step10/kilo.c

@@ -0,0 +1,32 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+struct termios orig_termios;
+
+void disableRawMode() {
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
+}
+
+void enableRawMode() {
+  tcgetattr(STDIN_FILENO, &orig_termios);
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(IXON);
+  raw.c_lflag &= ~(ECHO | ICANON | ISIG);
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
+}
+
+int main() {
+  enableRawMode();
+  char c;
+  while (read(STDIN_FILENO, &c, 1) == 1 && c != 'q') {
+    if (iscntrl(c)) {
+      printf("%d\n", c);
+    } else {
+      printf("%d ('%c')\n", c, c);
+    }
+  }
+  return 0;
+}

+ 9 - 0
Done/step11/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step11/editor


+ 66 - 0
Done/step11/editor.mod

@@ -0,0 +1,66 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 11 *)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc;
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios);
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw);
+    END enableRawMode;
+
+BEGIN
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    result := termios.tcgetattr(FIO.StdIn, thetermios);
+    result := termios.tcgetattr(FIO.StdIn, raw);
+
+    enableRawMode;
+    p := SYSTEM.ADR(c);
+    WHILE (FIO.ReadNBytes(FIO.StdIn,1,p) = 1) AND (c <> "q") DO
+        IF CharClass.IsControl(c) THEN
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteLn;
+        ELSE
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteString(" ('");
+            STextIO.WriteChar(c);
+            STextIO.WriteString(" ')");
+            STextIO.WriteLn;
+        END;
+    END;
+END editor.

BIN
Done/step11/kilo


+ 32 - 0
Done/step11/kilo.c

@@ -0,0 +1,32 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+struct termios orig_termios;
+
+void disableRawMode() {
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
+}
+
+void enableRawMode() {
+  tcgetattr(STDIN_FILENO, &orig_termios);
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(IXON);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
+}
+
+int main() {
+  enableRawMode();
+  char c;
+  while (read(STDIN_FILENO, &c, 1) == 1 && c != 'q') {
+    if (iscntrl(c)) {
+      printf("%d\n", c);
+    } else {
+      printf("%d ('%c')\n", c, c);
+    }
+  }
+  return 0;
+}

+ 9 - 0
Done/step12/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step12/editor


+ 67 - 0
Done/step12/editor.mod

@@ -0,0 +1,67 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 12 *)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc;
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios);
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw);
+    END enableRawMode;
+
+BEGIN
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    result := termios.tcgetattr(FIO.StdIn, thetermios);
+    result := termios.tcgetattr(FIO.StdIn, raw);
+
+    enableRawMode;
+    p := SYSTEM.ADR(c);
+    WHILE (FIO.ReadNBytes(FIO.StdIn,1,p) = 1) AND (c <> "q") DO
+        IF ORD(c) > 32 THEN
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteString(" ('");
+            STextIO.WriteChar(c);
+            STextIO.WriteString(" ')");
+            STextIO.WriteLn;
+        ELSE
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteLn;
+        END;
+    END;
+END editor.

BIN
Done/step12/kilo


+ 32 - 0
Done/step12/kilo.c

@@ -0,0 +1,32 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+struct termios orig_termios;
+
+void disableRawMode() {
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
+}
+
+void enableRawMode() {
+  tcgetattr(STDIN_FILENO, &orig_termios);
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(ICRNL | IXON);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
+}
+
+int main() {
+  enableRawMode();
+  char c;
+  while (read(STDIN_FILENO, &c, 1) == 1 && c != 'q') {
+    if (iscntrl(c)) {
+      printf("%d\n", c);
+    } else {
+      printf("%d ('%c')\n", c, c);
+    }
+  }
+  return 0;
+}

+ 9 - 0
Done/step13/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step13/editor


+ 68 - 0
Done/step13/editor.mod

@@ -0,0 +1,68 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 13 *)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc;
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios);
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.opost, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw);
+    END enableRawMode;
+
+BEGIN
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    result := termios.tcgetattr(FIO.StdIn, thetermios);
+    result := termios.tcgetattr(FIO.StdIn, raw);
+
+    enableRawMode;
+    p := SYSTEM.ADR(c);
+    WHILE (FIO.ReadNBytes(FIO.StdIn,1,p) = 1) AND (c <> "q") DO
+        IF ORD(c) > 32 THEN
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteString(" ('");
+            STextIO.WriteChar(c);
+            STextIO.WriteString(" ')");
+            STextIO.WriteLn;
+        ELSE
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteLn;
+        END;
+    END;
+END editor.

BIN
Done/step13/kilo


+ 33 - 0
Done/step13/kilo.c

@@ -0,0 +1,33 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+struct termios orig_termios;
+
+void disableRawMode() {
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
+}
+
+void enableRawMode() {
+  tcgetattr(STDIN_FILENO, &orig_termios);
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(ICRNL | IXON);
+  raw.c_oflag &= ~(OPOST);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
+}
+
+int main() {
+  enableRawMode();
+  char c;
+  while (read(STDIN_FILENO, &c, 1) == 1 && c != 'q') {
+    if (iscntrl(c)) {
+      printf("%d\n", c);
+    } else {
+      printf("%d ('%c')\n", c, c);
+    }
+  }
+  return 0;
+}

+ 9 - 0
Done/step14/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step14/editor


+ 72 - 0
Done/step14/editor.mod

@@ -0,0 +1,72 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 14 *)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc;
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios);
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.opost, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw);
+    END enableRawMode;
+
+BEGIN
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    result := termios.tcgetattr(FIO.StdIn, thetermios);
+    result := termios.tcgetattr(FIO.StdIn, raw);
+
+    enableRawMode;
+    p := SYSTEM.ADR(c);
+    WHILE (FIO.ReadNBytes(FIO.StdIn,1,p) = 1) AND (c <> "q") DO
+        IF ORD(c) > 32 THEN
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteString(" ('");
+            STextIO.WriteChar(c);
+            STextIO.WriteString(" ')");
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13));
+        ELSE
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteLn;
+            (* found how to solve the problem ....*)
+            (* we have to send chr(13) to get the control chars to be printed out *)
+            STextIO.WriteChar(CHR(13));
+        END;
+    END;
+END editor.

BIN
Done/step14/kilo


+ 33 - 0
Done/step14/kilo.c

@@ -0,0 +1,33 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+struct termios orig_termios;
+
+void disableRawMode() {
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
+}
+
+void enableRawMode() {
+  tcgetattr(STDIN_FILENO, &orig_termios);
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(ICRNL | IXON);
+  raw.c_oflag &= ~(OPOST);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
+}
+
+int main() {
+  enableRawMode();
+  char c;
+  while (read(STDIN_FILENO, &c, 1) == 1 && c != 'q') {
+    if (iscntrl(c)) {
+      printf("%d\r\n", c);
+    } else {
+      printf("%d ('%c')\r\n", c, c);
+    }
+  }
+  return 0;
+}

+ 9 - 0
Done/step15/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step15/editor


+ 77 - 0
Done/step15/editor.mod

@@ -0,0 +1,77 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 15 *)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc;
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios);
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.opost, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.ibrkint, FALSE);
+        bresult := termios.SetFlag(raw,termios.inpck, FALSE);
+        bresult := termios.SetFlag(raw,termios.istrip, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.cs8, TRUE);
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw);
+    END enableRawMode;
+
+BEGIN
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    result := termios.tcgetattr(FIO.StdIn, thetermios);
+    result := termios.tcgetattr(FIO.StdIn, raw);
+
+    enableRawMode;
+    p := SYSTEM.ADR(c);
+    WHILE (FIO.ReadNBytes(FIO.StdIn,1,p) = 1) AND (c <> "q") DO
+        IF ORD(c) > 32 THEN
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteString(" ('");
+            STextIO.WriteChar(c);
+            STextIO.WriteString(" ')");
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13));
+        ELSE
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteLn;
+            (* found how to solve the problem ....*)
+            (* we have to send chr(13) to get the control chars to be printed out *)
+            STextIO.WriteChar(CHR(13));
+        END;
+    END;
+END editor.

BIN
Done/step15/kilo


+ 34 - 0
Done/step15/kilo.c

@@ -0,0 +1,34 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+struct termios orig_termios;
+
+void disableRawMode() {
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
+}
+
+void enableRawMode() {
+  tcgetattr(STDIN_FILENO, &orig_termios);
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+  raw.c_oflag &= ~(OPOST);
+  raw.c_cflag |= (CS8);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
+}
+
+int main() {
+  enableRawMode();
+  char c;
+  while (read(STDIN_FILENO, &c, 1) == 1 && c != 'q') {
+    if (iscntrl(c)) {
+      printf("%d\r\n", c);
+    } else {
+      printf("%d ('%c')\r\n", c, c);
+    }
+  }
+  return 0;
+}

+ 9 - 0
Done/step16/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step16/editor


+ 88 - 0
Done/step16/editor.mod

@@ -0,0 +1,88 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 16 *)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc;
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+    number : CARDINAL;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios);
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.opost, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.ibrkint, FALSE);
+        bresult := termios.SetFlag(raw,termios.inpck, FALSE);
+        bresult := termios.SetFlag(raw,termios.istrip, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.cs8, TRUE);
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw);
+
+        (* PROCEDURE SetChar (t: TERMIOS; c: ControlChar; ch: CHAR) : BOOLEAN ; *)
+        (* termios.vmin := 0;
+        termios.vtime := 1; *)
+        bresult := termios.SetChar(raw,termios.vmin,CHR(0));
+        bresult := termios.SetChar(raw,termios.vtime,CHR(1));
+    END enableRawMode;
+
+BEGIN
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    result := termios.tcgetattr(FIO.StdIn, thetermios);
+    result := termios.tcgetattr(FIO.StdIn, raw);
+
+    enableRawMode;
+    p := SYSTEM.ADR(c);
+
+    LOOP
+        c := CHR(0);
+        number := (FIO.ReadNBytes(FIO.StdIn,1,p));
+        IF ORD(c) < 32 THEN
+             NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13));
+        ELSE
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteString(" ('");
+            STextIO.WriteChar(c);
+            STextIO.WriteString(" ')");
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13));
+        END;
+        IF c = "q" THEN
+            EXIT
+        END;
+    END;
+END editor.

BIN
Done/step16/kilo


+ 38 - 0
Done/step16/kilo.c

@@ -0,0 +1,38 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+struct termios orig_termios;
+
+void disableRawMode() {
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
+}
+
+void enableRawMode() {
+  tcgetattr(STDIN_FILENO, &orig_termios);
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+  raw.c_oflag &= ~(OPOST);
+  raw.c_cflag |= (CS8);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
+  raw.c_cc[VMIN] = 0;
+  raw.c_cc[VTIME] = 1;
+}
+
+int main() {
+  enableRawMode();
+  while (1) {
+    char c = '\0';
+    read(STDIN_FILENO, &c, 1);
+    if (iscntrl(c)) {
+      printf("%d\r\n", c);
+    } else {
+      printf("%d ('%c')\r\n", c, c);
+    }
+    if (c == 'q') break;
+  }
+  return 0;
+}

+ 9 - 0
Done/step17/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step17/editor


+ 93 - 0
Done/step17/editor.mod

@@ -0,0 +1,93 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 17 *)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc;
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+    number : CARDINAL;
+
+    PROCEDURE die (s : ARRAY OF CHAR);
+    BEGIN
+        libc.perror(s);
+    END die;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios);
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.opost, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.ibrkint, FALSE);
+        bresult := termios.SetFlag(raw,termios.inpck, FALSE);
+        bresult := termios.SetFlag(raw,termios.istrip, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.cs8, TRUE);
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw);
+
+        (* PROCEDURE SetChar (t: TERMIOS; c: ControlChar; ch: CHAR) : BOOLEAN ; *)
+        (* termios.vmin := 0;
+        termios.vtime := 1; *)
+        bresult := termios.SetChar(raw,termios.vmin,CHR(0));
+        bresult := termios.SetChar(raw,termios.vtime,CHR(1));
+    END enableRawMode;
+
+BEGIN
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    result := termios.tcgetattr(FIO.StdIn, thetermios);
+    result := termios.tcgetattr(FIO.StdIn, raw);
+
+    enableRawMode;
+    p := SYSTEM.ADR(c);
+
+    LOOP
+        c := CHR(0);
+        number := (FIO.ReadNBytes(FIO.StdIn,1,p));
+        IF ORD(c) < 32 THEN
+             NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13));
+        ELSE
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteString(" ('");
+            STextIO.WriteChar(c);
+            STextIO.WriteString(" ')");
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13));
+        END;
+        IF c = "q" THEN
+            EXIT
+        END;
+    END;
+END editor.

BIN
Done/step17/kilo


+ 43 - 0
Done/step17/kilo.c

@@ -0,0 +1,43 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+struct termios orig_termios;
+
+void die(const char *s) {
+  perror(s);
+  exit(1);
+}
+
+void disableRawMode() {
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
+}
+
+void enableRawMode() {
+  tcgetattr(STDIN_FILENO, &orig_termios);
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+  raw.c_oflag &= ~(OPOST);
+  raw.c_cflag |= (CS8);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
+  raw.c_cc[VMIN] = 0;
+  raw.c_cc[VTIME] = 1;
+}
+
+int main() {
+  enableRawMode();
+  while (1) {
+    char c = '\0';
+    read(STDIN_FILENO, &c, 1);
+    if (iscntrl(c)) {
+      printf("%d\r\n", c);
+    } else {
+      printf("%d ('%c')\r\n", c, c);
+    }
+    if (c == 'q') break;
+  }
+  return 0;
+}

+ 12 - 0
Done/step18/Makefile

@@ -0,0 +1,12 @@
+all: kilo editor editor1
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod
+
+editor1: editor1.mod
+	gm2 -fiso -o editor1 editor1.mod

+ 17 - 0
Done/step18/cmakeraw.txt

@@ -0,0 +1,17 @@
+termios-p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|);
+termios-p->c_oflag &= ~OPOST;
+termios-p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+termios-p->c_cflag &= ~(CSIZE|PARENB);
+termios-p->c_cflag |= CS8;
+
+****************************
+
+    tnew.c_iflag &= ~( (T_XON == NULL || *T_XON == NUL ? IXON : 0));
+	tnew.c_lflag &= ~( ECHOE | );
+	//
+	tnew.c_oflag &= ~(ONLCR | XTABS);
+	
+	tnew.c_oflag &= ~(ONLCR | TAB3);
+	
+	tnew.c_oflag &= ~ONLCR;
+

+ 16 - 0
Done/step18/cmakeraw.txt~

@@ -0,0 +1,16 @@
+termios-p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|);
+termios-p->c_oflag &= ~OPOST;
+termios-p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+termios-p->c_cflag &= ~(CSIZE|PARENB);
+termios-p->c_cflag |= CS8;
+
+
+    tnew.c_iflag &= ~( (T_XON == NULL || *T_XON == NUL ? IXON : 0));
+	tnew.c_lflag &= ~( ECHOE | );
+	//
+	tnew.c_oflag &= ~(ONLCR | XTABS);
+	
+	tnew.c_oflag &= ~(ONLCR | TAB3);
+	
+	tnew.c_oflag &= ~ONLCR;
+

+ 17 - 0
Done/step18/doc.txt

@@ -0,0 +1,17 @@
+What cfmakeraw actually does
+Behind the scenes, cfmakeraw performs the following bitwise operations on your termios struct to strip all formatting: 
+
+    Input modes (c_iflag): Disables flow control and character translations (e.g., IGNBRK, BRKINT, PARMRK, ISTRIP, INLCR, IGNCR, ICRNL, IXON).
+    Output modes (c_oflag): Disables output processing (e.g., OPOST).
+    Local modes (c_lflag): Disables echoing, line-based input (ICANON), and signals (ISIG).
+    Control modes (c_cflag): Clears the character size mask and sets it strictly to 8 data bits per byte (CS8). 
+
+Important Next Steps for Raw Mode
+When you use cfmakeraw, it strips out timeout configurations (like VMIN and VTIME), which you usually need to manage how your blocking/non-blocking reads operate. You should manually set these after calling cfmakeraw to prevent your program from freezing indefinitely or eating up CPU cycles. 
+For more reference, check out the Linux Foundation cfmakeraw documentation or review standard FreeBSD Manual Pages.
+If you'd like, tell me:
+
+    What type of device are you communicating with? (e.g., Arduino, GPS module, modem)
+    Are you planning to use blocking or non-blocking reads?
+
+I can help refine this example to match your specific use case.

+ 37 - 0
Done/step18/doc1.txt

@@ -0,0 +1,37 @@
+    static struct termios told;
+	   struct termios tnew;
+
+	mch_tcgetattr(read_cmd_fd, &told);
+
+    tnew = told;
+    if (tmode == TMODE_RAW)
+    {
+	tnew.c_iflag &= ~(ICRNL | (T_XON == NULL || *T_XON == NUL ? IXON : 0));
+	tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE | IEXTEN);
+	//
+	tnew.c_oflag &= ~(ONLCR | XTABS);
+	
+	tnew.c_oflag &= ~(ONLCR | TAB3);
+	
+	tnew.c_oflag &= ~ONLCR;
+	//
+	
+	tnew.c_cc[VMIN] = 1;		// return after 1 char
+	tnew.c_cc[VTIME] = 0;		// don't wait
+    }
+    else if (tmode == TMODE_SLEEP)
+    {
+	tnew.c_lflag &= ~(ICANON | ECHO);
+	tnew.c_cc[VMIN] = 1;		// return after 1 char
+	tnew.c_cc[VTIME] = 0;		// don't wait
+    }
+
+    {
+	int	n = 10;
+
+	// A signal may cause tcsetattr() to fail (e.g., SIGCONT).  Retry a
+	// few times.
+	while (tcsetattr(read_cmd_fd, TCSANOW, &tnew) == -1
+						   && errno == EINTR && n > 0)
+	    --n;
+    }

+ 32 - 0
Done/step18/doc1.txt~

@@ -0,0 +1,32 @@
+    static struct termios told;
+	   struct termios tnew;
+
+	mch_tcgetattr(read_cmd_fd, &told);
+
+    tnew = told;
+    if (tmode == TMODE_RAW)
+    {
+	tnew.c_iflag &= ~(ICRNL | (T_XON == NULL || *T_XON == NUL ? IXON : 0));
+	tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE | IEXTEN);
+	tnew.c_oflag &= ~(ONLCR | XTABS);
+	tnew.c_oflag &= ~(ONLCR | TAB3);
+	tnew.c_oflag &= ~ONLCR;
+	tnew.c_cc[VMIN] = 1;		// return after 1 char
+	tnew.c_cc[VTIME] = 0;		// don't wait
+    }
+    else if (tmode == TMODE_SLEEP)
+    {
+	tnew.c_lflag &= ~(ICANON | ECHO);
+	tnew.c_cc[VMIN] = 1;		// return after 1 char
+	tnew.c_cc[VTIME] = 0;		// don't wait
+    }
+
+    {
+	int	n = 10;
+
+	// A signal may cause tcsetattr() to fail (e.g., SIGCONT).  Retry a
+	// few times.
+	while (tcsetattr(read_cmd_fd, TCSANOW, &tnew) == -1
+						   && errno == EINTR && n > 0)
+	    --n;
+    }

BIN
Done/step18/doc2


+ 58 - 0
Done/step18/doc2.c

@@ -0,0 +1,58 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+
+/* Use this variable to remember original terminal attributes. */
+
+struct termios saved_attributes;
+
+void 
+reset_input_mode (void)
+{
+  tcsetattr (STDIN_FILENO, TCSANOW, &saved_attributes);
+}
+
+void 
+set_input_mode (void)
+{
+  struct termios tattr;
+  char *name;
+
+  /* Make sure stdin is a terminal. */
+  if (!isatty (STDIN_FILENO))
+    {
+      fprintf (stderr, "Not a terminal.\n");
+      exit (EXIT_FAILURE);
+    }
+
+  /* Save the terminal attributes so we can restore them later. */
+  tcgetattr (STDIN_FILENO, &saved_attributes);
+  atexit (reset_input_mode);
+
+  /* Set the funny terminal modes. */
+  tcgetattr (STDIN_FILENO, &tattr);
+  tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
+  tattr.c_cc[VMIN] = 1;
+  tattr.c_cc[VTIME] = 0;
+  tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
+}
+
+int
+main (void)
+{
+  char c;
+
+  set_input_mode ();
+
+  while (1)
+    {
+      read (STDIN_FILENO, &c, 1);
+      if (c == '\004')          /* C-d */
+        break;
+      else
+        putchar (c);
+    }
+
+  return EXIT_SUCCESS;
+}

+ 58 - 0
Done/step18/doc2.txt

@@ -0,0 +1,58 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+
+/* Use this variable to remember original terminal attributes. */
+
+struct termios saved_attributes;
+
+void 
+reset_input_mode (void)
+{
+  tcsetattr (STDIN_FILENO, TCSANOW, &saved_attributes);
+}
+
+void 
+set_input_mode (void)
+{
+  struct termios tattr;
+  char *name;
+
+  /* Make sure stdin is a terminal. */
+  if (!isatty (STDIN_FILENO))
+    {
+      fprintf (stderr, "Not a terminal.\n");
+      exit (EXIT_FAILURE);
+    }
+
+  /* Save the terminal attributes so we can restore them later. */
+  tcgetattr (STDIN_FILENO, &saved_attributes);
+  atexit (reset_input_mode);
+
+  /* Set the funny terminal modes. */
+  tcgetattr (STDIN_FILENO, &tattr);
+  tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
+  tattr.c_cc[VMIN] = 1;
+  tattr.c_cc[VTIME] = 0;
+  tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
+}
+
+int
+main (void)
+{
+  char c;
+
+  set_input_mode ();
+
+  while (1)
+    {
+      read (STDIN_FILENO, &c, 1);
+      if (c == '\004')          /* C-d */
+        break;
+      else
+        putchar (c);
+    }
+
+  return EXIT_SUCCESS;
+}

+ 58 - 0
Done/step18/doc2.txt~

@@ -0,0 +1,58 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+
+/* Use this variable to remember original terminal attributes. */
+
+struct termios saved_attributes;
+
+void 
+reset_input_mode (void)
+{
+  tcsetattr (STDIN_FILENO, TCSANOW, &saved_attributes);
+}
+
+void 
+set_input_mode (void)
+{
+  struct termios tattr;
+  char *name;
+
+  /* Make sure stdin is a terminal. */
+  if (!isatty (STDIN_FILENO))
+    {
+      fprintf (stderr, "Not a terminal.\n");
+      exit (EXIT_FAILURE);
+    }
+
+  /* Save the terminal attributes so we can restore them later. */
+  tcgetattr (STDIN_FILENO, &saved_attributes);
+  atexit (reset_input_mode);
+
+  /* Set the funny terminal modes. */
+  tcgetattr (STDIN_FILENO, &tattr);
+  tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
+  tattr.c_cc[VMIN] = 1;
+  tattr.c_cc[VTIME] = 0;
+  tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
+}
+
+int
+main (void)
+{
+  char c;
+
+  set_input_mode ();
+
+  while (1)
+    {
+      read (STDIN_FILENO, &c, 1);
+      if (c == '\004')          /* C-d */
+        break;
+      else
+        putchar (c);
+    }
+
+  return EXIT_SUCCESS;
+}

BIN
Done/step18/doc3


+ 51 - 0
Done/step18/doc3.c

@@ -0,0 +1,51 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+/* Use this variable to remember original terminal attributes. */
+
+struct termios saved_attributes;
+
+void reset_input_mode (void)
+    {
+        tcsetattr (STDIN_FILENO, TCSANOW, &saved_attributes);
+    }
+    
+void set_input_mode (void)
+{
+    struct termios tattr;
+    /* Make sure stdin is a terminal. */
+    if (!isatty (STDIN_FILENO))
+    {
+    fprintf (stderr, "Not a terminal.\n");
+    exit (EXIT_FAILURE);
+    }
+    /* Save the terminal attributes so we can restore them later. */
+    tcgetattr (STDIN_FILENO, &saved_attributes);
+    atexit (reset_input_mode);
+    /* Set the funny terminal modes. */
+    tcgetattr (STDIN_FILENO, &tattr);
+    tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
+    tattr.c_cc[VMIN] = 1;
+    tattr.c_cc[VTIME] = 0;
+    tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
+}
+    
+int main (void)
+    {
+    char c;
+    
+    set_input_mode ();
+    while (1)
+        {
+        read (STDIN_FILENO, &c, 1);
+        if (c == '\004')
+        /* C-d */
+        break;
+        else
+        write (STDOUT_FILENO, &c, 1);
+        }
+        
+    return EXIT_SUCCESS;
+}
+

BIN
Done/step18/editor


+ 103 - 0
Done/step18/editor.mod

@@ -0,0 +1,103 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 18 *)
+
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc;
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+    number : CARDINAL;
+
+    PROCEDURE die (s : ARRAY OF CHAR);
+    BEGIN
+        libc.perror(s);
+        HALT
+    END die;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios) = -1 THEN
+            die("tcsetattr")
+        END;
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.opost, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.ibrkint, FALSE);
+        bresult := termios.SetFlag(raw,termios.inpck, FALSE);
+        bresult := termios.SetFlag(raw,termios.istrip, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.cs8, TRUE);
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw) = -1 THEN
+            die("tcsetattr")
+        END;
+
+        (* PROCEDURE SetChar (t: TERMIOS; c: ControlChar; ch: CHAR) : BOOLEAN ; *)
+        (* termios.vmin := 0;
+        termios.vtime := 1; *)
+        bresult := termios.SetChar(raw,termios.vmin,CHR(0));
+        bresult := termios.SetChar(raw,termios.vtime,CHR(1));
+    END enableRawMode;
+
+BEGIN
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    IF termios.tcgetattr(FIO.StdIn, thetermios) = -1 THEN
+        die("tcgetattr")
+    END;
+    IF termios.tcgetattr(FIO.StdIn, raw) = -1 THEN
+        die("tcgetattr")
+    END;
+
+    enableRawMode;
+    p := SYSTEM.ADR(c);
+
+    LOOP
+        c := CHR(0);
+        number := (FIO.ReadNBytes(FIO.StdIn,1,p));
+        IF ORD(c) < 32 THEN
+             NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13));
+        ELSE
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteString(" ('");
+            STextIO.WriteChar(c);
+            STextIO.WriteString(" ')");
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13));
+        END;
+        IF c = "q" THEN
+            EXIT
+        END;
+    END;
+END editor.

BIN
Done/step18/editor1


+ 111 - 0
Done/step18/editor1.mod

@@ -0,0 +1,111 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 18 *)
+
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc;
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+    number : CARDINAL;
+
+    PROCEDURE die (s : ARRAY OF CHAR);
+    BEGIN
+        libc.perror(s);
+        HALT
+    END die;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios) = -1 THEN
+            die("tcsetattr")
+        END;
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+(* 
+    static void setControlLines(int port, int dtr, int rts)
+{
+    struct termios tty;
+
+    tcgetattr(port, &tty);
+
+    cfmakeraw(&tty); // Sets raw mode, 8N1, etc.
+
+    tty.c_cflag &= ~CRTSCTS; // Disable hardware flow control
+    tty.c_cflag |= CLOCAL;  // Ignore modem control lines
+
+    tcsetattr(port, TCSANOW, &tty);
+
+    int flags = TIOCM_DTR | TIOCM_RTS;
+    ioctl(port, TIOCMBIS, &flags); // Set bits
+} *)
+
+(* termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+termios_p->c_oflag &= ~OPOST;
+termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+termios_p->c_cflag &= ~(CSIZE|PARENB);
+termios_p->c_cflag |= CS8; *)
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        termios.cfmakeraw(raw);
+        bresult := termios.SetFlag(raw,termios.crtscts, FALSE);
+        bresult := termios.SetFlag(raw,termios.clocal, TRUE);
+        result := termios.tcsnow();
+        (* STextIO.WriteChar(CHR(13)) *)
+        bresult := termios.SetChar(raw,termios.vmin,CHR(0));
+        bresult := termios.SetChar(raw,termios.vtime,CHR(1));
+    END enableRawMode;
+
+BEGIN
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    IF termios.tcgetattr(FIO.StdIn, thetermios) = -1 THEN
+        die("tcgetattr")
+    END;
+    IF termios.tcgetattr(FIO.StdIn, raw) = -1 THEN
+        die("tcgetattr")
+    END;
+
+    enableRawMode;
+    p := SYSTEM.ADR(c);
+
+    LOOP
+        c := CHR(0);
+        number := (FIO.ReadNBytes(FIO.StdIn,1,p));
+        IF ORD(c) < 32 THEN
+             NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13));
+        ELSE
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteString(" ('");
+            STextIO.WriteChar(c);
+            STextIO.WriteString(" ')");
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13));
+        END;
+        IF c = "q" THEN
+            EXIT
+        END;
+    END;
+END editor.

BIN
Done/step18/kilo


+ 52 - 0
Done/step18/kilo.c

@@ -0,0 +1,52 @@
+/*** includes ***/
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+/*** data ***/
+struct termios orig_termios;
+
+
+/*** terminal ***/
+void die(const char *s) {
+  perror(s);
+  exit(1);
+}
+
+void disableRawMode() {
+    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1)
+      die("tcsetattr");
+}
+
+void enableRawMode() {
+  if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) die("tcgetattr");
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+  raw.c_oflag &= ~(OPOST);
+  raw.c_cflag |= (CS8);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  raw.c_cc[VMIN] = 0;
+  raw.c_cc[VTIME] = 1;
+  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) die("tcsetattr");
+}
+
+
+/*** init ***/
+int main() {
+  enableRawMode();
+  while (1) {
+    char c = '\0';
+    if (read(STDIN_FILENO, &c, 1) == -1 && errno != EAGAIN) die("read");
+    if (iscntrl(c)) {
+      printf("%d\r\n", c);
+    } else {
+      printf("%d ('%c')\r\n", c, c);
+    }
+    if (c == 'q') break;
+  }
+  return 0;
+}

+ 9 - 0
Done/step19/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

+ 110 - 0
Done/step19/editor.mod

@@ -0,0 +1,110 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 19 *)
+
+(******************** INCLUDES ******************)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc;
+
+(******************** DATA ******************)
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+    number : CARDINAL;
+
+(******************** TERMINAL ******************)
+
+    PROCEDURE die (s : ARRAY OF CHAR);
+    BEGIN
+        libc.perror(s);
+        HALT
+    END die;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios) = -1 THEN
+            die("tcsetattr")
+        END;
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.opost, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.ibrkint, FALSE);
+        bresult := termios.SetFlag(raw,termios.inpck, FALSE);
+        bresult := termios.SetFlag(raw,termios.istrip, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.cs8, TRUE);
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw) = -1 THEN
+            die("tcsetattr")
+        END;
+
+        (* PROCEDURE SetChar (t: TERMIOS; c: ControlChar; ch: CHAR) : BOOLEAN ; *)
+        (* termios.vmin := 0;
+        termios.vtime := 1; *)
+        bresult := termios.SetChar(raw,termios.vmin,CHR(0));
+        bresult := termios.SetChar(raw,termios.vtime,CHR(1));
+    END enableRawMode;
+
+(******************** INIT ******************)
+
+BEGIN
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    IF termios.tcgetattr(FIO.StdIn, thetermios) = -1 THEN
+        die("tcgetattr")
+    END;
+    IF termios.tcgetattr(FIO.StdIn, raw) = -1 THEN
+        die("tcgetattr")
+    END;
+
+    enableRawMode;
+    p := SYSTEM.ADR(c);
+
+    LOOP
+        c := CHR(0);
+        number := (FIO.ReadNBytes(FIO.StdIn,1,p));
+        IF ORD(c) < 32 THEN
+             NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13));
+        ELSE
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteString(" ('");
+            STextIO.WriteChar(c);
+            STextIO.WriteString(" ')");
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13));
+        END;
+        IF c = "q" THEN
+            EXIT
+        END;
+    END;
+END editor.

+ 55 - 0
Done/step19/kilo.c

@@ -0,0 +1,55 @@
+/*** includes ***/
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+/*** defines ***/
+#define CTRL_KEY(k) ((k) & 0x1f)
+
+/*** data ***/
+struct termios orig_termios;
+
+
+/*** terminal ***/
+void die(const char *s) {
+  perror(s);
+  exit(1);
+}
+
+void disableRawMode() {
+    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1)
+      die("tcsetattr");
+}
+
+void enableRawMode() {
+  if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) die("tcgetattr");
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+  raw.c_oflag &= ~(OPOST);
+  raw.c_cflag |= (CS8);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  raw.c_cc[VMIN] = 0;
+  raw.c_cc[VTIME] = 1;
+  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) die("tcsetattr");
+}
+
+
+/*** init ***/
+int main() {
+  enableRawMode();
+  while (1) {
+    char c = '\0';
+    if (read(STDIN_FILENO, &c, 1) == -1 && errno != EAGAIN) die("read");
+    if (iscntrl(c)) {
+      printf("%d\r\n", c);
+    } else {
+      printf("%d ('%c')\r\n", c, c);
+    }
+    if (c == CTRL_KEY('q')) break;
+  }
+  return 0;
+}

+ 9 - 0
Done/step2/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step2/editor


+ 19 - 0
Done/step2/editor.mod

@@ -0,0 +1,19 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 2 *)
+
+IMPORT FIO, SYSTEM;
+
+VAR 
+    c : CHAR;
+    p : POINTER TO CHAR;
+
+BEGIN
+    p := SYSTEM.ADR(c);
+    (* PROCEDURE ReadNBytes (f: File; nBytes: CARDINAL; dest: ADDRESS) : CARDINAL ; *)
+    WHILE FIO.ReadNBytes(FIO.StdIn,1,p) = 1 DO
+        ;
+    END;
+END editor.

BIN
Done/step2/kilo


+ 6 - 0
Done/step2/kilo.c

@@ -0,0 +1,6 @@
+#include <unistd.h>
+int main() {
+  char c;
+  while (read(STDIN_FILENO, &c, 1) == 1);
+  return 0;
+}

+ 9 - 0
Done/step20/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step20/editor


+ 122 - 0
Done/step20/editor.mod

@@ -0,0 +1,122 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 20 *)
+
+(******************** INCLUDES ******************)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc;
+
+(******************** DATA ******************)
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+    number      : CARDINAL;
+
+(******************** TERMINAL ******************)
+
+    PROCEDURE CtrlKey(c: CHAR) : CHAR;
+
+        VAR
+            n : BITSET;
+
+    BEGIN
+        n := BITSET(ORD(c));
+        n := n * BITSET(1FH);
+        RETURN CHR(CARDINAL(n))
+    END CtrlKey;
+
+    PROCEDURE die (s : ARRAY OF CHAR);
+    BEGIN
+        libc.perror(s);
+        HALT
+    END die;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios) = -1 THEN
+            die("tcsetattr")
+        END;
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.opost, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.ibrkint, FALSE);
+        bresult := termios.SetFlag(raw,termios.inpck, FALSE);
+        bresult := termios.SetFlag(raw,termios.istrip, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.cs8, TRUE);
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw) = -1 THEN
+            die("tcsetattr")
+        END;
+
+        (* PROCEDURE SetChar (t: TERMIOS; c: ControlChar; ch: CHAR) : BOOLEAN ; *)
+        (* termios.vmin := 0;
+        termios.vtime := 1; *)
+        bresult := termios.SetChar(raw,termios.vmin,CHR(0));
+        bresult := termios.SetChar(raw,termios.vtime,CHR(1));
+    END enableRawMode;
+
+
+(******************** INIT ******************)
+
+BEGIN
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    IF termios.tcgetattr(FIO.StdIn, thetermios) = -1 THEN
+        die("tcgetattr")
+    END;
+    IF termios.tcgetattr(FIO.StdIn, raw) = -1 THEN
+        die("tcgetattr")
+    END;
+
+    enableRawMode;
+    p := SYSTEM.ADR(c);
+
+    LOOP
+        c := CHR(0);
+        number := (FIO.ReadNBytes(FIO.StdIn,1,p));
+        IF ORD(c) < 32 THEN
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13));
+        ELSE
+            NumberIO.WriteCard(ORD(c),5);
+            STextIO.WriteString(" ('");
+            STextIO.WriteChar(c);
+            STextIO.WriteString(" ')");
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13));
+        END;
+        IF c = "q" THEN
+            EXIT
+        END;
+    END;
+END editor.

BIN
Done/step20/kilo


+ 65 - 0
Done/step20/kilo.c

@@ -0,0 +1,65 @@
+/*** includes ***/
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+/*** defines ***/
+#define CTRL_KEY(k) ((k) & 0x1f)
+
+/*** data ***/
+struct termios orig_termios;
+
+
+/*** terminal ***/
+void die(const char *s) {
+  perror(s);
+  exit(1);
+}
+
+void disableRawMode() {
+    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1)
+      die("tcsetattr");
+}
+
+void enableRawMode() {
+  if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) die("tcgetattr");
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+  raw.c_oflag &= ~(OPOST);
+  raw.c_cflag |= (CS8);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  raw.c_cc[VMIN] = 0;
+  raw.c_cc[VTIME] = 1;
+  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) die("tcsetattr");
+}
+
+char editorReadKey() {
+  int nread;
+  char c;
+  while ((nread = read(STDIN_FILENO, &c, 1)) != 1) {
+    if (nread == -1 && errno != EAGAIN) die("read");
+  }
+  return c;
+}
+
+/*** input ***/
+void editorProcessKeypress() {
+  char c = editorReadKey();
+  switch (c) {
+    case CTRL_KEY('q'):
+      exit(0);
+      break;
+  }
+}
+/*** init ***/
+int main() {
+  enableRawMode();
+  while (1) {
+    editorProcessKeypress();
+  }
+  return 0;
+}

+ 9 - 0
Done/step21/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step21/editor


+ 139 - 0
Done/step21/editor.mod

@@ -0,0 +1,139 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 21 *)
+
+(******************** INCLUDES ******************)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc, ASCII;
+IMPORT Strings, errno;
+
+(******************** DATA ******************)
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+    number      : CARDINAL;
+    (* testing *)
+    test        : BOOLEAN;
+
+(******************** TERMINAL ******************)
+
+     PROCEDURE CtrlKey(c: CHAR) : CARDINAL;
+
+        VAR
+            n : BITSET;
+
+    BEGIN
+        n := BITSET(ORD(c));
+        n := n * BITSET(1FH);
+        RETURN CARDINAL(n)
+    END CtrlKey;
+
+    PROCEDURE die (s : ARRAY OF CHAR);
+    BEGIN
+        libc.perror(s);
+        HALT
+    END die;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios) = -1 THEN
+            die("tcsetattr")
+        END;
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.opost, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.ibrkint, FALSE);
+        bresult := termios.SetFlag(raw,termios.inpck, FALSE);
+        bresult := termios.SetFlag(raw,termios.istrip, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.cs8, TRUE);
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw) = -1 THEN
+            die("tcsetattr")
+        END;
+
+        (* PROCEDURE SetChar (t: TERMIOS; c: ControlChar; ch: CHAR) : BOOLEAN ; *)
+        (* termios.vmin := 0;
+        termios.vtime := 1; *)
+        bresult := termios.SetChar(raw,termios.vmin,CHR(0));
+        bresult := termios.SetChar(raw,termios.vtime,CHR(1));
+    END enableRawMode;
+
+    PROCEDURE  editorReadKey() : CHAR;
+        VAR
+            c : CHAR;
+            nread : INTEGER;
+    BEGIN
+        p := SYSTEM.ADR(c);
+        WHILE FIO.ReadNBytes(FIO.StdIn,1,p) <> 1 DO 
+           ;
+        END;
+        RETURN c
+    END editorReadKey; 
+
+(******************** output ******************)
+
+
+(******************** input  ******************)
+
+    PROCEDURE editorProcessKeypress;
+        VAR
+            c       : CHAR;
+            b       : BOOLEAN;
+    BEGIN
+        c := editorReadKey();
+        CASE ORD(c) OF
+          17 : HALT;
+        END
+    END editorProcessKeypress;
+
+(********************  INIT  ******************)
+
+
+
+BEGIN
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    IF termios.tcgetattr(FIO.StdIn, thetermios) = -1 THEN
+        die("tcgetattr")
+    END;
+    IF termios.tcgetattr(FIO.StdIn, raw) = -1 THEN
+        die("tcgetattr")
+    END;
+
+    enableRawMode;
+    
+    LOOP
+        editorProcessKeypress();
+    END;
+
+
+END editor.

BIN
Done/step21/kilo


+ 72 - 0
Done/step21/kilo.c

@@ -0,0 +1,72 @@
+/*** includes ***/
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+/*** defines ***/
+#define CTRL_KEY(k) ((k) & 0x1f)
+
+/*** data ***/
+struct termios orig_termios;
+
+
+/*** terminal ***/
+void die(const char *s) {
+  perror(s);
+  exit(1);
+}
+
+void disableRawMode() {
+    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1)
+      die("tcsetattr");
+}
+
+void enableRawMode() {
+  if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) die("tcgetattr");
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+  raw.c_oflag &= ~(OPOST);
+  raw.c_cflag |= (CS8);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  raw.c_cc[VMIN] = 0;
+  raw.c_cc[VTIME] = 1;
+  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) die("tcsetattr");
+}
+
+char editorReadKey() {
+  int nread;
+  char c;
+  while ((nread = read(STDIN_FILENO, &c, 1)) != 1) {
+    if (nread == -1 && errno != EAGAIN) die("read");
+  }
+  return c;
+}
+
+
+/*** output ***/
+void editorRefreshScreen() {
+  write(STDOUT_FILENO, "\x1b[2J", 4);
+}
+
+/*** input ***/
+void editorProcessKeypress() {
+  char c = editorReadKey();
+  switch (c) {
+    case CTRL_KEY('q'):
+      exit(0);
+      break;
+  }
+}
+/*** init ***/
+int main() {
+  enableRawMode();
+  while (1) {
+    editorRefreshScreen();
+    editorProcessKeypress();
+  }
+  return 0;
+}

+ 9 - 0
Done/step22/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step22/editor


+ 156 - 0
Done/step22/editor.mod

@@ -0,0 +1,156 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 22 *)
+
+(******************** INCLUDES ******************)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc, ASCII;
+IMPORT Strings, errno;
+
+(******************** DATA ******************)
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+    number      : CARDINAL;
+    (* testing *)
+    test        : BOOLEAN;
+    clearScreen : ARRAY[0..6] OF CHAR;
+
+(******************** TERMINAL ******************)
+
+     PROCEDURE CtrlKey(c: CHAR) : CARDINAL;
+
+        VAR
+            n : BITSET;
+
+    BEGIN
+        n := BITSET(ORD(c));
+        n := n * BITSET(1FH);
+        RETURN CARDINAL(n)
+    END CtrlKey;
+
+    PROCEDURE die (s : ARRAY OF CHAR);
+    BEGIN
+        libc.perror(s);
+        HALT
+    END die;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios) = -1 THEN
+            die("tcsetattr")
+        END;
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.opost, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.ibrkint, FALSE);
+        bresult := termios.SetFlag(raw,termios.inpck, FALSE);
+        bresult := termios.SetFlag(raw,termios.istrip, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.cs8, TRUE);
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw) = -1 THEN
+            die("tcsetattr")
+        END;
+
+        (* PROCEDURE SetChar (t: TERMIOS; c: ControlChar; ch: CHAR) : BOOLEAN ; *)
+        (* termios.vmin := 0;
+        termios.vtime := 1; *)
+        bresult := termios.SetChar(raw,termios.vmin,CHR(0));
+        bresult := termios.SetChar(raw,termios.vtime,CHR(1));
+    END enableRawMode;
+
+    PROCEDURE  editorReadKey() : CHAR;
+        VAR
+            c : CHAR;
+            nread : INTEGER;
+    BEGIN
+        p := SYSTEM.ADR(c);
+        WHILE FIO.ReadNBytes(FIO.StdIn,1,p) <> 1 DO 
+           ;
+        END;
+        RETURN c
+    END editorReadKey; 
+
+(******************** output ******************)
+
+PROCEDURE editorRefreshScreen;
+
+BEGIN
+    STextIO.WriteString(clearScreen)
+END editorRefreshScreen;
+
+(******************** input  ******************)
+
+    PROCEDURE editorProcessKeypress;
+        VAR
+            c       : CHAR;
+            b       : BOOLEAN;
+    BEGIN
+        c := editorReadKey();
+        CASE ORD(c) OF
+          17 : HALT;
+        END
+    END editorProcessKeypress;
+
+(********************  INIT  ******************)
+
+PROCEDURE InitClearScreen;
+
+BEGIN
+    clearScreen := "";
+    Strings.Concat(clearScreen,ASCII.esc,clearScreen);
+    Strings.Concat(clearScreen,"[2J",clearScreen);
+    (* Strings.Concat(clearScreen,ASCII.esc,clearScreen);
+    Strings.Concat(clearScreen,"[H",clearScreen); *)
+END InitClearScreen;
+
+BEGIN
+    InitClearScreen;
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    IF termios.tcgetattr(FIO.StdIn, thetermios) = -1 THEN
+        die("tcgetattr")
+    END;
+    IF termios.tcgetattr(FIO.StdIn, raw) = -1 THEN
+        die("tcgetattr")
+    END;
+
+    enableRawMode;
+    
+    LOOP
+        editorRefreshScreen;
+        editorProcessKeypress;
+        editorRefreshScreen;
+    END;
+
+
+END editor.

BIN
Done/step22/kilo


+ 73 - 0
Done/step22/kilo.c

@@ -0,0 +1,73 @@
+/*** includes ***/
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+/*** defines ***/
+#define CTRL_KEY(k) ((k) & 0x1f)
+
+/*** data ***/
+struct termios orig_termios;
+
+
+/*** terminal ***/
+void die(const char *s) {
+  perror(s);
+  exit(1);
+}
+
+void disableRawMode() {
+    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1)
+      die("tcsetattr");
+}
+
+void enableRawMode() {
+  if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) die("tcgetattr");
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+  raw.c_oflag &= ~(OPOST);
+  raw.c_cflag |= (CS8);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  raw.c_cc[VMIN] = 0;
+  raw.c_cc[VTIME] = 1;
+  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) die("tcsetattr");
+}
+
+char editorReadKey() {
+  int nread;
+  char c;
+  while ((nread = read(STDIN_FILENO, &c, 1)) != 1) {
+    if (nread == -1 && errno != EAGAIN) die("read");
+  }
+  return c;
+}
+
+
+/*** output ***/
+void editorRefreshScreen() {
+  write(STDOUT_FILENO, "\x1b[2J", 4);
+  write(STDOUT_FILENO, "\x1b[H", 3);
+}
+
+/*** input ***/
+void editorProcessKeypress() {
+  char c = editorReadKey();
+  switch (c) {
+    case CTRL_KEY('q'):
+      exit(0);
+      break;
+  }
+}
+/*** init ***/
+int main() {
+  enableRawMode();
+  while (1) {
+    editorRefreshScreen();
+    editorProcessKeypress();
+  }
+  return 0;
+}

+ 9 - 0
Done/step23/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step23/editor


+ 157 - 0
Done/step23/editor.mod

@@ -0,0 +1,157 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 23 *)
+
+(******************** INCLUDES ******************)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc, ASCII;
+IMPORT Strings, errno;
+
+(******************** DATA ******************)
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+    number      : CARDINAL;
+    (* testing *)
+    test        : BOOLEAN;
+    clearScreen : ARRAY[0..6] OF CHAR;
+
+(******************** TERMINAL ******************)
+
+     PROCEDURE CtrlKey(c: CHAR) : CARDINAL;
+
+        VAR
+            n : BITSET;
+
+    BEGIN
+        n := BITSET(ORD(c));
+        n := n * BITSET(1FH);
+        RETURN CARDINAL(n)
+    END CtrlKey;
+
+    PROCEDURE die (s : ARRAY OF CHAR);
+    BEGIN
+        libc.perror(s);
+        (* STextIO.WriteString(clearScreen); *)
+        HALT
+    END die;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios) = -1 THEN
+            die("tcsetattr")
+        END;
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.opost, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.ibrkint, FALSE);
+        bresult := termios.SetFlag(raw,termios.inpck, FALSE);
+        bresult := termios.SetFlag(raw,termios.istrip, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.cs8, TRUE);
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw) = -1 THEN
+            die("tcsetattr")
+        END;
+
+        (* PROCEDURE SetChar (t: TERMIOS; c: ControlChar; ch: CHAR) : BOOLEAN ; *)
+        (* termios.vmin := 0;
+        termios.vtime := 1; *)
+        bresult := termios.SetChar(raw,termios.vmin,CHR(0));
+        bresult := termios.SetChar(raw,termios.vtime,CHR(1));
+    END enableRawMode;
+
+    PROCEDURE  editorReadKey() : CHAR;
+        VAR
+            c : CHAR;
+            nread : INTEGER;
+    BEGIN
+        p := SYSTEM.ADR(c);
+        WHILE FIO.ReadNBytes(FIO.StdIn,1,p) <> 1 DO 
+           ;
+        END;
+        RETURN c
+    END editorReadKey; 
+
+(******************** output ******************)
+
+PROCEDURE editorRefreshScreen;
+
+BEGIN
+    STextIO.WriteString(clearScreen)
+END editorRefreshScreen;
+
+(******************** input  ******************)
+
+    PROCEDURE editorProcessKeypress;
+        VAR
+            c       : CHAR;
+            b       : BOOLEAN;
+    BEGIN
+        c := editorReadKey();
+        CASE ORD(c) OF
+          17 : HALT;
+        END
+    END editorProcessKeypress;
+
+(********************  INIT  ******************)
+
+PROCEDURE InitClearScreen;
+
+BEGIN
+    clearScreen := "";
+    Strings.Concat(clearScreen,ASCII.esc,clearScreen);
+    Strings.Concat(clearScreen,"[2J",clearScreen);
+    Strings.Concat(clearScreen,ASCII.esc,clearScreen);
+    Strings.Concat(clearScreen,"[H",clearScreen);
+END InitClearScreen;
+
+BEGIN
+    InitClearScreen;
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    IF termios.tcgetattr(FIO.StdIn, thetermios) = -1 THEN
+        die("tcgetattr")
+    END;
+    IF termios.tcgetattr(FIO.StdIn, raw) = -1 THEN
+        die("tcgetattr")
+    END;
+
+    enableRawMode;
+    
+    LOOP
+        editorRefreshScreen;
+        editorProcessKeypress;
+        editorRefreshScreen;
+    END;
+
+
+END editor.

BIN
Done/step23/kilo


+ 75 - 0
Done/step23/kilo.c

@@ -0,0 +1,75 @@
+/*** includes ***/
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+/*** defines ***/
+#define CTRL_KEY(k) ((k) & 0x1f)
+
+/*** data ***/
+struct termios orig_termios;
+
+
+/*** terminal ***/
+void die(const char *s) {
+  write(STDOUT_FILENO, "\x1b[2J", 4);
+  write(STDOUT_FILENO, "\x1b[H", 3);
+  perror(s);
+  exit(1);
+}
+
+void disableRawMode() {
+    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1)
+      die("tcsetattr");
+}
+
+void enableRawMode() {
+  if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) die("tcgetattr");
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+  raw.c_oflag &= ~(OPOST);
+  raw.c_cflag |= (CS8);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  raw.c_cc[VMIN] = 0;
+  raw.c_cc[VTIME] = 1;
+  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) die("tcsetattr");
+}
+
+char editorReadKey() {
+  int nread;
+  char c;
+  while ((nread = read(STDIN_FILENO, &c, 1)) != 1) {
+    if (nread == -1 && errno != EAGAIN) die("read");
+  }
+  return c;
+}
+
+
+/*** output ***/
+void editorRefreshScreen() {
+  write(STDOUT_FILENO, "\x1b[2J", 4);
+  write(STDOUT_FILENO, "\x1b[H", 3);
+}
+
+/*** input ***/
+void editorProcessKeypress() {
+  char c = editorReadKey();
+  switch (c) {
+    case CTRL_KEY('q'):
+      exit(0);
+      break;
+  }
+}
+/*** init ***/
+int main() {
+  enableRawMode();
+  while (1) {
+    editorRefreshScreen();
+    editorProcessKeypress();
+  }
+  return 0;
+}

+ 9 - 0
Done/step24/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step24/editor


+ 157 - 0
Done/step24/editor.mod

@@ -0,0 +1,157 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 24 *)
+
+(******************** INCLUDES ******************)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc, ASCII;
+IMPORT Strings, errno;
+
+(******************** DATA ******************)
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+    number      : CARDINAL;
+    (* testing *)
+    test        : BOOLEAN;
+    clearScreen : ARRAY[0..6] OF CHAR;
+
+(******************** TERMINAL ******************)
+
+     PROCEDURE CtrlKey(c: CHAR) : CARDINAL;
+
+        VAR
+            n : BITSET;
+
+    BEGIN
+        n := BITSET(ORD(c));
+        n := n * BITSET(1FH);
+        RETURN CARDINAL(n)
+    END CtrlKey;
+
+    PROCEDURE die (s : ARRAY OF CHAR);
+    BEGIN
+        libc.perror(s);
+        STextIO.WriteString(clearScreen);
+        HALT
+    END die;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios) = -1 THEN
+            die("tcsetattr")
+        END;
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.opost, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.ibrkint, FALSE);
+        bresult := termios.SetFlag(raw,termios.inpck, FALSE);
+        bresult := termios.SetFlag(raw,termios.istrip, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.cs8, TRUE);
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw) = -1 THEN
+            die("tcsetattr")
+        END;
+
+        (* PROCEDURE SetChar (t: TERMIOS; c: ControlChar; ch: CHAR) : BOOLEAN ; *)
+        (* termios.vmin := 0;
+        termios.vtime := 1; *)
+        bresult := termios.SetChar(raw,termios.vmin,CHR(0));
+        bresult := termios.SetChar(raw,termios.vtime,CHR(1));
+    END enableRawMode;
+
+    PROCEDURE  editorReadKey() : CHAR;
+        VAR
+            c : CHAR;
+            nread : INTEGER;
+    BEGIN
+        p := SYSTEM.ADR(c);
+        WHILE FIO.ReadNBytes(FIO.StdIn,1,p) <> 1 DO 
+           ;
+        END;
+        RETURN c
+    END editorReadKey; 
+
+(******************** output ******************)
+
+PROCEDURE editorRefreshScreen;
+
+BEGIN
+    STextIO.WriteString(clearScreen)
+END editorRefreshScreen;
+
+(******************** input  ******************)
+
+    PROCEDURE editorProcessKeypress;
+        VAR
+            c       : CHAR;
+            b       : BOOLEAN;
+    BEGIN
+        c := editorReadKey();
+        CASE ORD(c) OF
+          17 : HALT;
+        END
+    END editorProcessKeypress;
+
+(********************  INIT  ******************)
+
+PROCEDURE InitClearScreen;
+
+BEGIN
+    clearScreen := "";
+    Strings.Concat(clearScreen,ASCII.esc,clearScreen);
+    Strings.Concat(clearScreen,"[2J",clearScreen);
+    Strings.Concat(clearScreen,ASCII.esc,clearScreen);
+    Strings.Concat(clearScreen,"[H",clearScreen);
+END InitClearScreen;
+
+BEGIN
+    InitClearScreen;
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    IF termios.tcgetattr(FIO.StdIn, thetermios) = -1 THEN
+        die("tcgetattr")
+    END;
+    IF termios.tcgetattr(FIO.StdIn, raw) = -1 THEN
+        die("tcgetattr")
+    END;
+
+    enableRawMode;
+    
+    LOOP
+        editorRefreshScreen;
+        editorProcessKeypress;
+        editorRefreshScreen;
+    END;
+
+
+END editor.

BIN
Done/step24/kilo


+ 75 - 0
Done/step24/kilo.c

@@ -0,0 +1,75 @@
+/*** includes ***/
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+/*** defines ***/
+#define CTRL_KEY(k) ((k) & 0x1f)
+
+/*** data ***/
+struct termios orig_termios;
+
+
+/*** terminal ***/
+void die(const char *s) {
+  write(STDOUT_FILENO, "\x1b[2J", 4);
+  write(STDOUT_FILENO, "\x1b[H", 3);
+  perror(s);
+  exit(1);
+}
+
+void disableRawMode() {
+    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1)
+      die("tcsetattr");
+}
+
+void enableRawMode() {
+  if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) die("tcgetattr");
+  atexit(disableRawMode);
+  struct termios raw = orig_termios;
+  raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+  raw.c_oflag &= ~(OPOST);
+  raw.c_cflag |= (CS8);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  raw.c_cc[VMIN] = 0;
+  raw.c_cc[VTIME] = 1;
+  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) die("tcsetattr");
+}
+
+char editorReadKey() {
+  int nread;
+  char c;
+  while ((nread = read(STDIN_FILENO, &c, 1)) != 1) {
+    if (nread == -1 && errno != EAGAIN) die("read");
+  }
+  return c;
+}
+
+
+/*** output ***/
+void editorRefreshScreen() {
+  write(STDOUT_FILENO, "\x1b[2J", 4);
+  write(STDOUT_FILENO, "\x1b[H", 3);
+}
+
+/*** input ***/
+void editorProcessKeypress() {
+  char c = editorReadKey();
+  switch (c) {
+    case CTRL_KEY('q'):
+      exit(0);
+      break;
+  }
+}
+/*** init ***/
+int main() {
+  enableRawMode();
+  while (1) {
+    editorRefreshScreen();
+    editorProcessKeypress();
+  }
+  return 0;
+}

+ 9 - 0
Done/step25/Makefile

@@ -0,0 +1,9 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor editor.mod

BIN
Done/step25/editor


+ 177 - 0
Done/step25/editor.mod

@@ -0,0 +1,177 @@
+MODULE editor;
+
+(* based on the kilo editor building course*)
+
+(* Step 25 *)
+
+(******************** INCLUDES ******************)
+
+IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
+IMPORT CharClass, STextIO, libc, ASCII;
+IMPORT Strings, errno;
+
+(******************** DATA ******************)
+
+VAR 
+    c           : CHAR;
+    p           : POINTER TO CHAR;
+    thetermios  : termios.TERMIOS;
+    raw         : termios.TERMIOS;
+    result      : INTEGER;
+    number      : CARDINAL;
+    (* testing *)
+    test        : BOOLEAN;
+    clearScreen : ARRAY[0..6] OF CHAR;
+    cursorHome  : ARRAY[0..2] OF CHAR;
+
+(******************** TERMINAL ******************)
+
+     PROCEDURE CtrlKey(c: CHAR) : CARDINAL;
+
+        VAR
+            n : BITSET;
+
+    BEGIN
+        n := BITSET(ORD(c));
+        n := n * BITSET(1FH);
+        RETURN CARDINAL(n)
+    END CtrlKey;
+
+    PROCEDURE die (s : ARRAY OF CHAR);
+    BEGIN
+        libc.perror(s);
+        STextIO.WriteString(clearScreen);
+        HALT
+    END die;
+
+    PROCEDURE disableRawMode(): INTEGER;
+        VAR
+            TCSAFLUSH : INTEGER;
+            result    : INTEGER; 
+        
+    BEGIN
+        TCSAFLUSH := termios.tcsflush ();
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios) = -1 THEN
+            die("tcsetattr")
+        END;
+        RETURN result;
+    END disableRawMode;
+
+    PROCEDURE enableRawMode;
+
+        VAR
+            TCSAFLUSH   : INTEGER;
+            result      : INTEGER;
+            bresult     : BOOLEAN;
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        libc.atexit(disableRawMode);
+        bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
+        bresult := termios.SetFlag(raw,termios.ixon, FALSE);
+        bresult := termios.SetFlag(raw,termios.lecho, FALSE);
+        bresult := termios.SetFlag(raw,termios.opost, FALSE);
+        bresult := termios.SetFlag(raw,termios.licanon, FALSE);
+        bresult := termios.SetFlag(raw,termios.liexten, FALSE);
+        bresult := termios.SetFlag(raw,termios.lisig, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.ibrkint, FALSE);
+        bresult := termios.SetFlag(raw,termios.inpck, FALSE);
+        bresult := termios.SetFlag(raw,termios.istrip, FALSE);
+
+        bresult := termios.SetFlag(raw,termios.cs8, TRUE);
+        IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw) = -1 THEN
+            die("tcsetattr")
+        END;
+
+        (* PROCEDURE SetChar (t: TERMIOS; c: ControlChar; ch: CHAR) : BOOLEAN ; *)
+        (* termios.vmin := 0;
+        termios.vtime := 1; *)
+        bresult := termios.SetChar(raw,termios.vmin,CHR(0));
+        bresult := termios.SetChar(raw,termios.vtime,CHR(1));
+    END enableRawMode;
+
+    PROCEDURE  editorReadKey() : CHAR;
+        VAR
+            c : CHAR;
+            nread : INTEGER;
+    BEGIN
+        p := SYSTEM.ADR(c);
+        WHILE FIO.ReadNBytes(FIO.StdIn,1,p) <> 1 DO 
+           ;
+        END;
+        RETURN c
+    END editorReadKey; 
+
+(******************** output ******************)
+
+    PROCEDURE editorDrawRows;
+
+        VAR
+            y : CARDINAL;
+
+    BEGIN
+        FOR y := 1 TO 24 DO
+            STextIO.WriteChar("~");
+            STextIO.WriteLn;
+            STextIO.WriteChar(CHR(13))
+        END;
+    END editorDrawRows;
+
+    PROCEDURE editorRefreshScreen;
+
+    BEGIN
+        STextIO.WriteString(clearScreen);
+        editorDrawRows;
+        STextIO.WriteString(cursorHome);
+    END editorRefreshScreen;
+
+(******************** input  ******************)
+
+    PROCEDURE editorProcessKeypress;
+        VAR
+            c       : CHAR;
+            b       : BOOLEAN;
+    BEGIN
+        c := editorReadKey();
+        CASE ORD(c) OF
+          17 : HALT;
+        END
+    END editorProcessKeypress;
+
+(********************  INIT  ******************)
+
+PROCEDURE InitScreenEscapes;
+
+BEGIN
+    clearScreen := "";
+    Strings.Concat(clearScreen,ASCII.esc,clearScreen);
+    Strings.Concat(clearScreen,"[2J",clearScreen);
+    Strings.Concat(clearScreen,ASCII.esc,clearScreen);
+    Strings.Concat(clearScreen,"[H",clearScreen);
+    cursorHome := "";
+    Strings.Concat(cursorHome,ASCII.esc,cursorHome);
+    Strings.Concat(cursorHome,"[H",cursorHome);
+END InitScreenEscapes;
+
+BEGIN
+    InitScreenEscapes;
+
+    thetermios := termios.InitTermios();
+    raw := termios.InitTermios();
+    IF termios.tcgetattr(FIO.StdIn, thetermios) = -1 THEN
+        die("tcgetattr")
+    END;
+    IF termios.tcgetattr(FIO.StdIn, raw) = -1 THEN
+        die("tcgetattr")
+    END;
+
+    enableRawMode;
+    
+    LOOP
+        editorRefreshScreen;
+        editorProcessKeypress;
+        editorRefreshScreen;
+    END;
+
+
+END editor.

BIN
Done/step25/kilo


Some files were not shown because too many files changed in this diff