PageRenderTime 92ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/src/guile/skribilo/debug.scm

#
Scheme | 188 lines | 87 code | 27 blank | 74 comment | 0 complexity | 5b515a26a2310485594885a2f8145f23 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0
  1. ;;; debug.scm -- Debugging facilities. -*- coding: iso-8859-1 -*-
  2. ;;;
  3. ;;; Copyright 2005, 2006, 2009, 2012 Ludovic CourtĨs <ludo@gnu.org>
  4. ;;; Copyright 2003, 2004 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
  5. ;;;
  6. ;;; This file is part of Skribilo.
  7. ;;;
  8. ;;; Skribilo is free software: you can redistribute it and/or modify
  9. ;;; it under the terms of the GNU General Public License as published by
  10. ;;; the Free Software Foundation, either version 3 of the License, or
  11. ;;; (at your option) any later version.
  12. ;;;
  13. ;;; Skribilo is distributed in the hope that it will be useful,
  14. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. ;;; GNU General Public License for more details.
  17. ;;;
  18. ;;; You should have received a copy of the GNU General Public License
  19. ;;; along with Skribilo. If not, see <http://www.gnu.org/licenses/>.
  20. (define-module (skribilo debug)
  21. :use-module (skribilo utils syntax)
  22. :use-module (srfi srfi-39)
  23. :export (debug-item debug-bold with-debug))
  24. (skribilo-module-syntax)
  25. ;;;
  26. ;;; Parameters.
  27. ;;;
  28. ;; Current debugging level.
  29. (define-public *debug*
  30. (make-parameter 0 (lambda (val)
  31. (cond ((number? val) val)
  32. ((string? val)
  33. (string->number val))
  34. (else
  35. (error "*debug*: wrong argument type"
  36. val))))))
  37. ;; Whether to use colors.
  38. (define-public *debug-use-colors?* (make-parameter #t))
  39. ;; Where to spit debugging output.
  40. (define-public *debug-port* (make-parameter (current-output-port)))
  41. ;; Whether to debug individual items.
  42. (define-public *debug-item?* (make-parameter #f))
  43. ;; Watched (debugged) symbols (procedure names).
  44. (define-public *watched-symbols* (make-parameter '()))
  45. ;;;
  46. ;;; Implementation.
  47. ;;;
  48. (define *debug-depth* (make-parameter 0))
  49. (define *debug-margin* (make-parameter ""))
  50. (define *margin-level* (make-parameter 0))
  51. ;;
  52. ;; debug-port
  53. ;;
  54. ; (define (debug-port . o)
  55. ; (cond
  56. ; ((null? o)
  57. ; *debug-port*)
  58. ; ((output-port? (car o))
  59. ; (set! *debug-port* o)
  60. ; o)
  61. ; (else
  62. ; (error 'debug-port "Invalid debug port" (car o)))))
  63. ;
  64. ;;;
  65. ;;; debug-color
  66. ;;;
  67. (define (debug-color col . o)
  68. (with-output-to-string
  69. (if (and (*debug-use-colors?*)
  70. (equal? (getenv "TERM") "xterm"))
  71. (lambda ()
  72. (format #t "[1;~Am" (+ 31 col))
  73. (for-each display o)
  74. (display ""))
  75. (lambda ()
  76. (for-each display o)))))
  77. ;;;
  78. ;;; debug-bold
  79. ;;;
  80. (define (debug-bold . o)
  81. (apply debug-color -30 o))
  82. ;;;
  83. ;;; debug-item
  84. ;;;
  85. (define (%do-debug-item . args)
  86. (begin
  87. (display (*debug-margin*) (*debug-port*))
  88. (display (debug-color (- (*debug-depth*) 1) "- ") (*debug-port*))
  89. (for-each (lambda (a) (display a (*debug-port*))) args)
  90. (newline (*debug-port*))))
  91. (cond-expand
  92. (guile-2
  93. (define-syntax-rule (debug-item args ...)
  94. (if (*debug-item?*)
  95. (%do-debug-item args ...))))
  96. (else
  97. (begin
  98. ;; Work around Guile 1.8's broken macro support.
  99. (export %do-debug-item)
  100. (define-macro (debug-item . args)
  101. `(if (*debug-item?*) (%do-debug-item ,@args))))))
  102. ;;;
  103. ;;; %with-debug-margin
  104. ;;;
  105. (define (%with-debug-margin margin thunk)
  106. (parameterize ((*debug-depth* (+ (*debug-depth*) 1))
  107. (*debug-margin* (string-append (*debug-margin*) margin)))
  108. (thunk)))
  109. ;;;
  110. ;;; %with-debug
  111. ;;;
  112. (define (%do-with-debug lvl lbl thunk)
  113. (parameterize ((*margin-level* lvl)
  114. (*debug-item?* #t))
  115. (display (*debug-margin*) (*debug-port*))
  116. (display (if (= (*debug-depth*) 0)
  117. (debug-color (*debug-depth*) "+ " lbl)
  118. (debug-color (*debug-depth*) "--+ " lbl))
  119. (*debug-port*))
  120. (newline (*debug-port*))
  121. (%with-debug-margin (debug-color (*debug-depth*) " |")
  122. thunk)))
  123. ;; We have this as a macro in order to avoid procedure calls in the
  124. ;; non-debugging case. Unfortunately, the macro below duplicates BODY,
  125. ;; which has a negative impact on memory usage and startup time (XXX).
  126. (cond-expand
  127. (guile-2
  128. (define-syntax with-debug
  129. (lambda (s)
  130. (syntax-case s ()
  131. ((_ level label body ...)
  132. (integer? (syntax->datum #'level))
  133. #'(if (or (>= (*debug*) level)
  134. (memq label (*watched-symbols*)))
  135. (%do-with-debug level label (lambda () body ...))
  136. (begin body ...)))))))
  137. (else
  138. (begin
  139. (export %do-with-debug)
  140. (define-macro (with-debug level label . body)
  141. (if (number? level)
  142. `(if (or (>= (*debug*) ,level)
  143. (memq ,label (*watched-symbols*)))
  144. (%do-with-debug ,level ,label (lambda () ,@body))
  145. (begin ,@body))
  146. (error "with-debug: syntax error"))))))
  147. ; Example:
  148. ; (with-debug 0 'foo1.1
  149. ; (debug-item 'foo2.1)
  150. ; (debug-item 'foo2.2)
  151. ; (with-debug 0 'foo2.3
  152. ; (debug-item 'foo3.1)
  153. ; (with-debug 0 'foo3.2
  154. ; (debug-item 'foo4.1)
  155. ; (debug-item 'foo4.2))
  156. ; (debug-item 'foo3.3))
  157. ; (debug-item 'foo2.4))
  158. ;;; debug.scm ends here