Apart from the I/O modes which create ``sockets'' as detailed in Chapter 3 [Internet Sockets], the pipe and pump modes of Section 2.2 [Filters, Pipes, and Pumps], and the signal and timer modes described in Section 2.4 [Signals and Timers], the choices of second (``mode'') parameter to open (some of which have appeared in previous versions of SETL) are as follows. There are many synonyms here, largely for the sake of backward compatibility. There is no distinction between ``binary'' and other modes. Translation of end-of-line sequences on non-Unix systems is expected to be done by external filters if necessary, and the older meaning of binary I/O as input or output of some machine-level representation of SETL values is obsolete--the efficiency advantage of such modes is negligible, and the inconvenience significant. Moreover, SETL strings can accommodate any bit pattern that might be required by a foreign data format, so the coverage of needs in this regard is complete:
MODE SYNONYMS MEANING
`r' `rb', `input', `text', `text-in', `coded', stream input
`coded-in', `binary', `binary-in'
`w' `wb', `output', `print', `text-out', stream output
`a' `ab', `append', `output-append', stream output
`print-append', `text-append', starting at
`coded-append', `binary-append' end of file
`n' `nb', `new', `text-new', `new-text', stream output to
`coded-new', `new-coded', new file
`rw' `read-write', `input-output', bidirectional
`twoway', `two-way', `bidirectional' stream
`r+' `rb+', `r+b', `direct', `random' direct access file
`w+' `wb+', `w+b' empty file and then
do direct access
`a+' `ab+', `a+b' direct access file,
always write at end
`n+' `nb+', `n+b', `new+', `new-r+', direct access to
`new-w+', `direct-new', `new-direct', new file
Most of the names of the sequential I/O routines in the current version of SETL have appeared in previous versions, but there are a few new ones, and the semantics of some of them are slightly different from both CIMS SETL and SETL2 (which of course differ from each other): *
get (line1, line2, ...); -- geta from stdin
geta (fd, line1, line2, ...); -- line1, line2, ... are wr args
getb (fd, lhs1, lhs2, ...); -- lhs1, lhs2, ... are wr args
c := getc fd; -- retrieve one character
c := getchar (); -- getc from stdin, ``()'' optional
s := getfile fd; -- all characters up to EOF
s := getline fd; -- one input line
s := getn (fd, n); -- up to n characters
c := peekc fd; -- look ahead one character
c := peekchar (); -- peekc from stdin, ``()'' optional
print (rhs1, rhs2, ...); -- printa to stdout
printa (fd, rhs1, rhs2, ...); -- space-separated values on a line
nprint (rhs1, rhs2, ...); -- print without line terminator
nprinta (fd, rhs1, rhs2, ...); -- printa without line terminator
put (line1, line2, ...); -- puta to stdout
puta (fd, line1, line2, ...); -- line1, line2, ... are rd args
putb (fd, rhs1, rhs2, ...); -- rhs1, rhs2, ... are rd args
putc (fd, s); -- s is any string
putchar (s); -- putc to stdout
putline (fd, line1, line2, ...); -- same as puta
putfile (fd, s); -- similar to putc
read (lhs1, lhs2, ...); -- reada from stdin
reada (fd, lhs1, lhs2, ...); -- read and convert values
write (rhs1, rhs2, ...); -- writea to stdout
writea (fd, rhs1, rhs2, ...); -- same as putb
Print, printa, putb, write, and writea take rd arguments of any type, and write strings on a single line, with spaces between the represented values. Nprint and nprinta are just like print and printa respectively, but leave the output line unterminated. Putb is functionally identical to writea, and converts values the same way str does. Print and printa, however, treat strings as a special case, and leave them unquoted. Put and putb actually require strings, and if there is just one string argument, put behaves like print.
Read and reada can read any value written by write or writea, except for atoms (produced by newat) and procedure values (produced by routine). Reada differs subtly from getb in that it absorbs all characters up to the end of the line after reading as many values as directed by the presence of wr arguments, whereas getb does not--the next getb will pick up where the previous one left off. This accords with the historical intent of these routines. (The b in getb and putb stood for ``binary'', a mode to which the notion of a line boundary was foreign.) Tokens representing input values need to be separated by commas and/or runs of whitespace.
Putfile is identical to putc except that putfile will automatically close an automatically opened file (see Section 2.10 [Automatically Opened Files]). Puta is the same as putline, and puts a line terminator (a newline character in Unix) after each string it writes. Putc does not so terminate lines.
The getline operator reads up to the end of the current line (or to the end of the file, if the line is not terminated), but does not return any line terminator.
All input functions and operators, if the end of file is encountered before any characters are read on the call, return om. Procedural forms such as reada and geta assign om to unsatisfied wr arguments.
As in SETL2, it is possible to ``read'' from a string: *
reads (s, lhs1, lhs2, ...); -- lhs1, lhs2, ... are wr argsThis is not strictly compatible with the SETL2 version, which ``consumes'' value denotations from s and thus requires s to be writable as well as readable. The SETL version of reads (s, lhs1, lhs2, ...) is roughly equivalent to *
[lhs1, lhs2, ...] := unstr (`[' + s + `]')except that reads, like read and reada, will tolerate trailing ``junk'' characters after a delimiter that terminates the last denotation needed to satisfy the last writable argument. See Section 2.14.2 [Formatting and Extracting Values] for more information on unstr.
There is currently no corresponding writes or prints for string formatting. Arguably there should be, for completeness, but meanwhile, it is quite convenient simply to concatenate strings produced by the conversion primitives of Section 2.14.2 [Formatting and Extracting Values] on those occasions when it is necessary to buffer intermediate string forms.
For a stream opened in one of the direct-access modes listed at the beginning of this section, there are four special operations available, all of which employ the concept of a ``current position'' that is implicit in all file I/O. There is no distinction between input position and output position.
The current position can be explicitly set with the call *
seek (fd, offset);where an offset of 0 represents the beginning of the file. Also, *
rewind (fd);is equivalent to seek (fd, 0). Positions (offsets) are measured in characters.
For SETL2 compatibility, *
gets (fd, start, length, lhs); -- lhs is a wr argcombine position manipulation with I/O. Note that start obeys string indexing conventions, and must therefore be at least 1, corresponding to a file offset of 0. For gets, if the end of file is reached before length characters have been read, lhs will be assigned a string of fewer than length characters. Gets and puts update the current position after doing their reading or writing, respectively.
puts (fd, start, s);