source: trunk/abcl/src/org/armedbear/lisp/gray-streams.lisp

Last change on this file was 15779, checked in by Mark Evenson, 3 months ago

Add support for gray:stream-file-string-length

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 33.0 KB
Line 
1;;; gray-streams.lisp
2;;;
3;;; Copyright (C) 2004-2007 Peter Graves, Andras Simon
4;;; $Id: gray-streams.lisp 15779 2024-01-30 07:00:31Z mevenson $
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;;;;
61;;;; NB: The ABCL implementation has been extensively reworked since these
62;;;; notes were included.  Please see the ABCL revision history via
63;;;; the interface at
64;;;;
65;;;; http://trac.common-lisp.net/armedbear/browser/trunk/abcl/src/org/armedbear/lisp/gray-streams.lisp
66;;;;
67;;;; for a more relevant history vis a vis the ABCL implementation.
68;;;;
69;;;; A simple implementation of Gray streams for Corman Lisp 1.42.
70;;;; Gray streams are 'clos' based streams as described at:
71;;;;
72;;;; ftp://parcftp.xerox.com/pub/cl/cleanup/mail/stream-definition-by-user.mail
73;;;;
74;;;; 20110319
75;;;;   The xerox.com ftp URI doesn't resolve.  Instead see Kent Pitman's
76;;;;   archival copy at
77;;;;
78;;;;     http://www.nhplace.com/kent/CL/Issues/stream-definition-by-user.html
79;;;;
80;;;; Some differences exist between this implementation and the
81;;;; specification above. See notes below for details.
82;;;;
83;;;; More recent versions of this software may be available at:
84;;;;   http://www.double.co.nz/cl
85;;;;
86;;;; Comments, suggestions and bug reports to the author,
87;;;; Christopher Double, at: chris@double.co.nz
88;;;;
89;;;; 03/03/2001 - 1.0
90;;;;              Initial release.
91;;;;
92;;;; 20/08/2001 - 1.1
93;;;;              Small modifications by Frederic Bastenaire (fba@free.fr)
94;;;;              (lines flagged by  ;; # fb 1.01)
95;;;;              - Make it work with the READ function by
96;;;;                defining %read-char, %read-char-with-error
97;;;;               and input-character-stream-p
98;;;;              - Add nickname GS to package "GRAY-STREAMS" for ease of use
99;;;;              - added missing '*' to *old-write-byte* in gray-write-byte
100;;;;
101;;;; 03/01/2002 - 1.2
102;;;;              Fixed bug with GRAY-WRITE-LINE and GRAY-WRITE-STRING
103;;;;              that appeared in Corman Lisp 2.0 due to changes to
104;;;;              WRITE-LINE and WRITE-STRING.
105;;;;
106;;;; 04/01/2002 - 1.3
107;;;;              Added support for STREAM-READ-SEQUENCE and STREAM-WRITE-SEQUENCE.
108;;;;              Fixed STREAM-WRITE-STRING bug.
109;;;;
110;;;; Notes
111;;;; =====
112;;;;
113;;;;
114;;;; Much of the implementation of the Gray streams below is from the
115;;;; document referenced earlier.
116;;;;
117(require "PPRINT")
118
119(defpackage "GRAY-STREAMS"
120  (:use
121   "COMMON-LISP")
122  (:nicknames "GS") ;; # fb 1.01
123  (:export
124   "FUNDAMENTAL-STREAM"
125   "FUNDAMENTAL-OUTPUT-STREAM"
126   "FUNDAMENTAL-INPUT-STREAM"
127   "FUNDAMENTAL-CHARACTER-STREAM"
128   "FUNDAMENTAL-BINARY-STREAM"
129   "STREAM-READ-BYTE"
130   "STREAM-WRITE-BYTE"
131   "FUNDAMENTAL-CHARACTER-INPUT-STREAM"
132   "STREAM-READ-CHAR"
133   "STREAM-UNREAD-CHAR"
134   "STREAM-READ-CHAR-NO-HANG"
135   "STREAM-PEEK-CHAR"
136   "STREAM-LISTEN"
137   "STREAM-READ-LINE"
138   "STREAM-CLEAR-INPUT"
139   "FUNDAMENTAL-CHARACTER-OUTPUT-STREAM"
140   "STREAM-WRITE-CHAR"
141   "STREAM-LINE-COLUMN"
142   "STREAM-LINE-LENGTH"
143   "STREAM-START-LINE-P"
144   "STREAM-WRITE-STRING"
145   "STREAM-TERPRI"
146   "STREAM-FRESH-LINE"
147   "STREAM-FINISH-OUTPUT"
148   "STREAM-FORCE-OUTPUT"
149   "STREAM-CLEAR-OUTPUT"
150   "STREAM-ADVANCE-TO-COLUMN"
151   "STREAM-READ-SEQUENCE"
152   "STREAM-WRITE-SEQUENCE"
153   "STREAM-FILE-POSITION"
154   "STREAM-FILE-LENGTH"
155   "STREAM-FILE-STRING-LENGTH"
156   "STREAM-ELEMENT-TYPE"
157   "FUNDAMENTAL-BINARY-INPUT-STREAM"
158   "FUNDAMENTAL-BINARY-OUTPUT-STREAM"))
159
160(in-package :gray-streams)
161
162(defvar *ansi-read-char* #'read-char)
163(defvar *ansi-peek-char* #'peek-char)
164(defvar *ansi-unread-char* #'unread-char)
165(defvar *ansi-listen* #'listen)
166(defvar *ansi-read-line* #'read-line)
167(defvar *ansi-read-char-no-hang* #'read-char-no-hang)
168(defvar *ansi-write-char* #'write-char)
169(defvar *ansi-fresh-line* #'fresh-line)
170(defvar *ansi-terpri* #'terpri)
171(defvar *ansi-write-string* #'write-string)
172(defvar *ansi-write-line* #'write-line)
173(defvar *sys-%force-output* #'sys::%force-output)
174(defvar *sys-%finish-output* #'sys::%finish-output)
175(defvar *sys-%clear-output* #'sys::%clear-output)
176(defvar *sys-%output-object* #'sys::%output-object)
177(defvar *ansi-clear-input* #'clear-input)
178(defvar *ansi-read-byte* #'read-byte)
179(defvar *ansi-write-byte* #'write-byte)
180(defvar *ansi-stream-element-type* #'cl::stream-element-type)
181(defvar *ansi-stream-external-format* #'cl::stream-external-format)
182(defvar *ansi-close* #'cl::close)
183(defvar *ansi-input-character-stream-p*
184  #'(lambda (s) (and (input-stream-p s) (eql (stream-element-type s) 'character))))
185(defvar *ansi-input-stream-p* #'cl::input-stream-p)
186(defvar *ansi-output-stream-p* #'cl::output-stream-p)
187(defvar *ansi-interactive-stream-p* #'cl::interactive-stream-p)
188(defvar *ansi-open-stream-p* #'cl::open-stream-p)
189(defvar *ansi-streamp* #'cl::streamp)
190(defvar *ansi-read-sequence* #'cl::read-sequence)
191(defvar *ansi-write-sequence* #'cl::write-sequence)
192(defvar *ansi-make-two-way-stream* #'cl:make-two-way-stream)
193(defvar *ansi-two-way-stream-input-stream* #'cl:two-way-stream-input-stream)
194(defvar *ansi-two-way-stream-output-stream* #'cl:two-way-stream-output-stream)
195(defvar *ansi-file-position* #'cl:file-position)
196(defvar *ansi-file-length* #'cl:file-length)
197(defvar *ansi-file-string-length* #'cl:file-string-length)
198(defvar *ansi-pathname* #'cl:pathname)
199(defvar *ansi-truename* #'cl:truename)
200
201(defun ansi-streamp (stream)
202  (typep stream '(or sys::system-stream xp::xp-structure)))
203
204(defclass fundamental-stream (standard-object stream)
205  ((open-p :initform t
206           :accessor stream-open-p))
207  (:documentation "The base class of all Gray streams"))
208
209(defgeneric gray-close (stream &key abort))
210(defgeneric gray-open-stream-p (stream))
211(defgeneric gray-streamp (stream))
212(defgeneric gray-input-stream-p (stream))
213(defgeneric gray-input-character-stream-p (stream)) ;; # fb 1.01
214(defgeneric gray-output-stream-p (stream))
215(defgeneric gray-interactive-stream-p (stream))
216(defgeneric gray-stream-element-type (stream))
217(defgeneric (setf gray-stream-element-type) (new-value stream))
218(defgeneric gray-stream-external-format (stream))
219(defgeneric (setf gray-stream-external-format) (new-value stream))
220(defgeneric gray-pathname (pathspec))
221(defgeneric gray-truename (filespec))
222
223(defun assert-stream (stream)
224  (if (gray-streamp stream)
225      t
226      (error 'type-error :datum stream :expected-type 'stream)))
227
228(defun bug-or-error (stream fun)
229  (assert-stream stream)
230  (error "The stream ~S has no suitable method for ~S." stream fun))
231
232(defmethod gray-close ((stream fundamental-stream) &key abort)
233  (declare (ignore abort))
234  (setf (stream-open-p stream) nil)
235  t)
236
237(defmethod gray-open-stream-p ((stream fundamental-stream))
238  (stream-open-p stream))
239
240(defmethod gray-streamp ((s fundamental-stream))
241  s)
242
243(defmethod gray-stream-external-format ((s fundamental-stream))
244  :default)
245
246(defmethod gray-interactive-stream-p (stream)
247  (declare (ignore stream))
248  nil)
249
250(defclass fundamental-input-stream (fundamental-stream) ())
251
252(defmethod gray-input-character-stream-p (s)  ;; # fb 1.01
253  (and (gray-input-stream-p s)
254       (eq (gray-stream-element-type s) 'character)))
255
256(defmethod gray-input-stream-p ((s fundamental-input-stream))
257  (declare (ignore s))
258  t)
259
260(defclass fundamental-output-stream (fundamental-stream) ())
261
262(defmethod gray-input-stream-p ((s fundamental-output-stream))
263  (typep s 'fundamental-input-stream))
264
265(defmethod gray-output-stream-p ((s fundamental-output-stream))
266  (declare (ignore s))
267  t)
268
269(defmethod gray-output-stream-p ((s fundamental-input-stream))
270  (typep s 'fundamental-output-stream))
271
272(defclass fundamental-character-stream (fundamental-stream) ())
273
274(defmethod gray-stream-element-type ((s fundamental-character-stream))
275  (declare (ignore s))
276  'character)
277
278(defclass fundamental-binary-stream (fundamental-stream) ())
279
280(defgeneric stream-read-byte (stream))
281(defgeneric stream-write-byte (stream integer))
282
283(defclass fundamental-character-input-stream
284  (fundamental-input-stream fundamental-character-stream) ())
285
286(defgeneric stream-read-char (stream))
287(defgeneric stream-unread-char (stream character))
288(defgeneric stream-read-char-no-hang (stream))
289(defgeneric stream-peek-char (stream))
290(defgeneric stream-listen (stream))
291(defgeneric stream-read-line (stream))
292(defgeneric stream-clear-input (stream))
293
294(defmethod stream-read-char-no-hang ((stream fundamental-character-input-stream))
295  (stream-read-char stream))
296
297(defmethod stream-peek-char ((stream fundamental-character-input-stream))
298  (let ((character (stream-read-char stream)))
299    (unless (eq character :eof)
300      (stream-unread-char stream character))
301    character))
302
303(defmethod stream-listen ((stream  fundamental-character-input-stream))
304  (let ((char (stream-read-char-no-hang stream)))
305    (and (not (null char))
306         (not (eq char :eof))
307         (progn
308           (stream-unread-char stream char)
309           t))))
310
311(defmethod stream-read-line ((stream  fundamental-character-input-stream))
312  (let ((line (make-array 64
313                          :element-type 'character
314                          :fill-pointer 0
315                          :adjustable t)))
316    (loop
317      (let ((character (stream-read-char stream)))
318        (if (eq character :eof)
319            (return (values line t))
320            (if (eql character #\Newline)
321                (return (values line nil))
322                (vector-push-extend character line)))))))
323
324(defmethod stream-clear-input (stream)
325  (declare (ignore stream))
326  nil)
327
328(defclass fundamental-character-output-stream
329  (fundamental-output-stream fundamental-character-stream) ())
330
331(defgeneric stream-write-char (stream character))
332(defgeneric stream-line-column (stream))
333(defgeneric stream-start-line-p (stream))
334(defgeneric stream-line-length (stream))
335(defgeneric stream-write-string (stream string &optional start end))
336(defgeneric stream-terpri (stream))
337(defmethod stream-terpri (stream)
338  (stream-write-char stream #\Newline)
339  nil)
340
341(defgeneric stream-fresh-line (stream))
342(defgeneric stream-finish-output (stream))
343(defgeneric stream-force-output (stream))
344(defgeneric stream-clear-output (stream))
345(defgeneric stream-advance-to-column (stream column))
346(defgeneric stream-read-sequence (stream sequence &optional start end))
347(defgeneric stream-write-sequence (stream sequence &optional start end))
348
349(defmethod stream-force-output (stream)
350  (declare (ignore stream))
351  nil)
352
353(defmethod stream-finish-output (stream)
354  (declare (ignore stream))
355  nil)
356
357(defmethod stream-clear-output (stream)
358  (declare (ignore stream))
359  nil)
360
361(defmethod stream-start-line-p ((stream fundamental-character-output-stream))
362  (equal (stream-line-column stream) 0))
363
364(defmethod stream-write-string ((stream fundamental-character-output-stream)
365                                string
366                                &optional (start 0) end)
367  (let ((end (or end (length string))))
368    (do ((i start (1+ i)))
369        ((>= i end) string)
370      (stream-write-char stream (char string i)))))
371
372(defmethod stream-fresh-line ((stream fundamental-character-output-stream))
373  (if (stream-start-line-p stream)
374      nil
375      (progn
376        (stream-terpri stream)
377        t)))
378
379(defmethod stream-advance-to-column ((stream fundamental-character-output-stream)
380                                     column)
381  (let ((current (stream-line-column stream)))
382    (unless (null current)
383      (dotimes (i (- current column) t)
384        (stream-write-char stream #\Space)))))
385
386(defun basic-read-sequence (stream sequence start end
387                            expected-element-type read-fun)
388  (let ((element-type (stream-element-type stream)))
389    (if (subtypep element-type expected-element-type)
390        (dotimes (count (- end start)
391                  ;; If (< end start), skip the dotimes body but
392                  ;; return start
393                  (max start end))
394          (let ((el (funcall read-fun stream)))
395            (when (eq el :eof)
396              (return (+ count start)))
397            (setf (elt sequence (+ count start)) el)))
398        (error "Cannot READ-SEQUENCE on stream of :ELEMENT-TYPE ~A"
399               element-type))))
400
401(defun basic-write-sequence (stream sequence start end
402                             expected-element-type write-fun)
403  (let ((element-type (stream-element-type stream)))
404    (if (subtypep element-type expected-element-type)
405        ;; Avoid LOOP because it isn't loaded yet
406        (do ((n start (+ n 1)))
407            ((= n end))
408          (funcall write-fun stream (elt sequence n)))
409        (error "Cannot WRITE-SEQUENCE on stream of :ELEMENT-TYPE ~A"
410               element-type)))
411  (stream-force-output stream)
412  sequence)
413
414(defmethod stream-read-sequence ((stream  fundamental-character-input-stream)
415                                 sequence &optional (start 0) end)
416  (basic-read-sequence stream sequence start (or end (length sequence))
417                       'character #'stream-read-char))
418
419(defmethod stream-write-sequence ((stream fundamental-character-output-stream)
420                                  sequence &optional (start 0) end)
421  (basic-write-sequence stream sequence start (or end (length sequence))
422                        'character #'stream-write-char))
423
424(defclass fundamental-binary-input-stream
425  (fundamental-input-stream fundamental-binary-stream) ())
426
427(defclass fundamental-binary-output-stream
428  (fundamental-output-stream fundamental-binary-stream) ())
429
430(defmethod stream-read-sequence ((stream fundamental-binary-input-stream)
431                                 sequence &optional (start 0) end)
432  (basic-read-sequence stream sequence start (or end (length sequence))
433                       'signed-byte #'stream-read-byte))
434
435(defmethod stream-write-sequence ((stream fundamental-binary-output-stream)
436                                  sequence &optional (start 0) end)
437  (basic-write-sequence stream sequence start (or end (length sequence))
438                        'signed-byte #'stream-write-byte))
439
440(defmethod stream-line-length (stream)
441  (declare (ignore stream))
442  nil)
443
444(defmethod stream-line-length ((stream xp::xp-structure))
445  (xp::line-length stream))
446
447(defun decode-read-arg (arg)
448  (cond ((null arg) *standard-input*)
449        ((eq arg t) *terminal-io*)
450        (t arg)))
451
452(defun decode-print-arg (arg)
453  (cond ((null arg) *standard-output*)
454        ((eq arg t) *terminal-io*)
455        (t arg)))
456
457(defun report-eof (stream eof-errorp eof-value)
458  (if eof-errorp
459      (error 'end-of-file :stream stream)
460      eof-value))
461
462(defun check-for-eof (value stream eof-errorp eof-value)
463  (if (eq value :eof)
464      (report-eof stream eof-errorp eof-value)
465      value))
466
467(defun gray-read-char (&optional input-stream (eof-errorp t) eof-value recursive-p)
468  (let ((stream (decode-read-arg input-stream)))
469    (if (ansi-streamp stream)
470        (funcall *ansi-read-char* stream eof-errorp eof-value recursive-p)
471        (check-for-eof (stream-read-char stream) stream eof-errorp eof-value))))
472
473(defun gray-peek-char (&optional peek-type input-stream (eof-errorp t)
474                                 eof-value recursive-p)
475  (let ((stream (decode-read-arg input-stream)))
476    (if (ansi-streamp stream)
477        (funcall *ansi-peek-char* peek-type stream eof-errorp eof-value recursive-p)
478        (if (null peek-type)
479            (check-for-eof (stream-peek-char stream) stream eof-errorp eof-value)
480            (loop
481              (let ((value (stream-peek-char stream)))
482                (if (eq value :eof)
483                    (return (report-eof stream eof-errorp eof-value))
484                    (if (if (eq peek-type t)
485                            (not (member value
486                                         '(#\space #\tab #\newline #\return)))
487                            (char= peek-type value))
488                        (return value)
489                        (stream-read-char stream)))))))))
490
491(defun gray-unread-char (character &optional input-stream)
492  (let ((stream (decode-read-arg input-stream)))
493    (if (ansi-streamp stream)
494        (funcall *ansi-unread-char* character stream)
495        (stream-unread-char stream character))))
496
497(defun gray-listen (&optional input-stream)
498  (let ((stream (decode-read-arg input-stream)))
499    (if (ansi-streamp stream)
500        (funcall *ansi-listen* stream)
501        (stream-listen stream))))
502
503(defun gray-read-line (&optional input-stream (eof-error-p t)
504                                 eof-value recursive-p)
505  (let ((stream (decode-read-arg input-stream)))
506    (if (ansi-streamp stream)
507        (funcall *ansi-read-line* stream eof-error-p eof-value recursive-p)
508        (multiple-value-bind (string eofp)
509            (stream-read-line stream)
510          (values (if (and eofp (zerop (length string)))
511                      (report-eof stream eof-error-p eof-value)
512                      string)
513                  eofp)))))
514
515(defun gray-clear-input (&optional input-stream)
516  (let ((stream (decode-read-arg input-stream)))
517    (if (ansi-streamp stream)
518        (funcall *ansi-clear-input* stream)
519        (stream-clear-input stream))))
520
521(defun gray-output-object (object stream)
522  (if (ansi-streamp stream)
523      (funcall *sys-%output-object* object stream)
524      (stream-write-string stream 
525                           (with-output-to-string (s)
526                             (funcall *sys-%output-object* object s)))))
527
528(defun gray-read-char-no-hang (&optional input-stream (eof-errorp t)
529                                         eof-value recursive-p)
530  (let ((stream (decode-read-arg input-stream)))
531    (if (ansi-streamp stream)
532        (funcall *ansi-read-char-no-hang* stream eof-errorp eof-value recursive-p)
533        (check-for-eof (stream-read-char-no-hang stream)
534                       stream eof-errorp eof-value))))
535
536(defun gray-write-char (character &optional output-stream)
537  (let ((stream (decode-print-arg output-stream)))
538    (if (ansi-streamp stream)
539        (funcall *ansi-write-char* character stream)
540        (stream-write-char stream character))))
541
542(defun gray-fresh-line (&optional output-stream)
543  (let ((stream (decode-print-arg output-stream)))
544    (if (ansi-streamp stream)
545        (funcall *ansi-fresh-line* stream)
546        (stream-fresh-line stream))))
547
548(defun gray-terpri (&optional output-stream)
549  (let ((stream (decode-print-arg output-stream)))
550    (if (ansi-streamp stream)
551        (funcall *ansi-terpri* stream)
552        (stream-terpri stream))))
553
554(defun gray-write-string (string &optional output-stream &key (start 0) end)
555  (let ((stream (decode-print-arg output-stream)))
556    (if (ansi-streamp stream)
557        (funcall *ansi-write-string* string stream :start start :end end)
558        (stream-write-string stream string start end))))
559
560(defun gray-write-line (string &optional output-stream &key (start 0) end)
561  (let ((stream (decode-print-arg output-stream)))
562    (if (ansi-streamp stream)
563        (funcall *ansi-write-line* string stream :start start :end end)
564        (progn
565          (stream-write-string stream string start end)
566          (stream-terpri stream)
567          string))))
568
569(defun gray-force-output (&optional output-stream)
570  (let ((stream (decode-print-arg output-stream)))
571    (if (ansi-streamp stream)
572        (funcall *sys-%force-output* stream)
573        (stream-force-output stream))))
574
575(defun gray-finish-output (&optional output-stream)
576  (let ((stream (decode-print-arg output-stream)))
577    (if (ansi-streamp stream)
578        (funcall *sys-%finish-output* stream)
579        (stream-finish-output stream))))
580
581(defun gray-clear-output (&optional output-stream)
582  (let ((stream (decode-print-arg output-stream)))
583    (if (ansi-streamp stream)
584        (funcall *sys-%clear-output* stream)
585        (stream-clear-output stream))))
586
587(defun gray-read-byte (binary-input-stream &optional (eof-errorp t) eof-value)
588  (if (ansi-streamp binary-input-stream)
589      (funcall *ansi-read-byte* binary-input-stream eof-errorp eof-value)
590      (check-for-eof (stream-read-byte binary-input-stream)
591                     binary-input-stream eof-errorp eof-value)))
592
593(defun gray-write-byte (integer binary-output-stream)
594  (if (ansi-streamp binary-output-stream)
595      (funcall *ansi-write-byte* integer binary-output-stream)
596      (stream-write-byte binary-output-stream integer)))
597
598(defmethod stream-line-column ((stream stream))
599  nil)
600
601(defun gray-stream-column (&optional input-stream)
602  (let ((stream (decode-read-arg input-stream)))
603    (if (ansi-streamp stream)
604        nil ;(funcall *ansi-stream-column* stream)
605        (stream-line-column stream))))
606
607(defun gray-line-length (stream)
608  (max 0
609       (or *print-right-margin*
610           (stream-line-length stream)
611           xp::*default-right-margin*
612           80)))
613
614(defmethod gray-stream-element-type (stream)
615  (if (ansi-streamp stream)
616      (funcall *ansi-stream-element-type* stream)
617      (bug-or-error stream 'gray-stream-element-type)))
618
619(defmethod gray-stream-external-format (stream)
620  (if (ansi-streamp stream)
621      (funcall *ansi-stream-external-format* stream)
622      (bug-or-error stream 'gray-stream-external-format)))
623
624(defmethod (setf gray-stream-external-format) (new-value stream)
625  (if (ansi-streamp stream)
626      (sys::%set-stream-external-format stream new-value)
627      (bug-or-error stream 'gray-stream-external-format)))
628
629(defmethod gray-close (stream &key abort)
630  (if (ansi-streamp stream)
631      (funcall *ansi-close* stream :abort abort)
632      (bug-or-error stream 'gray-close)))
633
634(defmethod gray-input-stream-p (stream)
635  (cond ((ansi-streamp stream)
636         (funcall *ansi-input-stream-p* stream))
637        (t
638         (assert-stream stream)
639         nil)))
640
641(defmethod gray-input-character-stream-p (stream)
642  (cond ((ansi-streamp stream)
643         (funcall *ansi-input-character-stream-p* stream))
644        (t
645         (assert-stream stream)
646         nil)))
647
648(defmethod gray-output-stream-p (stream)
649  (cond ((ansi-streamp stream)
650         (funcall *ansi-output-stream-p* stream))
651        (t
652         (assert-stream stream)
653         nil)))
654
655(defmethod gray-interactive-stream-p (stream)
656  (cond ((ansi-streamp stream)
657         (funcall *ansi-interactive-stream-p* stream))
658        (t
659         (assert-stream stream)
660         nil)))
661
662(defmethod gray-open-stream-p (stream)
663  (cond ((ansi-streamp stream)
664         (funcall *ansi-open-stream-p* stream))
665        (t
666         (assert-stream stream)
667         nil)))
668
669(defmethod gray-streamp (stream)
670  (funcall *ansi-streamp* stream))
671
672(defmethod gray-pathname (pathspec)
673  (unless (typep pathspec '(or string pathname stream))
674    (error 'type-error :datum pathspec :expected-type '(or string pathname stream)))
675  (funcall *ansi-pathname* pathspec))
676
677(defmethod gray-truename (pathspec)
678  (unless (typep pathspec '(or string pathname stream))
679    (error 'type-error :datum pathspec :expected-type '(or string pathname stream)))
680  (funcall *ansi-truename* pathspec))
681
682(defun gray-write-sequence (sequence stream &key (start 0) end)
683  (if (ansi-streamp stream)
684      (funcall *ansi-write-sequence* sequence stream :start start :end end)
685      (stream-write-sequence stream sequence start end)))
686
687(defun gray-read-sequence (sequence stream &key (start 0) end)
688  (if (ansi-streamp stream)
689      (funcall *ansi-read-sequence* sequence stream :start start :end end)
690      (stream-read-sequence stream sequence start end)))
691
692(defgeneric stream-file-position (stream &optional position-spec))
693
694(defun gray-file-position (stream &optional position-spec)
695  (if position-spec
696      (if (ansi-streamp stream)
697          (funcall *ansi-file-position* stream position-spec)
698          (stream-file-position stream position-spec))
699      (if (ansi-streamp stream)
700          (funcall *ansi-file-position* stream)
701          (stream-file-position stream))))
702
703(defgeneric stream-file-length (stream)
704  (:method (stream)
705    (error 'type-error
706           :datum stream
707           :expected-type 'file-stream)))
708
709(defun gray-file-length (stream)
710  (if (ansi-streamp stream)
711      (funcall *ansi-file-length* stream)
712      (stream-file-length stream)))
713
714(defgeneric stream-file-string-length (stream object))
715
716(defmethod stream-file-string-length
717    ((stream fundamental-character-output-stream) object)
718  (declare (ignore object))
719  nil)
720
721(defun gray-file-string-length (stream object)
722  (if (ansi-streamp stream)
723      (funcall *ansi-file-string-length* stream object)
724      (stream-file-string-length stream object)))
725
726#|
727(defstruct (two-way-stream-g (:include stream))
728  input-stream output-stream)
729
730(defun gray-make-two-way-stream (in out)
731  (if (and (ansi-streamp in) (ansi-streamp out))
732      (funcall *ansi-make-two-way-stream* in out)
733      (make-two-way-stream-g :input-stream in :output-stream out)))
734
735(defun gray-two-way-stream-input-stream (stream)
736  (if (ansi-streamp stream)
737      (funcall *ansi-two-way-stream-input-stream* stream)
738      (two-way-stream-g-input-stream stream)))
739
740(defun gray-two-way-stream-output-stream (stream)
741  (if (ansi-streamp stream)
742      (funcall *ansi-two-way-stream-output-stream* stream)
743      (two-way-stream-g-output-stream stream)))
744
745|#
746
747(setf (symbol-function 'common-lisp::read-char) #'gray-read-char)
748(setf (symbol-function 'common-lisp::peek-char) #'gray-peek-char)
749(setf (symbol-function 'common-lisp::unread-char) #'gray-unread-char)
750(setf (symbol-function 'common-lisp::read-line) #'gray-read-line)
751(setf (symbol-function 'common-lisp::clear-input) #'gray-clear-input)
752(setf (symbol-function 'common-lisp::read-char-no-hang) #'gray-read-char-no-hang)
753(setf (symbol-function 'common-lisp::write-char) #'gray-write-char)
754(setf (symbol-function 'common-lisp::fresh-line) #'gray-fresh-line)
755(setf (symbol-function 'common-lisp::terpri) #'gray-terpri)
756(setf (symbol-function 'common-lisp::write-string) #'gray-write-string)
757(setf (symbol-function 'common-lisp::write-line) #'gray-write-line)
758(setf (symbol-function 'sys::%force-output) #'gray-force-output)
759(setf (symbol-function 'sys::%finish-output) #'gray-finish-output)
760(setf (symbol-function 'sys::%clear-output) #'gray-clear-output)
761(setf (symbol-function 'sys::%output-object) #'gray-output-object)
762(setf (symbol-function 'common-lisp::read-byte) #'gray-read-byte)
763(setf (symbol-function 'common-lisp::write-byte) #'gray-write-byte)
764(setf (symbol-function 'common-lisp::stream-column) #'gray-stream-column)
765(setf (symbol-function 'common-lisp::stream-element-type) #'gray-stream-element-type)
766(setf (fdefinition '(setf common-lisp::stream-element-type)) #'(setf gray-stream-element-type))
767(setf (symbol-function 'common-lisp::stream-external-format) #'gray-stream-external-format)
768(setf (fdefinition '(setf common-lisp::stream-external-format)) #'(setf gray-stream-external-format))
769(setf (symbol-function 'common-lisp::close) #'gray-close)
770(setf (symbol-function 'common-lisp::input-stream-p) #'gray-input-stream-p)
771(setf (symbol-function 'common-lisp::input-character-stream-p) #'gray-input-character-stream-p)  ;; # fb 1.01
772(setf (symbol-function 'common-lisp::output-stream-p) #'gray-output-stream-p)
773(setf (symbol-function 'common-lisp::interactive-stream-p) #'gray-interactive-stream-p)
774(setf (symbol-function 'common-lisp::open-stream-p) #'gray-open-stream-p)
775(setf (symbol-function 'common-lisp::streamp) #'gray-streamp)
776(setf (symbol-function 'common-lisp::read-sequence) #'gray-read-sequence)
777(setf (symbol-function 'common-lisp::write-sequence) #'gray-write-sequence)
778(setf (symbol-function 'common-lisp::file-position) #'gray-file-position)
779(setf (symbol-function 'common-lisp::file-length) #'gray-file-length)
780(setf (symbol-function 'common-lisp::file-string-length) #'gray-file-string-length)
781(setf (symbol-function 'common-lisp::listen) #'gray-listen)
782(setf (symbol-function 'ext:line-length) #'gray-line-length)
783(setf (symbol-function 'common-lisp::pathname) #'gray-pathname)
784(setf (symbol-function 'common-lisp::truename) #'gray-truename)
785
786(dolist (e '((common-lisp::read-char gray-read-char)
787             (common-lisp::peek-char gray-peek-char)
788             (common-lisp::unread-char gray-unread-char)
789             (common-lisp::read-line gray-read-line)
790             (common-lisp::clear-input gray-clear-input)
791             (common-lisp::read-char-no-hang gray-read-char-no-hang)
792             (common-lisp::write-char gray-write-char)
793             (common-lisp::fresh-line gray-fresh-line)
794             (common-lisp::terpri gray-terpri)
795             (common-lisp::write-string gray-write-string)
796             (common-lisp::write-line gray-write-line)
797             (sys::%force-output gray-force-output)
798             (sys::%finish-output gray-finish-output)
799             (sys::%clear-output gray-clear-output)
800             (sys::%output-object gray-output-object)
801             (common-lisp::read-byte gray-read-byte)
802             (common-lisp::write-byte gray-write-byte)
803             (common-lisp::stream-column gray-stream-column)
804             (common-lisp::stream-element-type gray-stream-element-type)
805             (common-lisp::stream-external-format gray-stream-external-format)
806             (common-lisp::close gray-close)
807             (common-lisp::input-stream-p gray-input-stream-p)
808             (common-lisp::input-character-stream-p gray-input-character-stream-p) ;; # fb 1.01
809             (common-lisp::output-stream-p gray-output-stream-p)
810             (common-lisp::open-stream-p gray-open-stream-p)
811             (common-lisp::streamp gray-streamp)
812             (common-lisp::read-sequence gray-read-sequence)
813             (common-lisp::write-sequence gray-write-sequence)
814             (common-lisp::file-position gray-file-position)
815             (common-lisp::file-length gray-file-length)
816             (common-lisp::file-string-length gray-file-string-length)
817             (common-lisp::listen gray-listen)
818             (common-lisp::pathname gray-pathname)
819             (common-lisp::truename gray-truename)))
820  (sys::put (car e) 'sys::source (cl:get (second e) 'sys::source)))
821
822#|
823(setf (symbol-function 'common-lisp::make-two-way-stream) #'gray-make-two-way-stream)
824(setf (symbol-function 'common-lisp::two-way-stream-input-stream) #'gray-two-way-stream-input-stream)
825(setf (symbol-function 'common-lisp::two-way-stream-output-stream) #'gray-two-way-stream-output-stream)
826|#
827
828(eval-when (:load-toplevel)
829  (mapcar (lambda (o) (mop:finalize-inheritance (find-class o)))
830          '(fundamental-stream 
831            fundamental-input-stream fundamental-output-stream
832            fundamental-character-stream 
833            fundamental-character-input-stream fundamental-character-output-stream
834            fundamental-binary-stream
835            fundamental-binary-input-stream fundamental-binary-output-stream)))
836 
837(provide 'gray-streams)
838
839;;; Fixup Gray/ANSI stream relations
840
841(defparameter *sys--stream-charpos* #'sys::stream-charpos)
842(defun sys::stream-charpos (stream)
843  (cond         
844    ((subtypep (type-of stream) 'gray-streams:fundamental-stream)
845     (stream-line-column stream))
846    ((streamp stream)
847     (funcall *sys--stream-charpos* stream))))
848
849(defparameter *sys--stream-%set-charpos* #'sys::stream-%set-charpos)
850(defun sys::stream-%set-charpos (new-value stream)
851  (cond 
852    ((subtypep (type-of stream) 'gray-streams:fundamental-stream)
853     (setf (stream-line-column stream) new-value))
854    ((streamp stream)
855     (funcall *sys--stream-%set-charpos* stream new-value))))
Note: See TracBrowser for help on using the repository browser.