source: trunk/abcl/src/org/armedbear/lisp/describe.lisp

Last change on this file was 15569, checked in by Mark Evenson, 2 years ago

Untabify en masse

Results of running style.org source blocks on tree

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.2 KB
Line 
1;;; describe.lisp
2;;;
3;;; Copyright (C) 2005 Peter Graves
4;;; $Id: describe.lisp 15569 2022-03-19 12:50:18Z mevenson $
5;;;
6;;; This program is free software; you can redistribute it and/or
7;;; modify it under the terms of the GNU General Public License
8;;; as published by the Free Software Foundation; either version 2
9;;; of the License, or (at your option) any later version.
10;;;
11;;; This program is distributed in the hope that it will be useful,
12;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with this program; if not, write to the Free Software
18;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19;;;
20;;; As a special exception, the copyright holders of this library give you
21;;; permission to link this library with independent modules to produce an
22;;; executable, regardless of the license terms of these independent
23;;; modules, and to copy and distribute the resulting executable under
24;;; terms of your choice, provided that you also meet, for each linked
25;;; independent module, the terms and conditions of the license of that
26;;; module.  An independent module is a module which is not derived from
27;;; or based on this library.  If you modify this library, you may extend
28;;; this exception to your version of the library, but you are not
29;;; obligated to do so.  If you do not wish to do so, delete this
30;;; exception statement from your version.
31
32(in-package #:system)
33
34(require '#:clos)
35(require '#:format)
36
37(defun describe-arglist (object stream)
38  (multiple-value-bind
39      (arglist known-p)
40      (arglist object)
41    (when known-p
42      (format stream "~&The function's lambda list is:~%  ~A~%" arglist))))
43
44(defun %describe-object (object stream)
45  (format stream "~S is an object of type ~S.~%" object (type-of object)))
46
47(defun describe (object &optional stream)
48  (describe-object object (out-synonym-of stream))
49  (values))
50
51(defmethod describe-object ((object t) stream)
52  (let ((*print-pretty* t))
53    (typecase object
54      (SYMBOL
55       (let ((package (symbol-package object)))
56         (if package
57             (multiple-value-bind
58                 (sym status)
59                 (find-symbol (symbol-name object) package)
60               (format stream "~S is an ~A symbol in the ~A package.~%"
61                       object
62                       (if (eq status :internal) "internal" "external")
63                       (package-name package)))
64             (format stream "~S is an uninterned symbol.~%" object))
65         (cond ((special-variable-p object)
66                (format stream "It is a ~A; "
67                        (if (constantp object) "constant" "special variable"))
68                (if (boundp object)
69                    (format stream "its value is ~S.~%" (symbol-value object))
70                    (format stream "it is unbound.~%")))
71               ((boundp object)
72                (format stream "It is an undefined variable; its value is ~S.~%"
73                        (symbol-value object)))))
74       (when (autoloadp object)
75         (resolve object))
76       (let ((function (and (fboundp object) (symbol-function object))))
77         (when function
78           (format stream "Its function binding is ~S.~%" function)
79           (describe-arglist function stream)))
80       (let ((doc (documentation object 'function)))
81         (when doc
82           (format stream "Function documentation:~%  ~A~%" doc)))
83       (let ((doc (documentation object 'variable)))
84         (when doc
85           (format stream "Variable documentation:~%  ~A~%" doc)))
86       (let ((plist (symbol-plist object)))
87         (when plist
88           (format stream "The symbol's property list contains these indicator/value pairs:~%")
89           (loop
90             (when (null plist) (return))
91             (format stream "  ~S ~S~%" (car plist) (cadr plist))
92             (setf plist (cddr plist))))))
93      (FUNCTION
94       (%describe-object object stream)
95       (describe-arglist object stream)
96       (let ((function-symbol (nth-value 2 (function-lambda-expression object))))
97         (if (and (consp function-symbol) (eq (car function-symbol) 'macro-function))
98             (setq function-symbol (second function-symbol)))
99         (when  function-symbol
100           (let ((doc (documentation function-symbol 'function)))
101             (when doc
102               (format stream "Function documentation:~%  ~A~%" doc)))
103           )))
104      (INTEGER
105       (%describe-object object stream)
106       (format stream "~D.~%~
107                       #x~X~%~
108                       #o~O~%~
109                       #b~B~%"
110               object object object object))
111      (t
112       (%describe-object object stream))))
113  (values))
114
115(defmethod describe-object ((object pathname) stream)
116  (format stream "~S is an object of type ~S:~%" object (type-of object))
117  (format stream "  HOST         ~S~%" (pathname-host object))
118  (format stream "  DEVICE       ~S~%" (pathname-device object))
119  (format stream "  DIRECTORY    ~S~%" (pathname-directory object))
120  (format stream "  NAME         ~S~%" (pathname-name object))
121  (format stream "  TYPE         ~S~%" (pathname-type object))
122  (format stream "  VERSION      ~S~%" (pathname-version object)))
123
124(defun %describe-standard-object/funcallable (object stream)
125  (let* ((class (class-of object))
126         (slotds (mop:class-slots class))
127         (max-slot-name-length 0)
128         (instance-slotds ())
129         (class-slotds ()))
130    (format stream "~S is an instance of ~S.~%" object class)
131    (dolist (slotd slotds)
132      (let* ((name (mop:slot-definition-name slotd))
133             (length (length (symbol-name name))))
134        (when (> length max-slot-name-length)
135          (setf max-slot-name-length length)))
136      (case (mop:slot-definition-allocation slotd)
137        (:instance (push slotd instance-slotds))
138        (:class  (push slotd class-slotds))))
139    (setf max-slot-name-length  (min (+ max-slot-name-length 3) 30))
140    (flet ((describe-slot (slot-name)
141             (if (slot-boundp object slot-name)
142                 (format stream
143                         "~&  ~A~VT  ~S"
144                         slot-name max-slot-name-length (slot-value object slot-name))
145                 (format stream
146                         "~&  ~A~VT  unbound"
147                         slot-name max-slot-name-length))))
148      (when instance-slotds
149        (format stream "The following slots have :INSTANCE allocation:~%")
150        (dolist (slotd (nreverse instance-slotds))
151          (describe-slot
152           (mop:slot-definition-name slotd))))
153        (format stream "~%")
154      (when class-slotds
155        (format stream "The following slots have :CLASS allocation:~%")
156        (dolist (slotd (nreverse class-slotds))
157          (describe-slot
158           (mop:slot-definition-name slotd)))
159        (format stream "~%")))))
160
161(defmethod describe-object ((object standard-object) stream)
162  (%describe-standard-object/funcallable object stream)
163  (values))
164
165(defmethod describe-object ((object mop:funcallable-standard-object) stream)
166  (%describe-standard-object/funcallable object stream)
167  (values))
168
169(defmethod describe-object ((object java:java-object) stream)
170  (java:describe-java-object object stream))
Note: See TracBrowser for help on using the repository browser.