0.8.7.19:
authorChristophe Rhodes <csr21@cam.ac.uk>
Tue, 20 Jan 2004 18:10:22 +0000 (18:10 +0000)
committerChristophe Rhodes <csr21@cam.ac.uk>
Tue, 20 Jan 2004 18:10:22 +0000 (18:10 +0000)
Fix for PEEK-CHAR: whitespace means "according to the
readtable", not "static list of characters"
... but that's complicated for efficiency: we need WHITESPACEP
defined before peek-char so that it can be expanded
inline
... so move peek-charish things into a new later file
... delete unused-by-core WHITESPACE-CHAR-P, and adjust
contribs to accomodate this
... also add #\page to sb-aclrepl's static whitespace characters

NEWS
build-order.lisp-expr
contrib/sb-aclrepl/repl.lisp
contrib/sb-simple-streams/impl.lisp
src/code/stream.lisp
src/code/target-char.lisp
src/code/target-extensions.lisp
src/code/target-stream.lisp [new file with mode: 0644]
version.lisp-expr

diff --git a/NEWS b/NEWS
index 3ca21d1..8be61c1 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2258,6 +2258,8 @@ changes in sbcl-0.8.8 relative to sbcl-0.8.7:
        host is already defined.
     ** RENAME-FILE works on streams instead of signalling an internal
        type error.
        host is already defined.
     ** RENAME-FILE works on streams instead of signalling an internal
        type error.
+    ** PEEK-CHAR now uses the current readtable when determining
+       whether a character is whitespace.
 
 planned incompatible changes in 0.8.x:
   * (not done yet, but planned:) When the profiling interface settles
 
 planned incompatible changes in 0.8.x:
   * (not done yet, but planned:) When the profiling interface settles
index 4214e69..4af8283 100644 (file)
  ("src/code/target-random"     :not-host) ; needs "code/random"
  ("src/code/target-hash-table" :not-host) ; needs "code/hash-table"
  ("src/code/reader"            :not-host) ; needs "code/readtable"
  ("src/code/target-random"     :not-host) ; needs "code/random"
  ("src/code/target-hash-table" :not-host) ; needs "code/hash-table"
  ("src/code/reader"            :not-host) ; needs "code/readtable"
+ ("src/code/target-stream"     :not-host) ; needs WHITESPACEP from "code/reader"
  ("src/code/target-pathname"   :not-host) ; needs "code/pathname"
  ("src/code/filesys"           :not-host) ; needs HOST from "code/pathname"
  ("src/code/save"              :not-host) ; uses the definition of PATHNAME
  ("src/code/target-pathname"   :not-host) ; needs "code/pathname"
  ("src/code/filesys"           :not-host) ; needs HOST from "code/pathname"
  ("src/code/save"              :not-host) ; uses the definition of PATHNAME
index defbc32..800d9b3 100644 (file)
   (and (characterp x)
        (or (char= x #\space)
           (char= x #\tab)
   (and (characterp x)
        (or (char= x #\space)
           (char= x #\tab)
+          (char= x #\page)
           (char= x #\newline)
           (char= x #\return))))
 
 (defun whitespace-char-not-newline-p (x)
   (and (whitespace-char-p x)
        (not (char= x #\newline))))
           (char= x #\newline)
           (char= x #\return))))
 
 (defun whitespace-char-not-newline-p (x)
   (and (whitespace-char-p x)
        (not (char= x #\newline))))
-
 \f
 ;;;; linking into SBCL hooks
 
 \f
 ;;;; linking into SBCL hooks
 
-
 (defun repl-prompt-fun (stream)
   (let ((break-level (when (plusp *break-level*)
                       *break-level*))
 (defun repl-prompt-fun (stream)
   (let ((break-level (when (plusp *break-level*)
                       *break-level*))
index 2657fb1..a8adfa0 100644 (file)
     (etypecase stream
       (simple-stream
        (%peek-char stream peek-type eof-error-p eof-value recursive-p))
     (etypecase stream
       (simple-stream
        (%peek-char stream peek-type eof-error-p eof-value recursive-p))
+      ;; FIXME: Broken on ECHO-STREAM (cf internal implementation?) --
+      ;; CSR, 2004-01-19
       (ansi-stream
        (let ((char (%ansi-stream-read-char stream eof-error-p eof-value t)))
           (cond ((eq char eof-value) char)
       (ansi-stream
        (let ((char (%ansi-stream-read-char stream eof-error-p eof-value t)))
           (cond ((eq char eof-value) char)
                  (do ((char char (%ansi-stream-read-char stream eof-error-p
                                                          eof-value t)))
                      ((or (eq char eof-value)
                  (do ((char char (%ansi-stream-read-char stream eof-error-p
                                                          eof-value t)))
                      ((or (eq char eof-value)
-                         (not (sb-int:whitespace-char-p char)))
+                         (not (sb-impl::whitespacep char)))
                       (unless (eq char eof-value)
                         (%ansi-stream-unread-char char stream))
                       char)))
                       (unless (eq char eof-value)
                         (%ansi-stream-unread-char char stream))
                       char)))
             ((eq peek-type t)
              (do ((char (sb-gray:stream-read-char stream)
                         (sb-gray:stream-read-char stream)))
             ((eq peek-type t)
              (do ((char (sb-gray:stream-read-char stream)
                         (sb-gray:stream-read-char stream)))
-                 ((or (eq char :eof) (not (sb-int:whitespace-char-p char)))
+                 ((or (eq char :eof) (not (sb-impl::whitespacep char)))
                   (cond ((eq char :eof)
                          (sb-impl::eof-or-lose stream eof-error-p eof-value))
                         (t
                   (cond ((eq char :eof)
                          (sb-impl::eof-or-lose stream eof-error-p eof-value))
                         (t
index f39c4f5..63b3fa3 100644 (file)
        (stream-unread-char stream character)))
   nil)
 
        (stream-unread-char stream character)))
   nil)
 
-
-;;; In the interest of ``once and only once'' this macro contains the
-;;; framework necessary to implement a peek-char function, which has
-;;; two special-cases (one for gray streams and one for echo streams)
-;;; in addition to the normal case.
-;;;
-;;; All arguments are forms which will be used for a specific purpose
-;;; PEEK-TYPE - the current peek-type as defined by ANSI CL
-;;; EOF-VALUE - the eof-value argument to peek-char
-;;; CHAR-VAR - the variable which will be used to store the current character
-;;; READ-FORM - the form which will be used to read a character
-;;; UNREAD-FORM - ditto for unread-char
-;;; SKIPPED-CHAR-FORM - the form to execute when skipping a character
-;;; EOF-DETECTED-FORM - the form to execute when EOF has been detected
-;;;                     (this will default to CHAR-VAR)
-(defmacro generalized-peeking-mechanism (peek-type eof-value char-var read-form unread-form &optional (skipped-char-form nil) (eof-detected-form nil))
-  `(let ((,char-var ,read-form))
-    (cond ((eql ,char-var ,eof-value) 
-          ,(if eof-detected-form
-               eof-detected-form
-               char-var))
-         ((characterp ,peek-type)
-          (do ((,char-var ,char-var ,read-form))
-              ((or (eql ,char-var ,eof-value) 
-                   (char= ,char-var ,peek-type))
-               (cond ((eql ,char-var ,eof-value)
-                      ,(if eof-detected-form
-                           eof-detected-form
-                           char-var))
-                     (t ,unread-form
-                        ,char-var)))
-            ,skipped-char-form))
-         ((eql ,peek-type t)
-          (do ((,char-var ,char-var ,read-form))
-              ((or (eql ,char-var ,eof-value)
-                   (not (whitespace-char-p ,char-var)))
-               (cond ((eql ,char-var ,eof-value)
-                      ,(if eof-detected-form
-                           eof-detected-form
-                           char-var))
-                     (t ,unread-form
-                        ,char-var)))
-            ,skipped-char-form))
-         ((null ,peek-type)
-          ,unread-form
-          ,char-var)
-         (t
-          (bug "Impossible case reached in PEEK-CHAR")))))
-
-(defun peek-char (&optional (peek-type nil)
-                           (stream *standard-input*)
-                           (eof-error-p t)
-                           eof-value
-                           recursive-p)
-  (declare (ignore recursive-p))
-  (the (or character boolean) peek-type)
-  (let ((stream (in-synonym-of stream)))
-    (cond ((typep stream 'echo-stream)
-          (echo-misc stream
-                     :peek-char
-                     peek-type
-                     (list eof-error-p eof-value)))
-         ((ansi-stream-p stream)
-          (generalized-peeking-mechanism
-           peek-type eof-value char
-           (read-char stream eof-error-p eof-value)
-           (unread-char char stream)))
-         (t
-          ;; by elimination, must be Gray streams FUNDAMENTAL-STREAM
-          (generalized-peeking-mechanism
-           peek-type :eof char
-           (if (null peek-type)
-               (stream-peek-char stream)
-               (stream-read-char stream))
-           (if (null peek-type)
-               ()
-               (stream-unread-char stream char))
-           ()
-           (eof-or-lose stream eof-error-p eof-value))))))
-
 (defun listen (&optional (stream *standard-input*))
   (let ((stream (in-synonym-of stream)))
     (if (ansi-stream-p stream)
 (defun listen (&optional (stream *standard-input*))
   (let ((stream (in-synonym-of stream)))
     (if (ansi-stream-p stream)
                      result)))))
   (in-fun echo-in read-char write-char eof-error-p eof-value)
   (in-fun echo-bin read-byte write-byte eof-error-p eof-value))
                      result)))))
   (in-fun echo-in read-char write-char eof-error-p eof-value)
   (in-fun echo-bin read-byte write-byte eof-error-p eof-value))
-
-(defun echo-misc (stream operation &optional arg1 arg2)
-  (let* ((in (two-way-stream-input-stream stream))
-        (out (two-way-stream-output-stream stream)))
-    (case operation
-      (:listen
-       (or (not (null (echo-stream-unread-stuff stream)))
-          (if (ansi-stream-p in)
-              (or (/= (the fixnum (ansi-stream-in-index in))
-                      +ansi-stream-in-buffer-length+)
-                  (funcall (ansi-stream-misc in) in :listen))
-              (stream-misc-dispatch in :listen))))
-      (:unread (push arg1 (echo-stream-unread-stuff stream)))
-      (:element-type
-       (let ((in-type (stream-element-type in))
-            (out-type (stream-element-type out)))
-        (if (equal in-type out-type)
-            in-type `(and ,in-type ,out-type))))
-      (:close
-       (set-closed-flame stream))
-      (:peek-char
-       ;; For the special case of peeking into an echo-stream
-       ;; arg1 is PEEK-TYPE, arg2 is (EOF-ERROR-P EOF-VALUE)
-       ;; returns peeked-char, eof-value, or errors end-of-file
-       ;;
-       ;; Note: This code could be moved into PEEK-CHAR if desired.
-       ;; I am unsure whether this belongs with echo-streams because it is
-       ;; echo-stream specific, or PEEK-CHAR because it is peeking code.
-       ;; -- mrd 2002-11-18
-       ;;
-       ;; UNREAD-CHAR-P indicates whether the current character was one
-       ;; that was previously unread.  In that case, we need to ensure that
-       ;; the semantics for UNREAD-CHAR are held; the character should
-       ;; not be echoed again.
-       (let ((unread-char-p nil))
-        (flet ((outfn (c)
-                 (unless unread-char-p
-                   (if (ansi-stream-p out)
-                       (funcall (ansi-stream-out out) out c)
-                       ;; gray-stream
-                       (stream-write-char out c))))
-               (infn ()
-                 ;; Obtain input from unread buffer or input stream,
-                 ;; and set the flag appropriately.
-                 (cond ((not (null (echo-stream-unread-stuff stream)))
-                        (setf unread-char-p t)
-                        (pop (echo-stream-unread-stuff stream)))
-                       (t
-                        (setf unread-char-p nil)
-                        (read-char in (first arg2) (second arg2))))))
-          (generalized-peeking-mechanism
-           arg1 (second arg2) char
-           (infn)
-           (unread-char char in)
-           (outfn char)))))
-      (t
-       (or (if (ansi-stream-p in)
-              (funcall (ansi-stream-misc in) in operation arg1 arg2)
-              (stream-misc-dispatch in operation arg1 arg2))
-          (if (ansi-stream-p out)
-              (funcall (ansi-stream-misc out) out operation arg1 arg2)
-              (stream-misc-dispatch out operation arg1 arg2)))))))
 \f
 ;;;; base STRING-STREAM stuff
 
 \f
 ;;;; base STRING-STREAM stuff
 
index 4be9e83..161d893 100644 (file)
          ;; Else, fail.
          (t nil))))
 
          ;; Else, fail.
          (t nil))))
 
-(defun whitespace-char-p (x)
-  (and (characterp x)
-       (or (char= x #\space)
-          (char= x (code-char tab-char-code))
-          (char= x (code-char return-char-code))
-          (char= x #\linefeed))))
-
 (defun alphanumericp (char)
   #!+sb-doc
   "Given a character-object argument, ALPHANUMERICP returns T if the
 (defun alphanumericp (char)
   #!+sb-doc
   "Given a character-object argument, ALPHANUMERICP returns T if the
index 7b13df4..cbaab4d 100644 (file)
   up. The system itself should be initialized at this point, but applications
   might not be.")
 \f
   up. The system itself should be initialized at this point, but applications
   might not be.")
 \f
-;;;; miscellaneous I/O
-
-(defun skip-whitespace (&optional (stream *standard-input*))
-  (loop (let ((char (read-char stream)))
-         (unless (sb!impl::whitespacep char)
-           (return (unread-char char stream))))))
-
 ;;; like LISTEN, but any whitespace in the input stream will be flushed
 (defun listen-skip-whitespace (&optional (stream *standard-input*))
   (do ((char (read-char-no-hang stream nil nil nil)
             (read-char-no-hang stream nil nil nil)))
       ((null char) nil)
 ;;; like LISTEN, but any whitespace in the input stream will be flushed
 (defun listen-skip-whitespace (&optional (stream *standard-input*))
   (do ((char (read-char-no-hang stream nil nil nil)
             (read-char-no-hang stream nil nil nil)))
       ((null char) nil)
-    (cond ((not (whitespace-char-p char))
+    (cond ((not (whitespacep char))
           (unread-char char stream)
           (return t)))))
 \f
           (unread-char char stream)
           (return t)))))
 \f
diff --git a/src/code/target-stream.lisp b/src/code/target-stream.lisp
new file mode 100644 (file)
index 0000000..4b254f6
--- /dev/null
@@ -0,0 +1,162 @@
+;;;; os-independent stream functions requiring reader machinery
+
+;;;; This software is part of the SBCL system. See the README file for
+;;;; more information.
+;;;;
+;;;; This software is derived from the CMU CL system, which was
+;;;; written at Carnegie Mellon University and released into the
+;;;; public domain. The software is in the public domain and is
+;;;; provided with absolutely no warranty. See the COPYING and CREDITS
+;;;; files for more information.
+
+(in-package "SB!IMPL")
+
+;;; In the interest of ``once and only once'' this macro contains the
+;;; framework necessary to implement a peek-char function, which has
+;;; two special-cases (one for gray streams and one for echo streams)
+;;; in addition to the normal case.
+;;;
+;;; All arguments are forms which will be used for a specific purpose
+;;; PEEK-TYPE - the current peek-type as defined by ANSI CL
+;;; EOF-VALUE - the eof-value argument to peek-char
+;;; CHAR-VAR - the variable which will be used to store the current character
+;;; READ-FORM - the form which will be used to read a character
+;;; UNREAD-FORM - ditto for unread-char
+;;; SKIPPED-CHAR-FORM - the form to execute when skipping a character
+;;; EOF-DETECTED-FORM - the form to execute when EOF has been detected
+;;;                     (this will default to CHAR-VAR)
+(eval-when (:compile-toplevel :execute)
+  (sb!xc:defmacro generalized-peeking-mechanism
+      (peek-type eof-value char-var read-form unread-form
+       &optional (skipped-char-form nil) (eof-detected-form nil))
+    `(let ((,char-var ,read-form))
+      (cond ((eql ,char-var ,eof-value) 
+             ,(if eof-detected-form
+                  eof-detected-form
+                  char-var))
+            ((characterp ,peek-type)
+             (do ((,char-var ,char-var ,read-form))
+                 ((or (eql ,char-var ,eof-value) 
+                      (char= ,char-var ,peek-type))
+                  (cond ((eql ,char-var ,eof-value)
+                         ,(if eof-detected-form
+                              eof-detected-form
+                              char-var))
+                        (t ,unread-form
+                           ,char-var)))
+               ,skipped-char-form))
+            ((eql ,peek-type t)
+             (do ((,char-var ,char-var ,read-form))
+                 ((or (eql ,char-var ,eof-value)
+                      (not (whitespacep ,char-var)))
+                  (cond ((eql ,char-var ,eof-value)
+                         ,(if eof-detected-form
+                              eof-detected-form
+                              char-var))
+                        (t ,unread-form
+                           ,char-var)))
+               ,skipped-char-form))
+            ((null ,peek-type)
+             ,unread-form
+             ,char-var)
+            (t
+             (bug "Impossible case reached in PEEK-CHAR"))))))
+
+;;; We proclaim them INLINE here, then proclaim them MAYBE-INLINE at EOF,
+;;; so, except in this file, they are not inline by default, but they can be.
+#!-sb-fluid (declaim (inline read-char unread-char read-byte listen))
+
+(defun peek-char (&optional (peek-type nil)
+                           (stream *standard-input*)
+                           (eof-error-p t)
+                           eof-value
+                           recursive-p)
+  (declare (ignore recursive-p))
+  (the (or character boolean) peek-type)
+  (let ((stream (in-synonym-of stream)))
+    (cond ((typep stream 'echo-stream)
+          (echo-misc stream
+                     :peek-char
+                     peek-type
+                     (list eof-error-p eof-value)))
+         ((ansi-stream-p stream)
+          (generalized-peeking-mechanism
+           peek-type eof-value char
+           (read-char stream eof-error-p eof-value)
+           (unread-char char stream)))
+         (t
+          ;; by elimination, must be Gray streams FUNDAMENTAL-STREAM
+          (generalized-peeking-mechanism
+           peek-type :eof char
+           (if (null peek-type)
+               (stream-peek-char stream)
+               (stream-read-char stream))
+           (if (null peek-type)
+               ()
+               (stream-unread-char stream char))
+           ()
+           (eof-or-lose stream eof-error-p eof-value))))))
+
+(defun echo-misc (stream operation &optional arg1 arg2)
+  (let* ((in (two-way-stream-input-stream stream))
+        (out (two-way-stream-output-stream stream)))
+    (case operation
+      (:listen
+       (or (not (null (echo-stream-unread-stuff stream)))
+          (if (ansi-stream-p in)
+              (or (/= (the fixnum (ansi-stream-in-index in))
+                      +ansi-stream-in-buffer-length+)
+                  (funcall (ansi-stream-misc in) in :listen))
+              (stream-misc-dispatch in :listen))))
+      (:unread (push arg1 (echo-stream-unread-stuff stream)))
+      (:element-type
+       (let ((in-type (stream-element-type in))
+            (out-type (stream-element-type out)))
+        (if (equal in-type out-type)
+            in-type `(and ,in-type ,out-type))))
+      (:close
+       (set-closed-flame stream))
+      (:peek-char
+       ;; For the special case of peeking into an echo-stream
+       ;; arg1 is PEEK-TYPE, arg2 is (EOF-ERROR-P EOF-VALUE)
+       ;; returns peeked-char, eof-value, or errors end-of-file
+       ;;
+       ;; Note: This code could be moved into PEEK-CHAR if desired.
+       ;; I am unsure whether this belongs with echo-streams because it is
+       ;; echo-stream specific, or PEEK-CHAR because it is peeking code.
+       ;; -- mrd 2002-11-18
+       ;;
+       ;; UNREAD-CHAR-P indicates whether the current character was one
+       ;; that was previously unread.  In that case, we need to ensure that
+       ;; the semantics for UNREAD-CHAR are held; the character should
+       ;; not be echoed again.
+       (let ((unread-char-p nil))
+        (flet ((outfn (c)
+                 (unless unread-char-p
+                   (if (ansi-stream-p out)
+                       (funcall (ansi-stream-out out) out c)
+                       ;; gray-stream
+                       (stream-write-char out c))))
+               (infn ()
+                 ;; Obtain input from unread buffer or input stream,
+                 ;; and set the flag appropriately.
+                 (cond ((not (null (echo-stream-unread-stuff stream)))
+                        (setf unread-char-p t)
+                        (pop (echo-stream-unread-stuff stream)))
+                       (t
+                        (setf unread-char-p nil)
+                        (read-char in (first arg2) (second arg2))))))
+          (generalized-peeking-mechanism
+           arg1 (second arg2) char
+           (infn)
+           (unread-char char in)
+           (outfn char)))))
+      (t
+       (or (if (ansi-stream-p in)
+              (funcall (ansi-stream-misc in) in operation arg1 arg2)
+              (stream-misc-dispatch in operation arg1 arg2))
+          (if (ansi-stream-p out)
+              (funcall (ansi-stream-misc out) out operation arg1 arg2)
+              (stream-misc-dispatch out operation arg1 arg2)))))))
+
+(declaim (maybe-inline read-char unread-char read-byte listen))
\ No newline at end of file
index 3979734..305174d 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.8.7.18"
+"0.8.7.19"