Version I.5, September 1978
This procedure opens an already existing file for reading and writing and mark the file as open.
This procedure opens an new file on disk for reading and writing and mark the file as open. The FILEID may be any PASCAL structured file as defined in Section 2.1, and the TITLE is a string containing any legal file title as defined in Section 1.2 Figure 2.
Note: if the device specified in the title is a non-directory structured device, e.g. PRINTER:, then the file is opened for input, output, or both in either case.
If the file was already open, and another RESET or REWRITE is attempted to it, an error will be returned in IORESULT. The file's state will remain unchanged.
RESET (FILEID) without optional string parameter "rewinds" the file by setting the file pointers back to the beginning (zero th record) of the file. The boolean functions ~ and EOLN are set by the implied GET in RESET.
These procedures behave differently with files of type INTERACTIVE. RESET on files of types other than INTERACTIVE will do an initial GET to the file, setting the window variable to the first record in the file (as described in Jensen & Wirth). RESET on a file of type INTERACTIVE will not do an initial GET.
Note that RESETting a file to an output only device, such as the line printer may cause an non-zero IORESULT as a result of the implied GET caused by the RESET.
These are dangerous intrinsics
These procedures are the low-level procedures which do I/O to various devices. The UNITNUMBER is the integer name of an I/O device. Unit number is the index into the physical device table, Section 5.3 Unit Numbers describes these numbers. The ARRAY is any declared packed array, which may be subscripted to indicate a starting position some machines may be sensitive to having the starting position be on a word boundary. This is used as the starting address to do the transfers from or to. The LENGTH is an integer value designating the number of bytes to transfer. The BLOCKNUMBER is required only when using a block-structured device (i.e. a disk) and is the absolute block number at which the transfer will start from or to. If the BLOCKNUMBER is left out, 0 is assumed. The ASYNC value is an optional integer (assumed 0) and indicates (if 1) that the transfer is to be done asynchronously. The block number is not necessary, a ‘, , 1’ will be sufficient. (See UNITBUSY and UNIIWAIT.)
This function returns a BOOLEAN value, indicating if TRUE that the device specified is waiting for an I/O transfer to complete.
Example:
UNITREAD(2, CH[0], 1, , 1); (* unit 2 = non-echoing keyboard, 1 character, async *) WHILE UNITBUSY(2) (* While the READ has not been completed *) WRITELN(OUTPUT, 'I am waiting for you to type something'); WRITELN(OUTPUT, 'Thank you for typing a ', CH[0]);
Execution of this example will continuously type out the line ‘I am waiting for you to type something’ until a character is struck on the keyboard. Suppose a ‘!’ were typed. The message ‘Thank you for typing a !’ will then appear, and program execution will proceed normally.
Currently implemented only on DEC computers.
This waits for the specified device to complete the I/O in progress. It can be simulated by:
WHILE UNITBUSY(n) DO (* waste a small amount of time *);
Currently implemented only on DEC computers.
UNITCLEAR cancels all I/O to the specified unit and resets the hardware to its power-up state. Sets IORESULT non-zero if unit is not present.
These functions return an INTEGER value equal to the number of blocks of data actually transferred. The FILE must be an untyped file (i.e. FILEID: FILE). The length of ARRAY should be an integer multiple of 512. ARRAY may be indexed to indicate a starting position in the array, however care must be taken as some machines may be sensitive to having the I/O take place to a word boundary. BLOCKS is the number of blocks you want transferred. RELBLOCK is the block number relative to the start of the file, block zero being the first block in the file. If no RELBLOCK is specified, the reads / writes will be done sequentially. Specifying RELBLOCK for an I/O moves the file pointers. Caution should be exercised when using these, as the array bounds are not heeded. EOF(FILEID) becomes true when the last block in a file is read.
OPTION may be null or ‘LOCK’, ‘NORMAL&rsquo, ‘PURGE’ or ‘CRUNCH’.
If OPTION is null then a NORMAL close is done, i.e. CLOSE simply sets the file state to closed. If the file was opened using REWRITE and is a disk file, it is deleted from the directory.
The LOCK option will cause the disk file associated with the FILEID to be made permanent in the directory if the file is on a directory-structured device and the file was opened with a REWRITE; otherwise a NORMAL close is done.
The PURGE option will delete the TITLE associated with the FILEID from the directory. The unit will go off-line if the device is not block structured.
The CRUNCH option LOCKs the file to the point of last access. i.e. the position of the last GET or PUT to the file is where the file will end.
All CLOSEs, regardless of the option, will mark the file closed and will make the implicit variable FILEID undefined. CLOSE on a CLOSEed file causes no action.
If (FILEID) is not present, the file-id INPUT is assumed (e.g. IF EOF THEN). EOLN and EOF return false after the file specified is RESET. They both return true on a closed file. When EOF(FILEID) is true, FILEID^ is undefined. When GET(FILEID) sets FILEID^ to the EOLN character or the EOF character, EOLN(FILEID) will return true, and FILEID^ (in a FILE OF CHAR) will be set to a blank. If, while doing puts or writes at the end of a file, the file cannot be expanded to accommodate the PUT or WRITE, EOF(FILEID) will return true.
After any I/O operation, IORESULT contains an INTEGER value corresponding to the values given in Table 2. If the compiler is allowed (i.e. (*$I-*) has not been used), it will generate checks after each I/O operation, causing the program to get a run-time error on any bed I/O operation. These are not generated any time after any UNITREAD or UNITWRITE.
These procedures are used for operations on typed files. A typed file is any file for which a type is specified in the variable declaration, i.e. ‘FILEID: FILE OF <type>’. This is as opposed to untyped files which are simply declared as ‘FILEID: FILE;’. In a typed file each logical record is a memory image fitting the description of a variable of the associated <type>.
GET(FILEID) will leave the contents of the current logical record pointed at by the file pointers in the implicitly declared “window” variable FILEID^ and increment the file pointers.
PUT(FILEID) puts the contents of FILEID^ into the file at the location of the current file pointers and then updates those pointers. The actual physical disk access may not occur until the next time the physically, associated block of the disk is no-longer considered the current working block. The kinds of operation which tend to force the block to be written are: a SEEK to elsewhere in the file, a RESET and CLOSE. Successive GETs or PUTs to the file will cause the physical I/O to happen when the block boundaries are crossed.
These procedures may be used only on TEXT files (FILE OF CHAR or INTERACTIVE) for I/O. If ‘FILEID’ is omitted, INPUT or OUTPUT (whichever is appropriate) is assumed. A READ(STRING) will read up to and not including the end-of-line character (<a carriage return>) and leave EOLN(FILEID) true. This means that any subsequent READs of STRING variables will return the null string until a READLN or READ(character) is executed.
There are three files of type INTERACTIVE which are predeclared: INPUT, OUTPUT and KEYBOARD. INPUT results in echoing of characters typed to the console device. KEYBOARD does no echoing and allows the programmer complete control of the response to user typing. OUTPUT allows the user to halt or flush the output.
This procedure, as described in Jensen & Wirth (ibid.), sends a top-of-form (ASCII FF) to the file.
This procedure changes the file pointers so that the next GET or PUT from / to the file uses the OFFSETth record of FILEID. Records in files are numbered from 0. A GET or PUT must be executed between SEEK calls since two SEEKs in a row may cause unexpected, unpredictable junk to be held in the window and associated buffers. Sets EOF and EOLN to false.
For constant fill optimization see FILLCHAR, section section 2.1.5.4.
The intrinsic SIZEOF (Section
2.1.3.1) is meant for use with these
intrinsics; as it is convenient not to have to figure out or remember
the number of bytes in a particular data structure. (Which may change
at the programmers whim.)