inout.mod 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. IMPLEMENTATION MODULE InOut;
  2. (* Layered on the file shim (SysShim), so OpenInput/OpenOutput can
  3. redirect the current input/output streams. *)
  4. FROM SYSTEM IMPORT ADDRESS;
  5. IMPORT SysShim;
  6. VAR
  7. inH, outH : ADDRESS;
  8. opened : BOOLEAN; (* a redirected file is open *)
  9. PROCEDURE SetDone (b : BOOLEAN);
  10. BEGIN
  11. Done := b
  12. END SetDone;
  13. PROCEDURE TrimName (VAR s : ARRAY OF CHAR; defext : ARRAY OF CHAR);
  14. (* Drop a trailing newline and, if the name ends in '.', append
  15. defext (the classic InOut convention). *)
  16. VAR i, j, k : CARDINAL;
  17. BEGIN
  18. i := 0;
  19. WHILE (i <= HIGH(s)) AND (s[i] # CHR(0)) DO INC(i) END;
  20. IF (i > 0) AND (s[i-1] = CHR(10)) THEN DEC(i); s[i] := CHR(0) END;
  21. IF (i > 0) AND (s[i-1] = CHR(13)) THEN DEC(i); s[i] := CHR(0) END;
  22. IF (i > 0) AND (s[i-1] = ".") THEN
  23. j := i;
  24. k := 0;
  25. WHILE (k <= HIGH(defext)) AND (defext[k] # CHR(0)) AND (j <= HIGH(s)) DO
  26. s[j] := defext[k]; INC(j); INC(k)
  27. END;
  28. IF j <= HIGH(s) THEN s[j] := CHR(0) END
  29. END
  30. END TrimName;
  31. PROCEDURE OpenInput (defext : ARRAY OF CHAR);
  32. VAR name : ARRAY [0 .. 1023] OF CHAR;
  33. h : ADDRESS;
  34. n : CARDINAL;
  35. BEGIN
  36. name[0] := CHR(0);
  37. n := SysShim.freadline(SysShim.stdin(), name, HIGH(name) + 1);
  38. TrimName(name, defext);
  39. h := SysShim.fopenread(name);
  40. IF h = NIL THEN Done := FALSE
  41. ELSE inH := h; Done := TRUE
  42. END
  43. END OpenInput;
  44. PROCEDURE CloseInput;
  45. BEGIN
  46. IF inH # SysShim.stdin() THEN SysShim.fclose(inH) END;
  47. inH := SysShim.stdin(); Done := TRUE
  48. END CloseInput;
  49. PROCEDURE OpenOutput (defext : ARRAY OF CHAR);
  50. VAR name : ARRAY [0 .. 1023] OF CHAR;
  51. h : ADDRESS;
  52. n : CARDINAL;
  53. BEGIN
  54. name[0] := CHR(0);
  55. n := SysShim.freadline(SysShim.stdin(), name, HIGH(name) + 1);
  56. TrimName(name, defext);
  57. h := SysShim.fopenwrite(name);
  58. IF h = NIL THEN Done := FALSE
  59. ELSE outH := h; Done := TRUE
  60. END
  61. END OpenOutput;
  62. PROCEDURE CloseOutput;
  63. BEGIN
  64. IF outH # SysShim.stdout() THEN SysShim.fclose(outH) END;
  65. outH := SysShim.stdout(); Done := TRUE
  66. END CloseOutput;
  67. PROCEDURE Read (VAR ch : CHAR);
  68. BEGIN
  69. ch := SysShim.fgetc(inH);
  70. termCH := ch;
  71. Done := (ch # CHR(0))
  72. END Read;
  73. PROCEDURE ReadString (VAR s : ARRAY OF CHAR);
  74. VAR n : CARDINAL;
  75. BEGIN
  76. n := SysShim.freadline(inH, s, HIGH(s) + 1);
  77. Done := TRUE
  78. END ReadString;
  79. PROCEDURE ReadInt (VAR x : INTEGER);
  80. BEGIN
  81. x := SysShim.freadint(inH);
  82. Done := TRUE
  83. END ReadInt;
  84. PROCEDURE ReadCard (VAR x : CARDINAL);
  85. BEGIN
  86. x := VAL(CARDINAL, SysShim.freadint(inH));
  87. Done := TRUE
  88. END ReadCard;
  89. PROCEDURE Write (ch : CHAR);
  90. BEGIN
  91. SysShim.fputc(outH, ch)
  92. END Write;
  93. PROCEDURE WriteLn;
  94. BEGIN
  95. SysShim.fwriteln(outH)
  96. END WriteLn;
  97. PROCEDURE WriteString (s : ARRAY OF CHAR);
  98. BEGIN
  99. SysShim.fputs(outH, s)
  100. END WriteString;
  101. PROCEDURE WriteInt (x : INTEGER; n : CARDINAL);
  102. BEGIN
  103. SysShim.fwriteintw(outH, x, n)
  104. END WriteInt;
  105. PROCEDURE WriteCard (x : CARDINAL; n : CARDINAL);
  106. BEGIN
  107. SysShim.fwriteintw(outH, x, n)
  108. END WriteCard;
  109. PROCEDURE WriteRadix (x : CARDINAL; n : CARDINAL; base : CARDINAL);
  110. VAR tmp : ARRAY [0 .. 31] OF CHAR;
  111. i, k : CARDINAL;
  112. v : CARDINAL;
  113. digit : CARDINAL;
  114. PROCEDURE EmitChar (c : CHAR);
  115. BEGIN
  116. SysShim.fputc(outH, c)
  117. END EmitChar;
  118. BEGIN
  119. v := x; i := 0;
  120. IF v = 0 THEN tmp[0] := "0"; i := 1
  121. ELSE
  122. WHILE (v > 0) AND (i <= HIGH(tmp)) DO
  123. digit := v MOD base;
  124. IF digit < 10 THEN tmp[i] := CHR(ORD("0") + digit)
  125. ELSE tmp[i] := CHR(ORD("A") + digit - 10)
  126. END;
  127. v := v DIV base;
  128. INC(i)
  129. END
  130. END;
  131. (* pad with spaces to width n *)
  132. k := i;
  133. WHILE k < n DO EmitChar(" "); INC(k) END;
  134. WHILE i > 0 DO DEC(i); EmitChar(tmp[i]) END
  135. END WriteRadix;
  136. PROCEDURE WriteOct (x : CARDINAL; n : CARDINAL);
  137. BEGIN
  138. WriteRadix(x, n, 8)
  139. END WriteOct;
  140. PROCEDURE WriteHex (x : CARDINAL; n : CARDINAL);
  141. BEGIN
  142. WriteRadix(x, n, 16)
  143. END WriteHex;
  144. BEGIN
  145. inH := SysShim.stdin();
  146. outH := SysShim.stdout();
  147. Done := TRUE;
  148. termCH := CHR(0)
  149. END InOut.