Changeset 745
- Timestamp:
- Mar 27, 2004, 2:58:39 AM (21 years ago)
- File:
-
- 1 edited
-
trunk/ccl/examples/cocoa-backtrace.lisp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ccl/examples/cocoa-backtrace.lisp
r654 r745 35 35 backtrace-window-controller) 36 36 #@"backtrace") 37 38 (define-objc-method ((:void close) 39 backtrace-window-controller) 40 (setf (slot-value self 'context) nil) 41 (send-super 'close)) 37 42 38 43 (defmethod our-frame-label-p ((self backtrace-window-controller) thing) … … 175 180 176 181 177 178 179 180 (defun backtrace-window-for-context (context) 181 (let* ((cont (make-instance 'backtrace-window-controller 182 :with-window-nib-name #@"backtrace" 183 :context context))) 184 (send cont :show-window nil) 185 cont)) 186 187 188 189 182 (defun backtrace-controller-for-context (context) 183 (or (bt.dialog context) 184 (setf (bt.dialog context) 185 (make-instance 'backtrace-window-controller 186 :with-window-nib-name #@"backtrace" 187 :context context)))) 188 189 #+debug 190 190 (define-objc-method ((:void will-load) 191 191 backtrace-window-controller) 192 192 (#_NSLog #@"will load %@" :address (send self 'window-nib-name))) 193 193 194 #+notyet 195 (progn 196 197 198 ;;;;;;; 199 ;; 200 ;; Interface to the break-loop 201 ;; 202 (defun select-backtrace (&aux (info (car ccl::*backtrace-dialogs*))) 203 (unless info (error "No context for backtrace")) 204 (if (ccl::bt.dialog info) 205 (window-select (ccl::bt.dialog info)) 206 (make-instance 'backtrace-window :info info 207 :window-title (format nil "Backtrace for ~A" 208 (process-name 209 (ccl::stack-group-process 210 (ccl::bt.sg info))))))) 211 212 213 ;; Interface to apply-in-nth-frame 214 (defmethod ccl::nth-frame ((w backtrace-window) target n) 215 (let ((error-frame (inspector-object (view-named 'stack-pane w)))) 216 (unless (eql target (stack-start error-frame)) 217 (error "Inconsistent args to nth-frame")) 218 (error-frame-n error-frame n))) 219 220 ;;;;;;; 221 ;; 222 ;; Interface to LOCAL 223 ;; 224 (defun ccl::names-in-frame (&optional (window (front-window :class 'backtrace-window))) 225 (when window 226 (let* ((view (inspector-view (view-named 'stack-frame-pane window))) 227 (inspector (inspector view)) 228 (lines (inspector-line-count inspector)) 229 res) 230 (dotimes (i lines) 231 (multiple-value-bind (val label) (cached-line-n view i) 232 (declare (ignore val)) 233 (push (cddr label) res))) 234 (nreverse res)))) 235 236 (defun ccl::nth-frame-info (n &optional (window (front-window :class 'backtrace-window))) 237 (when window 238 (let* ((view (inspector-view (view-named 'stack-frame-pane window)))) 239 (values (cached-line-n view n))))) 240 241 (defun ccl::set-nth-frame-value (n new-value) 242 (let ((window (front-window :class 'backtrace-window))) 243 (let* ((view (inspector-view (view-named 'stack-frame-pane window))) 244 (inspector (inspector view))) 245 (setf (line-n inspector n) new-value) 246 (resample view))) 247 new-value) 248 249 (defun ccl::frame-lfun (&optional (window (front-window :class 'backtrace-window))) 250 (when window 251 (let* ((inspector (inspector (view-named 'stack-frame-pane window))) 252 (info (frame-info inspector))) 253 (when info 254 (values (cadr info) (caddr info)))))) 255 256 ; Old inspector function that some folks were used to 257 (defun ccl::top-inspect-form () 258 (let ((w (front-window :class 'inspector-window))) 259 (and w (inspector-object w)))) 260 261 ;;;;;;; 262 ;; 263 ;; return-from and restart frame 264 ;; 265 266 267 (defun backtrace-return-from-frame (w) 268 (setq w (require-type w 'backtrace-window)) 269 (let* ((i (inspector (view-named 'stack-frame-pane w))) 270 (info (frame-info i)) 271 (sg (stack-group (inspector-object i))) 272 (frame (car info)) 273 (srv (ccl::frame-restartable-p frame sg))) 274 (if (not srv) 275 (ed-beep) ; Paranoia is a wonderful thing 276 (multiple-value-bind (value ok-button-p) (edit-value nil nil) 277 (when ok-button-p 278 (ccl::apply-in-frame-internal 279 sg 280 frame 281 #'values 282 (if (and (consp value) (eq (car value) 'values)) (cdr value) (list value)) 283 srv)))))) 284 285 (defun add-child-window (w child) 286 (view-put w :child-windows (push child (view-get w :child-windows)))) 287 288 (defun backtrace-restart-frame (w) 289 (setq w (require-type w 'backtrace-window)) 290 (let* ((inspector (inspector (view-named 'stack-frame-pane w))) 291 (info (frame-info inspector)) 292 (error-frame (inspector-object inspector)) 293 (sg (stack-group error-frame))) 294 (destructuring-bind (frame lfun pc child &rest rest) info 295 (declare (ignore rest)) 296 (multiple-value-bind (args types names count nclosed) 297 (ccl::frame-supplied-args frame lfun pc child sg) 298 (let* ((frame (car info)) 299 (srv (ccl::frame-restartable-p frame sg))) 300 (if (not (and (or (eq count t) (>= count nclosed)) frame srv)) 301 (ed-beep) 302 (let* ((name (function-name lfun)) 303 (f (ignore-errors (fboundp name)))) 304 (cond ((null f)) 305 ((eq (ccl::closure-function f) lfun) 306 (setq lfun name 307 args (nthcdr nclosed args) 308 types (nthcdr nclosed types) 309 names (nthcdr nclosed names) 310 nclosed 0)) 311 (f (setq lfun name))) 312 (let ((i (make-instance 'function-args-inspector 313 :stack-frame-inspector inspector 314 :restart-srv srv 315 :frame-to-restart frame 316 :object (cons lfun args) 317 :types types :names names :nclosed nclosed))) 318 (add-child-window w 319 (make-instance 'inspector-window 320 :inspector i :view-position '(:top 50))))))))))) 321 322 (defclass function-args-inspector (inspector) 323 ((types :initarg :types :accessor types) 324 (names :initarg :names :accessor names) 325 (nclosed :initarg :nclosed :accessor nclosed) 326 (stack-frame-inspector :initarg :stack-frame-inspector :reader stack-frame-inspector) 327 (frame-to-restart :initarg :frame-to-restart :reader frame-to-restart) 328 (restart-srv :initarg :restart-srv :reader restart-srv))) 329 330 (defmethod inspector-window-title ((i function-args-inspector)) 331 (format nil "Restart frame at #x~x" (ccl::index->address (frame-to-restart i)))) 332 333 (defmethod compute-line-count ((i function-args-inspector)) 334 (+ 3 (length (inspector-object i)))) 335 336 (defmethod line-n ((i function-args-inspector) n) 337 (let ((f&args (inspector-object i))) 338 (case n 339 (0 f&args) 340 (1 (values nil "Choose \"Restart\" from \"Commands\" menu when ready" 341 :comment)) 342 (2 (values (car f&args) "Function" :colon)) 343 (3 (values (ignore-errors (arglist (car f&args))) "Arglist: " :static)) 344 (t (decf n 4) 345 (let ((args (nthcdr n (cdr f&args))) 346 (type (nth n (types i))) 347 (name (nth n (names i)))) 348 (unless args (line-n-out-of-range i (+ n 4))) 349 (values (car args) (list n type name))))))) 350 351 (defmethod (setf line-n) (value (i function-args-inspector) n) 352 (flet ((install-new-function (i function) 353 (let ((arglist (arglist function)) 354 (types nil) 355 (names nil) 356 (type "required")) 357 (dolist (name arglist) 358 (cond ((eq name '&optional) (setq type "optional")) 359 ((memq name lambda-list-keywords) (return)) 360 (t (push type types) 361 (push name names)))) 362 (setf (types i) types 363 (names i) names) 364 (unless (eql 0 (nclosed i)) 365 (let ((f&args (inspector-object i))) 366 (setf (cdr f&args) (nthcdr (nclosed i) (cdr f&args)))) 367 (setf (nclosed i) 0))))) 368 (case n 369 (0 (if (ignore-errors 370 (and (listp value) (length value) (or (functionp (car value)) 371 (fboundp (car value))))) 372 (progn 373 (setf (inspector-object i) value) 374 (install-new-function i (car value)) 375 (resample-it)) 376 (ed-beep))) 377 ((1 3) (setf-line-n-out-of-range i n)) 378 (2 (if (ignore-errors (or (functionp value) (fboundp value))) 379 (progn 380 (setf (car (inspector-object i)) value) 381 (install-new-function i value) 382 (resample-it)) 383 (ed-beep))) 384 (t (decf n 4) 385 (let ((args (nthcdr n (cdr (inspector-object i))))) 386 (unless args (setf-line-n-out-of-range i (+ n 4))) 387 (setf (car args) value) 388 (resample-it)))))) 389 390 (defmethod prin1-label ((i function-args-inspector) stream value &optional label type) 391 (declare (ignore value type)) 392 (if (consp label) 393 (format stream "~d: " (car label)) 394 (call-next-method))) 395 396 (defmethod prin1-value ((i function-args-inspector) stream value &optional label type) 397 (declare (ignore type)) 398 (if (consp label) 399 (destructuring-bind (n type name) label 400 (declare (ignore n)) 401 (when name 402 (princ name stream) 403 (tyo #\space stream)) 404 (when type 405 (format stream "(~a) " type)))) 406 (prin1 value stream)) 407 408 409 (defmethod inspector-commands ((i function-args-inspector)) 410 (let ((res 411 `(("Restart " 412 ,#'(lambda () 413 (window-close (view-window (inspector-view i))) 414 (let* ((stack-frame-inspector (stack-frame-inspector i))) 415 (if (wptr (inspector-view stack-frame-inspector)) 416 (let* ((frame (frame-to-restart i)) 417 (srv (restart-srv i)) 418 (f&args (inspector-object i)) 419 (sg (stack-group (inspector-object stack-frame-inspector)))) 420 (ccl::apply-in-frame-internal 421 sg 422 frame 423 (car f&args) ; fn 424 (cdr f&args) ; args 425 srv))))))))) ; saved registers 426 (let* ((view (inspector-view i)) 427 (selection (selection view))) 428 (let ((f&args (inspector-object i))) 429 (push `("Insert arg after selection" 430 ,(and selection (>= (decf selection 3) 0) 431 #'(lambda () 432 (push nil (cdr (nthcdr selection f&args))) 433 (resample-it)))) 434 res) 435 (push `("Delete (and Copy) selected arg" 436 ,(and selection (> selection 0) 437 #'(lambda () 438 (copy view) 439 (pop (nthcdr selection f&args)) 440 (if (>= selection (length f&args)) 441 (set-selection (inspector-view i) nil)) 442 (resample-it)))) 443 res))) 444 (nreverse res))) 445 446 ) 194 (defmethod ui-object-enter-backtrace-context ((app ns:ns-application) 195 context) 196 (let* ((proc *current-process*)) 197 (when (typep proc 'cocoa-listener-process) 198 (push context (cocoa-listener-process-backtrace-contexts proc))))) 199 200 (defmethod ui-object-exit-backtrace-context ((app ns:ns-application) 201 context) 202 (let* ((proc *current-process*)) 203 (when (typep proc 'cocoa-listener-process) 204 (when (eq context (car (cocoa-listener-process-backtrace-contexts proc))) 205 (setf (cocoa-listener-process-backtrace-contexts proc) 206 (cdr (cocoa-listener-process-backtrace-contexts proc))) 207 (let* ((window (bt.dialog context))) 208 (when window 209 (send window 210 :perform-selector-on-main-thread 211 (@selector "close") 212 :with-object (%null-ptr) 213 :wait-until-done t))))))) 214 215 216 217 218 219 220
Note:
See TracChangeset
for help on using the changeset viewer.
