.c      Thursday  Oct 21,1982  20:20  NM+4D.14H.33M.29S.  -*- Bolio -*-

.chapter "Streams"
.setq stream-chapter-number chapter-number
.setq stream-chapter-page-number page-number
.setq stream-chapter-section-page section-page

In lan{nil}, a term_i{stream} is an object of flavor
kwd{stream}.  Stream operations (in lan{nil}) are handled
primarily by message passing using fun{send}.  However, it is not
usually necessary to understand that unless new streams (new flavors)
are to be defined, so that will not be covered here at this time, at
least not in any detail.

Excluded from this chapter are topics dealing specifically with
file system streams, as they interact heavily with other facilities
that concern the file system, which is described in
(file-system-chapter-section-page).

.section "Standard Streams"

The following variables are defined by lan{common lisp} to have
streams with particular as their values.  2Are these names going to
be changed to have asterisks at both ends?  That's going to be a big
screw!*

.defvar standard-input
This is used as the default stream for various input functions, and
for the toplevel and breaklevel loops.
.end_defvar

.defvar standard-output
This is used as the default stream for various output functions, and
for the toplevel and breaklevel loops.
.end_defvar

.defvar error-output
This is the stream to which error messages should be sent.  Normally,
it directs output through the value of var{terminal-io} (but see
comments below), but it could be made to send them to a file, for
instance.  (This may not be used properly yet.)
.end_defvar

.defvar query-io
This stream is used to ask questions of the user.  Normally it
uses the terminal, but could be made to (for instance) log the input.
.end_defvar

.defvar trace-output
This is the stream to which output from tracing (see the
fun_i{trace} function, (trace-fun)) is sent.
.end_defvar

.defvar terminal-io
The value of var{terminal-io} is ordinarily the stream which
connects to the user's console.
.end_defvar

All of the above streams, with the exception of var{terminal-io},
are initially bound to synonym streams which pass all operations on to
the stream which is the value of var{terminal-io}.  (In practice,
this may not be the case yet.  They may simply have as their values
the value of var{terminal-io}.)

The value of var{terminal-io} should not normally be changed;  to
change where various input and output is sent, the appropriate other
stream(s) should be modified.  There are occasions when it might be
reasonable to change the value of var{terminal-io}, however, which
is why the other streams are supposed to indirect through the value of
it:  fancy graphics or window hacking might necessitate making a
completely new stream for it.  This type of thing will be dealt with
in some later version of this document.

lan{Nil} additionally defines the following streams, which should
probably be flushed, or at least renamed with something more in line
with the above variables.

.defvar msgfiles
This is used for random kinds of message printout which will not
require interaction on the part of the user.  The compiler, for
instance, prints its notifications here.
.end_defvar

.defvar echofiles
This probably isn't supported.  It is documented so that you can be
told not to use it.  It probably doesn't work.  I don't feel like
trying it.
.end_defvar


.section "Creating New Streams"

.defun make-synonym-stream symbol
This makes a term_i{synonym stream}.  Such a stream directs (most)
operations on it to the current dynamic binding of the variable
2symbol*.  In this way, the stream produced can always be
indirecting to another stream, even when the other changes.
.end_defun

.defun make-string-output-stream &optional &key (:line-length 79) (:line-number 1) (:page-length 60) (:page-number 1) (:character-position 0)
This creates a stream which will accumulate all output given to it.
This output may be obtained as a string by
fun{get-output-stream-string}, below.

The 2options* are used to initialize various parameters of the
stream, so that formatting may be performed to it.  By special
dispensation to lan{common lisp}, if
fun{make-string-output-stream} is given exactly one argument, that
is the line length.
.end_defun

.defun get-output-stream-string string-output-stream
2string-output-stream* should be a stream created by
fun{make-string-output-stream}.  This returns all of the text
accumulated since the last call to fun{get-output-stream-string} on
this stream, or the stream's creation, as a string.
.end_defun

.defspec with-output-to-string (var . options) body...
This binds 2var* to a stream which will accumulate all output sent
to it as a string, which will be returned when
fun{with-output-to-string} returns.  The 2options* which the
stream may be created with are passed directly to
fun{make-string-output-stream}, q.v.  The stream so created has
only 2dynamic* extent;  it is allocated as a resource, and
deallocated on exit from fun{with-output-to-string}.  As such,
fun{with-output-to-string} can be more efficient than calling
fun{make-string-output-stream} and
fun{get-string-output-stream-string} yourself.
.end_defspec

.defun make-string-input-stream string &optional &key (:start 0) :end
This returns a stream which, when read from, will produce the
characters of 2string* from 2start* to 2end* (defaultly
the end of the string).  The behaviour of the stream is undefined if
2string* is modified during the reading.
.end_defun

.defspec with-input-from-stream (var string . options) body...
This evaluates 2body* in an environment in which 2var* is
bound to a stream created by fun{make-string-input-stream} with a
string of 2string* and extra options 2options*.

The stream so created, however, has only 2dynamic* extent.  The
stream is allocated on entry and deallocated on exit for later reuse,
so fun{with-input-from-stream} can be more efficient than doing this
yourself.
.end_defspec


.section "Operations on Streams"

.defun streamp object
Tells if 2object* is of type kwd{stream}.
.lisp
(streamp 2x*) <=> (typep 2x* 'stream)
.end_lisp
.end_defun


.defun close stream &optional abort-flag
Closes 2stream*.

You may close an already closed stream;  3close* will return
3nil* if the stream is already closed (or does not support
closing), 3t* otherwise.

If 2abort-flag* is not (false), then (in principal) this is an
error close, as perhaps performed by abnormal exit from a
fun{with-open-file} form.  For an output file, this 2might* mean
that the file gets deleted.  This is done with ordinary "disk"
type output streams.

2abort-flag* will probably be changed to be a keyworded argument
in the future.
.end_defun

