LispPad

Lightweight Scheme Development on macOS

LispKit Port

Ports represent abstractions for handling input and output. They are used to access files, devices, and similar things on the host system on which LispKit is running.

An input port is a LispKit object that can deliver data upon command, while an output port is an object that can accept data. In LispKit, input and output port types are disjoint, i.e. a port is either an input or an output port.

Different port types operate on different data. LispKit provides two differnt types of ports: textual ports and binary ports. Textual ports and binary ports are disjoint, i.e. a port is either textual or binary.

A textual port supports reading or writing of individual characters from or to a backing store containing characters using read-char and write-char, and it supports operations defined in terms of characters, such as read and write.

A binary port supports reading or writing of individual bytes from or to a backing store containing bytes using read-u8 and write-u8 below, as well as operations defined in terms of bytes.

Default ports

current-output-port [parameter object]
current-input-port
current-error-port

These parameter objects represent the current default input port, output port, or error port (an output port), respectively. These parameter objects can be overridden with parameterize.

default-output-port [constant]
default-input-port

These two ports are the initial values of current-output-port and current-input-port when LispKit gets initialized. They are typically referring to the default output and input device of the system on which LispKit is running.

Predicates

(port? obj) [procedure]

Returns #t if obj is a port object; otherwise #f is returned.

(input-port? obj) [procedure]
(output-port? obj)

These predicates return #t if obj is an input port or output port; otherwise they return #f.

(textual-port? obj) [procedure]
(binary-port? obj)

These predicates return #t if obj is a textual or a binary port; otherwise they return #f.

(input-port-open? port) [procedure]
(output-port-open? port)

Returns #t if port is still open and capable of performing input or output, respectively, and #f otherwise.

(eof-object? obj) [procedure]

Returns #t if obj is an end-of-file object, otherwise returns #f.

General ports

(close-port port) [procedure]
(close-input-port port)
(close-output-port port)

Closes the resource associated with port, rendering the port incapable of delivering or accepting data. It is an error to apply close-input-port and close-output-port to a port which is not an input or output port, respectively. All procedures for closing ports have no effect if the provided port has already been closed.

(with-input-from-port port thunk) [procedure]
(with-output-to-port port thunk)

The given port is made to be the value returned by current-input-port or current-output-port (as used by (read), (write obj), and so forth). The thunk is then called with no arguments. When the thunk returns, the port is closed and the previous default is restored. It is an error if thunk does not accept zero arguments. Both procedures return the values yielded by thunk. If an escape procedure is used to escape from the continuation of these procedures, they behave exactly as if the current input or output port had been bound dynamically with parameterize.

(call-with-port port proc) [procedure]

The call-with-port procedure calls proc with port as an argument. It is an error if proc does not accept one argument.

If proc returns, then the port is closed automatically and the values yielded by proc are returned. If proc does not return, then the port will not be closed automatically unless it is possible to prove that the port will never again be used for a read or write operation.

This is necessary, because LispKit’s escape procedures have unlimited extent and thus it is possible to escape from the current continuation but later to resume it. If LispKit would be permitted to close the port on any escape from the current continuation, then it would be impossible to write portable code using both call-with-current-continuation and call-with-port.

File ports

(open-input-file filepath) [procedure]
(open-binary-input-file filepath)

Takes a filepath referring to an existing file and returns a textual input port or binary input port that is capable of delivering data from the file. If the file does not exist or cannot be opened, an error that satisfies file-error? is signaled.

(open-output-file filepath) [procedure]
(open-binary-output-file filepath)

Takes a filepath referring to an output file to be created and returns a textual output port or binary output port that is capable of writing data to the new file. If a file with the given name exists already, the effect is unspecified. If the file cannot be opened, an error that satisfies file-error? is signaled.

(with-input-from-file filepath thunk) [procedure]
(with-output-to-file filepath thunk)

The file determined by filepath is opened for input or output as if by open-input-file or open-output-file, and the new port is made to be the value returned by current-input-port or current-output-port (as used by (read), (write obj), and so forth). The thunk is then called with no arguments. When the thunk returns, the port is closed and the previous default is restored. It is an error if thunk does not accept zero arguments. Both procedures return the values yielded by thunk. If an escape procedure is used to escape from the continuation of these procedures, they behave exactly as if the current input or output port had been bound dynamically with parameterize.

(call-with-input-file filepath proc) [procedure]
(call-with-output-file filepath proc)

These procedures create a textual port obtained by opening the file referred to by filepath (a string) for input or output as if by open-input-file or open-output-file. This port and proc are then passed to a procedure equivalent to call-with-port. It is an error if proc does not accept one argument.

String ports

(open-input-string str) [procedure]

Takes a string and returns a textual input port that delivers characters from the string. If the string is modified, the effect is unspecified.

(open-output-string) [procedure]

Returns a textual output port that will accumulate characters for retrieval by get-output-string.


(parameterize ((current-output-port (open-output-string)))
  (display "piece")
  (display " by piece ")
  (display "by piece.")
  (get-output-string (current-output-port)))
    ⇒ "piece by piece by piece."

(get-output-string port) [procedure]

It is an error if port was not created with open-output-string.

Returns a string consisting of the characters that have been output to port so far in the order they were output.


(parameterize ((current-output-port (open-output-string)))
  (display "piece")
  (display " by piece ")
  (display "by piece.")
  (newline)
  (get-output-string (current-output-port)))
    ⇒ "piece by piece by piece.\n"

(with-input-from-string str thunk) [procedure]

String str is opened for input as if by open-input-string, and the new textual string port is made to be the value returned by current-input-port. The thunk is then called with no arguments. When the thunk returns, the port is closed and the previous default is restored. It is an error if thunk does not accept zero arguments. with-input-from-string returns the values yielded by thunk. If an escape procedure is used to escape from the continuation of these procedures, they behave exactly as if the current input port had been bound dynamically with parameterize.

(with-output-to-string thunk) [procedure]

A new string output port is created as if by calling open-output-string, and the new port is made to be the value returned by current-output-port. The thunk is then called with no arguments. When the thunk returns, the port is closed and the previous default is restored. It is an error if thunk does not accept zero arguments. Both procedures return the values yielded by thunk. If an escape procedure is used to escape from the continuation of these procedures, they behave exactly as if the current input or output port had been bound dynamically with parameterize.

(call-with-output-string proc) [procedure]

The procedure proc is called with one argument, a textual output port. The values yielded by proc are ignored. When proc returns, call-with-output-string returns the port’s accumulated output as a string.

This procedure is defined as follows:


(define (call-with-output-string procedure)
  (let ((port (open-output-string)))
    (procedure port)
    (get-output-string port)))

Bytevector ports

(open-input-bytevector bvector) [procedure]

Takes a bytevector bvector and returns a binary input port that delivers bytes from the bytevector bvector.

(open-output-bytevector) [procedure]

Returns a binary output port that will accumulate bytes for retrieval by get-output-bytevector.

(get-output-bytevector port) [procedure]

It is an error if port was not created with open-output-bytevector. get-output-bytevector returns a bytevector consisting of the bytes that have been output to the port so far in the order they were output.

(call-with-output-bytevector proc) [procedure]

The procedure proc gets called with one argument, a binary output port. The values yielded by procedure proc are ignored. When it returns, call-with-output-bytevector returns the port’s accumulated output as a newly allocated bytevector.

This procedure is defined as follows:


(define (call-with-output-bytevector procedure)
  (let ((port (open-output-bytevector)))
    (procedure port)
    (get-output-bytevector port)))

URL ports

(open-input-url url) [procedure]

Takes a url referring to an existing resource and returns a textual input port that is capable of reading data from the resource (e.g. via HTTP).

(open-binary-input-url url) [procedure]

Takes a url referring to an existing resource and returns a binary input port that is capable of reading data from the resource (e.g. via HTTP).

(with-input-from-url url thunk) [procedure]

The given url is opened for input as if by open-input-url, and the new input port is made to be the value returned by current-input-port. The thunk is then called with no arguments. When the thunk returns, the port is closed and the previous default is restored. It is an error if thunk does not accept zero arguments. The procedure returns the values yielded by thunk. If an escape procedure is used to escape from the continuation of this procedure, they behave exactly as if current-input-port had been bound dynamically with parameterize.

(call-with-input-url obj) [procedure]

call-with-input-url creates a textual input port by opening the resource at url for input as if by open-input-url. This port and proc are then passed to a procedure equivalent to call-with-port. It is an error if proc does not accept one argument.

Asset ports

(open-input-asset name type) [procedure]
(open-input-asset name type dir)

This function can be used to open a textual LispKit asset file located in one of LispKit's asset paths. An asset is identified via a file name, a file type, and an optional directory path dir. name, type, and dir are all strings. open-input-asset constructs a relative file path in the following way (assuming name does not have a suffix already):

   dir/name.type

It then searches the asset paths in their given order for a file matching this relative file path. Once the first matching file is found, the file is opened as a text file and a corresponding textual input port that is capable of reading data from the file is returned. It is an error if no matching asset is found.

(open-binary-input-asset name type) [procedure]
(open-binary-input-asset name type dir)

This function can be used to open a binary LispKit asset file located in one of LispKit's asset paths. An asset is identified via a file name, a file type, and an optional directory path dir. name, type, and dir are all strings. open-input-asset constructs a relative file path in the following way (assuming name does not have a suffix already):

   dir/name.type

It then searches the asset paths in their given order for a file matching this relative file path. Once the first matching file is found, the file is opened as a binary file and a corresponding binary input port that is capable of reading data from the file is returned. It is an error if no matching asset is found.

Reading from ports

If port is omitted from any input procedure, it defaults to the value returned by (current-input-port). It is an error to attempt an input operation on a closed port.

(read) [procedure]
(read port)

The read procedure converts external representations of Scheme objects into the objects themselves by parsing the input. read returns the next object parsable from the given textual input port, updating port to point to the first character past the end of the external representation of the object.

If an end of file is encountered in the input before any characters are found that can begin an object, then an end-of-file object is returned. The port remains open, and further attempts to read will also return an end-of-file object. If an end of file is encountered after the beginning of an object’s external representation, but the external representation is incomplete and therefore not parsable, an error that satisfies read-error? is signaled.

(read-char) [procedure]
(read-char port)

Returns the next character available from the textual input port, updating port to point to the following character. If no more characters are available, an end-of-file object is returned.

(peek-char) [procedure]
(peek-char port)

Returns the next character available from the textual input port, but without updating port to point to the following character. If no more characters are available, an end-of-file object is returned.

Note: The value returned by a call to peek-char is the same as the value that would have been returned by a call to read-char with the same port. The only difference is that the very next call to read-char or peek-char on that port will return the value returned by the preceding call to peek-char. In particular, a call to peek-char on an interactive port will hang waiting for input whenever a call to read-char would have hung.

(char-ready?) [procedure]
(char-ready? port)

Returns #t if a character is ready on the textual input port and returns #f otherwise. If char-ready? returns #t then the next read-char operation on the given port is guaranteed not to hang. If the port is at end of file, then char-ready? returns #t.

Rationale: The char-ready? procedure exists to make it possible for a program to accept characters from interactive ports without getting stuck waiting for input. Any input editors associated with such ports must ensure that characters whose existence has been asserted by char-ready? cannot be removed from the input. If char-ready? were to return #f at end of file, a port at end of file would be indistinguishable from an interactive port that has no ready characters.

(read-token) [procedure]
(read-token port)
(read-token port charset)

Returns the next token of text available from the textual input port, updating port to point to the following character. A token is a non-empty sequence of characters delimited by characters from character set charset. Tokens never contain characters from charset. charset defaults to the set of all whitespace and newline characters.

(read-line obj) [procedure]
(read-line port)

Returns the next line of text available from the textual input port, updating port to point to the following character. If an end of line is read, a string containing all of the text up to (but not including) the end of line is returned, and port is updated to point just past the end of line. If an end of file is encountered before any end of line is read, but some characters have been read, a string containing those characters is returned. If an end of file is encountered before any characters are read, an end-of-file object is returned. For the purpose of this procedure, an end of line consists of either a linefeed character, a carriage return character, or a sequence of a carriage return character followed by a linefeed character.

(read-string k) [procedure]
(read-string k port)

Reads the next k characters, or as many as are available before the end of file, from the textual input port into a newly allocated string in left-to-right order and returns the string. If no characters are available before the end of file, an end-of-file object is returned.

(read-u8) [procedure]
(read-u8 port)

Returns the next byte available from the binary input port, updating port to point to the following byte. If no more bytes are available, an end-of-file object is returned.

(peek-u8 obj) [procedure]

Returns the next byte available from the binary input port, but without updating port to point to the following byte. If no more bytes are available, an end-of-file object is returned.

(u8-ready?) [procedure]
(u8-ready? port)

Returns #t if a byte is ready on the binary input port and returns #f otherwise. If u8-ready? returns #t then the next read-u8 operation on the given port is guaranteed not to hang. If the port is at end of file then u8-ready? returns #t.

(read-bytevector k) [procedure]
(read-bytevector k port)

Reads the next k bytes, or as many as are available before the end of file, from the binary input port into a newly allocated bytevector in left-to-right order and returns the bytevector. If no bytes are available before the end of file, an end-of-file object is returned.

(read-bytevector! bvector) [procedure]
(read-bytevector! bvector port)
(read-bytevector! bvector port start)
(read-bytevector! bvector port start end)

Reads the next end − start bytes, or as many as are available before the end of file, from the binary input port into bytevector bvector in left-to-right order beginning at the start position. If end is not supplied, reads until the end of bytevector bvector has been reached. If start is not supplied, reads beginning at position 0. Returns the number of bytes read. If no bytes are available, an end-of-file object is returned.

Writing to ports

If port is omitted from any output procedure, it defaults to the value returned by (current-output-port). It is an error to attempt an output operation on a closed port.

(write obj) [procedure]
(write obj port)

Writes a representation of obj to the given textual output port. Strings that appear in the written representation are enclosed in quotation marks, and within those strings backslash and quotation mark characters are escaped by backslashes. Symbols that contain non-ASCII characters are escaped with vertical lines. Character objects are writ- ten using the #\ notation.

If obj contains cycles which would cause an infinite loop using the normal written representation, then at least the objects that form part of the cycle will be represented using datum labels. Datum labels will not be used if there are no cycles.

(write-shared obj) [procedure]
(write-shared obj port)

The write-shared procedure is the same as write, except that shared structures will be represented using datum labels for all pairs and vectors that appear more than once in the output.

(write-simple obj) [procedure]
(write-simple obj port)

The write-simple procedure is the same as write, except that shared structures will never be represented using datum labels. This can cause write-simple not to terminate if obj contains circular structures.

(display obj) [procedure]
(display obj port)

Writes a representation of obj to the given textual output port. Strings that appear in the written representation are output as if by write-string instead of by write. Symbols are not escaped. Character objects appear in the representation as if written by write-char instead of by write. display will not loop forever on self-referencing pairs, vectors, or records.

The write procedure is intended for producing machine-readable output and display for producing human-readable output.

(newline) [procedure]
(newline port)

Writes an end of line to textual output port.

(write-char char) [procedure]
(write-char char port)

Writes the character char (not an external representation of the character) to the given textual output port.

(write-string str) [procedure]
(write-string str port)
(write-string str port start)
(write-string str port start end)

Writes the characters of string str from index start to end (exclusive) in left-to-right order to the textual output port. The default of start is 0, the default of end is the length of str.

(write-u8 byte) [procedure]
(write-u8 byte)

Writes the byte to the given binary output port.

(write-bytevector bvector) [procedure]
(write-bytevector bvector port)
(write-bytevector bvector port start)
(write-bytevector bvector port start end)

Writes the bytes of bytevector bvector from start to end (exclusive) in left-to-right order to the binary output port. The default of start is 0, the default of end is the length of bvector.

(flush-output-port) [procedure]
(flush-output-port port)

Flushes any buffered output from the buffer of the given output port to the underlying file or device.

(eof-object) [procedure]

Returns an end-of-file object.