Commit | Line | Data |
---|---|---|
1662094b BJ |
1 | .if !\n(xx .so tmac.p |
2 | .nr H1 2 | |
3 | .if n .ND | |
4 | .NH | |
5 | Input/output | |
6 | .NH 2 | |
7 | The files structure | |
8 | .PP | |
9 | Each file in the Pascal environment is represented by a pointer | |
10 | to a | |
11 | .I files | |
12 | structure in the heap. | |
13 | At the location addressed by the pointer is the element | |
14 | in the file's window variable. | |
15 | Behind this window variable is information about the file, | |
16 | at the following offsets: | |
17 | .TS | |
18 | center; | |
19 | n l l. | |
20 | \-14 FBUF Pointer to i/o buffer | |
21 | \-12 FCHAIN Chain to next file | |
22 | \-10 FLEV Pointer to associated block mark | |
23 | \-8 PFNAME Name of file for error messages | |
24 | \-6 FNAME Name of associated file | |
25 | \-4 FUNIT Unit number packed with flags | |
26 | \-2 FSIZE Size of elements in the file | |
27 | 0 File window element | |
28 | .TE | |
29 | .PP | |
30 | Here | |
31 | .SM FBUF | |
32 | is a pointer to the input or output buffer for the file. | |
33 | The standard system routines | |
34 | .I getc | |
35 | and | |
36 | .I putc | |
37 | are used and provide block buffered input/output, | |
38 | with 512 characters normally transferred at each read or write. | |
39 | .PP | |
40 | The files in the | |
41 | Pascal environment, | |
42 | with the exception of | |
43 | .I input | |
44 | and | |
45 | .I output | |
46 | are all linked together on a single file chain through the | |
47 | .SM FCHAIN | |
48 | links. | |
49 | For each file the | |
50 | .SM FLEV | |
51 | pointer gives its associated block mark. | |
52 | These are used to free files at block exit as described in section 3.3 | |
53 | below. | |
54 | .PP | |
55 | The | |
56 | NAME | |
57 | and | |
58 | PFNAME | |
59 | give the associated | |
60 | file name for the file and the name to be used when printing | |
61 | error diagnostics respectively. | |
62 | Although these names are usually the same, | |
63 | .I input | |
64 | and | |
65 | .I output | |
66 | usually have no associated | |
67 | file name so the distinction is necessary. | |
68 | .PP | |
69 | The | |
70 | FUNIT | |
71 | word contains the | |
72 | unit number on which the file is open as well as a set of flags. | |
73 | These flags and their representations are: | |
74 | .TS | |
75 | center; | |
76 | l l l. | |
77 | EOF 00400 At end-of-file | |
78 | EOLN 01000 At end-of-line | |
79 | SYNC 02000 File window is out of sync | |
80 | TEMP 04000 File is temporary | |
81 | FREAD 02000 File is open for reading | |
82 | FWRITE 04000 File is open for writing | |
83 | FTEXT 08000 File is a text file; process EOLN | |
84 | .TE | |
85 | .PP | |
86 | The | |
87 | EOF | |
88 | and | |
89 | EOLN | |
90 | bits here reflect the associated built-in function values. | |
91 | TEMP | |
92 | indicates that the file has a generated temporary name and that | |
93 | it should therefore be removed when its block exits. | |
94 | FREAD | |
95 | and | |
96 | FWRITE | |
97 | indicate that | |
98 | .I reset | |
99 | and | |
100 | .I rewrite | |
101 | respectively have been performed on the file so that | |
102 | input or output operations should be attempted. | |
103 | FTEXT | |
104 | indicates the file is a text file so that | |
105 | EOLN | |
106 | processing should be done, | |
107 | with newline characters turned into blanks, etc. | |
108 | .PP | |
109 | The | |
110 | SYNC | |
111 | bit, | |
112 | when true, | |
113 | indicates that there is no usable image in the file buffer window. | |
114 | As discussed in the | |
115 | .I "Berkeley Pascal User's Manual," | |
116 | it is necessary, | |
117 | because of the interactive environment, | |
118 | to have ``input^'' essentially undefined at the beginning | |
119 | of execution so that a program may print a prompt | |
120 | before the user is required to type input. | |
121 | The | |
122 | SYNC | |
123 | bit implements this. | |
124 | When it is set, | |
125 | it indicates that before the element in the window | |
126 | can be used the Pascal system must actually put something there. | |
127 | This is never done until necessary. | |
128 | .NH 2 | |
129 | Initialization of files | |
130 | .PP | |
131 | All the variables in the Pascal runtime environment are cleared to zero on | |
132 | block entry. | |
133 | This is necessary for simple processing of files. | |
134 | If a file is unused, its pointer will be | |
135 | .B nil. | |
136 | All references to an inactive file are thus references through a | |
137 | .B nil | |
138 | pointer. | |
139 | If the Pascal system did not clear storage to zero before execution | |
140 | it would not be possible to detect inactive files in this simple way; | |
141 | it would probably be necessary to generate (possibly complicated) | |
142 | code to initialize | |
143 | each file on block entry. | |
144 | .PP | |
145 | When a file is first mentioned in a | |
146 | .I reset | |
147 | or | |
148 | .I rewrite | |
149 | call, | |
150 | a buffer of the form described above is associated with it, | |
151 | and the necessary information about the file is placed in this | |
152 | buffer. | |
153 | The file is also linked into the active file chain. | |
154 | This chain is kept sorted by block mark address, the | |
155 | FLEV | |
156 | entries. | |
157 | .NH 2 | |
158 | Block exit | |
159 | .PP | |
160 | When block exit occurs the interpreter must free the files which are in | |
161 | use in the block | |
162 | and their associated buffers. | |
163 | This is simple and efficient because the files in the active file chain are | |
164 | sorted by increasing block mark address. | |
165 | This means that the files for the current block will be at the front | |
166 | of the chain. | |
167 | For each file which is no longer accessible | |
168 | the interpreter first flushes the files buffer | |
169 | if it is an output file. | |
170 | The interpreter then returns the file buffer and the files structure and window | |
171 | to the free space in the heap and removes the file from the active file chain. | |
172 | .NH 2 | |
173 | Flushing | |
174 | .PP | |
175 | Flushing all the file buffers at abnormal termination, | |
176 | or on a call to the procedure | |
177 | .I flush | |
178 | or | |
179 | .I message | |
180 | is quite easy. | |
181 | The Pascal system simply flushes the file | |
182 | .I output | |
183 | and each file on the file chain which has the | |
184 | FWRITE | |
185 | bit set in its flags word. | |
186 | .NH 2 | |
187 | The active file | |
188 | .PP | |
189 | For the purposes of input-output, | |
190 | .I px | |
191 | maintains a notion of an active file. | |
192 | Each operation which references a file makes the file | |
193 | it will be using the active file and then performs its operation. | |
194 | A subtle point here is that one may do a procedure call to | |
195 | .I write | |
196 | which involves a call to a function which references another file, | |
197 | thereby destroying the active file set up before the | |
198 | .I write. | |
199 | For this reason, | |
200 | the active file is saved at block entry | |
201 | in the block mark and restored at block exit.\*(Dg | |
202 | .FS | |
203 | \*(dgIt would probably be better to dispense with the notion of | |
204 | active file and use another mechanism which did not involve extra | |
205 | overhead on each procedure and function call. | |
206 | .FE | |
207 | .NH 2 | |
208 | File operations | |
209 | .PP | |
210 | Files in Pascal can be used in two distinct ways: | |
211 | as the object of | |
212 | .I read, | |
213 | .I write, | |
214 | .I get, | |
215 | and | |
216 | .I put | |
217 | calls, or indirectly as though they were pointers. | |
218 | It should be noted that the second use as pointers must be careful | |
219 | not to destroy the active file in a reference such as | |
220 | .LS | |
221 | write(output, input\(ua) | |
222 | .LE | |
223 | or the system would end up writing on the input device. | |
224 | .PP | |
225 | The fundamental operator related to the use of a file is | |
226 | FNIL. | |
227 | This takes the file variable, as a pointer, | |
228 | insures that the pointer is not | |
229 | .B nil, | |
230 | and also that a usable image is in the file window, | |
231 | by forcing the | |
232 | SYNC | |
233 | bit to be cleared. | |
234 | .PP | |
235 | The rest of the uses of files and the file operations may be summarized | |
236 | by a simple example: | |
237 | .LS | |
238 | write('*') | |
239 | .LE | |
240 | which generates the code | |
241 | .LS | |
242 | \s-2UNITOUT\s0 | |
243 | \s-2CONC\s0 '*' | |
244 | \s-2WRITC\s0 | |
245 | .LE | |
246 | Here the operator | |
247 | .SM UNITOUT | |
248 | is an abbreviated form of the operator | |
249 | .SM UNIT | |
250 | which sets the active file, | |
251 | when the file to be made active is | |
252 | .I output. | |
253 | Thus to write a character to the file | |
254 | .I output | |
255 | it is only necessary to make | |
256 | .I output | |
257 | the active file, | |
258 | to place the character to be output | |
259 | on the stack, | |
260 | and to do a | |
261 | .SM WRITC | |
262 | write character operation. | |
263 | .PP | |
264 | Files other than | |
265 | .I output | |
266 | differ from this example only in that the operator | |
267 | .op UNIT | |
268 | is used preceded by an evaluation of the file variable expression. | |
269 | Thus | |
270 | .LS | |
271 | writeln(f) | |
272 | .LE | |
273 | produces | |
274 | .LS | |
275 | \s-2RV\s0 \fIf\fP | |
276 | \s-2UNIT\s0 | |
277 | \s-2WRITELN\s0 | |
278 | .LE | |
279 | .PP | |
280 | Write widths are easily handled here by packing information | |
281 | about the presence or absence of width specifications and their | |
282 | types into the sub-operation code and pushing the values | |
283 | of the write widths onto the top of the stack. | |
284 | .PP | |
285 | One other operation worth mentioning is | |
286 | .SM DEFNAME | |
287 | which is used to implement the program statement association of | |
288 | file names. | |
289 | .SM DEFNAME | |
290 | simply allocates the | |
291 | .I files | |
292 | (section 3.1) area for the given file as though | |
293 | it had been the object of a | |
294 | .I reset | |
295 | or | |
296 | .I rewrite | |
297 | call, initializing the | |
298 | FNAME | |
299 | field, but omitting the system interactions associated with | |
300 | and actual | |
301 | .I reset | |
302 | or | |
303 | .I rewrite. |