home *** CD-ROM | disk | FTP | other *** search
- ;;; 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))
-