]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/m2/gm2-libs-iso/SeqFile.mod
Update copyright years.
[thirdparty/gcc.git] / gcc / m2 / gm2-libs-iso / SeqFile.mod
CommitLineData
1eee94d3
GM
1(* SeqFile.mod implement the ISO SeqFile specification.
2
83ffe9cd 3Copyright (C) 2008-2023 Free Software Foundation, Inc.
1eee94d3
GM
4Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
5
6This file is part of GNU Modula-2.
7
8GNU Modula-2 is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GNU Modula-2 is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16General Public License for more details.
17
18Under Section 7 of GPL version 3, you are granted additional
19permissions described in the GCC Runtime Library Exception, version
203.1, as published by the Free Software Foundation.
21
22You should have received a copy of the GNU General Public License and
23a copy of the GCC Runtime Library Exception along with this program;
24see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25<http://www.gnu.org/licenses/>. *)
26
27IMPLEMENTATION MODULE SeqFile ;
28
29FROM RTgen IMPORT ChanDev, DeviceType,
30 InitChanDev, doLook, doSkip, doSkipLook, doWriteLn,
31 doReadText, doWriteText, doReadLocs, doWriteLocs,
32 checkErrno ;
33
34FROM RTfio IMPORT doreadchar, dounreadchar, dogeterrno, dorbytes,
35 dowbytes, dowriteln, iseof, iseoln, iserror ;
36
37FROM IOLink IMPORT DeviceId, DeviceTablePtr, IsDevice, MakeChan, UnMakeChan,
38 DeviceTablePtrValue, RAISEdevException, AllocateDeviceId,
39 ResetProc ;
40
41FROM RTgenif IMPORT GenDevIF, InitGenDevIF ;
42FROM FIO IMPORT File ;
43FROM errno IMPORT geterrno ;
44FROM IOConsts IMPORT ReadResults ;
45FROM ChanConsts IMPORT readFlag, writeFlag ;
46
47IMPORT FIO, SYSTEM, RTio, errno, ErrnoCategory ;
48
49
50VAR
51 dev: ChanDev ;
52 did: DeviceId ;
53
54
55PROCEDURE look (d: DeviceTablePtr;
56 VAR ch: CHAR; VAR r: ReadResults) ;
57BEGIN
58 doLook(dev, d, ch, r)
59END look ;
60
61
62PROCEDURE skip (d: DeviceTablePtr) ;
63BEGIN
64 doSkip(dev, d)
65END skip ;
66
67
68PROCEDURE skiplook (d: DeviceTablePtr;
69 VAR ch: CHAR; VAR r: ReadResults) ;
70BEGIN
71 doSkipLook(dev, d, ch, r)
72END skiplook ;
73
74
75PROCEDURE lnwrite (d: DeviceTablePtr) ;
76BEGIN
77 doWriteLn(dev, d)
78END lnwrite ;
79
80
81PROCEDURE textread (d: DeviceTablePtr;
82 to: SYSTEM.ADDRESS;
83 maxChars: CARDINAL;
84 VAR charsRead: CARDINAL) ;
85BEGIN
86 doReadText(dev, d, to, maxChars, charsRead)
87END textread ;
88
89
90PROCEDURE textwrite (d: DeviceTablePtr;
91 from: SYSTEM.ADDRESS;
92 charsToWrite: CARDINAL);
93BEGIN
94 doWriteText(dev, d, from, charsToWrite)
95END textwrite ;
96
97
98PROCEDURE rawread (d: DeviceTablePtr;
99 to: SYSTEM.ADDRESS;
100 maxLocs: CARDINAL;
101 VAR locsRead: CARDINAL) ;
102BEGIN
103 doReadLocs(dev, d, to, maxLocs, locsRead)
104END rawread ;
105
106
107PROCEDURE rawwrite (d: DeviceTablePtr;
108 from: SYSTEM.ADDRESS;
109 locsToWrite: CARDINAL) ;
110BEGIN
111 doWriteLocs(dev, d, from, locsToWrite)
112END rawwrite ;
113
114
115PROCEDURE getname (d: DeviceTablePtr;
116 VAR a: ARRAY OF CHAR) ;
117BEGIN
118 FIO.GetFileName(RTio.GetFile(d^.cid), a)
119END getname ;
120
121
122PROCEDURE flush (d: DeviceTablePtr) ;
123BEGIN
124 FIO.FlushBuffer(RTio.GetFile(d^.cid))
125END flush ;
126
127
128(*
129 checkOpenErrno - assigns, e, and, res, depending upon file result of opening,
130 file.
131*)
132
133PROCEDURE checkOpenErrno (file: FIO.File; VAR e: INTEGER; VAR res: OpenResults) ;
134BEGIN
135 IF FIO.IsNoError(file)
136 THEN
137 e := 0 ;
138 ELSE
139 e := errno.geterrno()
140 END ;
141 res := ErrnoCategory.GetOpenResults(e)
142END checkOpenErrno ;
143
144
145(*
146 newCid - returns a ChanId which represents the opened file, name.
147 res is set appropriately on return.
148*)
149
150PROCEDURE newCid (fname: ARRAY OF CHAR;
151 f: FlagSet;
152 VAR res: OpenResults;
153 toRead: BOOLEAN;
154 whichreset: ResetProc) : ChanId ;
155VAR
156 c : RTio.ChanId ;
157 file: FIO.File ;
158 e : INTEGER ;
159 p : DeviceTablePtr ;
160BEGIN
161 IF toRead
162 THEN
163 file := FIO.OpenToRead(fname)
164 ELSE
165 file := FIO.OpenToWrite(fname)
166 END ;
167 checkOpenErrno(file, e, res) ;
168
169 IF FIO.IsNoError(file)
170 THEN
171 MakeChan(did, c) ;
172 RTio.SetFile(c, file) ;
173 p := DeviceTablePtrValue(c, did) ;
174 WITH p^ DO
175 flags := f ;
176 errNum := e ;
177 doLook := look ;
178 doSkip := skip ;
179 doSkipLook := skiplook ;
180 doLnWrite := lnwrite ;
181 doTextRead := textread ;
182 doTextWrite := textwrite ;
183 doRawRead := rawread ;
184 doRawWrite := rawwrite ;
185 doGetName := getname ;
186 doReset := whichreset ;
187 doFlush := flush ;
188 doFree := handlefree
189 END ;
190 RETURN( c )
191 ELSE
192 RETURN( IOChan.InvalidChan() )
193 END
194END newCid ;
195
196
197(*
198 Attempts to obtain and open a channel connected to a stored rewindable
199 file of the given name. The write flag is implied; without the raw
200 flag, text is implied. If successful, assigns to cid the identity of
201 the opened channel, assigns the value opened to res, and selects
202 output mode, with the write position at the start of the file (i.e.
203 the file is of zero length). If a channel cannot be opened as required,
204 the value of res indicates the reason, and cid identifies the
205 invalid channel.
206*)
207
208PROCEDURE OpenWrite (VAR cid: ChanId; name: ARRAY OF CHAR; flags: FlagSet;
209 VAR res: OpenResults) ;
210BEGIN
211 INCL(flags, ChanConsts.writeFlag) ;
212 IF NOT (ChanConsts.rawFlag IN flags)
213 THEN
214 INCL(flags, ChanConsts.textFlag)
215 END ;
216 cid := newCid(name, flags, res, FALSE, resetWrite)
217END OpenWrite ;
218
219
220(*
221 Attempts to obtain and open a channel connected to a stored rewindable
222 file of the given name. The read and old flags are implied; without
223 the raw flag, text is implied. If successful, assigns to cid the
224 identity of the opened channel, assigns the value opened to res, and
225 selects input mode, with the read position corresponding to the start
226 of the file. If a channel cannot be opened as required, the value of
227 res indicates the reason, and cid identifies the invalid channel.
228*)
229
230PROCEDURE OpenRead (VAR cid: ChanId; name: ARRAY OF CHAR; flags: FlagSet;
231 VAR res: OpenResults) ;
232BEGIN
233 flags := flags + ChanConsts.read + ChanConsts.old ;
234 IF NOT (ChanConsts.rawFlag IN flags)
235 THEN
236 INCL(flags, ChanConsts.textFlag)
237 END ;
238 cid := newCid(name, flags, res, TRUE, resetRead)
239END OpenRead ;
240
241
242(*
243 OpenAppend - attempts to obtain and open a channel connected
244 to a stored rewindable file of the given name.
245 The write and old flags are implied; without
246 the raw flag, text is implied. If successful,
247 assigns to cid the identity of the opened channel,
248 assigns the value opened to res, and selects output
249 mode, with the write position corresponding to the
250 length of the file. If a channel cannot be opened
251 as required, the value of res indicates the reason,
252 and cid identifies the invalid channel.
253 *)
254
255PROCEDURE OpenAppend (VAR cid: ChanId; name: ARRAY OF CHAR;
256 flags: FlagSet; VAR res: OpenResults) ;
257BEGIN
258 flags := flags + ChanConsts.write + ChanConsts.old ;
259 IF NOT (ChanConsts.rawFlag IN flags)
260 THEN
261 INCL(flags, ChanConsts.textFlag)
262 END ;
263 cid := newCid(name, flags, res, FALSE, resetAppend) ;
264 IF IsSeqFile(cid)
265 THEN
266 FIO.SetPositionFromEnd(RTio.GetFile(cid), 0) ;
267 checkErrno(dev, RTio.GetDevicePtr(cid))
268 END
269END OpenAppend ;
270
271
272(*
273 resetAppend - ensures that +write and -read and seeks to
274 the end of the file.
275*)
276
277PROCEDURE resetAppend (d: DeviceTablePtr) ;
278VAR
279 f: FIO.File ;
280BEGIN
281 WITH d^ DO
282 flags := flags + write - read ;
283 FIO.SetPositionFromEnd(RTio.GetFile(cid), 0) ;
284 END ;
285 checkErrno(dev, d)
286END resetAppend ;
287
288
289(*
290 resetRead -
291*)
292
293PROCEDURE resetRead (d: DeviceTablePtr) ;
294BEGIN
295 Reread(d^.cid)
296END resetRead ;
297
298
299(*
300 resetWrite -
301*)
302
303PROCEDURE resetWrite (d: DeviceTablePtr) ;
304BEGIN
305 Rewrite(d^.cid)
306END resetWrite ;
307
308
309(*
310 IsSeqFile - tests if the channel identified by cid is open to a
311 rewindable sequential file.
312*)
313
314PROCEDURE IsSeqFile (cid: ChanId) : BOOLEAN ;
315BEGIN
316 RETURN( (cid # NIL) AND (IOChan.InvalidChan() # cid) AND
317 (IsDevice(cid, did)) AND
318 ((ChanConsts.readFlag IN IOChan.CurrentFlags(cid)) OR
319 (ChanConsts.writeFlag IN IOChan.CurrentFlags(cid))) )
320END IsSeqFile ;
321
322
323(*
324 Reread - if the channel identified by cid is not open
325 to a rewindable sequential file, the exception
326 wrongDevice is raised; otherwise attempts to set
327 the read position to the start of the file, and
328 to select input mode. If the operation cannot
329 be performed (perhaps because of insufficient
330 permissions) neither input mode nor output
331 mode is selected.
332*)
333
334PROCEDURE Reread (cid: ChanId) ;
335VAR
336 d: DeviceTablePtr ;
337BEGIN
338 IF IsSeqFile(cid)
339 THEN
340 d := DeviceTablePtrValue(cid, did) ;
341 WITH d^ DO
342 EXCL(flags, writeFlag) ;
343 IF readFlag IN flags
344 THEN
345 FIO.SetPositionFromBeginning(RTio.GetFile(cid), 0) ;
346 checkErrno(dev, d)
347 ELSE
348 EXCL(flags, readFlag)
349 END
350 END
351 ELSE
352 RAISEdevException(cid, did, IOChan.wrongDevice,
353 'SeqFile.' + __FUNCTION__ +
354 ': channel is not a sequential file')
355 END
356END Reread ;
357
358
359(*
360 Rewrite - if the channel identified by cid is not open to a
361 rewindable sequential file, the exception wrongDevice
362 is raised; otherwise, attempts to truncate the
363 file to zero length, and to select output mode.
364 If the operation cannot be performed (perhaps
365 because of insufficient permissions) neither input
366 mode nor output mode is selected.
367*)
368
369PROCEDURE Rewrite (cid: ChanId) ;
370VAR
371 d: DeviceTablePtr ;
372BEGIN
373 IF IsSeqFile(cid)
374 THEN
375 d := DeviceTablePtrValue(cid, did) ;
376 WITH d^ DO
377 EXCL(flags, readFlag) ;
378 IF writeFlag IN flags
379 THEN
380 FIO.SetPositionFromBeginning(RTio.GetFile(cid), 0) ;
381 checkErrno(dev, d)
382 ELSE
383 EXCL(flags, writeFlag)
384 END
385 END
386 ELSE
387 RAISEdevException(cid, did, IOChan.wrongDevice,
388 'SeqFile.' + __FUNCTION__ +
389 ': channel is not a sequential file')
390 END
391END Rewrite ;
392
393
394(*
395 handlefree -
396*)
397
398PROCEDURE handlefree (d: DeviceTablePtr) ;
399VAR
400 f: File ;
401BEGIN
402 WITH d^ DO
403 doFlush(d) ;
404 checkErrno(dev, d) ;
405 f := RTio.GetFile(RTio.ChanId(cid)) ;
406 IF FIO.IsNoError(f)
407 THEN
408 FIO.Close(f) ;
409 END ;
410 checkErrno(dev, d)
411 END
412END handlefree ;
413
414
415(*
416 Close - if the channel identified by cid is not open to a sequential
417 stream, the exception wrongDevice is raised; otherwise
418 closes the channel, and assigns the value identifying
419 the invalid channel to cid.
420*)
421
422PROCEDURE Close (VAR cid: ChanId) ;
423BEGIN
424 IF IsSeqFile(cid)
425 THEN
426 UnMakeChan(did, cid) ;
427 cid := IOChan.InvalidChan()
428 ELSE
429 RAISEdevException(cid, did, IOChan.wrongDevice,
430 'SeqFile.' + __FUNCTION__ +
431 ': channel is not a sequential file')
432 END
433END Close ;
434
435
436(*
437 Init -
438*)
439
440PROCEDURE Init ;
441VAR
442 gen: GenDevIF ;
443BEGIN
444 AllocateDeviceId(did) ;
445 gen := InitGenDevIF(did, doreadchar, dounreadchar,
446 dogeterrno, dorbytes, dowbytes,
447 dowriteln,
448 iseof, iseoln, iserror) ;
449 dev := InitChanDev(streamfile, did, gen)
450END Init ;
451
452
453BEGIN
454 Init
455END SeqFile.