root/trunk/lisp/emacs-lisp/edebug.el

Revision 4220, 152.1 kB (checked in by miyoshi, 9 months ago)

Sync up with Emacs22.2.

  • Property svn:eol-style set to LF
Line 
1 ;;; edebug.el --- a source-level debugger for Emacs Lisp
2
3 ;; Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1997, 1999,
4 ;;   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5
6 ;; Author: Daniel LaLiberte <liberte@holonexus.org>
7 ;; Maintainer: FSF
8 ;; Keywords: lisp, tools, maint
9
10 ;; This file is part of GNU Emacs.
11
12 ;; GNU Emacs is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; any later version.
16
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ;; GNU General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
26
27 ;;; Commentary:
28
29 ;; This minor mode allows programmers to step through Emacs Lisp
30 ;; source code while executing functions.  You can also set
31 ;; breakpoints, trace (stopping at each expression), evaluate
32 ;; expressions as if outside Edebug, reevaluate and display a list of
33 ;; expressions, trap errors normally caught by debug, and display a
34 ;; debug style backtrace.
35
36 ;;; Minimal Instructions
37 ;; =====================
38
39 ;; First evaluate a defun with C-M-x, then run the function.  Step
40 ;; through the code with SPC, mark breakpoints with b, go until a
41 ;; breakpoint is reached with g, and quit execution with q.  Use the
42 ;; "?" command in edebug to describe other commands.
43 ;; See the Emacs Lisp Reference Manual for more details.
44
45 ;; If you wish to change the default edebug global command prefix, change:
46 ;; (setq edebug-global-prefix "\C-xX")
47
48 ;; Edebug was written by
49 ;; Daniel LaLiberte
50 ;; GTE Labs
51 ;; 40 Sylvan Rd
52 ;; Waltham, MA  02254
53 ;; liberte@holonexus.org
54
55 ;;; Code:
56
57 ;;; Bug reporting
58
59 (defalias 'edebug-submit-bug-report 'report-emacs-bug)
60
61 ;;; Options
62
63 (defgroup edebug nil
64   "A source-level debugger for Emacs Lisp."
65   :group 'lisp)
66
67
68 (defcustom edebug-setup-hook nil
69   "*Functions to call before edebug is used.
70 Each time it is set to a new value, Edebug will call those functions
71 once and then `edebug-setup-hook' is reset to nil.  You could use this
72 to load up Edebug specifications associated with a package you are
73 using but only when you also use Edebug."
74   :type 'hook
75   :group 'edebug)
76
77 ;; edebug-all-defs and edebug-all-forms need to be autoloaded
78 ;; because the byte compiler binds them; as a result, if edebug
79 ;; is first loaded for a require in a compilation, they will be left unbound.
80
81 ;;;###autoload
82 (defcustom edebug-all-defs nil
83   "*If non-nil, evaluating defining forms instruments for Edebug.
84 This applies to `eval-defun', `eval-region', `eval-buffer', and
85 `eval-current-buffer'.  `eval-region' is also called by
86 `eval-last-sexp', and `eval-print-last-sexp'.
87
88 You can use the command `edebug-all-defs' to toggle the value of this
89 variable.  You may wish to make it local to each buffer with
90 \(make-local-variable 'edebug-all-defs) in your
91 `emacs-lisp-mode-hook'."
92   :type 'boolean
93   :group 'edebug)
94
95 ;; edebug-all-defs and edebug-all-forms need to be autoloaded
96 ;; because the byte compiler binds them; as a result, if edebug
97 ;; is first loaded for a require in a compilation, they will be left unbound.
98
99 ;;;###autoload
100 (defcustom edebug-all-forms nil
101   "*Non-nil evaluation of all forms will instrument for Edebug.
102 This doesn't apply to loading or evaluations in the minibuffer.
103 Use the command `edebug-all-forms' to toggle the value of this option."
104   :type 'boolean
105   :group 'edebug)
106
107 (defcustom edebug-eval-macro-args nil
108   "*Non-nil means all macro call arguments may be evaluated.
109 If this variable is nil, the default, Edebug will *not* wrap
110 macro call arguments as if they will be evaluated.
111 For each macro, a `edebug-form-spec' overrides this option.
112 So to specify exceptions for macros that have some arguments evaluated
113 and some not, you should specify an `edebug-form-spec'."
114   :type 'boolean
115   :group 'edebug)
116
117 (defcustom edebug-save-windows t
118   "*If non-nil, Edebug saves and restores the window configuration.
119 That takes some time, so if your program does not care what happens to
120 the window configurations, it is better to set this variable to nil.
121
122 If the value is a list, only the listed windows are saved and
123 restored.
124
125 `edebug-toggle-save-windows' may be used to change this variable."
126   :type '(choice boolean (repeat string))
127   :group 'edebug)
128
129 (defcustom edebug-save-displayed-buffer-points nil
130   "*If non-nil, save and restore point in all displayed buffers.
131
132 Saving and restoring point in other buffers is necessary if you are
133 debugging code that changes the point of a buffer which is displayed
134 in a non-selected window.  If Edebug or the user then selects the
135 window, the buffer's point will be changed to the window's point.
136
137 Saving and restoring point in all buffers is expensive, since it
138 requires selecting each window twice, so enable this only if you need
139 it."
140   :type 'boolean
141   :group 'edebug)
142
143 (defcustom edebug-initial-mode 'step
144   "*Initial execution mode for Edebug, if non-nil.
145 If this variable is non-nil, it specifies the initial execution mode
146 for Edebug when it is first activated.  Possible values are step, next,
147 go, Go-nonstop, trace, Trace-fast, continue, and Continue-fast."
148   :type '(choice (const step) (const next) (const go)
149                  (const Go-nonstop) (const trace)
150                  (const Trace-fast) (const continue)
151                  (const Continue-fast))
152   :group 'edebug)
153
154 (defcustom edebug-trace nil
155   "*Non-nil means display a trace of function entry and exit.
156 Tracing output is displayed in a buffer named `*edebug-trace*', one
157 function entry or exit per line, indented by the recursion level.
158
159 You can customize by replacing functions `edebug-print-trace-before'
160 and `edebug-print-trace-after'."
161   :type 'boolean
162   :group 'edebug)
163
164 (defcustom edebug-test-coverage nil
165   "*If non-nil, Edebug tests coverage of all expressions debugged.
166 This is done by comparing the result of each expression
167 with the previous result. Coverage is considered OK if two different
168 results are found.
169
170 Use `edebug-display-freq-count' to display the frequency count and
171 coverage information for a definition."
172   :type 'boolean
173   :group 'edebug)
174
175 (defcustom edebug-continue-kbd-macro nil
176   "*If non-nil, continue defining or executing any keyboard macro.
177 Use this with caution since it is not debugged."
178   :type 'boolean
179   :group 'edebug)
180
181
182 (defcustom edebug-print-length 50
183   "*Default value of `print-length' for printing results in Edebug."
184   :type 'integer
185   :group 'edebug)
186 (defcustom edebug-print-level 50
187   "*Default value of `print-level' for printing results in Edebug."
188   :type 'integer
189   :group 'edebug)
190 (defcustom edebug-print-circle t
191   "*Default value of `print-circle' for printing results in Edebug."
192   :type 'boolean
193   :group 'edebug)
194
195 (defcustom edebug-unwrap-results nil
196   "*Non-nil if Edebug should unwrap results of expressions.
197 This is useful when debugging macros where the results of expressions
198 are instrumented expressions.  But don't do this when results might be
199 circular or an infinite loop will result."
200   :type 'boolean
201   :group 'edebug)
202
203 (defcustom edebug-on-error t
204   "*Value bound to `debug-on-error' while Edebug is active.
205
206 If `debug-on-error' is non-nil, that value is still used.
207
208 If the value is a list of signal names, Edebug will stop when any of
209 these errors are signaled from Lisp code whether or not the signal is
210 handled by a `condition-case'.  This option is useful for debugging
211 signals that *are* handled since they would otherwise be missed.
212 After execution is resumed, the error is signaled again."
213   :type '(choice (const :tag "off")
214                  (repeat :menu-tag "When"
215                          :value (nil)
216                          (symbol :format "%v"))
217                  (const :tag "always" t))
218   :group 'edebug)
219
220 (defcustom edebug-on-quit t
221   "*Value bound to `debug-on-quit' while Edebug is active."
222   :type 'boolean
223   :group 'edebug)
224
225 (defcustom edebug-global-break-condition nil
226   "*If non-nil, an expression to test for at every stop point.
227 If the result is non-nil, then break.  Errors are ignored."
228   :type 'sexp
229   :group 'edebug)
230
231 (defcustom edebug-sit-for-seconds 1
232   "*Number of seconds to pause when execution mode is `trace'."
233   :type 'number
234   :group 'edebug)
235
236 ;;; Form spec utilities.
237
238 (defmacro def-edebug-form-spec (symbol spec-form)
239   "For compatibility with old version."
240   (def-edebug-spec symbol (eval spec-form)))
241 (make-obsolete 'def-edebug-form-spec 'def-edebug-spec "22.1")
242
243 (defun get-edebug-spec (symbol)
244   ;; Get the spec of symbol resolving all indirection.
245   (let ((edebug-form-spec (get symbol 'edebug-form-spec))
246         indirect)
247     (while (and (symbolp edebug-form-spec)
248                 (setq indirect (get edebug-form-spec 'edebug-form-spec)))
249       ;; (edebug-trace "indirection: %s" edebug-form-spec)
250       (setq edebug-form-spec indirect))
251     edebug-form-spec
252     ))
253
254 ;;;###autoload
255 (defun edebug-basic-spec (spec)
256   "Return t if SPEC uses only extant spec symbols.
257 An extant spec symbol is a symbol that is not a function and has a
258 `edebug-form-spec' property."
259   (cond ((listp spec)
260          (catch 'basic
261            (while spec
262              (unless (edebug-basic-spec (car spec)) (throw 'basic nil))
263              (setq spec (cdr spec)))
264            t))
265         ((symbolp spec)
266          (unless (functionp spec) (get spec 'edebug-form-spec)))))
267
268 ;;; Utilities
269
270 ;; Define edebug-gensym - from old cl.el
271 (defvar edebug-gensym-index 0
272   "Integer used by `edebug-gensym' to produce new names.")
273
274 (defun edebug-gensym (&optional prefix)
275   "Generate a fresh uninterned symbol.
276 There is an  optional argument, PREFIX.  PREFIX is the
277 string that begins the new name. Most people take just the default,
278 except when debugging needs suggest otherwise."
279   (if (null prefix)
280       (setq prefix "G"))
281   (let ((newsymbol nil)
282         (newname   ""))
283     (while (not newsymbol)
284       (setq newname (concat prefix (int-to-string edebug-gensym-index)))
285       (setq edebug-gensym-index (+ edebug-gensym-index 1))
286       (if (not (intern-soft newname))
287           (setq newsymbol (make-symbol newname))))
288     newsymbol))
289
290 (defun edebug-lambda-list-keywordp (object)
291   "Return t if OBJECT is a lambda list keyword.
292 A lambda list keyword is a symbol that starts with `&'."
293   (and (symbolp object)
294        (= ?& (aref (symbol-name object) 0))))
295
296
297 (defun edebug-last-sexp ()
298   ;; Return the last sexp before point in current buffer.
299   ;; Assumes Emacs Lisp syntax is active.
300   (car
301    (read-from-string
302     (buffer-substring
303      (save-excursion
304        (forward-sexp -1)
305        (point))
306      (point)))))
307
308 (defun edebug-window-list ()
309   "Return a list of windows, in order of `next-window'."
310   ;; This doesn't work for epoch.
311   (let (window-list)
312     (walk-windows (lambda (w) (push w window-list)))
313     (nreverse window-list)))
314
315 ;; Not used.
316 '(defun edebug-two-window-p ()
317   "Return t if there are two windows."
318   (and (not (one-window-p))
319        (eq (selected-window)
320            (next-window (next-window (selected-window))))))
321
322 (defsubst edebug-lookup-function (object)
323   (while (and (symbolp object) (fboundp object))
324     (setq object (symbol-function object)))
325   object)
326
327 (defun edebug-macrop (object)
328   "Return the macro named by OBJECT, or nil if it is not a macro."
329   (setq object (edebug-lookup-function object))
330   (if (and (listp object)
331            (eq 'macro (car object))
332            (functionp (cdr object)))
333       object))
334
335 (defun edebug-sort-alist (alist function)
336   ;; Return the ALIST sorted with comparison function FUNCTION.
337   ;; This uses 'sort so the sorting is destructive.
338   (sort alist (function
339                (lambda (e1 e2)
340                  (funcall function (car e1) (car e2))))))
341
342 ;;(def-edebug-spec edebug-save-restriction t)
343
344 ;; Not used.  If it is used, def-edebug-spec must be defined before use.
345 '(defmacro edebug-save-restriction (&rest body)
346   "Evaluate BODY while saving the current buffers restriction.
347 BODY may change buffer outside of current restriction, unlike
348 save-restriction.  BODY may change the current buffer,
349 and the restriction will be restored to the original buffer,
350 and the current buffer remains current.
351 Return the result of the last expression in BODY."
352   `(let ((edebug:s-r-beg (point-min-marker))
353          (edebug:s-r-end (point-max-marker)))
354      (unwind-protect
355          (progn ,@body)
356        (save-excursion
357          (set-buffer (marker-buffer edebug:s-r-beg))
358          (narrow-to-region edebug:s-r-beg edebug:s-r-end)))))
359
360 ;;; Display
361
362 (defconst edebug-trace-buffer "*edebug-trace*"
363   "Name of the buffer to put trace info in.")
364
365 (defun edebug-pop-to-buffer (buffer &optional window)
366   ;; Like pop-to-buffer, but select window where BUFFER was last shown.
367   ;; Select WINDOW if it is provided and still exists.  Otherwise,
368   ;; if buffer is currently shown in several windows, choose one.
369   ;; Otherwise, find a new window, possibly splitting one.
370   (setq window
371         (cond
372          ((and (windowp window) (edebug-window-live-p window)
373                (eq (window-buffer window) buffer))
374           window)
375          ((eq (window-buffer (selected-window)) buffer)
376           ;; Selected window already displays BUFFER.
377           (selected-window))
378          ((edebug-get-buffer-window buffer))
379          ((one-window-p 'nomini)
380           ;; When there's one window only, split it.
381           (split-window))
382          ((let ((trace-window (get-buffer-window edebug-trace-buffer)))
383             (catch 'found
384               (dolist (elt (window-list nil 'nomini))
385                 (unless (or (eq elt (selected-window)) (eq elt trace-window)
386                             (window-dedicated-p elt))
387                   ;; Found a non-dedicated window not showing
388                   ;; `edebug-trace-buffer', use it.
389                   (throw 'found elt))))))
390          ;; All windows are dedicated or show `edebug-trace-buffer', split
391          ;; selected one.
392          (t (split-window))))
393   (select-window window)
394   (set-window-buffer window buffer)
395   (set-window-hscroll window 0);; should this be??
396   ;; Selecting the window does not set the buffer until command loop.
397   ;;(set-buffer buffer)
398   )
399
400 (defun edebug-get-displayed-buffer-points ()
401   ;; Return a list of buffer point pairs, for all displayed buffers.
402   (let (list)
403     (walk-windows (lambda (w)
404                     (unless (eq w (selected-window))
405                       (push (cons (window-buffer w)
406                                   (window-point w))
407                             list))))
408     list))
409
410
411 (defun edebug-set-buffer-points (buffer-points)
412   ;; Restore the buffer-points created by edebug-get-displayed-buffer-points.
413   (save-current-buffer
414     (mapcar (lambda (buf-point)
415               (when (buffer-live-p (car buf-point))
416                 (set-buffer (car buf-point))
417                 (goto-char (cdr buf-point))))
418             buffer-points)))
419
420 (defun edebug-current-windows (which-windows)
421   ;; Get either a full window configuration or some window information.
422   (if (listp which-windows)
423       (mapcar (function (lambda (window)
424                           (if (edebug-window-live-p window)
425                               (list window
426                                     (window-buffer window)
427                                     (window-point window)
428                                     (window-start window)
429                                     (window-hscroll window)))))
430               which-windows)
431     (current-window-configuration)))
432
433 (defun edebug-set-windows (window-info)
434   ;; Set either a full window configuration or some window information.
435   (if (listp window-info)
436       (mapcar (function
437                (lambda (one-window-info)
438                  (if one-window-info
439                      (apply (function
440                              (lambda (window buffer point start hscroll)
441                                (if (edebug-window-live-p window)
442                                    (progn
443                                      (set-window-buffer window buffer)
444                                      (set-window-point window point)
445                                      (set-window-start window start)
446                                      (set-window-hscroll window hscroll)))))
447                             one-window-info))))
448               window-info)
449     (set-window-configuration window-info)))
450
451 (defalias 'edebug-get-buffer-window 'get-buffer-window)
452 (defalias 'edebug-sit-for 'sit-for)
453 (defalias 'edebug-input-pending-p 'input-pending-p)
454
455
456 ;;; Redefine read and eval functions
457 ;; read is redefined to maybe instrument forms.
458 ;; eval-defun is redefined to check edebug-all-forms and edebug-all-defs.
459
460 ;; Save the original read function
461 (or (fboundp 'edebug-original-read)
462     (defalias 'edebug-original-read  (symbol-function 'read)))
463
464 (defun edebug-read (&optional stream)
465   "Read one Lisp expression as text from STREAM, return as Lisp object.
466 If STREAM is nil, use the value of `standard-input' (which see).
467 STREAM or the value of `standard-input' may be:
468  a buffer (read from point and advance it)
469  a marker (read from where it points and advance it)
470  a function (call it with no arguments for each character,
471      call it with a char as argument to push a char back)
472  a string (takes text from string, starting at the beginning)
473  t (read text line using minibuffer and use it).
474
475 This version, from Edebug, maybe instruments the expression. But the
476 STREAM must be the current buffer to do so.  Whether it instruments is
477 also dependent on the values of `edebug-all-defs' and
478 `edebug-all-forms'."
479   (or stream (setq stream standard-input))
480   (if (eq stream (current-buffer))
481       (edebug-read-and-maybe-wrap-form)
482     (edebug-original-read stream)))
483
484 (or (fboundp 'edebug-original-eval-defun)
485     (defalias 'edebug-original-eval-defun (symbol-function 'eval-defun)))
486
487 ;; We should somehow arrange to be able to do this
488 ;; without actually replacing the eval-defun command.
489 (defun edebug-eval-defun (edebug-it)
490   "Evaluate the top-level form containing point, or after point.
491
492 If the current defun is actually a call to `defvar', then reset the
493 variable using its initial value expression even if the variable
494 already has some other value.  (Normally `defvar' does not change the
495 variable's value if it already has a value.)  Treat `defcustom'
496 similarly.  Reinitialize the face according to `defface' specification.
497
498 With a prefix argument, instrument the code for Edebug.
499
500 Setting `edebug-all-defs' to a non-nil value reverses the meaning of
501 the prefix argument.  Code is then instrumented when this function is
502 invoked without a prefix argument
503
504 If acting on a `defun' for FUNCTION, and the function was
505 instrumented, `Edebug: FUNCTION' is printed in the minibuffer.  If not
506 instrumented, just FUNCTION is printed.
507
508 If not acting on a `defun', the result of evaluation is displayed in
509 the minibuffer."
510   (interactive "P")
511   (let* ((edebugging (not (eq (not edebug-it) (not edebug-all-defs))))
512          (edebug-result)
513          (form
514           (let ((edebug-all-forms edebugging)
515                 (edebug-all-defs (eq edebug-all-defs (not edebug-it))))
516             (edebug-read-top-level-form))))
517     ;; This should be consistent with `eval-defun-1', but not the
518     ;; same, since that gets a macroexpanded form.
519     (cond ((and (eq (car form) 'defvar)
520                 (cdr-safe (cdr-safe form)))
521            ;; Force variable to be bound.
522            (makunbound (nth 1 form)))
523           ((and (eq (car form) 'defcustom)
524                 (default-boundp (nth 1 form)))
525            ;; Force variable to be bound.
526            (set-default (nth 1 form) (eval (nth 2 form))))
527           ((eq (car form) 'defface)
528            ;; Reset the face.
529            (setq face-new-frame-defaults
530                  (assq-delete-all (nth 1 form) face-new-frame-defaults))
531            (put (nth 1 form) 'face-defface-spec nil)
532            ;; See comments in `eval-defun-1' for purpose of code below
533            (setq form (prog1 `(prog1 ,form
534                                 (put ',(nth 1 form) 'saved-face
535                                      ',(get (nth 1 form) 'saved-face))
536                                 (put ',(nth 1 form) 'customized-face
537                                      ,(nth 2 form)))
538                         (put (nth 1 form) 'saved-face nil)))))
539     (setq edebug-result (eval form))
540     (if (not edebugging)
541         (princ edebug-result)
542       edebug-result)))
543
544
545 ;;;###autoload
546 (defalias 'edebug-defun 'edebug-eval-top-level-form)
547
548 ;;;###autoload
549 (defun edebug-eval-top-level-form ()
550   "Evaluate the top level form point is in, stepping through with Edebug.
551 This is like `eval-defun' except that it steps the code for Edebug
552 before evaluating it.  It displays the value in the echo area
553 using `eval-expression' (which see).
554
555 If you do this on a function definition
556 such as a defun or defmacro, it defines the function and instruments
557 its definition for Edebug, so it will do Edebug stepping when called
558 later.  It displays `Edebug: FUNCTION' in the echo area to indicate
559 that FUNCTION is now instrumented for Edebug.
560
561 If the current defun is actually a call to `defvar' or `defcustom',
562 evaluating it this way resets the variable using its initial value
563 expression even if the variable already has some other value.
564 \(Normally `defvar' and `defcustom' do not alter the value if there
565 already is one.)"
566   (interactive)
567   (eval-expression
568    ;; Bind edebug-all-forms only while reading, not while evalling
569    ;; but this causes problems while edebugging edebug.
570    (let ((edebug-all-forms t)
571          (edebug-all-defs t))
572      (edebug-read-top-level-form))))
573
574
575 (defun edebug-read-top-level-form ()
576   (let ((starting-point (point)))
577     (end-of-defun)
578     (beginning-of-defun)
579     (prog1
580         (edebug-read-and-maybe-wrap-form)
581       ;; Recover point, but only if no error occurred.
582       (goto-char starting-point))))
583
584
585 ;; Compatibility with old versions.
586 (defalias 'edebug-all-defuns 'edebug-all-defs)
587
588 ;;;###autoload
589 (defun edebug-all-defs ()
590   "Toggle edebugging of all definitions."
591   (interactive)
592   (setq edebug-all-defs (not edebug-all-defs))
593   (message "Edebugging all definitions is %s."
594            (if edebug-all-defs "on" "off")))
595
596
597 ;;;###autoload
598 (defun edebug-all-forms ()
599   "Toggle edebugging of all forms."
600   (interactive)
601   (setq edebug-all-forms (not edebug-all-forms))
602   (message "Edebugging all forms is %s."
603            (if edebug-all-forms "on" "off")))
604
605
606 (defun edebug-install-read-eval-functions ()
607   (interactive)
608   ;; Don't install if already installed.
609   (unless load-read-function
610     (setq load-read-function 'edebug-read)
611     (defalias 'eval-defun 'edebug-eval-defun)))
612
613 (defun edebug-uninstall-read-eval-functions ()
614   (interactive)
615   (setq load-read-function nil)
616   (defalias 'eval-defun (symbol-function 'edebug-original-eval-defun)))
617
618
619 ;;; Edebug internal data
620
621 ;; The internal data that is needed for edebugging is kept in the
622 ;; buffer-local variable `edebug-form-data'.
623
624 (make-variable-buffer-local 'edebug-form-data)
625
626 (defvar edebug-form-data nil)
627 ;; A list of entries associating symbols with buffer regions.
628 ;; This is an automatic buffer local variable.  Each entry looks like:
629 ;; @code{(@var{symbol} @var{begin-marker} @var{end-marker}).  The markers
630 ;; are at the beginning and end of an entry level form and @var{symbol} is
631 ;; a symbol that holds all edebug related information for the form on its
632 ;; property list.
633
634 ;; In the future, the symbol will be irrelevant and edebug data will
635 ;; be stored in the definitions themselves rather than in the property
636 ;; list of a symbol.
637
638 (defun edebug-make-form-data-entry (symbol begin end)
639   (list symbol begin end))
640
641 (defsubst edebug-form-data-name (entry)
642   (car entry))
643
644 (defsubst edebug-form-data-begin (entry)
645   (nth 1 entry))
646
647 (defsubst edebug-form-data-end (entry)
648   (nth 2 entry))
649
650 (defsubst edebug-set-form-data-entry (entry name begin end)
651   (setcar entry name);; in case name is changed
652   (set-marker (nth 1 entry) begin)
653   (set-marker (nth 2 entry) end))
654
655 (defun edebug-get-form-data-entry (pnt &optional end-point)
656   ;; Find the edebug form data entry which is closest to PNT.
657   ;; If END-POINT is supplied, match must be exact.
658   ;; Return `nil' if none found.
659   (let ((rest edebug-form-data)
660         closest-entry
661         (closest-dist 999999))  ;; need maxint here
662     (while (and rest (< 0 closest-dist))
663       (let* ((entry (car rest))
664              (begin (edebug-form-data-begin entry))
665              (dist (- pnt begin)))
666         (setq rest (cdr rest))
667         (if (and (<= 0 dist)
668                  (< dist closest-dist)
669                  (or (not end-point)
670                      (= end-point (edebug-form-data-end entry)))
671                  (<= pnt (edebug-form-data-end entry)))
672             (setq closest-dist dist
673                   closest-entry entry))))
674     closest-entry))
675
676 ;; Also need to find all contained entries,
677 ;; and find an entry given a symbol, which should be just assq.
678
679 (defun edebug-form-data-symbol ()
680 ;; Return the edebug data symbol of the form where point is in.
681 ;; If point is not inside a edebuggable form, cause error.
682   (or (edebug-form-data-name (edebug-get-form-data-entry (point)))
683       (error "Not inside instrumented form")))
684
685 (defun edebug-make-top-form-data-entry (new-entry)
686   ;; Make NEW-ENTRY the first element in the `edebug-form-data' list.
687   (edebug-clear-form-data-entry new-entry)
688   (setq edebug-form-data (cons new-entry edebug-form-data)))
689
690 (defun edebug-clear-form-data-entry (entry)
691 ;; If non-nil, clear ENTRY out of the form data.
692 ;; Maybe clear the markers and delete the symbol's edebug property?
693   (if entry
694       (progn
695         ;; Instead of this, we could just find all contained forms.
696         ;; (put (car entry) 'edebug nil)   ;
697         ;; (mapcar 'edebug-clear-form-data-entry   ; dangerous
698         ;;   (get (car entry) 'edebug-dependents))
699         ;; (set-marker (nth 1 entry) nil)
700         ;; (set-marker (nth 2 entry) nil)
701         (setq edebug-form-data (delq entry edebug-form-data)))))
702
703 ;;; Parser utilities
704
705 (defun edebug-syntax-error (&rest args)
706   ;; Signal an invalid-read-syntax with ARGS.
707   (signal 'invalid-read-syntax args))
708
709
710 (defconst edebug-read-syntax-table
711   ;; Lookup table for significant characters indicating the class of the
712   ;; token that follows.  This is not a \"real\" syntax table.
713   (let ((table (make-char-table 'syntax-table 'symbol))
714         (i 0))
715     (while (< i ?!)
716       (aset table i 'space)
717       (setq i (1+ i)))
718     (aset table ?\( 'lparen)
719     (aset table ?\) 'rparen)
720     (aset table ?\' 'quote)
721     (aset table ?\` 'backquote)
722     (aset table ?\, 'comma)
723     (aset table ?\" 'string)
724     (aset table ?\? 'char)
725     (aset table ?\[ 'lbracket)
726     (aset table ?\] 'rbracket)
727     (aset table ?\. 'dot)
728     (aset table ?\# 'hash)
729     ;; We treat numbers as symbols, because of confusion with -, -1, and 1-.
730     ;; We don't care about any other chars since they won't be seen.
731     table))
732
733 (defun edebug-next-token-class ()
734   ;; Move to the next token and return its class.  We only care about
735   ;; lparen, rparen, dot, quote, backquote, comma, string, char, vector,
736   ;; or symbol.
737   (edebug-skip-whitespace)
738   (if (and (eq (following-char) ?.)
739            (save-excursion
740              (forward-char 1)
741              (or (and (eq (aref edebug-read-syntax-table (following-char))
742                           'symbol)
743                       (not (= (following-char) ?\;)))
744                  (memq (following-char) '(?\, ?\.)))))
745       'symbol
746     (aref edebug-read-syntax-table (following-char))))
747
748
749 (defun edebug-skip-whitespace ()
750   ;; Leave point before the next token, skipping white space and comments.
751   (skip-chars-forward " \t\r\n\f")
752   (while (= (following-char) ?\;)
753     (skip-chars-forward "^\n")  ; skip the comment
754     (skip-chars-forward " \t\r\n\f")))
755
756
757 ;; Mostly obsolete reader; still used in one case.
758
759 (defun edebug-read-sexp ()
760   ;; Read one sexp from the current buffer starting at point.
761   ;; Leave point immediately after it.  A sexp can be a list or atom.
762   ;; An atom is a symbol (or number), character, string, or vector.
763   ;; This works for reading anything legitimate, but it
764   ;; is gummed up by parser inconsistencies (bugs?)
765   (let ((class (edebug-next-token-class)))
766     (cond
767      ;; read goes one too far if a (possibly quoted) string or symbol
768      ;; is immediately followed by non-whitespace.
769      ((eq class 'symbol) (edebug-original-read (current-buffer)))
770      ((eq class 'string) (edebug-original-read (current-buffer)))
771      ((eq class 'quote) (forward-char 1)
772       (list 'quote (edebug-read-sexp)))
773      ((eq class 'backquote)
774       (list '\` (edebug-read-sexp)))
775      ((eq class 'comma)
776       (list '\, (edebug-read-sexp)))
777      (t ; anything else, just read it.
778       (edebug-original-read (current-buffer))))))
779
780 ;;; Offsets for reader
781
782 ;; Define a structure to represent offset positions of expressions.
783 ;; Each offset structure looks like: (before . after) for constituents,
784 ;; or for structures that have elements: (before <subexpressions> . after)
785 ;; where the <subexpressions> are the offset structures for subexpressions
786 ;; including the head of a list.
787 (defvar edebug-offsets nil)
788
789 ;; Stack of offset structures in reverse order of the nesting.
790 ;; This is used to get back to previous levels.
791 (defvar edebug-offsets-stack nil)
792 (defvar edebug-current-offset nil) ; Top of the stack, for convenience.
793
794 ;; We must store whether we just read a list with a dotted form that
795 ;; is itself a list.  This structure will be condensed, so the offsets
796 ;; must also be condensed.
797 (defvar edebug-read-dotted-list nil)
798
799 (defsubst edebug-initialize-offsets ()
800   ;; Reinitialize offset recording.
801   (setq edebug-current-offset nil))
802
803 (defun edebug-store-before-offset (point)
804   ;; Add a new offset pair with POINT as the before offset.
805   (let ((new-offset (list point)))
806     (if edebug-current-offset
807         (setcdr edebug-current-offset
808                 (cons new-offset (cdr edebug-current-offset)))
809       ;; Otherwise, we are at the top level, so initialize.
810       (setq edebug-offsets new-offset
811             edebug-offsets-stack nil
812             edebug-read-dotted-list nil))
813     ;; Cons the new offset to the front of the stack.
814     (setq edebug-offsets-stack (cons new-offset edebug-offsets-stack)
815           edebug-current-offset new-offset)
816     ))
817
818 (defun edebug-store-after-offset (point)
819   ;; Finalize the current offset struct by reversing it and
820   ;; store POINT as the after offset.
821   (if (not edebug-read-dotted-list)
822       ;; Just reverse the offsets of all subexpressions.
823       (setcdr edebug-current-offset (nreverse (cdr edebug-current-offset)))
824
825     ;; We just read a list after a dot, which will be abbreviated out.
826     (setq edebug-read-dotted-list nil)
827     ;; Drop the corresponding offset pair.
828     ;; That is, nconc the reverse of the rest of the offsets
829     ;; with the cdr of last offset.
830     (setcdr edebug-current-offset
831             (nconc (nreverse (cdr (cdr edebug-current-offset)))
832                    (cdr (car (cdr edebug-current-offset))))))
833
834   ;; Now append the point using nconc.
835   (setq edebug-current-offset (nconc edebug-current-offset point))
836   ;; Pop the stack.
837   (setq edebug-offsets-stack (cdr edebug-offsets-stack)
838         edebug-current-offset (car edebug-offsets-stack)))
839
840 (defun edebug-ignore-offset ()
841   ;; Ignore the last created offset pair.
842   (setcdr edebug-current-offset (cdr (cdr edebug-current-offset))))
843
844 (defmacro edebug-storing-offsets (point &rest body)
845   (declare (debug (form body)) (indent 1))
846   `(unwind-protect
847        (progn
848          (edebug-store-before-offset ,point)
849          ,@body)
850      (edebug-store-after-offset (point))))
851
852
853 ;;; Reader for Emacs Lisp.
854
855 ;; Uses edebug-next-token-class (and edebug-skip-whitespace) above.
856
857 (defconst edebug-read-alist
858   '((symbol . edebug-read-symbol)
859     (lparen . edebug-read-list)
860