Console.txt 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. MODULE HostConsole;
  2. (* THIS IS TEXT COPY OF Console.odc *)
  3. (* DO NOT EDIT *)
  4. (*
  5. A. V. Shiryaev, 2012.10
  6. Console implementation for Windows
  7. *)
  8. IMPORT SYSTEM, Console, WinApi;
  9. TYPE
  10. Cons = POINTER TO RECORD (Console.Console) END;
  11. CONST
  12. inBufLen = 128; (* > 0 *)
  13. VAR
  14. cons: Cons;
  15. out, in: WinApi.HANDLE;
  16. ss: ARRAY 1024 OF SHORTCHAR;
  17. inBuf: ARRAY [untagged] inBufLen OF SHORTCHAR;
  18. inBufW, inBufR: INTEGER; (* 0 <= inBufR <= inBufW <= inBufLen *)
  19. PROCEDURE (cons: Cons) ReadLn (OUT text: ARRAY OF CHAR);
  20. VAR
  21. W: INTEGER;
  22. res: WinApi.BOOL;
  23. i: INTEGER;
  24. done: BOOLEAN;
  25. res1: INTEGER;
  26. BEGIN
  27. (* ReadLine -> ss, W *)
  28. W := 0;
  29. done := FALSE;
  30. REPEAT
  31. i := inBufR;
  32. WHILE (i < inBufW) & (inBuf[i] # 0AX) & (W < LEN(ss)) DO
  33. ss[W] := inBuf[i];
  34. INC(W);
  35. INC(i)
  36. END;
  37. IF i = inBufW THEN
  38. inBufW := 0; inBufR := 0;
  39. res := WinApi.ReadFile(in, SYSTEM.ADR(inBuf[0]), inBufLen, i, NIL);
  40. IF res # 0 THEN (* TRUE *)
  41. inBufW := i
  42. ELSE
  43. (* W := 0; *) done := TRUE
  44. END
  45. ELSIF inBuf[i] = 0AX THEN
  46. ss[W] := 0AX; INC(W); done := TRUE;
  47. inBufR := i + 1
  48. ELSE (* ss is too small *)
  49. W := 0; done := TRUE
  50. END
  51. UNTIL done;
  52. IF W > 0 THEN
  53. res1 := WinApi.MultiByteToWideChar(WinApi.CP_OEMCP, {}, ss, W, text, LEN(text) - 1);
  54. IF (res1 > 0) & (res1 < LEN(text)) THEN
  55. text[res1] := 0X
  56. ELSE
  57. text[0] := 0X
  58. END
  59. ELSE
  60. text[0] := 0X
  61. END
  62. END ReadLn;
  63. PROCEDURE Print (IN s: ARRAY OF CHAR; len: INTEGER);
  64. VAR res, written: INTEGER;
  65. BEGIN
  66. IF len > 0 THEN
  67. res := WinApi.WideCharToMultiByte(WinApi.CP_OEMCP, {}, s, len, ss, LEN(ss), NIL, NIL);
  68. IF (res > 0) & (res <= LEN(ss)) THEN
  69. res := WinApi.WriteFile(out, SYSTEM.ADR(ss[0]), res, written, NIL)
  70. END
  71. END
  72. END Print;
  73. PROCEDURE (cons: Cons) WriteChar (c: CHAR);
  74. VAR ss: ARRAY 1 OF CHAR;
  75. BEGIN
  76. ss[0] := c;
  77. Print(ss, 1)
  78. END WriteChar;
  79. PROCEDURE (cons: Cons) WriteStr (IN text: ARRAY OF CHAR);
  80. BEGIN
  81. Print(text, LEN(text$))
  82. END WriteStr;
  83. PROCEDURE (cons: Cons) WriteLn;
  84. BEGIN
  85. Print(0DX + 0AX, 2)
  86. END WriteLn;
  87. PROCEDURE Init;
  88. VAR res: WinApi.BOOL;
  89. BEGIN
  90. NEW(cons);
  91. res := WinApi.AllocConsole(); (* Open console on module load time *)
  92. out := WinApi.GetStdHandle(WinApi.STD_OUTPUT_HANDLE);
  93. in := WinApi.GetStdHandle(WinApi.STD_INPUT_HANDLE);
  94. inBufW := 0; inBufR := 0;
  95. Console.SetConsole(cons)
  96. END Init;
  97. BEGIN
  98. Init
  99. END HostConsole.