CLCS
Function

read, read-preserving-whitespace

read &optional input-stream eof-error-p eof-value recursive-p ⇒ object

read-preserving-whitespace &optional input-stream eof-error-p eof-value recursive-p
object

Arguments and Values

input-streaman input stream designator.
eof-error-pa generalized boolean. The default is true.
eof-valuean object.

The default is nil.

recursive-pa generalized boolean. The default is false.
objectan object (parsed by the Lisp reader) or the eof-value.

Description

read parses the printed representation of an object from input-stream and builds such an object.

read-preserving-whitespace is like read but preserves any whitespace_2 character that delimits the printed representation of the object. read-preserving-whitespace is exactly like read when the recursive-p argument to read-preserving-whitespace is true.

When *read-suppress* is false, read throws away the delimiting character required by certain printed representations if it is a whitespace_2 character; but read preserves the character (using unread-char) if it is syntactically meaningful, because it could be the start of the next expression.

If a file ends in a symbol or a number immediately followed by an end of file_1, read reads the symbol or number successfully; when called again, it sees the end of file_1 and only then acts according to eof-error-p. If a file contains ignorable text at the end, such as blank lines and comments, read does not consider it to end in the middle of an object.

If recursive-p is true, the call to read is expected to be made from within some function that itself has been called from read or from a similar input function, rather than from the top level.

Both functions return the object read from input-stream. Eof-value is returned if eof-error-p is false and end of file is reached before the beginning of an object.

Examples

 (read)
 |>  |>>'a<<|
⇒  (QUOTE A)
 (with-input-from-string (is " ") (read is nil 'the-end)) ⇒  THE-END
 (defun skip-then-read-char (s c n)
    (if (char= c #\{) (read s t nil t) (read-preserving-whitespace s))
    (read-char-no-hang s)) ⇒  SKIP-THEN-READ-CHAR
 (let ((*readtable* (copy-readtable nil)))
    (set-dispatch-macro-character #\# #\{ #'skip-then-read-char)
    (set-dispatch-macro-character #\# #\} #'skip-then-read-char)
    (with-input-from-string (is "#{123 x #}123 y")
      (format t "~S ~S" (read is) (read is)))) ⇒  #\x, #\Space, NIL

As an example, consider this reader macro definition:

 (defun slash-reader (stream char)
   (declare (ignore char))
   `(path . ,(loop for dir = (read-preserving-whitespace stream t nil t)
                   then (progn (read-char stream t nil t)
                               (read-preserving-whitespace stream t nil t))
                   collect dir
                   while (eql (peek-char nil stream nil nil t) #\/))))
 (set-macro-character #\/ #'slash-reader)

Consider now calling read on this expression:

 (zyedh /usr/games/zork /usr/games/boggle)

The / macro reads objects separated by more / characters; thus /usr/games/zork is intended to read as (path usr games zork). The entire example expression should therefore be read as

 (zyedh (path usr games zork) (path usr games boggle))

However, if read had been used instead of read-preserving-whitespace, then after the reading of the symbol zork, the following space would be discarded; the next call to peek-char would see the following /, and the loop would continue, producing this interpretation:

 (zyedh (path usr games zork usr games boggle))

There are times when whitespace_2 should be discarded. If a command interpreter takes single-character commands, but occasionally reads an object then if the whitespace_2 after a symbol is not discarded it might be interpreted as a command some time later after the symbol had been read.

Exceptional Situations

read signals an error of type end-of-file, regardless of eof-error-p, if the file ends in the middle of an object representation. For example, if a file does not contain enough right parentheses to balance the left parentheses in it, read signals an error. This is detected when read or read-preserving-whitespace is called with recursive-p and eof-error-p non-nil, and end-of-file is reached before the beginning of an object.

If eof-error-p is true, an error of type end-of-file is signaled at the end of file.