aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Yavner2003-11-30 06:56:28 +0000
committerJonathan Yavner2003-11-30 06:56:28 +0000
commitbbaa142972a148a3a6cc68c2a8aaf973aaf2135f (patch)
tree35d56c0decf3f74553e0f0ed3ce0e9ac3047d73e
parent190177521fe7c6f0d895606b585852f1e3635de4 (diff)
downloademacs-bbaa142972a148a3a6cc68c2a8aaf973aaf2135f.tar.gz
emacs-bbaa142972a148a3a6cc68c2a8aaf973aaf2135f.zip
Ensure that forms marked with `1value' actually always return the same value.
-rw-r--r--lisp/emacs-lisp/testcover.el55
1 files changed, 34 insertions, 21 deletions
diff --git a/lisp/emacs-lisp/testcover.el b/lisp/emacs-lisp/testcover.el
index 4d668a78678..547e2cbd32d 100644
--- a/lisp/emacs-lisp/testcover.el
+++ b/lisp/emacs-lisp/testcover.el
@@ -171,14 +171,13 @@ call to one of the `testcover-1value-functions'."
171;;; Add instrumentation to your module 171;;; Add instrumentation to your module
172;;;========================================================================= 172;;;=========================================================================
173 173
174;;;###autoload
175(defun testcover-start (filename &optional byte-compile) 174(defun testcover-start (filename &optional byte-compile)
176 "Uses edebug to instrument all macros and functions in FILENAME, then 175 "Uses edebug to instrument all macros and functions in FILENAME, then
177changes the instrumentation from edebug to testcover--much faster, no 176changes the instrumentation from edebug to testcover--much faster, no
178problems with type-ahead or post-command-hook, etc. If BYTE-COMPILE is 177problems with type-ahead or post-command-hook, etc. If BYTE-COMPILE is
179non-nil, byte-compiles each function after instrumenting." 178non-nil, byte-compiles each function after instrumenting."
180 (interactive "f") 179 (interactive "f")
181 (let ((buf (find-file filename)) 180 (let ((buf (find-file filename))
182 (load-read-function 'testcover-read) 181 (load-read-function 'testcover-read)
183 (edebug-all-defs t)) 182 (edebug-all-defs t))
184 (setq edebug-form-data nil 183 (setq edebug-form-data nil
@@ -210,7 +209,8 @@ non-nil, byte-compiles each function after instrumenting."
210 "Reinstruments FORM to use testcover instead of edebug. This function 209 "Reinstruments FORM to use testcover instead of edebug. This function
211modifies the list that FORM points to. Result is non-nil if FORM will 210modifies the list that FORM points to. Result is non-nil if FORM will
212always return the same value." 211always return the same value."
213 (let ((fun (car-safe form))) 212 (let ((fun (car-safe form))
213 id)
214 (cond 214 (cond
215 ((not fun) ;Atom 215 ((not fun) ;Atom
216 (or (not (symbolp form)) 216 (or (not (symbolp form))
@@ -234,10 +234,10 @@ always return the same value."
234 (testcover-reinstrument (cadr form))) 234 (testcover-reinstrument (cadr form)))
235 ((memq fun testcover-compose-functions) 235 ((memq fun testcover-compose-functions)
236 ;;1-valued if all arguments are 236 ;;1-valued if all arguments are
237 (setq fun t) 237 (setq id t)
238 (mapc #'(lambda (x) (setq fun (or (testcover-reinstrument x) fun))) 238 (mapc #'(lambda (x) (setq id (or (testcover-reinstrument x) id)))
239 (cdr form)) 239 (cdr form))
240 fun) 240 id)
241 ((eq fun 'edebug-enter) 241 ((eq fun 'edebug-enter)
242 ;;(edebug-enter 'SYM ARGS #'(lambda nil FORMS)) 242 ;;(edebug-enter 'SYM ARGS #'(lambda nil FORMS))
243 ;; => (testcover-enter 'SYM #'(lambda nil FORMS)) 243 ;; => (testcover-enter 'SYM #'(lambda nil FORMS))
@@ -250,17 +250,22 @@ always return the same value."
250 ;; => (testcover-after YYY FORM), mark XXX as ok-coverage 250 ;; => (testcover-after YYY FORM), mark XXX as ok-coverage
251 (unless (eq (cadr form) 0) 251 (unless (eq (cadr form) 0)
252 (aset testcover-vector (cadr (cadr form)) 'ok-coverage)) 252 (aset testcover-vector (cadr (cadr form)) 'ok-coverage))
253 (setq fun (nth 2 form)) 253 (setq id (nth 2 form))
254 (setcdr form (nthcdr 2 form)) 254 (setcdr form (nthcdr 2 form))
255 (if (not (memq (car-safe (nth 2 form)) testcover-noreturn-functions)) 255 (cond
256 (setcar form 'testcover-after) 256 ((memq (car-safe (nth 2 form)) testcover-noreturn-functions)
257 ;;This function won't return, so set the value in advance 257 ;;This function won't return, so set the value in advance
258 ;;(edebug-after (edebug-before XXX) YYY FORM) 258 ;;(edebug-after (edebug-before XXX) YYY FORM)
259 ;; => (progn (edebug-after YYY nil) FORM) 259 ;; => (progn (edebug-after YYY nil) FORM)
260 (setcar form 'progn) 260 (setcar form 'progn)
261 (setcar (cdr form) `(testcover-after ,fun nil))) 261 (setcar (cdr form) `(testcover-after ,id nil)))
262 ((eq (car-safe (nth 2 form)) '1value)
263 ;;This function is always supposed to return the same value
264 (setcar form 'testcover-1value))
265 (t
266 (setcar form 'testcover-after)))
262 (when (testcover-reinstrument (nth 2 form)) 267 (when (testcover-reinstrument (nth 2 form))
263 (aset testcover-vector fun '1value))) 268 (aset testcover-vector id '1value)))
264 ((eq fun 'defun) 269 ((eq fun 'defun)
265 (if (testcover-reinstrument-list (nthcdr 3 form)) 270 (if (testcover-reinstrument-list (nthcdr 3 form))
266 (push (cadr form) testcover-module-1value-functions))) 271 (push (cadr form) testcover-module-1value-functions)))
@@ -316,8 +321,11 @@ always return the same value."
316 ;;Hack - pretend the arg is 1-valued here 321 ;;Hack - pretend the arg is 1-valued here
317 (if (symbolp (cadr form)) ;A pseudoconstant variable 322 (if (symbolp (cadr form)) ;A pseudoconstant variable
318 t 323 t
324 (if (eq (car (cadr form)) 'edebug-after)
325 (setq id (car (nth 3 (cadr form))))
326 (setq id (car (cadr form))))
319 (let ((testcover-1value-functions 327 (let ((testcover-1value-functions
320 (cons (car (cadr form)) testcover-1value-functions))) 328 (cons id testcover-1value-functions)))
321 (testcover-reinstrument (cadr form))))) 329 (testcover-reinstrument (cadr form)))))
322 (t ;Some other function or weird thing 330 (t ;Some other function or weird thing
323 (testcover-reinstrument-list (cdr form)) 331 (testcover-reinstrument-list (cdr form))
@@ -348,15 +356,6 @@ Result is t if every clause is 1-valued."
348 (let ((buf (find-file-noselect buffer))) 356 (let ((buf (find-file-noselect buffer)))
349 (eval-buffer buf t))) 357 (eval-buffer buf t)))
350 358
351(defmacro 1value (form)
352 "For coverage testing, indicate FORM should always have the same value."
353 form)
354
355(defmacro noreturn (form)
356 "For coverage testing, indicate that FORM will never return."
357 `(prog1 ,form
358 (error "Form marked with `noreturn' did return")))
359
360 359
361;;;========================================================================= 360;;;=========================================================================
362;;; Accumulate coverage data 361;;; Accumulate coverage data
@@ -379,6 +378,19 @@ binding `testcover-vector' to the code-coverage vector for TESTCOVER-SYM
379 (aset testcover-vector idx 'ok-coverage))) 378 (aset testcover-vector idx 'ok-coverage)))
380 val) 379 val)
381 380
381(defun testcover-1value (idx val)
382 "Internal function for coverage testing. Returns VAL after installing it in
383`testcover-vector' at offset IDX. Error if FORM does not always return the
384same value during coverage testing."
385 (cond
386 ((eq (aref testcover-vector idx) '1value)
387 (aset testcover-vector idx (cons '1value val)))
388 ((not (and (eq (car-safe (aref testcover-vector idx)) '1value)
389 (equal (cdr (aref testcover-vector idx)) val)))
390 (error "Value of form marked with `1value' does vary.")))
391 val)
392
393
382 394
383;;;========================================================================= 395;;;=========================================================================
384;;; Display the coverage data as color splotches on your code. 396;;; Display the coverage data as color splotches on your code.
@@ -411,6 +423,7 @@ eliminated by adding more test cases."
411 (setq len (1- len) 423 (setq len (1- len)
412 data (aref coverage len)) 424 data (aref coverage len))
413 (when (and (not (eq data 'ok-coverage)) 425 (when (and (not (eq data 'ok-coverage))
426 (not (eq (car-safe data) '1value))
414 (setq j (+ def-mark (aref points len)))) 427 (setq j (+ def-mark (aref points len))))
415 (setq ov (make-overlay (1- j) j)) 428 (setq ov (make-overlay (1- j) j))
416 (overlay-put ov 'face 429 (overlay-put ov 'face