1 ;;;; some stuff for displaying information for debugging/experimenting
2 ;;;; with the system, mostly conditionalized with #!+SB-SHOW
4 ;;;; This software is part of the SBCL system. See the README file for
7 ;;;; This software is derived from the CMU CL system, which was
8 ;;;; written at Carnegie Mellon University and released into the
9 ;;;; public domain. The software is in the public domain and is
10 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
11 ;;;; files for more information.
15 ;;;; various SB-SHOW-dependent forms
17 ;;;; In general, macros named /FOO
18 ;;;; * are for debugging/tracing
19 ;;;; * expand into nothing unless :SB-SHOW is in the target
21 ;;;; Often, they also do nothing at runtime if */SHOW* is NIL, but
22 ;;;; this is not always true for some very-low-level ones.
24 ;;;; (I follow the "/FOO for debugging/tracing expressions" naming
25 ;;;; rule and several other naming conventions in all my Lisp
26 ;;;; programming when possible, and then set Emacs to display comments
27 ;;;; in one shade of blue, tracing expressions in another shade of
28 ;;;; blue, and declarations and assertions in a yellowish shade, so
29 ;;;; that it's easy to separate them from the "real code" which
30 ;;;; actually does the work of the program. -- WHN 2001-05-07)
32 ;;; Set this to NIL to suppress output from /SHOW-related forms.
33 #!+sb-show
(defvar */show
* t
)
36 (defun cannot-/show
(string)
37 (declare (type simple-string string
))
38 #+sb-xc-host
(error "can't /SHOW: ~A" string
)
39 ;; We end up in this situation when we execute /SHOW too early in
40 ;; cold init. That happens to me often enough that it's really
41 ;; annoying for it to cause a hard failure -- which at that point is
42 ;; hard to recover from -- instead of just diagnostic output.
44 (progn (%primitive print
45 (concatenate 'simple-base-string
46 "/can't /SHOW:" (the simple-base-string string
)))
49 ;;; Should /SHOW output be suppressed at this point?
51 ;;; Note that despite the connoting-no-side-effects-pure-predicate
52 ;;; name, we emit some error output if we're called at a point where
53 ;;; /SHOW is inherently invalid.
55 (defun suppress-/show-p
()
56 ;; protection against /SHOW too early in cold init for
57 ;; (FORMAT *TRACE-OUTPUT* ..) to work, part I: Obviously
58 ;; we need *TRACE-OUTPUT* bound.
59 (if (not (boundp '*trace-output
*))
60 (cannot-/show
"*TRACE-OUTPUT* isn't bound. (Try /SHOW0.)")
61 ;; ordinary, healthy reason to suppress /SHOW, no error
62 ;; output needed. Assume by default _not_ to suppress.
63 (and (boundp '*/show
*) (not */show
*))))
65 ;;; shorthand for a common idiom in output statements used in
66 ;;; debugging: (/SHOW "Case 2:" X Y) becomes a pretty-printed version
67 ;;; of (FORMAT .. "~&/Case 2: X=~S Y=~S~%" X Y), conditional on */SHOW*.
68 (defmacro /show
(&rest xlist
)
69 #!-sb-show
(declare (ignore xlist
))
71 (flet (;; Is X something we want to just show literally by itself?
72 ;; (instead of showing it as NAME=VALUE)
73 (literal-p (x) (or (stringp x
) (numberp x
))))
74 ;; We build a FORMAT statement out of what we find in XLIST.
75 (let ((format-stream (make-string-output-stream)) ; string arg to FORMAT
76 (format-reverse-rest) ; reversed &REST argument to FORMAT
77 (first-p t
)) ; first pass through loop?
78 (write-string "~&~<~;/" format-stream
)
82 (write-string #+ansi-cl
" ~_"
83 #-ansi-cl
" " ; for CLISP (CLTL1-ish)
86 (princ x format-stream
)
87 (progn (let ((*print-pretty
* nil
))
88 (format format-stream
"~S=~~S" x
))
89 (push x format-reverse-rest
))))
90 (write-string "~;~:>~%" format-stream
)
91 (let ((format-string (get-output-stream-string format-stream
))
92 (format-rest (reverse format-reverse-rest
)))
94 (declare (optimize (speed 1) (space 2) (safety 3)))
95 (unless (suppress-/show-p
)
96 (format *trace-output
*
98 #+ansi-cl
(list ,@format-rest
)
99 #-ansi-cl
,@format-rest
)) ; for CLISP (CLTL1-ish)
102 ;;; a disabled-at-compile-time /SHOW, implemented as a macro instead
103 ;;; of a function so that leaving occasionally-useful /SHOWs in place
104 ;;; but disabled incurs no run-time overhead and works even when the
105 ;;; arguments can't be evaluated (e.g. because they're only meaningful
106 ;;; in a debugging version of the system, or just due to bit rot..)
107 (defmacro /noshow
(&rest rest
)
108 (declare (ignore rest
)))
110 ;;; like /SHOW, except displaying values in hexadecimal
111 (defmacro /xhow
(&rest rest
)
112 `(let ((*print-base
* 16))
114 (defmacro /noxhow
(&rest rest
)
115 (declare (ignore rest
)))
117 ;;; a trivial version of /SHOW which only prints a constant string,
118 ;;; implemented at a sufficiently low level that it can be used early
121 ;;; Unlike the other /SHOW-related functions, this one doesn't test
122 ;;; */SHOW* at runtime, because messing with special variables early
123 ;;; in cold load is too much trouble to be worth it.
124 (defmacro /show0
(&rest string-designators
)
125 ;; We can't use inline MAPCAR here because, at least in 0.6.11.x,
126 ;; this code gets compiled before DO-ANONYMOUS is defined.
127 ;; Similarly, we don't use inline CONCATENATE, because some of the
128 ;; machinery behind its optimizations isn't available in the
130 (declare (notinline mapcar concatenate
))
131 (let ((s (apply #'concatenate
133 (mapcar #'string string-designators
))))
134 (declare (ignorable s
)) ; (for when #!-SB-SHOW)
135 #+sb-xc-host
`(/show
,s
)
139 ,(concatenate 'simple-string
"/" s
)))))
140 (defmacro /noshow0
(&rest rest
)
141 (declare (ignore rest
)))
143 ;;; low-level display of a string, works even early in cold init
144 (defmacro /primitive-print
(thing)
145 (declare (ignorable thing
)) ; (for when #!-SB-SHOW)
148 #+sb-xc-host
`(/show
"(/primitive-print)" ,thing
)
149 #-sb-xc-host
`(%primitive print
(the simple-string
,thing
))))
151 ;;; low-level display of a system word, works even early in cold init
152 (defmacro /hexstr
(thing)
153 (declare (ignorable thing
)) ; (for when #!-SB-SHOW)
156 #+sb-xc-host
`(/show
"(/hexstr)" ,thing
)
157 #-sb-xc-host
`(%primitive print
(hexstr ,thing
))))
159 (defmacro /nohexstr
(thing)
160 (declare (ignore thing
)))
162 (/show0
"done with show.lisp")