X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Finspect.lisp;h=43faa94fe68c658c73211895672d6c1b65011531;hb=b1b85bbf17f686a0787304a04cf0e01e8216d038;hp=71a07612059445bed646d0e73abdf3d3586fb8ae;hpb=e27303999070c06c788a0e1359ee4b0900186aa1;p=sbcl.git diff --git a/src/code/inspect.lisp b/src/code/inspect.lisp index 71a0761..43faa94 100644 --- a/src/code/inspect.lisp +++ b/src/code/inspect.lisp @@ -11,24 +11,28 @@ (in-package "SB-IMPL") ;(SB-IMPL, not SB!IMPL, since we're built in warm load.) -(declaim #.*optimize-byte-compilation*) - (defparameter *inspect-length* 10) ;;; When *INSPECT-UNBOUND-OBJECT-MARKER* occurs in a parts list, it ;;; indicates that that a slot is unbound. (defvar *inspect-unbound-object-marker* (gensym "INSPECT-UNBOUND-OBJECT-")) -(defun inspect (object) - (declare #.*optimize-external-despite-byte-compilation*) +(defun inspector (object input-stream output-stream) + (declare (ignore input-stream)) (catch 'quit-inspect - (%inspect object *standard-output*)) + (%inspect object output-stream)) (values)) +(defvar *inspect-fun* #'inspector + "a function of three arguments OBJECT, INPUT, and OUTPUT which starts an interactive inspector.") + (defvar *inspected*) (setf (documentation '*inspected* 'variable) "the value currently being inspected in CL:INSPECT") +(defun inspect (object) + (funcall *inspect-fun* object *standard-input* *standard-output*)) + (defvar *help-for-inspect* " help for INSPECT: @@ -44,23 +48,26 @@ evaluated expressions. ") (defun %inspect (*inspected* s) - (named-let redisplay () ; "lambda, the ultimate GOTO":-| + (named-let redisplay () ; "LAMBDA, the ultimate GOTO":-| (multiple-value-bind (description named-p elements) (inspected-parts *inspected*) (tty-display-inspected-parts description named-p elements s) (named-let reread () (format s "~&> ") (force-output) - (let (;; KMP idiom, using stream itself as EOF value - (command (read *standard-input* nil *standard-input*))) - (typecase command - (stream ; i.e. EOF + (let* (;; newly-consed object for hermetic protection against + ;; mischievous input like #.*EOF-OBJECT*: + (eof (cons *eof-object* nil)) + (command (read *standard-input* nil eof))) + (when (eq command eof) ;; currently-undocumented feature: EOF is handled as Q. ;; If there's ever consensus that this is *the* right ;; thing to do (as opposed to e.g. handling it as U), we ;; could document it. Meanwhile, it seems more Unix-y to ;; do this than to signal an error. + (/show0 "THROWing QUIT-INSPECT for EOF") (throw 'quit-inspect nil)) + (typecase command (integer (let ((elements-length (length elements))) (cond ((< -1 command elements-length) @@ -78,12 +85,13 @@ evaluated expressions. (format s "~%The object contains nothing to inspect.~%") (return-from %inspect (reread))) (t - (format s "~%Enter a valid index (~:[0-~D~;0~]).~%" + (format s "~%Enter a valid index (~:[0-~W~;0~]).~%" (= elements-length 1) (1- elements-length)) (return-from %inspect (reread)))))) (symbol (case (find-symbol (symbol-name command) *keyword-package*) ((:q :e) + (/show0 "THROWing QUIT-INSPECT for :Q or :E") (throw 'quit-inspect nil)) (:u (return-from %inspect)) @@ -147,7 +155,7 @@ evaluated expressions. (defgeneric inspected-parts (object)) (defmethod inspected-parts ((object symbol)) - (values (format nil "The object is a SYMBOL.~%" object) + (values (format nil "The object is a SYMBOL.~%") t (list (cons "Name" (symbol-name object)) (cons "Package" (symbol-package object)) @@ -164,7 +172,7 @@ evaluated expressions. (info (layout-info (sb-kernel:layout-of object)))) (when (sb-kernel::defstruct-description-p info) (dolist (dd-slot (dd-slots info) (nreverse parts-list)) - (push (cons (dsd-%name dd-slot) + (push (cons (dsd-name dd-slot) (funcall (dsd-accessor-name dd-slot) object)) parts-list))))) @@ -194,15 +202,21 @@ evaluated expressions. (values (format nil "The object is a FUNCALLABLE-INSTANCE of type ~S.~%" (type-of object)) t - (inspected-structure-elements object))) + (inspected-standard-object-elements object))) + +(defmethod inspected-parts ((object condition)) + (values (format nil "The object is a CONDITION of type ~S.~%" + (type-of object)) + t + (inspected-standard-object-elements object))) (defmethod inspected-parts ((object function)) - (let* ((type (sb-kernel:get-type object)) - (object (if (= type sb-vm:closure-header-type) - (sb-kernel:%closure-function object) + (let* ((type (sb-kernel:widetag-of object)) + (object (if (= type sb-vm:closure-header-widetag) + (sb-kernel:%closure-fun object) object))) (values (format nil "FUNCTION ~S.~@[~%Argument List: ~A~]." object - (sb-kernel:%function-arglist object) + (sb-kernel:%simple-fun-arglist object) ;; Defined-from stuff used to be here. Someone took ;; it out. FIXME: We should make it easy to get ;; to DESCRIBE from the inspector. @@ -212,7 +226,7 @@ evaluated expressions. (defmethod inspected-parts ((object vector)) (values (format nil - "The object is a ~:[~;displaced ~]VECTOR of length ~D.~%" + "The object is a ~:[~;displaced ~]VECTOR of length ~W.~%" (and (array-header-p object) (%array-displaced-p object)) (length object)) @@ -229,7 +243,7 @@ evaluated expressions. (multiple-value-bind (q r) (floor index dim) (setq index q) (push r list))) - (format nil "[~D~{,~D~}]" (car list) (cdr list))))) + (format nil "[~W~{,~W~}]" (car list) (cdr list))))) (defmethod inspected-parts ((object array)) (let* ((length (min (array-total-size object) *inspect-length*))