-*-TEXT-*-  Node: Top Next: Args Up: (DIR) This describes TDEBUG, a package of Teco macros for debugging Teco macros. Provision is made for macro stack examination, editing, stepping, and q-register pdl examination. By executing MM Debug Mode$, a minibuffer is entered. The commands typed into this minibuffer will be stepped. The debugger can also be entered by code hitting a user placed breakpoint. When the debugger is entered, the screen is split into two windows, with the current buffer displayed in the top window, and the current macro frame in the bottom buffer. There is an area between the window, that contains information about the current macro frame. When loaded, the debugger also becomes the default error handler, replacing the standard EMACS Backtrace. The stepper can break at the start of any macro invocation, a succeeding conditional, or after a control-m . It cannot break in the middle of a line unless a breakpoint is explicitly placed there. *Note Exit: Execution. Whether you will actually see a break, of course, depends upon what commands you have typed. * Menu: Minimum abbreviations: A Br S Ed Ex Di Q Do Bu I F * Args:: Command arguments * Breakpoints:: Placing and removing Breakpoints * Stack:: Macro stack manipulation * Editing:: ^R on the macro frame or buffer * Execution:: Stepping, etc. * Display:: Controlling display * QPdl:: Display of QPdl slots * Documentation:: * Bugs:: Bugs * Insides:: Helpful notes about implementation and modification * Future:: Future features (sigh)  Node: Args Next: Breakpoints Previous: Top Up: Top Some commands may take prefix arguments which are entered by typing the digits. Rubout will flush any accumulated argument. An equals sign "=" will do nothing but type (and flush) its arg. All arguments default to 1.  Node: Breakpoints Next: Stack Previous: Args Up: Top There is a facility for placing and removing breakpoints, via the MM Break$ and MM Unbreak$ commands. The MM Break$ command takes a string argument, and installs a breakpoint in that macro. The MM Unbreak$ command, removes the breakpoint from a macro if given a macro name, or removes all breakpoints if no macro name is given. Both of these macros try to be clever about not breakpointing a macro that is already has a breakpoint installed, and not removing breakpoints from the macro, if it has changed. Thus it is hard to screw yourself by putting a breakpoint it a macro, recompiling it, and then trying to unbreakpoint the same macro. The way a macro is breakpointed is to install a call to MM & Tdebug Breakpoint$ on the front of the macro. The user can thus install one of these in a macro to signal an error condition if he likes. One problem with breakpoints currently is that if you are not already in the debugger when you hit a breakpoint, you will not be able to step past that breakpoint. This is because the step macro will not be set up outside this explicit call to the debugger. You will end up in debug mode, and be able to examine the stack however. If you were previously in the debugger, all facilities will be available when you hit a break point.  Node: Stack Next: Editing Previous: Breakpoints Up: Top When inside the debugger, the scope of the stack is normally all levels of macro invocations since entering the debugger at the lowest level. Thus recursive entries to the debugger (like hitting a breakpoint while you are stepping) still allow you to examine the entire stack. While this is normally true, it is possible to get the debugger allow access to the entire stack, by way of whole stack mode. The commands listed here may take prefix arguments as described above. "D" or will move down the stack, to earlier macro invocations. "U" or "^" will move up the stack, to more recent invocations. If you go past the end of the stack in either direction, an "out of range" message will be displayed. "W" toggles whole stack mode. When in whole stack mode, the debugger allows examination of the entire macro and q-register stack. When in non whole stack mode, it limits its displays to only the macros invoked, and q-registers pushed since entering the debugger. The exception to this, is when the debugger is entered by a breakpoint or an error, in which case, since the debugger does not know what part of the stack is of interest to the user, it enables whole stack mode.  Node: Editing Next: Execution Previous: Stack Up: Top ^R-style editing can be done on the macro frame, the current buffer, a fresh buffer, or a minibuffer. "^R" will call ^R on the presently displayed macro frame. This might be useful in case not all of the frame can be seen in the window, or else to set point for later use *Note ^R: Execution. "B" calls ^R on the presently displayed buffer (q..o). "\" will call ^R on an fresh, empty buffer displayed in the upper window. This is intended for patching and/or random ^R hacking where doing it in the "real" buffer or the macro frame might be inconvenient. When the ^R is exited, its buffer disappears completely. will cause the familiar minibuffer to appear. Q..O is set to the "real" buffer, rather than the macro frame" buffer (which is inaccessable through this minibuffer). If you really want a minibuffer to hack the macro frame buffer, do "M". "M" will cause the familiar minibuffer to appear, for hacking the macro frame buffer. Node: Execution Next: Display Previous: Editing Up: Top The available commands for controlling macro execution are: abort; two flavors of stepping; level exiting; and three (count them, 3) synonyms for exiting. "Q" will abort any and all macro levels called since the last invocation of ^R and exit the debugger. "^N" (control-N) or space will break at the next opportunity, whether it be at the current macro level or at another. ^N, strangely enough, will break at the th next opportunity. "^N" is sort of analogous to DDT's "^N" command. "N" will break only when the pc is greater than or equal to point in the currently displayed frame. Thus a succession of "N"s will step line by line through the current macro level, stepping over called macros. In this sense, "N" is analogous to DDT's $$^N. N will do "N" times. Another use for "N" is to proceed directly to some point other than the next line in the current frame. This would be done by doing "D" or "U" to get to the desired macro level, doing "^R" so that point can be moved around, exiting the "^R", and finally doing the "N". "L" is used for exiting from levels of macro invocation, in analogy to DDT's "P,$$^N". This would be useful in case you ^N'ed into a macro level but then wanted to get out. The "L" command is functionally equivalent to "D N". "X", and control-altmode all exit from step mode, clearing the bottom window, and continue macro execution. At present, don't "N" past the end of a macro, or else you will invisibly step through untold volumes of macros, finally breaking inside the next macro that is invoked at that macro level, and has a line past the current point.  Node: Display Next: QPdl Previous: Execution Up: Top Since we are trying to display two "buffers" in two windows with important information in both windows being communicated by the position of the single console "hardware" cursor, the command "." is provided to switch the cursor between windows. In the case of display lossage, "^L" (control-L) will clear the entire screen, and redisplay both windows.  Node: QPdl Next: Documentation Previous: Display Up: Top There are two modes in general for displaying the contents of a teco object. These are toggled by the command "F", which toggles full display of Q-Vectors, and prints in a slightly more lucid format. This is the default printing mode. The other mode is slightly more concise, as it is somewhat a relic of the past. "S" will type some information about the home and contents of q-register pdl slot . Just typing "S" will at least tell you how many slots are presently in use (including those used by the break macro itself). "H" displays the same stuff as "S" for all qpdl slots, starting from the top of the pdl and going down. H will display only the top slots. The slot contents are displayed with a HV, so if you see a --MORE-- you can give it a space to see the next screenful. Whole stack mode controls whether you see the entire qpdl, or just the qpld pushed since the debugger was entered. *Note Whole: Stack. "V" will prompt you for a q register name, and display it's contents in the same format as S. This uses the EMACS macro MM & Read Q-Reg Name to read the name of the Q-register, and is able to display single elements of a Q-Vector.  Node: Documentation Next: Bugs Previous: QPdl Up: Top Typing a "?" when in a breakpoint will print some initial identification as to what the darn thing's doing, and offer to enter "documentation" mode if you type another "?". If you do, the macro & Debug Describe$ will run, entering a loop asking you to type the name of a debug command character, or else a "*" (to see the list of available commands). To get out of the loop, type a space when you can.  Node: Bugs Next: Insides Previous: Documentation Up: Top Present bugs and misfeatures: 1) There still are problems with redisplay of the macro frame when it is not necessary. 2) Some portions of the debugger does not conform with Emacs conventions about recursive ^R mode. 3) Stepping off the end of a macro with N should probably cause a break at the next level up. 4) For some reason moving forward with ^R in the macro buffer, and the doing an "N" stops at conditionals, before the point where you did the "N".  Node: Insides Next: Future Previous: Bugs Up: Top As you might have guessed, this all works by using Teco's FS Step Macro$ and FS Backtrace$ flags. Each time the step handler (in & Tdebug Break) runs, it decides whether to break. The decision is made in terms of four cases: 1) If its arg is negative (as set by MM& Tdebug Breakpoint which calls it), it always breaks. 2) If it was proceeded by ^N or space the last time, then exit if the count hasn't expired, otherwise break 3) If it was proceeded by N or L, and we are at or past the point where we were the last time, check the count, otherwise just exit. 4) If the code we are about to look at is internal Teco code, just return. The commands are dispatched by doing M(M.MTdebug # $); hence user additions or modifications to what the commands do is straightforward. Hopefully, the documentation stuff will also win for such additions.  Node: Future Previous: Insides Up: Top Future Features and mods (sigh...) 1) A way of keying QPdl levels to macro invocation levels.