;;; -*- Mode:LISP; Package:FILE-SYSTEM; Base:10; Readtable:ZL -*- ;;; All "MAP-" streams are internal to the file system and support only simple ;;; serial IO. All "LM-" streams are streams used when opening files. (DEFFLAVOR MAP-STREAM-MIXIN ((STATUS :OPEN) ;:OPEN, :EOF, :BEING-CLOSED, :CLOSED (MAP (MAP-CREATE)) ;The map this stream is acting upon. (MAP-INDEX 0) ;Current index within map. (BYTE-SIZE 8) ;The byte size of the STREAM. (RQB (GET-DISK-RQB STANDARD-BLOCK-SIZE)) ;The RQB in which the physical buffer lives. (RQB-VALID-PAGES NIL)) ;The number of pages of data in RQB () (:INCLUDED-FLAVORS SI:STREAM) (:INITABLE-INSTANCE-VARIABLES MAP BYTE-SIZE) (:GETTABLE-INSTANCE-VARIABLES BYTE-SIZE)) (DEFWRAPPER (MAP-STREAM-MIXIN :CLOSE) ((&OPTIONAL IGNORE) . BODY) `(AND (NEQ STATUS :CLOSED) (PROG1 (PROGN ,@BODY) (SETQ STATUS :CLOSED)))) (DEFMETHOD (MAP-STREAM-MIXIN :CLOSE) (&OPTIONAL IGNORE) (AND RQB (RETURN-DISK-RQB RQB)) (SETQ RQB NIL)) (DEFFLAVOR MAP-INPUT-STREAM-MIXIN () (MAP-STREAM-MIXIN) (:INCLUDED-FLAVORS SI:BUFFERED-INPUT-STREAM)) (DEFFLAVOR MAP-OUTPUT-STREAM-MIXIN () (MAP-STREAM-MIXIN) (:INCLUDED-FLAVORS SI:BUFFERED-OUTPUT-STREAM)) (DEFMETHOD (MAP-INPUT-STREAM-MIXIN :NEXT-INPUT-BUFFER) (&OPTIONAL IGNORE) (COND ((EQ STATUS :CLOSED) (FERROR NIL "Attempt to get input from ~S, which is closed." SELF))) (LET ((MAP-NBLOCKS (MAP-NBLOCKS MAP)) SIZE) (COND ((< MAP-INDEX MAP-NBLOCKS) (SETQ STATUS :OPEN) ;May have been at :EOF (SETQ SIZE (MAP-BLOCK-SIZE MAP MAP-INDEX) RQB-VALID-PAGES (CEILING SIZE PAGE-SIZE-IN-BITS)) (LM-DISK-READ RQB (MAP-BLOCK-LOCATION MAP MAP-INDEX) RQB-VALID-PAGES) (VALUES (GET-RQB-ARRAY RQB BYTE-SIZE) 0 (FLOOR SIZE BYTE-SIZE))) ;; If we're out of range, simply call it an :EOF. (T (SETQ STATUS :EOF) NIL)))) ;; This doesn't really discard the buffer (why bother), but does increment ;; the buffer pointer for the next :NEXT-INPUT-BUFFER message. (DEFMETHOD (MAP-INPUT-STREAM-MIXIN :DISCARD-INPUT-BUFFER) (IGNORE) (INCF MAP-INDEX)) ;; This message would work, but would not do anything near what ;; the user would want -- it would just use up more disk space. (DEFMETHOD (MAP-OUTPUT-STREAM-MIXIN :FORCE-OUTPUT) IGNORE) (DEFMETHOD (MAP-OUTPUT-STREAM-MIXIN :NEW-OUTPUT-BUFFER) (&AUX LOC) (COND ((EQ STATUS :CLOSED) (FERROR NIL "Attempt to do output on ~S, which is closed." SELF))) (IF (= MAP-INDEX (MAP-NBLOCKS MAP)) ;; At end: add a new block. (PROGN (MULTIPLE-VALUE (LOC RQB-VALID-PAGES) (ALLOCATE-DISK-BLOCK)) (MAP-APPEND-BLOCK MAP LOC 0) (VALUES (GET-RQB-ARRAY RQB BYTE-SIZE) 0 (FLOOR (* RQB-VALID-PAGES PAGE-SIZE-IN-BITS) BYTE-SIZE))) ;; In the middle: read contents of next existing block ;; so that we can change only the bytes actually output. (LET ((SIZE (MAP-BLOCK-SIZE MAP MAP-INDEX))) (SETQ RQB-VALID-PAGES (CEILING SIZE PAGE-SIZE-IN-BITS)) (LM-DISK-READ RQB (MAP-BLOCK-LOCATION MAP MAP-INDEX) RQB-VALID-PAGES) (VALUES (GET-RQB-ARRAY RQB BYTE-SIZE) 0 (FLOOR SIZE BYTE-SIZE))))) ;; The :NEW-OUTPUT-BUFFER method gets the old data, so this has nothing to do. (DEFMETHOD (MAP-OUTPUT-STREAM-MIXIN :GET-OLD-DATA) (&REST IGNORE) NIL) (DEFMETHOD (MAP-OUTPUT-STREAM-MIXIN :SEND-OUTPUT-BUFFER) (BUFFER TO-INDEX) (OR (AND (ARRAY-INDIRECT-P BUFFER) (EQ (%P-CONTENTS-OFFSET BUFFER (1+ (%P-LDB-OFFSET %%ARRAY-LONG-LENGTH-FLAG BUFFER 0))) RQB)) (FERROR NIL "Attempt to :SEND-OUTPUT-BUFFER ~S, which is not indirected into ~S" BUFFER RQB)) (LET* ((LOC (MAP-BLOCK-LOCATION MAP MAP-INDEX)) (SIZE-FROM-INDEX (* TO-INDEX BYTE-SIZE)) (SIZE (MAX SIZE-FROM-INDEX (MAP-BLOCK-SIZE MAP MAP-INDEX))) (USED-NPAGES (CEILING SIZE PAGE-SIZE-IN-BITS))) (WHEN (PLUSP SIZE) (LM-DISK-WRITE RQB LOC USED-NPAGES) (WHEN (< (MAP-BLOCK-SIZE MAP MAP-INDEX) SIZE-FROM-INDEX) ;NECESSARY NOW? (SETF (MAP-BLOCK-SIZE MAP MAP-INDEX) SIZE-FROM-INDEX)) (INCF MAP-INDEX)) (WHEN (AND ( USED-NPAGES RQB-VALID-PAGES) (NULL (AND (TYPEP SELF 'LM-OUTPUT-STREAM-MIXIN) (FUNCALL-SELF :KEEP-RESERVED-BLOCKS)))) (USING-PUT (CHANGE-BLOCK-DISK-SPACE (+ LOC USED-NPAGES) (- RQB-VALID-PAGES USED-NPAGES) PUT-RESERVED PUT-FREE) ;; Try to minimize small holes by backing up the search pointer. (SETQ PUT-SCANNING-INDEX (+ LOC USED-NPAGES))) (WHEN (ZEROP SIZE) (DECF (MAP-NBLOCKS MAP)))))) (DEFMETHOD (MAP-OUTPUT-STREAM-MIXIN :MAYBE-UPDATE-MAP-BLOCK-SIZE) (CHAR-INDEX) (AND MAP ;Don't do anything if stream closed (LET ((CHAR-BITS (* CHAR-INDEX BYTE-SIZE))) (WHEN (< (MAP-BLOCK-SIZE MAP MAP-INDEX) CHAR-BITS) (SETF (MAP-BLOCK-SIZE MAP MAP-INDEX) CHAR-BITS))))) (DEFMETHOD (MAP-OUTPUT-STREAM-MIXIN :CURRENT-LENGTH-FROM-MAP) () (AND MAP (// (MAP-LENGTH MAP) BYTE-SIZE))) ; RETURN MAP-INDEX IF FILE IS EMPTY OR MAP-INDEX POINTS TO LAST BLOCK (DEFMETHOD (MAP-OUTPUT-STREAM-MIXIN :LAST-BLOCK-P) () (LET ((MAP-NBLOCKS (MAP-NBLOCKS MAP))) (WHEN (OR (ZEROP MAP-NBLOCKS) (= MAP-NBLOCKS (1+ MAP-INDEX))) MAP-INDEX))) (DEFMETHOD (MAP-OUTPUT-STREAM-MIXIN :MAP-NBLOCKS) () (AND MAP (MAP-NBLOCKS MAP))) (DEFMETHOD (MAP-OUTPUT-STREAM-MIXIN :UPDATE-RQB-VALID-PAGES) (BYTES) (SETQ RQB-VALID-PAGES (CEILING (* BYTES BYTE-SIZE) PAGE-SIZE-IN-BITS))) ; RETURN NIL IF MAP IS EMPTY (DEFMETHOD (MAP-OUTPUT-STREAM-MIXIN :SET-MAP-FOR-APPEND) (&OPTIONAL APPEND-NEW-BLOCK) (LET ((BLOCKS (MAP-NBLOCKS MAP))) (COND ((NOT (PLUSP BLOCKS)) ;file is empty (SETQ MAP-INDEX 0) NIL) (T (SETQ MAP-INDEX (IF APPEND-NEW-BLOCK BLOCKS (1- BLOCKS))))))) (DEFMETHOD (MAP-OUTPUT-STREAM-MIXIN :MAX-BYTES-IN-BLOCK) (&OPTIONAL (BLOCK MAP-INDEX)) (COND ((ZEROP (MAP-NBLOCKS MAP)) 0) (T (LET* ((PAGES-IN-BLOCK (CEILING (MAP-BLOCK-SIZE MAP BLOCK) PAGE-SIZE-IN-BITS)) (BYTES-IN-BLOCK (CEILING (* PAGES-IN-BLOCK PAGE-SIZE-IN-BITS) BYTE-SIZE))) (MAX BYTES-IN-BLOCK (IF RQB-VALID-PAGES (CEILING (* RQB-VALID-PAGES PAGE-SIZE-IN-BITS) BYTE-SIZE) 0)))))) (DEFMETHOD (MAP-OUTPUT-STREAM-MIXIN :BYTES-IN-BLOCK) (&OPTIONAL (BLOCK MAP-INDEX)) (COND ((ZEROP (MAP-NBLOCKS MAP)) 0) (T (CEILING (MAP-BLOCK-SIZE MAP BLOCK) BYTE-SIZE)))) (DEFMETHOD (MAP-OUTPUT-STREAM-MIXIN :DISCARD-OUTPUT-BUFFER) (BUFFER) (SEND SELF :SEND-OUTPUT-BUFFER BUFFER 0)) ;These flavors are not used. ;(DEFFLAVOR MAP-INPUT-STREAM ; () ; (MAP-INPUT-STREAM-MIXIN SI:BUFFERED-INPUT-STREAM)) ; ;(DEFFLAVOR MAP-OUTPUT-STREAM ; () ; (MAP-OUTPUT-STREAM-MIXIN SI:BUFFERED-OUTPUT-STREAM)) ;; The next two flavors are used internally by the file system. (DEFFLAVOR MAP-CHARACTER-INPUT-STREAM () (MAP-INPUT-STREAM-MIXIN SI:BUFFERED-LINE-INPUT-STREAM)) (DEFFLAVOR MAP-CHARACTER-OUTPUT-STREAM () (MAP-OUTPUT-STREAM-MIXIN SI:BUFFERED-OUTPUT-CHARACTER-STREAM)) (DEFMETHOD (MAP-CHARACTER-OUTPUT-STREAM :MAP) () MAP) ;; The next flavor is for input streams opened in an odd byte size. (DEFFLAVOR ODD-BYTE-SIZE-MIXIN () () (:REQUIRED-FLAVORS SI:MAP-INPUT-STREAM-MIXIN)) (DEFWRAPPER (ODD-BYTE-SIZE-MIXIN :NEXT-INPUT-BUFFER) ((&OPTIONAL IGNORE) . BODY) (LET ((VAL1 (GENTEMP)) (VAL2 (GENTEMP)) (VAL3 (GENTEMP)) (I (GENTEMP))) `(MULTIPLE-VALUE-PROG1 (,VAL1 ,VAL2 ,VAL3) (PROGN . ,BODY) (COND (,VAL1 (LOOP FOR ,I FROM ,VAL2 BELOW ,VAL3 DO (ASET (LDB BYTE-SIZE (AREF ,VAL1 ,I)) ,VAL1 ,I)))) (VALUES ,VAL1 ,VAL2 ,VAL3)))) (DEFFLAVOR LM-STREAM-MIXIN (TRUENAME) (SI:PROPERTY-LIST-MIXIN SI:FILE-STREAM-MIXIN) (:GETTABLE-INSTANCE-VARIABLES TRUENAME) (:INIT-KEYWORDS :FILE :APPEND :TRUENAME :IF-EXISTS)) (DEFMETHOD (LM-STREAM-MIXIN :INIT) (PLIST) (LET ((FILE (GET PLIST :FILE))) (IF FILE (SETQ TRUENAME (FILE-TRUENAME FILE) SI:PROPERTY-LIST (LMFS-FILE-PROPERTIES FILE)) (SETQ TRUENAME (GET PLIST :TRUENAME))))) (DEFMETHOD (LM-STREAM-MIXIN :QFASLP) () (GET (LOCF SI:PROPERTY-LIST) :QFASLP)) ;; For probes, assume you really mean :LENGTH-IN-BYTES (DEFMETHOD (LM-STREAM-MIXIN :LENGTH) () (GET (LOCF SI:PROPERTY-LIST) :LENGTH-IN-BYTES)) (DEFMETHOD (LM-STREAM-MIXIN :PROPERTIES) (&OPTIONAL ERROR-P) ERROR-P ; would be quite hard to get an error here (VALUES (CONS TRUENAME SI:PROPERTY-LIST) LM-UNSETTABLE-PROPERTIES)) (DEFFLAVOR LM-DATA-STREAM-MIXIN (FILE) (LM-STREAM-MIXIN) (:INCLUDED-FLAVORS MAP-STREAM-MIXIN) (:INITABLE-INSTANCE-VARIABLES FILE)) (DEFMETHOD (LM-DATA-STREAM-MIXIN :STATUS) () STATUS) (DEFMETHOD (LM-DATA-STREAM-MIXIN :DELETE) (&OPTIONAL (ERROR-P T)) (IDENTIFY-FILE-OPERATION :DELETE (HANDLING-ERRORS ERROR-P (LMFS-DELETE-FILE FILE)))) (DEFMETHOD (LM-DATA-STREAM-MIXIN :RENAME) (NEW-NAME &OPTIONAL (ERROR-P T)) (IDENTIFY-FILE-OPERATION :RENAME (HANDLING-ERRORS ERROR-P (LMFS-RENAME-FILE FILE (PATHNAME-DIRECTORY NEW-NAME) (PATHNAME-NAME NEW-NAME) (PATHNAME-TYPE NEW-NAME) (PATHNAME-VERSION NEW-NAME))) (SETQ TRUENAME (FILE-TRUENAME FILE)))) (DEFMETHOD (LM-DATA-STREAM-MIXIN :CHANGE-PROPERTIES) (ERROR-P &REST PROPERTIES) (IDENTIFY-FILE-OPERATION :CHANGE-PROPERTIES (HANDLING-ERRORS ERROR-P (LMFS-CHANGE-FILE-PROPERTIES FILE PROPERTIES)))) (DEFMETHOD (LM-DATA-STREAM-MIXIN :INIT) (IGNORE) (SETQ MAP (FILE-MAP FILE) TRUENAME (FILE-TRUENAME FILE) SI:PROPERTY-LIST (LMFS-FILE-PROPERTIES FILE)) (WITHOUT-INTERRUPTS (SETQ LM-FILE-STREAMS-LIST (CONS-IN-AREA SELF LM-FILE-STREAMS-LIST LOCAL-FILE-SYSTEM-AREA)))) (DEFMETHOD (LM-DATA-STREAM-MIXIN :SET-BUFFER-POINTER) (NEW-POINTER) (DO ((NBLOCKS (MAP-NBLOCKS MAP)) (I 0 (1+ I)) (P 0 P1) (P1)) (NIL) (COND ((OR ( I NBLOCKS) (> (SETQ P1 (+ P (FLOOR (MAP-BLOCK-SIZE MAP I) BYTE-SIZE))) NEW-POINTER)) (SETQ MAP-INDEX I) (RETURN P))))) (DEFMETHOD (LM-DATA-STREAM-MIXIN :SET-BUFFER-POINTER-TO-END) () (WHEN (PLUSP (MAP-NBLOCKS MAP)) (SETQ MAP-INDEX (1- (MAP-NBLOCKS MAP))) (- (FUNCALL-SELF :LENGTH) (// (MAP-BLOCK-SIZE MAP MAP-INDEX) BYTE-SIZE)))) (DEFMETHOD (LM-DATA-STREAM-MIXIN :BYTES-BEFORE-CURRENT-BLOCK) () (LOOP FOR SIZE = 0 THEN (+ SIZE (FLOOR (MAP-BLOCK-SIZE MAP COUNT) BYTE-SIZE)) FOR COUNT = 0 THEN (1+ COUNT) UNTIL (= COUNT MAP-INDEX) FINALLY (RETURN SIZE))) (DEFFLAVOR LM-INPUT-STREAM-MIXIN () (LM-DATA-STREAM-MIXIN SI:INPUT-FILE-STREAM-MIXIN) (:INCLUDED-FLAVORS MAP-STREAM-MIXIN)) (DEFFLAVOR LM-OUTPUT-STREAM-MIXIN (APPEND-OR-OVERWRITE KEEP-RESERVED-BLOCKS) (LM-DATA-STREAM-MIXIN SI:OUTPUT-FILE-STREAM-MIXIN) (:INCLUDED-FLAVORS MAP-STREAM-MIXIN) (:REQUIRED-FLAVORS SI:OUTPUT-POINTER-REMEMBERING-MIXIN) (:GETTABLE-INSTANCE-VARIABLES APPEND-OR-OVERWRITE KEEP-RESERVED-BLOCKS)) (DEFMETHOD (LM-INPUT-STREAM-MIXIN :AFTER :CLOSE) (&OPTIONAL IGNORE) (LET ((DEFAULT-CONS-AREA LOCAL-FILE-SYSTEM-AREA)) (LMFS-CLOSE-FILE FILE) (WITHOUT-INTERRUPTS (SETQ LM-FILE-STREAMS-LIST (DELQ SELF LM-FILE-STREAMS-LIST))) (SETQ FILE NIL MAP NIL))) ;Remove pointers into temp area. ;; For input streams, :LENGTH may be different from :LENGTH-IN-BYTES (DEFMETHOD (LM-INPUT-STREAM-MIXIN :LENGTH) () (FLOOR (* (GET (LOCF SI:PROPERTY-LIST) :LENGTH-IN-BYTES) (GET (LOCF SI:PROPERTY-LIST) :BYTE-SIZE)) BYTE-SIZE)) (DEFMETHOD (LM-OUTPUT-STREAM-MIXIN :AFTER :INIT) (INIT-PLIST) (SETQ KEEP-RESERVED-BLOCKS T) (LET ((IF-EXISTS (GET INIT-PLIST :IF-EXISTS))) (CASE IF-EXISTS (:APPEND (SETQ APPEND-OR-OVERWRITE :APPEND) (USING-PUT (CHANGE-MAP-DISK-SPACE MAP PUT-USED PUT-RESERVED)) (FUNCALL-SELF :SETUP-BUFFER-FOR-APPEND)) (:OVERWRITE (SETQ APPEND-OR-OVERWRITE :OVERWRITE) (USING-PUT (CHANGE-MAP-DISK-SPACE MAP PUT-USED PUT-RESERVED)) (FUNCALL-SELF :SETUP-BUFFER-FOR-APPEND) (FUNCALL-SELF :SET-POINTER :START)) (T (SETQ APPEND-OR-OVERWRITE NIL))))) (DEFMETHOD (LM-OUTPUT-STREAM-MIXIN :LENGTH) () (WHEN SI:STREAM-OUTPUT-BUFFER (FUNCALL-SELF :MAYBE-UPDATE-MAP-BLOCK-SIZE SI:STREAM-OUTPUT-INDEX)) (FUNCALL-SELF :CURRENT-LENGTH-FROM-MAP)) (DEFMETHOD (LM-OUTPUT-STREAM-MIXIN :BEFORE :CLOSE) (&OPTIONAL ABORTP) ABORTP (LET ((LEN (FUNCALL-SELF :LENGTH))) (SETQ KEEP-RESERVED-BLOCKS NIL) (WHEN (PLUSP LEN) (FUNCALL-SELF :SET-POINTER LEN)))) (DEFMETHOD (LM-OUTPUT-STREAM-MIXIN :AFTER :CLOSE) (&OPTIONAL ABORTP) (LET ((DEFAULT-CONS-AREA LOCAL-FILE-SYSTEM-AREA)) (COND ((AND ABORTP (NOT (FILE-CLOSED? FILE)) (NOT APPEND-OR-OVERWRITE)) (SETF (FILE-DELETED? FILE) T) (LMFS-EXPUNGE-FILE FILE) (WRITE-DIRECTORY-FILES (FILE-DIRECTORY FILE))) (T (LMFS-CLOSE-FILE FILE))) (WITHOUT-INTERRUPTS (SETQ LM-FILE-STREAMS-LIST (DELQ SELF LM-FILE-STREAMS-LIST))) (SETQ FILE NIL MAP NIL))) ;Remove pointers into temp area. (DEFFLAVOR LM-INPUT-STREAM () (LM-INPUT-STREAM-MIXIN MAP-INPUT-STREAM-MIXIN SI:BUFFERED-INPUT-STREAM)) (DEFFLAVOR LM-OUTPUT-STREAM () (LM-OUTPUT-STREAM-MIXIN MAP-OUTPUT-STREAM-MIXIN SI:BUFFERED-OUTPUT-STREAM)) (DEFFLAVOR LM-IO-STREAM () (SI:IO-STREAM-INPUT-MIXIN LM-OUTPUT-STREAM)) (DEFFLAVOR LM-CHARACTER-INPUT-STREAM () (LM-INPUT-STREAM-MIXIN MAP-INPUT-STREAM-MIXIN SI:BUFFERED-INPUT-CHARACTER-STREAM)) (DEFFLAVOR LM-CHARACTER-OUTPUT-STREAM () (LM-OUTPUT-STREAM-MIXIN MAP-OUTPUT-STREAM-MIXIN SI:BUFFERED-OUTPUT-CHARACTER-STREAM)) (DEFFLAVOR LM-CHARACTER-IO-STREAM () (SI:IO-STREAM-INPUT-MIXIN LM-CHARACTER-OUTPUT-STREAM)) (DEFFLAVOR LM-PROBE-STREAM () (LM-STREAM-MIXIN SI:STREAM) ;; Kludge so that OPEN can pass this a :BYTE-SIZE :DEFAULT (:INIT-KEYWORDS :BYTE-SIZE)) (DEFMETHOD (LM-PROBE-STREAM :STATUS) () :CLOSED) (DEFMETHOD (LM-PROBE-STREAM :DIRECTION) () NIL) (DEFMETHOD (LM-PROBE-STREAM :BYTE-SIZE) () (GETF SI:PROPERTY-LIST :BYTE-SIZE)) (COMPILE-FLAVOR-METHODS ;MAP-INPUT-STREAM MAP-OUTPUT-STREAM MAP-CHARACTER-INPUT-STREAM MAP-CHARACTER-OUTPUT-STREAM LM-INPUT-STREAM LM-OUTPUT-STREAM LM-CHARACTER-INPUT-STREAM LM-CHARACTER-OUTPUT-STREAM LM-PROBE-STREAM) (DEFUN MAKE-MAP-STREAM (FLAVOR &REST INIT-PLIST) (INSTANTIATE-FLAVOR FLAVOR (LOCF INIT-PLIST) NIL NIL LOCAL-FILE-SYSTEM-AREA)) (DEFUN MAKE-MAP-STREAM-IN (MAP) (MAKE-MAP-STREAM 'MAP-CHARACTER-INPUT-STREAM :MAP MAP)) (DEFUN MAKE-MAP-STREAM-OUT () (MAKE-MAP-STREAM 'MAP-CHARACTER-OUTPUT-STREAM :MAP (MAP-CREATE 4))) ;Internal things tend to be small. ;; A simple stream for reading and writing the disk configuration. ;; DISK-CONFIGURATION-BUFFER-POINTER must be bound for this stream to work. (DEFSELECT (DISK-CONFIGURATION-STREAM DISK-CONFIGURATION-STREAM-DEFAULT) (:TYI (&OPTIONAL IGNORE) (AREF DISK-CONFIGURATION-BUFFER (PROG1 DISK-CONFIGURATION-BUFFER-POINTER (INCF DISK-CONFIGURATION-BUFFER-POINTER)))) (:UNTYI (CHAR) (DECF DISK-CONFIGURATION-BUFFER-POINTER) CHAR) (:TYO (CHAR) (ASET CHAR DISK-CONFIGURATION-BUFFER (PROG1 DISK-CONFIGURATION-BUFFER-POINTER (INCF DISK-CONFIGURATION-BUFFER-POINTER))))) (DEFUN DISK-CONFIGURATION-STREAM-DEFAULT (OP &OPTIONAL ARG1 &REST ARGS) (STREAM-DEFAULT-HANDLER #'DISK-CONFIGURATION-STREAM OP ARG1 ARGS))