/[cmucl]/src/code/stream.lisp
ViewVC logotype

Diff of /src/code/stream.lisp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.89.4.1 by rtoy, Thu Feb 25 20:34:52 2010 UTC revision 1.102 by rtoy, Wed Jun 29 00:55:04 2011 UTC
# Line 55  Line 55 
55  ;;; The initialization of these streams is performed by Stream-Init,  ;;; The initialization of these streams is performed by Stream-Init,
56  ;;; which lives in the file of machine-specific stream functions.  ;;; which lives in the file of machine-specific stream functions.
57  ;;;  ;;;
58  (defvar *terminal-io* () _N"Terminal I/O stream.")  (defvar *terminal-io* () "Terminal I/O stream.")
59  (defvar *standard-input* () _N"Default input stream.")  (defvar *standard-input* () "Default input stream.")
60  (defvar *standard-output* () _N"Default output stream.")  (defvar *standard-output* () "Default output stream.")
61  (defvar *error-output* () _N"Error output stream.")  (defvar *error-output* () "Error output stream.")
62  (defvar *query-io* () _N"Query I/O stream.")  (defvar *query-io* () "Query I/O stream.")
63  (defvar *trace-output* () _N"Trace output stream.")  (defvar *trace-output* () "Trace output stream.")
64  (defvar *debug-io* () _N"Interactive debugging stream.")  (defvar *debug-io* () "Interactive debugging stream.")
65    
66  (defun ill-in-any (stream &rest ignore)  (defun ill-in-any (stream &rest ignore)
67    (declare (ignore ignore))    (declare (ignore ignore))
68    (error 'simple-type-error    (error 'simple-type-error
69           :datum stream           :datum stream
70           :expected-type '(satisfies input-stream-p)           :expected-type '(satisfies input-stream-p)
71           :format-control _"~S is not an input stream."           :format-control (intl:gettext "~S is not an input stream.")
72           :format-arguments (list stream)))           :format-arguments (list stream)))
73  (defun ill-out-any (stream &rest ignore)  (defun ill-out-any (stream &rest ignore)
74    (declare (ignore ignore))    (declare (ignore ignore))
75    (error 'simple-type-error    (error 'simple-type-error
76           :datum stream           :datum stream
77           :expected-type '(satisfies output-stream-p)           :expected-type '(satisfies output-stream-p)
78           :format-control _"~S is not an output stream."           :format-control (intl:gettext "~S is not an output stream.")
79           :format-arguments (list stream)))           :format-arguments (list stream)))
80  (defun ill-in (stream &rest ignore)  (defun ill-in (stream &rest ignore)
81    (declare (ignore ignore))    (declare (ignore ignore))
82    (error 'simple-type-error    (error 'simple-type-error
83           :datum stream           :datum stream
84           :expected-type '(satisfies input-stream-p)           :expected-type '(satisfies input-stream-p)
85           :format-control _"~S is not a character input stream."           :format-control (intl:gettext "~S is not a character input stream.")
86           :format-arguments (list stream)))           :format-arguments (list stream)))
87  (defun ill-out (stream &rest ignore)  (defun ill-out (stream &rest ignore)
88    (declare (ignore ignore))    (declare (ignore ignore))
89    (error 'simple-type-error    (error 'simple-type-error
90           :datum stream           :datum stream
91           :expected-type '(satisfies output-stream-p)           :expected-type '(satisfies output-stream-p)
92           :format-control _"~S is not a character output stream."           :format-control (intl:gettext "~S is not a character output stream.")
93           :format-arguments (list stream)))           :format-arguments (list stream)))
94  (defun ill-bin (stream &rest ignore)  (defun ill-bin (stream &rest ignore)
95    (declare (ignore ignore))    (declare (ignore ignore))
96    (error 'simple-type-error    (error 'simple-type-error
97           :datum stream           :datum stream
98           :expected-type '(satisfies input-stream-p)           :expected-type '(satisfies input-stream-p)
99           :format-control _"~S is not a binary input stream."           :format-control (intl:gettext "~S is not a binary input stream.")
100           :format-arguments (list stream)))           :format-arguments (list stream)))
101  (defun ill-n-bin (stream &rest ignore)  (defun ill-n-bin (stream &rest ignore)
102    (declare (ignore ignore))    (declare (ignore ignore))
103    (error 'simple-type-error    (error 'simple-type-error
104           :datum stream           :datum stream
105           :expected-type '(satisfies input-stream-p)           :expected-type '(satisfies input-stream-p)
106           :format-control _"~S is not a binary input stream ~           :format-control (intl:gettext "~S is not a binary input stream ~
107                            or does not support multi-byte read operations."                            or does not support multi-byte read operations.")
108           :format-arguments (list stream)))           :format-arguments (list stream)))
109  (defun ill-bout (stream &rest ignore)  (defun ill-bout (stream &rest ignore)
110    (declare (ignore ignore))    (declare (ignore ignore))
111    (error 'simple-type-error    (error 'simple-type-error
112           :datum stream           :datum stream
113           :expected-type '(satisfies output-stream-p)           :expected-type '(satisfies output-stream-p)
114           :format-control _"~S is not a binary output stream."           :format-control (intl:gettext "~S is not a binary output stream.")
115           :format-arguments (list stream)))           :format-arguments (list stream)))
116  (defun closed-flame (stream &rest ignore)  (defun closed-flame (stream &rest ignore)
117    (declare (ignore ignore))    (declare (ignore ignore))
118    (error _"~S is closed." stream))    (error (intl:gettext "~S is closed.") stream))
119  (defun do-nothing (&rest ignore)  (defun do-nothing (&rest ignore)
120    (declare (ignore ignore)))    (declare (ignore ignore)))
121  (defun no-gray-streams (stream)  (defun no-gray-streams (stream)
122    (error 'simple-type-error    (error 'simple-type-error
123           :datum stream           :datum stream
124           :expected-type 'stream           :expected-type 'stream
125           :format-control _"~S is an unsupported Gray stream."           :format-control (intl:gettext "~S is an unsupported Gray stream.")
126           :format-arguments (list stream)))           :format-arguments (list stream)))
127    
128  (defun %print-stream (structure stream d)  (defun %print-stream (structure stream d)
# Line 207  Line 207 
207  ;;; Stream manipulation functions.  ;;; Stream manipulation functions.
208    
209  (defun input-stream-p (stream)  (defun input-stream-p (stream)
210    _N"Returns non-nil if the given Stream can perform input operations."    "Returns non-nil if the given Stream can perform input operations."
211    (declare (type stream stream))    (declare (type stream stream))
212    ;; Note: Gray streams redefines this function; any changes made here need    ;; Note: Gray streams redefines this function; any changes made here need
213    ;; to be duplicated in .../pcl/gray-streams.lisp    ;; to be duplicated in .../pcl/gray-streams.lisp
# Line 224  Line 224 
224                 (not (eq (lisp-stream-n-bin stream) #'ill-n-bin)))))))                 (not (eq (lisp-stream-n-bin stream) #'ill-n-bin)))))))
225    
226  (defun output-stream-p (stream)  (defun output-stream-p (stream)
227    _N"Returns non-nil if the given Stream can perform output operations."    "Returns non-nil if the given Stream can perform output operations."
228    (declare (type stream stream))    (declare (type stream stream))
229    ;; Note: Gray streams redefines this function; any changes made here need    ;; Note: Gray streams redefines this function; any changes made here need
230    ;; to be duplicated in .../pcl/gray-streams.lisp    ;; to be duplicated in .../pcl/gray-streams.lisp
# Line 240  Line 240 
240                 (not (eq (lisp-stream-bout stream) #'ill-bout)))))))                 (not (eq (lisp-stream-bout stream) #'ill-bout)))))))
241    
242  (defun open-stream-p (stream)  (defun open-stream-p (stream)
243    _N"Return true if Stream is not closed."    "Return true if Stream is not closed."
244    (declare (type stream stream))    (declare (type stream stream))
245    ;; Note: Gray streams redefines this function; any changes made here need    ;; Note: Gray streams redefines this function; any changes made here need
246    ;; to be duplicated in .../pcl/gray-streams.lisp    ;; to be duplicated in .../pcl/gray-streams.lisp
# Line 251  Line 251 
251      (not (eq (lisp-stream-in stream) #'closed-flame))))      (not (eq (lisp-stream-in stream) #'closed-flame))))
252    
253  (defun stream-element-type (stream)  (defun stream-element-type (stream)
254    _N"Returns a type specifier for the kind of object returned by the Stream."    "Returns a type specifier for the kind of object returned by the Stream."
255    (declare (type stream stream))    (declare (type stream stream))
256    ;; Note: Gray streams redefines this function; any changes made here need    ;; Note: Gray streams redefines this function; any changes made here need
257    ;; to be duplicated in .../pcl/gray-streams.lisp    ;; to be duplicated in .../pcl/gray-streams.lisp
# Line 262  Line 262 
262      (funcall (lisp-stream-misc stream) stream :element-type)))      (funcall (lisp-stream-misc stream) stream :element-type)))
263    
264  (defun interactive-stream-p (stream)  (defun interactive-stream-p (stream)
265    _N"Return true if Stream does I/O on a terminal or other interactive device."    "Return true if Stream does I/O on a terminal or other interactive device."
266    (declare (type stream stream))    (declare (type stream stream))
267    (stream-dispatch stream    (stream-dispatch stream
268      ;; simple-stream      ;; simple-stream
# Line 281  Line 281 
281      (error 'simple-type-error      (error 'simple-type-error
282             :datum stream             :datum stream
283             :expected-type 'stream:simple-stream             :expected-type 'stream:simple-stream
284             :format-control _"Can't set interactive flag on ~S."             :format-control (intl:gettext "Can't set interactive flag on ~S.")
285             :format-arguments (list stream))))             :format-arguments (list stream))))
286    
287  (defun stream-external-format (stream)  (defun stream-external-format (stream)
288    _N"Returns the external format used by the given Stream."    "Returns the external format used by the given Stream."
289    (declare (type stream stream))    (declare (type stream stream))
290    (stream-dispatch stream    (stream-dispatch stream
291      ;; simple-stream      ;; simple-stream
# Line 314  Line 314 
314    extfmt)    extfmt)
315    
316  (defun close (stream &key abort)  (defun close (stream &key abort)
317    _N"Closes the given Stream.  No more I/O may be performed, but inquiries    "Closes the given Stream.  No more I/O may be performed, but inquiries
318    may still be made.  If :Abort is non-nil, an attempt is made to clean    may still be made.  If :Abort is non-nil, an attempt is made to clean
319    up the side effects of having created the stream."    up the side effects of having created the stream."
320    (declare (type stream stream))    (declare (type stream stream))
# Line 347  Line 347 
347  ;;;    Call the misc method with the :file-position operation.  ;;;    Call the misc method with the :file-position operation.
348  ;;;  ;;;
349  (defun file-position (stream &optional position)  (defun file-position (stream &optional position)
350    _N"With one argument returns the current position within the file    "With one argument returns the current position within the file
351     File-Stream is open to.  If the second argument is supplied, then     File-Stream is open to.  If the second argument is supplied, then
352     this becomes the new file position.  The second argument may also     this becomes the new file position.  The second argument may also
353     be :start or :end for the start and end of the file, respectively."     be :start or :end for the start and end of the file, respectively."
# Line 364  Line 364 
364        (t        (t
365         (let ((res (funcall (lisp-stream-misc stream) stream         (let ((res (funcall (lisp-stream-misc stream) stream
366                             :file-position nil)))                             :file-position nil)))
367             ;; For Unicode, the LISP-STREAM-MISC function handles
368             ;; everything, so we can just return the result.
369             #-unicode
370           (when res           (when res
371             (- res (- in-buffer-length (lisp-stream-in-index stream)))))))))             (- res (- in-buffer-length (lisp-stream-in-index stream))))
372             #+unicode
373             res)))))
374    
375    
376  ;;; File-Length  --  Public  ;;; File-Length  --  Public
# Line 373  Line 378 
378  ;;;    Like File-Position, only use :file-length.  ;;;    Like File-Position, only use :file-length.
379  ;;;  ;;;
380  (defun file-length (stream)  (defun file-length (stream)
381    _N"This function returns the length of the file that File-Stream is open to."    "This function returns the length of the file that File-Stream is open to."
382    (stream-dispatch stream    (stream-dispatch stream
383      ;; simple-stream      ;; simple-stream
384      (stream::%file-length stream)      (stream::%file-length stream)
# Line 385  Line 390 
390    
391  (defun read-line (&optional (stream *standard-input*) (eof-errorp t) eof-value  (defun read-line (&optional (stream *standard-input*) (eof-errorp t) eof-value
392                              recursive-p)                              recursive-p)
393    _N"Returns a line of text read from the Stream as a string, discarding the    "Returns a line of text read from the Stream as a string, discarding the
394    newline character."    newline character."
395    (let ((stream (in-synonym-of stream)))    (let ((stream (in-synonym-of stream)))
396      (stream-dispatch stream      (stream-dispatch stream
# Line 431  Line 436 
436  (declaim (inline read-char unread-char read-byte listen))  (declaim (inline read-char unread-char read-byte listen))
437  (defun read-char (&optional (stream *standard-input*) (eof-errorp t) eof-value  (defun read-char (&optional (stream *standard-input*) (eof-errorp t) eof-value
438                              recursive-p)                              recursive-p)
439    _N"Inputs a character from Stream and returns it."    "Inputs a character from Stream and returns it."
440    (let ((stream (in-synonym-of stream)))    (let ((stream (in-synonym-of stream)))
441      (stream-dispatch stream      (stream-dispatch stream
442        ;; simple-stream        ;; simple-stream
# Line 448  Line 453 
453              char)))))              char)))))
454    
455  (defun unread-char (character &optional (stream *standard-input*))  (defun unread-char (character &optional (stream *standard-input*))
456    _N"Puts the Character back on the front of the input Stream."    "Puts the Character back on the front of the input Stream."
457    (let ((stream (in-synonym-of stream)))    (let ((stream (in-synonym-of stream)))
458      (stream-dispatch stream      (stream-dispatch stream
459        ;; simple-stream        ;; simple-stream
# Line 458  Line 463 
463        (let ((index (1- (lisp-stream-in-index stream)))        (let ((index (1- (lisp-stream-in-index stream)))
464              (buffer (lisp-stream-in-buffer stream)))              (buffer (lisp-stream-in-buffer stream)))
465          (declare (fixnum index))          (declare (fixnum index))
466          (when (minusp index) (error _"Nothing to unread."))          (when (minusp index) (error (intl:gettext "Nothing to unread.")))
467          (cond (buffer          (cond (buffer
468                 (setf (aref buffer index) (char-code character))                 (setf (aref buffer index) (char-code character))
469                 (setf (lisp-stream-in-index stream) index))                 (setf (lisp-stream-in-index stream) index))
# Line 471  Line 476 
476          (cond (sbuf          (cond (sbuf
477                 (let ((index (1- (lisp-stream-string-index stream))))                 (let ((index (1- (lisp-stream-string-index stream))))
478                   (when (minusp index)                   (when (minusp index)
479                     (error _"Nothing to unread."))                     (error (intl:gettext "Nothing to unread.")))
480                   (setf (aref sbuf index) character)                   (setf (aref sbuf index) character)
481                   (setf (lisp-stream-string-index stream) index)))                   (setf (lisp-stream-string-index stream) index)))
482                (ibuf                (ibuf
483                 (let ((index (1- (lisp-stream-in-index stream))))                 (let ((index (1- (lisp-stream-in-index stream))))
484                   (when (minusp index)                   (when (minusp index)
485                     (error _"Nothing to unread."))                     (error (intl:gettext "Nothing to unread.")))
486                   ;; This only works for iso8859-1!                   ;; This only works for iso8859-1!
487                   (setf (aref ibuf index) (char-code character))                   (setf (aref ibuf index) (char-code character))
488                   (setf (lisp-stream-in-index stream) index)))                   (setf (lisp-stream-in-index stream) index)))
# Line 541  Line 546 
546                    eof-detected-form))                    eof-detected-form))
547             ,char-var)             ,char-var)
548            (t            (t
549             (error _"Impossible case reached in PEEK-CHAR")))))             (error (intl:gettext "Impossible case reached in PEEK-CHAR"))))))
550    
551  (defun peek-char (&optional (peek-type nil) (stream *standard-input*)  (defun peek-char (&optional (peek-type nil) (stream *standard-input*)
552                              (eof-errorp t) eof-value recursive-p)                              (eof-errorp t) eof-value recursive-p)
553    _N"Peeks at the next character in the input Stream.  See manual for details."    "Peeks at the next character in the input Stream.  See manual for details."
554    ;; FIXME: The type of PEEK-TYPE is also declared in a DEFKNOWN, but    ;; FIXME: The type of PEEK-TYPE is also declared in a DEFKNOWN, but
555    ;; the compiler doesn't seem to be smart enough to go from there to    ;; the compiler doesn't seem to be smart enough to go from there to
556    ;; imposing a type check. Figure out why (because PEEK-TYPE is an    ;; imposing a type check. Figure out why (because PEEK-TYPE is an
# Line 555  Line 560 
560      (error 'simple-type-error      (error 'simple-type-error
561             :datum peek-type             :datum peek-type
562             :expected-type '(or character boolean)             :expected-type '(or character boolean)
563             :format-control _"~@<bad PEEK-TYPE=~S, ~_expected ~S~:>"             :format-control (intl:gettext "~@<bad PEEK-TYPE=~S, ~_expected ~S~:>")
564             :format-arguments (list peek-type '(or character boolean))))             :format-arguments (list peek-type '(or character boolean))))
565    (let ((stream (in-synonym-of stream)))    (let ((stream (in-synonym-of stream)))
566      (if (typep stream 'echo-stream)      (if (typep stream 'echo-stream)
# Line 586  Line 591 
591             :eof-detected-form (eof-or-lose stream eof-errorp eof-value))))))             :eof-detected-form (eof-or-lose stream eof-errorp eof-value))))))
592    
593  (defun listen (&optional (stream *standard-input*) (width 1))  (defun listen (&optional (stream *standard-input*) (width 1))
594    _N"Returns T if a character is available on the given Stream."    "Returns T if a character is available on the given Stream."
595    (declare (type streamlike stream))    (declare (type streamlike stream))
596    (let ((stream (in-synonym-of stream)))    (let ((stream (in-synonym-of stream)))
597      (stream-dispatch stream      (stream-dispatch stream
# Line 601  Line 606 
606    
607  (defun read-char-no-hang (&optional (stream *standard-input*)  (defun read-char-no-hang (&optional (stream *standard-input*)
608                                      (eof-errorp t) eof-value recursive-p)                                      (eof-errorp t) eof-value recursive-p)
609    _N"Returns the next character from the Stream if one is available, or nil."    "Returns the next character from the Stream if one is available, or nil."
610    (let ((stream (in-synonym-of stream)))    (let ((stream (in-synonym-of stream)))
611      (stream-dispatch stream      (stream-dispatch stream
612        ;; simple-stream        ;; simple-stream
# Line 619  Line 624 
624    
625    
626  (defun clear-input (&optional (stream *standard-input*) buffer-only)  (defun clear-input (&optional (stream *standard-input*) buffer-only)
627    _N"Clears any buffered input associated with the Stream."    "Clears any buffered input associated with the Stream."
628    (declare (type streamlike stream))    (declare (type streamlike stream))
629    (let ((stream (in-synonym-of stream)))    (let ((stream (in-synonym-of stream)))
630      (stream-dispatch stream      (stream-dispatch stream
# Line 634  Line 639 
639    nil)    nil)
640    
641  (defun read-byte (stream &optional (eof-errorp t) eof-value)  (defun read-byte (stream &optional (eof-errorp t) eof-value)
642    _N"Returns the next byte of the Stream."    "Returns the next byte of the Stream."
643    (declare (type stream stream))    (declare (type stream stream))
644    (let ((stream (in-synonym-of stream)))    (let ((stream (in-synonym-of stream)))
645      (stream-dispatch stream      (stream-dispatch stream
# Line 652  Line 657 
657              char)))))              char)))))
658    
659  (defun read-n-bytes (stream buffer start numbytes &optional (eof-errorp t))  (defun read-n-bytes (stream buffer start numbytes &optional (eof-errorp t))
660    _N"Reads Numbytes bytes into the Buffer starting at Start, returning the number    "Reads Numbytes bytes into the Buffer starting at Start, returning the number
661     of bytes read.     of bytes read.
662     -- If EOF-ERROR-P is true, an END-OF-FILE condition is signalled if     -- If EOF-ERROR-P is true, an END-OF-FILE condition is signalled if
663        end-of-file is encountered before Count bytes have been read.        end-of-file is encountered before Count bytes have been read.
# Line 718  Line 723 
723             (setf (lisp-stream-in-index stream) (1+ start))             (setf (lisp-stream-in-index stream) (1+ start))
724             (code-char (aref ibuf start))))))             (code-char (aref ibuf start))))))
725    
726    ;;; FAST-READ-CHAR-STRING-REFILL  --  Interface
727    ;;;
728    ;;;    This function is called by the fast-read-char expansion to refill the
729    ;;; string-buffer for text streams.  There is definitely a
730    ;;; string-buffer and an in-buffer, which implies there must be an
731    ;;; n-bin method.
732    ;;;
733  #+unicode  #+unicode
734  (defun fast-read-char-string-refill (stream eof-errorp eof-value)  (defun fast-read-char-string-refill (stream eof-errorp eof-value)
735    ;; Like fast-read-char-refill, but we don't need or want the    ;; Like fast-read-char-refill, but we don't need or want the
736    ;; in-buffer-extra.    ;; in-buffer-extra.
737    (let* ((ibuf (lisp-stream-in-buffer stream))    (let* ((ibuf (lisp-stream-in-buffer stream))
738           (index (lisp-stream-in-index stream)))           (index (lisp-stream-in-index stream))
739      (declare (type (integer 0 #.in-buffer-length) index))           (in-length (fd-stream-in-length stream)))
740        (declare (type (integer 0 #.in-buffer-length) index in-length))
741    
742        #+(or debug-frc-sr)
743        (progn
744          (format t "index = ~A~%" index)
745          (format t "in-length = ~A~%" in-length)
746          (format t "ibuf before = ~A~%" ibuf)
747          (format t "sbuf before = ~S~%" (subseq (lisp-stream-string-buffer stream) 0
748                                                 (lisp-stream-string-buffer-len stream))))
749    
750        ;; For debugging, clear out the stuff we've already read so we can
751        ;; see what's happening.
752        #+(or debug-frc-sr)
753        (fill ibuf 0 :start 0 :end index)
754    
755      ;; Copy the stuff we haven't read from in-buffer to the beginning      ;; Copy the stuff we haven't read from in-buffer to the beginning
756      ;; of the buffer.      ;; of the buffer.
757      (replace ibuf ibuf      (if (< index in-length)
758               :start1 0          (replace ibuf ibuf
759               :start2 index :end2 in-buffer-length)                   :start1 0
760                     :start2 index :end2 in-length)
761            (setf index in-length))
762    
763        ;; For debugging, clear out the stuff we've already read so we can
764        ;; see what's happening.
765        #+(or debug-frc-sr)
766        (when (< index (1- in-buffer-length))
767          (fill ibuf 0 :start (1+ index) :end in-buffer-length))
768    
769      (let ((count (funcall (lisp-stream-n-bin stream) stream      (setf index (- in-length index))
770                            ibuf (- in-buffer-length index)  
771                            index      #+(or debug-frc-sr)
772                            nil)))      (format t "ibuf after  = ~A~%" ibuf)
773        (declare (type (integer 0 #.in-buffer-length) count))  
774        (flet
775        (cond ((zerop count)          ((get-octets (start)
776               ;; Nothing left in the stream, so update our pointers to             (funcall (lisp-stream-n-bin stream) stream
777               ;; indicate we've read everything and call the stream-in                      ibuf start
778               ;; function so that we do the right thing for eof.                      (- in-buffer-length start)
779               (setf (lisp-stream-in-index stream) in-buffer-length)                      nil))
780               (setf (lisp-stream-string-index stream)           (handle-eof ()
781                     (lisp-stream-string-buffer-len stream))             ;; Nothing left in the stream, so update our pointers to
782               (funcall (lisp-stream-in stream) stream eof-errorp eof-value))             ;; indicate we've read everything and call the stream-in
783              (t             ;; function so that we do the right thing for eof.
784               (let ((sbuf (lisp-stream-string-buffer stream))             (setf (lisp-stream-in-index stream) in-buffer-length)
785                     (slen (lisp-stream-string-buffer-len stream)))             (setf (lisp-stream-string-index stream)
786                 (declare (simple-string sbuf)                   (lisp-stream-string-buffer-len stream))
787                          (type (integer 0 #.(1+ in-buffer-length)) slen)             (funcall (lisp-stream-in stream) stream eof-errorp eof-value)))
788                          (optimize (speed 3)))        (let ((count (get-octets index)))
789            (declare (type (integer 0 #.in-buffer-length) count))
790                 ;; Update in-length and saved-oc-state.  These are  
791                 ;; needed if we change the external-format of the          #+(or debug-frc-sr)
792                 ;; stream because we need to know how many octets are          (progn
793                 ;; valid (in case end-of-file was reached), and what            (format t "count = ~D~%" count)
794                 ;; the state was when originally converting the octets            (format t "new ibuf = ~A~%" ibuf))
795                 ;; to characters.  
796                 (setf (fd-stream-in-length stream) (+ count (- in-buffer-length index)))          (cond ((zerop count)
797                 (let ((state (fd-stream-oc-state stream)))                 (handle-eof))
798                   (setf (fd-stream-saved-oc-state stream)                (t
799                         (cons (car state)                 (let ((sbuf (lisp-stream-string-buffer stream))
800                               (funcall (ef-copy-state (fd-stream-external-format stream))                       (slen (lisp-stream-string-buffer-len stream)))
801                                        (cdr state)))))                   (declare (simple-string sbuf)
802                              (type (integer 0 #.(1+ in-buffer-length)) slen)
803                 ;; Copy the last read character to the beginning of the                            (optimize (speed 3)))
804                 ;; buffer to support unreading.  
805                 (when (plusp slen)                   ;; Update in-length.  This is needed if we change the
806                   (setf (schar sbuf 0) (schar sbuf (1- slen))))                   ;; external-format of the stream because we need to
807                     ;; know how many octets are valid (in case
808                     ;; end-of-file was reached)
809                 ;; Convert all the octets, including the ones that we                   (setf (fd-stream-in-length stream) (+ count index))
810                 ;; haven't processed yet and the ones we just read in.                   #+(or debug-frc-sr)
811                 (multiple-value-bind (s char-count octet-count new-state)                   (format t "in-length = ~D~%" (fd-stream-in-length stream))
812                     (octets-to-string ibuf  
813                                       :start 0                   #+(or debug-frc-sr)
814                                       :end (+ count (- in-buffer-length index))                   (format t "slen = ~A~%" slen)
815                                       :state (fd-stream-oc-state stream)  
816                                       :string sbuf                   ;; Copy the last read character to the beginning of the
817                                       :s-start 1                   ;; buffer to support unreading.
818                                       :external-format (fd-stream-external-format stream))                   (when (plusp slen)
819                   (declare (ignore s))                     (setf (schar sbuf 0) (schar sbuf (1- slen))))
820                   (setf (fd-stream-oc-state stream) new-state)  
821                   (setf (lisp-stream-string-buffer-len stream) char-count)                   #+(or debug-frc-sr)
822                   (setf (lisp-stream-string-index stream) 2)                   (progn
823                   (setf (lisp-stream-in-index stream) octet-count)                     (format t "sbuf[0] = ~S~%" (schar sbuf 0))
824                   (schar sbuf 1))))))))                     (format t "index = ~S~%" index))
825    
826    
827                     ;; Convert all the octets, including the ones that we
828                     ;; haven't processed yet and the ones we just read in.
829                     (flet
830                         ((convert-buffer ()
831                            (multiple-value-bind (s char-count octet-count new-state)
832                                (stream::octets-to-string-counted
833                                 ibuf
834                                 (fd-stream-octet-count stream)
835                                 :start 0
836                                 :end (fd-stream-in-length stream)
837                                 :state (fd-stream-oc-state stream)
838                                 :string sbuf
839                                 :s-start 1
840                                 :external-format (fd-stream-external-format stream)
841                                 :error (fd-stream-octets-to-char-error stream))
842                              (declare (ignore s)
843                                       (type (integer 0 #.in-buffer-length) char-count octet-count))
844                              #+(or debug-frc-sr)
845                              (progn
846                                (format t "char-count = ~A~%" char-count)
847                                (format t "octet-count = ~A~%" octet-count)
848                                (format t "in-index = ~A~%" (lisp-stream-in-index stream)))
849                              (when (> char-count 0)
850                                (setf (fd-stream-oc-state stream) new-state)
851                                (setf (lisp-stream-string-buffer-len stream) (1+ char-count))
852                                (setf (lisp-stream-string-index stream) 2)
853                                (setf (lisp-stream-in-index stream) octet-count)
854                                #+(or debug-frc-sr)
855                                (progn
856                                  (format t "new in-index = ~A~%" (lisp-stream-in-index stream))
857                                  (format t "new sbuf = ~S~%"
858                                          (subseq sbuf 0 (1+ char-count))))
859                                (schar sbuf 1)))))
860                       (let ((out (convert-buffer)))
861                         (or out
862                             ;; There weren't enough octets to convert at
863                             ;; least one character.  Try to read some more
864                             ;; octets and try again.  (If we still fail,
865                             ;; what should we do then?  Currently, just
866                             ;; just return NIL and let other parts of Lisp
867                             ;; catch that.)
868                             ;;
869                             ;; The in buffer holds unread octets up to
870                             ;; index in-length.  So start reading octets there.
871                             (let* ((index (fd-stream-in-length stream))
872                                    (count (get-octets index)))
873                               (declare (type (integer 0 #.in-buffer-length) count index))
874                               (cond ((zerop count)
875                                      (handle-eof))
876                                     (t
877                                      ;; Adjust in-length to the total
878                                      ;; number of octets that are now in
879                                      ;; the buffer.
880                                      (setf (fd-stream-in-length stream) (+ count index))
881                                      (convert-buffer))))))))))))))
882    
883  ;;; FAST-READ-BYTE-REFILL  --  Interface  ;;; FAST-READ-BYTE-REFILL  --  Interface
884  ;;;  ;;;
# Line 817  Line 908 
908  ;;; Output functions:  ;;; Output functions:
909    
910  (defun write-char (character &optional (stream *standard-output*))  (defun write-char (character &optional (stream *standard-output*))
911    _N"Outputs the Character to the Stream."    "Outputs the Character to the Stream."
912    (declare (type streamlike stream))    (declare (type streamlike stream))
913    (let ((stream (out-synonym-of stream)))    (let ((stream (out-synonym-of stream)))
914      (stream-dispatch stream      (stream-dispatch stream
# Line 830  Line 921 
921    character)    character)
922    
923  (defun terpri (&optional (stream *standard-output*))  (defun terpri (&optional (stream *standard-output*))
924    _N"Outputs a new line to the Stream."    "Outputs a new line to the Stream."
925    (declare (type streamlike stream))    (declare (type streamlike stream))
926    (let ((stream (out-synonym-of stream)))    (let ((stream (out-synonym-of stream)))
927      (stream-dispatch stream      (stream-dispatch stream
# Line 843  Line 934 
934    nil)    nil)
935    
936  (defun fresh-line (&optional (stream *standard-output*))  (defun fresh-line (&optional (stream *standard-output*))
937    _N"Outputs a new line to the Stream if it is not positioned at the beginning of    "Outputs a new line to the Stream if it is not positioned at the beginning of
938     a line.  Returns T if it output a new line, nil otherwise."     a line.  Returns T if it output a new line, nil otherwise."
939    (declare (type streamlike stream))    (declare (type streamlike stream))
940    (let ((stream (out-synonym-of stream)))    (let ((stream (out-synonym-of stream)))
# Line 859  Line 950 
950    
951  (defun write-string (string &optional (stream *standard-output*)  (defun write-string (string &optional (stream *standard-output*)
952                              &key (start 0) end)                              &key (start 0) end)
953    _N"Outputs the String to the given Stream."    "Outputs the String to the given Stream."
954    (write-string* string stream start (or end (length (the vector string)))))    (write-string* string stream start (or end (length (the vector string)))))
955    
956  (defun write-string* (string &optional (stream *standard-output*)  (defun write-string* (string &optional (stream *standard-output*)
# Line 886  Line 977 
977    
978  (defun write-line (string &optional (stream *standard-output*)  (defun write-line (string &optional (stream *standard-output*)
979                            &key (start 0) (end (length string)))                            &key (start 0) (end (length string)))
980    _N"Outputs the String to the given Stream, followed by a newline character."    "Outputs the String to the given Stream, followed by a newline character."
981    (write-line* string stream start (or end (length string))))    (write-line* string stream start (or end (length string))))
982    
983  (defun write-line* (string &optional (stream *standard-output*)  (defun write-line* (string &optional (stream *standard-output*)
# Line 918  Line 1009 
1009      string))      string))
1010    
1011  (defun charpos (&optional (stream *standard-output*))  (defun charpos (&optional (stream *standard-output*))
1012    _N"Returns the number of characters on the current line of output of the given    "Returns the number of characters on the current line of output of the given
1013    Stream, or Nil if that information is not availible."    Stream, or Nil if that information is not availible."
1014    (declare (type streamlike stream))    (declare (type streamlike stream))
1015    (let ((stream (out-synonym-of stream)))    (let ((stream (out-synonym-of stream)))
# Line 931  Line 1022 
1022        (stream-line-column stream))))        (stream-line-column stream))))
1023    
1024  (defun line-length (&optional (stream *standard-output*))  (defun line-length (&optional (stream *standard-output*))
1025    _N"Returns the number of characters that will fit on a line of output on the    "Returns the number of characters that will fit on a line of output on the
1026    given Stream, or Nil if that information is not available."    given Stream, or Nil if that information is not available."
1027    (declare (type streamlike stream))    (declare (type streamlike stream))
1028    (let ((stream (out-synonym-of stream)))    (let ((stream (out-synonym-of stream)))
# Line 944  Line 1035 
1035        (stream-line-length stream))))        (stream-line-length stream))))
1036    
1037  (defun finish-output (&optional (stream *standard-output*))  (defun finish-output (&optional (stream *standard-output*))
1038    _N"Attempts to ensure that all output sent to the Stream has reached its    "Attempts to ensure that all output sent to the Stream has reached its
1039     destination, and only then returns."     destination, and only then returns."
1040    (declare (type streamlike stream))    (declare (type streamlike stream))
1041    (let ((stream (out-synonym-of stream)))    (let ((stream (out-synonym-of stream)))
# Line 958  Line 1049 
1049    nil)    nil)
1050    
1051  (defun force-output (&optional (stream *standard-output*))  (defun force-output (&optional (stream *standard-output*))
1052    _N"Attempts to force any buffered output to be sent."    "Attempts to force any buffered output to be sent."
1053    (declare (type streamlike stream))    (declare (type streamlike stream))
1054    (let ((stream (out-synonym-of stream)))    (let ((stream (out-synonym-of stream)))
1055      (stream-dispatch stream      (stream-dispatch stream
# Line 971  Line 1062 
1062    nil)    nil)
1063    
1064  (defun clear-output (&optional (stream *standard-output*))  (defun clear-output (&optional (stream *standard-output*))
1065    _N"Clears the given output Stream."    "Clears the given output Stream."
1066    (declare (type streamlike stream))    (declare (type streamlike stream))
1067    (let ((stream (out-synonym-of stream)))    (let ((stream (out-synonym-of stream)))
1068      (stream-dispatch stream      (stream-dispatch stream
# Line 984  Line 1075 
1075    nil)    nil)
1076    
1077  (defun write-byte (integer stream)  (defun write-byte (integer stream)
1078    _N"Outputs the Integer to the binary Stream."    "Outputs the Integer to the binary Stream."
1079    (declare (type stream stream))    (declare (type stream stream))
1080    (let ((stream (out-synonym-of stream)))    (let ((stream (out-synonym-of stream)))
1081      (stream-dispatch stream      (stream-dispatch stream
# Line 1050  Line 1141 
1141    (streams () :type list :read-only t))    (streams () :type list :read-only t))
1142    
1143  (defun make-broadcast-stream (&rest streams)  (defun make-broadcast-stream (&rest streams)
1144    _N"Returns an output stream which sends its output to all of the given    "Returns an output stream which sends its output to all of the given
1145  streams."  streams."
1146    (dolist (s streams)    (dolist (s streams)
1147      (unless (output-stream-p s)      (unless (output-stream-p s)
# Line 1224  streams." Line 1315  streams."
1315            (two-way-stream-output-stream s)))            (two-way-stream-output-stream s)))
1316    
1317  (defun make-two-way-stream (input-stream output-stream)  (defun make-two-way-stream (input-stream output-stream)
1318    _N"Returns a bidirectional stream which gets its input from Input-Stream and    "Returns a bidirectional stream which gets its input from Input-Stream and
1319     sends its output to Output-Stream."     sends its output to Output-Stream."
1320    (unless (input-stream-p input-stream)    (unless (input-stream-p input-stream)
1321      (ill-in-any input-stream))      (ill-in-any input-stream))
# Line 1310  streams." Line 1401  streams."
1401            (concatenated-stream-streams s)))            (concatenated-stream-streams s)))
1402    
1403  (defun make-concatenated-stream (&rest streams)  (defun make-concatenated-stream (&rest streams)
1404    _N"Returns a stream which takes its input from each of the Streams in turn,    "Returns a stream which takes its input from each of the Streams in turn,
1405     going on to the next at EOF."     going on to the next at EOF."
1406    (dolist (s streams)    (dolist (s streams)
1407      (unless (input-stream-p s)      (unless (input-stream-p s)
# Line 1395  streams." Line 1486  streams."
1486    unread-stuff)    unread-stuff)
1487    
1488  (defun make-echo-stream (input-stream output-stream)  (defun make-echo-stream (input-stream output-stream)
1489    _N"Returns an echo stream that takes input from Input-stream and sends    "Returns an echo stream that takes input from Input-stream and sends
1490  output to Output-stream"  output to Output-stream"
1491    (unless (input-stream-p input-stream)    (unless (input-stream-p input-stream)
1492      (ill-in-any input-stream))      (ill-in-any input-stream))
# Line 1612  output to Output-stream" Line 1703  output to Output-stream"
1703    
1704  (defun make-string-input-stream (string &optional  (defun make-string-input-stream (string &optional
1705                                          (start 0) (end (length string)))                                          (start 0) (end (length string)))
1706    _N"Returns an input stream which will supply the characters of String between    "Returns an input stream which will supply the characters of String between
1707    Start and End in order."    Start and End in order."
1708    (declare (type string string)    (declare (type string string)
1709             (type index start)             (type index start)
# Line 1639  output to Output-stream" Line 1730  output to Output-stream"
1730    (write-string "#<String-Output Stream>" stream))    (write-string "#<String-Output Stream>" stream))
1731    
1732  (defun make-string-output-stream (&key (element-type 'character))  (defun make-string-output-stream (&key (element-type 'character))
1733    _N"Returns an Output stream which will accumulate all output given to it for    "Returns an Output stream which will accumulate all output given to it for
1734     the benefit of the function Get-Output-Stream-String."     the benefit of the function Get-Output-Stream-String."
1735    (declare (ignore element-type))    (declare (ignore element-type))
1736    (%make-string-output-stream))    (%make-string-output-stream))
# Line 1699  output to Output-stream" Line 1790  output to Output-stream"
1790       (set-closed-flame stream))))       (set-closed-flame stream))))
1791    
1792  (defun get-output-stream-string (stream)  (defun get-output-stream-string (stream)
1793    _N"Returns a string of all the characters sent to a stream made by    "Returns a string of all the characters sent to a stream made by
1794     Make-String-Output-Stream since the last call to this function."     Make-String-Output-Stream since the last call to this function."
1795    (declare (type string-output-stream stream))    (declare (type string-output-stream stream))
1796    (let* ((length (string-output-stream-index stream))    (let* ((length (string-output-stream-index stream))
# Line 1709  output to Output-stream" Line 1800  output to Output-stream"
1800      result))      result))
1801    
1802  (defun dump-output-stream-string (in-stream out-stream)  (defun dump-output-stream-string (in-stream out-stream)
1803    _N"Dumps the characters buffer up in the In-Stream to the Out-Stream as    "Dumps the characters buffer up in the In-Stream to the Out-Stream as
1804    Get-Output-Stream-String would return them."    Get-Output-Stream-String would return them."
1805    (write-string* (string-output-stream-string in-stream) out-stream    (write-string* (string-output-stream-string in-stream) out-stream
1806                   0 (string-output-stream-index in-stream))                   0 (string-output-stream-index in-stream))
# Line 1904  output to Output-stream" Line 1995  output to Output-stream"
1995    (target (required-argument) :type stream))    (target (required-argument) :type stream))
1996    
1997  (defun make-case-frob-stream (target kind)  (defun make-case-frob-stream (target kind)
1998    _N"Returns a stream that sends all output to the stream TARGET, but modifies    "Returns a stream that sends all output to the stream TARGET, but modifies
1999     the case of letters, depending on KIND, which should be one of:     the case of letters, depending on KIND, which should be one of:
2000       :upcase - convert to upper case.       :upcase - convert to upper case.
2001       :downcase - convert to lower case.       :downcase - convert to lower case.
# Line 2153  output to Output-stream" Line 2244  output to Output-stream"
2244  ;;; LISTEN fails, then we have some random stream we must wait on.  ;;; LISTEN fails, then we have some random stream we must wait on.
2245  ;;;  ;;;
2246  (defun get-stream-command (stream)  (defun get-stream-command (stream)
2247    _N"This takes a stream and waits for text or a command to appear on it.  If    "This takes a stream and waits for text or a command to appear on it.  If
2248     text appears before a command, this returns nil, and otherwise it returns     text appears before a command, this returns nil, and otherwise it returns
2249     a command."     a command."
2250    (let ((cmdp (funcall (lisp-stream-misc stream) stream :get-command)))    (let ((cmdp (funcall (lisp-stream-misc stream) stream :get-command)))
# Line 2168  output to Output-stream" Line 2259  output to Output-stream"
2259  ;;; READ-SEQUENCE --  ;;; READ-SEQUENCE --
2260    
2261  (defun read-sequence (seq stream &key (start 0) (end nil) partial-fill)  (defun read-sequence (seq stream &key (start 0) (end nil) partial-fill)
2262    _N"Destructively modify SEQ by reading elements from STREAM.    "Destructively modify SEQ by reading elements from STREAM.
2263    
2264    Seq is bounded by Start and End. Seq is destructively modified by    Seq is bounded by Start and End. Seq is destructively modified by
2265    copying successive elements into it from Stream. If the end of file    copying successive elements into it from Stream. If the end of file
# Line 2205  output to Output-stream" Line 2296  output to Output-stream"
2296        (cond ((not (open-stream-p stream))        (cond ((not (open-stream-p stream))
2297               (error 'simple-stream-error               (error 'simple-stream-error
2298                      :stream stream                      :stream stream
2299                      :format-control _"The stream is not open."))                      :format-control (intl:gettext "The stream is not open.")))
2300              ((not (input-stream-p stream))              ((not (input-stream-p stream))
2301               (error 'simple-stream-error               (error 'simple-stream-error
2302                      :stream stream                      :stream stream
2303                      :format-control _"The stream is not open for input."))                      :format-control (intl:gettext "The stream is not open for input.")))
2304              ((and seq (>= start end) 0))              ((and seq (>= start end) 0))
2305              (t              (t
2306               ;; So much for object-oriented programming!               ;; So much for object-oriented programming!
# Line 2293  output to Output-stream" Line 2384  output to Output-stream"
2384      (error 'type-error      (error 'type-error
2385             :datum (read-char stream nil #\Null)             :datum (read-char stream nil #\Null)
2386             :expected-type (stream-element-type stream)             :expected-type (stream-element-type stream)
2387             :format-control _"Trying to read characters from a binary stream."))             :format-control (intl:gettext "Trying to read characters from a binary stream.")))
2388    ;; Let's go as low level as it seems reasonable.    ;; Let's go as low level as it seems reasonable.
2389    (let* ((numbytes (- end start))    (let* ((numbytes (- end start))
2390           (total-bytes 0))           (total-bytes 0))
# Line 2321  output to Output-stream" Line 2412  output to Output-stream"
2412      (error 'type-error      (error 'type-error
2413             :datum (read-char stream nil #\Null)             :datum (read-char stream nil #\Null)
2414             :expected-type (stream-element-type stream)             :expected-type (stream-element-type stream)
2415             :format-control _"Trying to read characters from a binary stream."))             :format-control (intl:gettext "Trying to read characters from a binary stream.")))
2416    ;; Let's go as low level as it seems reasonable.    ;; Let's go as low level as it seems reasonable.
2417    (let* ((numbytes (- end start))    (let* ((numbytes (- end start))
2418           (total-bytes 0))           (total-bytes 0))
# Line 2345  output to Output-stream" Line 2436  output to Output-stream"
2436      (error 'type-error      (error 'type-error
2437             :datum (read-char stream nil #\Null)             :datum (read-char stream nil #\Null)
2438             :expected-type (stream-element-type stream)             :expected-type (stream-element-type stream)
2439             :format-control _"Trying to read characters from a binary stream."))             :format-control (intl:gettext "Trying to read characters from a binary stream.")))
2440    (do ((i start (1+ i))    (do ((i start (1+ i))
2441         (s-len (length s)))         (s-len (length s)))
2442        ((or (>= i s-len)        ((or (>= i s-len)
# Line 2418  output to Output-stream" Line 2509  output to Output-stream"
2509                    :datum (read-byte stream nil 0)                    :datum (read-byte stream nil 0)
2510                    :expected-type (stream-element-type stream) ; Bogus?!?                    :expected-type (stream-element-type stream) ; Bogus?!?
2511                    :format-control                    :format-control
2512                    _"Trying to read binary data from a text stream."))                    (intl:gettext "Trying to read binary data from a text stream.")))
2513    
2514            ;; Let's go as low level as it seems reasonable.            ;; Let's go as low level as it seems reasonable.
2515            ((not (member stream-et            ((not (member stream-et
# Line 2536  output to Output-stream" Line 2627  output to Output-stream"
2627  ;;; will always puzzle me.  ;;; will always puzzle me.
2628    
2629  (defun write-sequence (seq stream &key (start 0) (end nil))  (defun write-sequence (seq stream &key (start 0) (end nil))
2630    _N"Writes the elements of the Seq bounded by Start and End to Stream.    "Writes the elements of the Seq bounded by Start and End to Stream.
2631    
2632    Argument(s):    Argument(s):
2633    SEQ:     a proper SEQUENCE    SEQ:     a proper SEQUENCE
# Line 2565  output to Output-stream" Line 2656  output to Output-stream"
2656        (cond ((not (open-stream-p stream))        (cond ((not (open-stream-p stream))
2657               (error 'simple-stream-error               (error 'simple-stream-error
2658                      :stream stream                      :stream stream
2659                      :format-control _"The stream is not open."))                      :format-control (intl:gettext "The stream is not open.")))
2660              ((not (output-stream-p stream))              ((not (output-stream-p stream))
2661               (error 'simple-stream-error               (error 'simple-stream-error
2662                      :stream stream                      :stream stream
2663                      :format-control _"The stream is not open for output."))                      :format-control (intl:gettext "The stream is not open for output.")))
2664              ((and seq (>= start end)) seq)              ((and seq (>= start end)) seq)
2665              (t              (t
2666               ;; So much for object-oriented programming!               ;; So much for object-oriented programming!
# Line 2621  output to Output-stream" Line 2712  output to Output-stream"
2712                        :datum e                        :datum e
2713                        :expected-type type                        :expected-type type
2714                        :format-control                        :format-control
2715                        _"Trying to output an element of unproper type to a stream.")))))                        (intl:gettext "Trying to output an element of unproper type to a stream."))))))
2716      (let ((stream-et (stream-element-type stream)))      (let ((stream-et (stream-element-type stream)))
2717    
2718        (check-list-element-types seq stream-et)        (check-list-element-types seq stream-et)
# Line 2663  output to Output-stream" Line 2754  output to Output-stream"
2754      (error 'type-error      (error 'type-error
2755             :datum seq             :datum seq
2756             :expected-type (stream-element-type stream)             :expected-type (stream-element-type stream)
2757             :format-control _"Trying to output a string to a binary stream."))             :format-control (intl:gettext "Trying to output a string to a binary stream.")))
2758    (write-string seq stream :start start :end end)    (write-string seq stream :start start :end end)
2759    seq)    seq)
2760    
# Line 2700  output to Output-stream" Line 2791  output to Output-stream"
2791      (error 'simple-type-error      (error 'simple-type-error
2792             :datum (elt seq 0)             :datum (elt seq 0)
2793             :expected-type (stream-element-type stream)             :expected-type (stream-element-type stream)
2794             :format-control _"Trying to output binary data to a text stream."))             :format-control (intl:gettext "Trying to output binary data to a text stream.")))
2795    (cond ((system:fd-stream-p stream)    (cond ((system:fd-stream-p stream)
2796           (flet ((write-n-x8-bytes (stream data start end byte-size)           (flet ((write-n-x8-bytes (stream data start end byte-size)
2797                    (let ((x8-mult (truncate byte-size 8)))                    (let ((x8-mult (truncate byte-size 8)))

Legend:
Removed from v.1.89.4.1  
changed lines
  Added in v.1.102

  ViewVC Help
Powered by ViewVC 1.1.5