dos_compilers/Logitech Modula-2 v1.1/FILESYST.DEF
2024-06-30 15:43:04 -07:00

657 lines
19 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(* Version 1.10, Nov 1984 *)
DEFINITION MODULE FileSystem;
(*
File manipulation routines
This implementation is based on the underlying operating
system for file handling. It distinguishes between BINARY
files and TEXT files.
File structure:
After any file operation the result should be checked
for errors, by testing the field 'res' of the file
variable (see type declarations for 'File' and
'Response').
The BOOLEAN field 'eof' in a file variable (variable of
type 'File)' allows to determine the end-of-file. It is
set to TRUE after the first unsuccessful attempt to read
information from the file. This first attempt to read
beyond end-of-file does not set any error condition; the
field 'res' of the file variable still indicates 'done'.
However, the character (or other data) returned is
not valid.
Binary files:
A file is a sequence of bytes with no other structure
implied.
Under some operating systems (e.g. CP/M-86) the file
may be organized in records (128 bytes each), and
therefore, the length of a file will always be a
multiple of this record size.
Text files:
A file is a sequence of characters. The character code
32C (Ctrl-Z) indicates end-of-file). All other
character codes from 0C to 377C are legal. When reading
a text file, 'eof' becomes TRUE when encountering the
character 32C, or at the pysical end of the file. When
closing a text file that has been modified, the
character 32C is written on the file.
When reading from a text file (by means of procedure
'ReadChar'), the character ASCII.EOL is returned for
the sequence <CR, LF>, or for a single <CR> or <LF>.
When writing to a text file (by means of procedure
'WriteChar'), the character ASCII.EOL is changed to
the sequence <CR,LF>.
Any file is in one of the states 'opened', 'reading',
'writing', or 'modifying'. These states have the following
meaning:
opened = Content of file buffer is undefined and not
associated with a position in the file.
When starting to read or write from a file
that is in state open, the state is changed
implicitly to reading or writing.
reading = No writing is allowed.
writing = No reading is allowed. Writing always takes
place at the end-of-file position.
When writing on an existing file, which is
(physically) longer than the current write
position, it is undefined, whether the file
is truncated upon a close.
modifying = Reading and writing are allowed. Writing an
element inside of a file means 'overwriting'
the value of the element with a new value.
Upon a close, the file is not truncated.
The state of the file is given by the field 'flags' of
a file variable. By means of the procedures SetRead,
SetWrite, SetModify, and SetOpen, it is possible to change
the status of an open file.
To every file is associated a 'current position'. This
corresponds to the number of the current byte inside the
file, starting with zero for the first byte. The next
reading or writing takes place at the current position.
This position is updated automatically after reading or
writing. It can also be inquired or set through the
procedure GetPos or SetPos.
After the opening of a file (by means of Lookup or Create)
it is state 'opened' and positioned at the beginning
(low = 0, high = 0).
Conventions for filenames:
For the procedures Lookup and Rename, a filename has to be
given, including a medium name (drive name), a file name
and an optional file type. For the procedure Create, a
medium name has to be given. The medium name is up to
three characters long (alphanumeric, starting with a
letter). It is separated from the file name by a colon
(':'). The medium name must always be given explicitly.
The default medium must be denoted by 'DK:'.
Depending on the operating system, the file name may
include a path name, specifying the the directory where
the file exists. The length of the file (and path) name,
and the characters legal for file names, depend on the
operating system.
By default, the mediums (i.e. disk drives) handled by
module 'DiskFiles' are installed.
Derived from the Lilith Modula-2 system developed by the
group of Prof. N. Wirth at ETH Zurich, Switzerland.
*)
FROM SYSTEM IMPORT ADDRESS, WORD, BYTE;
EXPORT QUALIFIED
File, Response, Command,
Flag, FlagSet,
(* basic file operations: *)
Create, Close, Lookup, Rename, Delete,
SetRead, SetWrite, SetModify, SetOpen,
Doio,
SetPos, GetPos, Length,
(* stream-like I/O: *)
Reset, Again,
ReadWord, ReadChar, ReadByte, ReadNBytes,
WriteWord, WriteChar, WriteByte, WriteNBytes,
(* medium handling: *)
MediumType,
FileProc, DirectoryProc,
CreateMedium, RemoveMedium,
FileNameChar;
TYPE
MediumHint = CARDINAL;
(*- medium index used in DiskFiles *)
MediumType = ARRAY [0..2] OF CHAR;
(*- medium name (A, B...) *)
Flag = (er, ef, rd, wr, ag, txt);
(*
- status flag for file operations:
er = error occured, ef = end-of-file reached,
rd = in read mode, wr = in write mode,
ag = "Again" has been called after last read,
txt = text-file (the last access to the file was a
'WriteChar' or 'ReadChar').
*)
FlagSet = SET OF Flag;
(*- status flag set *)
Response = (done,
notdone, notsupported, callerror,
unknownmedium, unknownfile, paramerror,
toomanyfiles, eom, userdeverror);
(*- result of a file operation *)
Command = (create, close, lookup, rename, delete,
setread, setwrite, setmodify, setopen,
doio, setpos, getpos, length);
(*- commands passed to module 'DiskFiles' *)
BuffAdd = POINTER TO ARRAY [0..0FFFEH] OF CHAR;
(*- file buffer pointer type *)
File = RECORD
bufa: BuffAdd;
(*- buffer address *)
buflength: CARDINAL;
(*- size of buffer in bytes. In the
current release it is always a
multiple of 128. *)
validlength: CARDINAL;
(*- number of valid bytes in buffer *)
bufind: CARDINAL;
(*- byte-index to the buffer of the
current position *)
flags: FlagSet;
(*- status of the file *)
eof: BOOLEAN;
(*- TRUE if last access was past the end
of the file *)
res: Response;
(*- result of last operation *)
lastRead: CARDINAL;
(*- the word or byte (char) last read *)
mt: MediumType;
(*- selects the driver that supports this
file *)
fHint: CARDINAL;
(*- used internally by device driver *)
mHint: MediumHint;
(*- used internally by medium handler *)
CASE com: Command OF
lookup: new: BOOLEAN;
| setpos,
getpos,
length: highpos, lowpos: CARDINAL;
END;
END;
(*- file structure used for bookkeeping by DiskFiles *)
PROCEDURE Create (VAR f: File; mediumName: ARRAY OF CHAR);
(*
- create a temporary file
in: mediumName name of medium to create file on,
in character format
out: f initialized file structure
A temporary file is characterized by an empty name. To
make the file permanent, it has to be renamed with a
non-empty name before closing it. For subsequent
operations on this file, it is referenced by 'f'.
*)
PROCEDURE Close (VAR f: File);
(*
- Close a file
in: f structure referencing an open file
out: f the field f.res will be set appropriately.
Terminates the operations on file "f". If "f" is a
temporary file, it will be destroyed, whereas a file with
a non-empty name remains on its medium and is accessible
through "Lookup". When closing a text-file after writing,
the end-of-file code 32C is written on the file (MS-DOS
and CP/M-86 convention).
*)
PROCEDURE Lookup (VAR f: File; fileName: ARRAY OF CHAR;
newFile: BOOLEAN);
(*
- look for a file
in: filename drive and name of file to search for
newFile TRUE if file should be created if
not found
out: f initialized file structure; f.res will
be set appropriately.
Searches the medium specified in "filename" for a file
that matches the name and type given in "filename". If
the file is not found and "newFile" is TRUE, a new
(permanent) file with the given name and type is created.
If it is not found and "newFile" is FALSE, no action
takes place and "notdone" is returned in the result
field of "f".
*)
PROCEDURE Rename (VAR f: File; newname: ARRAY OF CHAR);
(*
- rename a file
in: f structure referencing an open file
newname filename to rename to, with
device:name.type specified
out: f file name in f will be changed and the
field f.res will be set appropriately.
The medium, on which the files reside can not be changed
with this command. The medium name inside "newname" has
to be the old one.
*)
PROCEDURE Delete (name: ARRAY OF CHAR; VAR f: File);
(*
- delete a file
in: name name of file to delete, with
dev:name.type specified
out: f the field f.res will be set appropriately.
*)
PROCEDURE ReadWord (VAR f: File; VAR w: WORD);
(*
- Returns the word at the current position in f
in: f structure referencing an open file
out: w word read from file
f the result field f.res will be set
appropriately.
The file will be positioned at the next word when the
read is done.
*)
PROCEDURE WriteWord (VAR f: File; w: WORD);
(*
- Write one word to a file
in: f structure referencing an open file
w word to write
out: f the field f.res will be set appropriately.
When overwriting, the file will be positioned at the next
word when the write is done.
*)
PROCEDURE ReadChar (VAR f: File; VAR ch: CHAR);
(*
- Read one character from a file
in: f structure referencing an open file
out: ch character read from file
f the field f.res will be set appropriately.
The file will be positioned at the next character when
the read is done.
*)
PROCEDURE WriteChar (VAR f: File; ch: CHAR);
(*
- Write one character to a file
in: f structure referencing an open file
ch character to write
out: f the field f.res will be set apporopriately.
When overwriting, the file will be positioned at the next
character when the write is done.
*)
PROCEDURE ReadByte (VAR f: File; VAR b: BYTE);
(*
- Read one byte from a file
in: f structure referencing an open file
out: b byte read from file
f the field f.res will be set appropriately.
The file will be positioned at the next byte when the
read is completed.
*)
PROCEDURE WriteByte (VAR f: File; b: BYTE);
(*
- Write one byte to a file
in: f structure referencing an open file
b byte to write
out: f the field f.res will be set appropriately.
When overwriting, the file will be positioned at the next
byte when the write is done.
*)
PROCEDURE ReadNBytes (VAR f: File;
bufPtr: ADDRESS;
requestedBytes: CARDINAL;
VAR read: CARDINAL);
(*
- Read a specified number of bytes from a file
in: f structure referencing an open file
bufPtr pointer to buffer area to read bytes into
requestedBytes number of bytes to read
out: bufPtr^ bytes read from file
f the field f.res will be set appropriately.
read the number of bytes actually read.
The file will be positioned at the next byte after the
requested sequence of bytes.
*)
PROCEDURE WriteNBytes (VAR f: File;
bufPtr: ADDRESS;
requestedBytes: CARDINAL;
VAR written: CARDINAL);
(*
- Write a specified number of bytes to a file
in: f structure referencing an open file
bufPtr pointer to string of bytes to write
requestedBytes number of bytes to write
out: f the field f.res will be set appropriately.
written the number of bytes actually written
When overwriting, the file will be positioned at the next
byte after the requested sequence of bytes.
*)
PROCEDURE Again (VAR f: File);
(*
- returns a character to the buffer to be read again
in: f structure referencing an open file
out: f the f.res field will be set appropriately.
This should be called after a read operation only (it has
no effect otherwise). It prevents the subsequent read
from reading the next element; the element just read
before will be returned a second time. Multiple calls to
Again without a read in between have the same effect as
one call to Again. The position in the file is undefined
after a call to Again (it is defined again after the next
read operation).
*)
PROCEDURE SetRead (VAR f: File);
(*
- Sets the file in reading- state, without changing the
current position.
in: f structure referencing an open file
out: f f.res will be set appropriately.
Upon calling SetRead, the current position must be before
the eof. In reading state, no writing is allowed.
*)
PROCEDURE SetWrite (VAR f: File);
(*
- Sets the file in writing-state, without changing the
current position.
in: f structure referencing an open file
out: f f.res will be set appropriately.
Upon calling SetWrite, the current position must be a
legal position in the file (including eof). In writing
state, no reading is allowed, and a write always takes
place at the eof. The current implementation does not
truncate the file.
*)
PROCEDURE SetModify (VAR f: File);
(*
- Sets the file in modifying-state, without changing the
current position.
in: f structure referencing an open file
out: f f.res will be set appropriately.
Upon calling SetModify, the current position must be
before the eof. In modifying-state, reading and writing
are allowed. Writing is done at the current position,
overwriting whatever element is already there. The file
is not truncated.
*)
PROCEDURE SetOpen (VAR f: File);
(*
- Set the file to opened-state, without changing the
current position.
in: f structure referencing an open file
out: f f.res will be set appropriately.
The buffer content is written back on the file, if the
file has been in writing or modifying status. The new
buffer content is undefined. In opened-state, neither
reading nor writing is allowed.
*)
PROCEDURE Reset (VAR f: File);
(*
- Set the file to opened state and position it to the
top of file.
in: f structure referencing an open file
out: f f.res will be set appropriately.
*)
PROCEDURE SetPos (VAR f: File; high, low: CARDINAL);
(*
- Set the current position in file
in: f structure referencing an open file
high high part of the byte offset
low low part of the byte offset
out: f f.res will be set appropriately.
The file will be positioned (high*2^16 +low) bytes from
top of file.
*)
PROCEDURE GetPos (VAR f: File; VAR high, low: CARDINAL);
(*
- Return the current byte position in file
in: f structure referencing an open file
out: high high part of byte offset
low low part of byte offset
The actual position is (high*2^16 +low) bytes from the top of file.
*)
PROCEDURE Length (VAR f: File; VAR high, low: CARDINAL);
(*
- Return the length of the file in bytes.
in: f structure referencing an open file.
out: high high part of byte offset
low low part of byte offset
The actual length is (high*2^16 +low) bytes. Depending on
the operating system, this length may always be a multiple
of some record size reflecting the physical length of the
file and maybe not the true logical file length.
*)
PROCEDURE Doio (VAR f: File);
(*
- Do various read/write operations on a file
in: f structure referencing an open file
out: f f.res will be set appropriately.
The exact effect of this command depends on the state of
the file (flags):
opened = NOOP.
reading = reads the record that contains the current
byte from the file. The old content of the
buffer is not written back.
writing = the buffer is written back. It is then
assigned to the record, that contains the
current position. Its content is not
changed.
modifying = the buffer is written back and the record
containing the current position is read.
Note that 'Doio' does not need to be used when reading
through the stream-like I/O routines. Its use is limited
to special applications.
*)
PROCEDURE FileNameChar (c: CHAR): CHAR;
(*
- Check the character c for legality in a filename.
in: c charater to check
out: 0C for illegal characters and c otherwise;
lowercase letters are transformed into
uppercase letters.
Which characters are leagl in a filename depends on the
host operating system.
*)
TYPE
FileProc = PROCEDURE (VAR File);
(*- Procedure type to be used for internal file
operations
A procedure of this type will be called for the following
functions (see TYPE 'Command'): setread, setwrite,
setmodify, setopen, doio, setpos, getpos, and length.
*)
DirectoryProc = PROCEDURE (VAR File, ARRAY OF CHAR);
(*- Procedure type to be used for operations on
entire files
A procedure of this type will be called for the following
functions (see TYPE 'Command'): create, close, lookup,
rename, and delete.
*)
PROCEDURE CreateMedium (mt: MediumType;
fproc: FileProc;
dproc: DirectoryProc;
VAR done: BOOLEAN);
(*
- Install the medium "mt" in the file system
in: mt medium type to install
fproc procedure to handle internal file
operations
dproc procedure to handle operations on an
entire file
out done TRUE if medium was installed successfully
Before accessing or creating a file on a medium, this
medium has to be announced to the file system by means
of the routine CreateMedium. FileSystem calls "fproc"
and "dproc" to perform operations on a file of this
medium. Up to 24 mediums can be announced.
*)
PROCEDURE RemoveMedium (mt: MediumType; VAR done: BOOLEAN);
(*
- Remove the medium "mt" from the file system
in: mt medium type to remove
out: done TRUE if medium was removed successfully
Attempts to access a file on this medium result in an
error (unknownmedium).
*)
END FileSystem.