source: trunk/minix/lib/ack/libm2/InOut.mod@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 7.5 KB
RevLine 
[9]1(*
2 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 See the copyright notice in the ACK home directory, in the file "Copyright".
4*)
5
6(*$R-*)
7IMPLEMENTATION MODULE InOut ;
8(*
9 Module: Wirth's Input/Output module
10 Author: Ceriel J.H. Jacobs
11 Version: $Header: /cvsup/minix/src/lib/ack/libm2/InOut.mod,v 1.1 2005/10/10 15:27:46 beng Exp $
12*)
13
14 IMPORT Streams;
15 FROM Conversions IMPORT
16 ConvertCardinal, ConvertInteger,
17 ConvertOctal, ConvertHex;
18 FROM Traps IMPORT Message;
19
20 CONST TAB = 11C;
21
22 TYPE numbuf = ARRAY[0..255] OF CHAR;
23
24 VAR unread: BOOLEAN;
25 unreadch: CHAR;
26 CurrIn, CurrOut: Streams.Stream;
27 result: Streams.StreamResult;
28
29 PROCEDURE Read(VAR c : CHAR);
30
31 BEGIN
32 IF unread THEN
33 unread := FALSE;
34 c := unreadch;
35 Done := TRUE;
36 ELSE
37 Streams.Read(CurrIn, c, result);
38 Done := result = Streams.succeeded;
39 END;
40 END Read;
41
42 PROCEDURE UnRead(ch: CHAR);
43 BEGIN
44 unread := TRUE;
45 unreadch := ch;
46 END UnRead;
47
48 PROCEDURE Write(c: CHAR);
49 BEGIN
50 Streams.Write(CurrOut, c, result);
51 END Write;
52
53 PROCEDURE OpenInput(defext: ARRAY OF CHAR);
54 VAR namebuf : ARRAY [1..128] OF CHAR;
55 BEGIN
56 IF CurrIn # Streams.InputStream THEN
57 Streams.CloseStream(CurrIn, result);
58 END;
59 MakeFileName("Name of input file: ", defext, namebuf);
60 IF NOT Done THEN RETURN; END;
61 openinput(namebuf);
62 END OpenInput;
63
64 PROCEDURE OpenInputFile(filename: ARRAY OF CHAR);
65 BEGIN
66 IF CurrIn # Streams.InputStream THEN
67 Streams.CloseStream(CurrIn, result);
68 END;
69 openinput(filename);
70 END OpenInputFile;
71
72 PROCEDURE openinput(namebuf: ARRAY OF CHAR);
73 BEGIN
74 IF (namebuf[0] = '-') AND (namebuf[1] = 0C) THEN
75 CurrIn := Streams.InputStream;
76 Done := TRUE;
77 ELSE
78 Streams.OpenStream(CurrIn, namebuf, Streams.text,
79 Streams.reading, result);
80 Done := result = Streams.succeeded;
81 END;
82 END openinput;
83
84 PROCEDURE CloseInput;
85 BEGIN
86 IF CurrIn # Streams.InputStream THEN
87 Streams.CloseStream(CurrIn, result);
88 END;
89 CurrIn := Streams.InputStream;
90 END CloseInput;
91
92 PROCEDURE OpenOutput(defext: ARRAY OF CHAR);
93 VAR namebuf : ARRAY [1..128] OF CHAR;
94 BEGIN
95 IF CurrOut # Streams.OutputStream THEN
96 Streams.CloseStream(CurrOut, result);
97 END;
98 MakeFileName("Name of output file: ", defext, namebuf);
99 IF NOT Done THEN RETURN; END;
100 openoutput(namebuf);
101 END OpenOutput;
102
103 PROCEDURE OpenOutputFile(filename: ARRAY OF CHAR);
104 BEGIN
105 IF CurrOut # Streams.OutputStream THEN
106 Streams.CloseStream(CurrOut, result);
107 END;
108 openoutput(filename);
109 END OpenOutputFile;
110
111 PROCEDURE openoutput(namebuf: ARRAY OF CHAR);
112 BEGIN
113 IF (namebuf[1] = '-') AND (namebuf[2] = 0C) THEN
114 CurrOut := Streams.OutputStream;
115 Done := TRUE;
116 ELSE
117 Streams.OpenStream(CurrOut, namebuf, Streams.text,
118 Streams.writing, result);
119 Done := result = Streams.succeeded;
120 END;
121 END openoutput;
122
123 PROCEDURE CloseOutput;
124 BEGIN
125 IF CurrOut # Streams.OutputStream THEN
126 Streams.CloseStream(CurrOut, result);
127 END;
128 CurrOut := Streams.OutputStream;
129 END CloseOutput;
130
131 PROCEDURE MakeFileName(prompt, defext : ARRAY OF CHAR;
132 VAR buf : ARRAY OF CHAR);
133 VAR i : INTEGER;
134 j : CARDINAL;
135 BEGIN
136 Done := TRUE;
137 IF Streams.isatty(Streams.InputStream, result) THEN
138 XWriteString(prompt);
139 END;
140 XReadString(buf);
141 i := 0;
142 WHILE buf[i] # 0C DO i := i + 1 END;
143 IF i # 0 THEN
144 i := i - 1;
145 IF buf[i] = '.' THEN
146 FOR j := 0 TO HIGH(defext) DO
147 i := i + 1;
148 buf[i] := defext[j];
149 END;
150 buf[i+1] := 0C;
151 END;
152 RETURN;
153 END;
154 Done := FALSE;
155 END MakeFileName;
156
157 PROCEDURE ReadInt(VAR integ : INTEGER);
158 CONST
159 SAFELIMITDIV10 = MAX(INTEGER) DIV 10;
160 SAFELIMITREM10 = MAX(INTEGER) MOD 10;
161 TYPE
162 itype = [0..31];
163 ibuf = ARRAY itype OF CHAR;
164 VAR
165 int : INTEGER;
166 neg : BOOLEAN;
167 safedigit: [0 .. 9];
168 chvalue: CARDINAL;
169 buf : ibuf;
170 index : itype;
171 BEGIN
172 ReadString(buf);
173 IF NOT Done THEN
174 RETURN
175 END;
176 index := 0;
177 IF buf[index] = '-' THEN
178 neg := TRUE;
179 INC(index);
180 ELSIF buf[index] = '+' THEN
181 neg := FALSE;
182 INC(index);
183 ELSE
184 neg := FALSE
185 END;
186
187 safedigit := SAFELIMITREM10;
188 IF neg THEN safedigit := safedigit + 1 END;
189 int := 0;
190 WHILE (buf[index] >= '0') & (buf[index] <= '9') DO
191 chvalue := ORD(buf[index]) - ORD('0');
192 IF (int > SAFELIMITDIV10) OR
193 ( (int = SAFELIMITDIV10) AND
194 (chvalue > safedigit)) THEN
195 Message("integer too large");
196 HALT;
197 ELSE
198 int := 10*int + VAL(INTEGER, chvalue);
199 INC(index)
200 END;
201 END;
202 IF neg THEN
203 integ := -int
204 ELSE
205 integ := int
206 END;
207 IF buf[index] > " " THEN
208 Message("illegal integer");
209 HALT;
210 END;
211 Done := TRUE;
212 END ReadInt;
213
214 PROCEDURE ReadCard(VAR card : CARDINAL);
215 CONST
216 SAFELIMITDIV10 = MAX(CARDINAL) DIV 10;
217 SAFELIMITREM10 = MAX(CARDINAL) MOD 10;
218
219 TYPE
220 itype = [0..31];
221 ibuf = ARRAY itype OF CHAR;
222
223 VAR
224 int : CARDINAL;
225 index : itype;
226 buf : ibuf;
227 safedigit: [0 .. 9];
228 chvalue: CARDINAL;
229 BEGIN
230 ReadString(buf);
231 IF NOT Done THEN RETURN; END;
232 index := 0;
233 safedigit := SAFELIMITREM10;
234 int := 0;
235 WHILE (buf[index] >= '0') & (buf[index] <= '9') DO
236 chvalue := ORD(buf[index]) - ORD('0');
237 IF (int > SAFELIMITDIV10) OR
238 ( (int = SAFELIMITDIV10) AND
239 (chvalue > safedigit)) THEN
240 Message("cardinal too large");
241 HALT;
242 ELSE
243 int := 10*int + chvalue;
244 INC(index);
245 END;
246 END;
247 IF buf[index] > " " THEN
248 Message("illegal cardinal");
249 HALT;
250 END;
251 card := int;
252 Done := TRUE;
253 END ReadCard;
254
255 PROCEDURE ReadString(VAR s : ARRAY OF CHAR);
256 TYPE charset = SET OF CHAR;
257 VAR i : CARDINAL;
258 ch : CHAR;
259
260 BEGIN
261 i := 0;
262 REPEAT
263 Read(ch);
264 UNTIL NOT (ch IN charset{' ', TAB, 12C, 15C});
265 IF NOT Done THEN
266 RETURN;
267 END;
268 UnRead(ch);
269 REPEAT
270 Read(ch);
271 termCH := ch;
272 IF i <= HIGH(s) THEN
273 s[i] := ch;
274 IF (NOT Done) OR (ch <= " ") THEN
275 s[i] := 0C;
276 END;
277 END;
278 INC(i);
279 UNTIL (NOT Done) OR (ch <= " ");
280 IF Done THEN UnRead(ch); END;
281 END ReadString;
282
283 PROCEDURE XReadString(VAR s : ARRAY OF CHAR);
284 VAR j : CARDINAL;
285 ch : CHAR;
286
287 BEGIN
288 j := 0;
289 LOOP
290 Streams.Read(Streams.InputStream, ch, result);
291 IF result # Streams.succeeded THEN
292 EXIT;
293 END;
294 IF ch <= " " THEN
295 s[j] := 0C;
296 EXIT;
297 END;
298 IF j < HIGH(s) THEN
299 s[j] := ch;
300 INC(j);
301 END;
302 END;
303 END XReadString;
304
305 PROCEDURE XWriteString(s: ARRAY OF CHAR);
306 VAR i: CARDINAL;
307 BEGIN
308 i := 0;
309 LOOP
310 IF (i <= HIGH(s)) AND (s[i] # 0C) THEN
311 Streams.Write(Streams.OutputStream, s[i], result);
312 INC(i);
313 ELSE
314 EXIT;
315 END;
316 END;
317 END XWriteString;
318
319 PROCEDURE WriteCard(card, width : CARDINAL);
320 VAR
321 buf : numbuf;
322 BEGIN
323 ConvertCardinal(card, width, buf);
324 WriteString(buf);
325 END WriteCard;
326
327 PROCEDURE WriteInt(int : INTEGER; width : CARDINAL);
328 VAR
329 buf : numbuf;
330 BEGIN
331 ConvertInteger(int, width, buf);
332 WriteString(buf);
333 END WriteInt;
334
335 PROCEDURE WriteHex(card, width : CARDINAL);
336 VAR
337 buf : numbuf;
338 BEGIN
339 ConvertHex(card, width, buf);
340 WriteString(buf);
341 END WriteHex;
342
343 PROCEDURE WriteLn;
344 BEGIN
345 Write(EOL)
346 END WriteLn;
347
348 PROCEDURE WriteOct(card, width : CARDINAL);
349 VAR
350 buf : numbuf;
351 BEGIN
352 ConvertOctal(card, width, buf);
353 WriteString(buf);
354 END WriteOct;
355
356 PROCEDURE WriteString(str : ARRAY OF CHAR);
357 VAR
358 nbytes : CARDINAL;
359 BEGIN
360 nbytes := 0;
361 WHILE (nbytes <= HIGH(str)) AND (str[nbytes] # 0C) DO
362 Write(str[nbytes]);
363 INC(nbytes)
364 END;
365 END WriteString;
366
367BEGIN (* InOut initialization *)
368 CurrIn := Streams.InputStream;
369 CurrOut := Streams.OutputStream;
370 unread := FALSE;
371END InOut.
Note: See TracBrowser for help on using the repository browser.