:stream stream
:code code))
+;;; Returning true goes into end of file handling, false will enter another
+;;; round of input buffer filling followed by re-entering character decode.
+(defun stream-decoding-error-and-handle (stream octet-count)
+ (restart-case
+ (stream-decoding-error stream
+ (let ((sap (fd-stream-ibuf-sap stream))
+ (head (fd-stream-ibuf-head stream)))
+ (loop for i from 0 below octet-count
+ collect (sap-ref-8 sap (+ head i)))))
+ (attempt-resync ()
+ :report (lambda (stream)
+ (format stream
+ "~@<Attempt to resync the stream at a character ~
+ character boundary and continue.~@:>"))
+ (fd-stream-resync stream)
+ nil)
+ (force-end-of-file ()
+ :report (lambda (stream)
+ (format stream "~@<Force an end of file.~@:>"))
+ t)))
+
+(defun stream-encoding-error-and-handle (stream code)
+ (restart-case
+ (stream-encoding-error stream code)
+ (output-nothing ()
+ :report (lambda (stream)
+ (format stream "~@<Skip output of this character.~@:>"))
+ (throw 'output-nothing nil))))
+
;;; This is called by the server when we can write to the given file
;;; descriptor. Attempt to write the data again. If it worked, remove
;;; the data from the OUTPUT-LATER list. If it didn't work, something
(fd-stream-ibuf-head ,stream-var))
(file-position ,stream-var (file-position ,stream-var))))
,(if restart
-
- `(with-simple-restart (output-nothing
- "~@<Skip output of this character.~@:>")
- ,@body
- (incf (fd-stream-obuf-tail ,stream-var) size))
+ `(catch 'output-nothing
+ ,@body
+ (incf (fd-stream-obuf-tail ,stream-var) size))
`(progn
,@body
(incf (fd-stream-obuf-tail ,stream-var) size)))
(fd-stream-ibuf-head ,stream-var))
(file-position ,stream-var (file-position ,stream-var))))
,(if restart
- `(with-simple-restart (output-nothing
- "~@<Skip output of this character.~@:>")
- ,@body
- (incf (fd-stream-obuf-tail ,stream-var) ,size))
+ `(catch 'output-nothing
+ ,@body
+ (incf (fd-stream-obuf-tail ,stream-var) ,size))
`(progn
,@body
(incf (fd-stream-obuf-tail ,stream-var) ,size)))
(mapcar
(lambda (buffering)
(let ((function
- (intern (let ((*print-case* :upcase))
- (format nil name-fmt (car buffering))))))
+ (intern (format nil name-fmt (string (car buffering))))))
`(progn
(defun ,function (stream byte)
(output-wrapper/variable-width (stream ,size ,buffering ,restart)
(mapcar
(lambda (buffering)
(let ((function
- (intern (let ((*print-case* :upcase))
- (format nil name-fmt (car buffering))))))
+ (intern (format nil name-fmt (string (car buffering))))))
`(progn
(defun ,function (stream byte)
(output-wrapper (stream ,size ,buffering ,restart)
((zerop bytes)) ; easy case
((<= bytes space)
(if (system-area-pointer-p thing)
- (system-area-copy thing
- (* start sb!vm:n-byte-bits)
- (fd-stream-obuf-sap fd-stream)
- (* tail sb!vm:n-byte-bits)
- (* bytes sb!vm:n-byte-bits))
+ (system-area-ub8-copy thing start
+ (fd-stream-obuf-sap fd-stream)
+ tail
+ bytes)
;; FIXME: There should be some type checking somewhere to
;; verify that THING here is a vector, not just <not a SAP>.
- (copy-to-system-area thing
- (+ (* start sb!vm:n-byte-bits)
- (* sb!vm:vector-data-offset
- sb!vm:n-word-bits))
- (fd-stream-obuf-sap fd-stream)
- (* tail sb!vm:n-byte-bits)
- (* bytes sb!vm:n-byte-bits)))
+ (copy-ub8-to-system-area thing start
+ (fd-stream-obuf-sap fd-stream)
+ tail
+ bytes))
(setf (fd-stream-obuf-tail fd-stream) newtail))
((<= bytes len)
(flush-output-buffer fd-stream)
(if (system-area-pointer-p thing)
- (system-area-copy thing
- (* start sb!vm:n-byte-bits)
- (fd-stream-obuf-sap fd-stream)
- 0
- (* bytes sb!vm:n-byte-bits))
+ (system-area-ub8-copy thing
+ start
+ (fd-stream-obuf-sap fd-stream)
+ 0
+ bytes)
;; FIXME: There should be some type checking somewhere to
;; verify that THING here is a vector, not just <not a SAP>.
- (copy-to-system-area thing
- (+ (* start sb!vm:n-byte-bits)
- (* sb!vm:vector-data-offset
- sb!vm:n-word-bits))
- (fd-stream-obuf-sap fd-stream)
- 0
- (* bytes sb!vm:n-byte-bits)))
+ (copy-ub8-to-system-area thing
+ start
+ (fd-stream-obuf-sap fd-stream)
+ 0
+ bytes))
(setf (fd-stream-obuf-tail fd-stream) bytes))
(t
(flush-output-buffer fd-stream)
:end end))))
(if (and (typep thing 'base-string)
(eq (fd-stream-external-format stream) :latin-1))
- (ecase (fd-stream-buffering stream)
- (:full
- (output-raw-bytes stream thing start end))
- (:line
- (output-raw-bytes stream thing start end)
- (when last-newline
- (flush-output-buffer stream)))
- (:none
- (frob-output stream thing start end nil)))
+ (ecase (fd-stream-buffering stream)
+ (:full
+ (output-raw-bytes stream thing start end))
+ (:line
+ (output-raw-bytes stream thing start end)
+ (when last-newline
+ (flush-output-buffer stream)))
+ (:none
+ (frob-output stream thing start end nil)))
(ecase (fd-stream-buffering stream)
(:full (funcall (fd-stream-output-bytes stream)
stream thing nil start end))
;;; per element.
(defvar *input-routines* ())
-;;; Fill the input buffer, and return the first character. Throw to
-;;; EOF-INPUT-CATCHER if the eof was reached. Drop into SYSTEM:SERVER
-;;; if necessary.
-(defun frob-input (stream)
+;;; Fill the input buffer, and return the number of bytes read. Throw
+;;; to EOF-INPUT-CATCHER if the eof was reached. Drop into
+;;; SYSTEM:SERVER if necessary.
+(defun refill-buffer/fd (stream)
(let ((fd (fd-stream-fd stream))
(ibuf-sap (fd-stream-ibuf-sap stream))
(buflen (fd-stream-ibuf-length stream))
(setf (fd-stream-ibuf-tail stream) 0))
(t
(decf tail head)
- (system-area-copy ibuf-sap (* head sb!vm:n-byte-bits)
- ibuf-sap 0 (* tail sb!vm:n-byte-bits))
+ (system-area-ub8-copy ibuf-sap head
+ ibuf-sap 0 tail)
(setf head 0)
(setf (fd-stream-ibuf-head stream) 0)
(setf (fd-stream-ibuf-tail stream) tail))))
(unless (sb!sys:wait-until-fd-usable
fd :input (fd-stream-timeout stream))
(error 'io-timeout :stream stream :direction :read))
- (frob-input stream))
+ (refill-buffer/fd stream))
(simple-stream-perror "couldn't read from ~S" stream errno)))
((zerop count)
(setf (fd-stream-listen stream) :eof)
(/show0 "THROWing EOF-INPUT-CATCHER")
(throw 'eof-input-catcher nil))
(t
- (incf (fd-stream-ibuf-tail stream) count))))))
+ (incf (fd-stream-ibuf-tail stream) count)
+ count)))))
;;; Make sure there are at least BYTES number of bytes in the input
-;;; buffer. Keep calling FROB-INPUT until that condition is met.
+;;; buffer. Keep calling REFILL-BUFFER/FD until that condition is met.
(defmacro input-at-least (stream bytes)
(let ((stream-var (gensym))
(bytes-var (gensym)))
(fd-stream-ibuf-head ,stream-var))
,bytes-var)
(return))
- (frob-input ,stream-var)))))
+ (refill-buffer/fd ,stream-var)))))
-(defmacro input-wrapper/variable-width ((stream bytes eof-error eof-value
- resync-function)
+(defmacro input-wrapper/variable-width ((stream bytes eof-error eof-value)
&body read-forms)
(let ((stream-var (gensym))
(retry-var (gensym))
(fd-stream-unread ,stream-var)
(setf (fd-stream-unread ,stream-var) nil)
(setf (fd-stream-listen ,stream-var) nil))
- (let ((,element-var nil))
+ (let ((,element-var nil)
+ (decode-break-reason nil))
(do ((,retry-var t))
((not ,retry-var))
- (setq ,retry-var nil)
- (restart-case
+ (unless
(catch 'eof-input-catcher
- (unless
- (block character-decode
- (input-at-least ,stream-var 1)
- (let* ((byte (sap-ref-8 (fd-stream-ibuf-sap
- ,stream-var)
- (fd-stream-ibuf-head
- ,stream-var))))
- (setq size ,bytes)
- (input-at-least ,stream-var size)
- (setq ,element-var (locally ,@read-forms))))
- (stream-decoding-error
- ,stream-var
- (if size
- (loop for i from 0 below size
- collect (sap-ref-8 (fd-stream-ibuf-sap
+ (setf decode-break-reason
+ (block decode-break-reason
+ (input-at-least ,stream-var 1)
+ (let* ((byte (sap-ref-8 (fd-stream-ibuf-sap
,stream-var)
- (+ (fd-stream-ibuf-head
- ,stream-var)
- i)))
- (list (sap-ref-8 (fd-stream-ibuf-sap
- ,stream-var)
- (fd-stream-ibuf-head
- ,stream-var)))))))
- (attempt-resync ()
- :report (lambda (stream)
- (format stream
- "~@<Attempt to resync the stream at a ~
- character boundary and continue.~@:>"))
- (,resync-function ,stream-var)
- (setq ,retry-var t))
- (force-end-of-file ()
- :report (lambda (stream)
- (format stream
- "~@<Force an end of file.~@:>"))
- nil)))
+ (fd-stream-ibuf-head
+ ,stream-var))))
+ (setq size ,bytes)
+ (input-at-least ,stream-var size)
+ (setq ,element-var (locally ,@read-forms))
+ (setq ,retry-var nil))
+ nil))
+ (when decode-break-reason
+ (stream-decoding-error-and-handle stream
+ decode-break-reason))
+ t)
+ (let ((octet-count (- (fd-stream-ibuf-tail ,stream-var)
+ (fd-stream-ibuf-head ,stream-var))))
+ (when (or (zerop octet-count)
+ (and (not ,element-var)
+ (not decode-break-reason)
+ (stream-decoding-error-and-handle
+ stream octet-count)))
+ (setq ,retry-var nil)))))
(cond (,element-var
(incf (fd-stream-ibuf-head ,stream-var) size)
,element-var)
(eof-or-lose ,stream-var ,eof-error ,eof-value))))))))
(defmacro def-input-routine/variable-width (name
- (type external-format size sap head
- resync-function)
+ (type external-format size sap head)
&rest body)
`(progn
(defun ,name (stream eof-error eof-value)
- (input-wrapper/variable-width (stream ,size eof-error eof-value
- ,resync-function)
+ (input-wrapper/variable-width (stream ,size eof-error eof-value)
(let ((,sap (fd-stream-ibuf-sap stream))
(,head (fd-stream-ibuf-head stream)))
,@body)))
(declare (type index start end))
(let* ((length (- end start))
(string (make-string length)))
- (copy-from-system-area sap (* start sb!vm:n-byte-bits)
- string (* sb!vm:vector-data-offset
- sb!vm:n-word-bits)
- (* length sb!vm:n-byte-bits))
+ (copy-ub8-from-system-area sap start
+ string 0
+ length)
string))
;;; the N-BIN method for FD-STREAMs
(= total-copied requested)
(return total-copied))
(;; If EOF, we're done in another way.
- (zerop (refill-fd-stream-buffer stream))
+ (null (catch 'eof-input-catcher (refill-buffer/fd stream)))
(if eof-error-p
(error 'end-of-file :stream stream)
(return total-copied)))
;; through into another pass of the loop.
))))
-;;; Try to refill the stream buffer. Return the number of bytes read.
-;;; (For EOF, the return value will be zero, otherwise positive.)
-(defun refill-fd-stream-buffer (stream)
- ;; We don't have any logic to preserve leftover bytes in the buffer,
- ;; so we should only be called when the buffer is empty.
- ;; FIXME: can have three bytes in buffer because of UTF-8
- (let ((new-head 0)
- (sap (fd-stream-ibuf-sap stream)))
- (do ((head (fd-stream-ibuf-head stream) (1+ head))
- (tail (fd-stream-ibuf-tail stream)))
- ((= head tail))
- (setf (sap-ref-8 sap new-head) (sap-ref-8 sap head))
- (incf new-head))
- (multiple-value-bind (count err)
- (sb!unix:unix-read (fd-stream-fd stream)
- (sap+ sap new-head)
- (- (fd-stream-ibuf-length stream) new-head))
- (declare (type (or index null) count))
- (when (null count)
- (simple-stream-perror "couldn't read from ~S" stream err))
- (setf (fd-stream-listen stream) nil
- (fd-stream-ibuf-head stream) 0
- (fd-stream-ibuf-tail stream) (+ count new-head))
- count)))
+(defun fd-stream-resync (stream)
+ (dolist (entry *external-formats*)
+ (when (member (fd-stream-external-format stream) (first entry))
+ (return-from fd-stream-resync
+ (funcall (symbol-function (eighth entry)) stream)))))
(defmacro define-external-format (external-format size output-restart
out-expr in-expr)
(let* ((name (first external-format))
- (out-function (intern (let ((*print-case* :upcase))
- (format nil "OUTPUT-BYTES/~A" name))))
- (format (format nil "OUTPUT-CHAR-~A-~~A-BUFFERED" name))
- (in-function (intern (let ((*print-case* :upcase))
- (format nil "FD-STREAM-READ-N-CHARACTERS/~A"
- name))))
- (in-char-function (intern (let ((*print-case* :upcase))
- (format nil "INPUT-CHAR/~A" name)))))
+ (out-function (symbolicate "OUTPUT-BYTES/" name))
+ (format (format nil "OUTPUT-CHAR-~A-~~A-BUFFERED" (string name)))
+ (in-function (symbolicate "FD-STREAM-READ-N-CHARACTERS/" name))
+ (in-char-function (symbolicate "INPUT-CHAR/" name)))
`(progn
(defun ,out-function (stream string flush-p start end)
(let ((start (or start 0))
(tail (fd-stream-obuf-tail stream)))
((or (= start end) (< (- len tail) 4)) tail)
,(if output-restart
- `(with-simple-restart (output-nothing
- "~@<Skip output of this character.~@:>")
- (let* ((byte (aref string start))
- (bits (char-code byte)))
- ,out-expr
- (incf tail ,size)))
+ `(catch 'output-nothing
+ (let* ((byte (aref string start))
+ (bits (char-code byte)))
+ ,out-expr
+ (incf tail ,size)))
`(let* ((byte (aref string start))
(bits (char-code byte)))
,out-expr
(= total-copied requested)
(return total-copied))
( ;; If EOF, we're done in another way.
- (zerop (refill-fd-stream-buffer stream))
+ (null (catch 'eof-input-catcher (refill-buffer/fd stream)))
(if eof-error-p
(error 'end-of-file :stream stream)
(return total-copied)))
(setf *external-formats*
(cons '(,external-format ,in-function ,in-char-function ,out-function
,@(mapcar #'(lambda (buffering)
- (intern (let ((*print-case* :upcase))
- (format nil format buffering))))
+ (intern (format nil format (string buffering))))
'(:none :line :full)))
*external-formats*)))))
(external-format output-restart out-size-expr
out-expr in-size-expr in-expr)
(let* ((name (first external-format))
- (out-function (intern (let ((*print-case* :upcase))
- (format nil "OUTPUT-BYTES/~A" name))))
- (format (format nil "OUTPUT-CHAR-~A-~~A-BUFFERED" name))
- (in-function (intern (let ((*print-case* :upcase))
- (format nil "FD-STREAM-READ-N-CHARACTERS/~A"
- name))))
- (in-char-function (intern (let ((*print-case* :upcase))
- (format nil "INPUT-CHAR/~A" name))))
- (resync-function (intern (let ((*print-case* :upcase))
- (format nil "RESYNC/~A" name)))))
+ (out-function (symbolicate "OUTPUT-BYTES/" name))
+ (format (format nil "OUTPUT-CHAR-~A-~~A-BUFFERED" (string name)))
+ (in-function (symbolicate "FD-STREAM-READ-N-CHARACTERS/" name))
+ (in-char-function (symbolicate "INPUT-CHAR/" name))
+ (resync-function (symbolicate "RESYNC/" name)))
`(progn
(defun ,out-function (fd-stream string flush-p start end)
(let ((start (or start 0))
(sap (fd-stream-obuf-sap fd-stream))
(tail (fd-stream-obuf-tail fd-stream)))
((or (= start end) (< (- len tail) 4)) tail)
- (let* ((byte (aref string start))
- (bits (char-code byte))
- (size ,out-size-expr))
- ,out-expr
- (incf tail size)
- (incf start))))
+ ,(if output-restart
+ `(catch 'output-nothing
+ (let* ((byte (aref string start))
+ (bits (char-code byte))
+ (size ,out-size-expr))
+ ,out-expr
+ (incf tail size)
+ (incf start)))
+ `(let* ((byte (aref string start))
+ (bits (char-code byte))
+ (size ,out-size-expr))
+ ,out-expr
+ (incf tail size)))
+ (incf start)))
(when (< start end)
(flush-output-buffer fd-stream)))
(when flush-p
(nil)
(let* ((head (fd-stream-ibuf-head stream))
(tail (fd-stream-ibuf-tail stream))
- (sap (fd-stream-ibuf-sap stream)))
+ (sap (fd-stream-ibuf-sap stream))
+ (head-start head)
+ (decode-break-reason nil))
(declare (type index head tail))
;; Copy data from stream buffer into user's buffer.
(do ((size nil nil))
((or (= tail head) (= requested total-copied)))
- (restart-case
- (unless (block character-decode
- (let ((byte (sap-ref-8 sap head)))
- (setq size ,in-size-expr)
- (when (> size (- tail head))
- (return))
- (setf (aref buffer (+ start total-copied))
- ,in-expr)
- (incf total-copied)
- (incf head size)))
- (setf (fd-stream-ibuf-head stream) head)
- (if (plusp total-copied)
- (return-from ,in-function total-copied)
- (stream-decoding-error
- stream
- (if size
- (loop for i from 0 below size
- collect (sap-ref-8 (fd-stream-ibuf-sap
- stream)
- (+ (fd-stream-ibuf-head
- stream)
- i)))
- (list (sap-ref-8 (fd-stream-ibuf-sap stream)
- (fd-stream-ibuf-head stream)))))))
- (attempt-resync ()
- :report (lambda (stream)
- (format stream
- "~@<Attempt to resync the stream at a ~
- character boundary and continue.~@:>"))
- (,resync-function stream)
- (setf head (fd-stream-ibuf-head stream)))
- (force-end-of-file ()
- :report (lambda (stream)
- (format stream "~@<Force an end of file.~@:>"))
+ (setf decode-break-reason
+ (block decode-break-reason
+ (let ((byte (sap-ref-8 sap head)))
+ (setq size ,in-size-expr)
+ (when (> size (- tail head))
+ (return))
+ (setf (aref buffer (+ start total-copied)) ,in-expr)
+ (incf total-copied)
+ (incf head size))
+ nil))
+ (setf (fd-stream-ibuf-head stream) head)
+ (when (and decode-break-reason
+ (= head head-start))
+ (when (stream-decoding-error-and-handle
+ stream decode-break-reason)
(if eof-error-p
(error 'end-of-file :stream stream)
- (return-from ,in-function total-copied)))))
+ (return-from ,in-function total-copied)))
+ (setf head (fd-stream-ibuf-head stream))
+ (setf tail (fd-stream-ibuf-tail stream)))
+ (when (plusp total-copied)
+ (return-from ,in-function total-copied)))
(setf (fd-stream-ibuf-head stream) head)
;; Maybe we need to refill the stream buffer.
(cond ( ;; If there were enough data in the stream buffer, we're done.
(= total-copied requested)
(return total-copied))
( ;; If EOF, we're done in another way.
- (zerop (refill-fd-stream-buffer stream))
+ (or (eq decode-break-reason 'eof)
+ (null (catch 'eof-input-catcher
+ (refill-buffer/fd stream))))
(if eof-error-p
(error 'end-of-file :stream stream)
(return total-copied)))
(def-input-routine/variable-width ,in-char-function (character
,external-format
,in-size-expr
- sap head
- ,resync-function)
+ sap head)
(let ((byte (sap-ref-8 sap head)))
,in-expr))
(defun ,resync-function (stream)
(loop (input-at-least stream 1)
(incf (fd-stream-ibuf-head stream))
- (when (block character-decode
- (let* ((sap (fd-stream-ibuf-sap stream))
- (head (fd-stream-ibuf-head stream))
- (byte (sap-ref-8 sap head))
- (size ,in-size-expr))
- ,in-expr))
+ (unless (block decode-break-reason
+ (let* ((sap (fd-stream-ibuf-sap stream))
+ (head (fd-stream-ibuf-head stream))
+ (byte (sap-ref-8 sap head))
+ (size ,in-size-expr))
+ ,in-expr)
+ nil)
(return))))
(setf *external-formats*
(cons '(,external-format ,in-function ,in-char-function ,out-function
,@(mapcar #'(lambda (buffering)
- (intern (let ((*print-case* :upcase))
- (format nil format buffering))))
+ (intern (format nil format (string buffering))))
'(:none :line :full))
,resync-function)
*external-formats*)))))
(define-external-format (:latin-1 :latin1 :iso-8859-1)
1 t
(if (>= bits 256)
- (stream-encoding-error stream bits)
+ (stream-encoding-error-and-handle stream bits)
(setf (sap-ref-8 sap tail) bits))
(code-char byte))
(define-external-format (:ascii :us-ascii :ansi_x3.4-1968)
1 t
(if (>= bits 128)
- (stream-encoding-error stream bits)
+ (stream-encoding-error-and-handle stream bits)
(setf (sap-ref-8 sap tail) bits))
(code-char byte))
(define-external-format (:ebcdic-us :ibm-037 :ibm037)
1 t
(if (>= bits 256)
- (stream-encoding-error stream bits)
+ (stream-encoding-error-and-handle stream bits)
(setf (sap-ref-8 sap tail) (aref reverse-table bits)))
(aref table byte)))
(if (< bits 256)
(if (= bits (char-code (aref latin-9-table bits)))
bits
- (stream-encoding-error stream byte))
+ (stream-encoding-error-and-handle stream byte))
(if (= (aref latin-9-reverse-1 (logand bits 15)) bits)
(aref latin-9-reverse-2 (logand bits 15))
- (stream-encoding-error stream byte))))
+ (stream-encoding-error-and-handle stream byte))))
(aref latin-9-table byte)))
(define-external-format/variable-width (:utf-8 :utf8) nil
(sap-ref-8 sap (+ 2 tail)) (logior #x80 (ldb (byte 6 6) bits))
(sap-ref-8 sap (+ 3 tail)) (logior #x80 (ldb (byte 6 0) bits)))))
(cond ((< byte #x80) 1)
- ((< byte #xc2) (return-from character-decode))
+ ((< byte #xc2) (return-from decode-break-reason 1))
((< byte #xe0) 2)
((< byte #xf0) 3)
(t 4))
(1 byte)
(2 (let ((byte2 (sap-ref-8 sap (1+ head))))
(unless (<= #x80 byte2 #xbf)
- (return-from character-decode))
+ (return-from decode-break-reason 2))
(dpb byte (byte 5 6) byte2)))
(3 (let ((byte2 (sap-ref-8 sap (1+ head)))
(byte3 (sap-ref-8 sap (+ 2 head))))
(unless (and (<= #x80 byte2 #xbf)
(<= #x80 byte3 #xbf))
- (return-from character-decode))
+ (return-from decode-break-reason 3))
(dpb byte (byte 4 12) (dpb byte2 (byte 6 6) byte3))))
(4 (let ((byte2 (sap-ref-8 sap (1+ head)))
(byte3 (sap-ref-8 sap (+ 2 head)))
(unless (and (<= #x80 byte2 #xbf)
(<= #x80 byte3 #xbf)
(<= #x80 byte4 #xbf))
- (return-from character-decode))
+ (return-from decode-break-reason 4))
(dpb byte (byte 3 18)
(dpb byte2 (byte 6 12)
(dpb byte3 (byte 6 6) byte4))))))))
(function c-string int))
sb!unix:codeset)
"LATIN-1")
- "KEYWORD")))
- (dolist (entry *external-formats*
- (setf (fd-stream-external-format fd-stream) :latin-1))
- (when (member (fd-stream-external-format fd-stream) (first entry))
- (return)))
+ "KEYWORD"))
+ (dolist (entry *external-formats*
+ (restart-case
+ (error "Invalid external-format ~A"
+ (fd-stream-external-format fd-stream))
+ (use-default ()
+ :report "Set external format to LATIN-1"
+ (setf (fd-stream-external-format fd-stream) :latin-1))))
+ (when (member (fd-stream-external-format fd-stream) (first entry))
+ (return))))
(when input-p
(multiple-value-bind (routine type size read-n-characters
0
0))))
(cond ((eql count 1)
- (frob-input fd-stream)
+ (refill-buffer/fd fd-stream)
(setf (fd-stream-ibuf-head fd-stream) 0)
(setf (fd-stream-ibuf-tail fd-stream) 0))
(t
(let ((original (case if-exists
((:rename :rename-and-delete)
(pick-backup-name namestring))
- ((:append)
+ ((:append :overwrite)
;; KLUDGE: Provent CLOSE from deleting
;; appending streams when called with :ABORT T
namestring)))