9.  Streams

      Input, output, and storage of text lines in unroff are centered around a new Scheme data type named stream and a set of primitives that work on streams. A stream can act as a source (input stream) or as a sink (output stream) for lines of text. Streams not only serve as the basis for input and output operations and for the exchange of text with shell commands, but can also be used to temporarily buffer lines of text (e.g. footnotes or tables of contents) and to implement user-defined macros in a simple way. Each input or output stream can be connected to one of the following three types of targets:

      Buffers act similar to (initially empty) files, except that they are not visible from the outside and that they are destroyed automatically on exit of the program. Once a buffer has been filled with text through an output stream, it can be reopened and read through an input stream multiple times. However, if a buffer is currently written through an output stream, no more streams may refer to the same buffer. As the contents of buffers kept in memory, input and output operations on buffers are fast. The sample implementation of user-defined macros utilizes buffers to store the macro bodies; a macro can then be expanded simply by redirecting the current input source to the corresponding buffer temporarily.

      Both the parser and all input and output primitives operate on a current input stream and a current output stream; input and output is always performed using these two streams. On startup, unroff initializes the current output stream to either point to standard output or to a newly created output file (usually depending on the value of the document option). If the current output stream is assigned the literal #f, output is sent to standard output[note 2] . Likewise, for each input file mentioned in the command line, a stream pointing to that file is created and assigned to the current input stream before the parser starts processing the file. The rest of this section lists the Scheme primitives operating on streams.

(stream? obj)

      The type predicate for the new data type. It returns #t if obj is a member of the type stream, otherwise #f.

(input-stream)
(output-stream)

      Returns the current input stream, or output stream respectively.

(open-input-stream target)
(open-output-stream target)
(append-output-stream target)

      These primitives create a new input stream or output stream pointing to the specified target. The argument target is a string or a symbol. If the target is enclosed in square brackets, it names a buffer; if it begins with the pipe symbol `|', a pipe to a shell running the rest of the target as a shell command is established; otherwise target is interpreted as a file name. append-output-stream rewinds to the end of the specified output buffer or file before the first output operation; it acts like open-output-stream in case of a pipe. Examples:

(let* ((buffer (open-output-stream '[temp]))
       (pipe   (open-input-stream "|ls -l /usr/lib/tmac"))
       (file   (open-input-stream "/etc/passwd")))
  ...)

(set-input-stream! stream)
(set-output-stream! stream)

      These primitives make the specified stream the current input stream (or output stream respectively). stream must be the result of a call to one of the three primitives that open a stream, or #f. An error is signaled if set-input-stream! is applied to an output stream or vice versa, or if the stream has been closed in the meantime.

(close-stream stream)

      Closes the specified stream. An error is signaled if the stream is still the current input stream or current output stream. Once an output stream pointing to a buffer has been closed, the buffer can be reopened for reading. A stream that is no longer reachable is closed automatically during the next run of the garbage collector.

(stream-buffer? stream)
(stream-file? stream)
(stream-pipe? stream)

      These predicates return #t if the specified stream points to a buffer, a file, or a pipe respectively, otherwise #f.

(stream-target stream)

      This primitive returns the target to which the specified stream points. The return value is a string. In case of a pipe, the target is truncated at the first space, that is, only the command name is included. The target of the current input stream (together with the current line number) is displayed as a prefix of error messages and can also be obtained through the primitive substitute described below.

(stream-position stream)

      Returns the current character position of the specified output stream, that is, the offset at which the next character will be written. The return value for input streams is currently always zero. This primitive is useful in conjunction with file-insertions (described below).

(stream-string target)

      This primitive opens an input string to the specified target, reads from the stream until end-of-stream is reached, closes the stream, and returns the concatenation of all the lines that have been read as a string[note 3] .


Markup created by unroff 1.0,    March 21, 1996,    net@informatik.uni-bremen.de