home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume11
/
test.el
/
part01
/
tst-instrument.el
< prev
Wrap
Lisp/Scheme
|
1987-09-08
|
6KB
|
212 lines
;;; tst-instrument
;;; Copyright 1987 Richard Rosenthal
;;; All rights reserved.
(provide 'tst-instrument)
(require 'tst-annotate)
(defvar *tst-last-instrumented-line* 0
"Defined in instrument.el. Used in the following functions:
tst-instrument-defun
tst-instrument-primitive")
(defun tst-instrument ()
"The tst-instrument function creates a buffer containing a copy of
the buffer in which the function was invoked. All code in the copied
buffer is then instrumented and compiled. We are talking about
compiling LISP code."
(interactive)
(let* ((old-buffer (buffer-name))
(instrumented-buffer
(get-buffer-create (concat old-buffer "-instrumented"))))
(save-excursion
(set-buffer instrumented-buffer)
(emacs-lisp-mode)
(erase-buffer)
(insert-buffer old-buffer)
(tst-ann-set-db nil)
(tst-instrument-region (point-min) (point-max))
(eval-current-buffer)
(message "Done"))))
(defun tst-instrument-region (start end)
(interactive "r")
(save-restriction
(narrow-to-region start end)
(goto-char (point-min))
(or (looking-at "\\s( *defun\\b") (beginning-of-next-defun))
(while (< (point) (point-max))
(tst-instrument-defun)
(beginning-of-next-defun))))
(defun tst-instrument-defun ()
(save-excursion
(save-restriction
(push-mark (point) 'nomsg)
(setq *tst-last-instrumented-line* (line-number))
(if (error-occurred (forward-sexp 1))
(progn
(goto-char (point-max))
nil)
(narrow-to-region (mark) (point))
(goto-char (point-min))
(down-list 1)
(next-sexp) ;looking at defun
(beginning-of-next-sexp) ;looking at function name
(let ((start (point))
end)
(forward-sexp 1)
(setq end (point))
(backward-sexp 1)
(message "Instrumenting (defun %s..." (buffer-substring start end))
)
(beginning-of-next-sexp) ;looking at parameter list
(beginning-of-next-sexp) ;looking at comment?
(if (looking-at "\\s\"")
(beginning-of-next-sexp)) ;looking at parameter list
;; now looking at first statement in defun
(while (< (point) (point-max))
(cond
((looking-at "\\s(")
(tst-instrument-function))
;;inside a comment
((nth 4 (parse-partial-sexp (point-min) (point) nil nil nil))
(end-of-line)
(next-sexp))
(t
(beginning-of-next-sexp))))
t))))
(defun tst-instrument-function ()
;;;at this point, I was definitly looking at a left "(".
(cond
((tst-looking-at-prohibited-form-p)
(beginning-of-next-sexp)) ;do nothing, skip it
((tst-looking-at-special-form-p)
(tst-instrument-primitive) ;instrument around it
(tst-instrument-special-form)) ;try to go in it
(t
(tst-instrument-primitive) ;instrument around it
(down-list 1)))) ;go in it
(defun tst-looking-at-prohibited-form-p ()
(cond
((looking-at "\\s( *interactive\\b") t)
((looking-at "\\s( *quote\\b") t)
((looking-at "\\s'\\s(") t)
(t nil)))
(defun tst-looking-at-special-form-p ()
"List potential trouble makers in this function"
(cond
((looking-at "\\s( *cond\\b") t)
((looking-at "\\s( *function\\b") t)
((looking-at "\\s( *let\\b") t)
((looking-at "\\s( *progn\\b") t)
(t nil)))
(defun tst-instrument-special-form ()
"Explain how to deal with known trouble makers in this function"
(cond
((looking-at "\\s( *let\\b") ;minor problem
(tst-instrument-let))
((looking-at "\\s( *progn\\b") ;no problem
(down-list 1))
(t ;skip forms I don't know about
(beginning-of-next-sexp))))
(defun tst-instrument-primitive ()
(let ((start (line-number)))
(if (> start *tst-last-instrumented-line*)
(progn
(setq *tst-last-instrumented-line* start)
(insert "(tst-cover " (int-to-string start) " ")
(forward-sexp 1)
(insert ")")
(backward-char 1)
(backward-sexp 1)
(tst-ann-append start 'count '(0))))))
(defun tst-instrument-let ()
(down-list 1)
(next-sexp) ;looking at let
(beginning-of-next-sexp) ;looking at parameter list
(forward-sexp 1) ;skip parameters for now
(next-sexp))
;;;----------------------------------------------------------------------------
(defun tst-cover (id arg)
"Version 2: for testing, display arg in mini-buffer while
moving cursor around buffer"
(save-excursion
(goto-line id)
(re-search-forward "\\s(")
(message "function returns %s" (prin1-to-string arg))
(sit-for 2)
)
arg)
(defun tst-cover (id arg)
"Version 1: for testing, display id and arg in mini-buffer"
(message "tst-cover %d %s" id (prin1-to-string arg))
(sit-for 0)
arg)
(defun tst-cover (id arg)
"Version 0: for testing, does nothing"
arg)
(defun tst-cover (id arg)
"The Real Thing: uses annotation capabilities"
(tst-ann-inc id 'count)
(tst-ann-append id 'values (list arg))
arg)
;;;============================================================================
(defun beginning-of-next-defun ()
"This function finds LISP defun"
(if (= (point) (point-max))
nil
(forward-char 1)
(and (re-search-forward "\\s( *defun\\b" nil 'move 1)
(re-search-backward "\\s("))))
(defmacro error-occurred (&rest body)
"As defined in mlsupport.el"
(list 'condition-case nil (cons 'progn (append body '(nil))) '(error t)))
(defun line-number ()
"Return line number of current line. Gives consistent results."
(count-lines-correctly 1 (point)))
(defun count-lines-correctly (start end)
"Return number of newlines between START and END. Gives
consistent results."
(save-excursion
(save-restriction
(goto-char end)
(end-of-line)
(narrow-to-region start (point))
(goto-char (point-min))
(- (buffer-size) (forward-line (buffer-size))))))
(defun next-sexp ()
(while (error-occurred (forward-sexp))
(forward-char 1))
(or (= (point) (point-max)) (backward-sexp)))
(defun beginning-of-next-sexp ()
(forward-sexp 1)
(next-sexp))