;;; Guile VM debugging facilities
-;;; Copyright (C) 2001, 2009, 2010 Free Software Foundation, Inc.
+;;; Copyright (C) 2001, 2009, 2010, 2011 Free Software Foundation, Inc.
;;;
;;; This library is free software; you can redistribute it and/or
;;; modify it under the terms of the GNU Lesser General Public
#:export (<debug>
make-debug debug?
debug-frames debug-index debug-error-message debug-for-trap?
+ terminal-width
print-registers print-locals print-frame print-frames frame->module
stack->vector narrow-stack->vector
frame->stack-vector))
\f
+;; A fluid, because terminals are usually implicitly associated with
+;; threads.
+;;
+(define terminal-width
+ (let ((set-width (make-fluid)))
+ (case-lambda
+ (()
+ (or (fluid-ref set-width)
+ (let ((w (false-if-exception (string->number (getenv "COLUMNS")))))
+ (and (integer? w) (exact? w) (> w 0) w))
+ 72))
+ ((w)
+ (if (or (not w) (and (integer? w) (exact? w) (> w 0)))
+ (fluid-set! set-width w)
+ (error "Expected a column number (a positive integer)" w))))))
+
+
+\f
+
(define (reverse-hashq h)
(let ((ret (make-hash-table)))
(hash-for-each
(print "fp = #x~x\n" (frame-address frame)))
(define* (print-locals frame #:optional (port (current-output-port))
- #:key (width 72) (per-line-prefix " "))
+ #:key (width (terminal-width)) (per-line-prefix " "))
(let ((bindings (frame-bindings frame)))
(cond
((null? bindings)
(frame-bindings frame))))))
(define* (print-frame frame #:optional (port (current-output-port))
- #:key index (width 72) (full? #f) (last-source #f)
- next-source?)
+ #:key index (width (terminal-width)) (full? #f)
+ (last-source #f) next-source?)
(define (source:pretty-file source)
(if source
(or (source:file source) "current input")
(define* (print-frames frames
#:optional (port (current-output-port))
- #:key (width 72) (full? #f) (forward? #f) count
- for-trap?)
+ #:key (width (terminal-width)) (full? #f)
+ (forward? #f) count for-trap?)
(let* ((len (vector-length frames))
(lower-idx (if (or (not count) (positive? count))
0
(format #t "Entering a new prompt. ")
(format #t "Type `,bt' for a backtrace or `,q' to continue.\n")
((@ (system repl repl) start-repl) #:debug debug))))))
+ ((report)
+ (lambda (key . args)
+ (if (not (memq key pass-keys))
+ (begin
+ (with-saved-ports
+ (lambda ()
+ (run-hook before-error-hook)
+ (print-exception err #f key args)
+ (run-hook after-error-hook)
+ (force-output err)))
+ (if #f #f)))))
+ ((backtrace)
+ (lambda (key . args)
+ (if (not (memq key pass-keys))
+ (let* ((tag (and (pair? (fluid-ref %stacks))
+ (cdar (fluid-ref %stacks))))
+ (frames (narrow-stack->vector
+ (make-stack #t)
+ ;; Narrow as above, for the debugging case.
+ 3 tag 0 (and tag 1))))
+ (with-saved-ports
+ (lambda ()
+ (print-frames frames)
+ (run-hook before-error-hook)
+ (print-exception err #f key args)
+ (run-hook after-error-hook)
+ (force-output err)))
+ (if #f #f)))))
((pass)
(lambda (key . args)
;; fall through to rethrow
(abort-on-error "parsing expression"
(repl-parse repl exp))))))
(run-hook before-eval-hook exp)
- (with-error-handling
- (with-stack-and-prompt thunk)))
+ (call-with-error-handling
+ (lambda ()
+ (with-stack-and-prompt thunk))
+ #:on-error (repl-option-ref repl 'on-error)))
(lambda (k) (values))))
(lambda l
(for-each (lambda (v)
l))))
(lambda (k . args)
(abort args))))
+ #:on-error (repl-option-ref repl 'on-error)
#:trap-handler 'disabled)))
(flush-to-newline) ;; consume trailing whitespace
(prompt-loop))))