source: branches/0.15.x/abcl/src/org/armedbear/lisp/gray-streams.lisp

Last change on this file was 11391, checked in by vvoutilainen, 17 years ago

ABCL license is GPL + Classpath exception. This was intended
by Peter Graves, the original author. For reference, see
http://sourceforge.net/mailarchive/forum.php?thread_name=20040721115302.839%40prufrock&forum_name=armedbear-j-announce

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 26.3 KB
Line 
1;;; gray-streams.lisp
2;;;
3;;; Copyright (C) 2004-2007 Peter Graves, Andras Simon
4;;; $Id: gray-streams.lisp 11391 2008-11-15 22:38:34Z vvoutilainen $
5;;;
6;;; This program is free software; you can redistribute it and/or
7;;; modify it under the terms of the GNU General Public License
8;;; as published by the Free Software Foundation; either version 2
9;;; of the License, or (at your option) any later version.
10;;;
11;;; This program is distributed in the hope that it will be useful,
12;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with this program; if not, write to the Free Software
18;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19;;;
20;;; As a special exception, the copyright holders of this library give you
21;;; permission to link this library with independent modules to produce an
22;;; executable, regardless of the license terms of these independent
23;;; modules, and to copy and distribute the resulting executable under
24;;; terms of your choice, provided that you also meet, for each linked
25;;; independent module, the terms and conditions of the license of that
26;;; module.  An independent module is a module which is not derived from
27;;; or based on this library.  If you modify this library, you may extend
28;;; this exception to your version of the library, but you are not
29;;; obligated to do so.  If you do not wish to do so, delete this
30;;; exception statement from your version.
31
32;;; Adapted from:
33;;;; Gray Streams Implementation for Corman Lisp - Version 1.3
34;;;;
35;;;; Copyright (C) 2000 Christopher Double. All Rights Reserved.
36;;;;
37;;;; License
38;;;; =======
39;;;; This software is provided 'as-is', without any express or implied
40;;;; warranty. In no event will the author be held liable for any damages
41;;;; arising from the use of this software.
42;;;;
43;;;; Permission is granted to anyone to use this software for any purpose,
44;;;; including commercial applications, and to alter it and redistribute
45;;;; it freely, subject to the following restrictions:
46;;;;
47;;;; 1. The origin of this software must not be misrepresented; you must
48;;;;    not claim that you wrote the original software. If you use this
49;;;;    software in a product, an acknowledgment in the product documentation
50;;;;    would be appreciated but is not required.
51;;;;
52;;;; 2. Altered source versions must be plainly marked as such, and must
53;;;;    not be misrepresented as being the original software.
54;;;;
55;;;; 3. This notice may not be removed or altered from any source
56;;;;    distribution.
57;;;;
58;;;; Notes
59;;;; =====
60;;;; A simple implementation of Gray streams for Corman Lisp 1.42.
61;;;; Gray streams are 'clos' based streams as described at:
62;;;;
63;;;; ftp://parcftp.xerox.com/pub/cl/cleanup/mail/stream-definition-by-user.mail
64;;;;
65;;;; Some differences exist between this implementation and the
66;;;; specification above. See notes below for details.
67;;;;
68;;;; More recent versions of this software may be available at:
69;;;;   http://www.double.co.nz/cl
70;;;;
71;;;; Comments, suggestions and bug reports to the author,
72;;;; Christopher Double, at: chris@double.co.nz
73;;;;
74;;;; 03/03/2001 - 1.0
75;;;;              Initial release.
76;;;;
77;;;; 20/08/2001 - 1.1
78;;;;              Small modifications by Frederic Bastenaire (fba@free.fr)
79;;;;              (lines flagged by  ;; # fb 1.01)
80;;;;              - Make it work with the READ function by
81;;;;                defining %read-char, %read-char-with-error
82;;;;               and input-character-stream-p
83;;;;              - Add nickname GS to package "GRAY-STREAMS" for ease of use
84;;;;              - added missing '*' to *old-write-byte* in gray-write-byte
85;;;;
86;;;; 03/01/2002 - 1.2
87;;;;              Fixed bug with GRAY-WRITE-LINE and GRAY-WRITE-STRING
88;;;;              that appeared in Corman Lisp 2.0 due to changes to
89;;;;              WRITE-LINE and WRITE-STRING.
90;;;;
91;;;; 04/01/2002 - 1.3
92;;;;              Added support for STREAM-READ-SEQUENCE and STREAM-WRITE-SEQUENCE.
93;;;;              Fixed STREAM-WRITE-STRING bug.
94;;;;
95;;;; Notes
96;;;; =====
97;;;; CLOSE is not a generic function in this implementation. Instead,
98;;;; the generic is called STREAM-CLOSE and the function CLOSE calls
99;;;; STREAM-CLOSE. The same goes for STREAMP, INPUT-STREAM-P,
100;;;; OUTPUT-STREAM-P and STREAM-ELEMENT-TYPE. The generic functions for
101;;;; these are STREAM-STREAMP, STREAM-INPUT-STREAM-P,
102;;;; STREAM-OUTPUT-STREAM-P and STREAM-STREAM-ELEMENT-TYPE.
103;;;;
104;;;; The standard Corman Lisp streams are not derived from
105;;;; FUNDAMENTAL-STREAM. All the stream functions check to see if the
106;;;; stream is an original Corman Lisp stream and forward on to the
107;;;; original function implementations.
108;;;;
109;;;; The string streams are implemented in this file as Gray streams
110;;;; but do not replace the Corman Lisp string streams. They are only
111;;;; implemented here to test the Gray stream functionality. These methods
112;;;; are called:
113;;;;    GRAY-MAKE-STRING-OUTPUT-STREAM
114;;;;    GRAY-GET-OUTPUT-STREAM-STRING
115;;;;    GRAY-MAKE-STRING-INPUT-STREAM
116;;;;
117;;;; Much of the implementation of the Gray streams below is from the
118;;;; document referenced earlier.
119;;;;
120(defpackage "GRAY-STREAMS"
121  (:use
122   "COMMON-LISP")
123  (:nicknames "GS") ;; # fb 1.01
124  (:export
125   "FUNDAMENTAL-STREAM"
126   "STREAM-CLOSE"
127   "STREAM-OPEN-STREAM-P"
128   "STREAM-STREAMP"
129   "STREAM-INPUT-STREAM-P"
130   "STREAM-OUTPUT-STREAM-P"
131   "STREAM-STREAM-ELEMENT-TYPE"
132   "STREAM-CLOSE"
133   "FUNDAMENTAL-OUTPUT-STREAM"
134   "FUNDAMENTAL-INPUT-STREAM"
135   "FUNDAMENTAL-CHARACTER-STREAM"
136   "FUNDAMENTAL-BINARY-STREAM"
137   "STREAM-READ-BYTE"
138   "STREAM-WRITE-BYTE"
139   "FUNDAMENTAL-CHARACTER-INPUT-STREAM"
140   "STREAM-READ-CHAR"
141   "STREAM-UNREAD-CHAR"
142   "STREAM-READ-CHAR-NO-HANG"
143   "STREAM-PEEK-CHAR"
144   "STREAM-LISTEN"
145   "STREAM-READ-LINE"
146   "STREAM-CLEAR-INPUT"
147   "FUNDAMENTAL-CHARACTER-OUTPUT-STREAM"
148   "STREAM-WRITE-CHAR"
149   "STREAM-LINE-COLUMN"
150   "STREAM-START-LINE-P"
151   "STREAM-WRITE-STRING"
152   "STREAM-TERPRI"
153   "STREAM-FRESH-LINE"
154   "STREAM-FINISH-OUTPUT"
155   "STREAM-FORCE-OUTPUT"
156   "STREAM-CLEAR-OUTPUT"
157   "STREAM-ADVANCE-TO-COLUMN"
158   "STREAM-READ-SEQUENCE"
159   "STREAM-WRITE-SEQUENCE"
160   "FUNDAMENTAL-BINARY-INPUT-STREAM"
161   "FUNDAMENTAL-BINARY-OUTPUT-STREAM"))
162
163(in-package :gray-streams)
164
165(defvar *old-read-char* #'read-char)
166(defvar *old-peek-char* #'peek-char)
167(defvar *old-unread-char* #'unread-char)
168(defvar *old-listen* nil)
169(defvar *old-read-line* #'read-line)
170(defvar *old-read-char-no-hang* #'read-char-no-hang)
171(defvar *old-write-char* #'write-char)
172(defvar *old-fresh-line* #'fresh-line)
173(defvar *old-terpri* #'terpri)
174(defvar *old-write-string* #'write-string)
175(defvar *old-write-line* #'write-line)
176(defvar *old-force-output* #'sys::%force-output)
177(defvar *old-finish-output* #'sys::%finish-output)
178(defvar *old-clear-output* #'sys::%clear-output)
179(defvar *old-clear-input* #'clear-input)
180(defvar *old-read-byte* #'read-byte)
181(defvar *old-write-byte* #'write-byte)
182(defvar *old-stream-element-type* #'cl::stream-element-type)
183(defvar *old-close* #'cl::close)
184(defvar *old-input-character-stream-p*
185  #'(lambda (s) (and (input-stream-p s) (eql (stream-element-type s) 'character))))
186(defvar *old-input-stream-p* #'cl::input-stream-p)
187(defvar *old-output-stream-p* #'cl::output-stream-p)
188(defvar *old-open-stream-p* #'cl::open-stream-p)
189(defvar *old-streamp* #'cl::streamp)
190(defvar *old-read-sequence* #'cl::read-sequence)
191(defvar *old-write-sequence* #'cl::write-sequence)
192(defvar *old-make-two-way-stream* #'cl:make-two-way-stream)
193(defvar *old-two-way-stream-input-stream* #'cl:two-way-stream-input-stream)
194(defvar *old-two-way-stream-output-stream* #'cl:two-way-stream-output-stream)
195
196
197(defun old-streamp (stream)
198  (funcall *old-streamp* stream))
199
200(defclass fundamental-stream ())
201
202(defgeneric stream-close (stream &key abort))
203(defgeneric stream-open-stream-p (stream))
204(defgeneric stream-streamp (stream))
205(defgeneric stream-input-stream-p (stream))
206(defgeneric stream-input-character-stream-p (stream)) ;; # fb 1.01
207(defgeneric stream-output-stream-p (stream))
208(defgeneric stream-stream-element-type (stream))
209
210(defmethod stream-close (stream &key abort)
211  (declare (ignore stream abort))
212  nil)
213
214(defmethod stream-streamp (s)
215  (declare (ignore s))
216  nil)
217
218(defmethod stream-streamp ((s fundamental-stream))
219  s)
220
221(defclass fundamental-input-stream (fundamental-stream))
222
223(defmethod stream-input-character-stream-p (s)  ;; # fb 1.01
224  (and (stream-input-stream-p s)
225       (eq (stream-stream-element-type s) 'character)))
226
227(defmethod stream-input-stream-p (s)
228  (declare (ignore s))
229  nil)
230
231(defmethod stream-input-stream-p ((s fundamental-input-stream))
232  (declare (ignore s))
233  t)
234
235(defclass fundamental-output-stream (fundamental-stream))
236
237(defmethod stream-output-stream-p (s)
238  (declare (ignore s))
239  nil)
240
241(defmethod stream-output-stream-p ((s fundamental-output-stream))
242  (declare (ignore s))
243  t)
244
245(defclass fundamental-character-stream (fundamental-stream))
246
247(defmethod stream-stream-element-type ((s fundamental-character-stream))
248  (declare (ignore s))
249  'character)
250
251(defclass fundamental-binary-stream (fundamental-stream))
252
253(defgeneric stream-read-byte (stream))
254(defgeneric stream-write-byte (stream integer))
255
256(defclass fundamental-character-input-stream
257  (fundamental-input-stream fundamental-character-stream))
258
259(defgeneric stream-read-char (stream))
260(defgeneric stream-unread-char (stream character))
261(defgeneric stream-read-char-no-hang (stream))
262(defgeneric stream-peek-char (stream))
263(defgeneric stream-listen (stream))
264(defgeneric stream-read-line (stream))
265(defgeneric stream-clear-input (stream))
266
267(defmethod stream-peek-char ((stream fundamental-character-input-stream))
268  (let ((character (stream-read-char stream)))
269    (unless (eq character :eof)
270      (stream-unread-char stream character))
271    character))
272
273(defmethod stream-listen ((stream  fundamental-character-input-stream))
274  (let ((char (stream-read-char-no-hang stream)))
275    (and (not (null char))
276         (not (eq char :eof))
277         (progn
278           (stream-unread-char stream char)
279           t))))
280
281(defmethod stream-read-line ((stream  fundamental-character-input-stream))
282  (let ((line (make-array 64
283                          :element-type 'character
284                          :fill-pointer 0
285                          :adjustable t)))
286    (loop
287      (let ((character (stream-read-char stream)))
288        (if (eq character :eof)
289            (return (values line t))
290            (if (eql character #\Newline)
291                (return (values line nil))
292                (vector-push-extend character line)))))))
293
294(defclass fundamental-character-output-stream
295  (fundamental-output-stream fundamental-character-stream))
296
297(defgeneric stream-write-char (stream character))
298(defgeneric stream-line-column (stream))
299(defgeneric stream-start-line-p (stream))
300(defgeneric stream-write-string (stream string &optional start end))
301(defgeneric stream-terpri (stream))
302(defgeneric stream-fresh-line (stream))
303(defgeneric stream-finish-output (stream))
304(defgeneric stream-force-output (stream))
305(defgeneric stream-clear-output (stream))
306(defgeneric stream-advance-to-column (stream column))
307(defgeneric stream-read-sequence (stream sequence start end))
308(defgeneric stream-write-sequence (stream sequence start end))
309
310(defmethod stream-force-output (stream)
311  (declare (ignore stream))
312  nil)
313
314(defmethod stream-start-line-p ((stream fundamental-character-output-stream))
315  (equal (stream-line-column stream) 0))
316
317(defmethod stream-write-string ((stream fundamental-character-output-stream)
318                                string
319                                &optional
320                                (start 0)
321                                (end (length string)))
322  (let ((start (or start 0))
323        (end (or end (length string))))
324    (do ((i start (1+ i)))
325        ((>= i end) string)
326      (stream-write-char stream (char string i)))))
327
328(defmethod stream-fresh-line ((stream fundamental-character-output-stream))
329  (if (stream-start-line-p stream)
330      nil
331      (progn
332        (stream-terpri stream)
333        t)))
334
335(defmethod stream-advance-to-column ((stream fundamental-character-output-stream)
336                                     column)
337  (let ((current (stream-line-column stream)))
338    (unless (null current)
339      (dotimes (i (- current column) t)
340        (stream-write-char stream #\Space)))))
341
342(defmethod stream-read-sequence ((stream  fundamental-character-input-stream) sequence start end)
343  (if (null end)
344      (setf end (length sequence)))
345  (let ((element-type (stream-element-type stream))
346        (eof (cons nil nil)))
347    (cond
348     ((eq element-type 'character)
349      (dotimes (count (- end start) (- end start))
350        (let ((c (stream-read-char stream nil eof)))
351          (if (eq c eof)
352              (return (+ count start)))
353          (setf (elt sequence (+ count start)) c))))
354     ((or (eq element-type 'byte)
355          (eq element-type 'unsigned-byte)
356          (eq element-type 'signed-byte))
357      (dotimes (count (- end start) (- end start))
358        (let ((b (stream-read-byte stream nil eof)))
359          (if (eq b eof)
360              (return (+ count start)))
361          (setf (elt sequence (+ count start)) b))))
362     (t (error "Cannot READ-SEQUENCE on stream of :ELEMENT-TYPE ~A" element-type)))))
363
364(defmethod stream-write-sequence ((stream fundamental-character-output-stream)
365                                  sequence start end)
366  (let ((element-type (stream-element-type stream))
367        (start (if start start 0))
368        (end (if end end (length sequence))))
369    (if (eq element-type 'character)
370        (do ((n start (+ n 1)))
371            ((= n end))
372          (stream-write-char
373           stream
374           (if (typep (elt sequence n) 'number)
375               (#+nil ccl:int-char code-char (elt sequence n))
376               (elt sequence n))))
377        (do ((n start (+ n 1)))
378            ((= n end))
379          (stream-write-byte (elt sequence n) stream))))    ;; recoded to avoid LOOP, because it isn't loaded yet
380  (stream-force-output stream))
381
382(defclass fundamental-binary-input-stream
383  (fundamental-input-stream fundamental-binary-stream))
384
385(defclass fundamental-binary-output-stream
386  (fundamental-output-stream fundamental-binary-stream))
387
388(defun decode-read-arg (arg)
389  (cond ((null arg) *standard-input*)
390        ((eq arg t) *terminal-io*)
391        (t arg)))
392
393(defun decode-print-arg (arg)
394  (cond ((null arg) *standard-output*)
395        ((eq arg t) *terminal-io*)
396        (t arg)))
397
398(defun report-eof (stream eof-errorp eof-value)
399  (if eof-errorp
400      (error 'end-of-file :stream stream)
401      eof-value))
402
403(defun check-for-eof (value stream eof-errorp eof-value)
404  (if (eq value :eof)
405      (report-eof stream eof-errorp eof-value)
406      value))
407
408(defun gray-read-char (&optional input-stream (eof-errorp t) eof-value recursive-p)
409  (let ((stream (decode-read-arg input-stream)))
410    (if (old-streamp stream)
411        (funcall *old-read-char* stream eof-errorp eof-value recursive-p)
412        (check-for-eof (stream-read-char stream) stream eof-errorp eof-value))))
413
414(defun gray-peek-char (&optional peek-type input-stream (eof-errorp t)
415                                 eof-value recursive-p)
416  (let ((stream (decode-read-arg input-stream)))
417    (if (old-streamp stream)
418        (funcall *old-peek-char* peek-type stream eof-errorp eof-value recursive-p)
419        (if (null peek-type)
420            (check-for-eof (stream-peek-char stream) stream eof-errorp eof-value)
421            (loop
422              (let ((value (stream-peek-char stream)))
423                (if (eq value :eof)
424                    (return (report-eof stream eof-errorp eof-value))
425                    (if (if (eq peek-type t)
426                            (not (member value
427                                         '(#\space #\tab #\newline #\return)))
428                            (char= peek-type value))
429                        (return value)
430                        (stream-read-char stream)))))))))
431
432(defun gray-unread-char (character &optional input-stream)
433  (let ((stream (decode-read-arg input-stream)))
434    (if (old-streamp stream)
435        (funcall *old-unread-char* character stream)
436        (stream-unread-char stream character))))
437
438(defun gray-listen (&optional input-stream)
439  (let ((stream (decode-read-arg input-stream)))
440    (if (old-streamp stream)
441        (funcall *old-listen* stream)
442        (stream-listen stream))))
443
444(defun gray-read-line (&optional input-stream (eof-error-p t)
445                                 eof-value recursive-p)
446  (let ((stream (decode-read-arg input-stream)))
447    (if (old-streamp stream)
448        (funcall *old-read-line* stream eof-error-p eof-value recursive-p)
449        (multiple-value-bind (string eofp)
450          (stream-read-line stream)
451          (if eofp
452              (if (= (length string) 0)
453                  (report-eof stream eof-error-p eof-value)
454                  (values string t))
455              (values string nil))))))
456
457(defun gray-clear-input (&optional input-stream)
458  (let ((stream (decode-read-arg input-stream)))
459    (if (old-streamp stream)
460        (funcall *old-clear-input* stream)
461        (stream-clear-input stream))))
462
463(defun gray-read-char-no-hang (&optional input-stream (eof-errorp t)
464                                         eof-value recursive-p)
465  (let ((stream (decode-read-arg input-stream)))
466    (if (old-streamp stream)
467        (funcall *old-read-char-no-hang* stream eof-errorp eof-value recursive-p)
468        (check-for-eof (stream-read-char-no-hang stream)
469                       stream eof-errorp eof-value))))
470
471(defun gray-write-char (character &optional output-stream)
472  (let ((stream (decode-print-arg output-stream)))
473    (if (old-streamp stream)
474        (funcall *old-write-char* character stream)
475        (stream-write-char stream character))))
476
477(defun gray-fresh-line (&optional output-stream)
478  (let ((stream (decode-print-arg output-stream)))
479    (if (old-streamp stream)
480        (funcall *old-fresh-line* stream)
481        (stream-fresh-line stream))))
482
483(defun gray-terpri (&optional output-stream)
484  (let ((stream (decode-print-arg output-stream)))
485    (if (old-streamp stream)
486        (funcall *old-terpri* stream)
487        (stream-terpri stream))))
488
489(defun gray-write-string (string &optional output-stream &key (start 0) end)
490  (let ((stream (decode-print-arg output-stream)))
491    (if (old-streamp stream)
492        (funcall *old-write-string* string stream :start start :end end)
493        (stream-write-string stream string start end))))
494
495(defun gray-write-line (string &optional output-stream &key (start 0) end)
496  (let ((stream (decode-print-arg output-stream)))
497    (if (old-streamp stream)
498        (funcall *old-write-line* string stream :start start :end end)
499        (progn
500          (stream-write-string stream string start end)
501          (stream-terpri stream)
502          string))))
503
504(defun gray-force-output (&optional output-stream)
505  (let ((stream (decode-print-arg output-stream)))
506    (if (old-streamp stream)
507        (funcall *old-force-output* stream)
508        (stream-force-output stream))))
509
510(defun gray-finish-output (&optional output-stream)
511  (let ((stream (decode-print-arg output-stream)))
512    (if (old-streamp stream)
513        (funcall *old-finish-output* stream)
514        (stream-finish-output stream))))
515
516(defun gray-clear-output (&optional output-stream)
517  (let ((stream (decode-print-arg output-stream)))
518    (if (old-streamp stream)
519        (funcall *old-clear-output* stream)
520        (stream-clear-output stream))))
521
522(defun gray-read-byte (binary-input-stream &optional (eof-errorp t) eof-value)
523  (if (old-streamp binary-input-stream)
524      (funcall *old-read-byte* binary-input-stream eof-errorp eof-value)
525      (check-for-eof (stream-read-byte binary-input-stream)
526                     binary-input-stream eof-errorp eof-value)))
527
528(defun gray-write-byte (integer binary-output-stream)
529  (if (old-streamp binary-output-stream)
530      (funcall *old-write-byte* integer binary-output-stream)
531      (stream-write-byte binary-output-stream integer)))
532
533(defclass string-input-stream (fundamental-character-input-stream)
534  ((string :initarg :string :type string)
535   (index :initarg :start :type fixnum)
536   (end :initarg :end :type fixnum)))
537
538(defun gray-make-string-input-stream (string &optional (start 0) end)
539  (make-instance 'string-input-stream :string string
540                 :start start :end (or end (length string))))
541
542(defmethod stream-read-char ((stream string-input-stream))
543  (with-slots (index end string) stream
544    (if (>= index end)
545        :eof
546        (prog1
547         (char string index)
548         (incf index)))))
549
550(defmethod stream-unread-char ((stream string-input-stream) character)
551  (with-slots (index end string) stream
552    (decf index)
553    (assert (eql (char string index) character))
554    nil))
555
556(defmethod stream-read-line ((stream string-input-stream))
557  (with-slots (index end string) stream
558    (let* ((endline (position #\newline string :start index :end end))
559           (line (subseq string index endline)))
560      (if endline
561          (progn
562            (setq index (1+ endline))
563            (values line nil))
564          (progn
565            (setq index end)
566            (values line t))))))
567
568(defclass string-output-stream (fundamental-character-output-stream)
569  ((string :initform nil :initarg :string)))
570
571(defun gray-make-string-output-stream ()
572  (make-instance 'string-output-stream))
573
574(defun gray-get-output-stream-string (stream)
575  (with-slots (string) stream
576    (if (null string)
577        ""
578        (prog1
579         (coerce string 'string)
580         (setq string nil)))))
581
582(defmethod stream-write-char ((stream string-output-stream) character)
583  (with-slots (string) stream
584    (when (null string)
585      (setq string (make-array 64 :slement-type 'character
586                               :fill-pointer 0 :adjustable t)))
587    (vector-push-extend character string)
588    character))
589
590(defmethod stream-line-column ((stream string-output-stream))
591  (with-slots (string) stream
592    (if (null string)
593        0
594        (let ((nx (position #\newline string :from-end t)))
595          (if (null nx)
596              (length string)
597              (- (length string) nx 1))))))
598
599(defmethod stream-line-column ((stream stream))
600  nil)
601
602(defun gray-stream-column (&optional input-stream)
603  (let ((stream (decode-read-arg input-stream)))
604    (if (old-streamp stream)
605        nil ;(funcall *old-stream-column* stream)
606        (stream-line-column stream))))
607
608(defun gray-stream-element-type (stream)
609  (if (old-streamp stream)
610      (funcall *old-stream-element-type* stream)
611      (stream-stream-element-type stream)))
612
613(defun gray-close (stream &key abort)
614  (if (old-streamp stream)
615      (funcall *old-close* stream :abort abort)
616      (stream-close stream :abort nil)))
617
618(defun gray-input-stream-p (stream)
619  (if (old-streamp stream)
620      (funcall *old-input-stream-p* stream)
621      (stream-input-stream-p stream)))
622
623(defun gray-input-character-stream-p (stream)
624  (if (old-streamp stream)
625      (funcall *old-input-character-stream-p* stream)
626      (stream-input-character-stream-p stream)))
627
628(defun gray-output-stream-p (stream)
629  (if (old-streamp stream)
630      (funcall *old-output-stream-p* stream)
631      (stream-output-stream-p stream)))
632
633(defun gray-open-stream-p (stream)
634  (if (old-streamp stream)
635      (funcall *old-open-stream-p* stream)
636      (stream-open-stream-p stream)))
637
638(defun gray-streamp (stream)
639  (if (old-streamp stream)
640      (funcall *old-streamp* stream)
641      (stream-streamp stream)))
642
643(defun gray-write-sequence (sequence stream &key (start 0) end)
644  (if (old-streamp stream)
645      (funcall *old-write-sequence* sequence stream :start start :end end)
646      (stream-write-sequence stream sequence start end)))
647
648(defun gray-read-sequence (sequence stream &key (start 0) (end nil))
649  (if (old-streamp stream)
650      (funcall *old-read-sequence* sequence stream :start start :end end)
651      (stream-read-sequence stream sequence start end)))
652
653(defstruct two-way-stream-g
654  input-stream output-stream)
655
656(defun gray-make-two-way-stream (in out)
657  (if (and (old-streamp in) (old-streamp out))
658      (funcall *old-make-two-way-stream* in out)
659      (make-two-way-stream-g :input-stream in :output-stream out)))
660
661(defun gray-two-way-stream-input-stream (stream)
662  (if (old-streamp stream)
663      (funcall *old-two-way-stream-input-stream* stream)
664      (two-way-stream-g-input-stream stream)))
665
666(defun gray-two-way-stream-output-stream (stream)
667  (if (old-streamp stream)
668      (funcall *old-two-way-stream-output-stream* stream)
669      (two-way-stream-g-output-stream stream)))
670
671(setf (symbol-function 'common-lisp::read-char) #'gray-read-char)
672(setf (symbol-function 'common-lisp::peek-char) #'gray-peek-char)
673(setf (symbol-function 'common-lisp::unread-char) #'gray-unread-char)
674(setf (symbol-function 'common-lisp::read-line) #'gray-read-line)
675(setf (symbol-function 'common-lisp::clear-input) #'gray-clear-input)
676(setf (symbol-function 'common-lisp::read-char-no-hang) #'gray-read-char-no-hang)
677(setf (symbol-function 'common-lisp::write-char) #'gray-write-char)
678(setf (symbol-function 'common-lisp::fresh-line) #'gray-fresh-line)
679(setf (symbol-function 'common-lisp::terpri) #'gray-terpri)
680(setf (symbol-function 'common-lisp::write-string) #'gray-write-string)
681(setf (symbol-function 'common-lisp::write-line) #'gray-write-line)
682(setf (symbol-function 'sys::%force-output) #'gray-force-output)
683(setf (symbol-function 'sys::%finish-output) #'gray-finish-output)
684(setf (symbol-function 'sys::%clear-output) #'gray-clear-output)
685(setf (symbol-function 'common-lisp::read-byte) #'gray-read-byte)
686(setf (symbol-function 'common-lisp::write-byte) #'gray-write-byte)
687(setf (symbol-function 'common-lisp::stream-column) #'gray-stream-column)
688(setf (symbol-function 'common-lisp::stream-element-type) #'gray-stream-element-type)
689(setf (symbol-function 'common-lisp::close) #'gray-close)
690(setf (symbol-function 'common-lisp::input-stream-p) #'gray-input-stream-p)
691(setf (symbol-function 'common-lisp::input-character-stream-p) #'gray-input-character-stream-p)  ;; # fb 1.01
692(setf (symbol-function 'common-lisp::output-stream-p) #'gray-output-stream-p)
693(setf (symbol-function 'common-lisp::open-stream-p) #'gray-open-stream-p)
694(setf (symbol-function 'common-lisp::streamp) #'gray-streamp)
695(setf (symbol-function 'common-lisp::read-sequence) #'gray-read-sequence)
696(setf (symbol-function 'common-lisp::write-sequence) #'gray-write-sequence)
697(setf (symbol-function 'common-lisp::make-two-way-stream) #'gray-make-two-way-stream)
698(setf (symbol-function 'common-lisp::two-way-stream-input-stream) #'gray-two-way-stream-input-stream)
699(setf (symbol-function 'common-lisp::two-way-stream-output-stream) #'gray-two-way-stream-output-stream)
700
701(provide 'gray-streams)
Note: See TracBrowser for help on using the repository browser.